c97373af24e95b916f6320d1b70d95be6efbf25a
[enigma2-curlytx.git] / src / CurlyTx.py
1 # -*- coding: utf-8 -*-
2 # CurlyTx main window
3 # Copyright (C) 2011 Christian Weiske <cweiske@cweiske.de>
4 # License: GPLv3 or later
5
6 from . import _
7
8 from Screens.Screen import Screen
9 from Screens.HelpMenu import HelpableScreen
10 from Screens.MessageBox import MessageBox
11 from Components.Label import Label
12 from Components.ScrollLabel import ScrollLabel
13 from Components.ActionMap import ActionMap
14 from Components.Sources.StaticText import StaticText
15 from twisted.web import client
16 from twisted.web.client import _makeGetterFactory, HTTPClientFactory
17 from enigma import gFont
18
19 from . import config
20 from Components.config import config
21
22 import os
23
24 class CurlyTx(Screen,HelpableScreen):
25     skin = """
26         <screen name="CurlyTx" position="center,center" size="560,430" title="CurlyTx" >
27           <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
28           <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
29           <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
30           <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
31           <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" />
32           <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" />
33           <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" />
34           <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" />
35           <widget name="text" position="5,45" size="550,380" font="Console;20" />
36         </screen>"""
37
38     currentUrl = None
39     currentPage = None
40     currentFontSize = 20
41     httpGetterFactory = None
42     showingHeaders = False
43
44     def __init__(self, session, args = None):
45         #self.skin = CurlyTx.skin
46         Screen.__init__(self, session)
47         HelpableScreen.__init__(self)
48         #self.skinName = [ "CurlyTx", "Setup" ]
49
50         self["text"] = ScrollLabel("foo")
51
52         self["key_red"]    = StaticText(_("Settings"))
53         self["key_green"]  = StaticText(_("Reload"))
54         self["key_yellow"] = StaticText(_("Prev"))
55         self["key_blue"]   = StaticText(_("Next"))
56
57
58         self["actions"] = ActionMap(
59             ["WizardActions", "ColorActions", "InputActions", "InfobarEPGActions"], {
60                 "ok":   self.close,
61                 "back": self.close,
62                 "up":   self.pageUp,
63                 "down": self.pageDown,
64
65                 "red":    self.showSettings,
66                 "green":  self.reload,
67                 "yellow": self.prevPage,
68                 "blue":   self.nextPage,
69
70                 "showEventInfo": self.showHeader
71             }, -1)
72
73         self.loadHelp()
74         self.loadButtons()
75         self.onLayoutFinish.append(self.afterLayout)
76
77     def afterLayout(self):
78         self.setTextFont
79         self.loadUrl(config.plugins.CurlyTx.defaultPage.value)
80
81     def loadHelp(self):
82         self.helpList.append((
83                 self["actions"], "WizardActions",
84                 [("up", _("Scroll page contents up"))]))
85         self.helpList.append((
86                 self["actions"], "WizardActions",
87                 [("down", _("Scroll page contents down"))]))
88         self.helpList.append((
89                 self["actions"], "InfobarEPGActions",
90                 [("showEventInfo", _("Show HTTP response headers"))]))
91         self.helpList.append((
92                 self["actions"], "ColorActions",
93                 [("red", _("Show program settings"))]))
94         self.helpList.append((
95                 self["actions"], "ColorActions",
96                 [("green", _("Reload current page URL"))]))
97         self.helpList.append((
98                 self["actions"], "ColorActions",
99                 [("yellow", _("Switch to next configured page URL"))]))
100         self.helpList.append((
101                 self["actions"], "ColorActions",
102                 [("blue", _("Switch to previous configured page URL"))]))
103         self.helpList.append((
104                 self["actions"], "WizardActions",
105                 [("ok", _("Close window"))]))
106         self.helpList.append((
107                 self["actions"], "WizardActions",
108                 [("back", _("Close window"))]))
109         self.helpList.append((
110                 self["actions"], "HelpActions",
111                 [("displayHelp", _("Show this help screen"))]))
112
113     def loadButtons(self):
114         pageCount = len(config.plugins.CurlyTx.pages)
115         if pageCount == 0:
116             self["key_green"].setText("")
117             self["key_yellow"].setText("")
118             self["key_blue"].setText("")
119         elif pageCount == 1:
120             self["key_green"].setText(_("Reload"))
121             self["key_yellow"].setText("")
122             self["key_blue"].setText("")
123         else:
124             self["key_green"].setText(_("Reload"))
125             self["key_yellow"].setText(_("Prev"))
126             self["key_blue"].setText(_("Next"))
127
128     def pageUp(self):
129         self["text"].pageUp()
130
131     def pageDown(self):
132         self["text"].pageDown()
133
134     def prevPage(self):
135         if self.currentPage == None:
136             return
137
138         pageId = self.currentPage - 1
139         if pageId < 0:
140             pageId = len(config.plugins.CurlyTx.pages) - 1
141         self.loadUrl(pageId)
142
143     def nextPage(self):
144         if self.currentPage == None:
145             return
146
147         pageId = self.currentPage + 1
148         if pageId > len(config.plugins.CurlyTx.pages) - 1:
149             pageId = 0
150         self.loadUrl(pageId)
151
152     def reload(self):
153         if self.currentPage == None:
154             return
155
156         self.loadUrl(self.currentPage)
157
158     def loadUrl(self, pageId):
159         self.httpGetterFactory = None
160         if pageId == None:
161             self.loadNoPage()
162             return
163
164         cfg = config.plugins.CurlyTx
165         pageCount = len(cfg.pages)
166         pageId = int(pageId)
167         if pageId > (pageCount - 1):
168             if len(cfg.pages) == 0:
169                 self.loadNoPage()
170             else:
171                 self["text"].setText(_("Invalid page") + " " + pageId);
172             return
173
174         url   = cfg.pages[pageId].uri.value
175         title = cfg.pages[pageId].title.value
176
177         if pageCount > 1:
178             title = "{0} [{1}/{2}]".format(title, pageId + 1, pageCount)
179
180         self.currentPage = pageId
181         self.currentUrl = url
182         self.currentFontSize = cfg.pages[pageId].fontSize.value
183
184         self.setTitle(title)
185         self.setTextFont()
186         self["text"].setText(_("Loading ...") + "\n" + url);
187
188         if (url.startswith('file://')):
189             self.loadLocalFile(url)
190         else:
191             self.getPageWebClient(url).addCallback(self.urlLoaded).addErrback(self.urlFailed, url)
192
193     def loadLocalFile(self, url):
194         file = url[7:]
195         if not os.path.exists(file):
196             self.showFail('File does not exist', file)
197             return
198
199         with open(file, 'r') as f:
200             self.urlLoaded(f.read())
201
202     def setTextFont(self):
203         if self["text"].long_text is not None:
204             self["text"].long_text.setFont(gFont("Console", self.currentFontSize))
205
206     def urlLoaded(self, html):
207         self["text"].setText(html)
208
209     def urlFailed(self, error, url):
210         self.showFail(error.getErrorMessage(), url)
211
212     def showFail(self, message, url):
213         self["text"].setText(
214             _("Error fetching URL:") + "\n " + message
215             + "\n\nURL: " + url
216             )
217
218     def loadNoPage(self):
219         self["text"].setText(_("Go and add a page in the settings"));
220
221     def showHeader(self):
222         if not self.httpGetterFactory:
223             return
224
225         if self.showingHeaders:
226             self["text"].setText(self.pageContent)
227             self.pageContent    = None
228             self.showingHeaders = False
229         elif self.httpGetterFactory.response_headers:
230             headers = _("HTTP response headers for") + "\n" + self.currentUrl + "\n\n"
231             for (k, v) in self.httpGetterFactory.response_headers.items():
232                 headers += k + ": " + ("\n" + k + ": ").join(v) + "\n"
233             self.pageContent = self["text"].getText()
234             self["text"].setText(headers)
235             self.showingHeaders = True
236
237     def showSettings(self):
238         from CurlyTxSettings import CurlyTxSettings
239         self.session.openWithCallback(self.onSettingsChanged, CurlyTxSettings)
240
241     def onSettingsChanged(self):
242         self.loadButtons()
243         if len(config.plugins.CurlyTx.pages) == 0:
244             self.currentPage = None
245             self.loadUrl(self.currentPage)
246         elif self.currentPage == None:
247             self.currentPage = 0
248             self.loadUrl(self.currentPage)
249
250
251     def getPageWebClient(self, url, contextFactory=None, *args, **kwargs):
252         """
253         Download a web page as a string.
254
255         COPY OF twisted.web.client.getPage to store the factory
256
257         Download a page. Return a deferred, which will callback with a
258         page (as a string) or errback with a description of the error.
259
260         See L{HTTPClientFactory} to see what extra arguments can be passed.
261         """
262         self.httpGetterFactory = _makeGetterFactory(
263             url,
264             HTTPClientFactory,
265             contextFactory=contextFactory,
266             *args, **kwargs)
267         return self.httpGetterFactory.deferred