added porn-center plugin
[enigma2-plugins.git] / porncenter / src / plugin.py
1 # Porn Center by AliAbdul
2 from Additions.Plugin import cache, getPlugins
3 from Components.ActionMap import ActionMap
4 from Components.config import config, ConfigSelection, ConfigSubsection, ConfigText, ConfigYesNo, getConfigListEntry
5 from Components.ConfigList import ConfigListScreen\r
6 from Components.FileList import FileList
7 from Components.Label import Label
8 from Components.Language import language
9 from Components.MenuList import MenuList
10 from Components.MultiContent import MultiContentEntryPixmapAlphaBlend, MultiContentEntryText
11 from Components.PluginComponent import plugins
12 from Components.ProgressBar import ProgressBar
13 from enigma import eListboxPythonMultiContent, eServiceReference, eTimer, getDesktop, gFont
14 from os import environ, remove
15 from Plugins.Plugin import PluginDescriptor
16 from Screens.InfoBar import MoviePlayer
17 from Screens.MessageBox import MessageBox
18 from Screens.ParentalControlSetup import ProtectedScreen
19 from Screens.Screen import Screen
20 from Tools.BoundFunction import boundFunction
21 from Tools.Directories import resolveFilename, SCOPE_LANGUAGE, SCOPE_PLUGINS
22 from Tools.Downloader import downloadWithProgress
23 from Tools.LoadPixmap import LoadPixmap
24 import gettext
25
26 ##################################################
27
28 desktop = getDesktop(0)
29 size = desktop.size()
30 WIDTH = size.width()
31 HEIGHT = size.height()
32
33 ##################################################
34
35 def localeInit():
36         lang = language.getLanguage()
37         environ["LANGUAGE"] = lang[:2]\r
38         gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))\r
39         gettext.textdomain("enigma2")
40         gettext.bindtextdomain("PornCenter", "%s%s" % (resolveFilename(SCOPE_PLUGINS), "Extensions/PornCenter/locale/"))
41
42 def _(txt):\r
43         t = gettext.dgettext("PornCenter", txt)\r
44         if t == txt:\r
45                 t = gettext.gettext(txt)\r
46         return t
47
48 localeInit()\r
49 language.addCallback(localeInit)
50
51 ##################################################
52
53 config.plugins.PornCenter = ConfigSubsection()
54 config.plugins.PornCenter.name = ConfigText(default=_("Porn Center"), fixed_size=False)
55 config.plugins.PornCenter.description = ConfigText(default=_("Adult streaming plugins for dm800/dm8000"), fixed_size=False)
56 config.plugins.PornCenter.buffer = ConfigYesNo(default=True)
57 config.plugins.PornCenter.bufferDevice = ConfigText(default="/media/hdd/", fixed_size=False)
58 config.plugins.PornCenter.keepStored = ConfigSelection(choices={"delete": _("delete"), "keep": _("keep on device"), "ask": _("ask me")}, default="delete")
59
60 ##################################################
61
62 class BufferThread():
63         def __init__(self):
64                 self.progress = 0
65                 self.downloading = False
66                 self.error = ""
67                 self.download = None
68
69         def startDownloading(self, url, file):
70                 self.progress = 0
71                 self.downloading = True
72                 self.error = ""
73                 self.download = downloadWithProgress(url, file)
74                 self.download.addProgress(self.httpProgress)
75                 self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed)
76
77         def httpProgress(self, recvbytes, totalbytes):
78                 self.progress = int(100 * recvbytes / float(totalbytes))
79
80         def httpFinished(self, string=""):
81                 self.downloading = False
82                 if string is not None:
83                         self.error = str(string)
84                 else:
85                         self.error = ""
86
87         def httpFailed(self, failure_instance=None, error_message=""):
88                 self.downloading = False
89                 if error_message == "" and failure_instance is not None:
90                         error_message = failure_instance.getErrorMessage()
91                         self.error = str(error_message)
92
93         def stop(self):
94                 self.progress = 0
95                 self.downloading = False
96                 self.error = ""
97                 self.download.stop()
98
99 bufferThread = BufferThread()
100
101 ##################################################
102
103 class PornCenterBuffer(Screen):
104         skin = """
105                 <screen position="center,center" size="520,80" title="%s" >\r
106                         <widget name="info" position="5,5" size="510,40" font="Regular;18" halign="center" valign="center" />
107                         <widget name="progress" position="100,50" size="320,14" pixmap="skin_default/progress_big.png" borderWidth="2" borderColor="#cccccc" />\r
108                 </screen>""" % _("Porn Center")
109 \r
110         def __init__(self, session, url, file):
111                 self.session = session
112                 Screen.__init__(self, session)
113                 
114                 self.url = url
115                 self.file = file
116                 
117                 self.infoTimer = eTimer()
118                 self.infoTimer.timeout.get().append(self.updateInfo)
119                 
120                 self["info"] = Label(_("Downloading movie: %s") % self.file)
121                 self["progress"] = ProgressBar()
122                 
123                 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.okClicked, "cancel": self.exit}, -1)
124                 
125                 self.onLayoutFinish.append(self.downloadMovie)
126
127         def downloadMovie(self):
128                 bufferThread.startDownloading(self.url, self.file)
129                 self.infoTimer.start(300, False)
130
131         def updateInfo(self):
132                 if bufferThread.error != "":
133                         self["info"].setText(bufferThread.error)
134                         self.infoTimer.stop()
135                 else:
136                         progress = int(bufferThread.progress)
137                         self["progress"].setValue(progress)
138                         if progress == 100:
139                                 self.infoTimer.stop()
140                                 self.close(True)
141
142         def okClicked(self):
143                 if int(bufferThread.progress) > 0:
144                         self.infoTimer.stop()
145                         self.close(True)
146
147         def exit(self):
148                 bufferThread.download.stop()
149                 self.close(None)
150
151 ##################################################
152
153 class ChangedMoviePlayer(MoviePlayer):
154         def __init__(self, session, service):
155                 MoviePlayer.__init__(self, session, service)
156                 self.skinName = "MoviePlayer"
157
158         def leavePlayer(self):
159                 self.session.openWithCallback(self.leavePlayerConfirmed, MessageBox, _("Stop playing this movie?"))
160
161         def leavePlayerConfirmed(self, answer):
162                 if answer:
163                         self.close()
164
165         def doEofInternal(self, playing):
166                 pass
167
168         def getPluginList(self):
169                 list = []
170                 for p in plugins.getPlugins(where=PluginDescriptor.WHERE_EXTENSIONSMENU):
171                         if (p.name != _("Porn Center")) and (p.name != config.plugins.PornCenter.name.value):
172                                 list.append(((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None))
173                 return list
174
175         def showMovies(self):
176                 pass
177
178 ##################################################
179
180 class PornCenterLocationSelection(Screen):
181         skin = """
182         <screen position="center,center" size="560,300" title="%s">
183                 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
184                 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
185                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
186                 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
187                 <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
188                 <widget name="filelist" position="10,45" size="550,255" scrollbarMode="showOnDemand" />
189         </screen>""" % _("Porn Center")\r
190 \r
191         def __init__(self, session, dir="/"):\r
192                 Screen.__init__(self, session)\r
193                 \r
194                 self["key_green"] = Label(_("Select"))\r
195                 \r
196                 try: self["filelist"] = FileList(dir, showDirectories=True, showFiles=False)\r
197                 except: self["filelist"] = FileList("/", showDirectories, showFiles)\r
198                 \r
199                 self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],\r
200                         {\r
201                                 "ok": self.okClicked,\r
202                                 "cancel": self.exit,\r
203                                 "green": self.select\r
204                         }, -1)
205                 
206                 self.onLayoutFinish.append(self.updateDirectoryName)\r
207                 \r
208         def okClicked(self):\r
209                 if self["filelist"].canDescent():\r
210                         self["filelist"].descent()\r
211                         self["filelist"].instance.moveSelectionTo(0)\r
212                         self.updateDirectoryName()\r
213 \r
214         def exit(self):\r
215                 self.close(None)\r
216 \r
217         def select(self):\r
218                 dir = self["filelist"].getCurrentDirectory()\r
219                 if dir is not None:\r
220                         self.close(dir)\r
221                 else:\r
222                         self.close(None)\r
223 \r
224         def updateDirectoryName(self):
225                 try:
226                         dir = self["filelist"].getCurrentDirectory()
227                         self.instance.setTitle(dir)
228                 except:
229                         self.instance.setTitle("?")
230
231 ##################################################
232
233 class PornCenterConfig(ConfigListScreen, Screen):
234         skin = """
235                 <screen position="center,center" size="520,150" title="%s" >
236                         <widget name="config" position="0,0" size="520,150" scrollbarMode="showOnDemand" />
237                 </screen>""" % _("Porn Center")
238
239         def __init__(self, session, args=None):
240                 Screen.__init__(self, session)
241                 self.session = session
242                 
243                 ConfigListScreen.__init__(self, [])
244                 
245                 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.change, "cancel": self.exit}, -2)
246                 
247                 self.onLayoutFinish.append(self.createConfig)
248
249         def createConfig(self):
250                 self.deviceEntry = ConfigSelection(choices=[config.plugins.PornCenter.bufferDevice.value], default=config.plugins.PornCenter.bufferDevice.value)
251                 self["config"].list = [
252                         getConfigListEntry(_("Name:"), config.plugins.PornCenter.name),
253                         getConfigListEntry(_("Description:"), config.plugins.PornCenter.description),
254                         getConfigListEntry(_("Buffer:"), config.plugins.PornCenter.buffer),
255                         getConfigListEntry(_("Buffer device:"), self.deviceEntry),
256                         getConfigListEntry(_("Buffer file handling:"), config.plugins.PornCenter.keepStored)]
257
258         def keyLeft(self):
259                 ConfigListScreen.keyLeft(self)
260                 self.handleKeysLeftAndRight()
261
262         def keyRight(self):
263                 ConfigListScreen.keyRight(self)
264                 self.handleKeysLeftAndRight()
265
266         def handleKeysLeftAndRight(self):
267                 sel = self["config"].getCurrent()[1]
268                 if sel == self.deviceEntry:
269                         self.session.openWithCallback(self.locationSelected, PornCenterLocationSelection, config.plugins.PornCenter.bufferDevice.value)
270
271         def locationSelected(self, dir):
272                 if dir is not None and dir != "?":
273                         config.plugins.PornCenter.bufferDevice.value = dir
274                         config.plugins.PornCenter.bufferDevice.save()
275                         self.createConfig()
276
277         def change(self):
278                 for x in self["config"].list:
279                         x[1].save()
280                 self.close()
281
282         def exit(self):
283                 for x in self["config"].list:
284                         x[1].cancel()
285                 self.close()
286
287 ##################################################
288
289 class PinChecker:
290         def __init__(self):
291                 self.pin_entered = False
292                 self.timer = eTimer()
293                 self.timer.callback.append(self.lock)
294
295         def pinEntered(self):
296                 self.pin_entered = True
297                 self.timer.start(60000*10, 1)
298
299         def lock(self):
300                 self.pin_entered = False
301 pinchecker = PinChecker()
302
303 ##################################################
304
305 class PornCenterList(MenuList):
306         def __init__(self):
307                 MenuList.__init__(self, [], False, eListboxPythonMultiContent)
308                 self.l.setItemHeight(75)
309                 if WIDTH == 720:
310                         self.l.setFont(0, gFont("Regular", 30))
311                         self.center_up = 22
312                 else:
313                         self.l.setFont(0, gFont("Regular", 40))
314                         self.center_up = 15
315
316         def SetList(self, entries):
317                 list = []
318                 for entry in entries:
319                         res = [(entry)]
320                         if entry.thumb:
321                                 res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(150, 75), png=entry.thumb))
322                         else:
323                                 res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(150, 75), png=LoadPixmap(cached=True, path=resolveFilename(SCOPE_PLUGINS)+"/Extensions/PornCenter/nopreview.png")))
324                         res.append(MultiContentEntryText(pos=(155, self.center_up), size=(WIDTH-270, 45), font=0, text=entry.name))
325                         list.append(res)
326                 self.setList(list)
327
328 ##################################################
329
330 class PornCenterSub(Screen, ProtectedScreen):
331         def __init__(self, session, plugin=None):
332                 Screen.__init__(self, session)
333                 if pinchecker.pin_entered == False:
334                         ProtectedScreen.__init__(self)
335                 
336                 self.session = session
337                 self.plugin = plugin
338                 self.list = []
339                 
340                 self["list"] = PornCenterList()
341                 
342                 self["actions"] = ActionMap(["InfobarActions", "MenuActions", "OkCancelActions"],
343                         {
344                                 "ok": self.ok,
345                                 "cancel": self.exit,
346                                 "menu": self.config,
347                                 "showMovies": self.showMore
348                         }, -1)
349                 
350                 self.onLayoutFinish.append(self.getEntries)
351
352         def isProtected(self):
353                 return config.ParentalControl.setuppinactive.value and config.ParentalControl.configured.value
354         
355         def pinEntered(self, result):
356                 if result is None:
357                         self.close()
358                 elif not result:
359                         self.close()
360                 else:
361                         pinchecker.pinEntered()
362
363         def ok(self):
364                 curr = self["list"].getCurrent()
365                 if curr:
366                         curr = curr[0]
367                         if curr.type == "Plugin":
368                                 self.session.open(PornCenterMain, curr)
369                         elif curr.type == "Movie":
370                                 url = curr.getVideoUrl()
371                                 if url:
372                                         if config.plugins.PornCenter.buffer.value:
373                                                 file = url
374                                                 while file.__contains__("/"):
375                                                         idx = file.index("/")
376                                                         file = file[idx+1:]
377                                                 self.file = "%s%s" % (config.plugins.PornCenter.bufferDevice.value, file)
378                                                 self.session.openWithCallback(self.bufferCallback, PornCenterBuffer, url, self.file)
379                                         else:
380                                                 self.session.open(ChangedMoviePlayer, eServiceReference(4097, 0, url))
381                                 else:
382                                         self.session.open(MessageBox, _("Error while getting video url!"), MessageBox.TYPE_ERROR)
383
384         def bufferCallback(self, callback):
385                 if callback is not None:
386                         ref = eServiceReference(4097, 0, self.file)
387                         self.session.openWithCallback(self.delete, ChangedMoviePlayer, ref)
388
389         def delete(self, callback=None):
390                 if bufferThread.downloading: #still downloading?
391                         bufferThread.stop()
392                 if config.plugins.PornCenter.keepStored.value == "delete":
393                         remove(self.file)
394                 elif config.plugins.PornCenter.keepStored.value == "ask":
395                         self.session.openWithCallback(self.deleteCallback, MessageBox, _("Delete this movie?"))
396
397         def deleteCallback(self, callback):
398                 if callback:
399                         remove(self.file)
400
401         def exit(self):
402                 cache.finishCallback = None
403                 for x in self.list:
404                         del x
405                 self.close()
406
407         def getEntries(self):
408                 if not self.plugin:
409                         self.gotEntries(getPlugins())
410                 else:
411                         cache.finishCallback = self.listChanged
412                         self.plugin.getEntries(self.gotEntries)
413
414         def gotEntries(self, entries=None):
415                 if entries:
416                         for entry in entries:
417                                 self.list.append(entry)
418                         self["list"].SetList(self.list)
419
420         def listChanged(self):
421                 self["list"].SetList(self.list)
422
423         def config(self):
424                 self.session.open(PornCenterConfig)
425
426         def showMore(self):
427                 if self.plugin:
428                         if self.plugin.type == "Plugin":
429                                 self.plugin.getMoreEntries()
430
431 ##################################################
432
433 class PornCenterMain(PornCenterSub):
434         if HEIGHT == 576:
435                 LISTHEIGHT = 450
436         else:
437                 LISTHEIGHT = HEIGHT - 100
438                 if LISTHEIGHT > 600:
439                         LISTHEIGHT = 600\r
440         skin = """\r
441                 <screen position="0,0" size="%d,%d" flags="wfNoBorder" backgroundColor="#000000" >\r
442                         <widget name="list" position="50,50" size="%d,%d" transparent="1" scrollbarMode="showOnDemand" />\r
443                 </screen>""" % (WIDTH, HEIGHT, WIDTH - 100, LISTHEIGHT)
444
445         def __init__(self, *x):
446                 PornCenterSub.__init__(self, *x)
447
448 ##################################################
449
450 def main_closed(callback=None):
451         cache.session.nav.playService(cache.oldService)
452
453 def main(session, **kwargs):
454         cache.session = session
455         cache.oldService = session.nav.getCurrentlyPlayingServiceReference()
456         session.nav.stopService()
457         session.openWithCallback(main_closed, PornCenterMain)
458
459 def Plugins(**kwargs):
460         return PluginDescriptor(name=config.plugins.PornCenter.name.value, description=config.plugins.PornCenter.description.value, where=[PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU], fnc=main, icon="plugin.png")