summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2009-06-26 11:37:44 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2009-06-26 11:37:44 +0200
commite260b201f94a2a1e470b85a6499ea70e20a11277 (patch)
tree356dc9f5a7d8ef14cf6befb8cfa324b991571a0c
parentfixed occasionally appearing cli bug, catpcha method for sharebiz @ ~60% (diff)
downloadpyload-e260b201f94a2a1e470b85a6499ea70e20a11277.tar.xz
Cli stable, able to abort downloads, pause/kill server
-rw-r--r--Plugins/RapidshareCom.py1
-rw-r--r--module/download_thread.py5
-rw-r--r--module/file_list.py14
-rwxr-xr-xmodule/network/Request.py6
-rw-r--r--module/thread_list.py9
-rw-r--r--pyLoadCli.py100
-rw-r--r--pyLoadCore.py18
7 files changed, 116 insertions, 37 deletions
diff --git a/Plugins/RapidshareCom.py b/Plugins/RapidshareCom.py
index 4eb7bf93d..b34576d23 100644
--- a/Plugins/RapidshareCom.py
+++ b/Plugins/RapidshareCom.py
@@ -130,6 +130,7 @@ class RapidshareCom(Plugin):
file_url_pattern = r".*name=\"dlf\" action=\"(.*)\" method=.*"
return re.search(file_url_pattern, self.html[1]).group(1)
else:
+ print self.html[1] #test print
raise Exception, "Error when retrieving download url"
def get_file_name(self):
diff --git a/module/download_thread.py b/module/download_thread.py
index 202ebcafb..2c9cc8791 100644
--- a/module/download_thread.py
+++ b/module/download_thread.py
@@ -22,6 +22,7 @@ import traceback
from time import sleep
from time import time
+from module.network.Request import AbortDownload
class Status(object):
""" Saves all status information
@@ -53,7 +54,6 @@ class Status(object):
class Reconnect(Exception):
pass
-
class Download_Thread(threading.Thread):
def __init__(self, parent):
threading.Thread.__init__(self)
@@ -70,6 +70,9 @@ class Download_Thread(threading.Thread):
if self.loadedPyFile:
try:
self.download(self.loadedPyFile)
+ except AbortDownload:
+ self.loadedPyFile.plugin.req.abort = False
+ self.loadedPyFile.status.type = "aborted"
except Reconnect:
pass
except Exception, e:
diff --git a/module/file_list.py b/module/file_list.py
index 8f32ef474..feb7613bd 100644
--- a/module/file_list.py
+++ b/module/file_list.py
@@ -20,6 +20,8 @@
LIST_VERSION = 2
+from threading import RLock
+
import cPickle
from Py_Load_File import PyLoadFile
from module.remote.RequestObject import RequestObject
@@ -29,6 +31,7 @@ class File_List(object):
self.core = core
self.files = []
self.data = {'version': LIST_VERSION, 'order': []}
+ self.lock = RLock()
self.load()
def new_pyfile(self, url):
@@ -61,6 +64,7 @@ class File_List(object):
del self.data[pyfile.id]
def remove_id(self, pyid):
+ #also abort download
pyid = int(pyid)
found = False
for pyfile in self.files:
@@ -70,6 +74,10 @@ class File_List(object):
break
if not found:
+ for pyfile in self.core.thread_list.py_downloading:
+ if pyfile.id == pyid:
+ pyfile.plugin.req.abort = True
+ break
return False
self.data['order'].remove(pyid)
@@ -84,10 +92,14 @@ class File_List(object):
return id
def save(self):
+ self.lock.acquire()
+
output = open('links.pkl', 'wb')
cPickle.dump(self.data, output, -1)
self.inform_client()
+
+ self.lock.release()
def load(self):
try:
@@ -102,7 +114,7 @@ class File_List(object):
for i in obj['order']:
self.append(obj[i].url)
- self.core.logger.info("Links loaded: "+ str(int(len(obj) - 1)))
+ self.core.logger.info("Links loaded: " + str(int(len(obj) - 1)))
def inform_client(self):
obj = RequestObject()
diff --git a/module/network/Request.py b/module/network/Request.py
index 0b518cf66..346412446 100755
--- a/module/network/Request.py
+++ b/module/network/Request.py
@@ -24,6 +24,9 @@ from cStringIO import StringIO
retrieveUrl returns response as string
"""
+class AbortDownload(Exception):
+ pass
+
class Request:
def __init__(self):
@@ -33,6 +36,8 @@ class Request:
self.dl_arrived = 0
self.dl = False
+ self.abort = False
+
self.cookies = []
self.lastURL = None
self.cj = cookielib.CookieJar()
@@ -146,6 +151,7 @@ class Request:
self.dl_arrived = 0
self.dl_time = time.time()
for chunk in conn:
+ if self.abort: raise AbortDownload
self.dl_arrived += len(chunk)
file.write(chunk)
file.close()
diff --git a/module/thread_list.py b/module/thread_list.py
index 1dadb91d3..52b264648 100644
--- a/module/thread_list.py
+++ b/module/thread_list.py
@@ -99,18 +99,19 @@ class Thread_List(object):
self.list.remove(pyfile)
if pyfile.plugin.props['type'] == "container":
-
self.list.extend(pyfile.plugin.links)
-
- if pyfile.status.type == "reconnected":#put it back in queque
+ elif pyfile.status.type == "reconnected":#put it back in queque
self.list.files.insert(0, pyfile)
- if pyfile.status.type == "failed":
+ elif pyfile.status.type == "failed":
self.parent.logger.warning("Download failed: " + pyfile.url+" | "+ pyfile.status.error)
with open(self.parent.config['failed_file'], 'a') as f:
f.write(pyfile.url + "\n")
+ self.list.remove(pyfile)
+ elif pyfile.status.type == "aborted":
+ self.parent.logger.info("Download aborted: " + pyfile.url)
self.list.remove(pyfile)
self.list.save()
diff --git a/pyLoadCli.py b/pyLoadCli.py
index 378b97de9..bd13206ac 100644
--- a/pyLoadCli.py
+++ b/pyLoadCli.py
@@ -1,3 +1,4 @@
+import os.path
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
@@ -28,7 +29,7 @@ class pyLoadCli:
self.thread = SocketThread(adress, int(port), pw, self)
self.getch = _Getch()
self.input = ""
- self.pos = [0,0]
+ self.pos = [0, 0]
self.inputline = 0
self.menuline = 0
@@ -76,10 +77,10 @@ class pyLoadCli:
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, "")
+ self.println(self.inputline + 1, "")
+ self.println(self.inputline + 2, "")
+ self.println(self.inputline + 3, "")
+ self.println(self.inputline + 4, "")
def data_arrived(self, obj):
"""Handle incoming data"""
@@ -98,7 +99,7 @@ class pyLoadCli:
speed += download['speed']
self.println(line, cyan(download["name"]))
line += 1
- self.println(line, blue("[") + yellow(z * "#" + (25-z) * " ") + blue("] ") + green(str(percent) + "%") + " Speed: " + green(str(int(download['speed'])) + " kb/s") + " Finished in: " + green(self.format_time(download['eta'])))
+ self.println(line, blue("[") + yellow(z * "#" + (25-z) * " ") + blue("] ") + green(str(percent) + "%") + " Speed: " + green(str(int(download['speed'])) + " kb/s") + " Finished in: " + green(self.format_time(download['eta'])) + " ID: " + green(str(download['id'])))
line += 1
if download["status"] == "waiting":
self.println(line, cyan(download["name"]))
@@ -107,7 +108,10 @@ class pyLoadCli:
line += 1
self.println(line, "")
line += 1
- self.println(line, "Status: " + red("paused") if obj.status['pause'] else "Status: " + red("running") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"])))
+ if obj.status['pause']:
+ self.println(line, "Status: " + red("paused") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"])))
+ else:
+ self.println(line, "Status: " + red("running") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"])))
line += 1
self.println(line, "")
line += 1
@@ -128,7 +132,7 @@ class pyLoadCli:
line += 1
self.println(line, mag("2.") + " Remove Links")
line += 1
- self.println(line, mag("3.") + " Pause Server")
+ self.println(line, mag("3.") + " (Un)Pause Server")
line += 1
self.println(line, mag("4.") + " Kill Server")
line += 1
@@ -157,18 +161,18 @@ class pyLoadCli:
self.println(line, "Type the number of the link you want to delete.")
line += 1
i = 0
- for id in range(self.pos[1],self.pos[1]+5):
- if id < 0 or id >= len(self.file_list['order']):
- continue
- item = self.file_list['order'][id]
- self.println(line, mag(str(item)) + ": " + self.file_list[item].url)
- line += 1
- i += 1
+ for id in range(self.pos[1], self.pos[1] + 5):
+ if id < 0 or id >= len(self.file_list['order']):
+ continue
+ item = self.file_list['order'][id]
+ self.println(line, mag(str(item)) + ": " + self.file_list[item].url)
+ line += 1
+ i += 1
for x in range(5-i):
- self.println(line,"")
+ self.println(line, "")
line += 1
- self.println(line, mag("p") +" - previous" + " | " + mag("n") + " - next")
+ self.println(line, mag("p") + " - previous" + " | " + mag("n") + " - next")
line += 1
self.println(line, mag("0.") + " back to main menu")
@@ -178,7 +182,7 @@ class pyLoadCli:
def handle_input(self):
inp = self.input
if inp == "0":
- self.pos = [0,0]
+ self.pos = [0, 0]
self.build_menu()
return True
@@ -190,14 +194,15 @@ class pyLoadCli:
self.pos[0] = 2
self.pos[1] = 0
elif inp == "3":
- self.pos[0] = 3
+ self.thread.push_exec("toggle_pause")
elif inp == "4":
- self.pos[0] = 4
+ self.thread.push_exec("kill")
+ sys.exit()
elif inp == "5":
os.system('clear')
sys.exit()
elif self.pos[0] == 1: #add links
- if inp[:7] == "http://":
+ if inp[:7] == "http://" or os.path.exists(inp):
self.thread.push_exec("add_links", [(inp, None)])
self.links_added += 1
elif self.pos[0] == 2: #remove links
@@ -211,12 +216,18 @@ class pyLoadCli:
self.build_menu()
class _Getch:
- """Gets a single character from standard input. Does not echo to the screen."""
+ """
+ Gets a single character from standard input. Does not echo to
+ the screen.
+ """
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
- self.impl = _GetchUnix()
+ try:
+ self.impl = _GetchMacCarbon()
+ except(AttributeError, ImportError):
+ self.impl = _GetchUnix()
def __call__(self): return self.impl()
@@ -249,6 +260,37 @@ class _GetchWindows:
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"
@@ -272,12 +314,10 @@ def white(string):
if __name__ == "__main__":
if len(sys.argv) != 4:
- #address = raw_input("Adress:")
- #port = raw_input("Port:")
- #password = raw_input("Password:")
- address = "localhost"
- port = "7272"
- password = "pwhere"
+ address = raw_input("Adress:")
+ port = raw_input("Port:")
+ password = raw_input("Password:")
+
cli = pyLoadCli(address, port, password)
else:
- cli = pyLoadCli( * sys.argv[1:])
+ cli = pyLoadCli(* sys.argv[1:])
diff --git a/pyLoadCore.py b/pyLoadCore.py
index e9d933dc6..3f45ca332 100644
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -50,6 +50,8 @@ class Core(object):
self.read_config()
+ self.do_kill = False
+
translation = gettext.translation("pyLoad", "locale", languages=[self.config['language']])
translation.install(unicode=True)
@@ -219,6 +221,7 @@ class Core(object):
self._test_print_status()
self.server_test()
sleep(2)
+ if self.do_kill: exit()
def server_test(self):
obj = RequestObject()
@@ -238,12 +241,17 @@ class Core(object):
self.server.start()
def kill(self):
+ self.do_kill = True
exit()
+ return True
def shutdown(self):
-
+ "abort all downloads and exit"
self.thread_list.pause = True
+ for pyfile in self.thread_list.py_downloading:
+ pyfile.plugin.req.abort = True
+
while self.thread_list.py_downloading:
sleep(1)
@@ -261,6 +269,14 @@ class Core(object):
def get_links(self):
return self.file_list.data
+ def toggle_pause(self):
+ if self.thread_list.pause:
+ self.thread_list.pause = False
+ return False
+ elif not self.thread_list.pause:
+ self.thread_list.pause = True
+ return True
+
if __name__ == "__main__":
testLoader = Core()
testLoader.start()