1 from enigma import loadPic
2 from enigma import eTimer
3 from enigma import getDesktop
5 from Screens.Screen import Screen
6 from Components.AVSwitch import AVSwitch
7 from Components.config import config
8 from Components.Pixmap import Pixmap
9 from Components.ActionMap import ActionMap
11 from FTPDownloader import FTPDownloader
12 from twisted.web.client import HTTPDownloader
13 from twisted.internet import reactor
14 from urlparse import urlparse, urlunparse
16 def _parse(url, defaultPort = None):
18 parsed = urlparse(url)
20 path = urlunparse(('','')+parsed[2:])
22 if defaultPort is None:
30 host, port = parsed[1], defaultPort
33 username, host = host.split('@')
35 username, password = username.split(':')
43 host, port = host.split(':')
49 return scheme, host, port, path, username, password
51 def download(url, file, contextFactory = None, *args, **kwargs):
53 """Download a remote file from http(s) or ftp.
55 @param file: path to file on filesystem, or file-like object.
57 See HTTPDownloader to see what extra args can be passed if remote file
58 is accessible via http or https. Both Backends should offer supportPartial.
60 scheme, host, port, path, username, password = _parse(url)
63 if not (username and password):
64 username = 'anonymous'
65 password = 'my@email.com'
67 client = FTPDownloader(
77 return client.deferred
79 # We force username and password here as we lack a satisfying input method
80 if username and password:
81 from base64 import encodestring
83 # twisted will crash if we don't rewrite this ;-)
84 url = scheme + '://' + host + ':' + str(port) + path
86 basicAuth = encodestring("%s:%s" % (username, password))
87 authHeader = "Basic " + basicAuth.strip()
88 AuthHeaders = {"Authorization": authHeader}
90 if kwargs.has_key("headers"):
91 kwargs["headers"].update(AuthHeaders)
93 kwargs["headers"] = AuthHeaders
95 factory = HTTPDownloader(url, file, *args, **kwargs)
97 from twisted.internet import ssl
98 if contextFactory is None:
99 contextFactory = ssl.ClientContextFactory()
100 reactor.connectSSL(host, port, factory, contextFactory)
102 reactor.connectTCP(host, port, factory)
104 return factory.deferred
106 class PictureScreen(Screen):
108 prozessing =False # if fetching or converting is active
110 def __init__(self, session,title,filename, slideshowcallback = None,args=0):
111 self.slideshowcallback=slideshowcallback
112 self.screentitle = title
114 size_w = getDesktop(0).size().width()
115 size_h = getDesktop(0).size().height()
117 <screen position="0,0" size="%i,%i" title="%s" flags=\"wfNoBorder\">
118 <widget name="pixmap" position="0,0" size="%i,%i" backgroundColor=\"black\"/>
119 </screen>""" % (size_w,size_h,filename,size_w,size_h)
120 Screen.__init__(self, session)
121 self.filename = filename
122 self["pixmap"] = Pixmap()
124 self["actions"] = ActionMap(["WizardActions", "DirectionActions","ChannelSelectBaseActions","ShortcutActions"],
128 "green":self.AutoReloaderSwitch,
131 self.onLayoutFinish.append(self.do)
133 def AutoReloaderSwitch(self):
134 if self.filename.startswith("http") or self.filename.startswith("ftp"):
135 if self.autoreload is False:
136 self.autoreload = True
139 self.autoreload = False
144 elif self.filename.startswith("http") or self.filename.startswith("ftp"):
145 self.fetchFile(self.filename)
147 self.sourcefile = self.filename
148 self.setPicture(self.filename)
156 if os.path.exists("/tmp/loadedfile"):
157 os.remove("/tmp/loadedfile")
161 def fetchFile(self,url):
162 self.prozessing =True
163 self.setTitle("loading File")
164 print "fetching URL ",url
165 self.sourcefile = "/tmp/loadedfile"
166 download(url,self.sourcefile).addCallback(self.fetchFinished).addErrback(self.fetchFailed)
168 def fetchFailed(self,string):
169 print "fetch failed",string
170 self.setTitle( "fetch failed: "+string)
172 def fetchFinished(self,string):
173 print "fetching finished "
174 self.setPicture(self.sourcefile)
176 def setPicture(self,string):
177 self.setTitle(self.filename.split("/")[-1])
178 pixmap = loadPic(string,getDesktop(0).size().width(),getDesktop(0).size().height(), AVSwitch().getAspectRatioSetting()/2,1, 0,1)
179 if pixmap is not None:
180 self["pixmap"].instance.setPixmap(pixmap)
181 self.prozessing =False
183 if self.autoreload is True:
186 elif self.slideshowcallback is not None:
187 self.closetimer = eTimer()
188 self.closetimer.timeout.get().append(self.slideshowcallback)
189 print "waiting ",config.plugins.pictureviewer.slideshowtime.value," seconds for next picture"
190 self.closetimer.start(int(config.plugins.pictureviewer.slideshowtime.value))