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