1#!/usr/bin/env php 2 3<?php 4 5ini_set('display_errors', 'On'); 6error_reporting(E_ALL); 7 8set_time_limit(0); 9set_include_path(get_include_path() . PATH_SEPARATOR . "../../bindings/php"); 10 11include 'megaapi.php'; 12 13if (file_exists('vendor/autoload.php')) 14 require_once('vendor/autoload.php'); 15else 16 require_once('Symfony/autoload.php'); 17 18use Symfony\Component\Console\Shell; 19use Symfony\Component\Console\Application; 20use Symfony\Component\Console\Command\Command; 21use Symfony\Component\Console\Input\InputInterface; 22use Symfony\Component\Console\Output\OutputInterface; 23use Symfony\Component\Console\Input\InputArgument; 24use Symfony\Component\Console\Input\InputOption; 25 26if (!PHP_ZTS) 27{ 28 print("WARNING: Your version of PHP is not thread-safe (ZTS).\nThe MEGA SDK uses a worker thread to send callbacks to apps so this app could crash for that reason.\n"); 29} 30 31$megaapi = NULL; 32$cwd = NULL; 33 34class AppListener implements MegaListenerInterface 35{ 36 public function onRequestStart($megaApi, $request) 37 { 38 } 39 40 public function onRequestFinish($megaApi, $request, $error) 41 { 42 global $cwd; 43 44 if($error->getErrorCode() != MegaError::API_OK) 45 { 46 print("INFO: Request finished with error ( " . $request . " ) Result: " . $error . "\n"); 47 print("MEGA > "); 48 return; 49 } 50 51 $requestType = $request->getType(); 52 if($requestType == MegaRequest::TYPE_LOGIN) 53 { 54 print("Fetchning nodes. Please wait...\n"); 55 print("MEGA > "); 56 $megaApi->fetchNodes(); 57 } 58 else if($requestType == MegaRequest::TYPE_FETCH_NODES) 59 { 60 print("Account correctly loaded\n"); 61 print("MEGA > "); 62 $cwd = $megaApi->getRootNode(); 63 } 64 else if($requestType == MegaRequest::TYPE_EXPORT) 65 { 66 print("INFO: Exported link: " . $request->getLink() . "\n"); 67 print("MEGA > "); 68 } 69 else if($requestType == MegaRequest::TYPE_ACCOUNT_DETAILS) 70 { 71 $accountDetails = $request->getMegaAccountDetails(); 72 print("INFO: Account details received\n"); 73 print("Account e-mail: " . $megaApi->getMyEmail() . "\n"); 74 print("Storage: " . $accountDetails->getStorageUsed() . " of " . $accountDetails->getStorageMax() . 75 " (" . (100 * $accountDetails->getStorageUsed() / $accountDetails->getStorageMax()) . "%)\n"); 76 print("Pro level: " . $accountDetails->getProLevel() . "\n"); 77 print("MEGA > "); 78 } 79 } 80 81 public function onRequestTemporaryError($megaApi, $request, $error) 82 { 83 print("INFO: Request temporary error ( " . $request . " ) Error: " + $error . "\n"); 84 } 85 86 public function onTransferStart($megaApi, $transfer) 87 { 88 print("INFO: Transfer start ( " . $transfer . " " . $transfer->getFileName() . " )\n"); 89 } 90 91 public function onTransferFinish($megaApi, $transfer, $error) 92 { 93 print("INFO: Transfer finished ( " . $transfer . " " . $transfer->getFileName() . " ) Result: " . $error . "\n"); 94 print("MEGA > "); 95 } 96 97 public function onTransferUpdate($megaApi, $transfer) 98 { 99 print("INFO: Transfer update ( " . $transfer . " " . $transfer->getFileName() . " ) Progress: " . $transfer->getTransferredBytes()/1024 ." KB of " . $transfer->getTotalBytes()/1024 . " KB, " . $transfer->getSpeed()/1024 . " KB/s\n"); 100 } 101 102 public function onTransferTemporaryError($megaApi, $request, $error) 103 { 104 print("INFO: Transfer temporary error ( " . $transfer . " " . $transfer->getFileName() . " ) Error: " . $error . "\n"); 105 } 106 107 public function onUsersUpdate($megaApi, $users) 108 { 109 } 110 111 public function onNodesUpdate($megaApi, $nodes) 112 { 113 global $cwd; 114 115 if($nodes != NULL) 116 { 117 print("INFO: Nodes updated ( " . count($nodes) . " )\n"); 118 print("MEGA > "); 119 } 120 else 121 $cwd = $megaApi->getRootNode(); 122 } 123 124 public function onReloadNeeded($megaApi) 125 { 126 127 } 128} 129 130class LoginCommand extends Command 131{ 132 protected function configure() 133 { 134 $this->setName('login'); 135 $this->setDescription('Log in to a MEGA account'); 136 $this->addArgument('email', InputArgument::REQUIRED, 'Email of the account'); 137 $this->addArgument('password', InputArgument::REQUIRED, 'Password of the account'); 138 } 139 140 protected function execute(InputInterface $input, OutputInterface $output) 141 { 142 global $megaapi; 143 144 $email = $input->getArgument('email'); 145 $password = $input->getArgument('password'); 146 $megaapi->login($email, $password); 147 } 148} 149 150class LogoutCommand extends Command 151{ 152 protected function configure() 153 { 154 $this->setName('logout'); 155 $this->setDescription('Log out a MEGA account'); 156 } 157 158 protected function execute(InputInterface $input, OutputInterface $output) 159 { 160 global $megaapi; 161 global $cwd; 162 163 $megaapi->logout(); 164 $cwd = null; 165 } 166} 167 168class LsCommand extends Command 169{ 170 protected function configure() 171 { 172 $this->setName('ls'); 173 $this->setDescription('List a MEGA folder'); 174 $this->addArgument('path', InputArgument::OPTIONAL, 'folder path'); 175 } 176 177 protected function execute(InputInterface $input, OutputInterface $output) 178 { 179 global $megaapi; 180 global $cwd; 181 182 if($cwd == null) 183 { 184 $output->writeln("Not logged in"); 185 return; 186 } 187 188 $path = $input->getArgument('path'); 189 if ($path) 190 { 191 $folder = $megaapi->getNodeByPath($path, $cwd); 192 } 193 else 194 { 195 $folder = $cwd; 196 } 197 198 199 $output->writeln(" ."); 200 if($megaapi->getParentNode($folder) != NULL) 201 { 202 $output->writeln(" .."); 203 } 204 205 $children = $megaapi->getChildren($folder); 206 foreach($children as $node) 207 { 208 $output->write(" " . $node->getName()); 209 if($node->getType() == MegaNode::TYPE_FILE) 210 { 211 $output->writeln(" (" . $node->getSize() . " bytes)"); 212 } 213 else 214 { 215 $output->writeln(" (folder)"); 216 } 217 } 218 } 219} 220 221class MkdirCommand extends Command 222{ 223 protected function configure() 224 { 225 $this->setName('mkdir'); 226 $this->setDescription('Create a folder'); 227 $this->addArgument('name', InputArgument::REQUIRED, 'folder name'); 228 } 229 230 protected function execute(InputInterface $input, OutputInterface $output) 231 { 232 global $megaapi; 233 global $cwd; 234 235 if($cwd == null) 236 { 237 $output->writeln("Not logged in"); 238 return; 239 } 240 241 $name = $input->getArgument('name'); 242 $megaapi->createFolder($name, $cwd); 243 } 244} 245 246class CdCommand extends Command 247{ 248 protected function configure() 249 { 250 $this->setName('cd'); 251 $this->setDescription('Change the current directory'); 252 $this->addArgument('path', InputArgument::REQUIRED, 'new current directory'); 253 } 254 255 protected function execute(InputInterface $input, OutputInterface $output) 256 { 257 global $megaapi; 258 global $cwd; 259 260 if($cwd == null) 261 { 262 $output->writeln("Not logged in"); 263 return; 264 } 265 266 $path = $input->getArgument('path'); 267 $new = $megaapi->getNodeByPath($path, $cwd); 268 if($new == null) 269 { 270 $output->writeln("Invalid path"); 271 return; 272 } 273 274 $cwd = $new; 275 } 276} 277 278class MvCommand extends Command 279{ 280 protected function configure() 281 { 282 $this->setName('mv'); 283 $this->setDescription('Move a file/folder'); 284 $this->addArgument('source', InputArgument::REQUIRED, 'Source file/folder'); 285 $this->addArgument('destination', InputArgument::REQUIRED, 'Destination file/folder'); 286 } 287 288 protected function execute(InputInterface $input, OutputInterface $output) 289 { 290 global $megaapi; 291 global $cwd; 292 293 if($cwd == null) 294 { 295 $output->writeln("Not logged in"); 296 return; 297 } 298 299 $source = $input->getArgument('source'); 300 $name = $input->getArgument('destination'); 301 302 $srcNode = $megaapi->getNodeByPath($source, $cwd); 303 if($srcNode == null) 304 { 305 $output->writeln($source . ": No such file or directory"); 306 return; 307 } 308 309 $dstNode = $megaapi->getNodeByPath($name, $cwd); 310 if(($dstNode != null) && $dstNode->isFile()) 311 { 312 $output->writeln($name . ": Not a directory"); 313 return; 314 } 315 316 if($dstNode != null) 317 { 318 $megaapi->moveNode($srcNode, $dstNode); 319 return; 320 } 321 322 if(strpos($name,"/") !== false || strpos($name,"\\") !== false) 323 { 324 $str1 = strrchr($name, "/"); 325 $str2 = strrchr($name, "\\"); 326 $index = null; 327 328 if($str2 == FALSE || strlen($str1) < strlen($str2)) 329 { 330 echo "A\n"; 331 $index = strlen($name) - strlen($str1); 332 } 333 else 334 { 335 echo "B\n"; 336 $index = strlen($name) - strlen($str2); 337 } 338 339 $path = substr($name, 0, $index); 340 $base = $megaapi->getNodeByPath($path, $cwd); 341 $name = substr($name, $index+1); 342 343 echo "INDEX: " . $index . "\n"; 344 echo "str1: " . $str1 . "\n"; 345 echo "str2: " . $str2 . "\n"; 346 echo "PATH: " . $path . "\n"; 347 echo "NAME: " . $name . "\n"; 348 349 if($base == null) 350 { 351 $output->writeln($path . ": Not such directory"); 352 return; 353 } 354 355 if($base->isFile()) 356 { 357 $output->writeln($path . ": Not a directory"); 358 return; 359 } 360 361 $megaapi->moveNode($srcNode, $base); 362 if(strlen($name) != 0) 363 { 364 $megaapi->renameNode($srcNode, $name); 365 } 366 return; 367 } 368 369 if($dstNode == null) 370 { 371 $megaapi->renameNode($srcNode, $name); 372 } 373 } 374} 375 376class PwdCommand extends Command 377{ 378 protected function configure() 379 { 380 $this->setName('pwd'); 381 $this->setDescription('Get the current working directory'); 382 } 383 384 protected function execute(InputInterface $input, OutputInterface $output) 385 { 386 global $megaapi; 387 global $cwd; 388 389 if($cwd == null) 390 { 391 $output->writeln("Not logged in"); 392 return; 393 } 394 395 $output->writeln($megaapi->getNodePath($cwd)); 396 } 397} 398 399class RmCommand extends Command 400{ 401 protected function configure() 402 { 403 $this->setName('rm'); 404 $this->setDescription('Remove a file/folder'); 405 $this->addArgument('path', InputArgument::REQUIRED, 'Path to file/folder to delete'); 406 } 407 408 protected function execute(InputInterface $input, OutputInterface $output) 409 { 410 global $megaapi; 411 global $cwd; 412 413 if($cwd == null) 414 { 415 $output->writeln("Not logged in"); 416 return; 417 } 418 419 $path = $input->getArgument('path'); 420 $node = $megaapi->getNodeByPath($path, $cwd); 421 if($node == null) 422 { 423 $output->writeln("Invalid path"); 424 return; 425 } 426 427 $megaapi->remove($node); 428 } 429} 430 431class GetCommand extends Command 432{ 433 protected function configure() 434 { 435 $this->setName('get'); 436 $this->setDescription('Download a file from MEGA'); 437 $this->addArgument('path', InputArgument::REQUIRED, 'Path to the file'); 438 } 439 440 protected function execute(InputInterface $input, OutputInterface $output) 441 { 442 global $megaapi; 443 global $cwd; 444 445 if($cwd == null) 446 { 447 $output->writeln("Not logged in"); 448 return; 449 } 450 451 $path = $input->getArgument('path'); 452 $node = $megaapi->getNodeByPath($path, $cwd); 453 if($node == null) 454 { 455 $output->writeln("Invalid path"); 456 return; 457 } 458 459 if(!$node->isFile()) 460 { 461 $output->writeln("Not a file"); 462 return; 463 } 464 465 $megaapi->startDownload($node, "./"); 466 } 467} 468 469class PutCommand extends Command 470{ 471 protected function configure() 472 { 473 $this->setName('put'); 474 $this->setDescription('Upload a file to MEGA'); 475 $this->addArgument('path', InputArgument::REQUIRED, 'Path to the local file'); 476 } 477 478 protected function execute(InputInterface $input, OutputInterface $output) 479 { 480 global $megaapi; 481 global $cwd; 482 483 if($cwd == null) 484 { 485 $output->writeln("Not logged in"); 486 return; 487 } 488 489 $path = $input->getArgument('path'); 490 $megaapi->startUpload($path, $cwd); 491 } 492} 493 494class ExportCommand extends Command 495{ 496 protected function configure() 497 { 498 $this->setName('export'); 499 $this->setDescription('Generate a public link'); 500 $this->addArgument('path', InputArgument::REQUIRED, 'Path to the file/folder in MEGA'); 501 } 502 503 protected function execute(InputInterface $input, OutputInterface $output) 504 { 505 global $megaapi; 506 global $cwd; 507 508 if($cwd == null) 509 { 510 $output->writeln("Not logged in"); 511 return; 512 } 513 514 $path = $input->getArgument('path'); 515 $node = $megaapi->getNodeByPath($path, $cwd); 516 if($node == null) 517 { 518 $output->writeln("Invalid path"); 519 return; 520 } 521 522 $megaapi->exportNode($node); 523 } 524} 525 526class ImportCommand extends Command 527{ 528 protected function configure() 529 { 530 $this->setName('import'); 531 $this->setDescription('Import a MEGA public file link'); 532 $this->addArgument('link', InputArgument::REQUIRED, 'Public MEGA file link'); 533 } 534 535 protected function execute(InputInterface $input, OutputInterface $output) 536 { 537 global $megaapi; 538 global $cwd; 539 540 if($cwd == null) 541 { 542 $output->writeln("Not logged in"); 543 return; 544 } 545 546 $link = $input->getArgument('link'); 547 $megaapi->importFileLink($link, $cwd); 548 } 549} 550 551class PasswdCommand extends Command 552{ 553 protected function configure() 554 { 555 $this->setName('passwd'); 556 $this->setDescription('Change the access password'); 557 $this->addArgument('current_password', InputArgument::REQUIRED, 'Current password'); 558 $this->addArgument('new_password', InputArgument::REQUIRED, 'New password'); 559 $this->addArgument('repeat_new_password', InputArgument::REQUIRED, 'New password'); 560 } 561 562 protected function execute(InputInterface $input, OutputInterface $output) 563 { 564 global $megaapi; 565 global $cwd; 566 567 if($cwd == null) 568 { 569 $output->writeln("Not logged in"); 570 return; 571 } 572 573 $current_password = $input->getArgument('current_password'); 574 $new_password = $input->getArgument('new_password'); 575 $repeat_new_password = $input->getArgument('repeat_new_password'); 576 577 if($new_password != $repeat_new_password) 578 { 579 $output->writeln("Error: Password mismatch"); 580 return; 581 } 582 583 $megaapi->changePassword($current_password, $new_password); 584 } 585} 586 587class WhoamiCommand extends Command 588{ 589 protected function configure() 590 { 591 $this->setName('whoami'); 592 $this->setDescription('Show info about the current user'); 593 } 594 595 protected function execute(InputInterface $input, OutputInterface $output) 596 { 597 global $megaapi; 598 global $cwd; 599 600 if($cwd == null) 601 { 602 $output->writeln("Not logged in"); 603 return; 604 } 605 606 $output->writeln($megaapi->getMyEmail()); 607 $megaapi->getAccountDetails(); 608 } 609} 610 611class MountCommand extends Command 612{ 613 protected function configure() 614 { 615 $this->setName('mount'); 616 $this->setDescription('Show incoming shares'); 617 } 618 619 protected function execute(InputInterface $input, OutputInterface $output) 620 { 621 global $megaapi; 622 global $cwd; 623 624 if($cwd == null) 625 { 626 $output->writeln("Not logged in"); 627 return; 628 } 629 630 $output->writeln("INFO: INSHARES:"); 631 $users = $megaapi->getContacts(); 632 foreach($users as $user) 633 { 634 $megaapi->getInShares(); 635 $inshares = $megaapi->getInShares($user); 636 foreach($inshares as $share) 637 { 638 $output->writeln("INFO: INSHARE on " . $user->getEmail() . " " . $share->getName() . " Access level: " . $megaapi->getAccess($share)); 639 } 640 } 641 } 642} 643 644class ExitCommand extends Command 645{ 646 protected function configure() 647 { 648 $this->setName('exit'); 649 $this->setDescription('Exit the app'); 650 } 651 652 protected function execute(InputInterface $input, OutputInterface $output) 653 { 654 exit(0); 655 } 656} 657 658class QuitCommand extends ExitCommand 659{ 660 protected function configure() 661 { 662 $this->setName('quit'); 663 $this->setDescription('Exit the app'); 664 } 665} 666 667MegaApi::setLogLevel(MegaApi::LOG_LEVEL_ERROR); 668$applistener = new AppListener(); 669 670$megaapi = new MegaApiPHP("API_KEY", "PHP megacli"); 671$megaapi->addListener($applistener); 672 673$application = new Application('MEGA', 'PHP'); 674$application->add(new LoginCommand()); 675$application->add(new LogoutCommand()); 676$application->add(new LsCommand()); 677$application->add(new MkdirCommand()); 678$application->add(new CdCommand()); 679$application->add(new PwdCommand()); 680$application->add(new RmCommand()); 681$application->add(new GetCommand()); 682$application->add(new PutCommand()); 683$application->add(new ExitCommand()); 684$application->add(new QuitCommand()); 685$application->add(new ExportCommand()); 686$application->add(new ImportCommand()); 687$application->add(new WhoamiCommand()); 688$application->add(new PasswdCommand()); 689$application->add(new MountCommand()); 690$application->add(new MvCommand()); 691 692$shell = new Shell($application); 693$shell->run(); 694 695?> 696 697 698