Downloading ' in line:
+ if "href" in line:
+ tmp = line.split('')[0].split("/")
+ tmp.append(urllib.quote(tmp.pop()))
+ self.link = "/".join(tmp)
+ except Exception, e:
+ logger.exception("%s :%s" % (url, e))
+
+ def handle_starttag(self, tag, attrs):
+ """"""
+ if tag == "input":
+ if ("name", "action") in attrs:
+ for ref, value in attrs:
+ if ref == "value" and value == "checkcaptcha":
+ self.action_captcha = value
+ elif ("name", "captchaid") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.captchaid = value
+ elif ("name", "hash1") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.hash1 = value
+ elif ("name", "hash2") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.hash2 = value
+ elif tag == "img":
+ self.captcha_url = "%s%s" % (BASE_URL, attrs[0][1])
+
+ def filter_image(self, image):
+ """"""
+ image = image.point(self.filter_pixel)
+ image = ImageOps.grayscale(image)
+ return image
+
+ def filter_pixel(self, pixel):
+ """"""
+ if pixel > 110:
+ return 255
+ if pixel > 90:
+ return 100
+ else:
+ return 1
+
+class Parser(HTMLParser):
+ def __init__(self, url):
+ """"""
+ HTMLParser.__init__(self)
+ self.link = None
+ self.form = None
+ self.tm = None
+ self.tmhash = None
+ self.waithash = None
+ self.wait = None
+ try:
+ opener = URLOpen()
+ self.feed(opener.open(url).read())
+ self.close()
+ self.form = urllib.urlencode([("action", "capt"), ("tm", self.tm), ("tmhash", self.tmhash), ("wait", self.wait), ("waithash", self.waithash)])
+ except Exception, e:
+ logger.exception("%s :%s" % (url, e))
+
+ def handle_starttag(self, tag, attrs):
+ """"""
+ if self.link:
+ if tag == "input":
+ if ("name", "tm") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.tm = value
+ elif ("name", "tmhash") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.tmhash = value
+ elif ("name", "wait") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.wait = int(value)
+ elif ("name", "waithash") in attrs:
+ for ref, value in attrs:
+ if ref == "value":
+ self.waithash = value
+ else:
+ if tag == "form":
+ if len(attrs) > 3:
+ self.link = "%s%s" % (BASE_URL, attrs[1][1])
+
+class CheckLinks:
+ """"""
+ def check(self, url):
+ """"""
+ name = None
+ size = 0
+ unit = None
+ try:
+ for line in URLOpen().open(url).readlines():
+ if ' ' in line:
+ name = line.split('Downloading ')[1].split(' ')[0]
+ tmp = line.split('|')[1].strip().split(' ')[0]
+ unit = tmp[-2:].upper()
+ size = int(round(float(tmp[:-2])))
+ if not unit:
+ name = url
+ size = -1
+ except Exception, e:
+ name = url
+ size = -1
+ logger.exception("%s :%s" % (url, e))
+ return name, size, unit
+
+if __name__ == "__main__":
+ c = Parser("http://hotfile.com/dl/7174149/00fbb47/Sander_Van_Doorn-Live_at_Sensation_White_Saint-Petersburg-12062009.mp3.html")
+ print c.link
+ print c.form
+ import time
+ for i in range(c.wait):
+ print i
+ time.sleep(1)
+ m = CaptchaParser(c.link, c.form)
+ print m.link
+ #print CheckLinks().check("http://hotfile.com/dl/10804393/9f439e8/Bruno_-_www.crostuff.net.part1.rar.html")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/hotfile/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/hotfile/service.conf
--- tucan-0.3.8/default_plugins/hotfile/service.conf 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/default_plugins/hotfile/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -0,0 +1,14 @@
+[anonymous_download]
+name = AnonymousDownload
+author = Crak
+captcha = True
+version = 0.1
+slots = 1
+
+[main]
+enabled = False
+name = hotfile.com
+icon = favicon_hotfile.ico
+downloads = True
+uploads = False
+update = 200910070050
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/mediafire/anonymous_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/mediafire/anonymous_download.py
--- tucan-0.3.8/default_plugins/mediafire/anonymous_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/mediafire/anonymous_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -24,11 +24,9 @@
import logging
logger = logging.getLogger(__name__)
-from download_plugin import DownloadPlugin
-
from parsers import CheckLinks, FormParser
-import cons
+from core.download_plugin import DownloadPlugin
class AnonymousDownload(DownloadPlugin):
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/mediafire/parsers.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/mediafire/parsers.py
--- tucan-0.3.8/default_plugins/mediafire/parsers.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/mediafire/parsers.py 2009-10-07 00:02:27.000000000 +0100
@@ -23,7 +23,8 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
+from core.tesseract import Tesseract
+from core.url_open import URLOpen
class FormParser:
""""""
@@ -46,25 +47,27 @@
handle = opener.open("http://www.mediafire.com/dynamic/download.php?%s" % (urllib.urlencode([("qk", tmp[0]), ("pk", tmp[1]), ("r", tmp[2])])))
tmp = handle.readlines()
vars = {}
+
+ tmp1 = tmp[2].split("function dz()")[0].split(";", 4)
+ sum = tmp[2].split("+mL+'/' ")[1].split(" 'g/'+mH+'/'+mY+'")[0]
+
+ server = tmp1[1].split("'")[1]
+ link = tmp1[2].split("'")[1]
+ name = tmp1[3].split("'")[1]
- server = tmp[11].split("'")[1]
- link = tmp[12].split("'")[1]
- name = tmp[13].split("'")[1]
-
- for var in tmp[14].split(";"):
+ for var in tmp1.pop().strip().split(";"):
var = var.split("var")
if len(var) > 1:
var = var[1].strip().split("=")
if ((len(var) > 1) and ("'" in var[1])):
vars[var[0]] = var[1].split("'")[1]
- for var in tmp[27].split(" ")[14].split("+"):
+ for var in sum.split("+"):
if len(var) > 0:
if var in vars.keys():
random += vars[var]
else:
error = True
except Exception, e:
- print e
error = True
logger.exception("%s: %s" % (url, e))
if server and random and link and name and not error:
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/mediafire/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/mediafire/service.conf
--- tucan-0.3.8/default_plugins/mediafire/service.conf 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/mediafire/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -11,4 +11,4 @@
icon = favicon_mediafire.ico
downloads = True
uploads = False
-update = 200907150200
+update = 200910070050
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/anonymous_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/anonymous_download.py
--- tucan-0.3.8/default_plugins/megaupload/anonymous_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/anonymous_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -25,15 +25,14 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
-
from captcha import CaptchaForm
from check_links import CheckLinks
-from download_plugin import DownloadPlugin
-from slots import Slots
+from core.download_plugin import DownloadPlugin
+from core.url_open import URLOpen
+from core.slots import Slots
-import cons
+import core.cons as cons
WAIT = 45
@@ -52,7 +51,7 @@
return self.start(path, parser.link, file_name, WAIT, None, self.post_wait)
def post_wait(self, link):
- """Must return link and form"""
+ """Must return handle"""
try:
handle = URLOpen().open(link)
except Exception, e:
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/captcha.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/captcha.py
--- tucan-0.3.8/default_plugins/megaupload/captcha.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/captcha.py 2009-10-07 00:02:27.000000000 +0100
@@ -23,9 +23,9 @@
logger = logging.getLogger(__name__)
from HTMLParser import HTMLParser
-from url_open import URLOpen
-from tesseract import Tesseract
+from core.url_open import URLOpen
+from core.tesseract import Tesseract
CAPTCHACODE = "captchacode"
MEGAVAR = "megavar"
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/check_links.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/check_links.py
--- tucan-0.3.8/default_plugins/megaupload/check_links.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/check_links.py 2009-10-07 00:02:27.000000000 +0100
@@ -22,9 +22,9 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
+from core.url_open import URLOpen
-import cons
+import core.cons as cons
class CheckLinks:
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/premium_cookie.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/premium_cookie.py
--- tucan-0.3.8/default_plugins/megaupload/premium_cookie.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/premium_cookie.py 2009-10-07 00:02:27.000000000 +0100
@@ -21,7 +21,7 @@
import urllib
import cookielib
-from url_open import URLOpen
+from core.url_open import URLOpen
class PremiumCookie:
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/premium_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/premium_download.py
--- tucan-0.3.8/default_plugins/megaupload/premium_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/premium_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -22,14 +22,14 @@
import logging
logger = logging.getLogger(__name__)
-from accounts import Accounts
-from service_config import SECTION_PREMIUM_DOWNLOAD, ServiceConfig
-from download_plugin import DownloadPlugin
-
from premium_cookie import PremiumCookie
from premium_parser import PremiumParser
from check_links import CheckLinks
+from core.accounts import Accounts
+from core.service_config import SECTION_PREMIUM_DOWNLOAD, ServiceConfig
+from core.download_plugin import DownloadPlugin
+
class PremiumDownload(DownloadPlugin, Accounts):
""""""
def __init__(self, config):
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/megaupload/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/megaupload/service.conf
--- tucan-0.3.8/default_plugins/megaupload/service.conf 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/megaupload/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -12,7 +12,7 @@
premium_cookie = PremiumCookie
downloads = True
uploads = False
-update = 200907150200
+update = 200910070050
[premium_download]
name = PremiumDownload
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/rapidshare/anonymous_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/rapidshare/anonymous_download.py
--- tucan-0.3.8/default_plugins/rapidshare/anonymous_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/rapidshare/anonymous_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -24,13 +24,12 @@
from HTMLParser import HTMLParser
-from url_open import URLOpen
-
-from download_plugin import DownloadPlugin
-from slots import Slots
-
from check_links import CheckLinks
+from core.download_plugin import DownloadPlugin
+from core.url_open import URLOpen
+from core.slots import Slots
+
class FormParser(HTMLParser):
""""""
def __init__(self, url):
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/rapidshare/check_links.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/rapidshare/check_links.py
--- tucan-0.3.8/default_plugins/rapidshare/check_links.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/rapidshare/check_links.py 2009-10-07 00:02:27.000000000 +0100
@@ -21,9 +21,9 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
+from core.url_open import URLOpen
-import cons
+import core.cons as cons
class CheckLinks:
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/rapidshare/premium_cookie.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/rapidshare/premium_cookie.py
--- tucan-0.3.8/default_plugins/rapidshare/premium_cookie.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/rapidshare/premium_cookie.py 2009-10-07 00:02:27.000000000 +0100
@@ -21,7 +21,7 @@
import urllib
import cookielib
-from url_open import URLOpen
+from core.url_open import URLOpen
class PremiumCookie:
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/rapidshare/premium_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/rapidshare/premium_download.py
--- tucan-0.3.8/default_plugins/rapidshare/premium_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/rapidshare/premium_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -24,16 +24,15 @@
from HTMLParser import HTMLParser
-from accounts import Accounts
-from service_config import SECTION_PREMIUM_DOWNLOAD
-from download_plugin import DownloadPlugin
-
-from url_open import URLOpen
-
from premium_cookie import PremiumCookie
from check_links import CheckLinks
-import cons
+from core.service_config import SECTION_PREMIUM_DOWNLOAD
+from core.download_plugin import DownloadPlugin
+from core.accounts import Accounts
+from core.url_open import URLOpen
+
+import core.cons as cons
class FormParser(HTMLParser):
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/rapidshare/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/rapidshare/service.conf
--- tucan-0.3.8/default_plugins/rapidshare/service.conf 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/rapidshare/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -10,9 +10,9 @@
name = rapidshare.com
icon = favicon_rapidshare.ico
premium_cookie = PremiumCookie
-uploads = False
downloads = True
-update = 200907150200
+uploads = False
+update = 200910070050
[premium_download]
name = PremiumDownload
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/sendspace/anonymous_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/sendspace/anonymous_download.py
--- tucan-0.3.8/default_plugins/sendspace/anonymous_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/sendspace/anonymous_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -23,15 +23,15 @@
from parsers import CheckLinks, Parser
-from download_plugin import DownloadPlugin
-from slots import Slots
-
+from core.download_plugin import DownloadPlugin
+from core.url_open import URLOpen
+from core.slots import Slots
class AnonymousDownload(DownloadPlugin, Slots):
""""""
def __init__(self):
""""""
- Slots.__init__(self, 1, 30)
+ Slots.__init__(self, 1, 300)
DownloadPlugin.__init__(self)
def check_links(self, url):
@@ -43,12 +43,23 @@
if self.get_slot():
parser = Parser(link)
if parser.link:
- if self.start(path, parser.link, file_name):
+ if self.start(path, parser.link, file_name, None, None, self.post_wait):
return True
- else:
- logger.warning("Limit Exceded.")
- self.add_wait()
-
+ else:
+ logger.warning("Limit Exceded.")
+ self.add_wait()
+ self.return_slot()
+
+ def post_wait(self, link):
+ """Must return handle"""
+ handle = URLOpen().open(link)
+ if "text/html" in handle.info().getheader("Content-Type"):
+ logger.warning("Limit Exceded.")
+ self.add_wait()
+ self.return_slot()
+ else:
+ return handle
+
def delete(self, file_name):
""""""
if self.stop(file_name):
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/sendspace/parsers.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/sendspace/parsers.py
--- tucan-0.3.8/default_plugins/sendspace/parsers.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/sendspace/parsers.py 2009-10-07 00:02:27.000000000 +0100
@@ -22,10 +22,10 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
-
import HTMLParser
+from core.url_open import URLOpen
+
B64S = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"';
class Parser(HTMLParser.HTMLParser):
@@ -34,6 +34,10 @@
""""""
HTMLParser.HTMLParser.__init__(self)
self.link = None
+ code = ""
+ vars = ""
+ var1 = ""
+ var2 = ""
try:
for line in URLOpen().open(url).readlines():
if "base64ToText" in line:
@@ -49,8 +53,9 @@
def handle_starttag(self, tag, attrs):
""""""
if tag == "a":
- if len(attrs) == 4:
- self.link = urllib.quote(attrs[2][1], "/:")
+ for ref, value in attrs:
+ if ref == "href":
+ self.link = value
def decode(self, code, num, text):
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/sendspace/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/sendspace/service.conf
--- tucan-0.3.8/default_plugins/sendspace/service.conf 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/sendspace/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -11,4 +11,4 @@
icon = favicon_sendspace.ico
downloads = True
uploads = False
-update = 200907150200
+update = 200910070050
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/zshare/anonymous_download.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/zshare/anonymous_download.py
--- tucan-0.3.8/default_plugins/zshare/anonymous_download.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/zshare/anonymous_download.py 2009-10-07 00:02:27.000000000 +0100
@@ -23,7 +23,7 @@
from parsers import CheckLinks, Parser
-from download_plugin import DownloadPlugin
+from core.download_plugin import DownloadPlugin
WAIT = 50
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/zshare/parsers.py /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/zshare/parsers.py
--- tucan-0.3.8/default_plugins/zshare/parsers.py 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/zshare/parsers.py 2009-10-07 00:02:27.000000000 +0100
@@ -22,7 +22,7 @@
import logging
logger = logging.getLogger(__name__)
-from url_open import URLOpen
+from core.url_open import URLOpen
class Parser:
""""""
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/default_plugins/zshare/service.conf /tmp/DgSymrsclJ/tucan-0.3.9/default_plugins/zshare/service.conf
--- tucan-0.3.8/default_plugins/zshare/service.conf 2009-07-15 01:15:15.000000000 +0100
+++ tucan-0.3.9/default_plugins/zshare/service.conf 2009-10-07 00:02:27.000000000 +0100
@@ -11,4 +11,4 @@
icon = favicon_zshare.ico
downloads = True
uploads = False
-update = 200907150200
+update = 200910070050
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/downloader.py /tmp/DgSymrsclJ/tucan-0.3.9/downloader.py
--- tucan-0.3.8/downloader.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/downloader.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,126 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import urllib2
-import threading
-import time
-import logging
-logger = logging.getLogger(__name__)
-
-from url_open import URLOpen
-
-import cons
-
-BASE_SIZE = 4
-BUFFER_SIZE = BASE_SIZE * 1024
-
-class Downloader(threading.Thread):
- """"""
- def __init__(self, path, url, file_name, wait, cookie, post_wait):
- """"""
- threading.Thread.__init__(self)
-
- self.max_speed = 0
-
- self.post_wait = post_wait
- self.status = cons.STATUS_WAIT
- self.path = path
- self.url = url
- self.file = file_name
- self.wait = wait
- self.stop_flag = False
- self.start_time = time.time()
- self.time_remaining = 0
- self.total_size = 1
- self.actual_size = 0
- self.speed = 0
- self.tmp_time = 0
- self.tmp_size = 0
- #build opener
- self.opener = URLOpen(cookie)
-
- def run(self):
- """"""
- if self.wait:
- while ((self.wait > 0) and not self.stop_flag):
- time.sleep(1)
- self.wait -= 1
- self.time_remaining = self.wait
- if not self.stop_flag:
- try:
- if self.post_wait:
- handle = self.post_wait(self.url)
- else:
- handle = self.opener.open(self.url)
- if handle:
- self.status = cons.STATUS_ACTIVE
- logger.debug("%s :%s" % (self.file, handle.info().getheader("Content-Type")))
- self.total_size = int(handle.info().getheader("Content-Length"))
- if not os.path.exists(unicode(self.path)):
- os.mkdir(self.path)
- f = open(unicode(os.path.join(self.path, self.file)), "wb")
- self.start_time = time.time()
- data = "None"
- while ((len(data) > 0) and not self.stop_flag):
- tmp_size = 0
- if self.max_speed > 0:
- max_size = self.max_speed/BASE_SIZE
- else:
- max_size = 0
- start_seconds = time.time()
- while (time.time() - start_seconds) < 1:
- if max_size == 0 or tmp_size < max_size:
- data = handle.read(BUFFER_SIZE)
- f.write(data)
- self.actual_size += len(data)
- tmp_size += 1
- else:
- time.sleep(0.1)
- self.speed = BASE_SIZE * tmp_size
- self.time_remaining = time.time() - self.start_time
- f.close()
- if not self.stop_flag:
- self.stop_flag = True
- if self.actual_size == self.total_size:
- self.status = cons.STATUS_CORRECT
- else:
- self.status = cons.STATUS_ERROR
- else:
- self.stop_flag = True
- self.status = cons.STATUS_PEND
- #except TypeError, e:
- # logger.exception("%s: %s" % (self.file, e))
- # self.stop_flag = True
- # self.status = cons.STATUS_PEND
- except Exception, e:
- logger.exception("%s: %s" % (self.file, e))
- self.stop_flag = True
- self.status = cons.STATUS_ERROR
-
- def get_speed(self):
- """return int speed KB/s"""
- elapsed_time = time.time() - self.tmp_time
- size = self.actual_size - self.tmp_size
- if size > 0:
- self.speed = int(float(size/1024)/float(elapsed_time))
- self.tmp_time = time.time()
- self.tmp_size = self.actual_size
- return self.speed
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/download_manager.py /tmp/DgSymrsclJ/tucan-0.3.9/download_manager.py
--- tucan-0.3.8/download_manager.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/download_manager.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,255 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import time
-import threading
-
-import logging
-logger = logging.getLogger(__name__)
-
-import cons
-
-class Link:
- """"""
- def __init__(self, url, plugin, type, service):
- """"""
- self.active = False
- self.url = url
- self.plugin = plugin
- self.plugin_type = type
- self.service = service
-
-class DownloadItem:
- """"""
- def __init__(self, path, name, links, total_size, size_unit):
- """"""
- self.path = path
- self.name = name
- self.status = cons.STATUS_PEND
- self.links = []
- for url, plugin, type, service in links:
- self.links.append(Link(url, plugin, type, service))
- self.progress = 0
- self.total_size = total_size
- self.total_size_unit = size_unit
- self.actual_size = 0
- self.actual_size_unit = cons.UNIT_KB
- self.speed = 0
- self.prev_speed = 0
- self.time = 0
-
- def update(self, status=cons.STATUS_STOP, progress=0, actual_size=0, size_unit=cons.UNIT_KB, speed=0, prev_speed=0, time=0):
- """"""
- self.status = status
- self.progress = progress
- self.actual_size = actual_size
- self.actual_size_unit = size_unit
- self.speed = speed
- self.prev_speed = prev_speed
- self.time = time
-
-class DownloadManager:
- """"""
- def __init__(self, get_plugin, services):
- """"""
- self.services = services
- self.get_plugin = get_plugin
- self.limits = []
- self.pending_downloads = []
- self.active_downloads = []
- self.complete_downloads = []
- self.timer = None
- self.scheduling = False
-
- def get_limits(self):
- """"""
- for service in self.services:
- if service.anonymous_download_plugin:
- if "limit" in dir(service.anonymous_download_plugin):
- if service.anonymous_download_plugin.limit:
- if service.name not in [name[0] for name in self.limits]:
- self.limits.append((service.name, cons.TYPE_ANONYMOUS, "[%s]" % time.strftime("%H:%M"), service.icon_path))
- else:
- for limit in self.limits:
- if service.name == limit[0]:
- self.limits.remove(limit)
- return self.limits
-
- def delete_link(self, name, link):
- """"""
- for download in self.pending_downloads:
- if download.name == name:
- for url in download.links:
- if link == url.url:
- del download.links[download.links.index(url)]
- return True
-
- def get_files(self):
- """"""
- result = []
- for downloads in [self.pending_downloads, self.active_downloads, self.complete_downloads]:
- for download in downloads:
- result.append(download)
- self.update()
- return result
-
- def clear(self, files):
- """"""
- for name in files:
- complete = [tmp.name for tmp in self.complete_downloads]
- if name in complete:
- logger.info("Cleared %s" % name)
- del self.complete_downloads[complete.index(name)]
-
- def add(self, path, name, links, total_size, size_unit):
- """"""
- if name not in [tmp.name for tmp in (self.active_downloads + self.pending_downloads)]:
- self.pending_downloads.append(DownloadItem(path, name, links, total_size, size_unit))
- threading.Timer(1, self.scheduler).start()
- return True
-
- def start(self, name):
- """"""
- for download in self.pending_downloads:
- if name == download.name:
- download.status = cons.STATUS_WAIT
- for link in download.links:
- link.plugin, link.type = self.get_plugin(link.service)
- if link.plugin.add(download.path, link.url, download.name):
- link.active = True
- self.active_downloads.append(download)
- self.pending_downloads.remove(download)
- return True
- else:
- link.active = False
- if not download.status == cons.STATUS_ERROR:
- download.status = cons.STATUS_PEND
-
- def stop(self, name):
- """"""
- for download in self.pending_downloads:
- if name == download.name:
- download.status = cons.STATUS_STOP
- for download in self.active_downloads:
- if name == download.name:
- for link in download.links:
- if link.active:
- if link.plugin.stop(download.name):
- if "return_slot" in dir(link.plugin):
- link.plugin.return_slot()
- link.active = False
- self.pending_downloads.append(download)
- self.active_downloads.remove(download)
- download.update()
- return True
-
- def update(self):
- """"""
- new_speed = 0
- permanent = True
- speeds = [download.speed for download in self.active_downloads if download.status == cons.STATUS_ACTIVE]
- current_active = len(speeds)
- #print max_downloads, max_download_speed
- #print current_active, speeds
- remain_speed = max_download_speed
- for speed in speeds:
- remain_speed -= speed
- #print remain_speed
- if current_active > 0:
- if remain_speed < 0:
- new_speed = max_download_speed/current_active
- permanent = False
- for download in self.active_downloads:
- plugin = None
- for link in download.links:
- if link.active:
- plugin = link.plugin
- break
- if plugin:
- if permanent:
- if download.speed == 0:
- if remain_speed <= 0:
- new_speed = 20
- else:
- new_speed = remain_speed
- elif download.prev_speed >= download.speed:
- new_speed = download.prev_speed
- if remain_speed - 2 > 0:
- new_speed += 2
- remain_speed -= 2
- else:
- new_speed += remain_speed
- remain_speed = 0
- else:
- new_speed = download.speed
- status, progress, actual_size, unit, speed, time = plugin.get_status(download.name, new_speed)
- #print download.name, status, progress, actual_size, unit, speed, new_speed, time
- if status:
- download.update(status, progress, actual_size, unit, speed, new_speed, time)
- #if status in [cons.STATUS_PEND, cons.STATUS_STOP]:
- # logger.warning("%s %s %s %s %s %s %s" % (download.name, status, progress, actual_size, unit, speed, time))
- # if ((status == cons.STATUS_PEND) and ("add_wait" in dir(plugin))):
- # plugin.add_wait()
- # self.stop(download.name)
- if status == cons.STATUS_ERROR:
- logger.error("%s %s %s %s %s %s %s" % (download.name, status, progress, actual_size, unit, speed, time))
- if "return_slot" in dir(link.plugin):
- plugin.return_slot()
- link.active = False
- self.pending_downloads.append(download)
- self.active_downloads.remove(download)
- self.scheduler()
- elif status == cons.STATUS_CORRECT:
- logger.info("%s %s %s %s %s %s %s" % (download.name, status, progress, actual_size, unit, speed, time))
- if "return_slot" in dir(link.plugin):
- plugin.return_slot()
- download.progress = 100
- self.complete_downloads.append(download)
- self.active_downloads.remove(download)
-
- def scheduler(self):
- """"""
- if not self.scheduling:
- self.scheduling = True
- if len(self.pending_downloads) > 0:
- logger.debug("scheduling")
- for download in self.pending_downloads:
- if len(self.active_downloads) < max_downloads:
- if download.status not in [cons.STATUS_STOP]:
- if self.start(download.name):
- logger.info("Started: %s" % download.name)
- logger.debug("Active: %s" % [tmp.name for tmp in self.active_downloads])
- logger.debug("Pending: %s" % [tmp.name for tmp in self.pending_downloads])
- logger.debug("Complete: %s" % [tmp.name for tmp in self.complete_downloads])
- break
- if self.timer:
- self.timer.cancel()
- self.timer = threading.Timer(5, self.scheduler)
- self.timer.start()
- self.scheduling = False
-
- def quit(self):
- """"""
- if self.timer:
- self.scheduling = True
- self.timer.cancel()
- for download in self.active_downloads:
- for link in download.links:
- link.plugin.stop_all()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/download_plugin.py /tmp/DgSymrsclJ/tucan-0.3.9/download_plugin.py
--- tucan-0.3.8/download_plugin.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/download_plugin.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,90 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import time
-
-from downloader import Downloader
-
-import cons
-
-class DownloadPlugin(object):
- """"""
- def __init__(self):
- """"""
- self.active_downloads = {}
-
- def start(self, path, url, file_name, wait=None, cookie=None, post_wait=None):
- """"""
- if file_name not in self.active_downloads:
- th = Downloader(path, url, file_name, wait, cookie, post_wait)
- th.start()
- self.active_downloads[file_name] = th
- return True
-
- def stop(self, file_name):
- """"""
- if file_name in self.active_downloads:
- while self.active_downloads[file_name].isAlive():
- self.active_downloads[file_name].stop_flag = True
- time.sleep(0.1)
- del self.active_downloads[file_name]
- return True
-
- def stop_all(self):
- """"""
- for th in self.active_downloads.values():
- while th.isAlive():
- th.stop_flag = True
-
- def get_status(self, file_name, speed=0):
- """return (status, progress, actual_size, unit, speed, time)"""
- result = cons.STATUS_ERROR, 0, 0, None, 0, 0
- th = None
- if file_name in self.active_downloads:
- th = self.active_downloads[file_name]
- if self.active_downloads[file_name].stop_flag:
- del self.active_downloads[file_name]
- if th:
- actual_size, unit = self.get_size(th.actual_size)
- if th.status == cons.STATUS_ACTIVE:
- progress = int((float(th.actual_size)/float(th.total_size))*100)
- th.max_speed = speed
- speed = th.speed
- if speed > 0:
- time = int(float((th.total_size - th.actual_size)/1024)/float(speed))
- else:
- time = 0
- else:
- progress = 0
- speed = 0
- time = int(th.time_remaining)
- result = th.status, progress, actual_size, unit, speed, time
- return result
-
- def get_size(self, num):
- """"""
- result = 0, cons.UNIT_KB
- tmp = int(num/1024)
- if tmp > 0:
- result = tmp, cons.UNIT_KB
- tmp = int(tmp/1024)
- if tmp > 0:
- result = tmp, cons.UNIT_MB
- return result
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/file_chooser.py /tmp/DgSymrsclJ/tucan-0.3.9/file_chooser.py
--- tucan-0.3.8/file_chooser.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/file_chooser.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,88 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-import cons
-
-class FileChooser(gtk.FileChooserDialog):
- """"""
- def __init__(self, parent, func, default_path=None, files=False, save=False):
- """"""
- gtk.FileChooserDialog.__init__(self, None, parent)
-
- if default_path:
- self.set_current_folder(default_path)
- self.history_path = self.get_current_folder()
-
- if files:
- self.set_title(_("Select Files"))
- self.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
- self.set_select_multiple(True)
- elif save:
- self.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
- self.set_title(_("Save As"))
- else:
- self.set_title(_("Select a Folder"))
- self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
-
- hidden_button = gtk.CheckButton(("Show hidden files."))
- hidden_button.set_active(self.get_show_hidden())
- self.vbox.pack_start(hidden_button, False, False, 5)
- hidden_button.connect("clicked", self.show_hidden)
-
- button = gtk.Button(None, gtk.STOCK_CANCEL)
- button.connect("clicked", self.close)
- self.action_area.pack_start(button)
- button = gtk.Button(None, gtk.STOCK_OK)
- button.connect("clicked", self.on_choose_folder, func)
- self.action_area.pack_start(button)
- self.set_position(gtk.WIN_POS_CENTER)
-
- self.connect("response", self.close)
-
- self.show_all()
- self.run()
-
- def show_hidden(self, button):
- """"""
- self.set_show_hidden(button.get_active())
-
- def on_choose_folder(self, button, func):
- """"""
- for file_name in self.get_filenames():
- func(os.path.join(file_name))
- self.close()
-
- def close(self, widget=None, response=None):
- """"""
- self.history_path = self.get_current_folder()
- self.set_show_hidden(False)
- self.destroy()
-
-if __name__ == "__main__":
- def mierda(name):
- print name
- f = FileChooser(None, mierda, "/home/crak/")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/gui.py /tmp/DgSymrsclJ/tucan-0.3.9/gui.py
--- tucan-0.3.8/gui.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/gui.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,378 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import sys
-import time
-import threading
-import webbrowser
-import __builtin__
-import gettext
-import logging
-logger = logging.getLogger(__name__)
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-from about import About
-from message import Message
-from tray_icon import TrayIcon
-from preferences import Preferences
-from log_view import LogView
-
-from menu_bar import MenuBar
-from toolbar import Toolbar
-
-import config
-from sessions import Sessions
-from file_chooser import FileChooser
-
-from tree import Tree
-from input_links import InputLinks
-
-from service_manager import ServiceManager
-
-from service_update import ServiceUpdate
-
-import cons
-
-class Gui(gtk.Window, ServiceManager):
- """"""
- def __init__(self, conf):
- """"""
- #i18n
- gettext.bindtextdomain(cons.NAME_LOCALES, cons.PATH_LOCALES)
- gettext.textdomain(cons.NAME_LOCALES)
- __builtin__._ = gettext.gettext
-
- #configuration
- self.configuration = conf
-
- #show preferences if not configured
- if not self.configuration.configured:
- Preferences(self.configuration, True)
- self.preferences_shown = False
-
- #l10n
- lang = gettext.translation(cons.NAME_LOCALES, cons.PATH_LOCALES, languages=[self.configuration.get(config.SECTION_MAIN, config.OPTION_LANGUAGE)])
- lang.install()
-
- ServiceManager.__init__(self, self.configuration)
- gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
-
- self.set_icon_from_file(cons.ICON_TUCAN)
- self.set_title("%s - Version: %s" % (cons.TUCAN_NAME, cons.TUCAN_VERSION))
- self.set_position(gtk.WIN_POS_CENTER)
- self.set_size_request(900, 500)
- self.vbox = gtk.VBox()
- self.add(self.vbox)
-
- #menu items
- menu_load_session = _("Load Session"), lambda x: FileChooser(self, self.load_session, cons.CONFIG_PATH, True)
- menu_save_session = _("Save Session"), lambda x: FileChooser(self, self.save_session, cons.CONFIG_PATH, save=True)
- menu_quit = gtk.STOCK_QUIT, self.quit
- menu_help = gtk.STOCK_HELP, self.help
- menu_about = gtk.STOCK_ABOUT, About
- menu_preferences = gtk.STOCK_PREFERENCES, self.preferences
- menu_log = _("Show Logs"), LogView
- show_uploads = gtk.CheckMenuItem(_("Show Uploads")), self.resize_pane, self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS)
-
- #menubar
- file_menu = _("File"), [menu_load_session, menu_save_session, None, menu_quit]
- view_menu = _("View"), [show_uploads, menu_log, None, menu_preferences]
- help_menu = _("Help"), [menu_help, menu_about]
- self.vbox.pack_start(MenuBar([file_menu, view_menu, help_menu]), False)
-
- #toolbar
- download = _("Add Downloads"), gtk.image_new_from_file(cons.ICON_DOWNLOAD), self.add_links
- upload = _("Add Uploads"), gtk.image_new_from_file(cons.ICON_UPLOAD), self.not_implemented #self.quit
- clear = _("Clear Complete"), gtk.image_new_from_file(cons.ICON_CLEAR), self.clear_complete
- up = _("Move Up"), gtk.image_new_from_file(cons.ICON_UP), self.move_up
- down = _("Move Down"), gtk.image_new_from_file(cons.ICON_DOWN), self.move_down
- start = _("Start Selected"), gtk.image_new_from_file(cons.ICON_START), self.start
- stop = _("Stop Selected"), gtk.image_new_from_file(cons.ICON_STOP), self.stop
- self.vbox.pack_start(Toolbar([download, upload, None, clear, None, up, down, None, start, stop]), False)
-
- copy = gtk.STOCK_COPY, self.copy_clipboard
- delete = gtk.STOCK_REMOVE, self.delete
- start = gtk.STOCK_MEDIA_PLAY, self.start
- stop = gtk.STOCK_MEDIA_STOP, self.stop
-
- #trees
- self.downloads = Tree([copy, None, delete], self.download_manager)
- #self.uploads = Tree()
- self.uploads = gtk.VBox()
-
- #sessions
- self.session = Sessions()
- if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION):
- self.load_default_session()
- else:
- if os.path.exists(cons.SESSION_FILE):
- title = _("Tucan Manager - Restore previous session.")
- message = _("Your last session closed unexpectedly.\nTucan will try to restore it now.")
- m = Message(None, cons.SEVERITY_WARNING, title, message, both=True)
- if m.accepted:
- self.load_default_session()
-
- #pane
- self.pane = gtk.VPaned()
- self.vbox.pack_start(self.pane)
- self.pane.pack1(self.downloads, True)
- self.pane.pack2(self.uploads, True)
- self.pane.set_position(self.get_size()[1])
-
- self.connect("key-press-event", self.delete_key)
-
- if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE):
- self.connect("delete_event", self.hide_on_delete)
- else:
- self.connect("delete_event", self.quit)
-
- self.show_all()
-
- #trayicon
- tray_menu = [menu_preferences, menu_about, None, menu_quit]
- self.tray_icon = TrayIcon(self.show, self.hide, tray_menu)
- self.connect("hide", self.tray_icon.activate)
- self.downloads.status_bar.connect("text-pushed", self.tray_icon.change_tooltip)
-
- #Autocheck services
- if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE):
- th = threading.Thread(group=None, target=self.check_updates, name=None)
- th.start()
-
- #ugly polling
- gobject.timeout_add(120000, self.save_default_session)
-
- def check_updates(self):
- """"""
- s = ServiceUpdate(self.configuration)
- updates = s.get_updates()
- if len(updates) > 0:
- gobject.idle_add(self.update_manager, updates)
-
- def update_manager(self, updates):
- """"""
- if not self.preferences_shown:
- self.preferences_shown = True
- Preferences(self.configuration, True, updates)
- self.preferences_shown = False
- return False
-
- def delete_key(self, window, event):
- """pressed del key"""
- if event.keyval == 65535:
- self.delete()
-
- def preferences(self, button=None):
- """"""
- if not self.preferences_shown:
- self.preferences_shown = True
- Preferences(self.configuration)
- #sincronice statusbar
- self.downloads.status_bar.synchronize()
- self.preferences_shown = False
-
- def not_implemented(self, widget):
- """"""
- w = Message(self, cons.SEVERITY_WARNING, "Not Implemented!", "The functionality you are trying to use is not implemented yet.")
-
- def resize_pane(self, checkbox):
- """"""
- if checkbox.get_active():
- self.pane.set_position(-1)
- else:
- self.pane.set_position(self.get_size()[1])
-
- def help(self, widget):
- """"""
- webbrowser.open(cons.DOC)
-
- def add_links(self, button):
- """"""
- default_path = self.configuration.get(config.SECTION_MAIN, config.OPTION_DOWNLOADS_FOLDER)
- show_advanced_packages = self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES)
- InputLinks(default_path, self.filter_service, self.get_check_links, self.create_packages, self.manage_packages, show_advanced_packages)
-
- def copy_clipboard(self, button):
- """"""
- model, iter = self.downloads.treeview.get_selection().get_selected()
- if iter:
- link_list = self.downloads.get_links(iter)
- clipboard = gtk.Clipboard()
- clipboard.clear()
- clipboard.set_text("\n".join(link_list))
-
- def load_session(self, path):
- """"""
- try:
- packages, info = self.session.load_session(path)
- if packages != None:
- self.manage_packages(packages, info)
- logger.debug("Session loaded: %s" % info)
- except Exception, e:
- logger.exception("Session not loaded: %s" % e)
- gobject.idle_add(self.session_error)
-
- def session_error(self):
- """"""
- title = _("Tucan Manager - Session Error.")
- message = _("There was a problem loading the last session. Links are unrecoverable.")
- Message(self, cons.SEVERITY_ERROR, title, message)
-
- def save_session(self, path):
- """"""
- packages, info = self.downloads.get_packages()
- self.session.save_session(path, packages, info)
- logger.debug("Session saved: %s" % info)
-
- def load_default_session(self):
- """"""
- self.load_session(cons.SESSION_FILE)
-
- def save_default_session(self):
- """"""
- self.save_session(cons.SESSION_FILE)
- return True
-
- def manage_packages(self, packages, packages_info):
- """"""
- tmp_packages = []
- if not len(packages_info) > 0:
- default_path = self.configuration.get(config.SECTION_MAIN, config.OPTION_DOWNLOADS_FOLDER)
- packages_info = [(default_path, name, None) for name, package_files in packages]
- #create directories and password files
- for info in packages_info:
- package_path = unicode(os.path.join(info[0], info[1].replace(" ", "_"), ""))
- if not os.path.exists(package_path):
- os.mkdir(package_path)
- if info[2]:
- f = open(package_path + "password.txt", "w")
- f.write(info[2] + "\n")
- f.close()
- #add packages to gui and manager
- for package_name, package_downloads in packages:
- info = packages_info[packages.index((package_name, package_downloads))]
- package_name = info[1].replace(" ", "_")
- package_path = os.path.join(info[0], package_name, "")
- self.downloads.add_package(package_name, package_path, package_downloads, info[2])
- for download in package_downloads:
- tmp = []
- for service in download[2]:
- plugin, plugin_type = self.get_download_plugin(service)
- tmp.append((download[0][download[2].index(service)], plugin, plugin_type, service))
- self.download_manager.add(package_path, download[1], tmp, download[3], download[4])
-
- def start(self, button):
- """Implementado solo para descargas"""
- model, paths = self.downloads.treeview.get_selection().get_selected_rows()
- if len(paths) > 0:
- if len(paths[0]) > 1:
- logger.info("Start file: %s" % self.download_manager.start(model.get_value(model.get_iter(paths[0]), 3)))
- else:
- logger.info("Start package.")
- for item in self.downloads.package_files(model.get_iter(paths[0])):
- self.download_manager.start(item)
-
- def stop(self, button):
- """Implementado solo para descargas"""
- model, paths = self.downloads.treeview.get_selection().get_selected_rows()
- if len(paths) > 0:
- if len(paths[0]) > 1:
- logger.info("Stop file: %s" % self.download_manager.stop(model.get_value(model.get_iter(paths[0]), 3)))
- else:
- logger.info("Stop package.")
- for item in self.downloads.package_files(model.get_iter(paths[0])):
- self.download_manager.stop(item)
-
- def clear_complete(self, button):
- """Implementado solo para descargas"""
- files = self.downloads.clear()
- logger.info("Cleared: %s" % files)
- if len(files) > 0:
- self.download_manager.clear(files)
-
- def move_up(self, button):
- """Implementado solo para descargas"""
- model, paths = self.downloads.treeview.get_selection().get_selected_rows()
- if len(paths) > 0:
- if not len(paths[0]) > 1:
- logger.info("Move up: %s" % self.downloads.move_up(model.get_iter(paths[0])))
-
- def move_down(self, button):
- """Implementado solo para descargas"""
- model, paths = self.downloads.treeview.get_selection().get_selected_rows()
- if len(paths) > 0:
- if not len(paths[0]) > 1:
- logger.info("Move down: %s" % self.downloads.move_down(model.get_iter(paths[0])))
-
- def delete(self, button=None):
- """Implementado solo para descargas"""
- model, paths = self.downloads.treeview.get_selection().get_selected_rows()
- status = [cons.STATUS_STOP, cons.STATUS_PEND, cons.STATUS_ERROR]
- if len(paths) > 0:
- if len(paths[0]) > 2:
- name, link = self.downloads.delete_link(status, model.get_iter(paths[0]))
- if link:
- logger.warning("Remove %s: %s" % (link, self.download_manager.delete_link(name, link)))
- elif len(paths[0]) > 1:
- name = self.downloads.delete_file(status, model.get_iter(paths[0]))
- if name:
- logger.warning("Remove %s: %s" % (name, self.download_manager.clear([name])))
- else:
- files = self.downloads.delete_package(status, model.get_iter(paths[0]))
- if len(files) > 0:
- logger.warning("Remove package: %s" % self.download_manager.clear(files))
-
- def quit(self, dialog=None, response=None):
- """"""
- if len(self.download_manager.active_downloads) > 0:
- message = "Tucan still has active downloads.\n Are you sure you want to quit?"
- m = Message(self, cons.SEVERITY_WARNING, "Tucan Manager - Active Downloads.", message, True, True)
- if m.accepted:
- self.close()
- else:
- #This way GTK won't destroy the window.
- return True
- else:
- self.close()
-
- def close(self):
- """"""
- if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION):
- self.save_default_session()
- else:
- try:
- os.remove(cons.SESSION_FILE)
- except Exception, e:
- logger.info(e)
- self.hide()
- self.tray_icon.set_visible(False)
- self.stop_all()
- gtk.main_quit()
- tucan_exit(0)
-
-if __name__ == "__main__":
- g = Gui()
- gobject.threads_init()
- gtk.main()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/cs/cs.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/cs/cs.po
--- tucan-0.3.8/i18n/cs/cs.po 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/i18n/cs/cs.po 2009-10-07 00:02:27.000000000 +0100
@@ -0,0 +1,180 @@
+# Tucan Manager.
+# Copyright (C) 2008-2009 The Tucan Project.
+# Krtek , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.3\n"
+"POT-Creation-Date: 2009-01-10 04:03+CET\n"
+"PO-Revision-Date: 2009-07-27 02:07+GTM+1\n"
+"Last-Translator: Krtek \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: utf-8\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: ./advanced_packages.py:37
+msgid "Advanced Packages"
+msgstr "RozÅ¡ÃÅ™ené balÃÄky"
+
+#: ./advanced_packages.py:96
+msgid "Choose new path for selected Package."
+msgstr "Vyberte nové umÃstÄ›nà pro vybrané balÃÄky."
+
+#: ./file_chooser.py:33
+msgid "Select a Folder"
+msgstr "Vybrat složku"
+
+#: ./file_chooser.py:40
+msgid "Show hidden files."
+msgstr "Ukázat skryté soubory."
+
+#: ./gui.py:84
+msgid "Load Session"
+msgstr "Nahrát sezenÃ"
+
+#: ./gui.py:85
+msgid "Save Session"
+msgstr "Uložit sezenÃ"
+
+#: ./gui.py:90
+msgid "Show Uploads"
+msgstr "Ukázat nahrávané"
+
+#: ./gui.py:93
+msgid "File"
+msgstr "Soubor"
+
+#: ./gui.py:94
+msgid "View"
+msgstr "Pohled"
+
+#: ./gui.py:95
+msgid "Help"
+msgstr "Nápověda"
+
+#: ./gui.py:99
+msgid "Add Downloads"
+msgstr "Přidat stahované"
+
+#: ./gui.py:100
+msgid "Add Uploads"
+msgstr "Přidat nahrávané"
+
+#: ./gui.py:101
+msgid "Clear Complete"
+msgstr "VyÄiÅ¡tit dokonÄené"
+
+#: ./gui.py:102
+msgid "Move Up"
+msgstr "Posunout nahoru"
+
+#: ./gui.py:103
+msgid "Move Down"
+msgstr "Posunout dolů"
+
+#: ./gui.py:104
+msgid "Start Selected"
+msgstr "Zahájit vybrané"
+
+#: ./gui.py:105
+msgid "Stop Selected"
+msgstr "Zastavit vybrané"
+
+#: ./input_links.py:54
+msgid "Input Links"
+msgstr "Vložené odkazy"
+
+#: ./input_links.py:69
+msgid "Paste links here:"
+msgstr "Vložte odkazy zde:"
+
+#: ./input_links.py:88
+msgid "Check Links"
+msgstr "Zkontrolovat odkazy"
+
+#: ./input_links.py:131
+msgid "Show advanced Package configuration."
+msgstr "Ukázat rozÅ¡ÃÅ™ené nastavenà balÃÄku."
+
+#: ./input_links.py:207
+msgid "Checking links, please wait."
+msgstr "Kontrola odkazů, prosÃm Äekejte."
+
+#: ./input_links.py:260
+msgid "Check Canceled!"
+msgstr "Kontrola přerušena!"
+
+#: ./preferences.py:54
+msgid "General Configuration"
+msgstr "Obecné nastavenÃ"
+
+#: ./preferences.py:55
+msgid "Service Configuration"
+msgstr "Nastavenà služby"
+
+#: ./preferences.py:56
+msgid "Advanced Configuration"
+msgstr "RozÅ¡ÃÅ™ené nastavenÃ"
+
+#: ./preferences.py:120
+msgid "Choose language: "
+msgstr "Vyberte jazyk: "
+
+#: ./preferences.py:138
+msgid "Max simultaneous downloads: "
+msgstr "Maximum stahovánà zároveň: "
+
+#: ./preferences.py:173
+msgid "Downloads Folder: "
+msgstr "Složka stahovánÃ: "
+
+#: ./preferences.py:260
+msgid "Restart Tucan to apply service changes."
+msgstr "Restartujte Tucana, aby se změny projevily."
+
+#: ./preferences.py:279
+msgid "The choosed directory isn't a service, or it's not configured."
+msgstr "Vybraný adresář nenà službou nebo nenà nastaven."
+
+#: ./preferences.py:307
+msgid "Before using this service, you must accept it's terms of service at "
+msgstr "PÅ™ed použÃvánÃm této služby musÃte souhlasit s podmÃnkami služby na "
+
+#: ./preferences.py:308
+msgid "Terms of service"
+msgstr "PodmÃnky služby"
+
+#: ./preferences.py:331
+msgid "Close to tray."
+msgstr "ZavÅ™Ãt do panelu."
+
+#: ./preferences.py:335
+msgid "Save session on close."
+msgstr "Uložit sezenà při odchodu."
+
+#: ./preferences.py:339
+msgid "Default advanced packages."
+msgstr "Původnà rozÅ¡ÃÅ™ené nastavenÃ."
+
+#: ./preferences.py:343
+msgid "Show uploads."
+msgstr "Ukázat nahrávané."
+
+#: ./service_preferences.py:47
+msgid "Author"
+msgstr "Autor"
+
+#: ./service_preferences.py:55
+msgid "Version"
+msgstr "Verze"
+
+#: ./service_preferences.py:64
+msgid "Slots"
+msgstr "Sloty"
+
+#: ./service_preferences.py:71
+msgid "Captcha"
+msgstr "Captcha"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/cs/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/cs/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/de/de.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/de/de.po
--- tucan-0.3.8/i18n/de/de.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/de/de.po 2009-10-07 00:02:27.000000000 +0100
@@ -10,8 +10,8 @@
"Last-Translator: c455\n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
"Generated-By: pygettext.py 1.5\n"
@@ -21,7 +21,7 @@
#: ./advanced_packages.py:96
msgid "Choose new path for selected Package."
-msgstr "Wähle einen neuen Pfad für das gewählte Paket"
+msgstr "Wähle einen neuen Pfad für das gewählte Paket."
#: ./file_chooser.py:33
msgid "Select a Folder"
@@ -141,7 +141,7 @@
#: ./preferences.py:307
msgid "Before using this service, you must accept it's terms of service at "
-msgstr "Bevor dieser Service genutzt wird, müssen folgende Nutzungsbedingungen akzeptiert werden"
+msgstr "Bevor dieser Service genutzt wird, müssen folgende Nutzungsbedingungen akzeptiert werden "
#: ./preferences.py:308
msgid "Terms of service"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/de/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/de/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/fr/fr.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/fr/fr.po
--- tucan-0.3.8/i18n/fr/fr.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/fr/fr.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,32 +1,35 @@
# Tucan Manager.
# Copyright (C) 2008-2009 The Tucan Project.
-# Crak, 2009.
+# Mathieu Divaret , 2009.
#
msgid ""
msgstr ""
-"Project-Id-Version: 0.3\n"
-"POT-Creation-Date: 2009-01-10 04:03+CET\n"
-"Last-Translator: Mathieu Divaret \n"
-"Language-Team: \n"
+"Project-Id-Version: 0.3.7\n"
+"POT-Creation-Date: 2009-06-09 01:40+CET\n"
+"PO-Revision-Date: 2009-06-09 01:50+CET\n"
+"Last-Translator: Guilhem LETTRON \n"
+"Language-Team: FRENCH \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf8\n"
-"Content-Transfer-Encoding: utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
+"Generated-By: pygettext.py 1.5\n"
+
#: ./advanced_packages.py:37
msgid "Advanced Packages"
-msgstr "Paquets avancés"
+msgstr "Gestion avancée"
#: ./advanced_packages.py:96
msgid "Choose new path for selected Package."
-msgstr "Choisissez un nouvel emplacement pour le paquet sélectionné"
+msgstr "Choisir un nouvel emplacement pour le paquet sélectionné."
#: ./file_chooser.py:33
msgid "Select a Folder"
-msgstr "Choisissez un dossier"
+msgstr "Sélectionnez un dossier"
#: ./file_chooser.py:40
msgid "Show hidden files."
-msgstr "Montrer les fichiers cachés."
+msgstr "Voir les fichiers cachés."
#: ./gui.py:84
msgid "Load Session"
@@ -34,11 +37,11 @@
#: ./gui.py:85
msgid "Save Session"
-msgstr "Sauvegarder une session"
+msgstr "Sauver une session"
#: ./gui.py:90
msgid "Show Uploads"
-msgstr "Montrer les fichiers en partagés"
+msgstr "Voir les envois"
#: ./gui.py:93
msgid "File"
@@ -54,15 +57,15 @@
#: ./gui.py:99
msgid "Add Downloads"
-msgstr "Ajouter des fichiers à télécharger"
+msgstr "Télécharger"
#: ./gui.py:100
msgid "Add Uploads"
-msgstr "Ajouter des fichiers à partager"
+msgstr "Envoyer"
#: ./gui.py:101
msgid "Clear Complete"
-msgstr "Effacer les fichiers complets"
+msgstr "Effacer les complets"
#: ./gui.py:102
msgid "Move Up"
@@ -74,19 +77,19 @@
#: ./gui.py:104
msgid "Start Selected"
-msgstr "Démarrer les fichiers sélectionnés"
+msgstr "Lancer"
#: ./gui.py:105
msgid "Stop Selected"
-msgstr "Arrêter les fichiers sélectionnés"
+msgstr "Arrêter"
#: ./input_links.py:54
msgid "Input Links"
-msgstr "Insérer les liens"
+msgstr "Insertion des liens"
#: ./input_links.py:69
msgid "Paste links here:"
-msgstr "Copier les liens ici:"
+msgstr "Collez les liens ici:"
#: ./input_links.py:88
msgid "Check Links"
@@ -94,15 +97,15 @@
#: ./input_links.py:131
msgid "Show advanced Package configuration."
-msgstr "Montrer la configuration des paquets avancés."
+msgstr "Voir la gestion avancée."
#: ./input_links.py:207
msgid "Checking links, please wait."
-msgstr "Liens en cours de vérification, merci de patienter."
+msgstr "Vérification des liens en cours."
#: ./input_links.py:260
msgid "Check Canceled!"
-msgstr "Vérification annulée!"
+msgstr "Vérification annulée"
#: ./preferences.py:54
msgid "General Configuration"
@@ -114,39 +117,39 @@
#: ./preferences.py:56
msgid "Advanced Configuration"
-msgstr "Configuration avancée"
+msgstr "Gestion avancée"
#: ./preferences.py:120
msgid "Choose language: "
-msgstr "Choisissez la langue: "
+msgstr "Choisissez une langue: "
#: ./preferences.py:138
msgid "Max simultaneous downloads: "
-msgstr "Nombre de téléchargements simultanés maximum: "
+msgstr "Téléchargement simultanés Max: "
#: ./preferences.py:173
msgid "Downloads Folder: "
-msgstr "Dossier de réception: "
+msgstr "Dossier destination: "
#: ./preferences.py:260
msgid "Restart Tucan to apply service changes."
-msgstr "Redémarrer Tucan pour appliquer les modifications."
+msgstr "Redémarrez Tucan pour appliquer changements."
#: ./preferences.py:279
msgid "The choosed directory isn't a service, or it's not configured."
-msgstr "Le répertoire choisi n'est pas un service, où il n'est pas configuré."
+msgstr "Le dossier choisi n'est pas un service ou n'est pas configuré."
#: ./preferences.py:307
msgid "Before using this service, you must accept it's terms of service at "
-msgstr "Avant d'utiliser ce service, vous devez en accepter les conditions d'utilisation"
+msgstr "Avant d'utiliser ce service, vous devez accepter les conditions d'utilisation à "
#: ./preferences.py:308
msgid "Terms of service"
-msgstr "Conditions d'utilisation du service"
+msgstr "Conditions d'utilisation"
#: ./preferences.py:331
msgid "Close to tray."
-msgstr "Minimiser dans la barre de tâches."
+msgstr "Fermer dans la barre de tache."
#: ./preferences.py:335
msgid "Save session on close."
@@ -154,11 +157,11 @@
#: ./preferences.py:339
msgid "Default advanced packages."
-msgstr "Paquets avancés par défaut."
+msgstr "Gestion avancée par défaut."
#: ./preferences.py:343
msgid "Show uploads."
-msgstr "Montrer les fichiers partagés."
+msgstr "Voir les envois par défaut."
#: ./service_preferences.py:47
msgid "Author"
@@ -170,8 +173,8 @@
#: ./service_preferences.py:64
msgid "Slots"
-msgstr "Nombre de fichiers téléchargeables au même moment"
+msgstr "Emplacements"
#: ./service_preferences.py:71
msgid "Captcha"
-msgstr "Captcha"
+msgstr "Visuel protégé"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/fr/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/fr/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/gr/gr.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/gr/gr.po
--- tucan-0.3.8/i18n/gr/gr.po 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/i18n/gr/gr.po 2009-10-07 00:02:27.000000000 +0100
@@ -0,0 +1,180 @@
+# Tucan Manager.
+# Copyright (C) 2008-2009 The Tucan Project.
+# , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.3\n"
+"POT-Creation-Date: 2009-01-11 22:54+CET\n"
+"PO-Revision-Date: 2009-10-04 22:10+CET\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: ./advanced_packages.py:37
+msgid "Advanced Packages"
+msgstr "ΠακÎτα για Ï€ÏοχωÏημÎνους"
+
+#: ./advanced_packages.py:96
+msgid "Choose new path for selected Package."
+msgstr "Επιλογή νÎας τοποθεσίας για ετα επιλεγμÎνα πακÎτα."
+
+#: ./file_chooser.py:33
+msgid "Select a Folder"
+msgstr "ΕπιλÎξτε Φάκελο"
+
+#: ./file_chooser.py:40
+msgid "Show hidden files."
+msgstr "Î Ïοβάλετε ΚÏυφά ΑÏχεία."
+
+#: ./gui.py:84
+msgid "Load Session"
+msgstr "ΦόÏτωση ΕÏγασίας"
+
+#: ./gui.py:85
+msgid "Save Session"
+msgstr "Αποθήκευση ΕÏγασίας"
+
+#: ./gui.py:90
+msgid "Show Uploads"
+msgstr "Î Ïοβολή ΑπεσταλμÎνων"
+
+#: ./gui.py:93
+msgid "File"
+msgstr "ΑÏχείο"
+
+#: ./gui.py:94
+msgid "View"
+msgstr "Î Ïοβολή"
+
+#: ./gui.py:95
+msgid "Help"
+msgstr "Βοήθεια"
+
+#: ./gui.py:99
+msgid "Add Downloads"
+msgstr "Î ÏοσθÎστε ΑÏχεία για Λήψη"
+
+#: ./gui.py:100
+msgid "Add Uploads"
+msgstr "Î ÏοσθÎστε ΑÏχεία για Αποστολή"
+
+#: ./gui.py:101
+msgid "Clear Complete"
+msgstr "ΟλοκλήÏωση ΚαθαÏισμοÏ"
+
+#: ./gui.py:102
+msgid "Move Up"
+msgstr "Μετακίνηση Επάνω"
+
+#: ./gui.py:103
+msgid "Move Down"
+msgstr "Μετακίνηση Κάτω"
+
+#: ./gui.py:104
+msgid "Start Selected"
+msgstr "Εκκίνηση ΕπιλεγμÎνων"
+
+#: ./gui.py:105
+msgid "Stop Selected"
+msgstr "Σταμάτημα ΕπιλεγμÎνων"
+
+#: ./input_links.py:54
+msgid "Input Links"
+msgstr "Εισαγωγή ΔιεÏθυνσης"
+
+#: ./input_links.py:69
+msgid "Paste links here:"
+msgstr "Επικολλήση ΔιευθÏνσεων:"
+
+#: ./input_links.py:88
+msgid "Check Links"
+msgstr "Έλεγχος ΔιευθÏνσεων"
+
+#: ./input_links.py:131
+msgid "Show advanced Package configuration."
+msgstr ""
+
+#: ./input_links.py:207
+msgid "Checking links, please wait."
+msgstr "ΠαÏακαλώ ΠεÏιμÎνετε, Γίνετε ΕξακÏίβωση ΔιευθÏνσεων."
+
+#: ./input_links.py:260
+msgid "Check Canceled!"
+msgstr "ΑκÏÏωση ΕλÎγχου"
+
+#: ./preferences.py:54
+msgid "General Configuration"
+msgstr "ΓενικÎÏ‚ Ρυθμίσεις"
+
+#: ./preferences.py:55
+msgid "Service Configuration"
+msgstr "Ρυθμίσεις ΥπηÏεσιών"
+
+#: ./preferences.py:56
+msgid "Advanced Configuration"
+msgstr "ΕξειδικευμÎνες Ρυθμίσεις"
+
+#: ./preferences.py:120
+msgid "Choose language: "
+msgstr "Επιλογή Γλώσσας: "
+
+#: ./preferences.py:138
+msgid "Max simultaneous downloads: "
+msgstr "ΤαυτόχÏονες Λήψεις: "
+
+#: ./preferences.py:173
+msgid "Downloads Folder: "
+msgstr "Φάκελος Λήψεων: "
+
+#: ./preferences.py:260
+msgid "Restart Tucan to apply service changes."
+msgstr "Επαννεκίνηση του Ï€ÏογÏάμματος για εφαÏμογή των Ïυθμίσεων."
+
+#: ./preferences.py:279
+msgid "The choosed directory isn't a service, or it's not configured."
+msgstr "Ο επιλεγμÎνος φάκελος δεν ισχÏει ή δεν είναι ÏυθμισμÎνος."
+
+#: ./preferences.py:307
+msgid "Before using this service, you must accept it's terms of service at "
+msgstr "Î Ïίν χÏεισιμοποιήσετε την υπηÏεσία Ï€ÏÎπει να αποδεχτήτε τους ÏŒÏους "
+
+#: ./preferences.py:308
+msgid "Terms of service"
+msgstr "ÎŒÏοι ΧÏήσης"
+
+#: ./preferences.py:331
+msgid "Close to tray."
+msgstr "Κλείσιμο στη μπάÏα."
+
+#: ./preferences.py:335
+msgid "Save session on close."
+msgstr "Αποθήκευση κατα το κλείσιμο."
+
+#: ./preferences.py:339
+msgid "Default advanced packages."
+msgstr "Î ÏοεπιλεγμÎνες Ρυθμίσεις."
+
+#: ./preferences.py:343
+msgid "Show uploads."
+msgstr "Î Ïοβολή ΑπεσταλμÎνων."
+
+#: ./service_preferences.py:47
+msgid "Author"
+msgstr "ΣυγγÏαφÎας"
+
+#: ./service_preferences.py:55
+msgid "Version"
+msgstr "Έκδοση"
+
+#: ./service_preferences.py:64
+msgid "Slots"
+msgstr "ΘÏÏες"
+
+#: ./service_preferences.py:71
+msgid "Captcha"
+msgstr "Captcha"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/gr/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/gr/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/it/it.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/it/it.po
--- tucan-0.3.8/i18n/it/it.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/it/it.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,6 +1,6 @@
# Tucan Manager.
-# Copyright (C) 2009 Tucan Project.
-# Crak, 2009.
+# Copyright (C) 2008-2009 The Tucan Project.
+# kir, 2009.
#
msgid ""
msgstr ""
@@ -10,8 +10,8 @@
"Last-Translator: kir & cionci\n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
"Generated-By: pygettext.py 1.5\n"
@@ -29,7 +29,7 @@
#: ./gui.py:70
msgid "Load Session"
-msgstr "Carica Sessione"
+msgstr "Carica Sessione"
#: ./gui.py:71
msgid "Save Session"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/it/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/it/LC_MESSAGES/tucan.mo differ
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/pl/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/pl/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/pl/pl.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/pl/pl.po
--- tucan-0.3.8/i18n/pl/pl.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/pl/pl.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,17 +1,17 @@
# Tucan Manager.
# Copyright (C) 2008-2009 The Tucan Project.
-# Translated by exc1te.org 2009.
+# exc1te.org , 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.3\n"
"POT-Creation-Date: 2009-01-10 04:03+CET\n"
"PO-Revision-Date: 2009-01-10 04:32+CET\n"
-"Last-Translator: ErNi_\n"
-"Language-Team: exc1te \n"
+"Last-Translator: exc1te.org \n"
+"Language-Team: exc1te \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: ISO-8859-2\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
"Generated-By: pygettext.py 1.5\n"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/pt/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/pt/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/pt/pt.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/pt/pt.po
--- tucan-0.3.8/i18n/pt/pt.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/pt/pt.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,18 +1,19 @@
# Tucan Manager.
# Copyright (C) 2008-2009 The Tucan Project.
-# Carlos Pais, 2009.
+# Carlos Pais , 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.3\n"
"POT-Creation-Date: 2009-04-17 22:54+CET\n"
"POT-Creation-Date: 2009-04-17 22:54+CET\n"
-"Last-Translator: Carlos Pais \n"
+"Last-Translator: Carlos Pais \n"
"PO-Revision-Date: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Transfer-Encoding: UTF-8\n"
+
#: ./advanced_packages.py:37
msgid "Advanced Packages"
@@ -20,7 +21,7 @@
#: ./advanced_packages.py:96
msgid "Choose new path for selected Package."
-msgstr "Escolha um novo caminho para o Pacote seleccionado"
+msgstr "Escolha um novo caminho para o Pacote seleccionado."
#: ./file_chooser.py:33
msgid "Select a Folder"
@@ -28,7 +29,7 @@
#: ./file_chooser.py:40
msgid "Show hidden files."
-msgstr "Mostrar ficheiros escondidos"
+msgstr "Mostrar ficheiros escondidos."
#: ./gui.py:84
msgid "Load Session"
@@ -88,7 +89,7 @@
#: ./input_links.py:69
msgid "Paste links here:"
-msgstr "Colar links aqui"
+msgstr "Colar links aqui:"
#: ./input_links.py:88
msgid "Check Links"
@@ -96,11 +97,11 @@
#: ./input_links.py:131
msgid "Show advanced Package configuration."
-msgstr "Mostrar configuração avanaçada de pacotes"
+msgstr "Mostrar configuração avanaçada de pacotes."
#: ./input_links.py:207
msgid "Checking links, please wait."
-msgstr "A verificar links, por favor espere"
+msgstr "A verificar links, por favor espere."
#: ./input_links.py:260
msgid "Check Canceled!"
@@ -120,23 +121,23 @@
#: ./preferences.py:120
msgid "Choose language: "
-msgstr "Escolha a lÃngua"
+msgstr "Escolha a lÃngua: "
#: ./preferences.py:138
msgid "Max simultaneous downloads: "
-msgstr "Max downloads simultâneos"
+msgstr "Max downloads simultâneos: "
#: ./preferences.py:173
msgid "Downloads Folder: "
-msgstr "Pasta de Downloads"
+msgstr "Pasta de Downloads: "
#: ./preferences.py:260
msgid "Restart Tucan to apply service changes."
-msgstr "Reiniciar Tucan para aplicar as alterações de serviço"
+msgstr "Reiniciar Tucan para aplicar as alterações de serviço."
#: ./preferences.py:279
msgid "The choosed directory isn't a service, or it's not configured."
-msgstr "A directoria escolhida não é um serviço ou não está configurada"
+msgstr "A directoria escolhida não é um serviço ou não está configurada."
#: ./preferences.py:307
msgid "Before using this service, you must accept it's terms of service at "
@@ -148,19 +149,19 @@
#: ./preferences.py:331
msgid "Close to tray."
-msgstr "Fechar para tray"
+msgstr "Fechar para tray."
#: ./preferences.py:335
msgid "Save session on close."
-msgstr "Salvar sessão ao fechar"
+msgstr "Salvar sessão ao fechar."
#: ./preferences.py:339
msgid "Default advanced packages."
-msgstr "Pacotes avançados originais"
+msgstr "Pacotes avançados originais."
#: ./preferences.py:343
msgid "Show uploads."
-msgstr "Mostrar uploads"
+msgstr "Mostrar uploads."
#: ./service_preferences.py:47
msgid "Author"
@@ -177,4 +178,3 @@
#: ./service_preferences.py:71
msgid "Captcha"
msgstr "Captcha"
-
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/ru/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/ru/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/ru/ru.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/ru/ru.po
--- tucan-0.3.8/i18n/ru/ru.po 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/i18n/ru/ru.po 2009-10-07 00:02:27.000000000 +0100
@@ -0,0 +1,180 @@
+# Tucan Manager.
+# Copyright (C) 2008-2009 The Tucan Project.
+# Paul Somebody , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.3.7\n"
+"POT-Creation-Date: 2009-01-11 22:54+CET\n"
+"PO-Revision-Date: 2009-07-22 02:44+CET\n"
+"Last-Translator: Paul Somebody \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: ./advanced_packages.py:37
+msgid "Advanced Packages"
+msgstr "Дополнительные пакеты"
+
+#: ./advanced_packages.py:96
+msgid "Choose new path for selected Package."
+msgstr "Выберите новый путь Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ пакета."
+
+#: ./file_chooser.py:33
+msgid "Select a Folder"
+msgstr "Выберите папку"
+
+#: ./file_chooser.py:40
+msgid "Show hidden files."
+msgstr "Показывать Ñкрытые файлы."
+
+#: ./gui.py:84
+msgid "Load Session"
+msgstr "Загрузить ÑеÑÑию"
+
+#: ./gui.py:85
+msgid "Save Session"
+msgstr "Сохранить ÑеÑÑию"
+
+#: ./gui.py:90
+msgid "Show Uploads"
+msgstr "Показывать закачки"
+
+#: ./gui.py:93
+msgid "File"
+msgstr "Файл"
+
+#: ./gui.py:94
+msgid "View"
+msgstr "Вид"
+
+#: ./gui.py:95
+msgid "Help"
+msgstr "Помощь"
+
+#: ./gui.py:99
+msgid "Add Downloads"
+msgstr "Добавить загрузки"
+
+#: ./gui.py:100
+msgid "Add Uploads"
+msgstr "Добавить закачки"
+
+#: ./gui.py:101
+msgid "Clear Complete"
+msgstr "Удалить завершенные"
+
+#: ./gui.py:102
+msgid "Move Up"
+msgstr "Выше"
+
+#: ./gui.py:103
+msgid "Move Down"
+msgstr "Ðиже"
+
+#: ./gui.py:104
+msgid "Start Selected"
+msgstr "ЗапуÑтить выбранные"
+
+#: ./gui.py:105
+msgid "Stop Selected"
+msgstr "ОÑтановить выбранные"
+
+#: ./input_links.py:54
+msgid "Input Links"
+msgstr "ВходÑщие ÑÑылки"
+
+#: ./input_links.py:69
+msgid "Paste links here:"
+msgstr "Скопируйте ÑÑылки Ñюда."
+
+#: ./input_links.py:88
+msgid "Check Links"
+msgstr "Проверить ÑÑылки"
+
+#: ./input_links.py:131
+msgid "Show advanced Package configuration."
+msgstr "Показать дополнительные наÑтройки пакетов."
+
+#: ./input_links.py:207
+msgid "Checking links, please wait."
+msgstr "СÑылки проверÑÑŽÑ‚ÑÑ, пожалуйÑта подождите."
+
+#: ./input_links.py:260
+msgid "Check Canceled!"
+msgstr "Проверка была отменена!"
+
+#: ./preferences.py:54
+msgid "General Configuration"
+msgstr "Общие наÑтройки"
+
+#: ./preferences.py:55
+msgid "Service Configuration"
+msgstr "ÐаÑтройки ÑервиÑов"
+
+#: ./preferences.py:56
+msgid "Advanced Configuration"
+msgstr "Дополнительные наÑтройки"
+
+#: ./preferences.py:120
+msgid "Choose language: "
+msgstr "Выберите Ñзык: "
+
+#: ./preferences.py:138
+msgid "Max simultaneous downloads: "
+msgstr "КоличеÑтво одновременных загрузок: "
+
+#: ./preferences.py:173
+msgid "Downloads Folder: "
+msgstr "Папка загрузок: "
+
+#: ./preferences.py:260
+msgid "Restart Tucan to apply service changes."
+msgstr "ПерезапуÑтите программу Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек ÑервиÑов."
+
+#: ./preferences.py:279
+msgid "The choosed directory isn't a service, or it's not configured."
+msgstr "Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° не ÑвлÑетÑÑ ÑервиÑом, или она неправильно наÑтроена."
+
+#: ./preferences.py:307
+msgid "Before using this service, you must accept it's terms of service at "
+msgstr "Прежде чем начать пользоватьÑÑ Ñтим ÑервиÑом вы должны принÑÑ‚ÑŒ его правила иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ адреÑу "
+
+#: ./preferences.py:308
+msgid "Terms of service"
+msgstr "Правила иÑпользованиÑ"
+
+#: ./preferences.py:331
+msgid "Close to tray."
+msgstr "Сворачивать в облаÑÑ‚ÑŒ уведомлений."
+
+#: ./preferences.py:335
+msgid "Save session on close."
+msgstr "СохранÑÑ‚ÑŒ ÑеÑÑию при выходе."
+
+#: ./preferences.py:339
+msgid "Default advanced packages."
+msgstr "Пакеты по умолчанию."
+
+#: ./preferences.py:343
+msgid "Show uploads."
+msgstr "Показывать закачки."
+
+#: ./service_preferences.py:47
+msgid "Author"
+msgstr "Ðвтор"
+
+#: ./service_preferences.py:55
+msgid "Version"
+msgstr "ВерÑиÑ"
+
+#: ./service_preferences.py:64
+msgid "Slots"
+msgstr "Слоты"
+
+#: ./service_preferences.py:71
+msgid "Captcha"
+msgstr "Проверочный код"
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/se/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/se/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/se/se.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/se/se.po
--- tucan-0.3.8/i18n/se/se.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/se/se.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,19 +1,20 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR ORGANIZATION
-# FIRST AUTHOR , YEAR.
+# Tucan Manager.
+# Copyright (C) 2008-2009 The Tucan Project.
+# Christian Widell , 2009.
#
msgid ""
msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: 0.3.7\n"
"POT-Creation-Date: 2009-01-11 22:54+CET\n"
"PO-Revision-Date: 2009-05-03 09:50+0100\n"
-"Last-Translator: Christian Widell \n"
+"Last-Translator: Christian Widell \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
"Generated-By: pygettext.py 1.5\n"
+
#: ./advanced_packages.py:37
msgid "Advanced Packages"
msgstr "Avancerade paket"
@@ -100,7 +101,7 @@
#: ./input_links.py:207
msgid "Checking links, please wait."
-msgstr "Kontrollerar länkar, vänligen vänta"
+msgstr "Kontrollerar länkar, vänligen vänta."
#: ./input_links.py:260
msgid "Check Canceled!"
@@ -120,15 +121,15 @@
#: ./preferences.py:120
msgid "Choose language: "
-msgstr "Välj språk:"
+msgstr "Välj språk: "
#: ./preferences.py:138
msgid "Max simultaneous downloads: "
-msgstr "Max antal parallela nedladdningar:"
+msgstr "Max antal parallela nedladdningar: "
#: ./preferences.py:173
msgid "Downloads Folder: "
-msgstr "Nedladdningsmapp:"
+msgstr "Nedladdningsmapp: "
#: ./preferences.py:260
msgid "Restart Tucan to apply service changes."
@@ -140,7 +141,7 @@
#: ./preferences.py:307
msgid "Before using this service, you must accept it's terms of service at "
-msgstr "Innan du accepterar den här tjänsten måste du acceptera deras användningsvillkor på"
+msgstr "Innan du accepterar den här tjänsten måste du acceptera deras användningsvillkor på "
#: ./preferences.py:308
msgid "Terms of service"
@@ -148,7 +149,7 @@
#: ./preferences.py:331
msgid "Close to tray."
-msgstr "Stäng till notifieringsyta"
+msgstr "Stäng till notifieringsyta."
#: ./preferences.py:335
msgid "Save session on close."
@@ -177,4 +178,3 @@
#: ./service_preferences.py:71
msgid "Captcha"
msgstr "Förhandsvisning"
-
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/sk/LC_MESSAGES/tucan.mo and /tmp/DgSymrsclJ/tucan-0.3.9/i18n/sk/LC_MESSAGES/tucan.mo differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/i18n/sk/sk.po /tmp/DgSymrsclJ/tucan-0.3.9/i18n/sk/sk.po
--- tucan-0.3.8/i18n/sk/sk.po 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/i18n/sk/sk.po 2009-10-07 00:02:27.000000000 +0100
@@ -1,21 +1,22 @@
# Tucan Manager.
# Copyright (C) 2008-2009 The Tucan Project.
-# Tomáš Vadina, 2009.
+# Tomáš Vadina , 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.3.7 alpha\n"
"POT-Creation-Date: 2009-01-11 22:54+CET\n"
"PO-Revision-Date: 2009-04-30 10:30+0100\n"
-"Last-Translator: Tomáš Vadina \n"
-"Language-Team: kyberdev \n"
+"Last-Translator: Tomáš Vadina \n"
+"Language-Team: kyberdev \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Transfer-Encoding: UTF-8\n"
"Generated-By: pygettext.py 1.5\n"
"X-Poedit-Language: Slovak\n"
"X-Poedit-Country: SLOVAKIA\n"
+
#: advanced_packages.py:37
msgid "Advanced Packages"
msgstr "PokroÄilé balÃky"
@@ -122,15 +123,15 @@
#: preferences.py:120
msgid "Choose language: "
-msgstr "Vybrať jazyk:"
+msgstr "Vybrať jazyk: "
#: preferences.py:138
msgid "Max simultaneous downloads: "
-msgstr "Maximum simultánnych sÅ¥ahovanÃ:"
+msgstr "Maximum simultánnych sÅ¥ahovanÃ: "
#: preferences.py:173
msgid "Downloads Folder: "
-msgstr "PrieÄinok sÅ¥ahovania:"
+msgstr "PrieÄinok sÅ¥ahovania: "
#: preferences.py:260
msgid "Restart Tucan to apply service changes."
@@ -142,7 +143,7 @@
#: preferences.py:307
msgid "Before using this service, you must accept it's terms of service at "
-msgstr "Skôr ako zaÄnete použÃvaÅ¥ túto službu, musÃte súhlasiÅ¥ s podmienkami jej použÃvania na"
+msgstr "Skôr ako zaÄnete použÃvaÅ¥ túto službu, musÃte súhlasiÅ¥ s podmienkami jej použÃvania na "
#: preferences.py:308
msgid "Terms of service"
@@ -179,4 +180,3 @@
#: service_preferences.py:71
msgid "Captcha"
msgstr "Captcha"
-
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/input_files.py /tmp/DgSymrsclJ/tucan-0.3.9/input_files.py
--- tucan-0.3.8/input_files.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/input_files.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,295 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-from file_chooser import FileChooser
-
-import cons
-
-SERVICES = [("Megaupload", 100, cons.UNIT_MB, ["Anonymous", "Premium"]), ("Rapidshare", 200, cons.UNIT_MB, ["Collector", "Premium"]), ("Gigasize", 100, cons.UNIT_MB, ["Anonymous"])]
-
-class InputFiles(gtk.Dialog):
- """"""
- def __init__(self, upload_services):
- """"""
- gtk.Dialog.__init__(self)
- self.set_icon_from_file(cons.ICON_UPLOAD)
- self.set_title(("Input Files"))
- self.set_size_request(600,500)
-
- self.history_path = cons.DEFAULT_PATH
-
- main_hbox = gtk.HBox()
- self.vbox.pack_start(main_hbox)
-
- self.file_icon = self.render_icon(gtk.STOCK_FILE, gtk.ICON_SIZE_BUTTON)
- self.correct_icon = self.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
- self.incorrect_icon = self.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
-
- #package treeview
- frame = gtk.Frame()
- main_hbox.pack_start(frame, True)
- frame.set_border_width(5)
- scroll = gtk.ScrolledWindow()
- frame.add(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.package_treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, bool))
- scroll.add(self.package_treeview)
-
- self.package_treeview.set_rules_hint(True)
- self.package_treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- tree_icon.pack_start(icon_cell, True)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.package_treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- self.package_treeview.append_column(tree_name)
-
- tree_size = gtk.TreeViewColumn('Size')
- size_cell = gtk.CellRendererText()
- tree_size.pack_start(size_cell, False)
- tree_size.add_attribute(size_cell, 'text', 2)
- self.package_treeview.append_column(tree_size)
-
- service_vbox = gtk.VBox()
- main_hbox.pack_start(service_vbox, False, False)
-
- # services treeview
- frame = gtk.Frame()
- service_vbox.pack_start(frame)
- frame.set_size_request(200, -1)
- frame.set_border_width(5)
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_PREFERENCES_SERVICES))
- scroll = gtk.ScrolledWindow()
- frame.add(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- services = gtk.ListStore(gtk.gdk.Pixbuf, str, int, str, bool, gobject.TYPE_PYOBJECT)
- self.services_treeview = gtk.TreeView(services)
- self.services_treeview.get_selection().connect("changed", self.select)
- scroll.add(self.services_treeview)
-
- self.services_treeview.set_rules_hint(True)
- self.services_treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- tree_icon.pack_start(icon_cell, True)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.services_treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- self.services_treeview.append_column(tree_name)
-
- tree_add = gtk.TreeViewColumn('Add')
- add_cell = gtk.CellRendererToggle()
- add_cell.connect("toggled", self.toggled)
- tree_add.pack_start(add_cell, True)
- tree_add.add_attribute(add_cell, 'active', 4)
- self.services_treeview.append_column(tree_add)
-
- #plugins
- self.plugins_frame = gtk.Frame()
- service_vbox.pack_start(self.plugins_frame, False, False)
- self.plugins_frame.set_size_request(200, 100)
- self.plugins_frame.set_border_width(5)
-
- for service, size, unit, plugins in upload_services:
- vbox = gtk.VBox()
- first = None
- for plugin in plugins:
- first = gtk.RadioButton(first, plugin)
- vbox.pack_start(first, False, False, 1)
- services.append([self.correct_icon, service, size, unit, False, vbox])
-
- #choose path
- hbox = gtk.HBox()
- self.vbox.pack_start(hbox, False, False, 5)
- path_button = gtk.Button(None, gtk.STOCK_OPEN)
- path_button.set_size_request(90,40)
- hbox.pack_start(path_button, False, False, 5)
- path_button.connect("clicked", self.choose_files)
- path_label = gtk.Label(("Choose files to upload."))
- hbox.pack_start(path_label, False, False, 5)
- aspect = gtk.AspectFrame()
- hbox.pack_start(aspect, True, True)
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- clear_button = gtk.Button(None, gtk.STOCK_CLEAR)
- clear_button.set_size_request(190,40)
- hbox.pack_start(clear_button, False, False, 5)
- clear_button.connect("clicked", self.clear)
-
- #action area
- cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
- add_button = gtk.Button(None, gtk.STOCK_ADD)
- self.action_area.pack_start(cancel_button)
- self.action_area.pack_start(add_button)
- cancel_button.connect("clicked", self.close)
- add_button.connect("clicked", self.add_files)
-
- self.connect("response", self.close)
- self.show_all()
- self.set_focus(path_button)
- self.run()
-
- def clear(self, button):
- """"""
- self.package_treeview.get_model().clear()
-
- def select(self, selection):
- """"""
- model, service_iter = selection.get_selected()
- if iter:
- if self.plugins_frame.get_child():
- self.plugins_frame.remove(self.plugins_frame.get_child())
- vbox = model.get_value(service_iter, 5)
- self.plugins_frame.add(vbox)
- vbox.show_all()
-
- def add_files(self, button):
- """"""
- result = []
- package_model = self.package_treeview.get_model()
- services_model = self.services_treeview.get_model()
-
- file_iter = package_model.get_iter_root()
- while file_iter:
- services = []
- service_iter = package_model.iter_children(file_iter)
- while service_iter:
- service_name = package_model.get_value(service_iter, 1)
- if package_model.get_value(service_iter, 4):
- for service in services_model:
- if service[1] == service_name:
- for button in service[5].get_children():
- if button.get_active():
- services.append((service_name, button.get_label()))
- service_iter = package_model.iter_next(service_iter)
- if len(services) > 0:
- tmp = package_model.get_value(file_iter, 2).split(" ")
- size, unit = self.split_size(self.join_size(int(tmp[0]), tmp[1]))
- result.append((package_model.get_value(file_iter, 3), int(size), unit, services))
- file_iter = package_model.iter_next(file_iter)
- self.close()
- print result
-
- def toggled(self, button, path):
- """"""
- active = True
- if button.get_active():
- active = False
- button.set_active(active)
-
- services_model = self.services_treeview.get_model()
- package_model = self.package_treeview.get_model()
-
- services_model.set_value(services_model.get_iter(path), 4, active)
-
- file_iter = package_model.get_iter_root()
- while file_iter:
- service_iter = package_model.iter_children(file_iter)
- found = False
- while service_iter:
- if services_model.get_value(services_model.get_iter(path), 1) == package_model.get_value(service_iter, 1):
- found = True
- break
- service_iter = package_model.iter_next(service_iter)
- if active:
- if not found:
- tmp = package_model.get_value(file_iter, 2).split(" ")
- max_size = self.join_size(services_model.get_value(services_model.get_iter(path), 2), services_model.get_value(services_model.get_iter(path), 3))
- self.add_service(package_model, file_iter, services_model.get_value(services_model.get_iter(path), 1), self.join_size(int(tmp[0]), tmp[1]), max_size)
- else:
- if found:
- package_model.remove(service_iter)
- file_iter = package_model.iter_next(file_iter)
-
- def choose_files(self, button):
- """"""
- f = FileChooser(self, self.on_choose, self.history_path, True)
- self.history_path = f.history_path
-
- def on_choose(self, path):
- """"""
- package_model = self.package_treeview.get_model()
- services_model = self.services_treeview.get_model()
- if os.path.isfile(path):
- if path not in [row[1] for row in package_model]:
- file_size = int(os.stat(path).st_size/1024)
- size, unit = self.split_size(file_size)
- file_iter = package_model.append(None, [self.file_icon, os.path.basename(path), "%i %s" %(size, unit), path, None])
- for row in services_model:
- if row[4]:
- self.add_service(package_model, file_iter, row[1], file_size, self.join_size(row[2], row[3]))
-
- def join_size(self, size, unit):
- """"""
- factor = 1
- if unit == cons.UNIT_KB:
- factor = 1
- elif unit == cons.UNIT_MB:
- factor = 1024
- elif unit == cons.UNIT_GB:
- factor = 1024*1024
- return size*factor
-
- def split_size(self, size):
- """"""
- if size > 0:
- tmp = size/1024
- if tmp > 0:
- tmp2 = tmp/1024
- if tmp2 > 0:
- return tmp2, cons.UNIT_GB
- else:
- return tmp, cons.UNIT_MB
- else:
- return size, cons.UNIT_KB
- else:
- return 1, cons.UNIT_KB
-
- def add_service(self, package_model, file_iter, service, file_size, max_size):
- """"""
- if max_size > file_size:
- package_model.append(file_iter, [self.correct_icon, service, None, None, True])
- else:
- package_model.append(file_iter, [self.incorrect_icon, service, None, None, False])
- self.package_treeview.expand_row(package_model.get_path(file_iter), True)
-
- def close(self, widget=None, other=None):
- """"""
- self.destroy()
-
-if __name__ == "__main__":
- x = InputFiles(SERVICES)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/input_links.py /tmp/DgSymrsclJ/tucan-0.3.9/input_links.py
--- tucan-0.3.8/input_links.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/input_links.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,296 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import HTMLParser
-import threading
-import logging
-logger = logging.getLogger(__name__)
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-from message import Wait, Message
-from advanced_packages import AdvancedPackages
-
-import cons
-
-class ClipParser(HTMLParser.HTMLParser):
- """"""
- def __init__(self):
- """"""
- HTMLParser.HTMLParser.__init__(self)
- self.url = []
-
- def handle_starttag(self, tag, attrs):
- """"""
- if tag == "a":
- for ref, link in attrs:
- if ref == "href":
- self.url.append(link)
-
-class InputLinks(gtk.Dialog):
- """"""
- def __init__(self, path, sort, check, create, manage, show_advanced_packages):
- """"""
- gtk.Dialog.__init__(self)
- self.set_icon_from_file(cons.ICON_DOWNLOAD)
- self.set_title(_("Input Links"))
- self.set_size_request(600,500)
-
- self.cancel_check = False
-
- self.clipboard = gtk.clipboard_get()
- self.clipboard.request_targets(self.get_clipboard)
-
- self.default_path = path
- self.sort_links = sort
- self.check_links = check
- self.create_packages = create
- self.packages = manage
-
- #textview
- frame = gtk.Frame(_("Paste links here:"))
- self.vbox.pack_start(frame)
- frame.set_border_width(10)
- hbox = gtk.HBox()
- frame.add(hbox)
- scroll = gtk.ScrolledWindow()
- hbox.pack_start(scroll, True, True, 10)
- scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- #auto scroll
- scroll.get_vadjustment().connect("changed", self.changed)
- scroll.get_vadjustment().connect("value-changed", self.value_changed)
- buffer = gtk.TextBuffer()
- self.textview = gtk.TextView(buffer)
- scroll.add(self.textview)
- self.textview.set_wrap_mode(gtk.WRAP_CHAR)
-
- #check button
- button_box = gtk.HButtonBox()
- hbox.pack_start(button_box, False, False, 10)
- vbox = gtk.VBox()
- check_image = gtk.image_new_from_file(cons.ICON_CHECK)
- vbox.pack_start(check_image)
- check_label = gtk.Label(_("Check Links"))
- vbox.pack_start(check_label)
- check_button = gtk.Button()
- check_button.add(vbox)
- button_box.pack_start(check_button)
- check_button.connect("clicked", self.check)
-
- #treeview
- frame = gtk.Frame()
- self.vbox.pack_start(frame)
- frame.set_border_width(10)
- scroll = gtk.ScrolledWindow()
- frame.add(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- #auto scroll
- scroll.get_vadjustment().connect("changed", self.changed)
- scroll.get_vadjustment().connect("value-changed", self.value_changed)
-
- self.treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, int, str, str, bool, bool))
- scroll.add(self.treeview)
-
- self.treeview.set_rules_hint(True)
- self.treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- tree_icon.pack_start(icon_cell, True)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- name_cell.set_property("editable", True)
- name_cell.connect("edited", self.change_name)
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 2)
- self.treeview.append_column(tree_name)
-
- tree_add = gtk.TreeViewColumn('Add')
- add_cell = gtk.CellRendererToggle()
- add_cell.connect("toggled", self.toggled)
- tree_add.pack_start(add_cell, True)
- tree_add.add_attribute(add_cell, 'active', 6)
- tree_add.add_attribute(add_cell, 'visible', 7)
- self.treeview.append_column(tree_add)
-
- #advanced checkbutton
- self.advanced_button = gtk.CheckButton(_("Show advanced Package configuration."))
- self.advanced_button.set_active(show_advanced_packages)
- self.vbox.pack_start(self.advanced_button, False)
-
- #action area
- cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
- add_button = gtk.Button(None, gtk.STOCK_ADD)
- self.action_area.pack_start(cancel_button)
- self.action_area.pack_start(add_button)
- cancel_button.connect("clicked", self.close)
- add_button.connect("clicked", self.add_links)
-
- self.connect("response", self.close)
- self.show_all()
- self.run()
-
- def changed(self, vadjust):
- """autoscroll"""
- if not hasattr(vadjust, "need_scroll") or vadjust.need_scroll:
- vadjust.set_value(vadjust.upper-vadjust.page_size)
- vadjust.need_scroll = True
-
- def value_changed (self, vadjust):
- """autoscroll"""
- vadjust.need_scroll = abs(vadjust.value + vadjust.page_size - vadjust.upper) < vadjust.step_increment
-
- def change_name(self, cellrenderertext, path, new_text):
- """"""
- model = self.treeview.get_model()
- model.set_value(model.get_iter(path), 2, new_text)
-
- def get_clipboard(self, clipboard, selection_data, data):
- """"""
- target_html = "text/html"
- if target_html in list(selection_data):
- selection = self.clipboard.wait_for_contents(target_html)
- if selection:
- for line in str(selection.data.decode("utf16")).split("\n"):
- try:
- parser = ClipParser()
- parser.feed(line)
- parser.close()
- if len(parser.url) > 0:
- self.textview.get_buffer().insert_at_cursor("\n".join(parser.url) + "\n")
- except HTMLParser.HTMLParseError:
- pass
- def toggled(self, button, path):
- """"""
- model = self.treeview.get_model()
- active = True
- if button.get_active():
- active = False
- button.set_active(active)
- model.set_value(model.get_iter(path), 6, active)
-
- def add_links(self, button):
- """"""
- tmp = {}
- store = self.treeview.get_model()
- for column in store:
- if column[2] != cons.TYPE_UNSUPPORTED:
- tmp[column[2]] = []
- for value in column.iterchildren():
- if value[1] != value[2]:
- if value[6]:
- logger.info("Added: %s %s %s %s %s" % (value[1], value[2], value[3], value[4], value[5]))
- tmp[column[2]].append((value[1], value[2], value[3], value[4], value[5]))
- if tmp != {}:
- self.hide()
- packages = self.create_packages(tmp)
- packages_info = None
- if self.advanced_button.get_active():
- w = AdvancedPackages(self.default_path, packages)
- packages_info = w.packages
- if packages_info:
- self.packages(packages, packages_info)
- self.close()
- else:
- self.show()
- else:
- self.packages(packages, [])
- self.close()
- else:
- title = _("Input Links - Nothing to add.")
- message = _("There aren't links to add.\nPlease check the links before adding.")
- m = Message(self, cons.SEVERITY_INFO, title, message, both=True)
- if not m.accepted:
- self.close()
-
- def check(self, button):
- """"""
- w = Wait(_("Checking links, please wait."), self)
- w.connect("key-press-event", self.cancel)
- th = threading.Thread(group=None, target=self.check_all, name=None, args=(w,))
- th.start()
-
- def check_all(self, wait):
- """"""
- store = self.treeview.get_model()
- store.clear()
- buffer = self.textview.get_buffer()
- start, end = buffer.get_bounds()
- link_list = [link.strip() for link in buffer.get_text(start, end).split("\n")]
-
- service_icon = self.treeview.render_icon(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
- unsupported_icon = self.treeview.render_icon(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_MENU)
- active_icon = self.treeview.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
- unchecked_icon = self.treeview.render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_MENU)
- unactive_icon = self.treeview.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
- try:
- for service, links in self.sort_links(link_list).items():
- if links != []:
- if service == cons.TYPE_UNSUPPORTED:
- service_iter = store.append(None, [unsupported_icon, service, service, 0, None, None, False, False])
- for link in links:
- store.append(service_iter, [unchecked_icon, link, link, 0, None, None, False, False])
- else:
- service_iter = store.append(None, [service_icon, service, service, 0, None, None, False, False])
- for link in links:
- if self.cancel_check:
- self.cancel_check = False
- raise Exception("Check Links cancelled")
- check, plugin_type = self.check_links(service)
- file_name, size, size_unit = check(link)
- if file_name:
- if size > 0:
- icon = active_icon
- marked = True
- else:
- icon = unchecked_icon
- marked = False
- else:
- icon = unactive_icon
- marked = False
- file_name = link
- logger.info("Checked: %s %s %s" % (file_name, size, size_unit))
- store.append(service_iter, [icon, link, file_name, size, size_unit, plugin_type, marked, marked])
- self.treeview.expand_row(store.get_path(service_iter), True)
- except:
- gobject.idle_add(wait.destroy)
- else:
- buffer.set_text("")
- gobject.idle_add(wait.destroy)
-
- def cancel(self, window, event):
- """Esc key"""
- if event.keyval == 65307:
- window.progress.set_text(_("Check Canceled!"))
- self.cancel_check = True
-
- def close(self, widget=None, other=None):
- """"""
- self.destroy()
-
-if __name__ == "__main__":
- x = InputLinks(None, None, None)
- gtk.main()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/log_view.py /tmp/DgSymrsclJ/tucan-0.3.9/log_view.py
--- tucan-0.3.8/log_view.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/log_view.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,147 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-import cons
-
-SEVERITY = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
-COLORS = {"DEBUG": "grey", "INFO": "green", "WARNING": "yellow", "ERROR": "red", "CRITICAL": "white"}
-
-class LogView(gtk.Dialog):
- """"""
- def __init__(self, widget=None):
- """"""
- gtk.Dialog.__init__(self)
- self.set_title("Log View")
- self.set_size_request(700,500)
- self.set_icon(self.render_icon(gtk.STOCK_FILE, gtk.ICON_SIZE_MENU))
-
- self.file = open(cons.LOG_FILE, "r")
- self.back_buffer = gtk.TextBuffer()
- self.back_buffer.set_text(self.file.read())
-
- frame = gtk.Frame()
- self.vbox.pack_start(frame)
- frame.set_border_width(10)
- hbox = gtk.HBox()
- frame.add(hbox)
-
- #auto scroll
- scroll = gtk.ScrolledWindow()
- hbox.pack_start(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scroll.get_vadjustment().connect("changed", self.changed)
- scroll.get_vadjustment().connect("value-changed", self.value_changed)
-
- #textview
- buffer = gtk.TextBuffer()
- self.textview = gtk.TextView(buffer)
- scroll.add(self.textview)
- self.textview.set_wrap_mode(gtk.WRAP_NONE)
- self.textview.set_editable(False)
- self.textview.set_cursor_visible(False)
- self.textview.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("black"))
-
- table = buffer.get_tag_table()
- for name, color in COLORS.items():
- tag = gtk.TextTag(name)
- tag.set_property("foreground", color)
- tag.set_property("left_margin", 10)
- tag.set_property("right_margin", 10)
- table.add(tag)
-
- #combo
- hbox = gtk.HBox()
- self.vbox.pack_start(hbox, False, False, 10)
- buttonbox = gtk.HButtonBox()
- hbox.pack_start(buttonbox, False, False, 10)
- label = gtk.Label("Minimum severity shown.")
- hbox.pack_start(label, False, False, 10)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- hbox.pack_start(aspect)
-
- self.combo = gtk.combo_box_new_text()
- buttonbox.pack_start(self.combo)
- self.combo.connect("changed", self.reload)
-
- for s in SEVERITY:
- self.combo.append_text(s)
- self.combo.set_active(2)
-
- #action area
- button = gtk.Button(None, gtk.STOCK_CLOSE)
- self.action_area.pack_start(button)
- button.connect("clicked", self.close)
-
- self.connect("response", self.close)
- self.show_all()
-
- gobject.timeout_add(1000, self.update)
- self.run()
-
- def insert_color(self, buffer, line):
- """"""
- for s in SEVERITY[self.combo.get_active():]:
- if s in line:
- buffer.insert_with_tags(buffer.get_end_iter(), "%s\n" % line, buffer.get_tag_table().lookup(s))
- break
-
- def reload(self, textview):
- """"""
- buffer = self.textview.get_buffer()
- buffer.set_text("")
- ini, fin = self.back_buffer.get_bounds()
- for line in self.back_buffer.get_text(ini, fin).split("\n"):
- self.insert_color(buffer, line)
-
- def update(self):
- """"""
- try:
- buffer = self.textview.get_buffer()
- for line in self.file.readlines():
- self.back_buffer.insert(self.back_buffer.get_end_iter(), line)
- self.insert_color(buffer, line.strip())
- except:
- pass
- else:
- return True
-
- def changed(self, vadjust):
- """autoscroll"""
- if not hasattr(vadjust, "need_scroll") or vadjust.need_scroll:
- vadjust.set_value(vadjust.upper-vadjust.page_size)
- vadjust.need_scroll = True
-
- def value_changed (self, vadjust):
- """autoscroll"""
- vadjust.need_scroll = abs(vadjust.value + vadjust.page_size - vadjust.upper) < vadjust.step_increment
-
- def close(self, widget=None, other=None):
- """"""
- self.file.close()
- self.destroy()
-
-if __name__ == "__main__":
- c = LogView()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/Makefile /tmp/DgSymrsclJ/tucan-0.3.9/Makefile
--- tucan-0.3.8/Makefile 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/Makefile 2009-10-07 00:02:31.000000000 +0100
@@ -30,9 +30,11 @@
ICONFILE = tucan.svg
MANPAGE = tucan.1.gz
DESKTOPFILE = tucan.desktop
+COREDIR = core/
PLUGINDIR = default_plugins/
I18NDIR = i18n/
MEDIADIR = media/
+UIDIR = ui/
basic-install:
mkdir -p $(BINDIR) $(MAINDIR) $(ICONDIR) $(MANDIR) $(DESKTOPDIR)
@@ -40,9 +42,11 @@
install -p -m 0644 *.py $(MAINDIR)
chmod 0755 $(MAINDIR)$(EXECFILE)
+ cp -pR $(COREDIR) $(MAINDIR)
cp -pR $(PLUGINDIR) $(MAINDIR)
cp -pR $(I18NDIR) $(MAINDIR)
cp -pR $(MEDIADIR) $(MAINDIR)
+ cp -pR $(UIDIR) $(MAINDIR)
install -p -m 0644 $(MEDIADIR)$(ICONFILE) $(ICONDIR)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/media/mail-reply-sender.svg /tmp/DgSymrsclJ/tucan-0.3.9/media/mail-reply-sender.svg
--- tucan-0.3.8/media/mail-reply-sender.svg 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/media/mail-reply-sender.svg 2009-10-07 00:02:26.000000000 +0100
@@ -0,0 +1,548 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+ Mail Reply
+
+
+ Garrett LeSage
+
+
+
+
+ Jakub Steiner, Andreas Nilsson
+
+
+
+
+
+ mail
+ e-mail
+ reply
+ sender
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/menu_bar.py /tmp/DgSymrsclJ/tucan-0.3.9/menu_bar.py
--- tucan-0.3.8/menu_bar.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/menu_bar.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,45 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-class MenuBar(gtk.MenuBar):
- """"""
- def __init__(self, list):
- """list = [(menu_name=str, [(item_image=stock_item, callback), None=separator])]"""
- gtk.MenuBar.__init__(self)
- for menu in list:
- item = gtk.MenuItem(menu[0])
- self.append(item)
- submenu = gtk.Menu()
- for sub in menu[1]:
- if sub == None:
- subitem = gtk.SeparatorMenuItem()
- elif isinstance(sub[0], gtk.CheckMenuItem):
- subitem = sub[0]
- subitem.set_active(sub[2])
- subitem.connect("toggled", sub[1])
- else:
- subitem = gtk.ImageMenuItem(sub[0])
- subitem.connect("activate", sub[1])
- submenu.append(subitem)
- item.set_submenu(submenu)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/message.py /tmp/DgSymrsclJ/tucan-0.3.9/message.py
--- tucan-0.3.8/message.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/message.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,113 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-import cons
-
-class Wait(gtk.Window):
- """"""
- def __init__(self, message, parent):
- """"""
- gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
- self.set_transient_for(parent)
- self.set_modal(True)
- self.set_position(gtk.WIN_POS_CENTER)
- self.set_property("skip-pager-hint", True)
- self.set_property("skip-taskbar-hint", True)
- self.set_resizable(False)
- self.set_decorated(False)
- self.set_size_request(300,100)
-
- self.progress = gtk.ProgressBar()
- self.add(self.progress)
- self.progress.set_text(message)
-
- self.show_all()
-
- gobject.timeout_add(100, self.pulse)
-
- def pulse(self):
- """"""
- self.progress.pulse()
- return True
-
-class Message(gtk.Dialog):
- """"""
- def __init__(self, parent, severity, title, message, accept=False, both=False):
- """"""
- gtk.Dialog.__init__(self)
- self.set_title(title)
- self.set_position(gtk.WIN_POS_CENTER)
- self.set_resizable(False)
- self.set_transient_for(parent)
-
- self.accepted = False
-
- hbox = gtk.HBox()
- self.vbox.pack_start(hbox, True, True, 10)
- icon = gtk.STOCK_DIALOG_INFO
- if severity == cons.SEVERITY_WARNING:
- icon = gtk.STOCK_DIALOG_WARNING
- elif severity == cons.SEVERITY_ERROR:
- icon = gtk.STOCK_DIALOG_ERROR
- hbox.pack_start(gtk.image_new_from_stock(icon, gtk.ICON_SIZE_DIALOG), True, False, 10)
- self.set_icon(self.render_icon(icon, gtk.ICON_SIZE_MENU))
-
- label = gtk.Label(message)
- hbox.pack_start(label, True, False, 5)
- label.set_width_chars(35)
- label.set_line_wrap(True)
-
- #action area
- if both:
- close_button = gtk.Button(None, gtk.STOCK_CANCEL)
- self.action_area.pack_start(close_button)
- close_button.connect("clicked", self.close)
- ok_button = gtk.Button(None, gtk.STOCK_OK)
- self.action_area.pack_start(ok_button)
- ok_button.connect("clicked", self.accept)
- elif accept:
- ok_button = gtk.Button(None, gtk.STOCK_OK)
- self.action_area.pack_start(ok_button)
- ok_button.connect("clicked", self.accept)
- else:
- close_button = gtk.Button(None, gtk.STOCK_CLOSE)
- self.action_area.pack_start(close_button)
- close_button.connect("clicked", self.close)
-
- self.connect("response", self.close)
- self.show_all()
- self.run()
-
- def accept(self, button):
- """"""
- self.accepted = True
- self.close()
-
- def close(self, widget=None, other=None):
- """"""
- self.destroy()
-
-if __name__ == "__main__":
- m = Message(None, cons.SEVERITY_WARNING, "Tucan Manager - Restore previous session.", "Your last session closed unexpectedly.\nTucan will try to restore it now.", both=True)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/arch/PKGBUILD /tmp/DgSymrsclJ/tucan-0.3.9/packages/arch/PKGBUILD
--- tucan-0.3.8/packages/arch/PKGBUILD 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/arch/PKGBUILD 2009-10-07 00:02:31.000000000 +0100
@@ -3,13 +3,13 @@
# Note: The pakage's host puts a random number in tarball's link. New var added for this "pkgrediris".
pkgname=tucan
-pkgver=0.3.5
-pkgrel=2
-pkgrediris=1135
+pkgver=0.3.8
+pkgrel=1
+pkgrediris=1400
pkgdesc="Download and upload manager for hosting sites."
arch=('i686' 'x86_64')
-url="http://cusl3-tucan.forja.rediris.es/"
-license=('GPLv2')
+url="http://tucaneando.com/"
+license=('GPLv3')
groups=()
depends=('python' 'pygtk' 'pil' 'tesseract' 'librsvg')
makedepends=()
@@ -18,7 +18,7 @@
backup=()
install=${pkgname}.install
source=(http://forja.rediris.es/frs/download.php/$pkgrediris/$pkgname-$pkgver.tar.gz)
-md5sums=('229f88beef7ea52a29dabba08fab6d7a')
+md5sums=('3e27a9b17f67d8523950522366b18b77')
build() {
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/changelog /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/changelog
--- tucan-0.3.8/packages/debian/changelog 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/changelog 2009-10-07 00:02:28.000000000 +0100
@@ -1,12 +1,22 @@
+tucan (0.3.8-1) unstable; urgency=low
+
+ * New upstream release
+ * debian-policy updated to 3.8.2
+ * License upgraded to GPLv3
+ * New upstream/maintainer mail
+ * Solved data loss (Closes: #531392)
+
+ -- Fran Lupion (Crak) Wed, 15 Jul 2009 22:54:52 +0200
+
tucan (0.3.7-1) unstable; urgency=low
* New upstream release
* Uploaded to debian (Closes: #520470)
- -- Fran Lupion (Crak) Sun, 19 Apr 2009 19:39:32 +0200
+ -- Fran Lupion (Crak) Sun, 19 Apr 2009 19:39:32 +0200
tucan (0.3.6-1) unstable; urgency=low
* Initial release
- -- Fran Lupion (Crak) Tue, 07 Apr 2009 19:23:20 +0200
+ -- Fran Lupion (Crak) Tue, 07 Apr 2009 19:23:20 +0200
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/control /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/control
--- tucan-0.3.8/packages/debian/control 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/control 2009-10-07 00:02:28.000000000 +0100
@@ -1,10 +1,10 @@
Source: tucan
Section: net
Priority: optional
-Maintainer: Fran Lupion (Crak)
+Maintainer: Fran Lupion (Crak)
Build-Depends: debhelper (>= 7)
-Standards-Version: 3.8.1
-Homepage: http://cusl3-tucan.forja.rediris.es/
+Standards-Version: 3.8.2
+Homepage: http://www.tucaneando.com
Package: tucan
Architecture: all
@@ -16,6 +16,11 @@
- http://gigasize.com/
- http://mediafire.com/
- http://4shared.com/
+ - http://sendspace.com/
+ - http://zshare.net/
+ - http://filefactory.com/
+ - http://easy-share.com/
+ - http://badongo.com/
- (...)
Main Features:
- Graphical User Interface in GTK+.
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/copyright /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/copyright
--- tucan-0.3.8/packages/debian/copyright 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/copyright 2009-10-07 00:02:28.000000000 +0100
@@ -1,14 +1,14 @@
This package was debianized by:
- Fran Lupion (Crak) on Tue, 07 Apr 2009 19:23:20 +0200
+ Fran Lupion (Crak) on Tue, 07 Apr 2009 19:23:20 +0200
It was downloaded from:
-
+
Upstream Author:
- Fran Lupion (Crak)
+ Fran Lupion (Crak)
Copyright:
@@ -18,7 +18,7 @@
This package 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 2 of the License, or
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This package is distributed in the hope that it will be useful,
@@ -31,12 +31,12 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
-Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
+Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'.
The Debian packaging is:
- Copyright (C) 2009 Fran Lupion (Crak)
+ Copyright (C) 2009 Fran Lupion (Crak)
-and is licensed under the GPL version 2,
-see `/usr/share/common-licenses/GPL-2'.
+and is licensed under the GPL version 3,
+see `/usr/share/common-licenses/GPL-3'.
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/files /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/files
--- tucan-0.3.8/packages/debian/files 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/files 2009-10-07 00:02:28.000000000 +0100
@@ -1 +1 @@
-tucan_0.3.7-1_all.deb net optional
+tucan_0.3.8-1_all.deb net optional
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/scripts/tucan /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/scripts/tucan
--- tucan-0.3.8/packages/debian/scripts/tucan 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/scripts/tucan 2009-10-07 00:02:28.000000000 +0100
@@ -1,2 +1,2 @@
#!/bin/sh
-python /usr/share/tucan/tucan.py
\ No newline at end of file
+python /usr/share/tucan/tucan.py
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/tucan.debhelper.log /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/tucan.debhelper.log
--- tucan-0.3.8/packages/debian/tucan.debhelper.log 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/tucan.debhelper.log 1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-dh_prep
-dh_installchangelogs
-dh_installdocs
-dh_installmenu
-dh_installman
-dh_compress
-dh_fixperms
-dh_installdeb
-dh_gencontrol
-dh_md5sums
-dh_builddeb
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/debian/tucan.substvars /tmp/DgSymrsclJ/tucan-0.3.9/packages/debian/tucan.substvars
--- tucan-0.3.8/packages/debian/tucan.substvars 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/debian/tucan.substvars 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-misc:Depends=
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/layman.txt /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/layman.txt
--- tucan-0.3.8/packages/gentoo/layman.txt 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/layman.txt 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ http://tucaneando.com/
+
+
+
+ Tucan unofficial overlay
+
+
+
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/Manifest /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/Manifest
--- tucan-0.3.8/packages/gentoo/Manifest 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/Manifest 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-DIST tucan-0.3.7.tar.gz 199208 RMD160 628a0818f251293e4e01b9c278411dac51a0ec69 SHA1 ec70756f6c2501a42a95f59f99da40eda551d951 SHA256 56eb1038f1ddef4a82f72f74cf472edbd26679d0f8d27c40e7e6703fe575b683
-EBUILD tucan-0.3.7.ebuild 823 RMD160 a85f98fee7718df7e7102781fe352c8cb551c2a9 SHA1 7d0596c485a88caca8a4e2a61b9e0a55ed962e74 SHA256 893dc541790d69218f8e867c4f4c8e00c25147a6f85b1ca9b240a92fd0609014
-MISC tucan-0.3.7.ebuild-back 1191 RMD160 204c7d0e3a5a87d16fdacd019508c892371b43df SHA1 3ef2aa062b518464f4c8a3282861a7f7311606ce SHA256 2b49446e17b248deab81955ba9fc73e07e1213db8c4581da3e7de117f7c2ac41
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/Manifest /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/Manifest
--- tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/Manifest 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/Manifest 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1,5 @@
+DIST tucan-0.3.7.tar.gz 199208 RMD160 628a0818f251293e4e01b9c278411dac51a0ec69 SHA1 ec70756f6c2501a42a95f59f99da40eda551d951 SHA256 56eb1038f1ddef4a82f72f74cf472edbd26679d0f8d27c40e7e6703fe575b683
+DIST tucan-0.3.8.tar.gz 184714 RMD160 3acb31016dc6093e121948a77d857f2262e4218c SHA1 aa7ea520838359229d57fc50ef03b132c4e5a995 SHA256 dd9acb147bdb229a5acd52213b1ddc57fea02cc0eec065b51c9278f15a181b30
+EBUILD tucan-0.3.7.ebuild 822 RMD160 8bc43194da4e9ac199d04b5f6c7a151dbd942cb3 SHA1 d93e77a8a61636d67838bbafc250a76773242c80 SHA256 102fe408b94b5698f6893074ec39844f2ec2177e82ef291ad2d093d7fd06be4d
+EBUILD tucan-0.3.8.ebuild 777 RMD160 9f0f26c42961980c1ed5e074d5d244de4060f35b SHA1 5649a9014e619fd43923d043d92dfeee239fb40c SHA256 c33b3a85a8c14ff15cc618f01b3d6ac8858e50f66ba758284202db20ef311d5c
+EBUILD tucan-9999.ebuild 658 RMD160 8c1d8e0754fa5450a8e3d27956056f3cea59fc43 SHA1 d7694fb49853a5ac4b904facac7cb518b75d4d87 SHA256 e4857434eb6840dad08d6fcb1df0064dd4e88b7abed2a86ae3262302e19940f8
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.7.ebuild /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.7.ebuild
--- tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.7.ebuild 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.7.ebuild 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1,33 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils
+
+DESCRIPTION="Software designed for automatic management of downloads and uploads at hosting sites like rapidshare or megaupload"
+HOMEPAGE="http://cusl3-tucan.forja.rediris.es"
+SRC_URI="http://forja.rediris.es/frs/download.php/1290/${P}.tar.gz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~x86 ~amd64"
+
+IUSE=""
+DEPEND="dev-lang/python
+ dev-python/pygtk
+ dev-python/imaging
+ app-text/tesseract[linguas_en]
+ gnome-base/librsvg"
+
+src_compile() {
+ sed -i \
+ -e '/^DESTDIR/d' \
+ Makefile || die "sed failed"
+}
+
+src_install() {
+ emake DESTDIR="${D}"/usr install || die "emake install failed"
+ dodoc CHANGELOG README || die
+ newicon media/tucan.svg "${PN}.svg"
+ make_desktop_entry tucan Tucan
+}
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.8.ebuild /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.8.ebuild
--- tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.8.ebuild 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-0.3.8.ebuild 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1,32 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils
+
+DESCRIPTION="Software designed for automatic management of downloads and uploads at hosting sites like rapidshare or megaupload"
+HOMEPAGE="http://tucaneando.com/"
+SRC_URI="http://forja.rediris.es/frs/download.php/1400/${P}.tar.gz"
+
+LICENSE="GPLv3"
+SLOT="0"
+KEYWORDS="~x86 ~amd64"
+
+IUSE=""
+DEPEND="dev-lang/python
+ dev-python/pygtk
+ dev-python/imaging
+ app-text/tesseract[linguas_en]
+ gnome-base/librsvg"
+
+src_compile() {
+ sed -i \
+ -e '/^DESTDIR/d' \
+ Makefile || die "sed failed"
+}
+
+src_install() {
+ emake DESTDIR="${D}"/usr install || die "emake install failed"
+ dodoc CHANGELOG README || die
+ newicon media/tucan.svg "${PN}.svg"
+}
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-9999.ebuild /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-9999.ebuild
--- tucan-0.3.8/packages/gentoo/overlay/net-misc/tucan/tucan-9999.ebuild 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/overlay/net-misc/tucan/tucan-9999.ebuild 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1,32 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit subversion
+
+ESVN_REPO_URI="https://forja.rediris.es/svn/cusl3-tucan/trunk/"
+ESVN_PROJECT="tucan-svn"
+ESVN_STORE_DIR="${D}/svn-src"
+
+LICENSE="GPLv3"
+SLOT="0"
+KEYWORDS=""
+
+IUSE=""
+DEPEND="dev-lang/python
+ dev-python/pygtk
+ dev-python/imaging
+ app-text/tesseract[linguas_en]
+ gnome-base/librsvg"
+
+src_compile() {
+ sed -i \
+ -e '/^DESTDIR/d' \
+ Makefile || die "sed failed"
+}
+
+src_install() {
+ emake DESTDIR="${D}"/usr install || die "emake install failed"
+ dodoc CHANGELOG README || die
+ newicon media/tucan.svg "${PN}.svg"
+}
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/overlay/profiles/repo_name /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/overlay/profiles/repo_name
--- tucan-0.3.8/packages/gentoo/overlay/profiles/repo_name 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/overlay/profiles/repo_name 2009-10-07 00:02:31.000000000 +0100
@@ -0,0 +1 @@
+tucan-overlay
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/gentoo/tucan-0.3.7.ebuild /tmp/DgSymrsclJ/tucan-0.3.9/packages/gentoo/tucan-0.3.7.ebuild
--- tucan-0.3.8/packages/gentoo/tucan-0.3.7.ebuild 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/packages/gentoo/tucan-0.3.7.ebuild 1970-01-01 01:00:00.000000000 +0100
@@ -1,34 +0,0 @@
-# Copyright 1999-2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: $
-
-inherit eutils
-
-DESCRIPTION="Software designed for automatic management of downloads and uploads at hosting sites like rapidshare or megaupload"
-HOMEPAGE="http://cusl3-tucan.forja.rediris.es"
-SRC_URI="http://forja.rediris.es/frs/download.php/1290/${P}.tar.gz"
-
-LICENSE="GPL-2"
-SLOT="0"
-KEYWORDS="~x86 ~amd64"
-
-IUSE=""
-DEPEND="dev-lang/python
- dev-python/pygtk
- dev-python/imaging
- app-text/tesseract[linguas_en]
- gnome-base/librsvg"
-
-src_compile() {
- sed -i \
- -e '/^DESTDIR/d' \
- Makefile || die "sed failed"
-}
-
-src_install() {
- emake DESTDIR="${D}"/usr install || die "emake install failed"
- dodoc CHANGELOG README || die
- newicon media/tucan.svg "${PN}.svg"
- make_desktop_entry tucan Tucan
-}
-
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/environment.sh /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/environment.sh
--- tucan-0.3.8/packages/osx/environment.sh 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/environment.sh 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export PYTHONPATH=$GTK_PATH/lib/python2.5/site-packages/PIL:$GTK_PATH/lib/python2.5/site-packages/gtk-2.0:$GTK_PATH/lib/python2.5/site-packages
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/gtkrc /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/gtkrc
--- tucan-0.3.8/packages/osx/gtkrc 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/gtkrc 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,424 @@
+
+# Please keep this gtkrc in sync with the other ones from Clearlooks based themes.
+
+gtk-color-scheme = "base_color:#ffffff\nfg_color:#000000\ntooltip_fg_color:#000000\nselected_bg_color:#86ABD9\nselected_fg_color:#ffffff\ntext_color:#1A1A1A\nbg_color:#EDECEB\ntooltip_bg_color:#F5F5B5"
+
+style "default" {
+ xthickness = 1
+ ythickness = 1
+
+ #######################
+ # Style Properties
+ #######################
+ GtkButton::child-displacement-x = 1
+ GtkButton::child-displacement-y = 1
+ GtkButton::default-border = { 0, 0, 0, 0 }
+
+ GtkCheckButton::indicator-size = 14
+
+ GtkPaned::handle-size = 6
+
+ GtkRange::trough-border = 0
+ GtkRange::slider-width = 15
+ GtkRange::stepper-size = 15
+
+ GtkScale::slider-length = 23
+ GtkScale::trough-side-details = 1
+
+ GtkScrollbar::min-slider-length = 30
+ GtkMenuBar::internal-padding = 0
+ GtkExpander::expander-size = 16
+ GtkToolbar::internal-padding = 1
+ GtkTreeView::expander-size = 14
+ GtkTreeView::vertical-separator = 0
+
+ GtkMenu::horizontal-padding = 0
+ GtkMenu::vertical-padding = 0
+
+ WnckTasklist::fade-overlay-rect = 0
+ # The following line hints to gecko (and possibly other appliations)
+ # that the entry should be drawn transparently on the canvas.
+ # Without this, gecko will fill in the background of the entry.
+ GtkEntry::honors-transparent-bg-hint = 1
+
+ GtkEntry::progress-border = { 2, 2, 2, 2 }
+
+ ####################
+ # Color Definitions
+ ####################
+ bg[NORMAL] = @bg_color
+ bg[PRELIGHT] = shade (1.02, @bg_color)
+ bg[SELECTED] = @selected_bg_color
+ bg[INSENSITIVE] = @bg_color
+ bg[ACTIVE] = shade (0.9, @bg_color)
+
+ fg[NORMAL] = @fg_color
+ fg[PRELIGHT] = @fg_color
+ fg[SELECTED] = @selected_fg_color
+ fg[INSENSITIVE] = darker (@bg_color)
+ fg[ACTIVE] = @fg_color
+
+ text[NORMAL] = @text_color
+ text[PRELIGHT] = @text_color
+ text[SELECTED] = @selected_fg_color
+ text[INSENSITIVE] = darker (@bg_color)
+ text[ACTIVE] = @selected_fg_color
+
+ base[NORMAL] = @base_color
+ base[PRELIGHT] = shade (0.95, @bg_color)
+ base[SELECTED] = @selected_bg_color
+ base[INSENSITIVE] = @bg_color
+ base[ACTIVE] = shade (0.9, @selected_bg_color)
+
+ engine "clearlooks" {
+ colorize_scrollbar = TRUE
+ reliefstyle = 1
+ menubarstyle = 2
+ toolbarstyle = 1
+ animation = FALSE
+ radius = 3.0
+ style = GUMMY
+
+ # Set a hint to disable backward compatibility fallbacks.
+ hint = "use-hints"
+ }
+}
+
+style "wide" {
+ xthickness = 2
+ ythickness = 2
+}
+
+style "wider" {
+ xthickness = 3
+ ythickness = 3
+}
+
+style "entry" {
+ xthickness = 3
+ ythickness = 3
+
+ bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
+ fg[SELECTED] = @text_color
+
+ engine "clearlooks" {
+ focus_color = shade (0.65, @selected_bg_color)
+ }
+}
+
+style "spinbutton" {
+
+ engine "clearlooks" {
+ hint = "spinbutton"
+ }
+}
+
+style "scale" {
+ xthickness = 2
+ ythickness = 2
+
+ engine "clearlooks" {
+ hint = "scale"
+ }
+}
+
+style "vscale" {
+
+ engine "clearlooks" {
+ hint = "vscale"
+ }
+}
+
+style "hscale" {
+
+ engine "clearlooks" {
+ hint = "hscale"
+ }
+}
+
+style "scrollbar" {
+ xthickness = 2
+ ythickness = 2
+
+ engine "clearlooks" {
+ hint = "scrollbar"
+ }
+}
+
+style "hscrollbar" {
+
+ engine "clearlooks" {
+ hint = "hscrollbar"
+ }
+}
+
+style "vscrollbar" {
+
+ engine "clearlooks" {
+ hint = "vscrollbar"
+ }
+}
+
+style "notebook_bg" {
+
+ bg[NORMAL] = shade (1.02, @bg_color)
+}
+
+style "button" {
+ xthickness = 3
+ ythickness = 3
+
+ bg[NORMAL] = shade (1.04, @bg_color)
+ bg[PRELIGHT] = shade (1.06, @bg_color)
+ bg[ACTIVE] = shade (0.85, @bg_color)
+}
+
+# The color is changed by the notebook_bg style, this style
+# changes the x/ythickness
+style "notebook" {
+ xthickness = 3
+ ythickness = 3
+}
+
+style "statusbar" {
+
+ engine "clearlooks" {
+ hint = "statusbar"
+ }
+}
+
+style "comboboxentry" {
+
+ engine "clearlooks" {
+ # Note:
+ # If you set the appears-as-list option on comboboxes in the theme,
+ # then you should set this hint on the combobox instead.
+ hint = "comboboxentry"
+ }
+}
+
+style "menubar" {
+
+ engine "clearlooks" {
+ hint = "menubar"
+ }
+}
+
+style "menu" {
+ xthickness = 0
+ ythickness = 0
+
+ bg[NORMAL] = shade (1.08, @bg_color)
+
+ engine "clearlooks" {
+ radius = 0.0
+ }
+}
+
+style "menu_item" {
+ xthickness = 2
+ ythickness = 3
+
+ fg[PRELIGHT] = @selected_fg_color
+}
+
+# This style is there to modify the separator menu items. The goals are:
+# 1. Get a specific height.
+# 2. The line should go to the edges (ie. no border at the left/right)
+style "separator_menu_item" {
+ xthickness = 1
+ ythickness = 0
+
+ GtkSeparatorMenuItem::horizontal-padding = 0
+ GtkWidget::wide-separators = 1
+ GtkWidget::separator-width = 1
+ GtkWidget::separator-height = 7
+}
+
+style "frame_title" {
+
+ fg[NORMAL] = lighter (@fg_color)
+}
+
+style "treeview" {
+
+ engine "clearlooks" {
+ hint = "treeview"
+ }
+}
+
+# The almost useless progress bar style
+style "progressbar" {
+ xthickness = 1
+ ythickness = 1
+
+ fg[PRELIGHT] = @selected_fg_color
+
+ engine "clearlooks" {
+ # Explicitly set the radius for the progress bars inside menu items.
+ radius = 3.0
+
+ hint = "progressbar"
+ }
+}
+
+# This style is based on the default style, so that the colors from the button
+# style are overriden again.
+style "treeview_header" = "default" {
+ xthickness = 2
+ ythickness = 1
+
+ engine "clearlooks" {
+ hint = "treeview-header"
+ }
+}
+
+style "tooltips" {
+ xthickness = 4
+ ythickness = 4
+
+ bg[NORMAL] = @tooltip_bg_color
+ fg[NORMAL] = @tooltip_fg_color
+}
+
+style "nautilus_location" {
+
+ bg[NORMAL] = mix (0.60, shade (1.05, @bg_color), @selected_bg_color)
+}
+
+# Wrokaroudn style for places where the text color is used instead of the fg color.
+style "text_is_fg_color_workaround" {
+
+ text[NORMAL] = @fg_color
+ text[PRELIGHT] = @fg_color
+ text[SELECTED] = @selected_fg_color
+ text[ACTIVE] = @fg_color
+ text[INSENSITIVE] = darker (@bg_color)
+}
+
+# Workaround style for menus where the text color is used instead of the fg color.
+style "menuitem_text_is_fg_color_workaround" {
+
+ text[NORMAL] = @fg_color
+ text[PRELIGHT] = @selected_fg_color
+ text[SELECTED] = @selected_fg_color
+ text[ACTIVE] = @fg_color
+ text[INSENSITIVE] = darker (@bg_color)
+}
+
+# Workaround style for places where the fg color is used instead of the text color.
+style "fg_is_text_color_workaround" {
+
+ fg[NORMAL] = @text_color
+ fg[PRELIGHT] = @text_color
+ fg[SELECTED] = @selected_fg_color
+ fg[ACTIVE] = @selected_fg_color
+ fg[INSENSITIVE] = darker (@bg_color)
+}
+
+# Style to set the toolbar to use a flat style. This is because the "New" button in
+# Evolution is not drawn transparent. So if there is a gradient in the background it will
+# look really wrong.
+# See http://bugzilla.gnome.org/show_bug.cgi?id=446953.
+style "evo_new_button_workaround" {
+
+ engine "clearlooks" {
+ toolbarstyle = 0
+ }
+}
+
+
+###############################################################################
+# The following part of the gtkrc applies the different styles to the widgets.
+###############################################################################
+
+# The default style is applied to every widget
+class "GtkWidget" style "default"
+
+class "GtkSeparator" style "wide"
+class "GtkFrame" style "wide"
+class "GtkCalendar" style "wide"
+class "GtkEntry" style "entry"
+
+class "GtkSpinButton" style "spinbutton"
+class "GtkScale" style "scale"
+class "GtkVScale" style "vscale"
+class "GtkHScale" style "hscale"
+class "GtkScrollbar" style "scrollbar"
+class "GtkHScrollbar" style "hscrollbar"
+class "GtkVScrollbar" style "vscrollbar"
+
+# General matching follows. The order is choosen so that the right styles override
+# each other. EG. progressbar needs to be more important than the menu match.
+widget_class "*" style "notebook_bg"
+# This is not perfect, it could be done better.
+# (That is modify *every* widget in the notebook, and change those back that
+# we really don't want changed)
+widget_class "**" style "notebook_bg"
+widget_class "**" style "notebook_bg"
+widget_class "**" style "notebook_bg"
+widget_class "**" style "notebook_bg"
+widget_class "**" style "notebook_bg"
+
+widget_class "*" style "button"
+widget_class "*" style "notebook"
+widget_class "**" style "statusbar"
+
+widget_class "**" style "comboboxentry"
+widget_class "**" style "comboboxentry"
+
+widget_class "**" style "menubar"
+widget_class "**" style "menu"
+widget_class "**" style "menu_item"
+widget_class "**" style "separator_menu_item"
+
+widget_class "*.." style "frame_title"
+widget_class "*.*" style "treeview"
+
+widget_class "*" style "progressbar"
+
+# Treeview headers (and similar stock GTK+ widgets)
+widget_class "*.." style "treeview_header"
+widget_class "*.." style "treeview_header"
+widget_class "*.." style "treeview_header"
+widget_class "*.." style "treeview_header"
+
+# The window of the tooltip is called "gtk-tooltip"
+##################################################################
+# FIXME:
+# This will not work if one embeds eg. a button into the tooltip.
+# As far as I can tell right now we will need to rework the theme
+# quite a bit to get this working correctly.
+# (It will involve setting different priorities, etc.)
+##################################################################
+widget "gtk-tooltip*" style "tooltips"
+
+##########################################################################
+# Following are special cases and workarounds for issues in applications.
+##########################################################################
+
+# Workaround for the evolution ETable (bug #527532)
+widget_class "*.ETable.ECanvas" style "treeview_header"
+# Workaround for the evolution ETree
+widget_class "*.ETree.ECanvas" style "treeview_header"
+
+# Special case the nautilus-extra-view-widget
+# ToDo: A more generic approach for all applications that have a widget like this.
+widget "*.nautilus-extra-view-widget" style : highest "nautilus_location"
+
+# Work around for http://bugzilla.gnome.org/show_bug.cgi?id=382646
+# Note that this work around assumes that the combobox is _not_ in appears-as-list mode.
+widget_class "*.." style "text_is_fg_color_workaround"
+# This is the part of the workaround that fixes the menus
+widget "*.gtk-combobox-popup-menu.*" style "menuitem_text_is_fg_color_workaround"
+
+# Work around the usage of GtkLabel inside GtkListItems to display text.
+# This breaks because the label is shown on a background that is based on the base color.
+widget_class "**" style "fg_is_text_color_workaround"
+# GtkCList also uses the fg color to draw text on top of the base colors.
+widget_class "*" style "fg_is_text_color_workaround"
+# Nautilus when renaming files, and maybe other places.
+widget_class "*" style "fg_is_text_color_workaround"
+
+# See the documentation of the style.
+widget_class "EShellWindow.GtkVBox.BonoboDock.BonoboDockBand.BonoboDockItem*" style "evo_new_button_workaround"
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/Info.plist /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/Info.plist
--- tucan-0.3.8/packages/osx/Info.plist 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/Info.plist 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,30 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ TucanManager
+ CFBundleGetInfoString
+ 0.3.8 alpha
+ CFBundleIconFile
+ tucan.icns
+ CFBundleIdentifier
+ org.tucan
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 0.3.8
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 0.3.8
+ NSHumanReadableCopyright
+ The Tucan Project, GPLv3.
+ LSMinimumSystemVersion
+ 10.5
+
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/instructions.txt /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/instructions.txt
--- tucan-0.3.8/packages/osx/instructions.txt 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/instructions.txt 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,41 @@
+Build Tucan OSX
+-------------------------
+#prepare source
++ sh release_tucan.sh , rename as "src"
++ delete packages/
+
+#create the .app
++ export PATH=$PATH:/Users/Crak/bin
++ ige-mac-bundler tucan.bundle
++ copy TucanManager to Contents/MacOS/
+!!! copy /lib/libigemacintegration.0.dylib to Contents/Resources/lib/
+
+#clean up (save size!)
++ remove Contents/Resources/lib/gtk-2.0/2.10.0/print-backends
++ remove Contents/Resources/lib/gtk-2.0/2.10.0/engines/* (leave clearlooks)
+
+#compile binary
+gcc `python-config --libs` `python-config --includes` -u _PyMac_Error -framework CoreFoundation -Wall tucan.c -o tucan
+
+#debug
+IGE_DEBUG_LAUNCHER=yes TucanManager.app/Contents/MacOS/TucanManager
+
+#create .dmg
+hdiutil create -size 80m -volname Tucan\ Manager -srcfolder build tucan-0.3.8.dmg
+
+#ERRORS
+1.
+[2009-08-08 15:39:41,999] easy-share.parsers ERROR: http://www.easy-share.com/1699551079.html :decoder jpeg not available
+Traceback (most recent call last):
+ File "/Users/Crak/.tucan/plugins/easy-share/parsers.py", line 60, in __init__
+ tes = Tesseract(opener.open(self.captcha_url).read(), self.filter_image)
+ File "/Users/Crak/Desktop/TucanManager.app/Contents/Resources/src/tesseract.py", line 57, in __init__
+ p.feed(data)
+ File "/Library/Python/2.5/site-packages/PIL/ImageFile.py", line 411, in feed
+ im.mode, d, a, im.decoderconfig
+ File "/Library/Python/2.5/site-packages/PIL/Image.py", line 375, in _getdecoder
+ raise IOError("decoder %s not available" % decoder_name)
+IOError: decoder jpeg not available
+
+2.
+08/08/09 13:48:26 [0x0-0x1bf1bf].org.tucan[4796] glib.GError: Unable to load image-loading module: @executable_path/Resources/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-ico.so: dlopen(@executable_path/Resources/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-ico.so, 1): image not found
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/tucan.bundle /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/tucan.bundle
--- tucan-0.3.8/packages/osx/tucan.bundle 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/tucan.bundle 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,49 @@
+
+
+
+
+ /Users/Crak/gtk/inst
+ ${env:HOME}/Desktop
+
+
+
+ ${project}/Info.plist
+
+
+ ${prefix}/bin/pygtk-demo
+
+
+
+
+ ${project}/src
+
+
+
+
+ ${project}/tesseract
+
+
+
+ ${project}/tucan.icns
+
+
+
+ ${project}/gtkrc
+
+
+
+
+ ${project}/environment.sh
+
+
+
+
+ ${prefix}/lib/gtk-2.0
+
+
+
+
+ ${prefix}/lib/python2.5
+
+
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/tucan.c /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/tucan.c
--- tucan-0.3.8/packages/osx/tucan.c 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/tucan.c 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,67 @@
+/* Main binary for OSX bundle.
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#define TUCAN_FILE "/src/tucan.py"
+
+int main()
+{
+ int result = 0;
+
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
+ char path[PATH_MAX];
+
+ if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
+ {
+ char *tucan_path;
+
+ tucan_path = (char *)calloc(strlen(path) + strlen(TUCAN_FILE) + 1, sizeof(char));
+ strcpy(tucan_path, path);
+ strcat(tucan_path, TUCAN_FILE);
+ printf("Tucan Path: %s\n", tucan_path);
+
+ FILE *fp = fopen(tucan_path, "r");
+
+ Py_Initialize();
+
+ char *argv[1];
+ argv[0] = tucan_path;
+ argv[1] = NULL;
+
+ PySys_SetArgv(1, argv);
+ result = PyRun_SimpleFile(fp, tucan_path);
+
+ //printf("PATH: %s\n", Py_GetPath());
+ Py_Finalize();
+
+ free(tucan_path);
+ }
+ CFRelease(resourcesURL);
+
+ return result;
+}
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/tucan.icns and /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/tucan.icns differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/packages/osx/TucanManager /tmp/DgSymrsclJ/tucan-0.3.9/packages/osx/TucanManager
--- tucan-0.3.8/packages/osx/TucanManager 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/packages/osx/TucanManager 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+if test "x$IGE_DEBUG_LAUNCHER" != x; then
+ set -x
+fi
+
+if test "x$IGE_DEBUG_GDB" != x; then
+ EXEC="gdb --args"
+else
+ EXEC=exec
+fi
+
+name="`basename $0`"
+tmp="`pwd`/$0"
+tmp=`dirname "$tmp"`
+tmp=`dirname "$tmp"`
+bundle=`dirname "$tmp"`
+bundle_contents="$bundle"/Contents
+bundle_res="$bundle_contents"/Resources
+bundle_lib="$bundle_res"/lib
+bundle_bin="$bundle_res"/bin
+bundle_data="$bundle_res"/share
+bundle_etc="$bundle_res"/etc
+
+export DYLD_LIBRARY_PATH="$bundle_lib"
+export XDG_CONFIG_DIRS="$bundle_etc"/xdg
+export XDG_DATA_DIRS="$bundle_data"
+export GTK_DATA_PREFIX="$bundle_res"
+export GTK_EXE_PREFIX="$bundle_res"
+export GTK_PATH="$bundle_res"
+
+export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
+export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
+export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
+export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
+
+# We need a UTF-8 locale.
+lang=`defaults read .GlobalPreferences AppleLocale 2>/dev/null`
+if test "$?" != "0"; then
+ lang=`defaults read .GlobalPreferences AppleCollationOrder 2>/dev/null | sed 's/_.*//'`
+fi
+if test "$?" == "0"; then
+ export LANG="`grep \"\`echo $lang\`_\" /usr/share/locale/locale.alias | \
+ tail -n1 | sed 's/\./ /' | awk '{print $2}'`.UTF-8"
+fi
+
+if test -f "$bundle_lib/charset.alias"; then
+ export CHARSETALIASDIR="$bundle_lib"
+fi
+
+# Extra arguments can be added in environment.sh.
+EXTRA_ARGS=
+if test -f "$bundle_res/environment.sh"; then
+ source "$bundle_res/environment.sh"
+fi
+
+# Strip out the argument added by the OS.
+if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then
+ shift 1
+fi
+
+$EXEC "$bundle_contents"/MacOS/tucan $* $EXTRA_ARGS
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/preferences.py /tmp/DgSymrsclJ/tucan-0.3.9/preferences.py
--- tucan-0.3.8/preferences.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/preferences.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,428 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import __builtin__
-import gettext
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import pango
-
-import cons
-import config
-import service_config
-import url_open
-
-from service_preferences import ServicePreferences
-from message import Message
-from file_chooser import FileChooser
-from update_manager import UpdateManager
-
-LANGUAGES = [("English", "en"), ("French", "fr"), ("German", "de"), ("Italian", "it"), ("Polish", "pl"), ("Portuguese", "pt"), ("Slovak", "sk"), ("Spanish", "es"), ("Swedish", "se")]
-
-class Preferences(gtk.Dialog):
- """"""
- def __init__(self, configuration, show_services=False, updates=None):
- """"""
- gtk.Dialog.__init__(self)
- self.set_icon_from_file(cons.ICON_PREFERENCES)
- self.set_title("Tucan Preferences")
- self.set_size_request(500,500)
-
- self.config = configuration
-
- self.notebook = gtk.Notebook()
- self.notebook.set_property("homogeneous", True)
- self.vbox.pack_start(self.notebook)
- self.new_page(_("General Configuration"), cons.ICON_PREFERENCES_MAIN, self.init_main())
- self.new_page(_("Service Configuration"), cons.ICON_PREFERENCES_SERVICES, self.init_services())
- self.new_page(_("Advanced Configuration"), cons.ICON_PREFERENCES_ADVANCED, self.init_advanced())
-
- #action area
- cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
- save_button = gtk.Button(None, gtk.STOCK_SAVE)
- self.action_area.pack_start(cancel_button)
- self.action_area.pack_start(save_button)
- cancel_button.connect("clicked", self.close)
- save_button.connect("clicked", self.save)
-
- self.connect("response", self.close)
- self.show_all()
-
- if show_services:
- self.notebook.set_current_page(1)
- if updates:
- gobject.idle_add(self.update_manager, None, updates)
- self.run()
-
- def save(self, button):
- """"""
- self.config.set(config.SECTION_MAIN, config.OPTION_LANGUAGE, [lang[1] for lang in LANGUAGES][self.language.get_active()])
-
- #live changes
- self.config.set(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS, str(self.max_downloads.get_value_as_int()))
- __builtin__.max_downloads = self.max_downloads.get_value_as_int()
- self.config.set(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED, str(self.max_download_speed.get_value_as_int()))
- __builtin__.max_download_speed = self.max_download_speed.get_value_as_int()
-
- #self.config.set(config.SECTION_MAIN, config.OPTION_MAX_UPLOADS, str(self.max_uploads.get_value_as_int()))
- self.config.set(config.SECTION_MAIN, config.OPTION_DOWNLOADS_FOLDER, self.downloads_folder.get_label())
-
- model = self.treeview.get_model()
- iter = model.get_iter_root()
- while iter:
- configuration = model.get_value(iter, 3)
- configuration.enable(model.get_value(iter, 2))
- if not self.config.has_option(config.SECTION_SERVICES, model.get_value(iter,1)):
- self.config.set(config.SECTION_SERVICES, model.get_value(iter,1), configuration.path)
- iter = model.iter_next(iter)
-
- self.config.set(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE, str(self.tray_close.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES, str(self.advanced_packages.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION, str(self.save_session.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE, str(self.auto_update.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS, str(self.show_uploads.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_ENABLE_PROXY, str(self.enable_proxy.get_active()))
- self.config.set(config.SECTION_ADVANCED, config.OPTION_PROXY_URL, self.proxy_url.get_text())
- self.config.set(config.SECTION_ADVANCED, config.OPTION_PROXY_PORT, str(self.proxy_port.get_value_as_int()))
-
- #change proxy settings
- if self.enable_proxy.get_active():
- proxy_url, proxy_port = self.config.get_proxy()
- url_open.set_proxy(proxy_url, proxy_port)
- else:
- url_open.set_proxy(None)
-
- self.config.save()
- self.close()
-
- def new_page(self, tab_name, tab_image, page):
- """"""
- vbox = gtk.VBox()
- vbox.pack_start(gtk.image_new_from_file(tab_image))
- vbox.pack_start(gtk.Label(tab_name))
- vbox.show_all()
- self.notebook.append_page(page, vbox)
- self.notebook.set_tab_label_packing(page, True, True, gtk.PACK_START)
-
- def init_main(self):
- """"""
- vbox = gtk.VBox()
-
- frame = gtk.Frame()
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_LANGUAGE))
- frame.set_border_width(5)
- vbox.pack_start(frame, False, False)
- hbox = gtk.HBox()
- vbox1 = gtk.VBox()
- frame.add(vbox1)
- hbox = gtk.HBox()
- vbox1.pack_start(hbox, False, False, 5)
- label = gtk.Label(_("Choose language: "))
- hbox.pack_start(label, False, False, 10)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- hbox.pack_start(aspect)
- self.language = gtk.combo_box_new_text()
- for lang in [lang[0] for lang in LANGUAGES]:
- self.language.append_text(lang)
- self.language.set_active([lang[1] for lang in LANGUAGES].index(self.config.get(config.SECTION_MAIN, config.OPTION_LANGUAGE)))
- hbox.pack_start(self.language, False, False, 10)
-
- frame = gtk.Frame()
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_NETWORK))
- frame.set_border_width(5)
- vbox.pack_start(frame, False, False)
- vbox1 = gtk.VBox()
- frame.add(vbox1)
- hbox = gtk.HBox()
- label = gtk.Label(_("Max simultaneous downloads: "))
- hbox.pack_start(label, False, False, 10)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- hbox.pack_start(aspect)
- self.max_downloads = gtk.SpinButton(None, 1, 0)
- self.max_downloads.set_range(1,20)
- self.max_downloads.set_increments(1,0)
- self.max_downloads.set_numeric(True)
- self.max_downloads.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS))
- hbox.pack_start(self.max_downloads, False, False, 10)
- vbox1.pack_start(hbox, False, False, 2)
- hbox = gtk.HBox()
- label = gtk.Label(_("Max download speed: "))
- hbox.pack_start(label, False, False, 10)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- hbox.pack_start(aspect)
- self.max_download_speed = gtk.SpinButton(None, 4, 0)
- self.max_download_speed.set_range(0,5000)
- self.max_download_speed.set_increments(4,0)
- self.max_download_speed.set_numeric(True)
- self.max_download_speed.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED))
- hbox.pack_start(self.max_download_speed, False, False, 10)
- vbox1.pack_start(hbox, False, False, 2)
- #hbox = gtk.HBox()
- #label = gtk.Label(_("Max simultaneous uploads: "))
- #hbox.pack_start(label, False, False, 10)
- #aspect = gtk.AspectFrame()
- #aspect.set_shadow_type(gtk.SHADOW_NONE)
- #hbox.pack_start(aspect)
- #self.max_uploads = gtk.SpinButton(None, 1, 0)
- #self.max_uploads.set_range(1,10)
- #self.max_uploads.set_increments(1,0)
- #self.max_uploads.set_numeric(True)
- #self.max_uploads.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_UPLOADS))
- #hbox.pack_start(self.max_uploads, False, False, 10)
- #vbox1.pack_start(hbox, False, False, 2)
-
- frame = gtk.Frame()
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_FOLDER))
- frame.set_border_width(5)
- vbox.pack_start(frame, False, False)
- vbox1 = gtk.VBox()
- frame.add(vbox1)
- hbox = gtk.HBox()
- vbox1.pack_start(hbox, False, False, 5)
-
- label = gtk.Label(_("Downloads Folder: "))
- hbox.pack_start(label, False, False, 10)
- path = self.config.get(config.SECTION_MAIN, config.OPTION_DOWNLOADS_FOLDER)
- self.downloads_folder = gtk.Label(path)
- hbox.pack_start(self.downloads_folder, False, False, 10)
- bbox = gtk.HButtonBox()
- bbox.set_layout(gtk.BUTTONBOX_END)
- hbox.pack_start(bbox, True, True, 10)
- button = gtk.Button(None, gtk.STOCK_OPEN)
- button.connect("clicked", self.choose_path)
- bbox.pack_start(button)
-
- vbox.show_all()
- return vbox
-
- def choose_path(self, button):
- """"""
- FileChooser(self, self.downloads_folder.set_label, self.downloads_folder.get_label())
-
- def init_services(self):
- """"""
- vbox = gtk.VBox()
-
- frame = gtk.Frame()
- frame.set_size_request(-1, 300)
- vbox.pack_start(frame)
- frame.set_border_width(10)
- scroll = gtk.ScrolledWindow()
- frame.add(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- store = gtk.ListStore(gtk.gdk.Pixbuf, str, bool, gobject.TYPE_PYOBJECT)
- self.treeview = gtk.TreeView(store)
- scroll.add(self.treeview)
- self.treeview.connect("row-activated", self.service_preferences)
-
- self.treeview.set_rules_hint(True)
- #self.treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- icon_cell.set_property("width", 50)
- tree_icon.pack_start(icon_cell, False)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- name_cell.set_property("width", 300)
- name_cell.set_property("xalign", 0.1)
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- self.treeview.append_column(tree_name)
-
- tree_enable = gtk.TreeViewColumn('Enabled')
- enable_cell = gtk.CellRendererToggle()
- enable_cell.connect("toggled", self.toggled)
- tree_enable.pack_start(enable_cell, True)
- tree_enable.add_attribute(enable_cell, 'active', 2)
- self.treeview.append_column(tree_enable)
-
- #fill store
- for path, icon_path, name, enabled, configuration in self.config.get_services():
- self.add_service(path, icon_path, name, enabled, configuration)
-
- frame = gtk.Frame()
- frame.set_border_width(10)
- frame.set_shadow_type(gtk.SHADOW_NONE)
- vbox.pack_start(frame, False, False)
- bbox = gtk.HButtonBox()
- bbox.set_layout(gtk.BUTTONBOX_EDGE)
- frame.add(bbox)
- button = gtk.Button(None, gtk.STOCK_FIND)
- button.connect("clicked", self.update_manager)
- bbox.pack_start(button)
- button = gtk.Button(None, gtk.STOCK_REMOVE)
- button.connect("clicked", self.delete_service)
- bbox.pack_start(button)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- bbox.pack_start(aspect)
- button = gtk.Button(None, gtk.STOCK_INFO)
- button.connect("clicked", self.service_info)
- bbox.pack_start(button)
-
- hbox = gtk.HBox()
- vbox.pack_start(hbox, False, False, 5)
- label = gtk.Label()
- hbox.pack_start(label, False, False, 10)
- label.set_markup("* " + _("Restart Tucan to apply service changes.") + " ")
-
- return vbox
-
- def service_info(self, button):
- """"""
- model, iter = self.treeview.get_selection().get_selected()
- if iter:
- self.service_preferences(None, model.get_path(iter))
-
- def add_service(self, path, icon_path, name, enabled, configuration):
- """"""
- if configuration:
- if icon_path:
- icon = gtk.gdk.pixbuf_new_from_file_at_size(icon_path, 32, 32)
- else:
- icon = gtk.gdk.pixbuf_new_from_file_at_size(cons.ICON_MISSING, 32, 32)
- self.treeview.get_model().append((icon, name, enabled, configuration))
- else:
- Message(self, cons.SEVERITY_ERROR, path , _("Service not configured."))
-
- def update_manager(self, button, updates=None):
- """"""
- UpdateManager(self.config, self, updates)
- self.treeview.get_model().clear()
- for path, icon_path, name, enabled, configuration in self.config.get_services():
- self.add_service(path, icon_path, name, enabled, configuration)
-
- def delete_service(self, button):
- """"""
- model, iter = self.treeview.get_selection().get_selected()
- if iter:
- next_iter = model.iter_next(iter)
- self.config.remove_option(config.SECTION_SERVICES, model.get_value(iter, 1))
- model.remove(iter)
- if next_iter:
- self.treeview.set_cursor_on_cell(model.get_path(next_iter))
-
- def toggled(self, button, path):
- """"""
- model = self.treeview.get_model()
- if button.get_active():
- active = False
- else:
- tos = _("Before using this service, you must accept it's terms of service at ") + model.get_value(model.get_iter(path), 1)
- m = Message(self, cons.SEVERITY_INFO, _("Tucan Manager - Terms of service"), tos, True)
- active = m.accepted
- button.set_active(active)
- model.set_value(model.get_iter(path), 2, active)
-
- def service_preferences(self, treeview, path, view_column=None):
- """"""
- model = self.treeview.get_model()
- icon = model.get_value(model.get_iter(path), 0)
- name = model.get_value(model.get_iter(path), 1)
- config = model.get_value(model.get_iter(path), 3)
- ServicePreferences(self, name, icon, config)
-
- def init_advanced(self):
- """"""
- frame = gtk.Frame()
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_ADVANCED))
- frame.set_border_width(10)
- hbox = gtk.HBox()
- frame.add(hbox)
- vbox = gtk.VBox()
- hbox.pack_start(vbox, True, True, 10)
-
- self.tray_close = gtk.CheckButton(_("Close to tray."))
- vbox.pack_start(self.tray_close, False, False, 5)
- self.tray_close.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE))
-
- self.save_session = gtk.CheckButton(_("Save session on close."))
- vbox.pack_start(self.save_session, False, False, 5)
- self.save_session.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION))
-
- self.advanced_packages = gtk.CheckButton(_("Default advanced packages."))
- vbox.pack_start(self.advanced_packages, False, False, 5)
- self.advanced_packages.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES))
-
- self.auto_update = gtk.CheckButton(_("Automatic check for updates."))
- vbox.pack_start(self.auto_update, False, False, 5)
- self.auto_update.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE))
-
- self.show_uploads = gtk.CheckButton(_("Show uploads."))
- vbox.pack_start(self.show_uploads, False, False, 5)
- self.show_uploads.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS))
-
- self.enable_proxy = gtk.CheckButton(_("Enable proxy:"))
- vbox.pack_start(self.enable_proxy, False, False, 5)
- self.enable_proxy.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_ENABLE_PROXY))
- self.enable_proxy.connect("toggled", self.change_state)
-
- self.proxy_box = gtk.HBox()
- vbox.pack_start(self.proxy_box, False, False, 5)
- self.proxy_box.pack_start(gtk.Label("HTTP Proxy:"), False, False, 5)
- self.proxy_url = gtk.Entry()
- self.proxy_box.pack_start(self.proxy_url, True, True, 5)
- self.proxy_url.set_text(self.config.get(config.SECTION_ADVANCED, config.OPTION_PROXY_URL))
-
- self.proxy_box.pack_start(gtk.Label("Port:"), False, False, 5)
- self.proxy_port = gtk.SpinButton(None, 1, 0)
- self.proxy_box.pack_start(self.proxy_port, False, False, 5)
- self.proxy_port.set_range(0,65535)
- self.proxy_port.set_increments(1,0)
- self.proxy_port.set_numeric(True)
- self.proxy_port.set_value(self.config.getint(config.SECTION_ADVANCED, config.OPTION_PROXY_PORT))
-
- self.change_state()
-
- return frame
-
- def change_state(self, button=None):
- """"""
- self.proxy_box.set_sensitive(self.enable_proxy.get_active())
-
- def close(self, widget=None, other=None):
- """"""
- enabled_services = 0
- model = self.treeview.get_model()
- iter = model.get_iter_root()
- while iter:
- if model.get_value(iter, 3).getboolean(service_config.SECTION_MAIN, service_config.OPTION_ENABLED):
- enabled_services += 1
- iter = model.iter_next(iter)
- if enabled_services > 0:
- self.destroy()
- else:
- Message(self, cons.SEVERITY_WARNING, _("Tucan Manager - No services enabled!") , _("Enable some services and restart Tucan."))
- self.run()
-
-if __name__ == "__main__":
- import gettext
- _ = gettext.gettext
- x = Preferences(config.Config())
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/README /tmp/DgSymrsclJ/tucan-0.3.9/README
--- tucan-0.3.8/README 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/README 2009-10-07 00:02:31.000000000 +0100
@@ -15,6 +15,8 @@
- http://filefactory.com/
- http://easy-share.com/
- http://badongo.com/
+ - http://depositfiles.com/
+ - http://hotfile.com/
- (...)
@@ -38,29 +40,33 @@
Plugins
=========
- ----------------------------------------------------------------------------
+ +===================+========================+=============================+
| Hosting site | Downloads | Uploads |
- ----------------------------------------------------------------------------
+ +===================+========================+=============================+
| rapidshare.com | anonymous and premium | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| megaupload.com | anonymous and premium | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| gigasize.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| mediafire.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| 4shared.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| sendspace.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| zshare.net | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| filefactory.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| easy-share.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| badongo.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
+ | depositfiles.com | anonymous | |
+ +-------------------+------------------------+-----------------------------+
+ | hotfile.com | anonymous | |
+ +-------------------+------------------------+-----------------------------+
===================
@@ -73,35 +79,35 @@
- Tesseract OCR (with the english language pack)
- SVG Rendering Library
- --------------------------------------------------------------------
+ +=========================+===================+====================+
| Package \ Distribution | Debian / Ubuntu | Gentoo |
- --------------------------------------------------------------------
+ +=========================+===================+====================+
| Python >= 2.5 | python | dev-lang/python |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| PyGTK | python-gtk2 | dev-python/pygtk |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| Python Imaging Library | python-imaging | dev-python/imaging |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| Tesseract OCR | tesseract-ocr | app-text/tesseract |
| (english language pack) | tesseract-ocr-eng | (linguas_en) |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| SVG Rendering Library | librsvg2-common | gnome-base/librsvg |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
- ---------------------------------------------------
- | Arch | Fedora | OpenSuSE |
- ---------------------------------------------------
- | python | python | python |
- ---------------------------------------------------
- | pygtk | pygtk2 | python-gtk |
- ---------------------------------------------------
- | pil | python-imaging | python-imaging |
- ---------------------------------------------------
- | tesseract | tesseract | tesseract |
- | | tesseract-langpack | |
- ---------------------------------------------------
- | librsvg | librsvg2 | librsvg |
- ---------------------------------------------------
+ +===========+====================+================+================+
+ | Arch | Fedora | OpenSuSE | Mandriva |
+ +===========+====================+================+================+
+ | python | python | python | python |
+ +-----------+--------------------+----------------+----------------+
+ | pygtk | pygtk2 | python-gtk | pygtk2.0 |
+ +-----------+--------------------+----------------+----------------+
+ | pil | python-imaging | python-imaging | python-imaging |
+ +-----------+--------------------+----------------+----------------+
+ | tesseract | tesseract | tesseract | tesseract |
+ | | tesseract-langpack | | |
+ +-----------+--------------------+----------------+----------------+
+ | librsvg | librsvg2 | librsvg | librsvg |
+ +-----------+--------------------+----------------+----------------+
===================
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/README.es /tmp/DgSymrsclJ/tucan-0.3.9/README.es
--- tucan-0.3.8/README.es 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/README.es 2009-10-07 00:02:31.000000000 +0100
@@ -15,6 +15,8 @@
- http://filefactory.com/
- http://easy-share.com/
- http://badongo.com/
+ - http://depositfiles.com/
+ - http://hotfile.com/
- (...)
@@ -38,29 +40,33 @@
Plugins
=========
- ----------------------------------------------------------------------------
+ +===================+========================+=============================+
| Hosting site | Downloads | Uploads |
- ----------------------------------------------------------------------------
+ +===================+========================+=============================+
| rapidshare.com | anonymous and premium | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| megaupload.com | anonymous and premium | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| gigasize.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| mediafire.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| 4shared.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| sendspace.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| zshare.net | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| filefactory.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| easy-share.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
| badongo.com | anonymous | |
- ----------------------------------------------------------------------------
+ +-------------------+------------------------+-----------------------------+
+ | depositfiles.com | anonymous | |
+ +-------------------+------------------------+-----------------------------+
+ | hotfile.com | anonymous | |
+ +-------------------+------------------------+-----------------------------+
===================
@@ -73,35 +79,35 @@
- Tesseract OCR (con el paquete del idioma inglés)
- SVG Rendering Library
- --------------------------------------------------------------------
+ +=========================+===================+====================+
| Paquete \ Distribución | Debian / Ubuntu | Gentoo |
- --------------------------------------------------------------------
+ +=========================+===================+====================+
| Python >= 2.5 | python | dev-lang/python |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| PyGTK | python-gtk2 | dev-python/pygtk |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| Python Imaging Library | python-imaging | dev-python/imaging |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| Tesseract OCR | tesseract-ocr | app-text/tesseract |
| (english language pack) | tesseract-ocr-eng | (linguas_en) |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
| SVG Rendering Library | librsvg2-common | gnome-base/librsvg |
- --------------------------------------------------------------------
+ +-------------------------+-------------------+--------------------+
- ---------------------------------------------------
- | Arch | Fedora | OpenSuSE |
- ---------------------------------------------------
- | python | python | python |
- ---------------------------------------------------
- | pygtk | pygtk2 | python-gtk |
- ---------------------------------------------------
- | pil | python-imaging | python-imaging |
- ---------------------------------------------------
- | tesseract | tesseract | tesseract |
- | | tesseract-langpack | |
- ---------------------------------------------------
- | librsvg | librsvg2 | librsvg |
- ---------------------------------------------------
+ +===========+====================+================+================+
+ | Arch | Fedora | OpenSuSE | Mandriva |
+ +===========+====================+================+================+
+ | python | python | python | python |
+ +-----------+--------------------+----------------+----------------+
+ | pygtk | pygtk2 | python-gtk | pygtk2.0 |
+ +-----------+--------------------+----------------+----------------+
+ | pil | python-imaging | python-imaging | python-imaging |
+ +-----------+--------------------+----------------+----------------+
+ | tesseract | tesseract | tesseract | tesseract |
+ | | tesseract-langpack | | |
+ +-----------+--------------------+----------------+----------------+
+ | librsvg | librsvg2 | librsvg | librsvg |
+ +-----------+--------------------+----------------+----------------+
===================
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/service_config.py /tmp/DgSymrsclJ/tucan-0.3.9/service_config.py
--- tucan-0.3.8/service_config.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/service_config.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,165 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import pickle
-import base64
-import logging
-logger = logging.getLogger(__name__)
-
-from ConfigParser import SafeConfigParser
-
-import cons
-
-SECTION_MAIN = "main"
-
-SECTION_ANONYMOUS_DOWNLOAD = "anonymous_download"
-SECTION_USER_DOWNLOAD = "user_download"
-SECTION_PREMIUM_DOWNLOAD = "premium_download"
-
-SECTION_ANONYMOUS_UPLOAD = "anonymous_upload"
-SECTION_USER_UPLOAD = "user_upload"
-SECTION_PREMIUM_UPLOAD = "premium_upload"
-
-OPTION_UPDATE = "update"
-OPTION_NAME = "name"
-OPTION_ICON = "icon"
-OPTION_ENABLED = "enabled"
-
-OPTION_PREMIUM_COOKIE = "premium_cookie"
-OPTION_USER_COOKIE = "user_cookie"
-
-OPTION_DOWNLOADS = "downloads"
-OPTION_UPLOADS = "uploads"
-
-OPTION_PATH = "path"
-OPTION_AUTHOR = "author"
-OPTION_VERSION = "version"
-OPTION_SLOTS = "slots"
-OPTION_CAPTCHA = "captcha"
-OPTION_ACCOUNTS = "accounts"
-
-CONF = "service.conf"
-
-class ServiceConfig(SafeConfigParser):
- """"""
- def __init__(self, path, fd=None):
- """"""
- SafeConfigParser.__init__(self)
- self.path = path
- if fd:
- self.readfp(fd)
- elif os.path.exists(unicode(os.path.join(self.path, CONF))):
- self.read(unicode(os.path.join(self.path, CONF)))
-
- def check_config(self):
- """"""
- if self.has_section(SECTION_MAIN):
- return True
-
- def enable(self, enabled):
- """"""
- self.set(SECTION_MAIN, OPTION_ENABLED, str(enabled))
- self.save()
-
- def get_name(self):
- """"""
- if self.has_option(SECTION_MAIN, OPTION_NAME):
- return self.get(SECTION_MAIN, OPTION_NAME)
-
- def get_update(self):
- """"""
- if self.has_option(SECTION_MAIN, OPTION_UPDATE):
- return self.getint(SECTION_MAIN, OPTION_UPDATE)
- else:
- return 0
-
- def get_icon(self):
- """"""
- if self.has_option(SECTION_MAIN, OPTION_ICON):
- if self.get(SECTION_MAIN, OPTION_ICON) != "None":
- return self.path + self.get(SECTION_MAIN, OPTION_ICON)
-
- def premium_cookie(self):
- """"""
- get_cookie = None
- if self.has_option(SECTION_MAIN, OPTION_PREMIUM_COOKIE):
- get_cookie = self.get(SECTION_MAIN, OPTION_PREMIUM_COOKIE)
- return OPTION_PREMIUM_COOKIE, get_cookie
-
- def user_cookie(self):
- """"""
- get_cookie = None
- if self.has_option(SECTION_MAIN, OPTION_USER_COOKIE):
- get_cookie = self.get(SECTION_MAIN, OPTION_USER_COOKIE)
- return OPTION_USER_COOKIE, get_cookie
-
- def get_plugins(self, sections):
- """"""
- result = []
- for section, section_type in sections:
- if ((self.has_section(section)) and (len(self.items(section)) > 0)):
- result.append((section, self.get(section, OPTION_NAME), section_type))
- return result
-
- def get_download_plugins(self):
- """"""
- result = []
- if self.has_option(SECTION_MAIN, OPTION_DOWNLOADS):
- if self.getboolean(SECTION_MAIN, OPTION_DOWNLOADS):
- result = self.get_plugins([(SECTION_ANONYMOUS_DOWNLOAD, cons.TYPE_ANONYMOUS), (SECTION_USER_DOWNLOAD, cons.TYPE_USER), (SECTION_PREMIUM_DOWNLOAD, cons.TYPE_PREMIUM)])
- return result
-
- def get_upload_plugins(self):
- """"""
- result = []
- if self.has_option(SECTION_MAIN, OPTION_UPLOADS):
- if self.getboolean(SECTION_MAIN, OPTION_UPLOADS):
- result = self.get_plugins([(SECTION_ANONYMOUS_UPLOAD, cons.TYPE_ANONYMOUS), (SECTION_USER_UPLOAD, cons.TYPE_USER), (SECTION_PREMIUM_UPLOAD, cons.TYPE_PREMIUM)])
- return result
-
- def get_accounts(self, section):
- """"""
- result = {}
- if self.has_section(section):
- if os.path.exists(self.path + self.get(section, OPTION_ACCOUNTS)):
- try:
- f = open(self.path + self.get(section, OPTION_ACCOUNTS), "rb")
- result = pickle.loads(base64.b64decode((f.read())))
- f.close()
- except EOFError, e:
- logger.error("Unable to load account: %s" % e)
- return result
-
- def set_accounts(self, section, accounts):
- """"""
- if self.has_section(section):
- f = open(self.path + self.get(section, OPTION_ACCOUNTS), "wb")
- f.write(base64.b64encode(pickle.dumps(accounts)))
- f.close()
-
- def save(self):
- """"""
- f = open(self.path + CONF, "w")
- self.write(f)
- f.close()
-
-if __name__ == "__main__":
- c = ServiceConfig("/home/crak/.tucan/plugins/megaupload/")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/service_manager.py /tmp/DgSymrsclJ/tucan-0.3.9/service_manager.py
--- tucan-0.3.8/service_manager.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/service_manager.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,218 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import __builtin__
-import re
-import sys
-import logging
-logger = logging.getLogger(__name__)
-
-from config import SECTION_MAIN, OPTION_MAX_DOWNLOADS, OPTION_MAX_DOWNLOAD_SPEED
-from download_manager import DownloadManager
-
-import cons
-
-class Service:
- """"""
- def __init__(self, name, icon):
- """"""
- self.icon_path = icon
- self.name = name
- self.anonymous_download_plugin = None
- self.user_download_plugin = None
- self.premium_download_plugin = None
- self.anonymous_upload_plugins = None
- self.user_upload_plugins = None
- self.premium_upload_plugins = None
-
-class ServiceManager:
- """"""
- def __init__(self, configuration):
- """"""
- self.services = []
- __builtin__.max_downloads = configuration.getint(SECTION_MAIN, OPTION_MAX_DOWNLOADS)
- __builtin__.max_download_speed = configuration.getint(SECTION_MAIN, OPTION_MAX_DOWNLOAD_SPEED)
- self.download_manager = DownloadManager(self.get_download_plugin, self.services)
- if cons.PLUGIN_PATH not in sys.path:
- sys.path.append(cons.PLUGIN_PATH)
- for package, icon, service, enabled, config in configuration.get_services():
- s = Service(service, icon)
- if enabled:
- #download plugins
- for plugin_module, plugin_name, plugin_type in config.get_download_plugins():
- logger.info("Loading: %s.%s" % (package, plugin_module))
- module = __import__(package + "." + plugin_module, None, None, [''])
- if plugin_type == cons.TYPE_ANONYMOUS:
- s.anonymous_download_plugin = eval("module" + "." + plugin_name + "()")
- elif plugin_type == cons.TYPE_USER:
- s.user_download_plugin = eval("module" + "." + plugin_name + "()")
- elif plugin_type == cons.TYPE_PREMIUM:
- s.premium_download_plugin = eval("module" + "." + plugin_name + "(config)")
- #upload plugins
- for plugin_module, plugin_name, plugin_type in config.get_upload_plugins():
- logger.info("Loading: %s.%s" % (package, plugin_module))
- module = __import__(package + "." + plugin_module, None, None, [''])
- if plugin_type == cons.TYPE_ANONYMOUS:
- s.anonymous_upload_plugin = eval("module" + "." + plugin_name + "()")
- elif plugin_type == cons.TYPE_USER:
- s.user_upload_plugin = eval("module" + "." + plugin_name + "()")
- elif plugin_type == cons.TYPE_PREMIUM:
- s.premium_upload_plugin = eval("module" + "." + plugin_name + "(config)")
- self.services.append(s)
-
- def prueba(self):
- """"""
- import url_open
- import time
-
- url_open.set_proxy(None)
- links = [("mediafire.com", "http://www.mediafire.com/download.php?z0gjmnwk1d0"), ("mediafire.com", "http://www.mediafire.com/download.php?d4j2nyyr4qy")]
- for service, link in links:
- name, size, unit = self.get_check_links(service)[0](link)
- print name, size, unit
- if name:
- plugin, plugin_type = self.get_download_plugin(service)
- self.download_manager.add("/home/crak/downloads/", name, [(link, plugin, plugin_type, service)], size, unit)
- while len(self.download_manager.active_downloads + self.download_manager.pending_downloads) > 0:
- print "\n"
- self.download_manager.update()
- time.sleep(1)
-
- def get_download_plugin(self, service_name):
- """"""
- for service in self.services:
- if service.name == service_name:
- if ((service.premium_download_plugin) and (service.premium_download_plugin.active)):
- return service.premium_download_plugin, cons.TYPE_PREMIUM
- else:
- return service.anonymous_download_plugin, cons.TYPE_ANONYMOUS
-
- def get_upload_plugin(self, service_name):
- """"""
- for service in self.services:
- if service.name == service_name:
- return service.anonymous_upload_plugin
-
- def get_check_links(self, service_name):
- """"""
- for service in self.services:
- if service.name == service_name:
- if ((service.premium_download_plugin) and (service.premium_download_plugin.active)):
- return service.premium_download_plugin.check_links, cons.TYPE_PREMIUM
- else:
- return service.anonymous_download_plugin.check_links, cons.TYPE_ANONYMOUS
-
- def get_check_files(self, service_name):
- """"""
- for service in self.services:
- if service.name == service_name:
- return service.check_files.check
-
- def filter_service(self, links):
- """"""
- services = {cons.TYPE_UNSUPPORTED: []}
- for link in links:
- found = False
- if "http://" in link:
- tmp = link.split("http://").pop()
- if "<" in tmp:
- tmp = tmp.split("<")[0]
- elif " " in tmp:
- tmp = tmp.split(" ")[0]
- elif "[" in tmp:
- tmp = tmp.split("[")[0]
- elif "'" in tmp:
- tmp = tmp.split("'")[0]
- link = "http://" + tmp
- for service in self.services:
- if link.find(service.name) > 0:
- found = True
- if service.name in services:
- services[service.name].append(link)
- else:
- services[service.name] = [link]
- if not found:
- services[cons.TYPE_UNSUPPORTED].append(link)
- return services
-
- def create_packages(self, dict):
- """"""
- packages = []
- files = []
- for service, links in dict.items():
- for link in links:
- found = False
- for tmp_link in files:
- if link[1] == tmp_link[1]:
- found = True
- if service not in tmp_link[2]:
- tmp_link[2].append(service)
- tmp_link[0].append(link[0])
- tmp_link[5].append(link[4])
- if not found:
- files.append(([link[0]], link[1], [service], link[2], link[3], [link[4]]))
- while len(files) > 0:
- tmp_name = []
- first = files[0]
- others = files[1:]
- for link in others:
- chars = re.split("[0-9]+", link[1])
- nums = re.split("[^0-9]+", link[1])
- tmp = ""
- for i in chars:
- if tmp+i == first[1][0:len(tmp+i)]:
- tmp += i
- for j in nums:
- if tmp+j == first[1][0:len(tmp+j)]:
- tmp += j
- tmp_name.append(tmp)
- final_name = ""
- for name in tmp_name:
- if len(name) > len(final_name):
- final_name = name
- if len(final_name) > 0:
- packages.append((final_name, [first]))
- del files[files.index(first)]
- tmp_list = []
- for link in files:
- if final_name in link[1]:
- tmp_list.append(link)
- for package_name, package_files in packages:
- if package_name == final_name:
- package_files += tmp_list
- for i in tmp_list:
- del files[files.index(i)]
- else:
- alone_name = first[1]
- alone_name = alone_name.split(".")
- alone_name.pop()
- alone_name = ".".join(alone_name)
- packages.append((alone_name, [first]))
- del files[files.index(first)]
- return packages
-
- def stop_all(self):
- """"""
- self.download_manager.quit()
-
-if __name__ == "__main__":
- from config import Config
- s = ServiceManager(Config())
- s.prueba()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/service_preferences.py /tmp/DgSymrsclJ/tucan-0.3.9/service_preferences.py
--- tucan-0.3.8/service_preferences.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/service_preferences.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,332 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-import service_config
-import cons
-
-class InfoPreferences(gtk.VBox):
- """"""
- def __init__(self, section, name, config, accounts=False):
- """"""
- gtk.VBox.__init__(self)
- vbox = gtk.VBox()
-
- frame = gtk.Frame()
- label = gtk.Label()
- label.set_markup("" + name + " ")
- frame.set_label_widget(label)
- frame.set_border_width(10)
- self.pack_start(frame)
- frame.add(vbox)
-
- hbox = gtk.HBox()
- label = gtk.Label()
- label.set_markup("" + _("Author") + ": ")
- hbox.pack_start(label, False, False, 10)
- label = gtk.Label(config.get(section, service_config.OPTION_AUTHOR))
- hbox.pack_start(label, False)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- hbox.pack_start(aspect)
- label = gtk.Label()
- label.set_markup("" + _("Version") + ": ")
- hbox.pack_start(label, False)
- label = gtk.Label(config.get(section, service_config.OPTION_VERSION))
- hbox.pack_start(label, False, False, 10)
- vbox.pack_start(hbox, False, False, 5)
-
- if not accounts:
- hbox = gtk.HBox()
- label = gtk.Label()
- label.set_markup("" + _("Slots") + ": ")
- hbox.pack_start(label, False, False, 10)
- label = gtk.Label(config.get(section, service_config.OPTION_SLOTS))
- hbox.pack_start(label, False)
- vbox.pack_start(hbox, False, False, 5)
- hbox = gtk.HBox()
- label = gtk.Label()
- label.set_markup("" + _("Captcha") + ": ")
- hbox.pack_start(label, False, False, 10)
- label = gtk.Label(config.get(section, service_config.OPTION_CAPTCHA))
- hbox.pack_start(label, False)
- vbox.pack_start(hbox, False, False, 5)
-
-class AccountPreferences(InfoPreferences):
- """"""
- def __init__(self, section, name, config, get_cookie):
- """"""
- InfoPreferences.__init__(self, section, name, config, True)
-
- self.get_cookie = get_cookie
-
- frame = gtk.Frame()
- frame.set_label_widget(gtk.image_new_from_file(cons.ICON_ACCOUNT))
- frame.set_border_width(10)
- self.pack_start(frame, False, False, 1)
- scroll = gtk.ScrolledWindow()
- scroll.set_size_request(-1, 110)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- frame.add(scroll)
- store = gtk.ListStore(gtk.gdk.Pixbuf, str, str, bool, bool, str)
- self.treeview = gtk.TreeView(store)
- scroll.add(self.treeview)
-
- self.treeview.set_rules_hint(True)
- #self.treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Active')
- icon_cell = gtk.CellRendererPixbuf()
- icon_cell.set_property("width", 50)
- tree_icon.pack_start(icon_cell, True)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('User Name')
- name_cell = gtk.CellRendererText()
- name_cell.set_property("width", 120)
- name_cell.set_property("editable", True)
- name_cell.connect("edited", self.change, 1)
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- self.treeview.append_column(tree_name)
-
- tree_pass = gtk.TreeViewColumn('Password')
- pass_cell = gtk.CellRendererText()
- pass_cell.set_property("width", 120)
- pass_cell.set_property("editable", True)
- pass_cell.connect("edited", self.change, 2)
- pass_cell.connect("editing-started", self.show_password)
- tree_pass.pack_start(pass_cell, True)
- tree_pass.add_attribute(pass_cell, 'text', 5)
- self.treeview.append_column(tree_pass)
-
- tree_enable = gtk.TreeViewColumn('Enable')
- enable_cell = gtk.CellRendererToggle()
- enable_cell.connect("toggled", self.toggled)
- tree_enable.pack_start(enable_cell, False)
- tree_enable.add_attribute(enable_cell, 'visible', 4)
- tree_enable.add_attribute(enable_cell, 'active', 3)
- self.treeview.append_column(tree_enable)
-
- self.active_service_icon = self.treeview.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_LARGE_TOOLBAR)
- self.unactive_service_icon = self.treeview.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_LARGE_TOOLBAR)
-
- accounts = config.get_accounts(section)
- for name in accounts.keys():
- password, enabled, active = accounts[name]
- if active:
- icon = self.active_service_icon
- else:
- icon = self.unactive_service_icon
- store.append([icon, name, password, enabled, active, "".join(["*" for i in range(len(password))])])
-
- frame = gtk.Frame()
- frame.set_border_width(10)
- frame.set_shadow_type(gtk.SHADOW_NONE)
- self.pack_start(frame, False, False)
- bbox = gtk.HButtonBox()
- bbox.set_layout(gtk.BUTTONBOX_EDGE)
- frame.add(bbox)
- button = gtk.Button(None, gtk.STOCK_ADD)
- button.connect("clicked", self.add)
- bbox.pack_start(button)
- button = gtk.Button(None, gtk.STOCK_REMOVE)
- button.connect("clicked", self.remove)
- bbox.pack_start(button)
- aspect = gtk.AspectFrame()
- aspect.set_shadow_type(gtk.SHADOW_NONE)
- bbox.pack_start(aspect)
- button = gtk.Button(None, gtk.STOCK_CONNECT)
- button.connect("clicked", self.check)
- bbox.pack_start(button)
-
- def show_password(self, cellrenderertext, editable, path):
- """"""
- model = self.treeview.get_model()
- editable.props.text = model.get_value(model.get_iter(path), 2)
-
- def change(self, cellrenderertext, path, new_text, column):
- """"""
- model = self.treeview.get_model()
- model.set_value(model.get_iter(path), column, new_text)
- if column == 2:
- model.set_value(model.get_iter(path), 5, "".join(["*" for i in range(len(new_text))]))
-
- def add(self, button):
- """"""
- model = self.treeview.get_model()
- iter = model.append([self.unactive_service_icon, "", "", False, False, ""])
- self.treeview.set_cursor(model.get_path(iter), self.treeview.get_column(1), True)
-
- def remove(self, button):
- """"""
- model, iter = self.treeview.get_selection().get_selected()
- if iter:
- next_iter = model.iter_next(iter)
- model.remove(iter)
- if next_iter:
- self.treeview.set_cursor_on_cell(model.get_path(next_iter))
-
- def check(self, button):
- """"""
- model, iter = self.treeview.get_selection().get_selected()
- if iter:
- cookie = self.get_cookie(model.get_value(iter, 1), model.get_value(iter, 2))
- if cookie:
- icon = self.active_service_icon
- active = True
- else:
- icon = self.unactive_service_icon
- active = False
- model.set_value(iter, 0, icon)
- model.set_value(iter, 3, active)
- model.set_value(iter, 4, active)
-
- def toggled(self, button, path):
- """"""
- model = self.treeview.get_model()
- if button.get_active():
- active = False
- else:
- active = True
- button.set_active(active)
- model.set_value(model.get_iter(path), 3, active)
-
- def get_accounts(self):
- """"""
- model = self.treeview.get_model()
- iter = model.get_iter_root()
- accounts = {}
- while iter:
- accounts[model.get_value(iter, 1)] = (model.get_value(iter, 2), model.get_value(iter, 3), model.get_value(iter, 4))
- iter = model.iter_next(iter)
- return accounts
-
-class ServicePreferences(gtk.Dialog):
- """"""
- def __init__(self, parent, service, icon, config):
- """"""
- gtk.Dialog.__init__(self)
- self.set_icon(icon)
- self.set_title(service)
- self.set_transient_for(parent)
- self.set_size_request(600, 400)
-
- self.config = config
-
- hbox = gtk.HBox()
- self.vbox.pack_start(hbox, True, True, 5)
- frame = gtk.Frame()
- hbox.pack_start(frame, False, False, 10)
-
- store = gtk.TreeStore(str, str, int)
- self.treeview = gtk.TreeView(store)
- self.treeview.get_selection().connect("changed", self.select)
- frame.add(self.treeview)
-
- self.treeview.set_headers_visible(False)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- name_cell.set_property("width", 100)
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- self.treeview.append_column(tree_name)
-
- self.notebook = gtk.Notebook()
- hbox.pack_start(self.notebook, True, True, 10)
- self.notebook.set_show_tabs(False)
-
- cont = 0
- plugin_list = []
- plugins = self.config.get_download_plugins()
- if plugins:
- plugin_list.append(("Download", plugins))
- plugins = self.config.get_upload_plugins()
- if plugins:
- plugin_list.append(("Upload", plugins))
- for item, plugins in plugin_list:
- iter = store.append(None, [None, item, -1])
- for section, section_name, section_type in plugins:
- page = gtk.VBox()
- if section_type == cons.TYPE_ANONYMOUS:
- page = InfoPreferences(section, section_name, self.config)
- else:
- if section_type == cons.TYPE_USER:
- module, name = config.user_cookie()
- elif section_type == cons.TYPE_PREMIUM:
- module, name = config.premium_cookie()
- if name:
- module = __import__(service.split(".")[0] + "." + module, None, None, [''])
- get_cookie = eval("module" + "." + name + "()").get_cookie
- page = AccountPreferences(section, section_name, self.config, get_cookie)
- self.notebook.append_page(page, None)
- subiter = store.append(iter, [section, section_type, cont])
- self.treeview.expand_to_path(store.get_path(subiter))
- if cont == 0:
- self.treeview.set_cursor_on_cell(store.get_path(subiter))
- cont += 1
- #action area
- cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
- save_button = gtk.Button(None, gtk.STOCK_SAVE)
- self.action_area.pack_start(cancel_button)
- self.action_area.pack_start(save_button)
- cancel_button.connect("clicked", self.close)
- save_button.connect("clicked", self.save)
-
- self.connect("response", self.close)
- self.show_all()
- self.run()
-
- def select(self, selection):
- """"""
- model, iter = selection.get_selected()
- if iter:
- child_iter = model.iter_children(iter)
- if child_iter:
- selection.select_iter(child_iter)
- else:
- self.notebook.set_current_page(model.get_value(iter, 2))
-
- def save(self, button):
- """"""
- model = self.treeview.get_model()
- iter = model.get_iter_root()
- while iter:
- child_iter = model.iter_children(iter)
- while child_iter:
- page = self.notebook.get_nth_page((model.get_value(iter, 2)))
- if ((page) and (model.get_value(child_iter, 1) != cons.TYPE_ANONYMOUS)):
- self.config.set_accounts(model.get_value(child_iter, 0), page.get_accounts())
- child_iter = model.iter_next(child_iter)
- iter = model.iter_next(iter)
- self.close()
-
- def close(self, widget=None, other=None):
- """"""
- self.destroy()
-
-if __name__ == "__main__":
- x = ServicePreferences("rapidshare.com", gtk.gdk.pixbuf_new_from_file(cons.ICON_MISSING), service_config.ServiceConfig("/home/crak/.tucan/plugins/megaupload/"))
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/service_update.py /tmp/DgSymrsclJ/tucan-0.3.9/service_update.py
--- tucan-0.3.8/service_update.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/service_update.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,134 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import urllib2
-import logging
-logger = logging.getLogger(__name__)
-
-from HTMLParser import HTMLParser
-
-from service_config import ServiceConfig
-import config
-
-import cons
-
-BASE = "https://forja.rediris.es/svn/cusl3-tucan/trunk"
-PLUGINS = "https://forja.rediris.es/svn/cusl3-tucan/branches/default_plugins/"
-CONF_FILE = "service.conf"
-
-class ServiceList(HTMLParser):
- """"""
- def __init__(self, url):
- """"""
- HTMLParser.__init__(self)
- self.services = []
- try:
- self.feed(urllib2.urlopen(urllib2.Request(url)).read())
- except (urllib2.URLError, urllib2.HTTPError), e:
- logger.error(e)
- self.close()
-
- def handle_starttag(self, tag, attrs):
- """"""
- if tag == "dir":
- self.services.append(attrs[1][1])
-
-class ServiceCheck(HTMLParser):
- """"""
- def __init__(self, url):
- """"""
- HTMLParser.__init__(self)
- self.files = []
- self.feed(urllib2.urlopen(urllib2.Request(url)).read())
- self.close()
-
- def handle_starttag(self, tag, attrs):
- """"""
- if tag == "file":
- self.files.append(attrs[1][1])
-
-class ServiceUpdate:
- """"""""
- def __init__(self, config):
- """urllib2 does not support proxy and https"""
- self.config = config
- self.local_services = config.get_services()
- self.server_version = None
- try:
- for line in urllib2.urlopen(urllib2.Request("%s/cons.py" % BASE)).readlines():
- if "VERSION" in line:
- self.server_version = line.split('"')[1].split('"')[0]
- except Exception, e:
- logger.exception(e)
-
- def get_updates(self):
- """"""
- new_services = {}
- list = ServiceList(PLUGINS)
- for remote_service in list.services:
- check = ServiceCheck(PLUGINS + remote_service)
- found = False
- if CONF_FILE in check.files:
- try:
- #get remote version
- config = ServiceConfig(None, urllib2.urlopen(urllib2.Request("%s%s%s" % (PLUGINS, remote_service, CONF_FILE))))
- remote_version = config.get_update()
- except Exception, e:
- logger.exception(e)
- else:
- #get local version
- for local_service in self.local_services:
- if local_service[0] == remote_service.split("/")[0]:
- found = True
- local_version = local_service[4].get_update()
- if remote_version > local_version:
- new_services[local_service[2]] = local_service[0], check.files, local_service[1]
- if not found:
- new_services[config.get_name()] = remote_service.split("/")[0], check.files, None
- return new_services
-
- def install_service(self, service_name, service_dir, files):
- """"""
- for file_name in files:
- try:
- handle = urllib2.urlopen(urllib2.Request("%s%s/%s" % (PLUGINS, service_dir, file_name)))
- except (urllib2.URLError, urllib2.HTTPError), e:
- logger.error(e)
- else:
- #windows incompatibility
- if "text" in handle.info()["Content-Type"]:
- write_mode = "w"
- else:
- write_mode = "wb"
- if not os.path.isdir(os.path.join(cons.PLUGIN_PATH, service_dir)):
- os.mkdir(os.path.join(cons.PLUGIN_PATH, service_dir))
- logger.warning("Updating: %s" % os.path.join(cons.PLUGIN_PATH, service_dir, file_name))
- f = file(os.path.join(cons.PLUGIN_PATH, service_dir, file_name), write_mode)
- f.write(handle.read())
- f.close()
- if not self.config.has_option(config.SECTION_SERVICES, service_name):
- self.config.set(config.SECTION_SERVICES, service_name, os.path.join(cons.PLUGIN_PATH, service_dir, ""))
-
-if __name__ == "__main__":
- from config import Config
- s = ServiceUpdate(Config())
- print s.server_version
- print s.get_updates()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/session.py /tmp/DgSymrsclJ/tucan-0.3.9/session.py
--- tucan-0.3.8/session.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/session.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,54 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import time
-import os.path
-import xml.etree.ElementTree
-
-import cons
-
-VERSION = "version"
-TIMESTAMP = "timestamp"
-CLOSED = "closed"
-
-class Session:
- """"""
- def __init__(self):
- """"""
- attrs = {VERSION: cons.TUCAN_VERSION, TIMESTAMP: time.strftime("%Y/%m/%d %H:%M"), CLOSED: "False"}
- self.tree = xml.etree.ElementTree.ElementTree(xml.etree.ElementTree.Element("Session", attrs))
-
- def load(self):
- """"""
- try:
- self.tree._setroot(self.tree.parse(cons.SESSION_FILE))
- except:
- print "error"
- else:
- print self.tree.getroot()
-
- def save(self):
- """"""
- self.tree.write(cons.SESSION_FILE)
-
-if __name__ == "__main__":
- s = Session()
- s.save()
- s.load()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/sessions.py /tmp/DgSymrsclJ/tucan-0.3.9/sessions.py
--- tucan-0.3.8/sessions.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/sessions.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,67 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import pickle
-
-from ConfigParser import SafeConfigParser
-
-import cons
-
-LAST_SESSION = "last.session"
-
-SECTION_DOWNLOADS = "downloads"
-OPTION_PACKAGES = "packages"
-OPTION_PACKAGES_INFO = "packages_info"
-
-PACKAGES = [('D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part', [(['http://www.megaupload.com/?d=GW1WB3IV', 'http://rapidshare.com/files/143483416/D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part1.rar'], 'D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part1.rar', ['megaupload.com', 'rapidshare.com'], 200, 'MB', ['AnonymousMegaupload', 'AnonymousRapidshare']), (['http://www.megaupload.com/?d=TITR6R0P', 'http://rapidshare.com/files/143483557/D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part2.rar'], 'D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part2.rar', ['megaupload.com', 'rapidshare.com'], 200, 'MB', ['AnonymousMegaupload', 'AnonymousRapidshare']), (['http://www.megaupload.com/?d=DCJX0RKQ', 'http://rapidshare.com/files/143483236/D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part3.rar'], 'D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part3.rar', ['megaupload.com', 'rapidshare.com'], 135, 'MB', ['AnonymousMegaupload', 'AnonymousRapidshare'])]), ('Californication.2x01.samuelro.part', [(['http://rapidshare.com/files/149540090/Californication.2x01.samuelro.part1.rar'], 'Californication.2x01.samuelro.part1.rar', ['rapidshare.com'], 200, 'MB', ['AnonymousRapidshare']), (['http://rapidshare.com/files/149537924/Californication.2x01.samuelro.part2.rar'], 'Californication.2x01.samuelro.part2.rar', ['rapidshare.com'], 41, 'MB', ['AnonymousRapidshare'])]), ('Californication.2x02.samuelro.part', [(['http://rapidshare.com/files/151602033/Californication.2x02.samuelro.part1.rar'], 'Californication.2x02.samuelro.part1.rar', ['rapidshare.com'], 195, 'MB', ['AnonymousRapidshare']), (['http://rapidshare.com/files/151408776/Californication.2x02.samuelro.part2.rar'], 'Californication.2x02.samuelro.part2.rar', ['rapidshare.com'], 45, 'MB', ['AnonymousRapidshare'])])]
-
-PACKAGES_INFO = [('/home/crak/', 'D.S03E01.PREAiR.DVDSCR.NOTYOU.cHoPPaHoLiK.part', None), ('/home/crak/downloads/', 'Californication.2x01.samuelro.part', 'mierda'), ('/home/crak/downloads/', 'Californication.2x02.samuelro.part', 'cojones')]
-
-class Sessions(SafeConfigParser):
- """"""
- def load_session(self, path):
- """"""
- result = None, None
- if os.path.exists(path):
- self.read(path)
- if self.has_section(SECTION_DOWNLOADS):
- if ((self.has_option(SECTION_DOWNLOADS, OPTION_PACKAGES)) and (self.has_option(SECTION_DOWNLOADS, OPTION_PACKAGES_INFO))):
- result = pickle.loads(self.get(SECTION_DOWNLOADS, OPTION_PACKAGES)), pickle.loads(self.get(SECTION_DOWNLOADS, OPTION_PACKAGES_INFO))
- return result
-
- def save_session(self, path, session_packages, session_info):
- """"""
- if not self.has_section(SECTION_DOWNLOADS):
- self.add_section(SECTION_DOWNLOADS)
- self.set(SECTION_DOWNLOADS, OPTION_PACKAGES, pickle.dumps(session_packages))
- self.set(SECTION_DOWNLOADS, OPTION_PACKAGES_INFO, pickle.dumps(session_info))
- self.save(path)
-
- def save(self, path):
- """"""
- f = open(path, "w")
- self.write(f)
- f.close()
-
-if __name__ == "__main__":
- s = Sessions()
- s.save_default_session(PACKAGES, PACKAGES_INFO)
- print s.load_default_session()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/slots.py /tmp/DgSymrsclJ/tucan-0.3.9/slots.py
--- tucan-0.3.8/slots.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/slots.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,53 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import time
-import logging
-logger = logging.getLogger(__name__)
-
-class Slots:
- """"""
- def __init__(self, slots=1, wait=300):
- """"""
- self.time_limit = wait
- self.limit = False
- self.end_wait = 0
- self.max = slots
- self.slots = slots
-
- def get_slot(self):
- """"""
- if self.slots > 0:
- if time.time() > self.end_wait:
- self.limit = False
- self.slots -= 1
- return True
-
- def add_wait(self):
- """"""
- logger.warning("Wait %i seconds." % self.time_limit)
- self.limit = True
- self.end_wait = time.time() + self.time_limit
-
- def return_slot(self):
- """"""
- if self.slots < self.max:
- self.slots += 1
- return True
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/statusbar.py /tmp/DgSymrsclJ/tucan-0.3.9/statusbar.py
--- tucan-0.3.8/statusbar.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/statusbar.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,156 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import __builtin__
-import gettext
-
-import time
-import logging
-logger = logging.getLogger(__name__)
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-import cons
-
-class Statusbar(gtk.Statusbar):
- """"""
- def __init__(self, limits):
- """"""
- gtk.Statusbar.__init__(self)
- self.set_has_resize_grip(False)
-
- #download speed limit
- frame = gtk.Frame()
- self.pack_start(frame, False, False)
- hbox = gtk.HBox()
- frame.add(hbox)
- label = gtk.Label(_("Max speed: "))
- hbox.pack_start(label)
- self.max_speed = gtk.SpinButton(None, 4, 0)
- self.max_speed.set_property("shadow-type", gtk.SHADOW_NONE)
- self.max_speed.set_range(0,5000)
- self.max_speed.set_increments(4,0)
- self.max_speed.set_numeric(True)
- self.max_speed.set_value(__builtin__.max_download_speed)
- hbox.pack_start(self.max_speed, False, False, 5)
-
- self.max_speed.connect("value-changed", self.change_speed)
-
- #show limits
- self.get_limits = limits
-
- self.menu = gtk.Menu()
-
- label = gtk.Label("Limits: ")
- self.pack_start(label, False)
-
- self.button = gtk.Button()
- self.button.set_image(gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_NONE))
- self.pack_start(self.button, False)
-
- self.limits = []
- self.max_limits = 0
-
- self.blinking = False
- self.white = True
- self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#fff"))
-
- self.button.connect("clicked", self.show_stack)
- self.show_all()
-
- gobject.timeout_add(60000, self.update_limits)
-
- def synchronize(self):
- """"""
- self.max_speed.set_value(__builtin__.max_download_speed)
-
- def change_speed(self, spinbutton):
- """"""
- __builtin__.max_download_speed = spinbutton.get_value_as_int()
-
- def update_limits(self):
- """"""
- self.limits = self.get_limits()
- if len(self.limits) > self.max_limits:
- if not self.blinking:
- gobject.timeout_add(800, self.blink)
- self.blinking = True
- logger.debug("Limits: %s" % self.limits)
- self.max_limits = len(self.limits)
- return True
-
- def blink(self):
- """"""
- if self.white:
- if self.blinking:
- self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#f99"))
- self.white = False
- return True
- else:
- return False
- else:
- self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#fff"))
- self.white = True
- if self.blinking:
- return True
- else:
- return False
-
- def show_stack(self, widget):
- """"""
- self.blinking = False
- for limit in self.menu:
- self.menu.remove(limit)
- self.limits = self.get_limits()
- if len(self.limits) == 0:
- self.limits = [("None", "", "", None)]
- for service, type, hour, icon_path in self.limits:
- limit = gtk.MenuItem()
- vbox = gtk.VBox()
- hbox = gtk.HBox()
- if icon_path:
- icon = gtk.gdk.pixbuf_new_from_file(icon_path)
- else:
- icon = gtk.gdk.pixbuf_new_from_file(cons.ICON_MISSING)
- hbox.pack_start(gtk.image_new_from_pixbuf(icon.scale_simple(24, 24, gtk.gdk.INTERP_BILINEAR)))
- hbox.pack_start(gtk.Label(service), True, True, 5)
- vbox.pack_start(hbox, True, False, 1)
- hbox = gtk.HBox()
- hbox.pack_start(gtk.Label(hour), True, True)
- hbox.pack_start(gtk.Label(type), True, True, 5)
- vbox.pack_start(hbox)
- limit.add(vbox)
- self.menu.append(limit)
- self.menu.append(gtk.SeparatorMenuItem())
- self.menu.show_all()
- self.menu.popup(None, None, self.menu_position, 1, 0, widget.get_allocation())
-
- def menu_position(self, menu, rect):
- """"""
- width, height = menu.size_request()
- window_x, window_y = self.parent.get_parent_window().get_position()
- return rect.x + window_x - (width - rect.width), rect.y + window_y - height, True
-
-if __name__ == "__main__":
- g = LimitStack()
- gtk.main()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/tesseract.py /tmp/DgSymrsclJ/tucan-0.3.9/tesseract.py
--- tucan-0.3.8/tesseract.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/tesseract.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,75 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import os
-import sys
-import subprocess
-import tempfile
-
-import ImageFile
-import Image
-import TiffImagePlugin
-
-import cons
-
-IMAGE_SUFFIX = ".tif"
-TEXT_SUFFIX = ".txt"
-
-class Tesseract:
- """"""
- def __init__(self, data, filter=None):
- """"""
- if "win" in sys.platform:
- self.image_name = os.path.join(sys.path[0], "tmp.tif")
- self.text_name = os.path.join(sys.path[0], "tmp")
- self.tesseract = os.path.join(sys.path[0], "tesseract", "tesseract.exe")
- else:
- self.text = tempfile.NamedTemporaryFile(suffix=TEXT_SUFFIX)
- self.image = tempfile.NamedTemporaryFile(suffix=IMAGE_SUFFIX)
- self.image_name = self.image.name
- self.text_name = self.text.name.rsplit(TEXT_SUFFIX, 1)[0]
- self.tesseract = "tesseract"
- p = ImageFile.Parser()
- p.feed(data)
- if filter:
- image = filter(p.close())
- else:
- image = p.close()
- image.save(self.image_name)
-
- def get_captcha(self):
- """"""
- captcha = ""
- if "win" in sys.platform:
- if subprocess.call([self.tesseract, self.image_name, self.text_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=134217728) == 0:
- f = file(self.text_name + TEXT_SUFFIX, "r")
- captcha = f.readline().strip()
- f.close()
- else:
- if subprocess.call([self.tesseract, self.image_name, self.text_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
- captcha = self.text.file.readline().strip()
- self.text.file.close()
- self.image.file.close()
- return captcha
-
-if __name__ == "__main__":
- f = file("tmp.png", "r")
- t = Tesseract(f.read())
- print t.get_captcha()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/TODO /tmp/DgSymrsclJ/tucan-0.3.9/TODO
--- tucan-0.3.8/TODO 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/TODO 2009-10-07 00:02:31.000000000 +0100
@@ -5,4 +5,3 @@
- Upload System.
- GenericTreeModel.
- Fill all docstrings.
-- Native support MACOSX.
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/toolbar.py /tmp/DgSymrsclJ/tucan-0.3.9/toolbar.py
--- tucan-0.3.8/toolbar.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/toolbar.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-class Toolbar(gtk.Toolbar):
- """"""
- def __init__(self, list):
- """list = [(tool_name, image, callback),]"""
- gtk.Toolbar.__init__(self)
- self.set_style(gtk.TOOLBAR_BOTH)
- for button in list:
- if button == None:
- item = gtk.SeparatorToolItem()
- else:
- item = gtk.ToolButton(button[1], button[0])
- item.connect("clicked", button[2])
- self.insert(item, -1)
\ No newline at end of file
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/tray_icon.py /tmp/DgSymrsclJ/tucan-0.3.9/tray_icon.py
--- tucan-0.3.8/tray_icon.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/tray_icon.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,71 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-import cons
-
-class TrayIcon(gtk.StatusIcon):
- """"""
- def __init__(self, show, hide, menu):
- """"""
- gtk.StatusIcon.__init__(self)
- self.set_tooltip("Tucan Manager - Version: %s" % cons.TUCAN_VERSION)
- self.set_from_file(cons.ICON_TUCAN)
- self.set_visible(True)
-
- self.window_visible = True
- self.show_window = show
- self.hide_window = hide
-
- self.menu = gtk.Menu()
- for item in menu:
- if item == None:
- tmp = gtk.SeparatorMenuItem()
- else:
- tmp = gtk.ImageMenuItem(item[0])
- tmp.connect('activate', item[1])
- self.menu.append(tmp)
- self.menu.show_all()
-
- self.connect('activate', self.activate)
- self.connect('popup-menu', self.popup_menu)
-
- def activate(self, statusicon, event=None):
- """"""
- if self.window_visible:
- self.hide_window()
- self.window_visible = False
- else:
- self.show_window()
- self.window_visible = True
-
- def popup_menu(self, statusicon, button, time):
- """"""
- self.menu.popup(None, None, gtk.status_icon_position_menu, button, time, self)
-
- def change_tooltip(self, statusbar, context, text):
- """"""
- #if context == "Downloads":
- tmp = text.split("\t")
- message = "Downloads: " + "".join(tmp[1:]) + "\n" + tmp[0].strip()
- self.set_tooltip(message)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/tree.py /tmp/DgSymrsclJ/tucan-0.3.9/tree.py
--- tucan-0.3.8/tree.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/tree.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,410 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import pango
-
-from statusbar import Statusbar
-
-import cons
-
-class Tree(gtk.VBox):
- """"""
- def __init__(self, menu, manager):
- """"""
- gtk.VBox.__init__(self)
- scroll = gtk.ScrolledWindow()
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, int, bool, str, str, str, str, str))
- scroll.add(self.treeview)
- self.pack_start(scroll)
-
- self.menu = gtk.Menu()
- for item in menu:
- if item == None:
- subitem = gtk.SeparatorMenuItem()
- else:
- subitem = gtk.ImageMenuItem(item[0])
- subitem.connect("activate", item[1])
- self.menu.append(subitem)
- self.menu.show_all()
- self.treeview.connect("button-press-event", self.mouse_menu)
-
- self.get_files = manager.get_files
-
- self.treeview.set_rules_hint(True)
- self.treeview.set_headers_visible(False)
-
- #tree columns
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- tree_icon.pack_start(icon_cell, False)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- self.treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- name_cell.set_property("width-chars", 60)
- name_cell.set_property("ellipsize", pango.ELLIPSIZE_MIDDLE)
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 3)
- self.treeview.append_column(tree_name)
-
- tree_progress = gtk.TreeViewColumn('Progress')
- tree_progress.set_min_width(150)
- progress_cell = gtk.CellRendererProgress()
- tree_progress.pack_start(progress_cell, True)
- tree_progress.add_attribute(progress_cell, 'value', 4)
- tree_progress.add_attribute(progress_cell, 'visible', 5)
- self.treeview.append_column(tree_progress)
-
- tree_current_size = gtk.TreeViewColumn('Current Size')
- current_size_cell = gtk.CellRendererText()
- tree_current_size.pack_start(current_size_cell, False)
- tree_current_size.add_attribute(current_size_cell, 'text', 6)
- self.treeview.append_column(tree_current_size)
-
- tree_total_size = gtk.TreeViewColumn('Total Size')
- total_size_cell = gtk.CellRendererText()
- tree_total_size.pack_start(total_size_cell, False)
- tree_total_size.add_attribute(total_size_cell, 'text', 7)
- self.treeview.append_column(tree_total_size)
-
- tree_speed = gtk.TreeViewColumn('Speed')
- speed_cell = gtk.CellRendererText()
- tree_speed.pack_start(speed_cell, False)
- tree_speed.add_attribute(speed_cell, 'text', 8)
- self.treeview.append_column(tree_speed)
-
- tree_time = gtk.TreeViewColumn('Time Left')
- time_cell = gtk.CellRendererText()
- tree_time.pack_start(time_cell, False)
- tree_time.add_attribute(time_cell, 'text', 9)
- self.treeview.append_column(tree_time)
-
- tree_plugins = gtk.TreeViewColumn('Plugin')
- plugins_cell = gtk.CellRendererText()
- tree_plugins.pack_start(plugins_cell, False)
- tree_plugins.add_attribute(plugins_cell, 'text', 10)
- self.treeview.append_column(tree_plugins)
-
- #icons
- self.package_icon = self.treeview.render_icon(gtk.STOCK_OPEN, gtk.ICON_SIZE_MENU)
- self.active_service_icon = self.treeview.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)
- self.unactive_service_icon = self.treeview.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU)
- self.correct_icon = self.treeview.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
- self.failed_icon = self.treeview.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
- self.wait_icon = self.treeview.render_icon(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
- self.active_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
- self.pending_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU)
- self.stoped_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_STOP, gtk.ICON_SIZE_MENU)
- self.icons = {cons.STATUS_CORRECT: self.correct_icon, cons.STATUS_ERROR: self.failed_icon, cons.STATUS_WAIT: self.wait_icon, cons.STATUS_ACTIVE: self.active_icon, cons.STATUS_PEND: self.pending_icon, cons.STATUS_STOP: self.stoped_icon}
-
- self.status_bar = Statusbar(manager.get_limits)
- self.pack_start(self.status_bar, False)
- self.status_bar.push(self.status_bar.get_context_id("Downloads"), " No Downloads Active.")
- self.updating = False
-
- def mouse_menu(self, widget, event):
- """right button"""
- if event.button == 3:
- model, paths = self.treeview.get_selection().get_selected_rows()
- if len(paths) > 0:
- self.menu.popup(None, None, None, event.button, event.time)
-
- def add_package(self, package_name, package_path, package, password):
- """
- TreeStore(icon, status, password, name, progress, progress_visible, current_size, total_size, speed, time, services)
- """
- tmp_size = []
- model = self.treeview.get_model()
- package_iter = model.append(None, [self.package_icon, cons.STATUS_PEND, password, package_name, 0, True, None, None, None, None, package_path])
- for item in package:
- tmp_size.append((item[3], item[4]))
- item_iter = model.append(package_iter, [self.pending_icon, cons.STATUS_PEND, None, item[1], 0, True, None, str(item[3])+item[4], None, None, str(item[2])])
- self.treeview.expand_to_path(model.get_path(item_iter))
- for link in item[0]:
- link_iter = model.append(item_iter, [self.unactive_service_icon, cons.STATUS_PEND, None, link, 0, False, None, None, None, None, item[5][item[0].index(link)]])
- package_size, package_unit = self.normalize(tmp_size)
- model.set_value(package_iter, 7, str(package_size)+package_unit)
- if not self.updating:
- self.updating = True
- gobject.timeout_add(1000, self.update)
- return package_iter
-
- def update(self):
- """(icon, status, None, name, progress, progress_visible, current_size, total_size, speed, time, services)"""
- files = self.get_files()
- if len(files) > 0:
- model = self.treeview.get_model()
- package_iter = model.get_iter_root()
- active_downloads = 0
- complete_downloads = 0
- total_downloads = 0
- total_speed = 0
- while package_iter:
- file_iter = model.iter_children(package_iter)
- #package_status = model.set_value(package_iter, 0)
- package_progress = 0
- package_speed = 0
- tmp_actual_size = []
- tmp_total_size = []
- while file_iter:
- total_downloads += 1
- name = model.get_value(file_iter, 3)
- for file in files:
- if file.name == name:
- model.set_value(file_iter, 0, self.icons[file.status])
- model.set_value(file_iter, 1, file.status)
- if file.status in [cons.STATUS_ACTIVE, cons.STATUS_WAIT]:
- active_downloads += 1
- elif file.status == cons.STATUS_CORRECT:
- complete_downloads += 1
- model.set_value(file_iter, 4, file.progress)
- package_progress += file.progress
- if file.actual_size > 0:
- model.set_value(file_iter, 6, str(file.actual_size)+file.actual_size_unit)
- tmp_actual_size.append((file.actual_size, file.actual_size_unit))
- tmp_total_size.append((file.total_size, file.total_size_unit))
- if file.speed > 1:
- model.set_value(file_iter, 8, str(file.speed)+cons.UNIT_SPEED)
- package_speed += file.speed
- elif file.speed == 0:
- model.set_value(file_iter, 8, None)
- if file.status == cons.STATUS_CORRECT:
- if not file.time > 0:
- file.time = 1
- file.actual_size = file.total_size
- file.actual_size_unit = file.total_size_unit
- model.set_value(file_iter, 9, self.calculate_time(file.time))
- link_iter = model.iter_children(file_iter)
- while link_iter:
- for tmp_link in file.links:
- if tmp_link.url == model.get_value(link_iter, 3):
- service_icon = self.unactive_service_icon
- link_status = cons.STATUS_STOP
- if tmp_link.active:
- service_icon = self.active_service_icon
- link_status = cons.STATUS_ACTIVE
- model.set_value(link_iter, 0, service_icon)
- model.set_value(link_iter, 1, link_status)
- link_iter = model.iter_next(link_iter)
- file_iter = model.iter_next(file_iter)
- package_actual_size, package_actual_unit = self.normalize(tmp_actual_size)
- package_total_size, package_total_unit = self.normalize(tmp_total_size)
- if package_actual_size > 0:
- if int(package_progress/model.iter_n_children(package_iter)) == 100:
- model.set_value(package_iter, 4, 100)
- else:
- model.set_value(package_iter, 4, int((float(self.get_size(package_actual_size, package_actual_unit))/float(self.get_size(package_total_size, package_total_unit)))*100))
- model.set_value(package_iter, 6, str(package_actual_size)+package_actual_unit)
- if package_speed > 0:
- model.set_value(package_iter, 8, str(package_speed)+cons.UNIT_SPEED)
- else:
- model.set_value(package_iter, 8, None)
- total_speed += package_speed
- package_iter = model.iter_next(package_iter)
- self.status_bar.pop(self.status_bar.get_context_id("Downloads"))
- self.status_bar.push(self.status_bar.get_context_id("Downloads"), " Downstream %dKB/s \tTotal %d \t Complete %d \t Active %d" % (total_speed, total_downloads, complete_downloads, active_downloads))
- return True
-
- def normalize(self, sizes):
- """"""
- total = 0
- total_unit = cons.UNIT_KB
- for size, unit in sizes:
- total += self.get_size(size, unit)
- tmp = int(total/1024)
- if tmp > 0:
- total = tmp
- total_unit = cons.UNIT_MB
- tmp = int(tmp/1024)
- # if tmp > 0:
- # total = tmp
- # total_unit = cons.UNIT_GB
- return total, total_unit
-
- def get_size(self, size, unit):
- """"""
- if unit == cons.UNIT_KB:
- return size
- elif unit == cons.UNIT_MB:
- return size*1024
- #elif unit == cons.UNIT_GB:
- # return size*1024*1024
-
- def get_packages(self):
- """"""
- model = self.treeview.get_model()
- package_iter = model.get_iter_root()
- packages = []
- info = []
- while package_iter:
- files = []
- file_iter = model.iter_children(package_iter)
- while file_iter:
- if model.get_value(file_iter, 1) != cons.STATUS_CORRECT:
- links = []
- plugins = []
- link_iter = model.iter_children(file_iter)
- while link_iter:
- links.append(model.get_value(link_iter, 3))
- plugins.append(model.get_value(link_iter, 10))
- link_iter = model.iter_next(link_iter)
- name = model.get_value(file_iter, 3)
- tmp = model.get_value(file_iter, 7)
- for unit in [cons.UNIT_KB, cons.UNIT_MB]:
- tmp_size = tmp.split(unit)
- if len(tmp_size) > 1:
- size_unit = unit
- size = int(tmp_size[0])
- break
- tmp = model.get_value(file_iter, 10)
- tmp = tmp.split(",")
- service_list = []
- for service in tmp:
- service_list.append(service.split("\'")[1])
- files.append((links, name, service_list, size, size_unit, plugins))
- file_iter = model.iter_next(file_iter)
- if len(files) > 0:
- name = model.get_value(package_iter, 3)
- packages.append((name, files))
- path = model.get_value(package_iter, 10).split(name)[0]
- info.append((path, name, model.get_value(package_iter, 2)))
- package_iter = model.iter_next(package_iter)
- return packages, info
-
- def get_links(self, iter):
- """"""
- links = []
- model = self.treeview.get_model()
- file_iter = model.iter_children(iter)
- if not file_iter:
- links.append(model.get_value(iter, 3))
- while file_iter:
- link_iter = model.iter_children(file_iter)
- if not link_iter:
- links.append(model.get_value(file_iter, 3))
- while link_iter:
- links.append(model.get_value(link_iter, 3))
- link_iter = model.iter_next(link_iter)
- file_iter = model.iter_next(file_iter)
- return links
-
- def package_files(self, package_iter):
- """"""
- files = []
- model = self.treeview.get_model()
- file_iter = model.iter_children(package_iter)
- while file_iter:
- if model.get_value(file_iter, 1) not in [cons.STATUS_ACTIVE, cons.STATUS_WAIT, cons.STATUS_CORRECT]:
- files.append(model.get_value(file_iter, 3))
- file_iter = model.iter_next(file_iter)
- return files
-
- def clear(self):
- """"""
- files = []
- model = self.treeview.get_model()
- package_iter = model.get_iter_root()
- while package_iter:
- tmp_iter = package_iter
- package_iter = model.iter_next(package_iter)
- files += self.delete_package([cons.STATUS_CORRECT], tmp_iter)
- return files
-
- def delete_package(self, status, package_iter):
- """"""
- tmp = []
- model = self.treeview.get_model()
- file_iter = model.iter_children(package_iter)
- while file_iter:
- if model.get_value(file_iter, 1) in status:
- tmp.append(model.get_value(file_iter, 3))
- file_iter = model.iter_next(file_iter)
- if len(tmp) == model.iter_n_children(package_iter):
- model.remove(package_iter)
- else:
- tmp = []
- return tmp
-
- def delete_file(self, status, iter):
- """"""
- model = self.treeview.get_model()
- if model.get_value(iter, 1) in status:
- if model.iter_n_children(model.iter_parent(iter)) > 1:
- result = model.get_value(iter, 3)
- model.remove(iter)
- return result
-
- def delete_link(self, status, iter):
- """"""
- result = None, None
- model = self.treeview.get_model()
- file_iter = model.iter_parent(iter)
- if model.iter_n_children(file_iter) > 1:
- if model.get_value(iter, 1) == cons.STATUS_STOP:
- result = model.get_value(file_iter, 3), model.get_value(iter, 3)
- model.remove(iter)
- return result
-
- def move_up(self, iter):
- """"""
- model = self.treeview.get_model()
- package_iter = model.iter_parent(iter)
- file_iter = model.iter_children(package_iter)
- prev_iter = None
- while ((file_iter) and (model.get_path(file_iter) != model.get_path(iter))):
- prev_iter = file_iter
- file_iter = model.iter_next(file_iter)
- if prev_iter:
- model.move_before(iter, prev_iter)
- return True
-
- def move_down(self, iter):
- """"""
- model = self.treeview.get_model()
- next_iter = model.iter_next(iter)
- if next_iter:
- model.move_after(iter, next_iter)
- return True
-
- def calculate_time(self, time):
- """"""
- result = None
- hours = 0
- minutes = 0
- while time >= cons.HOUR:
- time = time - cons.HOUR
- hours += 1
- while time >= cons.MINUTE:
- time = time - cons.MINUTE
- minutes += 1
- seconds = time
- if hours > 0:
- result = str(hours) + "h" + str(minutes) + "m" + str(seconds) + "s"
- elif minutes > 0:
- result = str(minutes) + "m" + str(seconds) + "s"
- elif seconds > 0:
- result = str(seconds) + "s"
- return result
Binary files /tmp/Mj7pJvsoYS/tucan-0.3.8/tucan.1.gz and /tmp/DgSymrsclJ/tucan-0.3.9/tucan.1.gz differ
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/tucan.py /tmp/DgSymrsclJ/tucan-0.3.9/tucan.py
--- tucan-0.3.8/tucan.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/tucan.py 2009-10-07 00:02:31.000000000 +0100
@@ -20,72 +20,162 @@
###############################################################################
import __builtin__
-import os.path
+import os
import sys
import logging
+import optparse
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-from gui import Gui
-
-import url_open
-import config
-import cons
+import core.misc as misc
+import core.url_open as url_open
+import core.config as config
+import core.cons as cons
class Tucan:
""""""
def __init__(self):
""""""
#exception hook
- self.old_exception_hook = sys.excepthook
sys.excepthook = self.exception_hook
+
+ #parse options
+ parser = optparse.OptionParser()
+ parser.add_option("-w", "--wizard", dest="wizard", help="setup: accounts, services, updates", metavar="TYPE")
+ parser.add_option("-d", "--daemon", action="store_true", dest="daemon", default=False, help="no interaction interface")
+ parser.add_option("-c", "--cli", action="store_true", dest="cli", default=False, help="command line interface")
+ parser.add_option("-i", "--input-links", dest="links_file", help="import links from FILE", metavar="FILE")
+ parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="print log to stdout")
+ parser.add_option("-V", "--version", action="store_true", dest="version", default=False, help="print version and exit")
+ options, args = parser.parse_args()
+
+ if options.version:
+ print "%s %s" % (cons.TUCAN_NAME, cons.TUCAN_VERSION)
+ sys.exit()
#configuration
- self.configuration = config.Config()
+ __builtin__.configuration = config.Config()
sys.path.append(cons.PLUGIN_PATH)
- #globals
- __builtin__.max_downloads = self.configuration.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS)
- __builtin__.max_download_speed = self.configuration.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED)
-
#logging
if os.path.exists(cons.LOG_FILE):
if os.path.exists("%s.old" % cons.LOG_FILE):
os.remove("%s.old" % cons.LOG_FILE)
os.rename(cons.LOG_FILE, "%s.old" % cons.LOG_FILE)
- logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s] %(name)s %(levelname)s: %(message)s', filename=cons.LOG_FILE, filemode='w')
+ logging.basicConfig(level=logging.DEBUG, format=cons.LOG_FORMAT, filename=cons.LOG_FILE, filemode='w')
self.logger = logging.getLogger(self.__class__.__name__)
+
+ #start user interface
+ try:
+ self.set_globals(options)
+ if options.wizard:
+ self.set_verbose()
+ self.start_wizard(options.wizard)
+ elif options.daemon:
+ self.set_verbose()
+ self.start_daemon(options.links_file)
+ elif options.cli:
+ self.start_cli(options.links_file)
+ else:
+ if options.verbose:
+ self.set_verbose()
+ self.start_gui()
+ except KeyboardInterrupt:
+ self.exit("KeyboardInterrupt")
+ except Exception, e:
+ self.logger.exception(e)
+ print e
+ print "Reporting error, please wait..."
+ #print "REPORT ID: %s" % misc.report_log("Automatic", str(e))
+ print "Unhandled Error! Check the log file for details."
+ self.exit(-1)
+
+ def set_verbose(self, severity=logging.INFO):
+ """"""
+ console = logging.StreamHandler(sys.stdout)
+ console.setLevel(severity)
+ console.setFormatter(logging.Formatter('%(levelname)-7s %(name)s: %(message)s'))
+ logging.getLogger("").addHandler(console)
+
+ def start_wizard(self, wizard_type):
+ """"""
+ from ui.console.wizard import Wizard
+
+ w = Wizard()
+ if wizard_type == "accounts":
+ w.account_setup(configuration)
+ elif wizard_type == "services":
+ w.service_setup(configuration)
+ elif wizard_type == "updates":
+ w.update_setup(configuration)
+ else:
+ print "TYPE should be one of: accounts, services or updates"
+
+ def start_daemon(self, file):
+ """"""
+ from ui.console.no_ui import NoUi
+
+ d = NoUi(configuration, file)
+ d.run()
+
+ def start_cli(self, file):
+ """"""
+ if cons.OS_WINDOWS:
+ print "No curses support."
+ self.exit()
+ else:
+ from curses.wrapper import wrapper
+ from ui.console.cli import Cli
+
+ c = Cli(configuration, file)
+ wrapper(c.run)
- self.logger.info(cons.TUCAN_VERSION)
- self.logger.debug("Main path: %s" % cons.PATH)
- self.logger.debug("Configuration path: %s" % cons.CONFIG_PATH)
+ def start_gui(self):
+ """"""
+ import pygtk
+ pygtk.require('2.0')
+ import gtk
+ import gobject
+
+ from ui.gtk.gui import Gui
+
+ try:
+ gtk.init_check()
+ except:
+ print "Could not connect to X server. Use 'tucan --cli' for curses interface."
+ else:
+ gobject.threads_init()
+ Gui(configuration)
+ gtk.main()
+
+ def set_globals(self, options):
+ """"""
+ #custom exit
+ __builtin__.tucan_exit = self.exit
#proxy settings
- proxy_url, proxy_port = self.configuration.get_proxy()
+ __builtin__.PROXY = None
+ proxy_url, proxy_port = configuration.get_proxy()
url_open.set_proxy(proxy_url, proxy_port)
-
- #global custom exit
- __builtin__.tucan_exit = self.exit
+
+ __builtin__.max_downloads = configuration.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS)
+ __builtin__.max_download_speed = configuration.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED)
def exception_hook(self, type, value, trace):
""""""
file_name = trace.tb_frame.f_code.co_filename
line_no = trace.tb_lineno
exception = type.__name__
- self.logger.critical("File %s line %i - %s: %s" % (file_name, line_no, exception, value))
- print self.old_exception_hook(type, value, trace)
+ try:
+ self.logger.critical("File %s line %i - %s: %s" % (file_name, line_no, exception, value))
+ except:
+ pass
+ sys.__excepthook__(type, value, trace)
self.exit(-1)
def exit(self, arg=0):
""""""
self.logger.debug("Exit: %s" % arg)
- exit(arg)
+ sys.exit(arg)
if __name__ == "__main__":
- gobject.threads_init()
t = Tucan()
- Gui(t.configuration)
- gtk.main()
+
\ No newline at end of file
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/console/cli.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/console/cli.py
--- tucan-0.3.8/ui/console/cli.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/console/cli.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,180 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import threading
+import time
+import curses
+import logging
+logger = logging.getLogger(__name__)
+
+from no_ui import NoUi
+from core.log_stream import LogStream
+
+import core.cons as cons
+
+STATUS_LINES = 1
+DOWNLOAD_LINES = 60
+LOG_LINES = 50
+WIDTH = 100
+
+class Cli(NoUi):
+ """"""
+ def __init__(self, *kwargs):
+ """"""
+ #set logger
+ self.stream = LogStream()
+ handler = logging.StreamHandler(self.stream)
+ handler.setLevel(logging.INFO)
+ handler.setFormatter(logging.Formatter('%(levelname)-7s %(message)s'))
+ logging.getLogger("").addHandler(handler)
+
+ NoUi.__init__(self, *kwargs)
+ self.quit_question = False
+ self.win_height = 0
+ self.win_chars = 0
+ self.last_length = 0
+ self.total_speed = 0
+
+ def run(self, screen):
+ """"""
+ self.screen = screen
+ self.screen.nodelay(1)
+ try:
+ curses.curs_set(0)
+ except:
+ logger.warning("Could not hide the cursor")
+
+ #set default screen
+ self.status_pad = curses.newpad(STATUS_LINES, WIDTH)
+ self.main_pad = curses.newpad(DOWNLOAD_LINES, WIDTH)
+ self.log_pad = curses.newpad(LOG_LINES, WIDTH)
+
+ #load links file
+ th = threading.Thread(group=None, target=self.load_file, name=None)
+ th.start()
+
+ while True:
+ self.win_height, self.win_chars = self.screen.getmaxyx()
+ self.parse_input()
+ try:
+ log_len = self.update_main()
+ self.update_log(log_len)
+ except curses.error, e:
+ logger.warning(e)
+ else:
+ curses.doupdate()
+ time.sleep(0.5)
+
+ def parse_input(self):
+ """"""
+ try:
+ input = self.screen.getkey()
+ except curses.error:
+ if not self.quit_question:
+ self.update_status()
+ else:
+ if self.quit_question:
+ if input.lower() == "y":
+ self.quit()
+ else:
+ self.quit_question = False
+ self.update_status()
+ else:
+ if input.lower() == "q":
+ self.quit_question = True
+ self.question()
+ else:
+ self.update_status()
+
+ def update_main(self):
+ """"""
+ if self.win_height > 5:
+ cont = 0
+ self.main_pad.erase()
+ self.total_speed = 0
+ for download in self.download_manager.complete_downloads + self.download_manager.active_downloads:
+ service = "[]"
+ for link in download.links:
+ if link.active:
+ service = "[%s %s]" %(link.plugin_type, link.service)
+ self.total_speed += download.speed
+ percent = "%i%s" % (int(download.progress), "%")
+ speed = "%s KB/s" % download.speed
+ size = "%i%s / %i%s" % (download.actual_size, download.actual_size_unit, download.total_size, download.total_size_unit)
+ time = str(self.calculate_time(download.time))
+ self.main_pad.addnstr(cont, 1, download.name, WIDTH)
+ self.main_pad.addnstr(cont+1, 5, "%s %s \t%s \t%s \t%s" % (percent, service, size, speed, time), WIDTH)
+ cont +=3
+ self.download_manager.update()
+ #2 primeras lineas en blanco
+ cont +=2
+ remain = self.win_height-cont
+ start = 0
+ while remain <= 5:
+ remain += 3
+ start += 3
+ self.main_pad.noutrefresh(start, 0, 2, 0, cont-start, self.win_chars-1)
+ return remain
+
+ def update_log(self, length):
+ """"""
+ if length:
+ lines = self.stream.readnlines(length)
+ if lines:
+ self.last_length = length
+ self.log_pad.erase()
+ for i in range(len(lines)):
+ self.log_pad.addnstr(i, 0, lines[i], WIDTH, curses.A_DIM)
+ self.log_pad.noutrefresh(0, 0, self.win_height-length, 0, self.win_height-1, self.win_chars-1)
+
+ def update_status(self):
+ """"""
+ active = len(self.download_manager.active_downloads)
+ complete = len(self.download_manager.complete_downloads)
+ total = len(self.download_manager.pending_downloads + self.download_manager.active_downloads + self.download_manager.complete_downloads)
+ self.status_pad.erase()
+ self.status_pad.addnstr(0, 0, "Downstream: %s KB/s \tTotal %s \tActive %s \tComplete %s" % (self.total_speed, total, active, complete), WIDTH, curses.A_BOLD)
+ self.status_pad.noutrefresh(0, 0, 0, 0, 0, self.win_chars-1)
+
+ def question(self):
+ """"""
+ self.status_pad.erase()
+ self.status_pad.addnstr(0, 0, "Are you sure you want to quit? [y/N]", WIDTH, curses.A_STANDOUT)
+ self.status_pad.noutrefresh(0, 0, 0, 0, 0, self.win_chars-1)
+
+ def calculate_time(self, time):
+ """"""
+ result = None
+ hours = 0
+ minutes = 0
+ while time >= cons.HOUR:
+ time = time - cons.HOUR
+ hours += 1
+ while time >= cons.MINUTE:
+ time = time - cons.MINUTE
+ minutes += 1
+ seconds = time
+ if hours > 0:
+ result = str(hours) + "h" + str(minutes) + "m" + str(seconds) + "s"
+ elif minutes > 0:
+ result = str(minutes) + "m" + str(seconds) + "s"
+ elif seconds > 0:
+ result = str(seconds) + "s"
+ return result
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/console/no_ui.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/console/no_ui.py
--- tucan-0.3.8/ui/console/no_ui.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/console/no_ui.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,100 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import os
+import sys
+import time
+import __builtin__
+import gettext
+import logging
+logger = logging.getLogger(__name__)
+
+from core.core import Core
+
+import core.config as config
+import core.cons as cons
+
+class NoUi(Core):
+ """"""
+ def __init__(self, conf, links_file):
+ """"""
+ self.configuration = conf
+ self.links_file = links_file
+ Core.__init__(self, self.configuration)
+
+ def run(self):
+ """"""
+ self.load_file()
+ while len(self.download_manager.active_downloads + self.download_manager.pending_downloads) > 0:
+ self.download_manager.update()
+ time.sleep(1)
+ self.quit()
+
+ def load_file(self):
+ """"""
+ if self.links_file:
+ try:
+ f = open(self.links_file, "r")
+ links = [link.lower().strip() for link in f.read().split("\n") if link and not link.startswith("#")]
+ f.close()
+ self.manage_packages(self.create_packages(self.check_links(links)), [])
+ except Exception, e:
+ logger.error(e)
+
+
+ def check_links(self, link_list):
+ """"""
+ result = {}
+ for service, links in self.filter_service(link_list).items():
+ if service != cons.TYPE_UNSUPPORTED:
+ tmp = []
+ check, plugin_type = self.get_check_links(service)
+ for link in links:
+ file_name, size, size_unit = check(link)
+ if file_name:
+ if size > 0:
+ tmp.append((link, file_name, size, size_unit, plugin_type))
+ else:
+ file_name = link
+ logger.info("Checked: %s %s %s" % (file_name, size, size_unit))
+ if len(tmp) > 0:
+ result[service] = tmp
+ return result
+
+ def manage_packages(self, packages, packages_info):
+ """"""
+ if not len(packages_info) > 0:
+ default_path = self.configuration.get_downloads_folder()
+ packages_info = [(default_path, name, None) for name, package_files in packages]
+ for package_name, package_downloads in packages:
+ info = packages_info[packages.index((package_name, package_downloads))]
+ package_name = info[1].replace(" ", "_")
+ package_path = os.path.join(info[0], package_name, "")
+ for download in package_downloads:
+ tmp = []
+ for service in download[2]:
+ plugin, plugin_type = self.get_download_plugin(service)
+ tmp.append((download[0][download[2].index(service)], plugin, plugin_type, service))
+ self.download_manager.add(package_path, download[1], tmp, download[3], download[4])
+
+ def quit(self):
+ """"""
+ self.stop_all()
+ tucan_exit(0)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/console/wizard.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/console/wizard.py
--- tucan-0.3.8/ui/console/wizard.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/console/wizard.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,225 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import getpass
+import logging
+logger = logging.getLogger(__name__)
+
+from core.service_update import ServiceUpdate
+from core.service_config import SECTION_PREMIUM_DOWNLOAD
+
+import core.misc
+import core.cons as cons
+
+class Wizard:
+ """"""
+ def __init__(self):
+ """"""
+ core.misc.main_info()
+
+ def account_setup(self, config):
+ """"""
+ logger.info("Setup accounts.")
+ quit = False
+ services = [service for service in config.get_services() if service[4].premium_cookie()[1] or service[4].user_cookie()[1]]
+ while not quit:
+ try:
+ cont = 0
+ for service in services:
+ print " [%s]\t%s \t%i accounts." % (cont, service[2], len(service[4].get_accounts(SECTION_PREMIUM_DOWNLOAD)))
+ cont +=1
+ input = raw_input("Choose [N] service or (Q)uit: ").strip()
+ if input.lower() == "q":
+ quit = True
+ elif int(input) in range(cont):
+ service = services[int(input)]
+ #module, class_name = service_config.user_cookie()
+ module, class_name = service[4].premium_cookie()
+ module = __import__("%s.%s" % (service[0], module), None, None, [''])
+ self.account_setup2(service, eval("module" + "." + class_name + "()").get_cookie)
+ except ValueError:
+ pass
+ except Exception, e:
+ logger.error("Error. %s" % e)
+ logger.info("DONE")
+
+ def account_setup2(self, service, get_cookie):
+ """"""
+ end = False
+ accounts = service[4].get_accounts(SECTION_PREMIUM_DOWNLOAD)
+ while not end:
+ try:
+ logger.info("Premium accounts for '%s'" % service[2])
+ cont = 0
+ for name, settings in accounts.items():
+ print " [%s]\t'%s' %s and %s" % (cont, name, self.get_active(settings[2]), self.get_status(settings[1]))
+ cont += 1
+ input = raw_input("Modify [N] account, (A)dd or (R)eturn: ").strip()
+ if input.lower() == "r":
+ service[4].set_accounts(SECTION_PREMIUM_DOWNLOAD, accounts)
+ end = True
+ elif input.lower() == "a":
+ user = self.get_user()
+ if user:
+ password = self.get_password()
+ if self.check_account(user, password, get_cookie):
+ accounts[user] = (password, True, True)
+ else:
+ accounts[user] = (password, False, False)
+ elif int(input) in range(cont):
+ name, settings = accounts.items()[int(input)]
+ input2 = raw_input("Set (U)ser, (P)assword, (E)nabled or (D)elete: ").strip()
+ if input2.lower() == "d":
+ del accounts[name]
+ logger.warning("'%s': DELETED!" % name)
+ elif input2.lower() == "u":
+ user = self.get_user()
+ if user:
+ logger.info("Changed '%s' to '%s'." % (name, user))
+ del accounts[name]
+ if self.check_account(user, settings[0], get_cookie):
+ accounts[user] = (settings[0], True, True)
+ else:
+ accounts[user] = (settings[0], False, False)
+ elif input2.lower() == "p":
+ password = self.get_password()
+ if password:
+ if self.check_account(name, settings[0], get_cookie):
+ accounts[name] = (password, True, True)
+ else:
+ accounts[name] = (password, False, False)
+ elif input2.lower() == "e":
+ enabled = settings[1]
+ if enabled:
+ enabled = not enabled
+ else:
+ if self.check_account(name, settings[0], get_cookie):
+ enabled = not enabled
+ accounts[name] = (settings[0], enabled, settings[2])
+ logger.info("'%s': %s" % (name, self.get_status(enabled)))
+ except ValueError:
+ pass
+ except Exception, e:
+ logger.error("Error. %s" % e)
+
+ def check_account(self, user, password, get_cookie):
+ """"""
+ logger.info("Checking account '%s'..." % user)
+ try:
+ if get_cookie(user, password):
+ logger.info("'%s': SUCCESS!" % user)
+ return True
+ else:
+ logger.warning("'%s': INVALID ACCOUNT." % user)
+ except Exception, e:
+ logger.error("Error. %s" % e)
+
+ def get_user(self):
+ """"""
+ user = raw_input("User: ").strip()
+ if user:
+ return user
+ else:
+ logger.error("No user name.")
+
+ def get_password(self):
+ """"""
+ while True:
+ pass1 = getpass.getpass("Password: ")
+ if pass1:
+ pass2 = getpass.getpass("Retype Password: ")
+ if pass1 == pass2:
+ return pass1
+ else:
+ logger.error("Passwords do not match.")
+ else:
+ logger.error("No password supplied.")
+
+
+ def get_active(self, status):
+ """"""
+ if status:
+ return "ACTIVE"
+ else:
+ return "INACTIVE"
+
+ def get_status(self, status):
+ """"""
+ if status:
+ return "ENABLED"
+ else:
+ return "DISABLED"
+
+ def list_enabled(self, services):
+ """"""
+ cont = 0
+ for service in services:
+ print " [%s]\t%s \t%s" % (cont, self.get_status(service[3]), service[2])
+ cont +=1
+ return cont
+
+ def service_setup(self, config):
+ """"""
+ logger.info("Enable services.")
+ quit = False
+ services = config.get_services()
+ cont = self.list_enabled(services)
+ while not quit:
+ try:
+ input = raw_input("Choose [N] service, (L)ist or (Q)uit: ").strip()
+ if input.lower() == "q":
+ quit = True
+ elif input.lower() == "l":
+ self.list_enabled(services)
+ elif int(input) in range(cont):
+ service = services[int(input)]
+ status = not service[3]
+ if status:
+ logger.info("You should read '%s' terms of service." % service[2])
+ logger.info("'%s' %s" % (service[2], self.get_status(status)))
+ service[4].enable(status)
+ services = config.get_services()
+ except ValueError:
+ pass
+ except Exception, e:
+ logger.error("Invalid argument!")
+ logger.info("DONE")
+
+ def update_setup(self, config):
+ """"""
+ try:
+ s = ServiceUpdate(config)
+ logger.info("Checking updates...")
+ s.get_updates()
+ new = 0
+ updates = 0
+ for key, value in s.updates.items():
+ if value[2]:
+ updates +=1
+ else:
+ new += 1
+ logger.info("%i New and %i Updates" % (new, updates))
+ for key, value in s.updates.items():
+ s.install_service(key, value[0], value[1])
+ except Exception, e:
+ logger.error("Error updating. %s" % e)
+ else:
+ config.save()
+ logger.info("DONE")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/about.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/about.py
--- tucan-0.3.8/ui/gtk/about.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/about.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,69 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+import media
+import core.cons as cons
+
+NAME = "Tucan"
+COPYRIGHT = "(C) 2008-2009 The Tucan Project"
+LICENSE = """
+ 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 .
+ """
+
+class About(gtk.AboutDialog):
+ """"""
+ def __init__(self, parent=None):
+ """"""
+ gtk.AboutDialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_icon_from_file(media.ICON_TUCAN)
+ self.set_logo(gtk.gdk.pixbuf_new_from_file(media.ICON_TUCAN))
+ self.set_name(NAME)
+ self.set_version(cons.TUCAN_VERSION)
+ self.set_copyright(COPYRIGHT)
+ self.set_license(LICENSE)
+ self.set_website(cons.WEBPAGE)
+ self.connect("response", self.close)
+ self.show_all()
+ self.run()
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
+
+if __name__ == "__main__":
+ g = About()
+ gtk.main()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/advanced_packages.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/advanced_packages.py
--- tucan-0.3.8/ui/gtk/advanced_packages.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/advanced_packages.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,212 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import time
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from file_chooser import FileChooser
+
+import media
+import core.cons as cons
+
+class AdvancedPackages(gtk.Dialog):
+ """"""
+ def __init__(self, parent, default_path, packages):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_icon_from_file(media.ICON_PACKAGE)
+ self.set_transient_for(parent)
+ self.set_title("%s - %s" % (cons.TUCAN_NAME, _("Advanced Packages")))
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(600,400)
+
+ self.packages = packages
+ self.packages_info = []
+ self.history_path = default_path
+
+ #radio
+ frame = gtk.Frame()
+ self.vbox.pack_start(frame, False, False)
+ frame.set_border_width(10)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ multi = gtk.RadioButton(None, "Auto Package Mode")
+ multi.connect("toggled", self.change_mode, True)
+ hbox.pack_start(multi)
+ single = gtk.RadioButton(multi, "Single Package Mode")
+ single.connect("toggled", self.change_mode, False)
+ hbox.pack_start(single)
+
+ #treeview
+ frame = gtk.Frame()
+ self.vbox.pack_start(frame)
+ frame.set_border_width(10)
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.multi_model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, int)
+ self.single_model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, int)
+ self.treeview = gtk.TreeView(self.multi_model)
+ self.treeview.get_selection().connect("changed", self.select)
+ scroll.add(self.treeview)
+
+ self.treeview.set_rules_hint(True)
+ #self.treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.treeview.append_column(tree_icon)
+
+ tree_path = gtk.TreeViewColumn('Path')
+ path_cell = gtk.CellRendererText()
+ tree_path.pack_start(path_cell, True)
+ tree_path.add_attribute(path_cell, 'text', 1)
+ self.treeview.append_column(tree_path)
+ self.treeview.connect("row-activated", self.choose)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.set_property("editable", True)
+ name_cell.connect("edited", self.change, 2)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 2)
+ self.treeview.append_column(tree_name)
+
+ tree_pass = gtk.TreeViewColumn('Password')
+ pass_cell = gtk.CellRendererText()
+ pass_cell.set_property("editable", True)
+ pass_cell.connect("edited", self.change, 3)
+ tree_pass.pack_start(pass_cell, True)
+ tree_pass.add_attribute(pass_cell, 'text', 3)
+ self.treeview.append_column(tree_pass)
+
+ #fill treestore
+ package_icon = gtk.gdk.pixbuf_new_from_file_at_size(media.ICON_PACKAGE, 32, 32)
+ single_package_name = "package-%s" % time.strftime("%Y%m%d%H%M%S")
+ single_package_links = []
+ for package_name, package_links in self.packages:
+ single_package_links += package_links
+ self.multi_model.append((package_icon, default_path, package_name, None, len(package_links)))
+ self.multi_packages = self.packages
+ self.single_package = [(single_package_name, single_package_links)]
+ self.single_model.append((package_icon, default_path, single_package_name, None, len(single_package_links)))
+
+ #choose path
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, False, False, 5)
+ path_button = gtk.Button(None, gtk.STOCK_OPEN)
+ hbox.pack_start(path_button, False, False, 10)
+ path_button.set_size_request(90,40)
+ path_button.connect("clicked", self.choose_path)
+ path_label = gtk.Label(_("Choose new path for selected Package."))
+ hbox.pack_start(path_label, False, False, 10)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect, True, True)
+
+ #info
+ frame = gtk.Frame()
+ hbox.pack_start(frame)
+ frame.set_border_width(10)
+ self.info_name = gtk.Label()
+ self.info_name.set_markup("%s: " % ("Packages"))
+ frame.set_label_widget(self.info_name)
+ vbox = gtk.VBox()
+ frame.add(vbox)
+ self.info_label = gtk.Label(len(packages))
+ vbox.pack_start(self.info_label, False, False, 5)
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ self.action_area.pack_start(cancel_button)
+ cancel_button.connect("clicked", self.close)
+ ok_button = gtk.Button(None, gtk.STOCK_OK)
+ self.action_area.pack_start(ok_button)
+ ok_button.connect("clicked", self.configure_packages)
+
+ self.connect("response", self.close)
+ self.show_all()
+ self.run()
+
+ def change_mode(self, button, multi):
+ """"""
+ if multi:
+ if button.get_active():
+ logger.info("setting Auto Package Mode")
+ self.treeview.set_model(self.multi_model)
+ self.treeview.set_cursor_on_cell(0)
+ self.packages = self.multi_packages
+ else:
+ if button.get_active():
+ logger.info("setting Single Package Mode")
+ self.treeview.set_model(self.single_model)
+ self.treeview.set_cursor_on_cell(0)
+ self.packages = self.single_package
+
+ def set_info(self, num):
+ """"""
+ self.info_name.set_markup("%s: " % ("Files"))
+ self.info_label.set_text(str(num))
+
+ def select(self, selection):
+ """"""
+ model, iter = selection.get_selected()
+ if iter:
+ self.set_info(model.get_value(iter, 4))
+
+ def configure_packages(self, button=None):
+ """"""
+ model = self.treeview.get_model()
+ for package in model:
+ self.packages_info.append((package[1], package[2], package[3]))
+ self.close()
+
+ def choose(self, treeview, path, view_column):
+ """"""
+ self.choose_path()
+
+ def choose_path(self, button=None):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ f = FileChooser(self, self.on_choose, self.history_path)
+ self.history_path = f.history_path
+
+ def on_choose(self, folder_path):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ model.set_value(iter, 1, folder_path)
+
+ def change(self, cellrenderertext, path, new_text, column):
+ """"""
+ model = self.treeview.get_model()
+ model.set_value(model.get_iter(path), column, new_text)
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/file_chooser.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/file_chooser.py
--- tucan-0.3.8/ui/gtk/file_chooser.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/file_chooser.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,88 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import os
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import core.cons as cons
+
+class FileChooser(gtk.FileChooserDialog):
+ """"""
+ def __init__(self, parent, func, default_path=None, files=False, save=False):
+ """"""
+ gtk.FileChooserDialog.__init__(self, "%s - %s" % (cons.TUCAN_NAME,_("Select a Folder")), parent)
+ self.set_position(gtk.WIN_POS_CENTER)
+
+ if default_path:
+ self.set_current_folder(default_path)
+ self.history_path = self.get_current_folder()
+
+ if files:
+ self.set_title("%s - %s" % (cons.TUCAN_NAME, _("Select Files")))
+ self.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+ self.set_select_multiple(True)
+ elif save:
+ self.set_title("%s - %s" % (cons.TUCAN_NAME,_("Save As")))
+ self.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
+ else:
+ self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+
+ hidden_button = gtk.CheckButton(("Show hidden files."))
+ hidden_button.set_active(self.get_show_hidden())
+ self.vbox.pack_start(hidden_button, False, False, 5)
+ hidden_button.connect("clicked", self.show_hidden)
+
+ button = gtk.Button(None, gtk.STOCK_CANCEL)
+ button.connect("clicked", self.close)
+ self.action_area.pack_start(button)
+ button = gtk.Button(None, gtk.STOCK_OK)
+ button.connect("clicked", self.on_choose_folder, func)
+ self.action_area.pack_start(button)
+ self.set_position(gtk.WIN_POS_CENTER)
+
+ self.connect("response", self.close)
+
+ self.show_all()
+ self.run()
+
+ def show_hidden(self, button):
+ """"""
+ self.set_show_hidden(button.get_active())
+
+ def on_choose_folder(self, button, func):
+ """"""
+ for file_name in self.get_filenames():
+ func(os.path.join(file_name))
+ self.close()
+
+ def close(self, widget=None, response=None):
+ """"""
+ self.history_path = self.get_current_folder()
+ self.set_show_hidden(False)
+ self.destroy()
+
+if __name__ == "__main__":
+ def mierda(name):
+ print name
+ f = FileChooser(None, mierda, "/home/crak/")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/gui.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/gui.py
--- tucan-0.3.8/ui/gtk/gui.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/gui.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,425 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import os
+import sys
+import time
+import threading
+import webbrowser
+import __builtin__
+import gettext
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import tray_icon
+import menu_bar
+import toolbar
+
+from about import About
+from message import Message
+from preferences import Preferences
+from log_view import LogView
+from shutdown import Shutdown
+from tree import Tree
+from input_links import InputLinks
+from file_chooser import FileChooser
+
+from core.core import Core
+from core.sessions import Sessions
+from core.log_stream import LogStream
+from core.service_update import ServiceUpdate
+
+import media
+import core.cons as cons
+import core.config as config
+
+class Gui(gtk.Window, Core):
+ """"""
+ def __init__(self, conf):
+ """"""
+ #i18n
+ gettext.bindtextdomain(cons.NAME_LOCALES, cons.PATH_LOCALES)
+ gettext.textdomain(cons.NAME_LOCALES)
+ __builtin__._ = gettext.gettext
+
+ #configuration
+ self.configuration = conf
+
+ #set logger
+ log_stream = LogStream()
+ handler = logging.StreamHandler(log_stream)
+ handler.setLevel(logging.DEBUG)
+ handler.setFormatter(logging.Formatter(cons.LOG_FORMAT))
+ logging.getLogger("").addHandler(handler)
+
+ #show preferences if not configured
+ if not self.configuration.configured:
+ Preferences(self, self.configuration, True)
+ self.preferences_shown = False
+
+ #l10n
+ lang = gettext.translation(cons.NAME_LOCALES, cons.PATH_LOCALES, languages=[self.configuration.get(config.SECTION_MAIN, config.OPTION_LANGUAGE)])
+ lang.install()
+
+ Core.__init__(self, self.configuration)
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+
+ self.set_icon_from_file(media.ICON_TUCAN)
+ self.set_title("%s - Version: %s" % (cons.TUCAN_NAME, cons.TUCAN_VERSION))
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(900, 500)
+ self.vbox = gtk.VBox()
+ self.add(self.vbox)
+
+ #menu items
+ menu_load_session = _("Load Session"), lambda x: FileChooser(self, self.load_session, cons.CONFIG_PATH, True)
+ menu_save_session = _("Save Session"), lambda x: FileChooser(self, self.save_session, cons.CONFIG_PATH, save=True)
+ menu_quit = gtk.STOCK_QUIT, self.quit
+ menu_help = gtk.STOCK_HELP, self.help
+ menu_about = gtk.STOCK_ABOUT, lambda x: About(self)
+ menu_preferences = gtk.STOCK_PREFERENCES, self.preferences
+ menu_log = _("Show Logs"), lambda x: LogView(self, log_stream)
+ show_uploads = gtk.CheckMenuItem(_("Show Uploads")), self.resize_pane, self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS)
+ shutdown = gtk.CheckMenuItem(_("Shutdown Computer")), self.shutdown, False
+
+ m_file = _("File")
+ m_view = _("View")
+ m_help = _("Help")
+ m_addons = _("Addons")
+
+ #integration menubar
+ integration = None
+ if cons.OS_OSX:
+ try:
+ about_menu = _("About TucanManager"), lambda x: About(self)
+ preferences_menu = _("Preferences"), self.preferences
+ file_menu = m_file, [menu_load_session, menu_save_session]
+ view_menu = m_view, [show_uploads, None, menu_log]
+ addons_menu = m_addons, [shutdown]
+ help_menu = m_help, [menu_help]
+ quit_menu = _("Quit"), self.quit
+ integration = gtk.Window(gtk.WINDOW_POPUP)
+ vbox = gtk.VBox()
+ integration.add(vbox)
+ vbox.pack_start(menu_bar.OSXMenuBar([file_menu, view_menu, addons_menu, help_menu], about_menu, preferences_menu, quit_menu))
+
+ except Exception, e:
+ integration = None
+ logger.critical("No OSX menu integration support.")
+
+ #normal menubar
+ if not integration:
+ file_menu = m_file, [menu_load_session, menu_save_session, None, menu_quit]
+ view_menu = m_view, [show_uploads, menu_log, None, menu_preferences]
+ addons_menu = m_addons, [shutdown]
+ help_menu = m_help, [menu_help, menu_about]
+ self.vbox.pack_start(menu_bar.MenuBar([file_menu, view_menu, addons_menu, help_menu]), False)
+
+ #toolbar
+ download = _("Add Downloads"), gtk.image_new_from_file(media.ICON_DOWNLOAD), self.add_links
+ upload = _("Add Uploads"), gtk.image_new_from_file(media.ICON_UPLOAD), self.not_implemented #self.quit
+ clear = _("Clear Complete"), gtk.image_new_from_file(media.ICON_CLEAR), self.clear_complete
+ up = _("Move Up"), gtk.image_new_from_file(media.ICON_UP), self.move_up
+ down = _("Move Down"), gtk.image_new_from_file(media.ICON_DOWN), self.move_down
+ start = _("Start Selected"), gtk.image_new_from_file(media.ICON_START), self.start
+ stop = _("Stop Selected"), gtk.image_new_from_file(media.ICON_STOP), self.stop
+ self.vbox.pack_start(toolbar.Toolbar([download, upload, None, clear, None, up, down, None, start, stop]), False)
+
+ copy = gtk.STOCK_COPY, self.copy_clipboard
+ delete = gtk.STOCK_REMOVE, self.delete
+ start = gtk.STOCK_MEDIA_PLAY, self.start
+ stop = gtk.STOCK_MEDIA_STOP, self.stop
+
+ #trees
+ self.downloads = Tree([copy, None, delete], self.download_manager)
+ #self.uploads = Tree()
+ self.uploads = gtk.VBox()
+
+ #tray icon
+ if cons.OS_OSX:
+ try:
+ #dock integration
+ self.tray_icon = tray_icon.OSXDock(self.show, self.quit)
+ self.connect("hide", self.tray_icon.activate, True)
+ except Exception, e:
+ logger.critical("No OSX dock integration support.")
+ self.tray_icon = None
+ else:
+ #trayicon
+ tray_menu = [menu_preferences, menu_about, None, menu_quit]
+ self.tray_icon = tray_icon.TrayIcon(self.show, self.hide, tray_menu)
+ self.connect("hide", self.tray_icon.activate)
+ self.downloads.status_bar.connect("text-pushed", self.tray_icon.change_tooltip)
+
+ #sessions
+ self.session = Sessions()
+ if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION):
+ self.load_default_session()
+ else:
+ if os.path.exists(cons.SESSION_FILE):
+ title = _("Tucan Manager - Restore previous session.")
+ message = _("Your last session closed unexpectedly.\nTucan will try to restore it now.")
+ m = Message(None, cons.SEVERITY_WARNING, title, message, both=True)
+ if m.accepted:
+ self.load_default_session()
+
+ #pane
+ self.pane = gtk.VPaned()
+ self.vbox.pack_start(self.pane)
+ self.pane.pack1(self.downloads, True)
+ self.pane.pack2(self.uploads, True)
+ self.pane.set_position(self.get_size()[1])
+
+ self.connect("key-press-event", self.delete_key)
+
+ if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE):
+ self.connect("delete_event", self.hide_on_delete)
+ else:
+ self.connect("delete_event", self.quit)
+
+ self.show_all()
+
+ #Autocheck services
+ if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE):
+ th = threading.Thread(group=None, target=self.check_updates, name=None)
+ th.start()
+
+ #ugly polling
+ gobject.timeout_add(120000, self.save_default_session)
+
+ def check_updates(self):
+ """"""
+ s = ServiceUpdate(self.configuration)
+ if s.get_updates():
+ gobject.idle_add(self.update_manager, s.remote_info)
+
+ def update_manager(self, info):
+ """"""
+ if not self.preferences_shown:
+ self.preferences_shown = True
+ Preferences(self, self.configuration, True, info)
+ self.preferences_shown = False
+ return False
+
+ def delete_key(self, window, event):
+ """pressed del key"""
+ if event.keyval == 65535:
+ self.delete()
+
+ def preferences(self, button=None):
+ """"""
+ if not self.preferences_shown:
+ self.preferences_shown = True
+ Preferences(self, self.configuration)
+ self.downloads.status_bar.synchronize()
+ self.preferences_shown = False
+
+ def not_implemented(self, widget):
+ """"""
+ w = Message(self, cons.SEVERITY_WARNING, "Not Implemented!", "The functionality you are trying to use is not implemented yet.")
+
+ def resize_pane(self, checkbox):
+ """"""
+ if checkbox.get_active():
+ self.pane.set_position(-1)
+ else:
+ self.pane.set_position(self.get_size()[1])
+
+ def shutdown(self, checkbox):
+ """"""
+ if checkbox.get_active():
+ self.shutdown_id = events.connect(cons.EVENT_ALL_COMPLETE, Shutdown, self, self.quit)
+ else:
+ events.disconnect(cons.EVENT_ALL_COMPLETE, self.shutdown_id)
+
+ def help(self, widget):
+ """"""
+ webbrowser.open(cons.DOC)
+
+ def add_links(self, button):
+ """"""
+ default_path = self.configuration.get_downloads_folder()
+ show_advanced_packages = self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES)
+ InputLinks(self, default_path, self.filter_service, self.get_check_links, self.create_packages, self.manage_packages, show_advanced_packages)
+
+ def copy_clipboard(self, button):
+ """"""
+ model, iter = self.downloads.treeview.get_selection().get_selected()
+ if iter:
+ link_list = self.downloads.get_links(iter)
+ clipboard = gtk.Clipboard()
+ clipboard.clear()
+ clipboard.set_text("\n".join(link_list))
+
+ def load_session(self, path):
+ """"""
+ try:
+ packages, info = self.session.load_session(path)
+ if packages != None:
+ self.manage_packages(packages, info)
+ logger.debug("Session loaded: %s" % info)
+ except Exception, e:
+ logger.exception("Session not loaded: %s" % e)
+ gobject.idle_add(self.session_error)
+
+ def session_error(self):
+ """"""
+ title = _("Tucan Manager - Session Error.")
+ message = _("There was a problem loading the last session. Links are unrecoverable.")
+ Message(self, cons.SEVERITY_ERROR, title, message)
+
+ def save_session(self, path):
+ """"""
+ packages, info = self.downloads.get_packages()
+ self.session.save_session(path, packages, info)
+ logger.debug("Session saved: %s" % info)
+
+ def load_default_session(self):
+ """"""
+ self.load_session(cons.SESSION_FILE)
+
+ def save_default_session(self):
+ """"""
+ self.save_session(cons.SESSION_FILE)
+ return True
+
+ def manage_packages(self, packages, packages_info):
+ """"""
+ tmp_packages = []
+ if not len(packages_info) > 0:
+ default_path = self.configuration.get_downloads_folder()
+ packages_info = [(default_path, name, None) for name, package_files in packages]
+ #create directories and password files
+ for info in packages_info:
+ package_path = os.path.join(info[0].decode("utf-8"), info[1].replace(" ", "_"), "")
+ if not os.path.exists(package_path):
+ os.makedirs(package_path)
+ if info[2]:
+ f = open(package_path + "password.txt", "w")
+ f.write(info[2] + "\n")
+ f.close()
+ #add packages to gui and manager
+ for package_name, package_downloads in packages:
+ info = packages_info[packages.index((package_name, package_downloads))]
+ package_name = info[1].replace(" ", "_")
+ package_path = os.path.join(info[0].decode("utf-8"), package_name, "")
+ self.downloads.add_package(package_name, package_path, package_downloads, info[2])
+ for download in package_downloads:
+ tmp = []
+ for service in download[2]:
+ plugin, plugin_type = self.get_download_plugin(service)
+ tmp.append((download[0][download[2].index(service)], plugin, plugin_type, service))
+ self.download_manager.add(package_path, download[1], tmp, download[3], download[4])
+
+ def start(self, button):
+ """Implementado solo para descargas"""
+ model, paths = self.downloads.treeview.get_selection().get_selected_rows()
+ if len(paths) > 0:
+ if len(paths[0]) > 1:
+ logger.info("Start file: %s" % self.download_manager.start(model.get_value(model.get_iter(paths[0]), 3)))
+ else:
+ logger.info("Start package.")
+ for item in self.downloads.package_files(model.get_iter(paths[0])):
+ self.download_manager.start(item)
+
+ def stop(self, button):
+ """Implementado solo para descargas"""
+ model, paths = self.downloads.treeview.get_selection().get_selected_rows()
+ if len(paths) > 0:
+ if len(paths[0]) > 1:
+ logger.info("Stop file: %s" % self.download_manager.stop(model.get_value(model.get_iter(paths[0]), 3)))
+ else:
+ logger.info("Stop package.")
+ for item in self.downloads.package_files(model.get_iter(paths[0])):
+ self.download_manager.stop(item)
+
+ def clear_complete(self, button):
+ """Implementado solo para descargas"""
+ files = self.downloads.clear()
+ logger.info("Cleared: %s" % files)
+ if len(files) > 0:
+ self.download_manager.clear(files)
+
+ def move_up(self, button):
+ """Implementado solo para descargas"""
+ model, paths = self.downloads.treeview.get_selection().get_selected_rows()
+ if len(paths) > 0:
+ if not len(paths[0]) > 1:
+ logger.info("Move up: %s" % self.downloads.move_up(model.get_iter(paths[0])))
+
+ def move_down(self, button):
+ """Implementado solo para descargas"""
+ model, paths = self.downloads.treeview.get_selection().get_selected_rows()
+ if len(paths) > 0:
+ if not len(paths[0]) > 1:
+ logger.info("Move down: %s" % self.downloads.move_down(model.get_iter(paths[0])))
+
+ def delete(self, button=None):
+ """Implementado solo para descargas"""
+ model, paths = self.downloads.treeview.get_selection().get_selected_rows()
+ status = [cons.STATUS_STOP, cons.STATUS_PEND, cons.STATUS_ERROR]
+ if len(paths) > 0:
+ if len(paths[0]) > 2:
+ name, link = self.downloads.delete_link(status, model.get_iter(paths[0]))
+ if link:
+ logger.warning("Remove %s: %s" % (link, self.download_manager.delete_link(name, link)))
+ elif len(paths[0]) > 1:
+ name = self.downloads.delete_file(status, model.get_iter(paths[0]))
+ if name:
+ logger.warning("Remove %s: %s" % (name, self.download_manager.clear([name])))
+ else:
+ files = self.downloads.delete_package(status, model.get_iter(paths[0]))
+ if len(files) > 0:
+ logger.warning("Remove package: %s" % self.download_manager.clear(files))
+
+ def quit(self, dialog=None, response=None):
+ """"""
+ if len(self.download_manager.active_downloads) > 0:
+ message = "Tucan still has active downloads.\n Are you sure you want to quit?"
+ m = Message(self, cons.SEVERITY_WARNING, "Tucan Manager - Active Downloads.", message, True, True)
+ if m.accepted:
+ self.close()
+ else:
+ #This way GTK won't destroy the window.
+ return True
+ else:
+ self.close()
+
+ def close(self):
+ """"""
+ self.hide()
+ if self.tray_icon:
+ self.tray_icon.close()
+ gtk.main_quit()
+
+ if self.configuration.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION):
+ self.save_default_session()
+ else:
+ try:
+ os.remove(cons.SESSION_FILE)
+ except Exception, e:
+ logger.info(e)
+ self.stop_all()
+ tucan_exit(0)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/input_files.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/input_files.py
--- tucan-0.3.8/ui/gtk/input_files.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/input_files.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,298 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import os
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from file_chooser import FileChooser
+
+import media
+import core.cons as cons
+
+SERVICES = [("Megaupload", 100, cons.UNIT_MB, ["Anonymous", "Premium"]), ("Rapidshare", 200, cons.UNIT_MB, ["Collector", "Premium"]), ("Gigasize", 100, cons.UNIT_MB, ["Anonymous"])]
+
+class InputFiles(gtk.Dialog):
+ """"""
+ def __init__(self, parent, upload_services):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_icon_from_file(media.ICON_UPLOAD)
+ self.set_title(("Input Files"))
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(600,500)
+
+ self.history_path = cons.DEFAULT_PATH
+
+ main_hbox = gtk.HBox()
+ self.vbox.pack_start(main_hbox)
+
+ self.file_icon = self.render_icon(gtk.STOCK_FILE, gtk.ICON_SIZE_BUTTON)
+ self.correct_icon = self.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
+ self.incorrect_icon = self.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
+
+ #package treeview
+ frame = gtk.Frame()
+ main_hbox.pack_start(frame, True)
+ frame.set_border_width(5)
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.package_treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, bool))
+ scroll.add(self.package_treeview)
+
+ self.package_treeview.set_rules_hint(True)
+ self.package_treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.package_treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ self.package_treeview.append_column(tree_name)
+
+ tree_size = gtk.TreeViewColumn('Size')
+ size_cell = gtk.CellRendererText()
+ tree_size.pack_start(size_cell, False)
+ tree_size.add_attribute(size_cell, 'text', 2)
+ self.package_treeview.append_column(tree_size)
+
+ service_vbox = gtk.VBox()
+ main_hbox.pack_start(service_vbox, False, False)
+
+ # services treeview
+ frame = gtk.Frame()
+ service_vbox.pack_start(frame)
+ frame.set_size_request(200, -1)
+ frame.set_border_width(5)
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_PREFERENCES_SERVICES))
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ services = gtk.ListStore(gtk.gdk.Pixbuf, str, int, str, bool, gobject.TYPE_PYOBJECT)
+ self.services_treeview = gtk.TreeView(services)
+ self.services_treeview.get_selection().connect("changed", self.select)
+ scroll.add(self.services_treeview)
+
+ self.services_treeview.set_rules_hint(True)
+ self.services_treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.services_treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ self.services_treeview.append_column(tree_name)
+
+ tree_add = gtk.TreeViewColumn('Add')
+ add_cell = gtk.CellRendererToggle()
+ add_cell.connect("toggled", self.toggled)
+ tree_add.pack_start(add_cell, True)
+ tree_add.add_attribute(add_cell, 'active', 4)
+ self.services_treeview.append_column(tree_add)
+
+ #plugins
+ self.plugins_frame = gtk.Frame()
+ service_vbox.pack_start(self.plugins_frame, False, False)
+ self.plugins_frame.set_size_request(200, 100)
+ self.plugins_frame.set_border_width(5)
+
+ for service, size, unit, plugins in upload_services:
+ vbox = gtk.VBox()
+ first = None
+ for plugin in plugins:
+ first = gtk.RadioButton(first, plugin)
+ vbox.pack_start(first, False, False, 1)
+ services.append([self.correct_icon, service, size, unit, False, vbox])
+
+ #choose path
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, False, False, 5)
+ path_button = gtk.Button(None, gtk.STOCK_OPEN)
+ path_button.set_size_request(90,40)
+ hbox.pack_start(path_button, False, False, 5)
+ path_button.connect("clicked", self.choose_files)
+ path_label = gtk.Label(("Choose files to upload."))
+ hbox.pack_start(path_label, False, False, 5)
+ aspect = gtk.AspectFrame()
+ hbox.pack_start(aspect, True, True)
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ clear_button = gtk.Button(None, gtk.STOCK_CLEAR)
+ clear_button.set_size_request(190,40)
+ hbox.pack_start(clear_button, False, False, 5)
+ clear_button.connect("clicked", self.clear)
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ add_button = gtk.Button(None, gtk.STOCK_ADD)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(add_button)
+ cancel_button.connect("clicked", self.close)
+ add_button.connect("clicked", self.add_files)
+
+ self.connect("response", self.close)
+ self.show_all()
+ self.set_focus(path_button)
+ self.run()
+
+ def clear(self, button):
+ """"""
+ self.package_treeview.get_model().clear()
+
+ def select(self, selection):
+ """"""
+ model, service_iter = selection.get_selected()
+ if iter:
+ if self.plugins_frame.get_child():
+ self.plugins_frame.remove(self.plugins_frame.get_child())
+ vbox = model.get_value(service_iter, 5)
+ self.plugins_frame.add(vbox)
+ vbox.show_all()
+
+ def add_files(self, button):
+ """"""
+ result = []
+ package_model = self.package_treeview.get_model()
+ services_model = self.services_treeview.get_model()
+
+ file_iter = package_model.get_iter_root()
+ while file_iter:
+ services = []
+ service_iter = package_model.iter_children(file_iter)
+ while service_iter:
+ service_name = package_model.get_value(service_iter, 1)
+ if package_model.get_value(service_iter, 4):
+ for service in services_model:
+ if service[1] == service_name:
+ for button in service[5].get_children():
+ if button.get_active():
+ services.append((service_name, button.get_label()))
+ service_iter = package_model.iter_next(service_iter)
+ if len(services) > 0:
+ tmp = package_model.get_value(file_iter, 2).split(" ")
+ size, unit = self.split_size(self.join_size(int(tmp[0]), tmp[1]))
+ result.append((package_model.get_value(file_iter, 3), int(size), unit, services))
+ file_iter = package_model.iter_next(file_iter)
+ self.close()
+ print result
+
+ def toggled(self, button, path):
+ """"""
+ active = True
+ if button.get_active():
+ active = False
+ button.set_active(active)
+
+ services_model = self.services_treeview.get_model()
+ package_model = self.package_treeview.get_model()
+
+ services_model.set_value(services_model.get_iter(path), 4, active)
+
+ file_iter = package_model.get_iter_root()
+ while file_iter:
+ service_iter = package_model.iter_children(file_iter)
+ found = False
+ while service_iter:
+ if services_model.get_value(services_model.get_iter(path), 1) == package_model.get_value(service_iter, 1):
+ found = True
+ break
+ service_iter = package_model.iter_next(service_iter)
+ if active:
+ if not found:
+ tmp = package_model.get_value(file_iter, 2).split(" ")
+ max_size = self.join_size(services_model.get_value(services_model.get_iter(path), 2), services_model.get_value(services_model.get_iter(path), 3))
+ self.add_service(package_model, file_iter, services_model.get_value(services_model.get_iter(path), 1), self.join_size(int(tmp[0]), tmp[1]), max_size)
+ else:
+ if found:
+ package_model.remove(service_iter)
+ file_iter = package_model.iter_next(file_iter)
+
+ def choose_files(self, button):
+ """"""
+ f = FileChooser(self, self.on_choose, self.history_path, True)
+ self.history_path = f.history_path
+
+ def on_choose(self, path):
+ """"""
+ package_model = self.package_treeview.get_model()
+ services_model = self.services_treeview.get_model()
+ if os.path.isfile(path):
+ if path not in [row[1] for row in package_model]:
+ file_size = int(os.stat(path).st_size/1024)
+ size, unit = self.split_size(file_size)
+ file_iter = package_model.append(None, [self.file_icon, os.path.basename(path), "%i %s" %(size, unit), path, None])
+ for row in services_model:
+ if row[4]:
+ self.add_service(package_model, file_iter, row[1], file_size, self.join_size(row[2], row[3]))
+
+ def join_size(self, size, unit):
+ """"""
+ factor = 1
+ if unit == cons.UNIT_KB:
+ factor = 1
+ elif unit == cons.UNIT_MB:
+ factor = 1024
+ elif unit == cons.UNIT_GB:
+ factor = 1024*1024
+ return size*factor
+
+ def split_size(self, size):
+ """"""
+ if size > 0:
+ tmp = size/1024
+ if tmp > 0:
+ tmp2 = tmp/1024
+ if tmp2 > 0:
+ return tmp2, cons.UNIT_GB
+ else:
+ return tmp, cons.UNIT_MB
+ else:
+ return size, cons.UNIT_KB
+ else:
+ return 1, cons.UNIT_KB
+
+ def add_service(self, package_model, file_iter, service, file_size, max_size):
+ """"""
+ if max_size > file_size:
+ package_model.append(file_iter, [self.correct_icon, service, None, None, True])
+ else:
+ package_model.append(file_iter, [self.incorrect_icon, service, None, None, False])
+ self.package_treeview.expand_row(package_model.get_path(file_iter), True)
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
+
+if __name__ == "__main__":
+ x = InputFiles(None, SERVICES)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/input_links.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/input_links.py
--- tucan-0.3.8/ui/gtk/input_links.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/input_links.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,321 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import HTMLParser
+import threading
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from message import Wait, Message
+from advanced_packages import AdvancedPackages
+
+import media
+import core.cons as cons
+
+class ClipParser(HTMLParser.HTMLParser):
+ """"""
+ def __init__(self):
+ """"""
+ HTMLParser.HTMLParser.__init__(self)
+ self.url = []
+
+ def handle_starttag(self, tag, attrs):
+ """"""
+ if tag == "a":
+ for ref, link in attrs:
+ if ref == "href":
+ self.url.append(link)
+
+class InputLinks(gtk.Dialog):
+ """"""
+ def __init__(self, parent, path, sort, check, create, manage, show_advanced_packages):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_icon_from_file(media.ICON_DOWNLOAD)
+ self.set_title("%s - %s" % (cons.TUCAN_NAME, _("Input Links")))
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(600,500)
+
+ self.cancel_check = False
+
+ self.default_path = path
+ self.sort_links = sort
+ self.check_links = check
+ self.create_packages = create
+ self.packages = manage
+
+ #textview
+ frame = gtk.Frame(_("Paste links here:"))
+ self.vbox.pack_start(frame)
+ frame.set_border_width(10)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ scroll = gtk.ScrolledWindow()
+ hbox.pack_start(scroll, True, True, 10)
+ scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ #auto scroll
+ scroll.get_vadjustment().connect("changed", self.changed)
+ scroll.get_vadjustment().connect("value-changed", self.value_changed)
+ buffer = gtk.TextBuffer()
+ self.textview = gtk.TextView(buffer)
+ scroll.add(self.textview)
+ self.textview.set_wrap_mode(gtk.WRAP_CHAR)
+
+ self.clipboard = gtk.clipboard_get()
+ self.clipboard.request_targets(self.get_clipboard)
+
+ #check button
+ button_box = gtk.HButtonBox()
+ hbox.pack_start(button_box, False, False, 10)
+ vbox = gtk.VBox()
+ check_image = gtk.image_new_from_file(media.ICON_CHECK)
+ vbox.pack_start(check_image)
+ check_label = gtk.Label(_("Check Links"))
+ vbox.pack_start(check_label)
+ check_button = gtk.Button()
+ check_button.add(vbox)
+ button_box.pack_start(check_button)
+ check_button.connect("clicked", self.check)
+
+ #treeview
+ frame = gtk.Frame()
+ self.vbox.pack_start(frame)
+ frame.set_border_width(10)
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ #auto scroll
+ scroll.get_vadjustment().connect("changed", self.changed)
+ scroll.get_vadjustment().connect("value-changed", self.value_changed)
+
+ self.treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, int, str, str, bool, bool))
+ scroll.add(self.treeview)
+
+ self.treeview.set_rules_hint(True)
+ self.treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.connect("edited", self.change_name)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 2)
+ tree_name.add_attribute(name_cell, 'editable', 7)
+ self.treeview.append_column(tree_name)
+
+ tree_add = gtk.TreeViewColumn('Add')
+ add_cell = gtk.CellRendererToggle()
+ add_cell.connect("toggled", self.toggled)
+ tree_add.pack_start(add_cell, True)
+ tree_add.add_attribute(add_cell, 'active', 6)
+ tree_add.add_attribute(add_cell, 'visible', 7)
+ self.treeview.append_column(tree_add)
+
+ #advanced checkbutton
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, False)
+ self.advanced_button = gtk.CheckButton(_("Show advanced Package configuration."))
+ self.advanced_button.set_active(show_advanced_packages)
+ hbox.pack_start(self.advanced_button, False, False, 8)
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ add_button = gtk.Button(None, gtk.STOCK_ADD)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(add_button)
+ cancel_button.connect("clicked", self.close)
+ add_button.connect("clicked", self.add_links)
+
+ self.connect("response", self.close)
+ self.show_all()
+ self.run()
+
+ def changed(self, vadjust):
+ """autoscroll"""
+ if not hasattr(vadjust, "need_scroll") or vadjust.need_scroll:
+ vadjust.set_value(vadjust.upper-vadjust.page_size)
+ vadjust.need_scroll = True
+
+ def value_changed (self, vadjust):
+ """autoscroll"""
+ vadjust.need_scroll = abs(vadjust.value + vadjust.page_size - vadjust.upper) < vadjust.step_increment
+
+ def change_name(self, cellrenderertext, path, new_text):
+ """"""
+ model = self.treeview.get_model()
+ model.set_value(model.get_iter(path), 2, new_text)
+
+ def get_clipboard(self, clipboard, selection_data, data):
+ """"""
+ urls = []
+ if cons.OS_OSX:
+ target_html = "public.rtf"
+ if target_html in list(selection_data):
+ selection = self.clipboard.wait_for_contents(target_html)
+ if selection:
+ for line in str(selection.data.decode("utf8", "ignore")).split("\n"):
+ if '{HYPERLINK "' in line:
+ urls.append(line.split('{HYPERLINK "')[1].split('"}')[0])
+ elif cons.OS_WINDOWS:
+ target_html = "HTML Format"
+ if target_html in list(selection_data):
+ try:
+ parser = ClipParser()
+ parser.feed(self.clipboard.wait_for_contents(target_html).data.decode("utf8", "ignore"))
+ parser.close()
+ if len(parser.url) > 0:
+ urls += parser.url
+ except HTMLParser.HTMLParseError:
+ pass
+ else:
+ target_html = "text/html"
+ if target_html in list(selection_data):
+ for line in str(self.clipboard.wait_for_contents(target_html).data.decode("utf16", "ignore")).split("\n"):
+ try:
+ parser = ClipParser()
+ parser.feed(line)
+ parser.close()
+ if len(parser.url) > 0:
+ urls += parser.url
+ except HTMLParser.HTMLParseError:
+ pass
+ if len(urls) > 0:
+ self.textview.get_buffer().insert_at_cursor("\n".join(urls) + "\n")
+
+ def toggled(self, button, path):
+ """"""
+ model = self.treeview.get_model()
+ active = True
+ if button.get_active():
+ active = False
+ button.set_active(active)
+ model.set_value(model.get_iter(path), 6, active)
+
+ def add_links(self, button):
+ """"""
+ tmp = {}
+ store = self.treeview.get_model()
+ for column in store:
+ if column[2] != cons.TYPE_UNSUPPORTED:
+ tmp[column[2]] = []
+ for value in column.iterchildren():
+ if value[1] != value[2]:
+ if value[6]:
+ logger.info("Added: %s %s %s %s %s" % (value[1], value[2], value[3], value[4], value[5]))
+ tmp[column[2]].append((value[1], value[2], value[3], value[4], value[5]))
+ if tmp != {}:
+ packages = self.create_packages(tmp)
+ packages_info = None
+ if self.advanced_button.get_active():
+ #self.hide()
+ w = AdvancedPackages(self, self.default_path, packages)
+ packages_info = w.packages_info
+ if packages_info:
+ self.packages(w.packages, packages_info)
+ self.close()
+ #else:
+ # self.show()
+ else:
+ self.packages(packages, [])
+ self.close()
+ else:
+ title = _("Input Links - Nothing to add.")
+ message = _("There aren't links to add.\nPlease check the links before adding.")
+ m = Message(self, cons.SEVERITY_INFO, title, message, both=True)
+ if not m.accepted:
+ self.close()
+
+ def check(self, button):
+ """"""
+ buffer = self.textview.get_buffer()
+ start, end = buffer.get_bounds()
+ link_list = [link.lower() for link in buffer.get_text(start, end).split("\n") if link.strip()]
+ if len(link_list) > 0:
+ w = Wait(_("Checking links, please wait."), self)
+ w.connect("key-press-event", self.cancel)
+ th = threading.Thread(group=None, target=self.check_all, name=None, args=(link_list, w))
+ th.start()
+
+ def check_all(self, link_list, wait):
+ """"""
+ buffer = self.textview.get_buffer()
+ store = self.treeview.get_model()
+ store.clear()
+
+ service_icon = self.treeview.render_icon(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
+ unsupported_icon = self.treeview.render_icon(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_MENU)
+ active_icon = self.treeview.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
+ unchecked_icon = self.treeview.render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_MENU)
+ unactive_icon = self.treeview.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
+ try:
+ for service, links in self.sort_links(link_list).items():
+ if links != []:
+ if service == cons.TYPE_UNSUPPORTED:
+ service_iter = store.append(None, [unsupported_icon, service, service, 0, None, None, False, False])
+ for link in links:
+ store.append(service_iter, [unchecked_icon, link, link, 0, None, None, False, False])
+ else:
+ service_iter = store.append(None, [service_icon, service, service, 0, None, None, False, False])
+ for link in links:
+ if self.cancel_check:
+ self.cancel_check = False
+ raise Exception("Check Links cancelled")
+ check, plugin_type = self.check_links(service)
+ file_name, size, size_unit = check(link)
+ if file_name:
+ if size > 0:
+ icon = active_icon
+ marked = True
+ else:
+ icon = unchecked_icon
+ marked = False
+ else:
+ icon = unactive_icon
+ marked = False
+ file_name = link
+ logger.info("Checked: %s %s %s" % (file_name, size, size_unit))
+ store.append(service_iter, [icon, link, file_name, size, size_unit, plugin_type, marked, marked])
+ self.treeview.expand_row(store.get_path(service_iter), True)
+ except:
+ gobject.idle_add(wait.destroy)
+ else:
+ buffer.set_text("")
+ gobject.idle_add(wait.destroy)
+
+ def cancel(self, window, event):
+ """Esc key"""
+ if event.keyval == 65307:
+ window.progress.set_text(_("Check Canceled!"))
+ self.cancel_check = True
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/log_view.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/log_view.py
--- tucan-0.3.8/ui/gtk/log_view.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/log_view.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,162 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from report import Report
+
+import media
+import core.cons as cons
+
+SEVERITY = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
+COLORS = {"DEBUG": "grey", "INFO": "green", "WARNING": "yellow", "ERROR": "red", "CRITICAL": "white"}
+
+class LogView(gtk.Dialog):
+ """"""
+ def __init__(self, parent, stream):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_title("%s - Log View" % cons.TUCAN_NAME)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(700,500)
+ self.set_icon(self.render_icon(gtk.STOCK_FILE, gtk.ICON_SIZE_MENU))
+
+ self.stream = stream
+ self.back_buffer = gtk.TextBuffer()
+ self.back_buffer.set_text(self.stream.read())
+
+ frame = gtk.Frame()
+ self.vbox.pack_start(frame)
+ frame.set_border_width(10)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+
+ #auto scroll
+ scroll = gtk.ScrolledWindow()
+ hbox.pack_start(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroll.get_vadjustment().connect("changed", self.changed)
+ scroll.get_vadjustment().connect("value-changed", self.value_changed)
+
+ #textview
+ buffer = gtk.TextBuffer()
+ self.textview = gtk.TextView(buffer)
+ scroll.add(self.textview)
+ self.textview.set_wrap_mode(gtk.WRAP_NONE)
+ self.textview.set_editable(False)
+ self.textview.set_cursor_visible(False)
+ self.textview.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("black"))
+
+ table = buffer.get_tag_table()
+ for name, color in COLORS.items():
+ tag = gtk.TextTag(name)
+ tag.set_property("foreground", color)
+ tag.set_property("left_margin", 10)
+ tag.set_property("right_margin", 10)
+ table.add(tag)
+
+ #combo
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, False, False, 10)
+ buttonbox = gtk.HButtonBox()
+ hbox.pack_start(buttonbox, False, False, 10)
+ label = gtk.Label("Minimum severity shown.")
+ hbox.pack_start(label, False, False, 10)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect)
+
+ self.combo = gtk.combo_box_new_text()
+ buttonbox.pack_start(self.combo)
+ self.combo.connect("changed", self.reload)
+
+ for s in SEVERITY:
+ self.combo.append_text(s)
+ self.combo.set_active(2)
+
+ #action area
+ button = gtk.Button("Report ")
+ self.action_area.pack_start(button)
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(media.ICON_SEND, 24, 24)
+ button.set_image(gtk.image_new_from_pixbuf(pixbuf))
+ button.connect("clicked", self.report)
+ button = gtk.Button(None, gtk.STOCK_CLOSE)
+ self.action_area.pack_start(button)
+ button.connect("clicked", self.close)
+
+ self.connect("response", self.close)
+ self.show_all()
+
+ gobject.timeout_add(1000, self.update)
+ self.run()
+
+ def report(self, button=None):
+ """"""
+ Report(self)
+
+ def insert_color(self, buffer, line):
+ """"""
+ for s in SEVERITY[self.combo.get_active():]:
+ if s in line and buffer.get_tag_table().lookup(s):
+ buffer.insert_with_tags(buffer.get_end_iter(), "%s\n" % line, buffer.get_tag_table().lookup(s))
+ break
+
+ def reload(self, textview):
+ """"""
+ buffer = self.textview.get_buffer()
+ buffer.set_text("")
+ ini, fin = self.back_buffer.get_bounds()
+ for line in self.back_buffer.get_text(ini, fin).split("\n"):
+ self.insert_color(buffer, line)
+
+ def update(self):
+ """"""
+ try:
+ lines = self.stream.readlines()
+ if lines:
+ buffer = self.textview.get_buffer()
+ for line in lines:
+ self.back_buffer.insert(self.back_buffer.get_end_iter(), line)
+ self.insert_color(buffer, line.strip())
+ except Exception, e:
+ logger.exception(e)
+ else:
+ return True
+
+ def changed(self, vadjust):
+ """autoscroll"""
+ if not hasattr(vadjust, "need_scroll") or vadjust.need_scroll:
+ vadjust.set_value(vadjust.upper-vadjust.page_size)
+ vadjust.need_scroll = True
+
+ def value_changed (self, vadjust):
+ """autoscroll"""
+ vadjust.need_scroll = abs(vadjust.value + vadjust.page_size - vadjust.upper) < vadjust.step_increment
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/media.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/media.py
--- tucan-0.3.8/ui/gtk/media.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/media.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,49 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import os.path
+
+from core.cons import PATH
+
+#media constants
+PATH_MEDIA = os.path.join(PATH, "media", "")
+ICON_TUCAN = PATH_MEDIA + "tucan.svg"
+ICON_DOWNLOAD = PATH_MEDIA + "document-save.svg"
+ICON_UPLOAD = PATH_MEDIA + "system-software-update.svg"
+ICON_CLEAR = PATH_MEDIA + "edit-delete.svg"
+ICON_DOWN = PATH_MEDIA + "go-down.svg"
+ICON_UP = PATH_MEDIA + "go-up.svg"
+ICON_START = PATH_MEDIA + "media-playback-start.svg"
+ICON_STOP = PATH_MEDIA + "media-playback-stop.svg"
+ICON_CHECK = PATH_MEDIA + "software-update-available.svg"
+ICON_PACKAGE = PATH_MEDIA + "package-x-generic.svg"
+ICON_PREFERENCES = PATH_MEDIA + "preferences-system.svg"
+ICON_PREFERENCES_MAIN = PATH_MEDIA + "preferences-desktop.svg"
+ICON_PREFERENCES_SERVICES = PATH_MEDIA + "contact-new.svg"
+ICON_PREFERENCES_ADVANCED = PATH_MEDIA + "applications-system.svg"
+ICON_LANGUAGE = PATH_MEDIA + "preferences-desktop-locale.svg"
+ICON_FOLDER = PATH_MEDIA + "user-home.svg"
+ICON_NETWORK = PATH_MEDIA + "network-error.svg"
+ICON_ADVANCED = PATH_MEDIA + "application-x-executable.svg"
+ICON_MISSING = PATH_MEDIA + "image-missing.svg"
+ICON_ACCOUNT = PATH_MEDIA + "system-users.svg"
+ICON_UPDATE = PATH_MEDIA + "software-update-urgent.svg"
+ICON_SEND = PATH_MEDIA + "mail-reply-sender.svg"
+
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/menu_bar.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/menu_bar.py
--- tucan-0.3.8/ui/gtk/menu_bar.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/menu_bar.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,81 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+import core.cons as cons
+
+class MenuBar(gtk.MenuBar):
+ """"""
+ def __init__(self, list):
+ """list = [(menu_name=str, [(item_image=stock_item, callback), None=separator])]"""
+ gtk.MenuBar.__init__(self)
+ for menu in list:
+ item = gtk.MenuItem(menu[0])
+ self.append(item)
+ submenu = gtk.Menu()
+ for sub in menu[1]:
+ if sub == None:
+ subitem = gtk.SeparatorMenuItem()
+ elif isinstance(sub[0], gtk.CheckMenuItem):
+ subitem = sub[0]
+ subitem.set_active(sub[2])
+ subitem.connect("toggled", sub[1])
+ else:
+ subitem = gtk.ImageMenuItem(sub[0])
+ subitem.connect("activate", sub[1])
+ submenu.append(subitem)
+ item.set_submenu(submenu)
+
+if cons.OS_OSX:
+ try:
+ from igemacintegration import *
+
+ except Exception:
+ pass
+ else:
+ class OSXMenuBar(MenuBar):
+ """"""
+ def __init__(self, menu, menu_about, menu_preferences, menu_quit):
+ """"""
+ MenuBar.__init__(self, menu)
+ self.show_all()
+
+ macmenu = MacMenu()
+ macmenu.set_menu_bar(self)
+
+ quit_item = gtk.MenuItem(menu_quit[0])
+ quit_item.connect("activate", menu_quit[1])
+ macmenu.set_quit_menu_item(quit_item)
+
+ group = macmenu.add_app_menu_group()
+ item = gtk.MenuItem(menu_about[0])
+ item.connect("activate", menu_about[1])
+ group.add_app_menu_item(item, None)
+
+ group = macmenu.add_app_menu_group()
+ item = gtk.MenuItem(menu_preferences[0])
+ item.connect("activate", menu_preferences[1])
+ group.add_app_menu_item(item, None)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/message.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/message.py
--- tucan-0.3.8/ui/gtk/message.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/message.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,114 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import core.cons as cons
+
+class Wait(gtk.Window):
+ """"""
+ def __init__(self, message, parent):
+ """"""
+ gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+ self.set_transient_for(parent)
+ self.set_modal(True)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_property("skip-pager-hint", True)
+ self.set_property("skip-taskbar-hint", True)
+ self.set_resizable(False)
+ self.set_decorated(False)
+ self.set_size_request(300,100)
+
+ self.progress = gtk.ProgressBar()
+ self.add(self.progress)
+ self.progress.set_text(message)
+
+ self.show_all()
+
+ gobject.timeout_add(100, self.pulse)
+
+ def pulse(self):
+ """"""
+ self.progress.pulse()
+ return True
+
+class Message(gtk.Dialog):
+ """"""
+ def __init__(self, parent, severity, title, message, accept=False, both=False, run=True):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_title(title)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_resizable(False)
+ self.set_transient_for(parent)
+
+ self.accepted = False
+
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, True, True, 10)
+ icon = gtk.STOCK_DIALOG_INFO
+ if severity == cons.SEVERITY_WARNING:
+ icon = gtk.STOCK_DIALOG_WARNING
+ elif severity == cons.SEVERITY_ERROR:
+ icon = gtk.STOCK_DIALOG_ERROR
+ hbox.pack_start(gtk.image_new_from_stock(icon, gtk.ICON_SIZE_DIALOG), True, False, 10)
+ self.set_icon(self.render_icon(icon, gtk.ICON_SIZE_MENU))
+
+ self.label = gtk.Label(message)
+ hbox.pack_start(self.label, True, False, 5)
+ self.label.set_width_chars(35)
+ self.label.set_line_wrap(True)
+
+ #action area
+ if both:
+ close_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ self.action_area.pack_start(close_button)
+ close_button.connect("clicked", self.close)
+ ok_button = gtk.Button(None, gtk.STOCK_OK)
+ self.action_area.pack_start(ok_button)
+ ok_button.connect("clicked", self.accept)
+ elif accept:
+ ok_button = gtk.Button(None, gtk.STOCK_OK)
+ self.action_area.pack_start(ok_button)
+ ok_button.connect("clicked", self.accept)
+ else:
+ close_button = gtk.Button(None, gtk.STOCK_CLOSE)
+ self.action_area.pack_start(close_button)
+ close_button.connect("clicked", self.close)
+
+ self.connect("response", self.close)
+ self.show_all()
+ if run:
+ self.run()
+
+ def accept(self, button):
+ """"""
+ self.accepted = True
+ self.close()
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
+
+if __name__ == "__main__":
+ m = Message(None, cons.SEVERITY_WARNING, "Tucan Manager - Restore previous session.", "Your last session closed unexpectedly.\nTucan will try to restore it now.", both=True)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/preferences.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/preferences.py
--- tucan-0.3.8/ui/gtk/preferences.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/preferences.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,443 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import __builtin__
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+import pango
+
+from service_preferences import ServicePreferences
+from message import Message
+from file_chooser import FileChooser
+from update_manager import UpdateManager
+
+import core.config as config
+import core.url_open as url_open
+import core.service_config as service_config
+
+import media
+import core.cons as cons
+
+LANGUAGES = [ ("Czech", "cs"),
+ ("English", "en"),
+ ("French", "fr"),
+ ("German", "de"),
+ ("Greek","gr"),
+ ("Italian", "it"),
+ ("Polish", "pl"),
+ ("Portuguese", "pt"),
+ ("Russian", "ru"),
+ ("Slovak", "sk"),
+ ("Spanish", "es"),
+ ("Swedish","se")]
+
+class Preferences(gtk.Dialog):
+ """"""
+ def __init__(self, parent, configuration, show_services=False, remote_info=None):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_icon_from_file(media.ICON_PREFERENCES)
+ self.set_title("%s - Preferences" % cons.TUCAN_NAME)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(500,500)
+
+ self.config = configuration
+
+ self.notebook = gtk.Notebook()
+ self.notebook.set_property("homogeneous", True)
+ self.vbox.pack_start(self.notebook)
+ self.new_page(_("General Configuration"), media.ICON_PREFERENCES_MAIN, self.init_main())
+ self.new_page(_("Service Configuration"), media.ICON_PREFERENCES_SERVICES, self.init_services())
+ self.new_page(_("Advanced Configuration"), media.ICON_PREFERENCES_ADVANCED, self.init_advanced())
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ save_button = gtk.Button(None, gtk.STOCK_SAVE)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(save_button)
+ cancel_button.connect("clicked", self.close)
+ save_button.connect("clicked", self.save)
+
+ self.connect("response", self.close)
+ self.show_all()
+
+ if show_services:
+ self.notebook.set_current_page(1)
+ if remote_info:
+ gobject.idle_add(self.update_manager, None, remote_info)
+ self.run()
+
+ def save(self, button):
+ """"""
+ self.config.set(config.SECTION_MAIN, config.OPTION_LANGUAGE, [lang[1] for lang in LANGUAGES][self.language.get_active()])
+
+ #live changes
+ self.config.set(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS, str(self.max_downloads.get_value_as_int()))
+ __builtin__.max_downloads = self.max_downloads.get_value_as_int()
+ self.config.set(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED, str(self.max_download_speed.get_value_as_int()))
+ __builtin__.max_download_speed = self.max_download_speed.get_value_as_int()
+
+ #self.config.set(config.SECTION_MAIN, config.OPTION_MAX_UPLOADS, str(self.max_uploads.get_value_as_int()))
+ self.config.set_downloads_folder(self.downloads_folder.get_label())
+
+ model = self.treeview.get_model()
+ iter = model.get_iter_root()
+ while iter:
+ configuration = model.get_value(iter, 3)
+ configuration.enable(model.get_value(iter, 2))
+ if not self.config.has_option(config.SECTION_SERVICES, model.get_value(iter,1)):
+ self.config.set(config.SECTION_SERVICES, model.get_value(iter,1), configuration.path)
+ iter = model.iter_next(iter)
+
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE, str(self.tray_close.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES, str(self.advanced_packages.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION, str(self.save_session.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE, str(self.auto_update.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS, str(self.show_uploads.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_ENABLE_PROXY, str(self.enable_proxy.get_active()))
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_PROXY_URL, self.proxy_url.get_text())
+ self.config.set(config.SECTION_ADVANCED, config.OPTION_PROXY_PORT, str(self.proxy_port.get_value_as_int()))
+
+ #change proxy settings
+ if self.enable_proxy.get_active():
+ proxy_url, proxy_port = self.config.get_proxy()
+ url_open.set_proxy(proxy_url, proxy_port)
+ else:
+ url_open.set_proxy(None)
+
+ self.config.save()
+ self.close()
+
+ def new_page(self, tab_name, tab_image, page):
+ """"""
+ vbox = gtk.VBox()
+ vbox.pack_start(gtk.image_new_from_file(tab_image))
+ vbox.pack_start(gtk.Label(tab_name))
+ vbox.show_all()
+ self.notebook.append_page(page, vbox)
+ self.notebook.set_tab_label_packing(page, True, True, gtk.PACK_START)
+
+ def init_main(self):
+ """"""
+ vbox = gtk.VBox()
+
+ frame = gtk.Frame()
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_LANGUAGE))
+ frame.set_border_width(5)
+ vbox.pack_start(frame, False, False)
+ hbox = gtk.HBox()
+ vbox1 = gtk.VBox()
+ frame.add(vbox1)
+ hbox = gtk.HBox()
+ vbox1.pack_start(hbox, False, False, 5)
+ label = gtk.Label(_("Choose language: "))
+ hbox.pack_start(label, False, False, 10)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect)
+ self.language = gtk.combo_box_new_text()
+ for lang in [lang[0] for lang in LANGUAGES]:
+ self.language.append_text(lang)
+ self.language.set_active([lang[1] for lang in LANGUAGES].index(self.config.get(config.SECTION_MAIN, config.OPTION_LANGUAGE)))
+ hbox.pack_start(self.language, False, False, 10)
+
+ frame = gtk.Frame()
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_NETWORK))
+ frame.set_border_width(5)
+ vbox.pack_start(frame, False, False)
+ vbox1 = gtk.VBox()
+ frame.add(vbox1)
+ hbox = gtk.HBox()
+ label = gtk.Label(_("Max simultaneous downloads: "))
+ hbox.pack_start(label, False, False, 10)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect)
+ self.max_downloads = gtk.SpinButton(None, 1, 0)
+ self.max_downloads.set_range(1,20)
+ self.max_downloads.set_increments(1,0)
+ self.max_downloads.set_numeric(True)
+ self.max_downloads.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOADS))
+ hbox.pack_start(self.max_downloads, False, False, 10)
+ vbox1.pack_start(hbox, False, False, 2)
+ hbox = gtk.HBox()
+ label = gtk.Label(_("Max download speed: "))
+ hbox.pack_start(label, False, False, 10)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect)
+ self.max_download_speed = gtk.SpinButton(None, 4, 0)
+ self.max_download_speed.set_range(0,5000)
+ self.max_download_speed.set_increments(4,0)
+ self.max_download_speed.set_numeric(True)
+ self.max_download_speed.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_DOWNLOAD_SPEED))
+ hbox.pack_start(self.max_download_speed, False, False, 10)
+ vbox1.pack_start(hbox, False, False, 2)
+ #hbox = gtk.HBox()
+ #label = gtk.Label(_("Max simultaneous uploads: "))
+ #hbox.pack_start(label, False, False, 10)
+ #aspect = gtk.AspectFrame()
+ #aspect.set_shadow_type(gtk.SHADOW_NONE)
+ #hbox.pack_start(aspect)
+ #self.max_uploads = gtk.SpinButton(None, 1, 0)
+ #self.max_uploads.set_range(1,10)
+ #self.max_uploads.set_increments(1,0)
+ #self.max_uploads.set_numeric(True)
+ #self.max_uploads.set_value(self.config.getint(config.SECTION_MAIN, config.OPTION_MAX_UPLOADS))
+ #hbox.pack_start(self.max_uploads, False, False, 10)
+ #vbox1.pack_start(hbox, False, False, 2)
+
+ frame = gtk.Frame()
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_FOLDER))
+ frame.set_border_width(5)
+ vbox.pack_start(frame, False, False)
+ vbox1 = gtk.VBox()
+ frame.add(vbox1)
+ hbox = gtk.HBox()
+ vbox1.pack_start(hbox, False, False, 5)
+
+ label = gtk.Label(_("Downloads Folder: "))
+ hbox.pack_start(label, False, False, 10)
+ path = self.config.get_downloads_folder()
+ self.downloads_folder = gtk.Label(path)
+ self.downloads_folder.set_width_chars(30)
+ self.downloads_folder.set_alignment(0, 0.5)
+ self.downloads_folder.set_ellipsize(pango.ELLIPSIZE_START)
+ hbox.pack_start(self.downloads_folder, False, False, 10)
+ bbox = gtk.HButtonBox()
+ bbox.set_layout(gtk.BUTTONBOX_END)
+ hbox.pack_start(bbox, True, True, 10)
+ button = gtk.Button(None, gtk.STOCK_OPEN)
+ button.connect("clicked", self.choose_path)
+ bbox.pack_start(button)
+
+ vbox.show_all()
+ return vbox
+
+ def choose_path(self, button):
+ """"""
+ FileChooser(self, self.downloads_folder.set_label, self.downloads_folder.get_label())
+
+ def init_services(self):
+ """"""
+ vbox = gtk.VBox()
+
+ frame = gtk.Frame()
+ frame.set_size_request(-1, 300)
+ vbox.pack_start(frame)
+ frame.set_border_width(10)
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ store = gtk.ListStore(gtk.gdk.Pixbuf, str, bool, gobject.TYPE_PYOBJECT)
+ self.treeview = gtk.TreeView(store)
+ scroll.add(self.treeview)
+ self.treeview.connect("row-activated", self.service_preferences)
+
+ self.treeview.set_rules_hint(True)
+ #self.treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ icon_cell.set_property("width", 50)
+ tree_icon.pack_start(icon_cell, False)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.set_property("width", 300)
+ name_cell.set_property("xalign", 0.1)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ self.treeview.append_column(tree_name)
+
+ tree_enable = gtk.TreeViewColumn('Enabled')
+ enable_cell = gtk.CellRendererToggle()
+ enable_cell.connect("toggled", self.toggled)
+ tree_enable.pack_start(enable_cell, True)
+ tree_enable.add_attribute(enable_cell, 'active', 2)
+ self.treeview.append_column(tree_enable)
+
+ #fill store
+ for path, icon_path, name, enabled, configuration in self.config.get_services():
+ self.add_service(path, icon_path, name, enabled, configuration)
+
+ frame = gtk.Frame()
+ frame.set_border_width(10)
+ frame.set_shadow_type(gtk.SHADOW_NONE)
+ vbox.pack_start(frame, False, False)
+ bbox = gtk.HButtonBox()
+ bbox.set_layout(gtk.BUTTONBOX_EDGE)
+ frame.add(bbox)
+ button = gtk.Button(None, gtk.STOCK_FIND)
+ button.connect("clicked", self.update_manager)
+ bbox.pack_start(button)
+ button = gtk.Button(None, gtk.STOCK_REMOVE)
+ button.connect("clicked", self.delete_service)
+ bbox.pack_start(button)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ bbox.pack_start(aspect)
+ button = gtk.Button(None, gtk.STOCK_INFO)
+ button.connect("clicked", self.service_info)
+ bbox.pack_start(button)
+
+ hbox = gtk.HBox()
+ vbox.pack_start(hbox, False, False, 5)
+ label = gtk.Label()
+ hbox.pack_start(label, False, False, 10)
+ label.set_markup("* " + _("Restart Tucan to apply service changes.") + " ")
+
+ return vbox
+
+ def service_info(self, button):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ self.service_preferences(None, model.get_path(iter))
+
+ def add_service(self, path, icon_path, name, enabled, configuration):
+ """"""
+ if configuration:
+ try:
+ icon = gtk.gdk.pixbuf_new_from_file_at_size(icon_path, 32, 32)
+ except Exception:
+ icon = gtk.gdk.pixbuf_new_from_file_at_size(media.ICON_MISSING, 32, 32)
+ logger.info("Could not load: %s" % icon_path)
+ self.treeview.get_model().append((icon, name, enabled, configuration))
+ else:
+ Message(self, cons.SEVERITY_ERROR, path , _("Service not configured."))
+
+ def update_manager(self, button=None, remote_info=None):
+ """"""
+ UpdateManager(self, self.config, remote_info)
+ self.treeview.get_model().clear()
+ for path, icon_path, name, enabled, configuration in self.config.get_services():
+ self.add_service(path, icon_path, name, enabled, configuration)
+
+ def delete_service(self, button):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ next_iter = model.iter_next(iter)
+ self.config.remove_option(config.SECTION_SERVICES, model.get_value(iter, 1))
+ model.remove(iter)
+ if next_iter:
+ self.treeview.set_cursor_on_cell(model.get_path(next_iter))
+
+ def toggled(self, button, path):
+ """"""
+ model = self.treeview.get_model()
+ if button.get_active():
+ active = False
+ else:
+ tos = _("Before using this service, you must accept it's terms of service at ") + model.get_value(model.get_iter(path), 1)
+ m = Message(self, cons.SEVERITY_INFO, _("Tucan Manager - Terms of service"), tos, True)
+ active = m.accepted
+ button.set_active(active)
+ model.set_value(model.get_iter(path), 2, active)
+
+ def service_preferences(self, treeview, path, view_column=None):
+ """"""
+ model = self.treeview.get_model()
+ icon = model.get_value(model.get_iter(path), 0)
+ name = model.get_value(model.get_iter(path), 1)
+ config = model.get_value(model.get_iter(path), 3)
+ ServicePreferences(self, name, icon, config)
+
+ def init_advanced(self):
+ """"""
+ frame = gtk.Frame()
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_ADVANCED))
+ frame.set_border_width(10)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ vbox = gtk.VBox()
+ hbox.pack_start(vbox, True, True, 10)
+
+ self.tray_close = gtk.CheckButton(_("Close to tray."))
+ vbox.pack_start(self.tray_close, False, False, 5)
+ self.tray_close.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_TRAY_CLOSE))
+
+ self.save_session = gtk.CheckButton(_("Save session on close."))
+ vbox.pack_start(self.save_session, False, False, 5)
+ self.save_session.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_SAVE_SESSION))
+
+ self.advanced_packages = gtk.CheckButton(_("Default advanced packages."))
+ vbox.pack_start(self.advanced_packages, False, False, 5)
+ self.advanced_packages.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_ADVANCED_PACKAGES))
+
+ self.auto_update = gtk.CheckButton(_("Automatic check for updates."))
+ vbox.pack_start(self.auto_update, False, False, 5)
+ self.auto_update.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_AUTO_UPDATE))
+
+ self.show_uploads = gtk.CheckButton(_("Show uploads."))
+ vbox.pack_start(self.show_uploads, False, False, 5)
+ self.show_uploads.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_SHOW_UPLOADS))
+
+ self.enable_proxy = gtk.CheckButton(_("Enable proxy:"))
+ vbox.pack_start(self.enable_proxy, False, False, 5)
+ self.enable_proxy.set_active(self.config.getboolean(config.SECTION_ADVANCED, config.OPTION_ENABLE_PROXY))
+ self.enable_proxy.connect("toggled", self.change_state)
+
+ self.proxy_box = gtk.HBox()
+ vbox.pack_start(self.proxy_box, False, False, 5)
+ self.proxy_box.pack_start(gtk.Label("HTTP Proxy:"), False, False, 5)
+ self.proxy_url = gtk.Entry()
+ self.proxy_box.pack_start(self.proxy_url, True, True, 5)
+ self.proxy_url.set_text(self.config.get(config.SECTION_ADVANCED, config.OPTION_PROXY_URL))
+
+ self.proxy_box.pack_start(gtk.Label("Port:"), False, False, 5)
+ self.proxy_port = gtk.SpinButton(None, 1, 0)
+ self.proxy_box.pack_start(self.proxy_port, False, False, 5)
+ self.proxy_port.set_range(0,65535)
+ self.proxy_port.set_increments(1,0)
+ self.proxy_port.set_numeric(True)
+ self.proxy_port.set_value(self.config.getint(config.SECTION_ADVANCED, config.OPTION_PROXY_PORT))
+
+ self.change_state()
+
+ return frame
+
+ def change_state(self, button=None):
+ """"""
+ self.proxy_box.set_sensitive(self.enable_proxy.get_active())
+
+ def close(self, widget=None, other=None):
+ """"""
+ enabled_services = 0
+ model = self.treeview.get_model()
+ iter = model.get_iter_root()
+ while iter:
+ if model.get_value(iter, 3).getboolean(service_config.SECTION_MAIN, service_config.OPTION_ENABLED):
+ enabled_services += 1
+ iter = model.iter_next(iter)
+ if enabled_services > 0:
+ self.destroy()
+ else:
+ Message(self, cons.SEVERITY_WARNING, _("Tucan Manager - No services enabled!") , _("Enable some services and restart Tucan."))
+ self.run()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/report.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/report.py
--- tucan-0.3.8/ui/gtk/report.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/report.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,150 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import threading
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from message import Message
+
+from core.misc import report_log
+import core.cons as cons
+import media
+
+class Report(gtk.Dialog):
+ """"""
+ def __init__(self, parent):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_transient_for(parent)
+ self.set_title("%s - Report problem" % cons.TUCAN_NAME)
+ self.set_position(gtk.WIN_POS_CENTER)
+ self.set_size_request(400, 300)
+ self.set_icon_from_file(media.ICON_SEND)
+
+ self.sending = False
+
+ frame = gtk.Frame()
+ label = gtk.Label()
+ label.set_markup("%s: " % ("Email"))
+ frame.set_label_widget(label)
+ self.vbox.pack_start(frame, False)
+ frame.set_border_width(10)
+ self.email = gtk.Entry()
+ frame.add(self.email)
+
+ frame = gtk.Frame()
+ label = gtk.Label()
+ label.set_markup("%s: " % ("Comment"))
+ frame.set_label_widget(label)
+ self.vbox.pack_start(frame)
+ frame.set_border_width(10)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ scroll = gtk.ScrolledWindow()
+ hbox.pack_start(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ #textview
+ buffer = gtk.TextBuffer()
+ self.textview = gtk.TextView(buffer)
+ scroll.add(self.textview)
+ self.textview.set_wrap_mode(gtk.WRAP_WORD)
+
+ #status
+ self.status_hbox = gtk.HBox()
+ self.vbox.pack_start(self.status_hbox, False, False, 5)
+ self.label = gtk.Label("Sending report.")
+ self.status_hbox.pack_start(self.label, False, False, 11)
+ self.progress = gtk.ProgressBar()
+ self.progress.pulse()
+ self.status_hbox.pack_start(self.progress, True, True, 11)
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ ok_button = gtk.Button(None, gtk.STOCK_OK)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(ok_button)
+ cancel_button.connect("clicked", self.close)
+ ok_button.connect("clicked", self.send)
+
+ self.connect("response", self.close)
+ self.show_all()
+ self.status_hbox.hide()
+ self.run()
+
+ def send(self, button):
+ """"""
+ self.status_hbox.show()
+ self.email.set_sensitive(False)
+ self.textview.set_editable(False)
+ self.textview.set_cursor_visible(False)
+ self.action_area.set_sensitive(False)
+ th = threading.Thread(group=None, target=self.th_send, name=None)
+ th.start()
+
+ def th_send(self):
+ """"""
+ self.sending = True
+ gobject.timeout_add(100, self.pulse)
+ buffer = self.textview.get_buffer()
+ start, end = buffer.get_bounds()
+ comment = buffer.get_text(start, end).strip()
+ id = report_log(self.email.get_text(), comment)
+ self.sending = False
+ gobject.idle_add(self.reported, id)
+
+ def reported(self, id):
+ """"""
+ if id:
+ label = "Report ID:"
+ self.status_hbox.remove(self.status_hbox.get_children().pop())
+ id = gtk.Label(id)
+ id.set_selectable(True)
+ self.status_hbox.pack_end(id, True, False, 10)
+ id.show()
+ else:
+ label = "Report failed, try again later."
+ self.progress.hide()
+ self.label.set_text(label)
+
+ close_button = gtk.Button(None, gtk.STOCK_CLOSE)
+ close_button.connect("clicked", self.close)
+ close_button.show()
+ for child in self.action_area.get_children():
+ self.action_area.remove(child)
+ self.action_area.pack_start(close_button)
+ self.action_area.set_sensitive(True)
+
+ def pulse(self):
+ """"""
+ if self.sending:
+ self.progress.pulse()
+ return True
+
+ def close(self, widget=None, other=None):
+ """"""
+ if not self.sending:
+ self.destroy()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/service_preferences.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/service_preferences.py
--- tucan-0.3.8/ui/gtk/service_preferences.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/service_preferences.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,334 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import core.service_config as service_config
+import core.cons as cons
+import media
+
+
+class InfoPreferences(gtk.VBox):
+ """"""
+ def __init__(self, section, name, config, accounts=False):
+ """"""
+ gtk.VBox.__init__(self)
+ vbox = gtk.VBox()
+
+ frame = gtk.Frame()
+ label = gtk.Label()
+ label.set_markup("" + name + " ")
+ frame.set_label_widget(label)
+ frame.set_border_width(10)
+ self.pack_start(frame)
+ frame.add(vbox)
+
+ hbox = gtk.HBox()
+ label = gtk.Label()
+ label.set_markup("" + _("Author") + ": ")
+ hbox.pack_start(label, False, False, 10)
+ label = gtk.Label(config.get(section, service_config.OPTION_AUTHOR))
+ hbox.pack_start(label, False)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ hbox.pack_start(aspect)
+ label = gtk.Label()
+ label.set_markup("" + _("Version") + ": ")
+ hbox.pack_start(label, False)
+ label = gtk.Label(config.get(section, service_config.OPTION_VERSION))
+ hbox.pack_start(label, False, False, 10)
+ vbox.pack_start(hbox, False, False, 5)
+
+ if not accounts:
+ hbox = gtk.HBox()
+ label = gtk.Label()
+ label.set_markup("" + _("Slots") + ": ")
+ hbox.pack_start(label, False, False, 10)
+ label = gtk.Label(config.get(section, service_config.OPTION_SLOTS))
+ hbox.pack_start(label, False)
+ vbox.pack_start(hbox, False, False, 5)
+ hbox = gtk.HBox()
+ label = gtk.Label()
+ label.set_markup("" + _("Captcha") + ": ")
+ hbox.pack_start(label, False, False, 10)
+ label = gtk.Label(config.get(section, service_config.OPTION_CAPTCHA))
+ hbox.pack_start(label, False)
+ vbox.pack_start(hbox, False, False, 5)
+
+class AccountPreferences(InfoPreferences):
+ """"""
+ def __init__(self, section, name, config, get_cookie):
+ """"""
+ InfoPreferences.__init__(self, section, name, config, True)
+
+ self.get_cookie = get_cookie
+
+ frame = gtk.Frame()
+ frame.set_label_widget(gtk.image_new_from_file(media.ICON_ACCOUNT))
+ frame.set_border_width(10)
+ self.pack_start(frame, False, False, 1)
+ scroll = gtk.ScrolledWindow()
+ scroll.set_size_request(-1, 110)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ frame.add(scroll)
+ store = gtk.ListStore(gtk.gdk.Pixbuf, str, str, bool, bool, str)
+ self.treeview = gtk.TreeView(store)
+ scroll.add(self.treeview)
+
+ self.treeview.set_rules_hint(True)
+ #self.treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Active')
+ icon_cell = gtk.CellRendererPixbuf()
+ icon_cell.set_property("width", 50)
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('User Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.set_property("width", 120)
+ name_cell.set_property("editable", True)
+ name_cell.connect("edited", self.change, 1)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ self.treeview.append_column(tree_name)
+
+ tree_pass = gtk.TreeViewColumn('Password')
+ pass_cell = gtk.CellRendererText()
+ pass_cell.set_property("width", 120)
+ pass_cell.set_property("editable", True)
+ pass_cell.connect("edited", self.change, 2)
+ pass_cell.connect("editing-started", self.show_password)
+ tree_pass.pack_start(pass_cell, True)
+ tree_pass.add_attribute(pass_cell, 'text', 5)
+ self.treeview.append_column(tree_pass)
+
+ tree_enable = gtk.TreeViewColumn('Enable')
+ enable_cell = gtk.CellRendererToggle()
+ enable_cell.connect("toggled", self.toggled)
+ tree_enable.pack_start(enable_cell, False)
+ tree_enable.add_attribute(enable_cell, 'visible', 4)
+ tree_enable.add_attribute(enable_cell, 'active', 3)
+ self.treeview.append_column(tree_enable)
+
+ self.active_service_icon = self.treeview.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_LARGE_TOOLBAR)
+ self.unactive_service_icon = self.treeview.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_LARGE_TOOLBAR)
+
+ accounts = config.get_accounts(section)
+ for name in accounts.keys():
+ password, enabled, active = accounts[name]
+ if active:
+ icon = self.active_service_icon
+ else:
+ icon = self.unactive_service_icon
+ store.append([icon, name, password, enabled, active, "".join(["*" for i in range(len(password))])])
+
+ frame = gtk.Frame()
+ frame.set_border_width(10)
+ frame.set_shadow_type(gtk.SHADOW_NONE)
+ self.pack_start(frame, False, False)
+ bbox = gtk.HButtonBox()
+ bbox.set_layout(gtk.BUTTONBOX_EDGE)
+ frame.add(bbox)
+ button = gtk.Button(None, gtk.STOCK_ADD)
+ button.connect("clicked", self.add)
+ bbox.pack_start(button)
+ button = gtk.Button(None, gtk.STOCK_REMOVE)
+ button.connect("clicked", self.remove)
+ bbox.pack_start(button)
+ aspect = gtk.AspectFrame()
+ aspect.set_shadow_type(gtk.SHADOW_NONE)
+ bbox.pack_start(aspect)
+ button = gtk.Button(None, gtk.STOCK_CONNECT)
+ button.connect("clicked", self.check)
+ bbox.pack_start(button)
+
+ def show_password(self, cellrenderertext, editable, path):
+ """"""
+ model = self.treeview.get_model()
+ editable.props.text = model.get_value(model.get_iter(path), 2)
+
+ def change(self, cellrenderertext, path, new_text, column):
+ """"""
+ model = self.treeview.get_model()
+ model.set_value(model.get_iter(path), column, new_text)
+ if column == 2:
+ model.set_value(model.get_iter(path), 5, "".join(["*" for i in range(len(new_text))]))
+
+ def add(self, button):
+ """"""
+ model = self.treeview.get_model()
+ iter = model.append([self.unactive_service_icon, "", "", False, False, ""])
+ self.treeview.set_cursor(model.get_path(iter), self.treeview.get_column(1), True)
+
+ def remove(self, button):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ next_iter = model.iter_next(iter)
+ model.remove(iter)
+ if next_iter:
+ self.treeview.set_cursor_on_cell(model.get_path(next_iter))
+
+ def check(self, button):
+ """"""
+ model, iter = self.treeview.get_selection().get_selected()
+ if iter:
+ cookie = self.get_cookie(model.get_value(iter, 1), model.get_value(iter, 2))
+ if cookie:
+ icon = self.active_service_icon
+ active = True
+ else:
+ icon = self.unactive_service_icon
+ active = False
+ model.set_value(iter, 0, icon)
+ model.set_value(iter, 3, active)
+ model.set_value(iter, 4, active)
+
+ def toggled(self, button, path):
+ """"""
+ model = self.treeview.get_model()
+ if button.get_active():
+ active = False
+ else:
+ active = True
+ button.set_active(active)
+ model.set_value(model.get_iter(path), 3, active)
+
+ def get_accounts(self):
+ """"""
+ model = self.treeview.get_model()
+ iter = model.get_iter_root()
+ accounts = {}
+ while iter:
+ accounts[model.get_value(iter, 1)] = (model.get_value(iter, 2), model.get_value(iter, 3), model.get_value(iter, 4))
+ iter = model.iter_next(iter)
+ return accounts
+
+class ServicePreferences(gtk.Dialog):
+ """"""
+ def __init__(self, parent, service, icon, config):
+ """"""
+ gtk.Dialog.__init__(self)
+ self.set_icon(icon)
+ self.set_title(service)
+ self.set_transient_for(parent)
+ self.set_size_request(600, 400)
+
+ self.config = config
+
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, True, True, 5)
+ frame = gtk.Frame()
+ hbox.pack_start(frame, False, False, 10)
+
+ store = gtk.TreeStore(str, str, int)
+ self.treeview = gtk.TreeView(store)
+ self.treeview.get_selection().connect("changed", self.select)
+ frame.add(self.treeview)
+
+ self.treeview.set_headers_visible(False)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.set_property("width", 100)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ self.treeview.append_column(tree_name)
+
+ self.notebook = gtk.Notebook()
+ hbox.pack_start(self.notebook, True, True, 10)
+ self.notebook.set_show_tabs(False)
+
+ cont = 0
+ plugin_list = []
+ plugins = self.config.get_download_plugins()
+ if plugins:
+ plugin_list.append(("Download", plugins))
+ plugins = self.config.get_upload_plugins()
+ if plugins:
+ plugin_list.append(("Upload", plugins))
+ for item, plugins in plugin_list:
+ iter = store.append(None, [None, item, -1])
+ for section, section_name, section_type in plugins:
+ page = gtk.VBox()
+ if section_type == cons.TYPE_ANONYMOUS:
+ page = InfoPreferences(section, section_name, self.config)
+ else:
+ if section_type == cons.TYPE_USER:
+ module, name = config.user_cookie()
+ elif section_type == cons.TYPE_PREMIUM:
+ module, name = config.premium_cookie()
+ if name:
+ module = __import__(service.split(".")[0] + "." + module, None, None, [''])
+ get_cookie = eval("module" + "." + name + "()").get_cookie
+ page = AccountPreferences(section, section_name, self.config, get_cookie)
+ self.notebook.append_page(page, None)
+ subiter = store.append(iter, [section, section_type, cont])
+ self.treeview.expand_to_path(store.get_path(subiter))
+ if cont == 0:
+ self.treeview.set_cursor_on_cell(store.get_path(subiter))
+ cont += 1
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ save_button = gtk.Button(None, gtk.STOCK_SAVE)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(save_button)
+ cancel_button.connect("clicked", self.close)
+ save_button.connect("clicked", self.save)
+
+ self.connect("response", self.close)
+ self.show_all()
+ self.run()
+
+ def select(self, selection):
+ """"""
+ model, iter = selection.get_selected()
+ if iter:
+ child_iter = model.iter_children(iter)
+ if child_iter:
+ selection.select_iter(child_iter)
+ else:
+ self.notebook.set_current_page(model.get_value(iter, 2))
+
+ def save(self, button):
+ """"""
+ model = self.treeview.get_model()
+ iter = model.get_iter_root()
+ while iter:
+ child_iter = model.iter_children(iter)
+ while child_iter:
+ page = self.notebook.get_nth_page((model.get_value(iter, 2)))
+ if ((page) and (model.get_value(child_iter, 1) != cons.TYPE_ANONYMOUS)):
+ self.config.set_accounts(model.get_value(child_iter, 0), page.get_accounts())
+ child_iter = model.iter_next(child_iter)
+ iter = model.iter_next(iter)
+ self.close()
+
+ def close(self, widget=None, other=None):
+ """"""
+ self.destroy()
+
+if __name__ == "__main__":
+ x = ServicePreferences("rapidshare.com", gtk.gdk.pixbuf_new_from_file(media.ICON_MISSING), service_config.ServiceConfig("/home/crak/.tucan/plugins/megaupload/"))
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/shutdown.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/shutdown.py
--- tucan-0.3.8/ui/gtk/shutdown.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/shutdown.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,72 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import time
+import logging
+import subprocess
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from message import Message
+
+import core.cons as cons
+
+class Shutdown:
+ """"""
+ def __init__(self, parent, quit):
+ """"""
+ self.time = 60
+ title = "Tucan Manager - Shutting down!"
+ self.message = "The system is going to shut down in"
+ self.dialog = Message(parent, cons.SEVERITY_WARNING, title, "%s 1 minute." % self.message, True, True, False)
+ gobject.timeout_add(1000, self.counter)
+ self.dialog.run()
+ if self.dialog.accepted:
+ try:
+ if cons.OS_WINDOWS:
+ if subprocess.call(["shutdown.exe", "-f", "-s"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=134217728) == 0:
+ quit()
+ elif cons.OS_OSX:
+ if subprocess.call(["osascript", "-e", "tell application \"Finder\" to shut down"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
+ quit()
+ else:
+ if subprocess.call(["sudo", "-n", "shutdown", "h", "now"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
+ quit()
+ Message(parent, cons.SEVERITY_ERROR, title, "Could not shut down the computer.")
+ except Exception, e:
+ logger.exception(e)
+
+ def counter(self):
+ """"""
+ if self.time > 0:
+ self.time -= 1
+ self.dialog.label.set_text("%s %i seconds." % (self.message, self.time))
+ return True
+ else:
+ self.dialog.accepted = True
+ self.dialog.close()
+
+if __name__ == "__main__":
+ Shutdown(None, None)
+
\ No newline at end of file
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/statusbar.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/statusbar.py
--- tucan-0.3.8/ui/gtk/statusbar.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/statusbar.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,153 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import time
+import __builtin__
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import media
+import core.cons as cons
+
+class Statusbar(gtk.Statusbar):
+ """"""
+ def __init__(self):
+ """"""
+ gtk.Statusbar.__init__(self)
+ self.set_has_resize_grip(False)
+
+ self.services = configuration.get_services()
+ self.blinks = 0
+
+ #download speed limit
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_IN)
+ self.pack_start(frame, False, False)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ label = gtk.Label(_("Max speed:"))
+ hbox.pack_start(label, False, False, 2)
+ self.max_speed = gtk.SpinButton(None, 4, 0)
+ self.max_speed.set_property("shadow-type", gtk.SHADOW_NONE)
+ self.max_speed.set_range(0,5000)
+ self.max_speed.set_increments(4,0)
+ self.max_speed.set_numeric(True)
+ self.max_speed.set_value(__builtin__.max_download_speed)
+ hbox.pack_start(self.max_speed, False, False, )
+
+ self.max_speed.connect("value-changed", self.change_speed)
+
+ self.menu = gtk.Menu()
+
+ self.limits = {}
+ events.connect(cons.EVENT_LIMIT_ON, self.add_limit)
+ events.connect(cons.EVENT_LIMIT_OFF, self.remove_limit)
+
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_IN)
+ self.pack_start(frame, False, False)
+ hbox = gtk.HBox()
+ frame.add(hbox)
+ label = gtk.Label("Limits:")
+ hbox.pack_start(label, False, False, 2)
+ self.button = gtk.Button()
+ self.button.set_image(gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_NONE))
+ hbox.pack_start(self.button, False, False, 2)
+ self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#fff"))
+
+ self.button.connect("clicked", self.show_stack)
+ self.show_all()
+
+ def synchronize(self):
+ """"""
+ self.max_speed.set_value(__builtin__.max_download_speed)
+
+ def change_speed(self, spinbutton):
+ """"""
+ __builtin__.max_download_speed = spinbutton.get_value_as_int()
+
+ def blink(self):
+ """"""
+ if self.blinks < 10:
+ self.blinks += 1
+ if self.blinks % 2:
+ self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#f99"))
+ else:
+ self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#fff"))
+ return True
+ else:
+ self.blinks = 0
+
+ def add_limit(self, module):
+ """"""
+ tmp = module.split(".")
+ callback = lambda x: events.trigger_limit_cancel(module)
+ if not module in self.limits:
+ for name, icon_path, url, enabled, config in self.services:
+ if tmp[0] == name:
+ self.limits[module] = self.new_item(url, tmp[1], icon_path, callback)
+ gobject.timeout_add(500, self.blink)
+ break
+
+ def remove_limit(self, module):
+ """"""
+ if module in self.limits:
+ del self.limits[module]
+
+ def show_stack(self, widget):
+ """"""
+ for limit in self.menu:
+ self.menu.remove(limit)
+ if len(self.limits) == 0:
+ self.menu.append(self.new_item("None", "", None, lambda x: x))
+ else:
+ for module, item in self.limits.items():
+ self.menu.append(item)
+ self.menu.append(gtk.SeparatorMenuItem())
+ self.menu.show_all()
+ self.menu.popup(None, None, self.menu_position, 1, 0, widget.get_allocation())
+
+ def new_item(self, service, service_type, icon_path, callback):
+ """"""
+ limit = gtk.MenuItem()
+ limit.connect("activate", callback)
+ vbox = gtk.VBox()
+ hbox = gtk.HBox()
+ vbox.pack_start(hbox)
+ if icon_path:
+ icon = gtk.gdk.pixbuf_new_from_file_at_size(icon_path, 32, 32)
+ else:
+ icon = gtk.gdk.pixbuf_new_from_file_at_size(media.ICON_MISSING, 32, 32)
+ hbox.pack_start(gtk.image_new_from_pixbuf(icon))
+ hbox.pack_start(gtk.Label(service))
+ vbox.pack_start(gtk.Label(service_type))
+ limit.add(vbox)
+ return limit
+
+ def menu_position(self, menu, rect):
+ """"""
+ width, height = menu.size_request()
+ window_x, window_y = self.parent.get_parent_window().get_position()
+ return rect.x + window_x - (width - rect.width), rect.y + window_y - height, True
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/toolbar.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/toolbar.py
--- tucan-0.3.8/ui/gtk/toolbar.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/toolbar.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,37 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+class Toolbar(gtk.Toolbar):
+ """"""
+ def __init__(self, list):
+ """list = [(tool_name, image, callback),]"""
+ gtk.Toolbar.__init__(self)
+ self.set_style(gtk.TOOLBAR_BOTH)
+ for button in list:
+ if button == None:
+ item = gtk.SeparatorToolItem()
+ else:
+ item = gtk.ToolButton(button[1], button[0])
+ item.connect("clicked", button[2])
+ self.insert(item, -1)
\ No newline at end of file
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/tray_icon.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/tray_icon.py
--- tucan-0.3.8/ui/gtk/tray_icon.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/tray_icon.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,110 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import logging
+logger = logging.getLogger(__name__)
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+import media
+import core.cons as cons
+
+if cons.OS_OSX:
+ try:
+ from igemacintegration import *
+ except Exception:
+ pass
+ else:
+ class OSXDock(MacDock):
+ """"""
+ def __init__(self, show, quit):
+ """"""
+ MacDock.__init__(self)
+
+ self.show_window = show
+ self.window_visible = True
+
+ self.connect("quit-activate", quit)
+ self.connect("clicked", self.activate)
+
+ def activate(self, statusicon, closed=False):
+ """"""
+ if self.window_visible:
+ if closed:
+ self.window_visible = False
+ else:
+ self.show_window()
+ self.window_visible = True
+
+ def close(self):
+ """"""
+ pass
+
+class TrayIcon(gtk.StatusIcon):
+ """"""
+ def __init__(self, show, hide, menu):
+ """"""
+ gtk.StatusIcon.__init__(self)
+ self.set_tooltip("Tucan Manager - Version: %s" % cons.TUCAN_VERSION)
+ self.set_from_file(media.ICON_TUCAN)
+ self.set_visible(True)
+
+ self.window_visible = True
+ self.show_window = show
+ self.hide_window = hide
+
+ self.menu = gtk.Menu()
+ for item in menu:
+ if item == None:
+ tmp = gtk.SeparatorMenuItem()
+ else:
+ tmp = gtk.ImageMenuItem(item[0])
+ tmp.connect('activate', item[1])
+ self.menu.append(tmp)
+ self.menu.show_all()
+
+ self.connect('activate', self.activate)
+ self.connect('popup-menu', self.popup_menu)
+
+ def activate(self, statusicon, event=None):
+ """"""
+ if self.window_visible:
+ self.hide_window()
+ self.window_visible = False
+ else:
+ self.show_window()
+ self.window_visible = True
+
+ def popup_menu(self, statusicon, button, time):
+ """"""
+ self.menu.popup(None, None, None, button, time, self)
+
+ def change_tooltip(self, statusbar, context, text):
+ """"""
+ #if context == "Downloads":
+ tmp = text.split("\t")
+ message = "Downloads: " + "".join(tmp[1:]) + "\n" + tmp[0].strip()
+ self.set_tooltip(message)
+
+ def close(self):
+ """"""
+ self.set_visible(False)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/tree.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/tree.py
--- tucan-0.3.8/ui/gtk/tree.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/tree.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,410 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+import pango
+
+from statusbar import Statusbar
+
+import core.cons as cons
+
+class Tree(gtk.VBox):
+ """"""
+ def __init__(self, menu, manager):
+ """"""
+ gtk.VBox.__init__(self)
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.treeview = gtk.TreeView(gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, int, bool, str, str, str, str, str))
+ scroll.add(self.treeview)
+ self.pack_start(scroll)
+
+ self.menu = gtk.Menu()
+ for item in menu:
+ if item == None:
+ subitem = gtk.SeparatorMenuItem()
+ else:
+ subitem = gtk.ImageMenuItem(item[0])
+ subitem.connect("activate", item[1])
+ self.menu.append(subitem)
+ self.menu.show_all()
+ self.treeview.connect("button-press-event", self.mouse_menu)
+
+ self.get_files = manager.get_files
+
+ self.treeview.set_rules_hint(True)
+ self.treeview.set_headers_visible(False)
+
+ #tree columns
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, False)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ self.treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ name_cell.set_property("width-chars", 60)
+ name_cell.set_property("ellipsize", pango.ELLIPSIZE_MIDDLE)
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 3)
+ self.treeview.append_column(tree_name)
+
+ tree_progress = gtk.TreeViewColumn('Progress')
+ tree_progress.set_min_width(150)
+ progress_cell = gtk.CellRendererProgress()
+ tree_progress.pack_start(progress_cell, True)
+ tree_progress.add_attribute(progress_cell, 'value', 4)
+ tree_progress.add_attribute(progress_cell, 'visible', 5)
+ self.treeview.append_column(tree_progress)
+
+ tree_current_size = gtk.TreeViewColumn('Current Size')
+ current_size_cell = gtk.CellRendererText()
+ tree_current_size.pack_start(current_size_cell, False)
+ tree_current_size.add_attribute(current_size_cell, 'text', 6)
+ self.treeview.append_column(tree_current_size)
+
+ tree_total_size = gtk.TreeViewColumn('Total Size')
+ total_size_cell = gtk.CellRendererText()
+ tree_total_size.pack_start(total_size_cell, False)
+ tree_total_size.add_attribute(total_size_cell, 'text', 7)
+ self.treeview.append_column(tree_total_size)
+
+ tree_speed = gtk.TreeViewColumn('Speed')
+ speed_cell = gtk.CellRendererText()
+ tree_speed.pack_start(speed_cell, False)
+ tree_speed.add_attribute(speed_cell, 'text', 8)
+ self.treeview.append_column(tree_speed)
+
+ tree_time = gtk.TreeViewColumn('Time Left')
+ time_cell = gtk.CellRendererText()
+ tree_time.pack_start(time_cell, False)
+ tree_time.add_attribute(time_cell, 'text', 9)
+ self.treeview.append_column(tree_time)
+
+ tree_plugins = gtk.TreeViewColumn('Plugin')
+ plugins_cell = gtk.CellRendererText()
+ tree_plugins.pack_start(plugins_cell, False)
+ tree_plugins.add_attribute(plugins_cell, 'text', 10)
+ self.treeview.append_column(tree_plugins)
+
+ #icons
+ self.package_icon = self.treeview.render_icon(gtk.STOCK_OPEN, gtk.ICON_SIZE_MENU)
+ self.active_service_icon = self.treeview.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)
+ self.unactive_service_icon = self.treeview.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU)
+ self.correct_icon = self.treeview.render_icon(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
+ self.failed_icon = self.treeview.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
+ self.wait_icon = self.treeview.render_icon(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
+ self.active_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
+ self.pending_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU)
+ self.stoped_icon = self.treeview.render_icon(gtk.STOCK_MEDIA_STOP, gtk.ICON_SIZE_MENU)
+ self.icons = {cons.STATUS_CORRECT: self.correct_icon, cons.STATUS_ERROR: self.failed_icon, cons.STATUS_WAIT: self.wait_icon, cons.STATUS_ACTIVE: self.active_icon, cons.STATUS_PEND: self.pending_icon, cons.STATUS_STOP: self.stoped_icon}
+
+ self.status_bar = Statusbar()
+ self.pack_start(self.status_bar, False)
+ self.status_bar.push(self.status_bar.get_context_id("Downloads"), " No Downloads Active.")
+ self.updating = False
+
+ def mouse_menu(self, widget, event):
+ """right button"""
+ if event.button == 3:
+ model, paths = self.treeview.get_selection().get_selected_rows()
+ if len(paths) > 0:
+ self.menu.popup(None, None, None, event.button, event.time)
+
+ def add_package(self, package_name, package_path, package, password):
+ """
+ TreeStore(icon, status, password, name, progress, progress_visible, current_size, total_size, speed, time, services)
+ """
+ tmp_size = []
+ model = self.treeview.get_model()
+ package_iter = model.append(None, [self.package_icon, cons.STATUS_PEND, password, package_name, 0, True, None, None, None, None, package_path])
+ for item in package:
+ tmp_size.append((item[3], item[4]))
+ item_iter = model.append(package_iter, [self.pending_icon, cons.STATUS_PEND, None, item[1], 0, True, None, str(item[3])+item[4], None, None, str(item[2])])
+ self.treeview.expand_to_path(model.get_path(item_iter))
+ for link in item[0]:
+ link_iter = model.append(item_iter, [self.unactive_service_icon, cons.STATUS_PEND, None, link, 0, False, None, None, None, None, item[5][item[0].index(link)]])
+ package_size, package_unit = self.normalize(tmp_size)
+ model.set_value(package_iter, 7, str(package_size)+package_unit)
+ if not self.updating:
+ self.updating = True
+ gobject.timeout_add(1000, self.update)
+ return package_iter
+
+ def update(self):
+ """(icon, status, None, name, progress, progress_visible, current_size, total_size, speed, time, services)"""
+ files = self.get_files()
+ if len(files) > 0:
+ model = self.treeview.get_model()
+ package_iter = model.get_iter_root()
+ active_downloads = 0
+ complete_downloads = 0
+ total_downloads = 0
+ total_speed = 0
+ while package_iter:
+ file_iter = model.iter_children(package_iter)
+ #package_status = model.set_value(package_iter, 0)
+ package_progress = 0
+ package_speed = 0
+ tmp_actual_size = []
+ tmp_total_size = []
+ while file_iter:
+ total_downloads += 1
+ name = model.get_value(file_iter, 3)
+ for file in files:
+ if file.name == name:
+ model.set_value(file_iter, 0, self.icons[file.status])
+ model.set_value(file_iter, 1, file.status)
+ if file.status in [cons.STATUS_ACTIVE, cons.STATUS_WAIT]:
+ active_downloads += 1
+ elif file.status == cons.STATUS_CORRECT:
+ complete_downloads += 1
+ model.set_value(file_iter, 4, file.progress)
+ package_progress += file.progress
+ if file.actual_size > 0:
+ model.set_value(file_iter, 6, str(file.actual_size)+file.actual_size_unit)
+ tmp_actual_size.append((file.actual_size, file.actual_size_unit))
+ tmp_total_size.append((file.total_size, file.total_size_unit))
+ if file.speed > 1:
+ model.set_value(file_iter, 8, str(file.speed)+cons.UNIT_SPEED)
+ package_speed += file.speed
+ elif file.speed == 0:
+ model.set_value(file_iter, 8, None)
+ if file.status == cons.STATUS_CORRECT:
+ if not file.time > 0:
+ file.time = 1
+ file.actual_size = file.total_size
+ file.actual_size_unit = file.total_size_unit
+ model.set_value(file_iter, 9, self.calculate_time(file.time))
+ link_iter = model.iter_children(file_iter)
+ while link_iter:
+ for tmp_link in file.links:
+ if tmp_link.url == model.get_value(link_iter, 3):
+ service_icon = self.unactive_service_icon
+ link_status = cons.STATUS_STOP
+ if tmp_link.active:
+ service_icon = self.active_service_icon
+ link_status = cons.STATUS_ACTIVE
+ model.set_value(link_iter, 0, service_icon)
+ model.set_value(link_iter, 1, link_status)
+ link_iter = model.iter_next(link_iter)
+ file_iter = model.iter_next(file_iter)
+ package_actual_size, package_actual_unit = self.normalize(tmp_actual_size)
+ package_total_size, package_total_unit = self.normalize(tmp_total_size)
+ if package_actual_size > 0:
+ if int(package_progress/model.iter_n_children(package_iter)) == 100:
+ model.set_value(package_iter, 4, 100)
+ else:
+ model.set_value(package_iter, 4, int((float(self.get_size(package_actual_size, package_actual_unit))/float(self.get_size(package_total_size, package_total_unit)))*100))
+ model.set_value(package_iter, 6, str(package_actual_size)+package_actual_unit)
+ if package_speed > 0:
+ model.set_value(package_iter, 8, str(package_speed)+cons.UNIT_SPEED)
+ else:
+ model.set_value(package_iter, 8, None)
+ total_speed += package_speed
+ package_iter = model.iter_next(package_iter)
+ self.status_bar.pop(self.status_bar.get_context_id("Downloads"))
+ self.status_bar.push(self.status_bar.get_context_id("Downloads"), " Downstream %dKB/s \tTotal %d \t Complete %d \t Active %d" % (total_speed, total_downloads, complete_downloads, active_downloads))
+ return True
+
+ def normalize(self, sizes):
+ """"""
+ total = 0
+ total_unit = cons.UNIT_KB
+ for size, unit in sizes:
+ total += self.get_size(size, unit)
+ tmp = int(total/1024)
+ if tmp > 0:
+ total = tmp
+ total_unit = cons.UNIT_MB
+ tmp = int(tmp/1024)
+ # if tmp > 0:
+ # total = tmp
+ # total_unit = cons.UNIT_GB
+ return total, total_unit
+
+ def get_size(self, size, unit):
+ """"""
+ if unit == cons.UNIT_KB:
+ return size
+ elif unit == cons.UNIT_MB:
+ return size*1024
+ #elif unit == cons.UNIT_GB:
+ # return size*1024*1024
+
+ def get_packages(self):
+ """"""
+ model = self.treeview.get_model()
+ package_iter = model.get_iter_root()
+ packages = []
+ info = []
+ while package_iter:
+ files = []
+ file_iter = model.iter_children(package_iter)
+ while file_iter:
+ if model.get_value(file_iter, 1) != cons.STATUS_CORRECT:
+ links = []
+ plugins = []
+ link_iter = model.iter_children(file_iter)
+ while link_iter:
+ links.append(model.get_value(link_iter, 3))
+ plugins.append(model.get_value(link_iter, 10))
+ link_iter = model.iter_next(link_iter)
+ name = model.get_value(file_iter, 3)
+ tmp = model.get_value(file_iter, 7)
+ for unit in [cons.UNIT_KB, cons.UNIT_MB]:
+ tmp_size = tmp.split(unit)
+ if len(tmp_size) > 1:
+ size_unit = unit
+ size = int(tmp_size[0])
+ break
+ tmp = model.get_value(file_iter, 10)
+ tmp = tmp.split(",")
+ service_list = []
+ for service in tmp:
+ service_list.append(service.split("\'")[1])
+ files.append((links, name, service_list, size, size_unit, plugins))
+ file_iter = model.iter_next(file_iter)
+ if len(files) > 0:
+ name = model.get_value(package_iter, 3)
+ packages.append((name, files))
+ path = model.get_value(package_iter, 10).split(name)[0]
+ info.append((path, name, model.get_value(package_iter, 2)))
+ package_iter = model.iter_next(package_iter)
+ return packages, info
+
+ def get_links(self, iter):
+ """"""
+ links = []
+ model = self.treeview.get_model()
+ file_iter = model.iter_children(iter)
+ if not file_iter:
+ links.append(model.get_value(iter, 3))
+ while file_iter:
+ link_iter = model.iter_children(file_iter)
+ if not link_iter:
+ links.append(model.get_value(file_iter, 3))
+ while link_iter:
+ links.append(model.get_value(link_iter, 3))
+ link_iter = model.iter_next(link_iter)
+ file_iter = model.iter_next(file_iter)
+ return links
+
+ def package_files(self, package_iter):
+ """"""
+ files = []
+ model = self.treeview.get_model()
+ file_iter = model.iter_children(package_iter)
+ while file_iter:
+ if model.get_value(file_iter, 1) not in [cons.STATUS_ACTIVE, cons.STATUS_WAIT, cons.STATUS_CORRECT]:
+ files.append(model.get_value(file_iter, 3))
+ file_iter = model.iter_next(file_iter)
+ return files
+
+ def clear(self):
+ """"""
+ files = []
+ model = self.treeview.get_model()
+ package_iter = model.get_iter_root()
+ while package_iter:
+ tmp_iter = package_iter
+ package_iter = model.iter_next(package_iter)
+ files += self.delete_package([cons.STATUS_CORRECT], tmp_iter)
+ return files
+
+ def delete_package(self, status, package_iter):
+ """"""
+ tmp = []
+ model = self.treeview.get_model()
+ file_iter = model.iter_children(package_iter)
+ while file_iter:
+ if model.get_value(file_iter, 1) in status:
+ tmp.append(model.get_value(file_iter, 3))
+ file_iter = model.iter_next(file_iter)
+ if len(tmp) == model.iter_n_children(package_iter):
+ model.remove(package_iter)
+ else:
+ tmp = []
+ return tmp
+
+ def delete_file(self, status, iter):
+ """"""
+ model = self.treeview.get_model()
+ if model.get_value(iter, 1) in status:
+ if model.iter_n_children(model.iter_parent(iter)) > 1:
+ result = model.get_value(iter, 3)
+ model.remove(iter)
+ return result
+
+ def delete_link(self, status, iter):
+ """"""
+ result = None, None
+ model = self.treeview.get_model()
+ file_iter = model.iter_parent(iter)
+ if model.iter_n_children(file_iter) > 1:
+ if model.get_value(iter, 1) == cons.STATUS_STOP:
+ result = model.get_value(file_iter, 3), model.get_value(iter, 3)
+ model.remove(iter)
+ return result
+
+ def move_up(self, iter):
+ """"""
+ model = self.treeview.get_model()
+ package_iter = model.iter_parent(iter)
+ file_iter = model.iter_children(package_iter)
+ prev_iter = None
+ while ((file_iter) and (model.get_path(file_iter) != model.get_path(iter))):
+ prev_iter = file_iter
+ file_iter = model.iter_next(file_iter)
+ if prev_iter:
+ model.move_before(iter, prev_iter)
+ return True
+
+ def move_down(self, iter):
+ """"""
+ model = self.treeview.get_model()
+ next_iter = model.iter_next(iter)
+ if next_iter:
+ model.move_after(iter, next_iter)
+ return True
+
+ def calculate_time(self, time):
+ """"""
+ result = None
+ hours = 0
+ minutes = 0
+ while time >= cons.HOUR:
+ time = time - cons.HOUR
+ hours += 1
+ while time >= cons.MINUTE:
+ time = time - cons.MINUTE
+ minutes += 1
+ seconds = time
+ if hours > 0:
+ result = str(hours) + "h" + str(minutes) + "m" + str(seconds) + "s"
+ elif minutes > 0:
+ result = str(minutes) + "m" + str(seconds) + "s"
+ elif seconds > 0:
+ result = str(seconds) + "s"
+ return result
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/ui/gtk/update_manager.py /tmp/DgSymrsclJ/tucan-0.3.9/ui/gtk/update_manager.py
--- tucan-0.3.8/ui/gtk/update_manager.py 1970-01-01 01:00:00.000000000 +0100
+++ tucan-0.3.9/ui/gtk/update_manager.py 2009-10-07 00:02:28.000000000 +0100
@@ -0,0 +1,211 @@
+###############################################################################
+## Tucan Project
+##
+## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
+##
+## 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+import threading
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+from message import Message
+from core.service_update import ServiceUpdate
+
+import media
+import core.cons as cons
+
+class UpdateManager(gtk.Dialog, ServiceUpdate):
+ """"""
+ def __init__(self, parent, config, info=None):
+ """"""
+ gtk.Dialog.__init__(self)
+ ServiceUpdate.__init__(self, config)
+ self.set_transient_for(parent)
+ self.parent_widget = parent
+
+ self.installing = False
+ self.remote_info = info
+
+ self.set_icon_from_file(media.ICON_UPDATE)
+ self.set_title(("Update Manager"))
+ self.set_size_request(400,300)
+
+ # treeview
+ frame = gtk.Frame()
+ self.vbox.pack_start(frame)
+ frame.set_size_request(200, -1)
+ frame.set_border_width(10)
+ label = gtk.Label()
+ label.set_markup("%s " % ("Update Services"))
+ frame.set_label_widget(label)
+ scroll = gtk.ScrolledWindow()
+ frame.add(scroll)
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.treeview = gtk.TreeView(gtk.ListStore(gtk.gdk.Pixbuf, str, bool, str, gobject.TYPE_PYOBJECT))
+ scroll.add(self.treeview)
+
+ self.treeview.set_rules_hint(True)
+ self.treeview.set_headers_visible(False)
+
+ tree_icon = gtk.TreeViewColumn('Icon')
+ icon_cell = gtk.CellRendererPixbuf()
+ tree_icon.pack_start(icon_cell, True)
+ tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
+ tree_icon.set_property('min-width', 100)
+ self.treeview.append_column(tree_icon)
+
+ tree_name = gtk.TreeViewColumn('Name')
+ name_cell = gtk.CellRendererText()
+ tree_name.pack_start(name_cell, True)
+ tree_name.add_attribute(name_cell, 'text', 1)
+ tree_name.set_property('min-width', 200)
+ self.treeview.append_column(tree_name)
+
+ tree_add = gtk.TreeViewColumn('Add')
+ add_cell = gtk.CellRendererToggle()
+ add_cell.connect("toggled", self.toggled)
+ tree_add.pack_start(add_cell, True)
+ tree_add.add_attribute(add_cell, 'active', 2)
+ self.treeview.append_column(tree_add)
+
+ #status
+ hbox = gtk.HBox()
+ self.vbox.pack_start(hbox, False, False, 5)
+
+ self.status_icon = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
+ hbox.pack_start(self.status_icon, False, False, 10)
+ self.status_label = gtk.Label("Checking for updates.")
+ hbox.pack_start(self.status_label, False, False, 5)
+ self.progress = gtk.ProgressBar()
+ hbox.pack_start(self.progress, True, True, 20)
+
+ #action area
+ cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
+ add_button = gtk.Button(None, gtk.STOCK_ADD)
+ self.action_area.pack_start(cancel_button)
+ self.action_area.pack_start(add_button)
+ cancel_button.connect("clicked", self.close)
+ add_button.connect("clicked", self.install)
+
+ self.connect("response", self.close)
+ self.show_all()
+
+ self.progress.hide()
+
+ gobject.timeout_add(200, self.check_version)
+
+ self.run()
+
+ def check_version(self):
+ """"""
+ self.get_updates()
+ if self.remote_version == None:
+ message = "Update Manager can't connect to server.\nTry again later."
+ Message(self, cons.SEVERITY_ERROR, "Tucan Manager - Not available!", message)
+ gobject.idle_add(self.close)
+ elif self.remote_version.split(" ")[0] <= cons.TUCAN_VERSION.split(" ")[0]:
+ self.check_updates()
+ else:
+ message = "Version %s released!\nPlease update and enjoy new services." % self.server_version
+ Message(self, cons.SEVERITY_ERROR, "Tucan Manager - Outdated!", message)
+ gobject.idle_add(self.close)
+
+ def toggled(self, button, path):
+ """"""
+ model = self.treeview.get_model()
+ active = True
+ if button.get_active():
+ active = False
+ button.set_active(active)
+ model.set_value(model.get_iter(path), 2, active)
+
+ def check_updates(self):
+ """"""
+ model = self.treeview.get_model()
+ default_icon = gtk.gdk.pixbuf_new_from_file_at_size(media.ICON_UPDATE, 32, 32)
+
+ updated = 0
+ new = 0
+ for service, options in self.updates.items():
+ if options[2]:
+ icon = gtk.gdk.pixbuf_new_from_file_at_size(options[2], 32, 32)
+ updated += 1
+ else:
+ icon = default_icon
+ new += 1
+ if model:
+ model.append([icon, service, False, options[0], options[1]])
+
+ self.status_icon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_BUTTON)
+ self.status_label.set_label("%i New and %i Updated." % (new, updated))
+ if updated == 0 and new == 0:
+ gobject.timeout_add(5000, self.close)
+
+ def install(self, button):
+ """"""
+ self.progress.show()
+ self.status_icon.set_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_MENU)
+ self.status_label.set_label("Installing")
+ self.action_area.set_sensitive(False)
+ th = threading.Thread(group=None, target=self.install_all, name=None)
+ th.start()
+
+ def install_all(self):
+ """"""
+ self.installing = True
+ model = self.treeview.get_model()
+
+ install_targets = []
+ update_iter = model.get_iter_root()
+ while update_iter:
+ if model.get_value(update_iter, 2):
+ install_targets.append(model.get(update_iter, 1, 3, 4))
+ update_iter = model.iter_next(update_iter)
+ if len(install_targets) > 0:
+ cont = 0
+ self.progress.set_text("%i of %i" % (cont, len(install_targets)))
+ for service_name, service_dir, archive in install_targets:
+ if self.install_service(service_name, service_dir, archive):
+ cont += 1
+ self.progress.set_fraction(float(cont)/len(install_targets))
+ self.progress.set_text("%i of %i" % (cont, len(install_targets)))
+ if cont != len(install_targets):
+ message = "Problem updating some services \nTry again later."
+ else:
+ message = "Save your configuration and restart Tucan \nto apply service changes."
+ gobject.idle_add(self.restart, message)
+ self.installing = False
+ gobject.idle_add(self.close)
+ else:
+ self.installing = False
+ gobject.idle_add(self.close)
+
+ def restart(self, message):
+ """"""
+ Message(self.parent_widget, cons.SEVERITY_WARNING, "Tucan Manager - Restart Needed.", message)
+
+ def close(self, widget=None, other=None):
+ """"""
+ if not self.installing:
+ self.destroy()
+
+if __name__ == "__main__":
+ from config import Config
+ x = UpdateManager(None, Config(), None)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/update_manager.py /tmp/DgSymrsclJ/tucan-0.3.9/update_manager.py
--- tucan-0.3.8/update_manager.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/update_manager.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,189 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-from service_update import ServiceUpdate
-from message import Message
-
-import cons
-
-class UpdateManager(gtk.Dialog, ServiceUpdate):
- """"""
- def __init__(self, config, parent, updates=None):
- """"""
- gtk.Dialog.__init__(self)
- ServiceUpdate.__init__(self, config)
- self.set_transient_for(parent)
-
- self.set_icon_from_file(cons.ICON_UPDATE)
- self.set_title(("Update Manager"))
- self.set_size_request(400,300)
-
- # treeview
- frame = gtk.Frame()
- self.vbox.pack_start(frame)
- frame.set_size_request(200, -1)
- frame.set_border_width(10)
- label = gtk.Label()
- label.set_markup("%s " % ("Update Services"))
- frame.set_label_widget(label)
- scroll = gtk.ScrolledWindow()
- frame.add(scroll)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.treeview = gtk.TreeView(gtk.ListStore(gtk.gdk.Pixbuf, str, bool, str, gobject.TYPE_PYOBJECT))
- scroll.add(self.treeview)
-
- self.treeview.set_rules_hint(True)
- self.treeview.set_headers_visible(False)
-
- tree_icon = gtk.TreeViewColumn('Icon')
- icon_cell = gtk.CellRendererPixbuf()
- tree_icon.pack_start(icon_cell, True)
- tree_icon.add_attribute(icon_cell, 'pixbuf', 0)
- tree_icon.set_property('min-width', 100)
- self.treeview.append_column(tree_icon)
-
- tree_name = gtk.TreeViewColumn('Name')
- name_cell = gtk.CellRendererText()
- tree_name.pack_start(name_cell, True)
- tree_name.add_attribute(name_cell, 'text', 1)
- tree_name.set_property('min-width', 200)
- self.treeview.append_column(tree_name)
-
- tree_add = gtk.TreeViewColumn('Add')
- add_cell = gtk.CellRendererToggle()
- add_cell.connect("toggled", self.toggled)
- tree_add.pack_start(add_cell, True)
- tree_add.add_attribute(add_cell, 'active', 2)
- self.treeview.append_column(tree_add)
-
- #status
- hbox = gtk.HBox()
- self.vbox.pack_start(hbox, False, False, 5)
-
- self.status_icon = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
- hbox.pack_start(self.status_icon, False, False, 10)
- self.status_label = gtk.Label("Checking for updates.")
- hbox.pack_start(self.status_label, False, False, 5)
- self.progress = gtk.ProgressBar()
- hbox.pack_start(self.progress, True, True, 20)
-
- #action area
- cancel_button = gtk.Button(None, gtk.STOCK_CANCEL)
- add_button = gtk.Button(None, gtk.STOCK_ADD)
- self.action_area.pack_start(cancel_button)
- self.action_area.pack_start(add_button)
- cancel_button.connect("clicked", self.close)
- add_button.connect("clicked", self.install)
-
- self.connect("response", self.close)
- self.show_all()
-
- self.progress.hide()
-
- if self.server_version.split(" ")[0] <= cons.TUCAN_VERSION.split(" ")[0]:
- gobject.timeout_add(1000, self.check_updates, updates)
- elif self.server_version == None:
- message = "Update Manager can't connect to server.\nTry again later."
- Message(self, cons.SEVERITY_ERROR, "Tucan Manager - Not available!", message)
- gobject.idle_add(self.close)
- else:
- message = "Version %s released!\nPlease update and enjoy new services." % self.server_version
- Message(self, cons.SEVERITY_ERROR, "Tucan Manager - Outdated!", message)
- gobject.idle_add(self.close)
- self.run()
-
- def toggled(self, button, path):
- """"""
- model = self.treeview.get_model()
- active = True
- if button.get_active():
- active = False
- button.set_active(active)
- model.set_value(model.get_iter(path), 2, active)
-
- def check_updates(self, updates=None):
- """"""
- model = self.treeview.get_model()
- default_icon = gtk.gdk.pixbuf_new_from_file_at_size(cons.ICON_UPDATE, 32, 32)
-
- updated = 0
- new = 0
- if not updates:
- updates = self.get_updates()
- for service, options in updates.items():
- if options[2]:
- icon = gtk.gdk.pixbuf_new_from_file_at_size(options[2], 32, 32)
- updated += 1
- else:
- icon = default_icon
- new += 1
- if model:
- model.append([icon, service, False, options[0], options[1]])
-
- self.status_icon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_BUTTON)
- self.status_label.set_label("%i New and %i Updated." % (new, updated))
- if updated == 0 and new == 0:
- gobject.timeout_add(5000, self.close)
-
- def install(self, button):
- """"""
- model = self.treeview.get_model()
-
- self.status_icon.set_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_MENU)
- self.status_label.set_label("Installing")
- self.progress.show()
-
- install_targets = []
- update_iter = model.get_iter_root()
- while update_iter:
- if model.get_value(update_iter, 2):
- install_targets.append(model.get(update_iter, 1, 3, 4))
- update_iter = model.iter_next(update_iter)
- if len(install_targets) > 0:
- self.progress.grab_add()
- cont = 0.0
- for service_name, service_dir, file_list in install_targets:
- self.progress.set_text("%i of %i" % (int(cont), len(install_targets)))
- #unfreezes widget
- while gtk.events_pending():
- gtk.main_iteration_do(False)
- self.install_service(service_name, service_dir, file_list)
- cont += 1
- self.progress.set_fraction(cont/len(install_targets))
- self.progress.set_text("%i of %i" % (int(cont), len(install_targets)))
- self.hide()
- message = "Save your configuration and restart Tucan \nto apply service changes."
- Message(self, cons.SEVERITY_WARNING, "Tucan Manager - Restart Needed.", message)
- self.close()
- else:
- self.close()
-
- def close(self, widget=None, other=None):
- """"""
- self.destroy()
-
-if __name__ == "__main__":
- from config import Config
- x = UpdateManager(Config(), None)
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/uploader.py /tmp/DgSymrsclJ/tucan-0.3.9/uploader.py
--- tucan-0.3.8/uploader.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/uploader.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,42 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-"""
-import MultipartPostHandler, urllib2, cookielib
-
-cookies = cookielib.CookieJar()
-opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler.MultipartPostHandler)
-params = { "username" : "bob", "password" : "riviera", "file" : open("filename", "rb") }
-opener.open("http://wwww.bobsite.com/upload/", params)
-"""
-
-import urllib
-import urllib2
-
-from HTMLParser import HTMLParser
-
-class Uploader(HTMLParser):
- """"""
- def __init__(self, file_name):
- """"""
- HTMLParser.__init__(self)
-
-if __name__ == "__main__":
- c = Uploader("/home/crak/mierda.html")
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/url_open.py /tmp/DgSymrsclJ/tucan-0.3.9/url_open.py
--- tucan-0.3.8/url_open.py 2009-07-15 01:15:18.000000000 +0100
+++ tucan-0.3.9/url_open.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-###############################################################################
-## Tucan Project
-##
-## Copyright (C) 2008-2009 Fran Lupion crak@tucaneando.com
-##
-## 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, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-###############################################################################
-
-import __builtin__
-
-import urllib2
-import logging
-logger = logging.getLogger(__name__)
-
-import socket
-
-import cons
-
-def set_proxy(url, port=0):
- """"""
- if url:
- PROXY = {"http": "%s:%i" % (url, port)}
- socket.setdefaulttimeout(60)
- logger.info("Using proxy: %s:%i" % (url, port))
- else:
- PROXY = None
- socket.setdefaulttimeout(120)
- logger.info("Proxy Disabled.")
- __builtin__.PROXY = PROXY
-
-class URLOpen:
- """"""
- def __init__(self, cookie=None):
- """"""
- if PROXY:
- self.opener = urllib2.build_opener(urllib2.ProxyHandler(PROXY), urllib2.HTTPCookieProcessor(cookie))
- else:
- self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
-
- def open(self, url, form=None):
- """"""
- if form:
- return self.opener.open(urllib2.Request(url, None, cons.USER_AGENT), form)
- else:
- return self.opener.open(urllib2.Request(url, None, cons.USER_AGENT))
-
-if __name__ == "__main__":
- PROXY = {"http": "proxy.alu.uma.es:3128"}
- o = URLOpen()
- print o.open("http://www.google.com").read()
diff -Nru /tmp/Mj7pJvsoYS/tucan-0.3.8/VERSION /tmp/DgSymrsclJ/tucan-0.3.9/VERSION
--- tucan-0.3.8/VERSION 2009-07-15 01:15:19.000000000 +0100
+++ tucan-0.3.9/VERSION 2009-10-07 00:02:33.000000000 +0100
@@ -1,2 +1,2 @@
-0.3.8
-rev 992
+0.3.9
+rev 1251