About: read commit logs from Github using json api
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / About.py
1 from Screen import Screen
2 from Components.config import config
3 from Components.ActionMap import ActionMap
4 from Components.Sources.StaticText import StaticText
5 from Components.Harddisk import harddiskmanager
6 from Components.NimManager import nimmanager
7 from Components.About import about
8 from Components.ScrollLabel import ScrollLabel
9 from Components.Button import Button
10
11 from Components.Label import Label
12 from Components.ProgressBar import ProgressBar
13
14 from Tools.StbHardware import getFPVersion
15 from enigma import eTimer, eLabel
16
17 from Components.HTMLComponent import HTMLComponent
18 from Components.GUIComponent import GUIComponent
19 import skin
20
21 class About(Screen):
22         def __init__(self, session):
23                 Screen.__init__(self, session)
24                 hddsplit, = skin.parameters.get("AboutHddSplit", (0,))
25
26                 AboutText = _("Hardware: ") + about.getHardwareTypeString() + "\n"
27                 AboutText += _("CPU: ") + about.getCPUInfoString() + "\n"
28                 AboutText += _("Image: ") + about.getImageTypeString() + "\n"
29                 AboutText += _("Installed: ") + about.getFlashDateString() + "\n"
30                 AboutText += _("Kernel version: ") + about.getKernelVersionString() + "\n"
31
32                 EnigmaVersion = "Enigma: " + about.getEnigmaVersionString()
33                 self["EnigmaVersion"] = StaticText(EnigmaVersion)
34                 AboutText += EnigmaVersion + "\n"
35                 AboutText += _("Enigma (re)starts: %d\n") % config.misc.startCounter.value
36
37                 GStreamerVersion = "GStreamer: " + about.getGStreamerVersionString().replace("GStreamer","")
38                 self["GStreamerVersion"] = StaticText(GStreamerVersion)
39                 AboutText += GStreamerVersion + "\n"
40
41                 ImageVersion = _("Last upgrade: ") + about.getImageVersionString()
42                 self["ImageVersion"] = StaticText(ImageVersion)
43                 AboutText += ImageVersion + "\n"
44
45                 AboutText += _("DVB drivers: ") + about.getDriverInstalledDate() + "\n"
46
47                 AboutText += _("Python version: ") + about.getPythonVersionString() + "\n"
48
49                 fp_version = getFPVersion()
50                 if fp_version is None:
51                         fp_version = ""
52                 else:
53                         fp_version = _("Frontprocessor version: %d") % fp_version
54                         AboutText += fp_version + "\n"
55
56                 self["FPVersion"] = StaticText(fp_version)
57
58                 self["TunerHeader"] = StaticText(_("Detected NIMs:"))
59                 AboutText += "\n" + _("Detected NIMs:") + "\n"
60
61                 nims = nimmanager.nimList()
62                 for count in range(len(nims)):
63                         if count < 4:
64                                 self["Tuner" + str(count)] = StaticText(nims[count])
65                         else:
66                                 self["Tuner" + str(count)] = StaticText("")
67                         AboutText += nims[count] + "\n"
68
69                 self["HDDHeader"] = StaticText(_("Detected HDD:"))
70                 AboutText += "\n" + _("Detected HDD:") + "\n"
71
72                 hddlist = harddiskmanager.HDDList()
73                 hddinfo = ""
74                 if hddlist:
75                         formatstring = hddsplit and "%s:%s, %.1f %sB %s" or "%s\n(%s, %.1f %sB %s)"
76                         for count in range(len(hddlist)):
77                                 if hddinfo:
78                                         hddinfo += "\n"
79                                 hdd = hddlist[count][1]
80                                 if int(hdd.free()) > 1024:
81                                         hddinfo += formatstring % (hdd.model(), hdd.capacity(), hdd.free()/1024, "G", _("free"))
82                                 else:
83                                         hddinfo += formatstring % (hdd.model(), hdd.capacity(), hdd.free()/1024, "M", _("free"))
84                 else:
85                         hddinfo = _("none")
86                 self["hddA"] = StaticText(hddinfo)
87                 AboutText += hddinfo
88                 self["AboutScrollLabel"] = ScrollLabel(AboutText)
89                 self["key_green"] = Button(_("Translations"))
90                 self["key_red"] = Button(_("Latest Commits"))
91                 self["key_blue"] = Button(_("Memory Info"))
92
93                 self["actions"] = ActionMap(["ColorActions", "SetupActions", "DirectionActions"],
94                         {
95                                 "cancel": self.close,
96                                 "ok": self.close,
97                                 "red": self.showCommits,
98                                 "green": self.showTranslationInfo,
99                                 "blue": self.showMemoryInfo,
100                                 "up": self["AboutScrollLabel"].pageUp,
101                                 "down": self["AboutScrollLabel"].pageDown
102                         })
103
104         def showTranslationInfo(self):
105                 self.session.open(TranslationInfo)
106
107         def showCommits(self):
108                 self.session.open(CommitInfo)
109
110         def showMemoryInfo(self):
111                 self.session.open(MemoryInfo)
112
113 class TranslationInfo(Screen):
114         def __init__(self, session):
115                 Screen.__init__(self, session)
116                 # don't remove the string out of the _(), or it can't be "translated" anymore.
117
118                 # TRANSLATORS: Add here whatever should be shown in the "translator" about screen, up to 6 lines (use \n for newline)
119                 info = _("TRANSLATOR_INFO")
120
121                 if info == "TRANSLATOR_INFO":
122                         info = "(N/A)"
123
124                 infolines = _("").split("\n")
125                 infomap = {}
126                 for x in infolines:
127                         l = x.split(': ')
128                         if len(l) != 2:
129                                 continue
130                         (type, value) = l
131                         infomap[type] = value
132                 print infomap
133
134                 self["key_red"] = Button(_("Cancel"))
135                 self["TranslationInfo"] = StaticText(info)
136
137                 translator_name = infomap.get("Language-Team", "none")
138                 if translator_name == "none":
139                         translator_name = infomap.get("Last-Translator", "")
140
141                 self["TranslatorName"] = StaticText(translator_name)
142
143                 self["actions"] = ActionMap(["SetupActions"],
144                         {
145                                 "cancel": self.close,
146                                 "ok": self.close,
147                         })
148
149 class CommitInfo(Screen):
150         def __init__(self, session):
151                 Screen.__init__(self, session)
152                 self.skinName = ["CommitInfo", "About"]
153                 self["AboutScrollLabel"] = ScrollLabel(_("Please wait"))
154
155                 self["actions"] = ActionMap(["SetupActions", "DirectionActions"],
156                         {
157                                 "cancel": self.close,
158                                 "ok": self.close,
159                                 "up": self["AboutScrollLabel"].pageUp,
160                                 "down": self["AboutScrollLabel"].pageDown,
161                                 "left": self.left,
162                                 "right": self.right
163                         })
164
165                 self["key_red"] = Button(_("Cancel"))
166
167                 self.project = 0
168                 self.projects = [
169                         ("enigma2", "Enigma2"),
170                         ("openpli-oe-core", "Openpli Oe Core"),
171                         ("enigma2-plugins", "Enigma2 Plugins"),
172                         ("aio-grab", "Aio Grab"),
173                         ("gst-plugin-dvbmediasink", "Gst Plugin Dvbmediasink"),
174                         ("openembedded", "Openembedded"),
175                         ("plugin-xmltvimport", "Plugin Xmltvimport"),
176                         ("plugins-enigma2", "Plugins Enigma2"),
177                         ("skin-magic", "Skin Magic"),
178                         ("tuxtxt", "Tuxtxt")
179                 ]
180                 self.cachedProjects = {}
181                 self.Timer = eTimer()
182                 self.Timer.callback.append(self.readGithubCommitLogs)
183                 self.Timer.start(50, True)
184
185         def readCommitLogs(self):
186                 url = 'http://sourceforge.net/p/openpli/%s/feed' % self.projects[self.project][0]
187                 commitlog = ""
188                 from urllib2 import urlopen
189                 try:
190                         commitlog += 80 * '-' + '\n'
191                         commitlog += url.split('/')[-2] + '\n'
192                         commitlog += 80 * '-' + '\n'
193                         for x in  urlopen(url, timeout=5).read().split('<title>')[2:]:
194                                 for y in x.split("><"):
195                                         if '</title' in y:
196                                                 title = y[:-7]
197                                         if '</dc:creator' in y:
198                                                 creator = y.split('>')[1].split('<')[0]
199                                         if '</pubDate' in y:
200                                                 date = y.split('>')[1].split('<')[0][:-6]
201                                 commitlog += date + ' ' + creator + '\n' + title + 2 * '\n'
202                         self.cachedProjects[self.projects[self.project][1]] = commitlog
203                 except:
204                         commitlog = _("Currently the commit log cannot be retrieved - please try later again")
205                 self["AboutScrollLabel"].setText(commitlog)
206
207         def readGithubCommitLogs(self):
208                 url = 'https://api.github.com/repos/openpli/%s/commits' % self.projects[self.project][0]
209                 commitlog = ""
210                 from datetime import datetime
211                 from json import loads
212                 from urllib2 import urlopen
213                 try:
214                         commitlog += 80 * '-' + '\n'
215                         commitlog += url.split('/')[-2] + '\n'
216                         commitlog += 80 * '-' + '\n'
217                         for c in loads(urlopen(url, timeout=5).read()):
218                                 creator = c['commit']['author']['name']
219                                 title = c['commit']['message']
220                                 date = datetime.strptime(c['commit']['committer']['date'], '%Y-%m-%dT%H:%M:%SZ').strftime('%x %X')
221                                 commitlog += date + ' ' + creator + '\n' + title + 2 * '\n'
222                         commitlog = commitlog.encode('utf-8')
223                         self.cachedProjects[self.projects[self.project][1]] = commitlog
224                 except:
225                         commitlog += _("Currently the commit log cannot be retrieved - please try later again")
226                 self["AboutScrollLabel"].setText(commitlog)
227
228         def updateCommitLogs(self):
229                 if self.cachedProjects.has_key(self.projects[self.project][1]):
230                         self["AboutScrollLabel"].setText(self.cachedProjects[self.projects[self.project][1]])
231                 else:
232                         self["AboutScrollLabel"].setText(_("Please wait"))
233                         self.Timer.start(50, True)
234
235         def left(self):
236                 self.project = self.project == 0 and len(self.projects) - 1 or self.project - 1
237                 self.updateCommitLogs()
238
239         def right(self):
240                 self.project = self.project != len(self.projects) - 1 and self.project + 1 or 0
241                 self.updateCommitLogs()
242
243 class MemoryInfo(Screen):
244         def __init__(self, session):
245                 Screen.__init__(self, session)
246
247                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
248                         {
249                                 "cancel": self.close,
250                                 "ok": self.getMemoryInfo,
251                                 "green": self.getMemoryInfo,
252                                 "blue": self.clearMemory,
253                         })
254
255                 self["key_red"] = Label(_("Cancel"))
256                 self["key_green"] = Label(_("Refresh"))
257                 self["key_blue"] = Label(_("Clear"))
258
259                 self['lmemtext'] = Label()
260                 self['lmemvalue'] = Label()
261                 self['rmemtext'] = Label()
262                 self['rmemvalue'] = Label()
263
264                 self['pfree'] = Label()
265                 self['pused'] = Label()
266                 self["slide"] = ProgressBar()
267                 self["slide"].setValue(100)
268
269                 self["params"] = MemoryInfoSkinParams()
270
271                 self['info'] = Label(_("This info is for developers only.\nFor a normal users it is not important.\nDon't panic, please, when here will be displayed any suspicious informations!"))
272
273                 self.setTitle(_("Memory Info"))
274                 self.onLayoutFinish.append(self.getMemoryInfo)
275
276         def getMemoryInfo(self):
277                 try:
278                         ltext = rtext = ""
279                         lvalue = rvalue = ""
280                         mem = 1
281                         free = 0
282                         i = 0
283                         for line in open('/proc/meminfo','r'):
284                                 ( name, size, units ) = line.strip().split()
285                                 if "MemTotal" in name:
286                                         mem = int(size)
287                                 if "MemFree" in name:
288                                         free = int(size)
289                                 if i < self["params"].rows_in_column:
290                                         ltext += "".join((name,"\n"))
291                                         lvalue += "".join((size," ",units,"\n"))
292                                 else:
293                                         rtext += "".join((name,"\n"))
294                                         rvalue += "".join((size," ",units,"\n"))
295                                 i += 1
296                         self['lmemtext'].setText(ltext)
297                         self['lmemvalue'].setText(lvalue)
298                         self['rmemtext'].setText(rtext)
299                         self['rmemvalue'].setText(rvalue)
300
301                         self["slide"].setValue(int(100.0*(mem-free)/mem+0.25))
302                         self['pfree'].setText("%.1f %s" % (100.*free/mem,'%'))
303                         self['pused'].setText("%.1f %s" % (100.*(mem-free)/mem,'%'))
304
305                 except Exception, e:
306                         print "[About] getMemoryInfo FAIL:", e
307
308         def clearMemory(self):
309                 from os import system
310                 system("sync")
311                 system("echo 3 > /proc/sys/vm/drop_caches")
312                 self.getMemoryInfo()
313
314 class MemoryInfoSkinParams(HTMLComponent, GUIComponent):
315         def __init__(self):
316                 GUIComponent.__init__(self)
317                 self.rows_in_column = 25
318
319         def applySkin(self, desktop, screen):
320                 if self.skinAttributes is not None:
321                         attribs = [ ]
322                         for (attrib, value) in self.skinAttributes:
323                                 if attrib == "rowsincolumn":
324                                         self.rows_in_column = int(value)
325                         self.skinAttributes = attribs
326                 return GUIComponent.applySkin(self, desktop, screen)
327
328         GUI_WIDGET = eLabel