1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-05 02:39:47 +02:00
ampache/modules/GMApi/GMApi.php
2013-11-17 01:21:00 +01:00

382 lines
10 KiB
PHP

<?php
/*
Copyright (C) 2012 raydan
http://code.google.com/p/unofficial-google-music-api-php/
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define("IN_GMAPI",true);
require_once('config.php');
require_once('utils.php');
require_once("PhpBuf/PhpBuf.php");
require_once('metadata/PB_Message_Abstract.php');
require_once('metadata/PB_UploadAuthResponse.php');
require_once('metadata/PB_Status.php');
require_once('metadata/PB_UploadAuth.php');
require_once('metadata/PB_MetadataRequest.php');
require_once('metadata/PB_TrackResponse.php');
require_once('metadata/PB_QueuedUpload.php');
require_once('metadata/PB_MetadataResponse.php');
require_once('metadata/PB_Track.php');
require_once('iProtocol.php');
require_once('protocol/WC_play.php');
require_once('protocol/WC_multidownload.php');
require_once('protocol/WC_deletesong.php');
require_once('protocol/WC_loadalltracks.php');
require_once('protocol/WC_modifyentries.php');
require_once('protocol/SJ_tracks.php');
require_once('protocol/SJ_playlists.php');
require_once('protocol/SJ_playlistbatch.php');
require_once('MM_Protocol.php');
require_once('GM_Protocol.php');
require_once('GM_Session.php');
class GMApi {
private static $_version = "1.0";
private static $_enable_debug;
private $_gm_session;
private $_mm_protocol;
private $_email;
private $_password;
private $_enable_restore;
private $_enable_mac_address_check;
private $_enable_session_file;
private $_skil_restore_check;
private $_login_type;
public function __construct() {
$this->_enable_restore = false;
$this->_enable_mac_address_check = true;
$this->_enable_session_file = false;
$this->_skil_restore_check = false;
$this->_gm_session = new GM_Session($this);
$this->_mm_protocol = new MM_Protocol($this);
}
/* API */
public static function version() { return GMApi::$_version; }
public static function setDebug($enable) { GMApi::$_enable_debug = $enable; }
public static function isDebug() { return GMApi::$_enable_debug; }
public static function clearAllSession() {
GM_Session::clearAllSession();
}
/*
try to restore login session from php $_SESSION or session file
*/
public function enableRestore($enable) { $this->_enable_restore = $enable; }
public function isEnableRestore() { return $this->_enable_restore; }
/*
write current login session information to file for later use?
*/
public function enableSessionFile($enable) { $this->_enable_session_file = $enable; }
public function isEnableSessionFile() { return $this->_enable_session_file; }
/*
set to false if already register the mac address, can save half second :D
*/
public function enableMACAddressCheck($enable) { $this->_enable_mac_address_check = $enable; }
public function isEnableMACAddressCheck() { return $this->_enable_mac_address_check; }
/*
skip the restore login check, should NOT enable, can save half second :D
*/
public function skipRestoreCheck($enable) { $this->_skil_restore_check = $enable; }
public function isSkipRestoreCheck() { return $this->_skil_restore_check; }
/*
fail, normal, session, file
*/
public function getLoginResultType() {
return $this->_gm_session->getLoginResultType();
}
public function logout() {
$this->_gm_session->logout();
}
public function login($email, $password, $mac_address) {
$this->_email = $email;
$this->_password = $password;
$this->_mm_protocol->initProtocol($mac_address);
$this->_gm_session->login($email, $password);
if($this->isEnableMACAddressCheck()) {
if($this->isAuthenticated()) {
$res = $this->_mm_pb_call("upload_auth");
if($res == false) {
$this->logout();
GMAPIPrintDebug("login success, but upload_auth fail");
}
}
}
return $this->isAuthenticated();
}
public function isAuthenticated() {
return ($this->_gm_session->isLoggedIn());
}
public function get_all_songs() {
$res = $this->_wc_call("loadalltracks");
if($res == false)
return false;
if(!is_array($res['playlist'])) {
if($res['success'] == false && $res['reloadXsrf'] == true) {
$this->logout();
$this->_gm_session->login($this->_email, $this->_password, false);
if($this->isAuthenticated()) {
return $this->get_all_songs();
}
}
GMAPIPrintDebug("playlist not array");
return false;
}
$output = array();
$output = array_merge($output, $res['playlist']);
$should_continue = (!empty($res['continuationToken']));
while($should_continue) {
$res = $this->_wc_call("loadalltracks",$res['continuationToken']);
if($res == false)
break;
if(!is_array($res['playlist'])) {
GMAPIPrintDebug("playlist not array");
return false;
}
$output = array_merge($output, $res['playlist']);
$should_continue = (!empty($res['continuationToken']));
}
return $output;
}
public function get_stream_url($songId) {
$res = $this->_wc_call("play", $songId);
if($res == false)
return false;
return $res['url'];
}
public function get_download_info($songId) {
$res = $this->_wc_call("multidownload", $songId);
if($res == false)
return false;
if(empty($res['downloadCounts']))
return false;
return array("url"=>$res['url'],
"count"=>intval($res['downloadCounts'][$songId]));
}
public function delete_songs($songIds) {
$res = $this->_wc_call("deletesong", $songIds);
if($res == false)
return false;
return $res;
}
public function change_song_metadata($songData) {
$res = $this->_wc_call("modifyentries", $songData);
if($res == false)
return false;
return $res;
}
public function upload($files) {
$fn_sid_map = array();
$cid_map = array();
$metadata_request = $this->_mm_protocol->make_metadata_request($files, $cid_map);
if($metadata_request == false) {
return false;
}
$metadataresp = $this->_mm_pb_call("metadata", $metadata_request);
if($metadataresp == false) {
return false;
}
$session_requests = $this->_mm_protocol->make_upload_session_requests($cid_map, $metadataresp);
foreach($session_requests as $session) {
$filename = $session[0];
$filepath = $session[1];
$server_id = $session[2];
$payload = $session[3];
$post_data = json_encode($payload);
$success = false;
$already_uploaded = false;
$attempts = 0;
while(!$success && $attempts < 3) {
$result = $this->_gm_session->jumper_post("/uploadsj/rupio", $post_data);
$res = json_decode($result,true);
if(!empty($res['sessionStatus'])) {
$success = true;
break;
}
if(!empty($res['errorMessage'])) {
$error_code = $res['errorMessage']['additionalInfo']['uploader_service.GoogleRupioAdditionalInfo']['completionInfo']['customerSpecificInfo']['ResponseCode'];
$error_code = intval($error_code);
switch($error_code)
{
case 503:
$attempts = -1;
break;
case 200:
$success = true;
$already_uploaded = true;
break;
case 404:
break;
default:
break;
}
if(!$success) {
sleep(3);
$attempts += 1;
}
}
break;
}
if($success && !$already_uploaded) {
$up = $res['sessionStatus']['externalFieldTransfers'][0];
$content = file_get_contents($filepath);
$result = $this->_gm_session->jumper_post($up['putInfo']['url'], $content, array('Content-Type'=>$up['content_type']));
$res = json_decode($result,true);
if($res['sessionStatus']['state'] == 'FINALIZED') {
$fn_sid_map[$filename] = $server_id;
}
} else if($already_uploaded) {
$fn_sid_map[$filename] = $server_id;
} else {
GMAPIPrintDebug("unable upload ".$filepath);
}
}
return $fn_sid_map;
}
public function get_tracks($track_id = null) {
$res = $this->_sj_call("tracks", $track_id);
if($res == false)
return false;
return $res;
}
public function get_playlists($playlist_id = null) {
$res = $this->_sj_call("playlists", $playlist_id);
if($res == false)
return false;
return $res;
}
public function create_playlist($playlist_name) {
if(empty($playlist_name) || strlen($playlist_name) <= 0)
return false;
$data = array('mutations'=>array(
array(
'create'=>array("name"=>$playlist_name),
)
)
);
$res = $this->_sj_call("playlistbatch", json_encode($data));
if($res == false || empty($res['mutate_response']))
return false;
return $this->get_playlists($res['mutate_response']['id']);
}
/* private function */
private function _sj_call($service_name, $args=null) {
$protocol = GM_Protocol::getSJProtocol($service_name);
if($protocol == false) {
GMAPIPrintDebug("cannot find sj protocol \"".$service_name."\"");
return false;
}
$result = $this->_gm_session->open_sj_https_url($protocol, $args);
if($result == false)
return false;
return json_decode($result,true);
}
private function _wc_call($service_name, $args=null) {
$protocol = GM_Protocol::getWCProtocol($service_name);
if($protocol == false) {
GMAPIPrintDebug("cannot find wc protocol \"".$service_name."\"");
return false;
}
$query = $protocol->buildTransaction($args);
$result = $this->_gm_session->open_authed_https_url($protocol, $query);
if($result == false)
return false;
return json_decode($result,true);
}
private function _mm_pb_call($service_name, $req = null) {
$res = $this->_mm_protocol->make_pb($service_name."_response");
if($req == null) {
$req = $this->_mm_protocol->make_pb($service_name."_request");
if(!$req) {
$req = $this->_mm_protocol->make_pb($service_name);
}
}
$url = $this->_mm_protocol->getpb_services($service_name);
$result = $this->_gm_session->protopost($url, $req);
if($result) {
$res->ParseFromString($result);
return $res;
}
return false;
}
}
?>