Miyanokouji Posted August 1, 2007 Report Share Posted August 1, 2007 I have written a PHP API for the WebUIHere's the sourceFollow the instructions in the commentsAny questions/etc post here.You _will_ need the cURL and JSON extensions (JSON included in PHP 5.2+ as standard)If you download torrents greater than 4GB in size and wish to see that size correctly you will need PHP 5.2.4 or greater.UpdatesAdded setProperty and getProperties, gave list of properties that can be used.Added more defines for ease of use and also added is_online to check it's onlineEeek! Didn't test the code properly after update2. is_online no longer outputs "invalid request" to the browser.Added the recheckTorrent function, modde the start, pause, stop, forcestart, and recheck functions to be able to receive arrays of hashes. A load of comments. Probably some other minor changes.Fixed a bug found by nowotny. Thanks nowotny!Added removedata functionality as coded by nowotny, also added the ability to add torrents from a URL (just use addTorrent("someurl"))Very very minor bug fix - fixed is_online so that it _only_ returns true or false.Another minor bug fix - forcestartTorrent and recheckTorrent no longer output the result. (Credit once again goes to nowotny)Yet another addition by Nowotny! The getLabel function has now been added.Bugfix. Due to new information the UTORRENT_TYPE_* definitions have changed.Very belated bugfix. Fixed addTorrent to use substr, not substring and to url-encode the file if a URL is passed. Thanks to m69bv3 and protomank. This will probably be the last time I update this, not because I consider it finished (due to not considering WebUI finshed, but because I have far too much going on in my life (GCSEs, etc) and too many coding projects.) If you wish to take on this PHP API as your own project, please keep your modifications in the same style as mine, or rewrite my parts into your style too, and most importantly, mention me somewhere [2008-04-08] [ultima] Fixed addTorrent's add-url call (was mistakenly calling get-url instead of add-url). Fixed setPriority. Use substr (not the non-existent substring).[2008-04-08] [ultima] I've a greatly simplified version of the API here, though it's raw and untested (no dogfood testing from me this time). Guinea pigs are welcome!<?phpdefine("UTORRENT_TORRENT_HASH",0);define("UTORRENT_TORRENT_STATUS",1);define("UTORRENT_TORRENT_NAME",2);define("UTORRENT_TORRENT_SIZE",3);define("UTORRENT_TORRENT_PROGRESS",4);define("UTORRENT_TORRENT_DOWNLOADED",5);define("UTORRENT_TORRENT_UPLOADED",6);define("UTORRENT_TORRENT_RATIO",7);define("UTORRENT_TORRENT_UPSPEED",8);define("UTORRENT_TORRENT_DOWNSPEED",9);define("UTORRENT_TORRENT_ETA",10);define("UTORRENT_TORRENT_LABEL",11);define("UTORRENT_TORRENT_PEERS_CONNECTED",12);define("UTORRENT_TORRENT_PEERS_SWARM",13);define("UTORRENT_TORRENT_SEEDS_CONNECTED",14);define("UTORRENT_TORRENT_SEEDS_SWARM",15);define("UTORRENT_TORRENT_AVAILABILITY",16);define("UTORRENT_TORRENT_QUEUE_POSITION",17);define("UTORRENT_TORRENT_REMAINING",18);define("UTORRENT_FILEPRIORITY_HIGH",3);define("UTORRENT_FILEPRIORITY_NORMAL",2);define("UTORRENT_FILEPRIORITY_LOW",1);define("UTORRENT_FILEPRIORITY_SKIP",0);define("UTORRENT_TYPE_INTEGER",0);define("UTORRENT_TYPE_BOOLEAN",1);define("UTORRENT_TYPE_STRING",2);define("UTORRENT_STATUS_STARTED",1);define("UTORRENT_STATUS_CHECKED",2);define("UTORRENT_STATUS_START_AFTER_CHECK",4);class uTorrent { //set host to be the IP or hostname of your uTorrent machine //set user and pass to be the user and pass you use for the webui public $host = ""; public $user = ""; public $pass = ""; public function is_online() { $ch = curl_init(); //uses start because at present (WebUI 0.31, uTorrent 1.7.2) this simply returns {"":""} and doesn't modify anything. curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action="); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); if($ret !== false) { $ret = true; } return $ret; } //returns an array of all torrent information public function getTorrents() { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?list=1"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); //echo curl_getinfo($ch,CURLINFO_HTTP_CODE); $obj = json_decode($ret,true); $torrents = $obj['torrents']; curl_close($ch); return $torrents; } //returns an array of all labels. public function getLabels(){ $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?list=1"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); $obj = json_decode($ret,true); $labels = $obj['label']; curl_close($ch); return $labels; } //if you set $estring then when the function is done and returns false, estring will be a string telling you what error happened. //$filename could probably be a temporary filenames ($_FILES['somefile']['tmp_name']) but I haven't checked //$filename can be a URL public function addTorrent($filename,&$estring = false) { if(substr($filename,0,7) == "http://") { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=add-url&s=".urlencode($filename)); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } else if(file_exists($filename)) { $form_fields = array(); //$form_fields['add_button'] = "Add File \n"; $form_fields['torrent_file'] = "@".realpath($filename); $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=add-file"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); //curl_setopt($ch,CURLOPT_HEADER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_setopt($ch,CURLOPT_POSTFIELDS,$form_fields); curl_setopt($ch,CURLOPT_VERBOSE,true); $ret = curl_exec($ch); //echo $ret; //echo curl_error($ch); curl_close($ch); $obj = json_decode($ret,true); if(isset($obj['error'])) { if($estring !== false) { $estring = $obj['error']; } return false; } else { return true; } } else { $estring = "File doesn't exist!"; return false; } } public function removeTorrent($hash,$data=false) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } if($data) { $action='removedata'; } else { $action='remove'; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=".$action.$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function startTorrent($hash) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=start".$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function pauseTorrent($hash) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=pause".$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function stopTorrent($hash) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=stop".$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function forcestartTorrent($hash) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=forcestart".$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function recheckTorrent($hash) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=recheck".$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } //This could get the files of multiple torrents, but unfortunately json_decode overwrites the files array each time, instead of // doing something nice like having files[i] where i is the number of how many hashes you used. //If someone writes a better JSON decoding function which does that I'd be happy to use that instead. public function getFiles($hash) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=getfiles&hash=".$hash); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); $obj = json_decode($ret,true); return $obj; } //This could be get the properties of multiple torrents, but unfortunately json_decode overwrites the props array each time, instead of // doing something nice like having props[i] where i is the number of how many hashes you used. //If someone writes a better JSON decoding function which does that I'd be happy to use that instead. public function getProperties($hash) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=getprops&hash=".$hash); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); $obj = json_decode($ret,true); return $obj; } /* * properties (in format * propertyname type and explanation) * trackers string (what trackers to use seperated by \r\n\r\n) * ulrate int (maximum upload rate of torrent) * dlrate int (maximum download rate of torrent) * superseed bool (whether or not to superseed) * dht bool (whether or not to use DHT) * pex bool (whether or not to use peer exchange) * seed_override bool (whether or not global seeding settings are overridden) * seed_ratio int (what ratio to seed to before stopping) * seed_time int (what time to seed to before stopping (seconds)) * ulslots int (number of upload slots) */ //this might work using multiple hashes but for now I haven't set to be able to //it equally might work with multiple properties and values, again I haven't tried so haven't coded it to do so public function setProperty($hash,$property,$value) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=setprops&hash=".$hash."&s=".$property."&v=".$value); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } //$file is a number between 0 and the number of files in the torrent minus one. ( I think. might be 1-based) //Files are in the order that getFiles returns them in //Priority is one of the UTORRENT_FILEPRIORITYs I defined earlier //If $files is an array it will set the priority on each public function setPriority($hash,$files,$priority) { $filenums = ""; if(is_array($files)) { foreach($files as $value) { $filenums.="&f=".$value; } } else { $filenums = "&f=".$file; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=setprio&hash=$hash&p=".$priority.$filenums); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } public function getSettings() { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=getsettings"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); $obj = json_decode($ret,true); return $obj; } public function setSetting($setting,$value) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=setsetting&s=".$setting."&v=".$value); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); }}?>USAGEYou can either set your host, user, and pass in the class, by changing it like so-snip-class uTorrent {-snip public $host = "someip:someport"; public $user = "somename"; public $pass = "somepass";OR, you can do it after you make the uTorrent object, like so$torrent = new uTorrent;$torrent->host = "someip:someport";$torrent->user = "someuser";$torrent->pass="somepass";Here are some examples of usage (in these examples we'll assume you set the host, user and pass in the class (as per the first example)//print out current torrents (just the names in a newline-seperated list)$utorrent = new uTorrent();$torrents = $utorrent->getTorrents();foreach($torrents as $torrent) { echo $torrent[UTORRENT_TORRENT_NAME]."\n";}//Forces a recheck of every torrent//way number one (slower)$utorrent = new uTorrent();foreach($utorrent->getTorrents() as $torrent) { $utorrent->recheck($torrent);}//Forces a recheck of every torrent//Way number two (faster)$utorrent = new uTorrent();$torrents = array();//collects an array containing every hashforeach($utorrent->getTorrents() as $torrent) { $torrents[] = $torrent[UTORRENT_TORRENT_HASH];}//rechecks every torrent$utorrent->recheck($torrents); Link to comment Share on other sites More sharing options...
Lord Alderaan Posted August 1, 2007 Report Share Posted August 1, 2007 Nice Link to comment Share on other sites More sharing options...
Arkard Posted August 1, 2007 Report Share Posted August 1, 2007 Really interesting Link to comment Share on other sites More sharing options...
Miyanokouji Posted August 2, 2007 Author Report Share Posted August 2, 2007 Updated it again - added is_online (from seeing that it would be useful in http://forum.utorrent.com/viewtopic.php?id=26175 ) Link to comment Share on other sites More sharing options...
TheDestroyer Posted August 5, 2007 Report Share Posted August 5, 2007 I need to implement such thing to my site (it is in the local network): Users open special page where they can add a new torrent download and watch the download progress. (Guest account allows only to see the download progress, not to add new downloads) Admin account allows to delete downloads and to change settings - ordinary users aren't allowed to do it. I guess that these API will help me to do it. I'm not familar with php classes and objects. So I go in this way:I think that these API are used on a web server, not in the zip archive of webui. Is this right?So I've created webui directory in my web root directory. There are two files webui_api.php and webui.php.webui_api.php contains the code from the first post. webui.php contains: require_once("webui_api.php");$torrent = new uTorrent;$torrents = $torrent->getTorrents();echo "result: ".$torrents;if ($torrent->addTorrent("c:\28.nedel.spustya.2007.DivX.DVDRip.kinozal.tv.avi.torrent")){print"<br> OK";}else{print "Bad";}So, echo "result: ".$torrents; prints result:<and adding file shows OK. But no file is added.Please, explain (examples appreciated) how to use these API. Link to comment Share on other sites More sharing options...
Ultima Posted August 5, 2007 Report Share Posted August 5, 2007 Um. I'm not all that familiar with coding in PHP, but from a cursory glance over the code... Aren't you supposed to be setting $torrent's $host, $user, and $pass variables before actually using its methods...?Also, IINM, getTorrents() returns an array... is it legal to concatenate strings with arrays in PHP? Link to comment Share on other sites More sharing options...
dAbReAkA Posted August 5, 2007 Report Share Posted August 5, 2007 if it really is an array than the output should be 'result: Array' Link to comment Share on other sites More sharing options...
Destroyer Posted August 6, 2007 Report Share Posted August 6, 2007 $torrent's $host, $user, and $pass variables are set in webui_api.php so there is no mistake.$torrent = new uTorrent;$torrents = $torrent->getTorrents();print_r(array_count_values($torrents));print_r - tells that it is not array. Can anyone show an example of listing downloads on the web page, similar to guest account? Link to comment Share on other sites More sharing options...
Miyanokouji Posted August 9, 2007 Author Report Share Posted August 9, 2007 Sorry for the slow response - been away on holiday all week with no internet!TheDestroyer, I think your problem lies within this line:if ($torrent->addTorrent("c:\28.nedel.spustya.2007.DivX.DVDRip.kinozal.tv.avi.torrent"))You should be using c:\\ I think (\28 would probably produce the ASCII character for 28 (or 2) (or nothing) (or something else entirely) (As you can tell I don't really know much about escape characters, except that backslashes need escaping)Also, I'm not entirely sure how cURL handles uploading files that don't exist (addTorrent was sort of an afterthought)And I added some usage examples and updated it again to add recheck($hash) and stuff Link to comment Share on other sites More sharing options...
Destroyer Posted August 21, 2007 Report Share Posted August 21, 2007 Thanx for reply. But I still have got problems listing torrents... Your example : //print out current torrents (just the names in a newline-seperated list)gives an error:Warning: Invalid argument supplied for foreach() ...How to fix it? Link to comment Share on other sites More sharing options...
Miyanokouji Posted August 24, 2007 Author Report Share Posted August 24, 2007 Destroyer: You failed to read this, before the examples.(in these examples we'll assume you set the host, user and pass in the class (as per the first example)If they are set correctly there is no problem. (just tested the script myself)For example, in my case I have used the second method of setting them that I gave (I.E. Not in the class) (this is with the user and pass changed to non-real values)$utorrent = new uTorrent();$utorrent->host = "192.168.1.65:20405";$utorrent->user = "M";$utorrent->pass = "likefromJamesBond";$torrents = $utorrent->getTorrents();foreach($torrents as $torrent) { echo $torrent[UTORRENT_TORRENT_NAME]."\n";}I'll see if I have time some time to add in some error handling in the class though this is really a very minor priority as I have a lot of projects all on the go at once and school is starting again soon for me Link to comment Share on other sites More sharing options...
Destroyer Posted August 27, 2007 Report Share Posted August 27, 2007 Thank you very much! My mistake was - IP without a port of webui.Waiting for more examples of userfull application of these API.There is a problem in getting size of uploads that are more then 4 GB. Result is negative. We can add 4 Gb to the result and get correct filesize, but if filesize is for example 10 Gb then we don't know how many times to add 4 Gb to the result of$torrent[uTORRENT_TORRENT_SIZE]Please, help me to get correct filesize. Link to comment Share on other sites More sharing options...
Miyanokouji Posted September 24, 2007 Author Report Share Posted September 24, 2007 I don't think that issue's going to be at all easily fixable.My instant suspicion goes to the PHP JSON module, as PHP internally uses only long integers (64-bit) to store data, although the JSON module might not, and the actual WebUI works for files over 4GB, so it's not a problem with the WebUI or my script.Eventually, some time in the future, I might see if I can go over the JSON module's source code and see if I'm right. Link to comment Share on other sites More sharing options...
Destroyer Posted September 26, 2007 Report Share Posted September 26, 2007 OkWaiting for more than 4Gb files issue fix. Link to comment Share on other sites More sharing options...
nowotny Posted September 26, 2007 Report Share Posted September 26, 2007 You need to update your PHP installation to the latest version... I updated today from 5.2.1 to 5.2.4 and it's fixed...Miyanokouji: I think there is a bug in the setPriority function...Below is the corected code:public function setPriority($hash,$files,$priority) { $filenums = ""; if(is_array($files)) { foreach($files as $value) { $filenums.="&f=".$value; } } else { $filenums = "&f=".$files; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=setprio&hash=$hash&p=".$priority.$filenums); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } Link to comment Share on other sites More sharing options...
Miyanokouji Posted September 26, 2007 Author Report Share Posted September 26, 2007 Thanks for the info and bugfix nowotny, I've now updated the webui and am intending to do another update soon to add url torrent-adding function. What use it'll be is up to the end user <.< Link to comment Share on other sites More sharing options...
nowotny Posted September 27, 2007 Report Share Posted September 27, 2007 I enhanced the removeTorrent function to the ability of removing the downloaded data too... It's backwards compatible so nothing will break...Here's the code://if you set $data to TRUE it'll delete already downloaded data too. Otherwise just the torret file is deleted public function removeTorrent($hash,$data=FALSE) { $hashes = ""; if(is_array($hash)) { foreach($hash as $value) { $hashes.="&hash=".$value; } } else { $hashes = "&hash=".$hash; } if($data) { $action='removedata'; } else { $action='remove'; } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=".$action.$hashes); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } Link to comment Share on other sites More sharing options...
Miyanokouji Posted September 27, 2007 Author Report Share Posted September 27, 2007 Thanks again nowotny, I've added your code to the apiI need to write more documentation. I'll do it this weekend maybe <.< Link to comment Share on other sites More sharing options...
vbo Posted October 14, 2007 Report Share Posted October 14, 2007 How to use the addTorrent function ?require_once("webui_api.php");$torrent = new uTorrent;if ($torrent->addTorrent("c:\\111.torrent")){print"<br> OK";}else{print "Bad";}But no file is added. Link to comment Share on other sites More sharing options...
nowotny Posted October 17, 2007 Report Share Posted October 17, 2007 Miyanokouji: the forcestartTorrent and recheckTorrent functions are missing curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); setting... it makes them output the response which I don't think we want... Link to comment Share on other sites More sharing options...
Miyanokouji Posted October 17, 2007 Author Report Share Posted October 17, 2007 So they are...This is why people open source things! I'll add them in a sec. Link to comment Share on other sites More sharing options...
nowotny Posted October 18, 2007 Report Share Posted October 18, 2007 Here is a getLabels function for retrieving labels:public function getLabels(){ $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?list=1"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); $ret = curl_exec($ch); $obj = json_decode($ret,true); $labels = $obj['label']; curl_close($ch); return $labels; } Link to comment Share on other sites More sharing options...
Miyanokouji Posted October 26, 2007 Author Report Share Posted October 26, 2007 Thanks again Nowotny! Link to comment Share on other sites More sharing options...
Rexxars Posted December 4, 2007 Report Share Posted December 4, 2007 I really liked the API you've written, but I lacked CURL on my server, so I decided to write a slightly altered version using fsockopen. Sorry, it works a little bit differently for some things (configuration etc), but most of it should be the same (function names and output).What I would really like to have is a json_decode alternative that can run on PHP4 or PHP5 prior to 5.2.4 that can handle longs (so we can show sizes larger than 2GB).Here's the code:<?phpdefine("UTORRENT_TORRENT_HASH", 0);define("UTORRENT_TORRENT_STATUS", 1);define("UTORRENT_TORRENT_NAME", 2);define("UTORRENT_TORRENT_SIZE", 3);define("UTORRENT_TORRENT_PROGRESS", 4);define("UTORRENT_TORRENT_DOWNLOADED", 5);define("UTORRENT_TORRENT_UPLOADED", 6);define("UTORRENT_TORRENT_RATIO", 7);define("UTORRENT_TORRENT_UPSPEED", 8);define("UTORRENT_TORRENT_DOWNSPEED", 9);define("UTORRENT_TORRENT_ETA", 10);define("UTORRENT_TORRENT_LABEL", 11);define("UTORRENT_TORRENT_PEERS_CONNECTED", 12);define("UTORRENT_TORRENT_PEERS_SWARM", 13);define("UTORRENT_TORRENT_SEEDS_CONNECTED", 14);define("UTORRENT_TORRENT_SEEDS_SWARM", 15);define("UTORRENT_TORRENT_AVAILABILITY", 16);define("UTORRENT_TORRENT_QUEUE_POSITION", 17);define("UTORRENT_TORRENT_REMAINING", 18);define("UTORRENT_FILEPRIORITY_HIGH", 3);define("UTORRENT_FILEPRIORITY_NORMAL", 2);define("UTORRENT_FILEPRIORITY_LOW", 1);define("UTORRENT_FILEPRIORITY_SKIP", 0);define("UTORRENT_TYPE_INTEGER", 0);define("UTORRENT_TYPE_BOOLEAN", 1);define("UTORRENT_TYPE_STRING", 2);define("UTORRENT_STATUS_STARTED", 1);define("UTORRENT_STATUS_CHECKED", 2);define("UTORRENT_STATUS_START_AFTER_CHECK", 4);class uTorrent { public $sHost; public $iPort; public $sUser; public $sPassword; public $iTimeout; private $oSocket; public function __construct($sHost = '127.0.0.1', $iPort = 32459, $sUser = 'admin', $sPassword = 'utorrent', $iTimeout = 10) { $this->sHost = $sHost; $this->iPort = $iPort; $this->sUser = $sUser; $this->sPassword = $sPassword; $this->iTimeout = $iTimeout; } private function doRequest($sURL) { $this->oSocket = @fsockopen($this->sHost, $this->iPort, $iError, $sError, $this->iTimeout); if($this->oSocket) { // Connected fputs($this->oSocket, 'GET ' . $sURL . '&cid=' . rand(100000000, 259199361) . ' HTTP/1.0' . "\r\n"); fputs($this->oSocket, 'Authorization: Basic ' . base64_encode($this->sUser . ':' . $this->sPassword) . "\r\n\r\n"); // Retrieve content-length header $sHeader = ''; for(; !strpos($sHeader, "\r\n\r\n"); $sHeader .= fread($this->oSocket, 1)); $aHeaders = explode("\n", $sHeader); $iContentLength = (int) substr($aHeaders[2], 16); if($iContentLength) { $sRead = fread($this->oSocket, $iContentLength); fclose($this->oSocket); return $sRead; } else { // Could not read content length header fclose($this->oSocket); return 'Could not read content-length'; } } else { // Couldn't connect to socket return 'Could not connect'; } } public function is_online() { // Uses start because at present (WebUI 0.31, uTorrent 1.7.2) this simply returns {"":""} and doesn't modify anything if($this->doRequest('/gui/?action=')) { return true; } else { return false; } } // Returns an array of all torrent information public function getTorrents() { $aResponse = json_decode($this->doRequest('/gui/?list=1'), true); return $aResponse['torrents']; } // Returns an array of all labels. public function getLabels() { $aResponse = json_decode($this->doRequest('/gui/?list=1'), true); return $aResponse['label']; } private function uploadFile($sFilename, $sHost, $iPort, $sPage, $sPostFieldName, $bGetResponse = false, $bGetHTTPHeaders = false) { // Read the file $sFileContents = file_get_contents($sFilename); // Generate a boundary $sBoundary = '---------------------------' . substr(sha1(rand(0, 65000) * pi()), 0, 10); // Set up POST data $sData = '--' . $sBoundary . "\n" . 'Content-Disposition: form-data; name="' . $sPostFieldName . '"; filename="' . basename($sFilename) . '"' . "\n". 'Content-Type: application/octet-stream' . "\n\n" . $sFileContents . '--' . $sBoundary . '--' . "\r\n\r\n"; // Set up POST request $sRequest = 'POST ' . $sPage . ' HTTP/1.0' . "\n" . 'Content-Type: multipart/form-data; boundary=' . $sBoundary . "\n" . 'Content-Length: ' . strlen($sData) . "\r\n\r\n"; // Open socket $this->oSocket = fsockopen($sHost, $iPort); if($this->oSocket) { // Write the request and data to the socket fputs($this->oSocket, $sRequest . $sData); if($bGetResponse) { $sResult = ''; while(!feof($this->oSocket)) { $sResult .= fread($this->oSocket, 1024); } fclose($this->oSocket); // If the user does not want the HTTP headers, strip them if(!$bGetHTTPHeaders) { $sResult = substr($sResult, (strpos($sResult, "\r\n\r\n")+4)); } return $sResult; } else { fclose($this->oSocket); return true; } } else { // Could not open socket! return false; } } // If you set $mErrorString then when the function is done and returns false, estring will be a string telling you what error happened. // $sFilename could probably be a temporary filenames ($_FILES['somefile']['tmp_name']) but I haven't checked // $sFilename can be a URL public function addTorrent($sFilename, &$mErrorString = false) { if(substring($sFilename, 0, 7) == 'http://') { $this->doRequest('/gui/?action=get-url&s=' . $sFilename); } else if(file_exists($sFilename)) { $aResponse = json_decode($this->uploadFile($sFilename, $this->sHost, $this->iPort, '/gui/?action=add-file', 'torrent_file', true), true); if(isset($aResponse['error'])) { if($mErrorString !== false) { $mErrorString = $aResponse['error']; } return false; } else { return true; } } else { $mErrorString = 'File does not exist!'; return false; } } private function processHashArgument($mHash) { $sHashes = ""; if(is_array($mHash)) { foreach($mHash as $sHash) { $sHashes .= "&hash=" . $sHash; } } else { $sHashes = "&hash=" . $mHash; } return $sHashes; } public function removeTorrent($mHash, $bRemoveData = false) { if($bRemoveData) { $sAction = 'removedata'; } else { $sAction = 'remove'; } $this->doRequest('/gui/?action=' . $sAction . $this->processHashArgument($mHash)); } public function startTorrent($mHash) { $this->doRequest('/gui/?action=start' . $this->processHashArgument($mHash)); } public function pauseTorrent($mHash) { $this->doRequest('/gui/?action=pause' . $this->processHashArgument($mHash)); } public function stopTorrent($mHash) { $this->doRequest('/gui/?action=stop' . $this->processHashArgument($mHash)); } public function forcestartTorrent($mHash) { $this->doRequest('/gui/?action=forcestart' . $this->processHashArgument($mHash)); } public function recheckTorrent($mHash) { $this->doRequest('/gui/?action=recheck' . $this->processHashArgument($mHash)); } // This could get the files of multiple torrents, but unfortunately json_decode overwrites the files array each time, // instead of doing something nice like having files[i] where i is the number of how many hashes you used. // If someone writes a better JSON decoding function which does that I'd be happy to use that instead. public function getFiles($sHash) { return json_decode($this->doRequest('/gui/?action=getfiles&hash=' . $sHash), true); } // This could be get the properties of multiple torrents, but unfortunately json_decode overwrites the props array each time, // instead of doing something nice like having props[i] where i is the number of how many hashes you used. // If someone writes a better JSON decoding function which does that I'd be happy to use that instead. public function getProperties($sHash) { return json_decode($this->doRequest('/gui/?action=getprops&hash=' . $sHash), true); } // properties (in format * propertyname type and explanation) // trackers string (what trackers to use seperated by \r\n\r\n) // ulrate int (maximum upload rate of torrent) // dlrate int (maximum download rate of torrent) // superseed bool (whether or not to superseed) // dht bool (whether or not to use DHT) // pex bool (whether or not to use peer exchange) // seed_override bool (whether or not global seeding settings are overridden) // seed_ratio int (what ratio to seed to before stopping) // seed_time int (what time to seed to before stopping (seconds)) // ulslots int (number of upload slots) // This might work using multiple hashes but for now I haven't set to be able to it equally might // work with multiple properties and values, again I haven't tried so haven't coded it to do so public function setProperty($sHash, $sProperty, $sValue) { $this->doRequest('/gui/?action=setprops&hash=' . $sHash . "&s=" . $sProperty . "&v=" . $sValue); } // $file is a number between 0 and the number of files in the torrent minus one. ( I think. might be 1-based) // Files are in the order that getFiles returns them in // Priority is one of the UTORRENT_FILEPRIORITYs I defined earlier // If $mFiles is an array it will set the priority on each public function setPriority($sHash, $mFiles, $iPriority) { $sFilenumbers = ""; if(is_array($mFiles)) { foreach($mFiles as $iValue) { $sFilenumbers .= "&f=" . $iValue; } } else { $sFilenumbers = "&f=" . $mFiles; } $this->doRequest('/gui/?action=setprio&hash=' . $sHash . '&p=' . $iPriority . '&f=' . $sFilenumbers); } public function getSettings() { return json_decode($this->doRequest('/gui/?action=getsettings'), true); } public function setSetting($sSetting, $sValue) { $this->doRequest('/gui/?action=setsetting&s=' . $sSetting . "&v=" . $sValue); }}Here's how I would use it to pause all the torrents:$uTorrent = new uTorrent('127.0.0.1', 57777, 'rexxars', 'password', 10);if($uTorrent->is_online()){ foreach($uTorrent->getTorrents() as $aTorrent) { $uTorrent->pauseTorrent($aTorrent[UTORRENT_TORRENT_HASH]); }}Hope it can be to help for somebody :-) Link to comment Share on other sites More sharing options...
m69bv3 Posted January 22, 2008 Report Share Posted January 22, 2008 Hi, Here some change on addtorrent() on adding torrent with urlThank's for this API! //if you set $estring then when the function is done and returns false, estring will be a string telling you what error happened. //$filename could probably be a temporary filenames ($_FILES['somefile']['tmp_name']) but I haven't checked //$filename can be a URL public function addTorrent($filename,&$estring = false) { if(substr($filename,0,7) == "http://") { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=add-url&s=".$filename); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_exec($ch); } else if(file_exists($filename)) { $form_fields = array(); //$form_fields['add_button'] = "Add File \n"; $form_fields['torrent_file'] = "@".realpath($filename); $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,"http://".$this->host."/gui/?action=add-file"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); //curl_setopt($ch,CURLOPT_HEADER,true); curl_setopt($ch,CURLOPT_USERPWD,$this->user.":".$this->pass); curl_setopt($ch,CURLOPT_POSTFIELDS,$form_fields); curl_setopt($ch,CURLOPT_VERBOSE,true); $ret = curl_exec($ch); //echo $ret; //echo curl_error($ch); curl_close($ch); $obj = json_decode($ret,true); if(isset($obj['error'])) { if($estring !== false) { $estring = $obj['error']; } return false; } else { return true; } } else { $estring = "File doesn't exist!"; return false; } } Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.