summaryrefslogtreecommitdiffstats
path: root/pyLoadCli.py
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2010-08-29 18:42:09 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2010-08-29 18:42:09 +0200
commitfe017986229a92a29541329650b25e1b326dc87f (patch)
treeafb4b74c4ce62e8d1b8940eff723e1a9094f9f17 /pyLoadCli.py
parentplugin updater (diff)
downloadpyload-fe017986229a92a29541329650b25e1b326dc87f.tar.xz
moved interfaces
Diffstat (limited to 'pyLoadCli.py')
-rwxr-xr-xpyLoadCli.py554
1 files changed, 554 insertions, 0 deletions
diff --git a/pyLoadCli.py b/pyLoadCli.py
new file mode 100755
index 000000000..1bfae7238
--- /dev/null
+++ b/pyLoadCli.py
@@ -0,0 +1,554 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#Copyright (C) 2010 RaNaN
+#
+#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/>.
+#
+###
+from getopt import GetoptError
+from getopt import getopt
+import gettext
+from itertools import islice
+import os
+import os.path
+from os.path import join
+from os.path import abspath
+from os.path import dirname
+import sys
+from sys import exit
+import threading
+import time
+from time import sleep
+import xmlrpclib
+from traceback import print_exc
+
+
+from module import InitHomeDir
+from module.ConfigParser import ConfigParser
+
+import codecs
+
+sys.stdout = codecs.getwriter("utf8")(sys.stdout, errors = "replace")
+
+if sys.stdout.encoding.lower().startswith("utf"):
+ conv = unicode
+else:
+ conv = str
+
+class pyLoadCli:
+ def __init__(self, server_url, add=False):
+ self.core = xmlrpclib.ServerProxy(server_url, allow_none=True)
+ self.getch = _Getch()
+ self.input = ""
+ self.pos = [0, 0, 0]
+ self.inputline = 0
+ self.menuline = 0
+
+ self.new_package = {}
+
+ try:
+ self.core.get_server_version()
+ except:
+ print _("pyLoadCore not running")
+ exit()
+
+ if add:
+ self.core.add_package(add, [add])
+ print _("Linklist added")
+ exit()
+
+ self.links_added = 0
+
+ os.system("clear")
+ self.println(1, blue("py") + yellow("Load") + white(_(" Command Line Interface")))
+ self.println(2, "")
+
+
+ self.file_list = {}
+
+ self.thread = RefreshThread(self)
+ self.thread.start()
+
+ self.start()
+
+ def start(self):
+ while True:
+ #inp = raw_input()
+ inp = self.getch.impl()
+ if ord(inp) == 3:
+ os.system("clear")
+ sys.exit() # ctrl + c
+ elif ord(inp) == 13:
+ try:
+ self.handle_input()
+ except Exception, e:
+ self.println(2, red(conv(e)))
+ self.input = "" #enter
+ self.print_input()
+ elif ord(inp) == 127:
+ self.input = self.input[:-1] #backspace
+ self.print_input()
+ elif ord(inp) == 27: #ugly symbol
+ pass
+ else:
+ self.input += inp
+ self.print_input()
+
+ def format_time(self, seconds):
+ seconds = int(seconds)
+
+ hours, seconds = divmod(seconds, 3600)
+ minutes, seconds = divmod(seconds, 60)
+ return "%.2i:%.2i:%.2i" % (hours, minutes, seconds)
+
+ def format_size(self, size):
+ return conv(size / 1024 ** 2) + " MiB"
+
+ def println(self, line, content):
+ print "\033[" + conv(line) + ";0H\033[2K" + content + "\033[" + conv((self.inputline if self.inputline > 0 else self.inputline + 1) - 1) + ";0H"
+
+ def print_input(self):
+ self.println(self.inputline, white(" Input: ") + self.input)
+ self.println(self.inputline + 1, "")
+ self.println(self.inputline + 2, "")
+ self.println(self.inputline + 3, "")
+ self.println(self.inputline + 4, "")
+
+ def refresh(self):
+ """Handle incoming data"""
+ data = self.core.status_downloads()
+ #print updated information
+ print "\033[J" #clear screen
+ self.println(1, blue("py") + yellow("Load") + white(_(" Command Line Interface")))
+ self.println(2, "")
+ self.println(3, white(_("%s Downloads:") % (len(data))))
+ line = 4
+ speed = 0
+ for download in data:
+ if download["status"] == 12: # downloading
+ percent = download["percent"]
+ z = percent / 4
+ speed += download['speed']
+ self.println(line, cyan(download["name"]))
+ line += 1
+ self.println(line, blue("[") + yellow(z * "#" + (25-z) * " ") + blue("] ") + green(conv(percent) + "%") + _(" Speed: ") + green(conv(int(download['speed'])) + " kb/s") + _(" Size: ") + green(download['format_size']) + _(" Finished in: ") + green(download['format_eta']) + _(" ID: ") + green(conv(download['id'])))
+ line += 1
+ if download["status"] == 5:
+ self.println(line, cyan(download["name"]))
+ line += 1
+ self.println(line, _("waiting: ") + green(download["format_wait"]) )
+ line += 1
+ self.println(line, "")
+ line += 1
+ status = self.core.status_server()
+ if status['pause']:
+ self.println(line, _("Status: ") + red("paused") + _(" total Speed: ") + red(conv(int(speed)) + " kb/s") + _(" Files in queue: ") + red(conv(status["queue"])))
+ else:
+ self.println(line, _("Status: ") + red("running") + _(" total Speed: ") + red(conv(int(speed)) + " kb/s") + _(" Files in queue: ") + red(conv(status["queue"])))
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.menuline = line
+
+ self.build_menu()
+ #
+ self.file_list = data
+
+ def build_menu(self):
+ line = self.menuline
+ self.println(line, white(_("Menu:")))
+ line += 1
+ if self.pos[0] == 0:# main menu
+ self.println(line, "")
+ line += 1
+ self.println(line, mag("1.") + _(" Add Links"))
+ line += 1
+ self.println(line, mag("2.") + _(" Manage Links"))
+ line += 1
+ self.println(line, mag("3.") + _(" (Un)Pause Server"))
+ line += 1
+ self.println(line, mag("4.") + _(" Kill Server"))
+ line += 1
+ self.println(line, mag("5.") + _(" Quit"))
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, "")
+ elif self.pos[0] == 1:#add links
+
+ if self.pos[1] == 0:
+ self.println(line, "")
+ line += 1
+ self.println(line, _("Name your package."))
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, mag("0.") + _(" back to main menu"))
+ line += 1
+ self.println(line, "")
+
+ else:
+ self.println(line, _("Package: %s") % self.new_package['name'])
+ line += 1
+ self.println(line, _("Parse the links you want to add."))
+ line += 1
+ self.println(line, _("Type %s when done.") % mag("END"))
+ line += 1
+ self.println(line, _("Links added: ") + mag(conv(self.links_added)))
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, "")
+ line += 1
+ self.println(line, mag("0.") + _(" back to main menu"))
+ line += 1
+ self.println(line, "")
+ elif self.pos[0] == 2:#remove links
+ if self.pos[1] == 0:
+ pack = self.core.get_queue()
+ self.println(line, _("Type d(number of package) to delete a package, r to restart, or w/o d,r to look into it."))
+ line += 1
+ i = 0
+ for id, value in islice(pack.iteritems(), self.pos[2], self.pos[2] + 5):
+ try:
+ self.println(line, mag(conv(id)) + ": " + value['name'])
+ line += 1
+ i += 1
+ except Exception, e:
+ pass
+ for x in range(5-i):
+ self.println(line, "")
+ line += 1
+
+ else:
+ links = self.core.get_package_data(self.pos[1])
+ self.println(line, _("Type d(number) of the link you want to delete or r(number) to restart."))
+ line += 1
+ i = 0
+ for id, value in islice(links["links"].iteritems(), self.pos[2], self.pos[2] + 5):
+ try:
+
+ self.println(line, mag(conv(id)) + ": %s | %s | %s" % (value['name'], value['statusmsg'], value['plugin']))
+ line += 1
+ i += 1
+
+ except Exception, e:
+ pass
+ for x in range(5-i):
+ self.println(line, "")
+ line += 1
+
+ self.println(line, mag("p") + _(" - previous") + " | " + mag("n") + _(" - next"))
+ line += 1
+ self.println(line, mag("0.") + _(" back to main menu"))
+
+ self.inputline = line + 1
+ self.print_input()
+
+ def handle_input(self):
+ inp = self.input.strip()
+ if inp == "0":
+ self.pos = [0, 0, 0]
+ self.build_menu()
+ return True
+
+ if self.pos[0] == 0:
+ if inp == "1":
+ self.links_added = 0
+ self.pos[0] = 1
+ elif inp == "2":
+ self.pos[0] = 2
+ self.pos[1] = 0
+ elif inp == "3":
+ self.core.toggle_pause()
+ elif inp == "4":
+ self.core.kill()
+ sys.exit()
+ elif inp == "5":
+ os.system('clear')
+ sys.exit()
+
+ elif self.pos[0] == 1: #add links
+ if self.pos[1] == 0:
+ self.new_package['name'] = inp
+ self.new_package['links'] = []
+ self.pos[1] = 1
+ else:
+ if inp == "END":
+ self.core.add_package(self.new_package['name'], self.new_package['links'], 1) # add package
+ self.pos = [0, 0, 0]
+ self.links_added = 0
+ else: #@TODO validation
+ self.new_package['links'].append(inp)
+ self.links_added += 1
+
+ elif self.pos[0] == 2: #remove links
+ if self.pos[1] == 0:
+ if inp.startswith("d"):
+ if inp.find("-") > -1:
+ self.core.del_packages(range(*map(int, inp[1:].split("-"))))
+ else:
+ self.core.del_packages([int(inp[1:])])
+ if inp.startswith("r"):
+ self.core.restart_package(int(inp[1:]))
+ elif inp != "p" and inp != "n":
+ self.pos[1] = int(inp)
+ self.pos[2] = 0
+ elif inp.startswith('r'):
+ if inp.find("-") > -1:
+ map(self.core.restart_file, range(*map(int, inp[1:].split("-"))))
+ else:
+ self.core.restart_file(int(inp[1:]))
+ elif inp.startswith('d') and inp != "p" and inp != "n":
+ if inp.find("-") > -1:
+ self.core.del_links(range(*map(int, inp[1:].split("-"))))
+ else:
+ self.core.del_links([int(inp[1:])])
+ if inp == "p":
+ self.pos[2] -= 5
+ elif inp == "n":
+ self.pos[2] += 5
+
+ self.build_menu()
+
+class RefreshThread(threading.Thread):
+ def __init__(self, cli):
+ threading.Thread.__init__(self)
+ self.setDaemon(True)
+ self.cli = cli
+
+ def run(self):
+ while True:
+ sleep(1)
+ try:
+ self.cli.refresh()
+ except Exception, e:
+ self.cli.println(2, red(conv(e)))
+ self.cli.pos[1] = 0
+ self.cli.pos[2] = 0
+ print_exc()
+
+
+
+
+class _Getch:
+ """
+ Gets a single character from standard input. Does not echo to
+ the screen.
+ """
+ def __init__(self):
+ try:
+ self.impl = _GetchWindows()
+ except ImportError:
+ try:
+ self.impl = _GetchMacCarbon()
+ except(AttributeError, ImportError):
+ self.impl = _GetchUnix()
+
+ def __call__(self): return self.impl()
+
+
+class _GetchUnix:
+ def __init__(self):
+ import tty
+ import sys
+
+ def __call__(self):
+ import sys
+ import tty
+ import termios
+
+ fd = sys.stdin.fileno()
+ old_settings = termios.tcgetattr(fd)
+ try:
+ tty.setraw(sys.stdin.fileno())
+ ch = sys.stdin.read(1)
+ finally:
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
+ return ch
+
+
+class _GetchWindows:
+ def __init__(self):
+ import msvcrt
+
+ def __call__(self):
+ import msvcrt
+ return msvcrt.getch()
+
+class _GetchMacCarbon:
+ """
+ A function which returns the current ASCII key that is down;
+ if no ASCII key is down, the null string is returned. The
+ page http://www.mactech.com/macintosh-c/chap02-1.html was
+ very helpful in figuring out how to do this.
+ """
+ def __init__(self):
+ import Carbon
+ Carbon.Evt #see if it has this (in Unix, it doesn't)
+
+ def __call__(self):
+ import Carbon
+ if Carbon.Evt.EventAvail(0x0008)[0] == 0: # 0x0008 is the keyDownMask
+ return ''
+ else:
+ #
+ # The event contains the following info:
+ # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
+ #
+ # The message (msg) contains the ASCII char which is
+ # extracted with the 0x000000FF charCodeMask; this
+ # number is converted to an ASCII character with chr() and
+ # returned
+ #
+ (what, msg, when, where, mod) = Carbon.Evt.GetNextEvent(0x0008)[1]
+ return chr(msg)
+
+def blue(string):
+ return "\033[1;34m" + string + "\033[0m"
+
+def green(string):
+ return "\033[1;32m" + string + "\033[0m"
+
+def yellow(string):
+ return "\033[1;33m" + string + "\033[0m"
+
+def red(string):
+ return "\033[1;31m" + string + "\033[0m"
+
+def cyan(string):
+ return "\033[1;36m" + string + "\033[0m"
+
+def mag(string):
+ return "\033[1;35m" + string + "\033[0m"
+
+def white(string):
+ return "\033[1;37m" + string + "\033[0m"
+
+def print_help():
+ print ""
+ print "pyLoadCli Copyright (c) 2008-2010 the pyLoad Team"
+ print ""
+ print "Usage: [python] pyLoadCli.py [options] [server url]"
+ print ""
+ print "<server url>"
+ print "The server url has this format: http://username:passwort@address:port"
+ print ""
+ print "<Options>"
+ print " -l, --local", " " * 6, "Use the local settings in config file"
+ print " -u, --username=<username>"
+ print " " * 20, "Specify username"
+ print ""
+ print " -a, --address=<address>"
+ print " " * 20, "Specify address (default=127.0.0.1)"
+ print ""
+ print " --linklist=<path>"
+ print " " * 20, "Add container to pyLoad"
+ print ""
+ print " -p, --port", " " * 7, "Specify port (default=7272)"
+ print " -s, --ssl", " " * 8, "Enable ssl (default=off)"
+ print " -h, --help", " " * 7, "Display this help screen"
+ print ""
+
+
+
+if __name__ == "__main__":
+ config = ConfigParser()
+
+ translation = gettext.translation("pyLoadCli", join(pypath, "locale"), languages=[config['general']['language']])
+ translation.install(unicode=(True if sys.stdout.encoding.lower().startswith("utf") else False))
+
+ server_url = ""
+ username = ""
+ password = ""
+ addr = ""
+ port = ""
+ ssl = None
+
+ add = ""
+
+ if len(sys.argv) > 1:
+
+
+ addr = "127.0.0.1"
+ port = "7272"
+ ssl = ""
+
+ shortOptions = 'lu:a:p:s:h'
+ longOptions = ['local', "username=", "address=", "port=", "ssl=", "help", "linklist=", "pw=", "configdir="]
+
+ try:
+ opts, extraparams = getopt(sys.argv[1:], shortOptions, longOptions)
+ for option, params in opts:
+ if option in ("-l", "--local"):
+
+ if config['ssl']['activated']:
+ ssl = "s"
+
+ username = config.username
+ password = config.password
+ addr = config['remote']['listenaddr']
+ port = config['remote']['port']
+ elif option in ("-u", "--username"):
+ username = params
+ elif option in ("-a", "--address"):
+ addr = params
+ elif option in ("-p", "--port"):
+ port = params
+ elif option in ("-s", "--ssl"):
+ if params.lower() == "true":
+ ssl = "s"
+ elif option in ("-h", "--help"):
+ print_help()
+ exit()
+ elif option in ("--linklist"):
+ add = params
+ elif option in ("--pw"):
+ password = params
+ except GetoptError:
+ print 'Unknown Argument(s) "%s"' % " ".join(sys.argv[1:])
+ print_help()
+ exit()
+
+ if len(extraparams) == 1:
+ server_url = sys.argv[1]
+
+ if not server_url:
+ if not username: username = raw_input(_("Username: "))
+ if not addr: addr = raw_input(_("address: "))
+ if ssl is None:
+ ssl = raw_input(_("Use SSL? ([y]/n): "))
+ if ssl == "y" or ssl == "":
+ ssl = "s"
+ else:
+ ssl = ""
+ if not port: port = raw_input(_("Port: "))
+ if not password:
+ from getpass import getpass
+ password = getpass(_("Password: "))
+
+ server_url = "http%s://%s:%s@%s:%s/" % (ssl, username, password, addr, port)
+
+ print server_url
+ if add:
+ cli = pyLoadCli(server_url, add)
+ else:
+ cli = pyLoadCli(server_url)