#!/usr/bin/env python # -*- coding: utf-8 -*- # #Copyright (C) 2009 sp00b, sebnapi, 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 . # ### #python from __future__ import with_statement import re import subprocess import time import urllib2 from threading import RLock from download_thread import Download_Thread class Thread_List(object): def __init__(self, parent): self.parent = parent self.threads = [] self.max_threads = int(self.parent.config['max_downloads']) self.py_load_files = [] # files in queque self.f_relation = [0, 0] self.lock = RLock() self.py_downloading = [] # files downloading self.occ_plugins = [] #occupied plugins self.pause = False self.reconnecting = False self.select_thread() def create_thread(self): """ creates thread for Py_Load_File and append thread to self.threads """ thread = Download_Thread(self) self.threads.append(thread) return True def get_loaded_urls(self): loaded_urls = [] for file in self.py_load_files: loaded_urls.append(file.url) return loaded_urls def remove_thread(self, thread): self.threads.remove(thread) def get_job(self): """return job if suitable, otherwise send thread idle""" if not self.parent.is_dltime(): return None if self.pause: return None if self.reconnecting: return None self.init_reconnect() self.lock.acquire() pyfile = None for i in range(len(self.py_load_files)): if not self.py_load_files[i].modul.__name__ in self.occ_plugins: pyfile = self.py_load_files.pop(i) break if pyfile: self.py_downloading.append(pyfile) if not pyfile.plugin.multi_dl: self.occ_plugins.append(pyfile.modul.__name__) self.parent.logger.info('Download starts: ' + pyfile.url) self.lock.release() return pyfile def job_finished(self, pyfile): self.lock.acquire() if not pyfile.plugin.multi_dl: self.occ_plugins.remove(pyfile.modul.__name__) self.py_downloading.remove(pyfile) if pyfile.status.type == "finished": self.parent.logger.info('Download finished: ' + pyfile.url + ' @' + str(pyfile.status.get_speed()) + 'kb/s') with open(self.parent.config['link_file'], 'r') as f: data = f.read() if pyfile.plugin.props['type'] == "container": links = "" for link in pyfile.plugin.links: links += link + "\n" self.parent.extend_links(pyfile.plugin.links) data = links + data # put the links into text file data = data.replace(pyfile.url + '\n', "") #with open(self.parent.config['link_file'], 'w') as f: #f.write(data) if pyfile.status.type == "reconnected":#put it back in queque self.py_load_files.insert(0, pyfile) if pyfile.status.type == "failed": self.parent.logger.warning("Download failed: " + pyfile.url) with open(self.parent.config['failed_file'], 'a') as f: f.write(pyfile.url + "\n") self.lock.release() return True def select_thread(self): """ select a thread """ if len(self.threads) < self.max_threads: self.create_thread() def append_py_load_file(self, py_load_file): py_load_file.id = len(self.py_load_files) self.py_load_files.append(py_load_file) self.f_relation[1] += 1 self.select_thread() def init_reconnect(self): """initialise a reonnect""" if not self.parent.config['use_reconnect']: return False if self.reconnecting: return False self.lock.acquire() if self.check_reconnect(): self.reconnecting = True self.reconnect() time.sleep(1.1) self.reconnecting = False self.lock.release() return True self.lock.release() return False def check_reconnect(self): """checks if all files want reconnect""" if not self.py_downloading: return False i = 0 for obj in self.py_downloading: if obj.status.want_reconnect: i += 1 if len(self.py_downloading) == i: return True else: return False def reconnect(self): reconn = subprocess.Popen(self.parent.config['reconnect_method']) reconn.wait() ip = re.match(".*Current IP Address: (.*).*", urllib2.urlopen("http://checkip.dyndns.org/").read()).group(1) #versuchen neue ip aus zu lesen while ip == "": #solange versuch bis neue ip ausgelesen ip = re.match(".*Current IP Address: (.*).*", urllib2.urlopen("http://checkip.dyndns.org/").read()).group(1) time.sleep(1) self.parent.logger.info("Reconnected, new IP: " + ip)