1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2011 Christian Weiske <cweiske@cweiske.de>
4 # License: GPLv3 or later
8 from Screens.Screen import Screen
9 from Screens.HelpMenu import HelpableScreen
10 from Components.Label import Label
11 from Components.ScrollLabel import ScrollLabel
12 from Components.ActionMap import ActionMap
13 from Components.Sources.StaticText import StaticText
14 from Tools import Directories
15 from twisted.web import client
16 from twisted.web.client import _makeGetterFactory, HTTPClientFactory
17 from enigma import gFont
20 from config import createPage, loadDefaultPageOptions, feedPagesToConfig, feedSettingsToConfig, savePageConfig
21 from Components.config import config
25 class CurlyTx(Screen, HelpableScreen):
27 <screen name="CurlyTx" position="center,center" size="560,430" title="CurlyTx" >
28 <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
29 <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
30 <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
31 <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
32 <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" />
33 <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" />
34 <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" />
35 <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" />
36 <widget name="text" position="5,45" size="550,380" font="Console;20" />
42 httpGetterFactory = None
43 showingHeaders = False
44 staticPageFeedFile = 'curlytx-pagefeed.xml'
46 def __init__(self, session, args = None):
47 #self.skin = CurlyTx.skin
48 Screen.__init__(self, session)
49 HelpableScreen.__init__(self)
50 #self.skinName = [ "CurlyTx", "Setup" ]
52 self["text"] = ScrollLabel("foo")
54 self["key_red"] = StaticText(_("Settings"))
55 self["key_green"] = StaticText(_("Reload"))
56 self["key_yellow"] = StaticText(_("Prev"))
57 self["key_blue"] = StaticText(_("Next"))
60 self["actions"] = ActionMap(
61 ["WizardActions", "ColorActions", "InputActions", "InfobarEPGActions"], {
65 "down": self.pageDown,
67 "red": self.showSettings,
69 "yellow": self.prevPage,
70 "blue": self.nextPage,
72 "showEventInfo": self.showHeader
77 self.onFirstExecBegin.append(self.afterLayout)
79 def afterLayout(self):
81 self.loadStaticConfig()
82 self.loadUrl(config.plugins.CurlyTx.defaultPage.value)
85 self.helpList.append((
86 self["actions"], "WizardActions",
87 [("up", _("Scroll page contents up"))]))
88 self.helpList.append((
89 self["actions"], "WizardActions",
90 [("down", _("Scroll page contents down"))]))
91 self.helpList.append((
92 self["actions"], "InfobarEPGActions",
93 [("showEventInfo", _("Show HTTP response headers"))]))
94 self.helpList.append((
95 self["actions"], "ColorActions",
96 [("red", _("Show program settings"))]))
97 self.helpList.append((
98 self["actions"], "ColorActions",
99 [("green", _("Reload current page URL"))]))
100 self.helpList.append((
101 self["actions"], "ColorActions",
102 [("yellow", _("Switch to next configured page URL"))]))
103 self.helpList.append((
104 self["actions"], "ColorActions",
105 [("blue", _("Switch to previous configured page URL"))]))
106 self.helpList.append((
107 self["actions"], "WizardActions",
108 [("ok", _("Close window"))]))
109 self.helpList.append((
110 self["actions"], "WizardActions",
111 [("back", _("Close window"))]))
113 def loadButtons(self):
114 pageCount = len(config.plugins.CurlyTx.pages)
116 self["key_green"].setText("")
117 self["key_yellow"].setText("")
118 self["key_blue"].setText("")
120 self["key_green"].setText(_("Reload"))
121 self["key_yellow"].setText("")
122 self["key_blue"].setText("")
124 self["key_green"].setText(_("Reload"))
125 self["key_yellow"].setText(_("Prev"))
126 self["key_blue"].setText(_("Next"))
128 if config.plugins.CurlyTx.enableSettings.getValue():
129 self["key_red"].setText(_("Settings"))
131 self["key_red"].setText("")
134 self["text"].pageUp()
137 self["text"].pageDown()
140 if self.currentPage == None:
143 pageId = self.currentPage - 1
145 pageId = len(config.plugins.CurlyTx.pages) - 1
149 if self.currentPage == None:
152 pageId = self.currentPage + 1
153 if pageId > len(config.plugins.CurlyTx.pages) - 1:
158 if self.currentPage == None:
161 self.loadUrl(self.currentPage)
163 def loadUrl(self, pageId):
164 self.httpGetterFactory = None
169 cfg = config.plugins.CurlyTx
170 pageCount = len(cfg.pages)
172 if pageId > (pageCount - 1):
173 if len(cfg.pages) == 0:
176 self["text"].setText(_("Invalid page") + " " + pageId);
179 url = cfg.pages[pageId].uri.value
180 title = cfg.pages[pageId].title.value
183 title = "{0} [{1}/{2}]".format(title, pageId + 1, pageCount)
185 self.currentPage = pageId
186 self.currentUrl = url
187 self.currentFontSize = cfg.pages[pageId].fontSize.value
191 self["text"].setText(_("Loading ...") + "\n" + url);
193 if (url.startswith('file://')):
194 self.loadLocalFile(url)
196 self.getPageWebClient(url).addCallback(self.urlLoaded).addErrback(self.urlFailed, url)
198 def loadLocalFile(self, url):
200 if not os.path.exists(file):
201 self.showFail('File does not exist', file)
204 with open(file, 'r') as f:
205 self.urlLoaded(f.read())
207 def setTextFont(self):
208 if self["text"].long_text is not None:
209 self["text"].long_text.setFont(gFont("Console", self.currentFontSize))
211 def urlLoaded(self, html):
212 self["text"].setText(html)
214 def urlFailed(self, error, url):
215 self.showFail(error.getErrorMessage(), url)
217 def showFail(self, message, url):
218 self["text"].setText(
219 _("Error fetching URL:") + "\n " + message
223 def loadNoPage(self):
224 self["text"].setText(_("Go and add a page in the settings"));
226 def showHeader(self):
227 if not self.httpGetterFactory:
230 if self.showingHeaders:
231 self["text"].setText(self.pageContent)
232 self.pageContent = None
233 self.showingHeaders = False
234 elif self.httpGetterFactory.response_headers:
235 headers = _("HTTP response headers for") + "\n" + self.currentUrl + "\n\n"
236 for (k, v) in self.httpGetterFactory.response_headers.items():
237 headers += k + ": " + ("\n" + k + ": ").join(v) + "\n"
238 self.pageContent = self["text"].getText()
239 self["text"].setText(headers)
240 self.showingHeaders = True
242 def showSettings(self):
243 if not config.plugins.CurlyTx.enableSettings.getValue():
246 from CurlyTxSettings import CurlyTxSettings
247 self.session.openWithCallback(self.onSettingsChanged, CurlyTxSettings)
249 def onSettingsChanged(self):
251 if len(config.plugins.CurlyTx.pages) == 0:
252 self.currentPage = None
253 self.loadUrl(self.currentPage)
254 elif self.currentPage == None:
256 self.loadUrl(self.currentPage)
259 def getPageWebClient(self, url, contextFactory=None, *args, **kwargs):
261 Download a web page as a string.
263 COPY OF twisted.web.client.getPage to store the factory
265 Download a page. Return a deferred, which will callback with a
266 page (as a string) or errback with a description of the error.
268 See L{HTTPClientFactory} to see what extra arguments can be passed.
270 self.httpGetterFactory = _makeGetterFactory(
273 contextFactory=contextFactory,
275 return self.httpGetterFactory.deferred
277 def loadStaticConfig(self):
279 Always try to load the static config file from
280 /etc/enigma2/curlytx-pagefeed.xml
282 staticFeedPath = Directories.resolveFilename(Directories.SCOPE_CONFIG, self.staticPageFeedFile)
283 if not os.path.exists(staticFeedPath):
286 from AtomFeed import AtomFeed
288 'file://' + staticFeedPath,
289 self.saveStaticConfig, self.loadStaticConfigFail
292 def loadStaticConfigFail(self, errorMessage):
293 """ Loading the page url feed failed somehow """
294 from Screens.MessageBox import MessageBox
297 _("Error loading page feed:") + "\n\n" + str(errorMessage),
298 type = MessageBox.TYPE_ERROR
301 def saveStaticConfig(self, pages, settings):
302 feedPagesToConfig(pages)
303 feedSettingsToConfig(settings)