1.4.2: Changes from Enigma integrated:
[enigma2-plugins.git] / trafficinfo / src / plugin.py
1 # by 3c5x9@2007
2 from enigma import eTimer, getDesktop
3 from Screens.Screen import Screen
4 from Components.ActionMap import ActionMap
5 from Components.Label import Label
6 from Components.MenuList import MenuList
7
8 from Components.MultiContent import MultiContentEntryText
9 from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT, RT_WRAP
10
11 from Plugins.Plugin import PluginDescriptor
12 import xml.dom.minidom
13
14 from twisted.web.client import getPage
15 from twisted.internet import reactor
16
17 ###############################################################################        
18 class TrafficInfoMain(Screen):
19     skin_SD = """
20         <screen position="110,83" size="530,430" title="Verkehrsinfo" >                        
21             <widget name="sectionlist" position="0,0" size="530,125" scrollbarMode="showOnDemand" />            
22             <widget name="itemlist" position="0,130" size="530,125" scrollbarMode="showOnDemand" />            
23             <widget name="itemdetails" position="0,260" size="530,140" font="Regular;20" halign=\"center\" valign=\"center\"/>            
24             <widget name="statuslabel" position="0,400" size="530,30" halign=\"left\"/>           
25         </screen>
26         """
27     skin_HD = """
28         <screen name="TrafficInfo" position="center,60" size="1030,600" title="Verkehrsinformation">
29             <widget name="sectionlist" position="100,0" size="830,205" scrollbarMode="showOnDemand" />
30             <widget name="itemlist" position="100,215" size="830,275" scrollbarMode="showOnDemand" />
31             <widget name="itemdetails" position="10,495" size="1010,90" font="Regular;20" halign="left" valign="center" />
32             <widget name="statuslabel" position="0,587" size="730,13" halign="left" />
33         </screen>
34         """
35     def __init__(self, session,args = 0):
36         self.loadinginprogress = False
37         self.session = session
38         desktop = getDesktop(0)
39         size = desktop.size()
40         width = size.width()
41         if width < 1280:
42             self.skin = TrafficInfoMain.skin_SD
43         else:
44             self.skin = TrafficInfoMain.skin_HD
45         Screen.__init__(self, session)
46         self.menu = args
47         self["sectionlist"] = MenuList([])
48         self["itemlist"] = ItemList([])
49         self["statuslabel"] = Label("")
50         self["itemdetails"] = Label("")
51         self["actions"] = ActionMap(["ChannelSelectBaseActions","WizardActions", "DirectionActions","MenuActions","NumberActions"], 
52             {
53              "ok":                  self.go,
54              "back":            self.exit,
55              "nextBouquet":     self.selectSectionlist,
56              "prevBouquet":     self.selectItemlist,
57              "down":            self.down,
58              "up":                  self.up,
59              "left":            self.left,
60              "right":           self.right,
61              }, -1)
62         self.statuslabelcleartimer = eTimer()
63         self.statuslabelcleartimer.timeout.get().append(self.clearStatusLabel)
64         
65         self["itemlist"].onSelectionChanged.append(self.onItemSelected)
66         self.selectSectionlist()
67         
68         self.onShown.append(self.getSections)
69         
70     def exit(self):
71         if self.loadinginprogress:
72             reactor.callLater(1,self.exit)
73         else:
74             self.close()
75
76     def selectSectionlist(self):
77         self.currList = "sectionlist"
78         self["sectionlist"].selectionEnabled(1)
79         self["itemlist"].selectionEnabled(0)
80         
81     def selectItemlist(self):
82         self.currList = "itemlist"
83         self["sectionlist"].selectionEnabled(0)
84         self["itemlist"].selectionEnabled(1)
85         self["itemlist"].selectionChanged()
86         
87     def go(self):
88         if self.currList == "sectionlist":
89             self.onSectionSelected()
90
91     def up(self):
92         self[self.currList].up()
93     
94     def down(self):
95         self[self.currList].down()
96         
97     def left(self):
98         self[self.currList].pageUp()
99     
100     def right(self):
101         self[self.currList].pageDown()
102         
103     def onSectionSelected(self):
104         c = self["sectionlist"].getCurrent()
105         if c is not None:
106             self.setTitle("Verkehrsinfo: "+c[1].name)
107             self.getItemsOfSection(c[1])
108         
109     def onItemSelected(self):
110         if self["itemlist"].getCurrent() is not None:
111             c = self["itemlist"].getCurrent()[0]
112             if c is not None:
113                 self["itemdetails"].setText(c.text)
114             
115     ###########
116     def clearStatusLabel(self):
117         self["statuslabel"].setText("")
118         
119     def setStatusLabel(self,text):
120         self.statuslabelcleartimer.stop()         
121         self["statuslabel"].setText(text)
122         self.statuslabelcleartimer.start(3000)
123         
124     def getSections(self):
125         self.setStatusLabel("loading sections")
126         self.loadinginprogress = True    
127         getPage("http://wap.verkehrsinfo.de/wvindex.php3").addCallback(self.sectionsLoaded).addErrback(self.sectionsLoadingFaild)
128     
129     def sectionsLoadingFaild(self,raw):
130         self.loadinginprogress = False
131         self.setStatusLabel("loading sections failed"+raw)
132         
133     def sectionsLoaded(self,raw):
134         self.loadinginprogress = False
135         try:
136             xmldoc = xml.dom.minidom.parseString( raw)
137             self.sections = []
138             for i in xmldoc.getElementsByTagName("a"):
139                 link = "/"+i.getAttribute("href")
140                 name = i.toxml().split(">")[1].split("<")[0]
141                 self.sections.append(TrafficInfoSection(name,link))
142             self.onSectionsLoaded()
143         except xml.parsers.expat.ExpatError,e:
144             print e
145             print raw
146             self.setStatusLabel("loading sections failed")
147
148     def onSectionsLoaded(self):
149         self.setStatusLabel("sections loaded")
150         list = []
151         for i in self.sections:
152             if i.name.startswith("BRD") is not True:
153                 list.append((i.name,i))
154         list.sort()
155         self["sectionlist"].l.setList(list)
156         self["sectionlist"].instance.moveSelectionTo(0)
157
158     def onItemsLoaded(self):
159         list=[]
160         for item in self.trafficitems:
161             res = [ item ]
162             res.append(MultiContentEntryText(pos=(0, 0), size=(75, 20), font=0, flags = RT_HALIGN_LEFT|RT_WRAP, text = item.street))
163             res.append(MultiContentEntryText(pos=(75,0), size=(455, 20), font=1, flags = RT_HALIGN_LEFT, text = item.direction))
164             list.append(res)
165         self["itemlist"].l.setList(list)
166         self["itemlist"].instance.moveSelectionTo(0)
167         self.setStatusLabel("messages loaded")
168
169     ##########
170     def getItemsOfSection(self,section):
171         print "loading section",section.name  ,section.link
172         self.setStatusLabel("loading messages "+section.name)
173         self.loadinginprogress = True    
174         getPage("http://wap.verkehrsinfo.de"+section.link).addCallback(self.trafficitemsLoaded).addErrback(self.trafficitemsLoadingFaild)
175
176     def trafficitemsLoadingFaild(self,raw):
177         self.loadinginprogress = False
178         print "loading items faild",raw
179         self.setStatusLabel("loading messages faild"+raw)
180         
181     def trafficitemsLoaded(self,raw):
182         self.loadinginprogress = False
183         try:
184             raw = raw.replace("&amp","")
185             xmldoc = xml.dom.minidom.parseString( raw)
186             self.trafficitems = []
187             for item in  xmldoc.getElementsByTagName("p"):
188                 self.trafficitems.append(self.parseItem(item))
189             self.onItemsLoaded()
190         except xml.parsers.expat.ExpatError,e:
191             print e
192             print raw
193             self.setStatusLabel("loading messages faild! Parsing Error")
194         
195     def parseItem(self,item):
196         source=item.toxml()
197         i= item.getElementsByTagName("b")
198         source=source.replace(i[0].toxml(),"")
199         street = i[0].toxml().replace("<b>","").replace("</b>","").replace("\n","")
200         
201         source=source.replace(i[1].toxml(),"")
202         direction = i[1].toxml().replace("<b>","").replace("</b>","").replace("\n","")
203         details = source.replace("<p>","").replace("</p>","").replace("<small>","").replace("</small>","").replace("<br/>","").replace("\n","")
204         if street == "<b/>":
205             street = "Info"
206         return TrafficInfoItem(street,direction,details)
207
208 class ItemList(MenuList):
209     def __init__(self, items, enableWrapAround = False):
210         MenuList.__init__(self, items, enableWrapAround, eListboxPythonMultiContent)
211         self.l.setFont(0, gFont("Regular", 20))
212         self.l.setFont(1, gFont("Regular", 18))
213
214     def getCurrentEntry(self):
215         return self.l.getCurrentSelection()
216
217 ####################
218 class TrafficInfoSection:
219     def __init__(self, name,link):
220         self.name = name.encode("utf-8")
221         self.link = link.encode("utf-8")
222
223     def __str__(self):
224         return "name="+self.name+", link="+self.link
225
226 ####################
227 class TrafficInfoItem:
228     def __init__(self, street,direction,text):
229         self.street = street.encode("utf-8")
230         self.direction = direction.encode("utf-8")
231         self.text = text.encode("utf-8")
232
233     def __str__(self):
234         return "street="+self.street+", dir="+self.direction+", text="+self.text
235
236 #############################
237 def main(session, **kwargs):
238     session.open(TrafficInfoMain)
239
240 def Plugins(**kwargs):
241   return PluginDescriptor(name="Verkehrsinfo",description="Show German traffic jams",where = PluginDescriptor.WHERE_PLUGINMENU,fnc = main,icon="plugin.png")
242