--- /dev/null
+from Screens.Screen import Screen
+from Components.Sources.List import List
+from Components.Button import Button
+from Components.Label import Label
+from Components.ActionMap import ActionMap
+from Screens.InputBox import InputBox
+from Components.Input import Input
+from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
+from Components.Pixmap import Pixmap
+from Components.AVSwitch import AVSwitch
+from Tools.BoundFunction import boundFunction
+
+from enigma import eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_HALIGN_RIGHT,ePicLoad,eTimer
+
+from PictureScreen import PictureScreen
+
+from twisted.web.client import getPage,downloadPage
+#from twisted.internet import reactor
+
+from xml.etree.cElementTree import fromstring as cElementTree_fromstring
+
+from os import remove as os_remove
+from os.path import exists as os_path_exists
+from datetime import datetime
+
+from urllib import quote as urllib_quote
+#########################################
+
+class TravelWebcamviewer(Screen):
+ skin = ""
+ def __init__(self, session, args = 0):
+ skin = """<screen position="93,70" size="550,450" title="Webcams provided by webcams.travel">
+
+ <widget source="list" render="Listbox" position="0,0" size="550,350" zPosition="1" scrollbarMode="showOnDemand" transparent="1" >
+ <convert type="TemplatedMultiContent">
+ {"templates":
+ {"default": (77,[
+ MultiContentEntryPixmapAlphaTest(pos = (0, 0), size = (100, 75), png = 4), # index 4 is the thumbnail
+ MultiContentEntryText(pos = (100, 1), size = (500, 22), font=0, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # index 1 is the Title
+ MultiContentEntryText(pos = (100, 24), size = (300, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 5), # index 5 is the Published Date
+ MultiContentEntryText(pos = (100, 43), size = (300, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 6), # index 6 is the Views Count
+ MultiContentEntryText(pos = (400, 24), size = (200, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 7), # index 7 is the duration
+ MultiContentEntryText(pos = (400, 43), size = (200, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 8), # index 8 is the ratingcount
+ ]),
+ "status": (77,[
+ MultiContentEntryText(pos = (10, 1), size = (500, 28), font=2, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 0), # index 0 is the name
+ MultiContentEntryText(pos = (10, 22), size = (500, 46), font=3, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # index 2 is the description
+ ])
+ },
+ "fonts": [gFont("Regular", 22),gFont("Regular", 18),gFont("Regular", 26),gFont("Regular", 20)],
+ "itemHeight": 77
+ }
+ </convert>
+ </widget>
+ <widget name="thumbnail" position="0,0" size="100,75" alphatest="on"/> # fake entry for dynamic thumbnail resizing, currently there is no other way doing this.
+
+ <widget name="count" position="5,360" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="page" position="150,360" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="currentnumbers" position="295,360" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+
+ <ePixmap position="5,410" zPosition="0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+ <ePixmap position="150,410" zPosition="1" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+ <ePixmap position="295,410" zPosition="2" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+ <!-- #not used now# ePixmap position="445,410" zPosition="3" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" //-->
+ <widget name="key_red" position="5,410" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_green" position="150,410" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_yellow" position="295,410" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_blue" position="445,410" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+
+ </screen>"""
+ self.skin = skin
+ Screen.__init__(self, session)
+ self.picloads = {}
+ self.thumbnails = {}
+
+ self["list"] = List([])
+ self["thumbnail"] = Pixmap()
+ self["thumbnail"].hide()
+
+ self["count"] = Label(_("Cams: "))
+ self["page"] = Label(_("Page: "))
+ self["currentnumbers"] = Label(_("current: "))
+
+
+ self["key_red"] = Button(_("prev"))
+ self["key_red"].hide()
+ self["key_green"] = Button(_("next"))
+ self["key_green"].hide()
+ self["key_yellow"] = Button(_("search"))
+ self["key_blue"] = Button(_("hdkfjhg"))
+
+ self["key_blue"].hide() #not used at the moment
+
+ self["actions"] = ActionMap(["WizardActions", "MenuActions", "DirectionActions", "ShortcutActions"],
+ {
+ "ok": self.onOK,
+ "red": self.onRed,
+ "green": self.onGreen,
+ "yellow": self.onYellow,
+ "back": self.close
+ }, -1)
+
+ self.timer_default = eTimer()
+ self.timer_default.timeout.callback.append(self.buildCamList)
+
+ self.timer_status = eTimer()
+ self.timer_status.timeout.callback.append(self.buildStatusList)
+
+ self.timer_labels = eTimer()
+ self.timer_labels.timeout.callback.append(self.refreshLabels)
+
+ self.onLayoutFinish.append(self.loadData)
+
+ def onOK(self):
+ selection = self["list"].getCurrent()
+ if selection:
+ print selection
+ self.session.open(PictureScreen,selection[0].title,selection[0].pic_url)
+
+ def onRed(self):
+ if self.hasPrevPage():
+ self.timer_status.start(1)
+ WebcamTravelerAPI().list_popular(self.onDataLoaded,_page=self.page-1)
+
+ def onGreen(self):
+ if self.hasNextPage():
+ self.timer_status.start(1)
+ WebcamTravelerAPI().list_popular(self.onDataLoaded,_page=self.page+1)
+
+ def onYellow(self):
+ self.session.openWithCallback(self.onSearchkeyEntered,InputBox, title=_("Please enter a searchkey:"), text="Search Webcams", maxSize=False, type=Input.TEXT)
+
+ def onSearchkeyEntered(self,value):
+ if value is not None:
+ self.timer_status.start(1)
+ WebcamTravelerAPI().search(self.onDataLoaded,value)
+
+ def loadData(self):
+ self.timer_status.start(1)
+ WebcamTravelerAPI().list_popular(self.onDataLoaded)
+
+ def onDataLoaded(self,list,count=0,page=0,per_page=0):
+ print "onDataLoaded",list,count,page,per_page
+ self.count =count
+ self.page = page
+ self.per_page = per_page
+
+ self.pixmaps_to_load = []
+ self.picloads = {}
+ self.thumbnails = {}
+ self.list = list
+ self.downloadThumbnails()
+
+ def downloadThumbnails(self):
+ for cam in self.list:
+ self.pixmaps_to_load.append(cam.webcamid)
+ downloadPage(cam.thumbnail_url,"/tmp/"+str(cam.webcamid)+"_thumb.jpg").addCallback(self.fetchFinished,cam.webcamid).addErrback(self.fetchFailed,cam.webcamid)
+
+ def fetchFailed(self,string,webcamid):
+ print "fetchFailed",webcamid,string.getErrorMessage()
+ self.buildEntryStatus(string.getErrorMessage())
+ self.pixmaps_to_load.remove(webcamid)
+
+ def fetchFinished(self,x,webcamid):
+ print "fetchFinished",x,webcamid
+ self.pixmaps_to_load.remove(webcamid)
+
+ sc = AVSwitch().getFramebufferScale()
+ if (os_path_exists("/tmp/"+str(webcamid)+"_thumb.jpg") == True):
+ self.picloads[webcamid] = ePicLoad()
+ self.picloads[webcamid].PictureData.get().append(boundFunction(self.finish_decode, webcamid))
+ self.picloads[webcamid].setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
+ self.picloads[webcamid].startDecode("/tmp/"+str(webcamid)+"_thumb.jpg")
+ else:
+ print "[decodePic] Thumbnail file NOT FOUND !!!-->:",thumbnailFile
+
+ def finish_decode(self,webcamid,info):
+ print "finish_decode - of webcamid", webcamid,info
+ ptr = self.picloads[webcamid].getData()
+ if ptr != None:
+ self.thumbnails[webcamid] = ptr
+ print "removing file"
+ os_remove("/tmp/"+str(webcamid)+"_thumb.jpg")
+ del self.picloads[webcamid]
+ self.timer_default.start(1)
+
+
+
+ def buildStatusList(self):
+ self.timer_status.stop()
+ print "buildStatusList"
+ statuslist = []
+ statuslist.append(self.buildEntryStatus("loading data"))
+
+ self["list"].style = "status"
+ self["list"].disable_callbacks = True
+ self["list"].list = statuslist
+ self["list"].disable_callbacks = False
+ self["list"].setIndex(0)
+ self["list"].setList(statuslist)
+ self["list"].updateList(statuslist)
+
+
+ def buildCamList(self):
+ if len(self.picloads) != 0:
+ return
+ self.timer_default.stop()
+ print "buildCamList"
+ statuslist = []
+ for cam in self.list:
+ x= self.buildEntryCam(cam)
+ statuslist.append(x)
+
+ self["list"].style = "default"
+ self["list"].disable_callbacks = True
+ self["list"].list = statuslist
+ self["list"].disable_callbacks = False
+ self["list"].setIndex(0)
+ self["list"].setList(statuslist)
+ self["list"].updateList(statuslist)
+ self.timer_labels.start(1)
+
+ def refreshLabels(self):
+ self.timer_labels.stop()
+ if self.hasNextPage():
+ self["key_green"].show()
+ else:
+ self["key_green"].hide()
+
+ if self.hasPrevPage():
+ self["key_red"].show()
+ else:
+ self["key_red"].hide()
+ self["count"].setText(_("Cams: ")+str(self.count))
+ self["page"].setText(_("Page: ")+str(self.page)+"/"+str(self.count/self.per_page))
+ self["currentnumbers"].setText(_("current: ")+str(((self.page-1)*self.per_page)+1)+"-"+str(((self.page-1)*self.per_page)+len(self.list)))
+
+ def buildEntryCam(self, cam):
+ return ((cam, cam.title, cam.webcamid,"last update",self.thumbnails[cam.webcamid], _("Last updated: ")+cam.last_update, _("Views: ")+cam.view_count, _("User: ")+cam.user, _("Ratings: ")+cam.rating_avg ))
+
+ def buildEntryStatus(self, text):
+ return (("loading ...", "please wait just a moment","cccccccccccc","last update","1111111111111", _("Last updated: "), _("Views: "), _("Duration: ") , _("Ratings: ") ))
+
+ def hasNextPage(self):
+ if (self.per_page*(self.page+1)>self.count):
+ return False
+ else:
+ return True
+
+ def hasPrevPage(self):
+ if (self.page>1):
+ return True
+ else:
+ return False
+
+
+#########################################
+
+
+
+#########################################
+# API ###################################
+#########################################
+#########################################
+#########################################
+
+class WebcamTravelerAPI:
+ APIKEY="e1019c6811f593a7cca1cf4f536da4c7"
+ URL_HOST = "api.webcams.travel"
+ URL_FORMAT = "rest"
+
+ def get(self,method,callback,errorback,**kwargs):
+ url = "http://"+self.URL_HOST+"/"+self.URL_FORMAT+"?method="+method+"&devid="+self.APIKEY
+ for key in kwargs:
+ print key,kwargs[key]
+ url +="&"+str(key)+"="+str(kwargs[key])
+ print url
+ cb = getPage(url).addCallback(callback)
+ if errorback!=None:
+ cb.addErrback(errorback)
+ else:
+ cb.addErrback(self.loadingFailed)
+
+ def loadingFailed(self,reason):
+ print "loadingFailed",reason
+
+ def list_popular(self,callback,_page=1,_per_page=30):
+ """ wct.webcams.list_popular
+ Get the popular webcams.
+
+ devid (required)
+ Your developer ID. If you do not have one, please signup for a developer ID.
+ per_page (optional)
+ Number of webcams to return per page. If this argument is omitted, it defaults to 10. The maximum allowed value is 50.
+ page (optional)
+ The page of results to return. If this argument is omitted, it defaults to 1.
+ """
+ cb = lambda raw: self.list_popularCB(raw,callback)
+ self.get("wct.webcams.list_popular",cb,None,page=_page,per_page=_per_page)
+
+ def list_popularCB(self,raw,callback):
+ dom = cElementTree_fromstring(raw)
+ list, _count, _page, _per_page = self.parseWebcam(dom)
+ callback(list,count=_count,page=_page,per_page=_per_page)
+
+ def parseWebcam(self,dom):
+ cams= dom.findall("webcams")
+ _count = int(cams[0].findtext("count", 0))
+ _page = int(cams[0].findtext("page", 0))
+ _per_page = int(cams[0].findtext("per_page", 0))
+ list = []
+ for cam in cams[0].findall("webcam"):
+ ca = Cam(cam)
+ list.append(ca)
+ return list,_count, _page, _per_page
+
+ def search(self,callback,searchkey,_page=1,_per_page=30):
+ """wct.search.webcams
+
+ Search the webcams by the given query.
+
+
+ Arguments
+
+ devid (required)
+ Your developer ID. If you do not have one, please signup for a developer ID.
+ query (required)
+ The query to search for.
+ per_page (optional)
+ Number of comments to return per page. If this argument is omitted, it defaults to 10. The maximum allowed value is 50.
+ page (optional)
+ The page of results to return. If this argument is omitted, it defaults to 1.
+ """
+ cb = lambda raw: self.searchCB(raw,callback)
+ self.get("wct.search.webcams",cb,None,query=urllib_quote(searchkey),page=_page,per_page=_per_page)
+
+ def searchCB(self,raw,callback):
+ dom = cElementTree_fromstring(raw)
+ list, _count, _page, _per_page = self.parseWebcam(dom)
+ callback(list,count=_count,page=_page,per_page=_per_page)
+
+
+class Cam:
+ def __init__(self,element):
+ self.title = element.findtext("title", 0).encode('utf-8',"ignore")
+ self.webcamid = int(element.findtext("webcamid", 0))
+ self.pic_url = "http://images.webcams.travel/webcam/"+str(self.webcamid)+".jpg"
+ #self.icon_url = element.findtext("icon_url", 0)
+ self.thumbnail_url = element.findtext("thumbnail_url", 0)
+ self.view_count = element.findtext("view_count", 0)
+ self.user = element.findtext("user", 0)
+ self.userid = element.findtext("userid", 0)
+ self.rating_avg = element.findtext("rating_avg", 0)
+ self.rating_count = element.findtext("rating_count", 0)
+ self.city = element.findtext("city", 0)
+ self.country = element.findtext("country", 0)
+ self.continent = element.findtext("continent", 0)
+ self.latitude = element.findtext("latitude", 0)
+ self.longitude = element.findtext("longitude", 0)
+
+ datex = datetime.fromtimestamp(int(element.findtext("last_update", 0)))
+ self.last_update = datex.strftime("%d.%m.%Y %H:%M:%S")
+
+
+
+