├── envato-cache └── README.txt ├── example.php ├── README.md ├── commission-split.php └── class.envato_scraper.php /envato-cache/README.txt: -------------------------------------------------------------------------------- 1 | make this folder writable so the PHP script can cache results 2 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | do_login('username','password'); 7 | $statement = $my_scraper->get_statement('1/2013'); 8 | $items = $my_scraper->get_users_items('dtbaker',array('codecanyon','themeforest')); // doesn't work with debug enabled. 9 | 10 | echo "
";
11 | echo "My Statement: \n";
12 | print_r($statement);
13 | echo "My Items: \n";
14 | print_r($items);
15 | echo "
"; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | envato-scraper 2 | ============== 3 | 4 | 5 | This simple PHP class scrapes the CSV statment down from Envato. 6 | 7 | Example Usage: 8 | 9 | ```php 10 | // return all dtbaker items from ThemeForest and CodeCanyon 11 | require_once 'class.envato_scraper.php'; 12 | $my_scraper = new envato_scraper(); 13 | $my_scraper->do_login('username','password'); 14 | $statement = $my_scraper->get_statement('1/2013'); 15 | $items = $my_scraper->get_users_items('dtbaker',array('codecanyon','themeforest')); // doesn't work with debug enabled. 16 | 17 | echo "My Statement: \n"; 18 | print_r($statement); 19 | echo "My Items: \n"; 20 | print_r($items); 21 | ``` 22 | 23 | Example Output: 24 |
25 | My Statement:
26 | Array
27 | (
28 |     [0] => Array
29 |         (
30 |             [type] => sale
31 |             [date] => 2013-01-31 23:43:06 +1100
32 |             [time] => 1359636186
33 |             [item] => WordPress Email Ticket Support Plugin
34 |             [item_id] => 254823
35 |             [envato_item_id] => 0
36 |             [earnt] => 15.40
37 |             [amount] => 22.00
38 |             [rate] => 70.0
39 |         )
40 | 
41 |     [1] => Array
42 |         (
43 |             [type] => sale
44 |             [date] => 2013-01-31 22:16:25 +1100
45 |             [time] => 1359630985
46 |             [item] => PHP Search Engine
47 |             [item_id] => 89499
48 |             [envato_item_id] => 0
49 |             [earnt] => 7.00
50 |             [amount] => 10.00
51 |             [rate] => 70.0
52 |         )
53 |         etc.....
54 | My Items:
55 | Array
56 | (
57 |     [0] => Array
58 |         (
59 |             [item_id] => 2621629
60 |             [preview_image] => http://1.s3.envato.com/files/30243603/preview-ucm-pro_renew-invoices_pdf_customer-database_emails.jpg
61 |             [cost] => 60
62 |             [sales] => 53
63 |             [name] => Ultimate Client Manager - Pro Edition
64 |             [category] => Php-scripts / Project-management-tools
65 |             [thumb_image] => http://0.s3.envato.com/files/30243602/thumb-ucm-pro_open-source-php-database.png
66 |             [url] => http://codecanyon.net/item/ultimate-client-manager-pro-edition/2621629
67 |             [marketplace] => http://codecanyon.net
68 |         )
69 | 
70 |     [1] => Array
71 |         (
72 |             [item_id] => 2616958
73 |             [preview_image] => http://2.s3.envato.com/files/30196302/preview-customer-job-discussion-project-management-plugin.jpg
74 |             [cost] => 6
75 |             [sales] => 7
76 |             [name] => UCM Plugin: Project Discussion / Customer Comments
77 |             [category] => Php-scripts / Project-management-tools
78 |             [thumb_image] => http://3.s3.envato.com/files/30196301/thumb-customer-project-comments-and-discussion.png
79 |             [url] => http://codecanyon.net/item/ucm-plugin-project-discussion-customer-comments/2616958
80 |             [marketplace] => http://codecanyon.net
81 |         )
82 | 
83 |     [2] => Array
84 |         (
85 | 	etc...
86 | 
87 | -------------------------------------------------------------------------------- /commission-split.php: -------------------------------------------------------------------------------- 1 | array( // REPLACE THIS WITH THE ITEM ID YOU WISH TO CALCULATE COMMISSION SPLITS ON 31 | 'start_date' => '2/2013', // WHAT MONTH TO START COMMISSION CALCULATIONS FROM ( in m/Y format, eg: 1/2012 or 12/2011 ) 32 | 'authors' => array( 33 | 'your_author_name_here' => array( 34 | 'split' => 0.5, // percentage here (eg: 50% is 0.5) 35 | 'total' => 0, 36 | ), 37 | 'other_author_name_here' => array( 38 | 'split' => 0.5, // percentage here (eg: 50% is 0.5) 39 | 'total' => 0, 40 | ), 41 | // add more authors here if you need to split 3 or more ways. 42 | ), 43 | ), 44 | // add more item configurations here if needed. 45 | ); 46 | 47 | 48 | /** END CONFIGURATION AREA **/ 49 | 50 | 51 | $item_id = isset($_REQUEST['item_id']) ? (int)$_REQUEST['item_id'] : false; 52 | if(!$item_id || !isset($splits[$item_id]))exit; 53 | require_once 'class.envato_scraper.php'; 54 | $my_scraper = new envato_scraper(); 55 | $my_scraper->do_login(_ENVATO_USERNAME,_ENVATO_PASSWORD); 56 | $statement = $my_scraper->get_statement($splits[$item_id]['start_date']); 57 | $menu_months = array(); 58 | foreach($statement as $item){ 59 | if(isset($item['item_id']) && $item['item_id'] == $item_id){ 60 | $key = date('Y/m',$item['time']); 61 | if(!isset($menu_months[$key]))$menu_months[$key] = array( 62 | 'sales'=> array(), 63 | 'label'=>date('F Y',$item['time']), 64 | ); 65 | $menu_months[$key]['sales'][] = $item; 66 | } 67 | } 68 | ?> 69 | 70 | 71 | 72 | 73 | Commission Split 74 | 75 | 76 | 77 | 78 | 79 | 80 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 120 | 121 |
122 |
123 |
124 | 132 |
133 |
134 |
135 |

Commission Split Calculator!

136 |
    137 | $split_data){ ?> 138 |
  • 139 | gets % 140 |
  • 141 | 142 |
143 |
144 |
145 | $menu_month){ 146 | $month_totals = array(); 147 | ?> 148 | 149 |
    150 | $split_data){ 152 | if(!isset($month_totals[$author_id]))$month_totals[$author_id]=0; 153 | $month_totals[$author_id]+= $item['earnt'] * $split_data['split']; 154 | $splits[$item_id]['authors'][$author_id]['total'] += $item['earnt'] * $split_data['split']; 155 | } 156 | ?> 157 |
  • 158 | sold for $ at rate of % earning a total of $. 159 |
  • 160 | 161 | $total){ ?> 162 |
  • earnt $
  • 163 | 164 |
165 | 166 | 167 |
168 |
169 |
170 | 171 |
172 | 173 | 174 |
175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /class.envato_scraper.php: -------------------------------------------------------------------------------- 1 | marketplaces)){ 30 | $this->main_marketplace = $main_marketplace; 31 | } 32 | if(!is_dir(_ENVATO_TMP_DIR)){ 33 | mkdir(_ENVATO_TMP_DIR); 34 | } 35 | if(!is_dir(_ENVATO_TMP_DIR) || !is_writable(_ENVATO_TMP_DIR)){ 36 | echo 'please make sure the temp directory '._ENVATO_TMP_DIR.' is writable by PHP scripts.'; 37 | } 38 | 39 | } 40 | 41 | /** 42 | * This pulls back list of all user items across all marketplaces (or specified marketplace) 43 | * 44 | * @param $user 45 | * @param array $from_marketplaces 46 | * @return array of items 47 | */ 48 | public function get_users_items($user,$from_marketplaces=array()){ 49 | $files = array(); 50 | if(!is_array($from_marketplaces))$from_marketplaces=array($from_marketplaces); 51 | foreach($from_marketplaces as $marketplace){ 52 | //http://marketplace.envato.com/api/v2/new-files-from-user:collis,themeforest.json 53 | $url = "http://marketplace.envato.com/api/v2/new-files-from-user:$user,$marketplace.json"; 54 | if(_ENVATO_DEBUG_MODE){ 55 | echo " Grabbing API url: $url
\n"; 56 | } 57 | $data = $this->get_url($url,array(),false); 58 | if(!empty($data)) { 59 | $json_data = json_decode($data, true); 60 | if(_ENVATO_DEBUG_MODE){ 61 | echo "data: ";print_r($json_data); 62 | } 63 | $files = array_merge($files,$json_data['new-files-from-user']); 64 | } 65 | } 66 | return $files; 67 | } 68 | 69 | public function authenticate_marketplace($url){ 70 | if(!in_array($url,$this->marketplaces))return false; 71 | $marketplace_tag = str_replace('.net','',str_replace('http://','',$url)); 72 | if(isset($this->authed_marketplaces[$marketplace_tag])){ 73 | $this->logged_in = true; 74 | }else{ 75 | $auth_check = $this->get_url('https://account.envato.com/sign_in?auto=true&to='.$marketplace_tag,array(),true); // todo - force this one? 76 | if(!$auth_check){ 77 | echo "failed to auth marketplace, try again."; 78 | return false; 79 | } 80 | 81 | preg_match('#name="authenticity_token" type="hidden" value="([^"]+)"#',$auth_check ,$matches); 82 | $authenticity_token = $matches[1]; 83 | 84 | preg_match('#name="token" type="hidden" value="([^"]+)"#',$auth_check ,$matches); 85 | $token = $matches[1]; 86 | 87 | 88 | if(_ENVATO_DEBUG_MODE){ 89 | echo "Authenticating $url to: ".'https://account.envato.com/sign_in?auto=true&to='.$marketplace_tag."
"; 90 | echo "Got auth: $authenticity_token and $token
"; 91 | } 92 | 93 | $post = array( 94 | 'utf8' => '✓', 95 | 'authenticity_token' => $authenticity_token, 96 | 'token' => $token 97 | ); 98 | $auth_check = $this->get_url('http://'.$marketplace_tag.'.net/sso/verify_token', $post, true); 99 | 100 | 101 | if(_ENVATO_DEBUG_MODE){ 102 | //echo "Auth check result: $auth_check
"; 103 | } 104 | 105 | if(preg_match('#/sign_out["\?]#',$auth_check)){ 106 | $this->authed_marketplaces[$marketplace_tag]=true; 107 | preg_match('##', $auth_check, $hits); 108 | $this->authenticity_tokens[$marketplace_tag]=$hits[1]; 109 | return true; 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | /** 116 | * returns true if the user is logged in 117 | * 118 | * @return bool 119 | */ 120 | public function is_logged_in(){ 121 | return $this->logged_in; 122 | } 123 | 124 | 125 | /** 126 | * do_login! The magic method that logs you into envato marketplaces. yew! 127 | * Even supports recaptcha if you're loading this script from a web browser :P 128 | * 129 | * @param string $username 130 | * @param string $password 131 | * @param int $try_number 132 | * @param bool $data 133 | * @return bool|int 134 | */ 135 | public function do_login($username,$password='',$try_number=0,$data=false){ 136 | 137 | if($this->logged_in)return true; 138 | 139 | $this->username = $username; 140 | if($this->waiting_on_recaptcha){ 141 | echo 'Waiting on recaptcha or manual password entry. Run script from browser.'; 142 | return false; 143 | } 144 | if(!$data){ 145 | $data = $this->_clean($this->get_url($this->main_marketplace.'/category/all',array(),true)); 146 | } 147 | 148 | // check if we are logged in or not. 149 | // simply look for the string logout and Log Out 150 | if($try_number>1){ 151 | // TODO: handle if envato is down for maintenance 152 | echo "Unable to login. Sorry, please try again shortly."; 153 | return false; 154 | }else if(preg_match('#/sign_out["\?]#',$data)){ 155 | // if sign_out is present on the page then we are logged in 156 | // new redirect hack with new account centre setup 157 | $this->logged_in = $this->authenticate_marketplace($this->main_marketplace); 158 | }else if($username){ 159 | 160 | $data = $this->get_url('https://account.envato.com'); 161 | $auth_token = ''; 162 | if(preg_match('#name="authenticity_token" type="hidden" value="([^"]+)"#',$data,$matches)){ 163 | $auth_token = $matches[1]; 164 | if($auth_token){ 165 | 166 | if(isset($_POST['envatopassword'.md5($this->main_marketplace)])){ 167 | $password = $_POST['envatopassword'.md5($this->main_marketplace)]; 168 | } 169 | if(!$password){ 170 | // prompt for password 171 | $this->waiting_on_recaptcha=true; //re-use this feature from the captcha thingey. 172 | ?> 173 |
174 |
175 | Enter Envato Password for account "":
176 | Enter Envato Two-Factor for account "" (optional):
177 | 178 |
179 | $username, 184 | "password"=>$password, 185 | "to" => 'codecanyon', 186 | "state" => '', 187 | "authenticity_token" => $auth_token, 188 | "utf8" => '✓', 189 | "commit" => 'Sign+In', 190 | "recaptcha_version" => '2', 191 | "recaptcha_site_key" => '6LcpTQITAAAAACIt_xhfOTWIZnT66AeAoy5xzgFG', 192 | //"from_header_bar"=>"true", 193 | ); 194 | if(isset($_REQUEST['envatopasswordtwofactor'.md5($this->main_marketplace)])){ 195 | $post_data['authentication_code'] = $_REQUEST['envatopasswordtwofactor'.md5($this->main_marketplace)]; 196 | } 197 | 198 | if(isset($_POST['recaptcha'.md5($this->main_marketplace)])){ 199 | $post_data["recaptcha_challenge_field"]=$_POST['recaptcha'.md5($this->main_marketplace)]; 200 | $post_data["recaptcha_response_field"]='manual_challenge'; 201 | unset($_POST['recaptcha'.md5($this->main_marketplace)]); 202 | } 203 | if(_ENVATO_DEBUG_MODE){ 204 | echo "Login attempt $try_number with username: ".$username."
"; 205 | } 206 | $url = "https://account.envato.com/sign_in"; 207 | if($_POST['go'] == 'Submit'){ 208 | $data = $this->get_url($url,$post_data,true); 209 | } else { 210 | $data = $this->get_url($url,$post_data,true); 211 | } 212 | if(_ENVATO_DEBUG_MODE){ 213 | file_put_contents(_ENVATO_TMP_DIR."debug-envato_login-".$try_number.".html",$data); 214 | echo "Saved LOGIN ATTEMPT file at: "._ENVATO_TMP_DIR."debug-envato_login-".$try_number.".html
"; 215 | } 216 | if ( preg_match( '#name="authenticity_token" type="hidden" value="([^"]+)"#', $data, $matches1 ) ) { 217 | if ( preg_match( '#name="token" type="hidden" value="([^"]+)"#', $data, $matches2 ) ) { 218 | if(_ENVATO_DEBUG_MODE){ 219 | echo "Got the verify_token after the /sign_in attempt, processing that callback
"; 220 | } 221 | $post_data = array( 222 | "authenticity_token" => $matches1[1], 223 | "token" => $matches2[1], 224 | "utf8" => '✓', 225 | ); 226 | $data = $this->get_url('http://codecanyon.net/sso/verify_token',$post_data,true); 227 | if(_ENVATO_DEBUG_MODE){ 228 | file_put_contents(_ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir-postback.html",$data); 229 | echo "Saved LOGIN ATTEMPT REDIRECT ( http://codecanyon.net/sso/verify_token ) file at: "._ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir-postback.html
"; 230 | } 231 | if(preg_match('#/sign_out["\?]#',$data)){ 232 | // if sign_out is present on the page then we are logged in 233 | // new redirect hack with new account centre setup 234 | $this->logged_in = $this->authenticate_marketplace($this->main_marketplace); 235 | return $this->logged_in; 236 | } 237 | } 238 | } 239 | $json_test = @json_decode($data,true); 240 | if(is_array($json_test) && isset($json_test['state']) && $json_test['state'] == 'ok' && isset($json_test['redirect']) && strlen($json_test['redirect']) > 10){ 241 | $data_redirect = $this->get_url($json_test['redirect'],array(),true); 242 | if(_ENVATO_DEBUG_MODE){ 243 | file_put_contents(_ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir.html",$data_redirect); 244 | echo "Saved LOGIN ATTEMPT REDIRECT ( ".$json_test['redirect']." ) file at: "._ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir.html
"; 245 | } 246 | if(strpos($data_redirect,'Now signing you into')) { 247 | // redirect worked! we're signing in :) 248 | /*
249 | 250 |

251 | Now signing you into CodeCanyon. 252 | if you aren't automatically redirected. 253 |

254 |
*/ 255 | if ( preg_match( '#name="authenticity_token" type="hidden" value="([^"]+)"#', $data_redirect, $matches1 ) ) { 256 | if ( preg_match( '#name="token" type="hidden" value="([^"]+)"#', $data_redirect, $matches2 ) ) { 257 | if(_ENVATO_DEBUG_MODE){ 258 | echo "Got verify_token after json redirect
"; 259 | } 260 | $post_data = array( 261 | "authenticity_token" => $matches1[1], 262 | "token" => $matches2[1], 263 | "utf8" => '✓', 264 | ); 265 | $new_url = preg_replace('#/callback\?.*$#','/verify_token',$json_test['redirect']); 266 | $data = $this->get_url($new_url,$post_data,true); 267 | if(_ENVATO_DEBUG_MODE){ 268 | file_put_contents(_ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir-postback.html",$data); 269 | echo "Saved LOGIN ATTEMPT REDIRECT ( ".$new_url." ) file at: "._ENVATO_TMP_DIR."debug-envato_login-".$try_number."-redir-postback.html
"; 270 | } 271 | if(preg_match('#/sign_out["\?]#',$data)){ 272 | // if sign_out is present on the page then we are logged in 273 | // new redirect hack with new account centre setup 274 | $this->logged_in = $this->authenticate_marketplace($this->main_marketplace); 275 | return $this->logged_in; 276 | } 277 | } 278 | } 279 | } 280 | 281 | echo "Redirect failed to load with this response:

$data_redirect "; 282 | return false; 283 | } 284 | if(preg_match('#temporarily locked out#',$data)){ 285 | echo "Sorry, temporarily locked out for too many failed login attempts."; 286 | return 0; 287 | }else if (preg_match('#recaptcha/api/noscript#',$data)){ 288 | $this->waiting_on_recaptcha=true; 289 | echo "Sorry, too many failed envato login attempts on ".$this->main_marketplace.". Please enter the re-captcha code below.
"; 290 | // '; 293 | ?> 294 |
295 |
296 | Enter Code: 297 | $val){ 298 | if(strpos($key,'recaptcha')!==false || strpos($key,'envatopassword')!==false){ 299 | ?> 300 | 301 | 304 |
305 | do_login($username,$password,$try_number+1,$data); 316 | }else { 317 | // no username or password, set, return false so we prompt them to login. 318 | return false; 319 | } 320 | 321 | // $data now contains our home page in logged in version. 322 | // how much cash do we have? 323 | //$4,829.40 324 | /*if(preg_match('#class="user_balance">\$([^<]+)<#',$data,$matches)){ 325 | print_r($matches); 326 | $this->account_balance = preg_replace('/[^\.\d]/','',$matches[1]); 327 | }*/ 328 | return $this->logged_in; 329 | } 330 | 331 | /** 332 | * 333 | * This method will return an array of purchased items. 334 | * 335 | * @param string $url the url from your email e.g. http://codecanyon.net/user/USERNAME?pm_key=OTgxMjYx%0B 336 | * 337 | * @return array 338 | */ 339 | public function verify_email_link($url){ 340 | 341 | $urlparts = parse_url($url); 342 | 343 | $purchases = array(); 344 | 345 | //login always on the main marketplace 346 | $data = $this->_clean($this->get_url($this->main_marketplace.$urlparts['path'].'?'.$urlparts['query'])); 347 | 348 | //if we found some purchased files 349 | if(preg_match('#

Purchases of your files