diff options
author | Nabil Hanna <ali@users.schwerkraft.elitedvb.net> | 2009-08-10 06:28:15 (GMT) |
---|---|---|
committer | Nabil Hanna <ali@users.schwerkraft.elitedvb.net> | 2009-08-10 06:28:15 (GMT) |
commit | 85f26a5486ac8478bcdaf8babeba6cdf19234af3 (patch) | |
tree | 7719834c12a4e3406c738c55a7aa48111b4814bb /podcast | |
parent | a2d09acff5ad88038dbe4341e64325a117660466 (diff) |
added podcast plugin
Diffstat (limited to 'podcast')
-rw-r--r-- | podcast/CONTROL/control | 10 | ||||
-rw-r--r-- | podcast/Makefile.am | 1 | ||||
-rw-r--r-- | podcast/etc/Makefile.am | 2 | ||||
-rw-r--r-- | podcast/etc/podcasts.xml | 89 | ||||
-rw-r--r-- | podcast/po/Makefile.am | 57 | ||||
-rw-r--r-- | podcast/po/Podcast.pot | 152 | ||||
-rw-r--r-- | podcast/po/de.po | 152 | ||||
-rw-r--r-- | podcast/po/tr.po | 97 | ||||
-rw-r--r-- | podcast/src/LICENSE.txt | 14 | ||||
-rw-r--r-- | podcast/src/Makefile.am | 3 | ||||
-rw-r--r-- | podcast/src/__init__.py | 0 | ||||
-rw-r--r-- | podcast/src/maintainer.info | 2 | ||||
-rw-r--r-- | podcast/src/plugin.py | 983 |
13 files changed, 1562 insertions, 0 deletions
diff --git a/podcast/CONTROL/control b/podcast/CONTROL/control new file mode 100644 index 0000000..e6f4927 --- /dev/null +++ b/podcast/CONTROL/control @@ -0,0 +1,10 @@ +Package: enigma2-plugin-extensions-podcast +Version: 0.1-r0 +Description: Stream podcasts +Architecture: all +Section: extra +Priority: optional +Maintainer: Nabil Hanna <nabil1978@web.de> +Homepage: http://code.google.com/p/enigma2 +Depends: enigma2(>=2.6git20090520) gst-plugin-neonhttpsrc twisted-web +Source: http://enigma2-plugins.schwerkraft.elitedvb.net/ diff --git a/podcast/Makefile.am b/podcast/Makefile.am new file mode 100644 index 0000000..7e3377e --- /dev/null +++ b/podcast/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = etc po src diff --git a/podcast/etc/Makefile.am b/podcast/etc/Makefile.am new file mode 100644 index 0000000..66ef89c --- /dev/null +++ b/podcast/etc/Makefile.am @@ -0,0 +1,2 @@ +installdir = /etc/podcast
+install_DATA = podcasts.xml diff --git a/podcast/etc/podcasts.xml b/podcast/etc/podcasts.xml new file mode 100644 index 0000000..9db977c --- /dev/null +++ b/podcast/etc/podcasts.xml @@ -0,0 +1,89 @@ +<podcasts>
+ <language name="German" >
+ <provider name="ARD" >
+ <podcast name="Deppendorfs Woche" url="http://www.tagesschau.de/export/video-podcast/deppendorfswoche/" />
+ <podcast name="Tagesschau" url="http://www.tagesschau.de/export/video-podcast/tagesschau/" />
+ <podcast name="Tagesschau in 100 Sekunden" url="http://www.tagesschau.de/export/video-podcast/tagesschau-in-100-sekunden/" />
+ <podcast name="Tagesthemen" url="http://www.tagesschau.de/export/video-podcast/tagesthemen/" />
+ <podcast name="Nachtmagazin" url="http://www.tagesschau.de/export/video-podcast/nachtmagazin/" />
+ <podcast name="Bericht aus Berlin" url="http://www.tagesschau.de/export/video-podcast/bab/" />
+ <podcast name="Wochenspiegel" url="http://www.tagesschau.de/export/video-podcast/wochenspiegel/" />
+ </provider>
+ <provider name="Pro 7" >
+ <podcast name="Germany's next Topmodel" url="http://pro7-topmodel.feedplace.de/rss+all" />
+ <podcast name="Look of Love - Neuer Style für die Liebe" url="http://prosieben-look-of-love.feedplace.de/rss+all" />
+ <podcast name="Mascerade - Deutschland verbiegt sich" url="http://prosieben-mascerade.feedplace.de/rss+all" />
+ <podcast name="Deine Chance! 3 Bewerber - 1 Job" url="http://prosieben-deinechance.feedplace.de/rss+all" />
+ <podcast name="Galileo - 100 Sekunden" url="http://prosieben-galileo-100sek.feedplace.de/rss+all" />
+ <podcast name="We are Family! So lebt Deutschland." url="http://prosieben-wearefamily.feedplace.de/rss+all" />
+ <podcast name="WipeOut - Heul nicht, lauf!" url="http://prosieben-wipeout.feedplace.de/rss+all" />
+ <podcast name="red! Stylomat" url="http://prosieben-red-stylomat.feedplace.de/rss+all" />
+ <podcast name="Comedystreet" url="http://prosieben-comedystreet.feedplace.de/rss+all" />
+ <podcast name="Queensberry TV" url="http://prosieben-queensberry.feedplace.de/rss+all" />
+ <podcast name="Switch reloaded" url="http://prosieben-switch-reloaded.feedplace.de/rss+all" />
+ <podcast name="U 20 - Deutschland, Deine Teenies" url="http://prosieben-u20.feedplace.de/rss+all" />
+ <podcast name="Kalkofes Mattscheibe" url="http://prosieben-kalkofes-mattscheibe.feedplace.de/rss+all" />
+ <podcast name="Galileo" url="http://pro7-galileo.feedplace.de/rss+all" />
+ <podcast name="Quatsch Comedy Club" url="http://pro7-quatschcomedyclub.feedplace.de/rss+all" />
+ <podcast name="Blockbuster TV" url="http://pro7-blockbuster-tv.feedplace.de/rss+all" />
+ <podcast name="SevenGames TV" url="http://pro7-sevengames.feedplace.de/rss+all" />
+ <podcast name="taff" url="http://pro7-taff.feedplace.de/rss" />
+ <podcast name="SAM" url="http://pro7-sam.feedplace.de/rss" />
+ <podcast name="The next Uri Geller" url="http://pro7-urigeller.feedplace.de/rss+all" />
+ <podcast name="POPSTARS - Just 4 Girls!" url="http://pro7-popstars.feedplace.de/rss" />
+ <podcast name="Sexreport 2008" url="http://prosieben-sexreport.feedplace.de/rss+all" />
+ <podcast name="Jana Ina und Giovanni - Wir sind schwanger" url="http://prosieben-janaina-und-giovanni.feedplace.de/rss+all" />
+ <podcast name="Sarah und Marc crazy in Love" url="http://prosieben-sarah-marc-crazy-in-love.feedplace.de/rss+all" />
+ <podcast name="Gülcan und Collien ziehen aufs Land" url="http://prosieben-guelcan-und-collien-ziehen-aufs-lan.feedplace.de/rss+all" />
+ <podcast name="Das Model und der Freak" url="http://pro7-modelfreak.feedplace.de/rss" />
+ <podcast name="The Next Fashion Talent" url="http://prosieben-thenextfashiontalent.feedplace.de/rss+all" />
+ <podcast name="Afterworld" url="http://prosieben-afterworld.feedplace.de/rss+all" />
+ <podcast name="Check It Out" url="http://prosieben-check-it-out.feedplace.de/rss+all" />
+ <podcast name="Hot Shots" url="http://prosieben-hotshots.feedplace.de/rss+all" />
+ <podcast name="Gina-Lisas Welt!" url="http://prosieben-gina-lisas-welt.feedplace.de/rss+all" />
+ <podcast name="Deutschlands sexiest Platte" url="http://prosieben-sam-sexiest-platte.feedplace.de/rss+all" />
+ <podcast name="UNSCHULDIG" url="http://prosieben-unschuldig.feedplace.de/rss+all" />
+ <podcast name="WE LOVE in concert: iTunes Live: Berlin Festival" url="http://prosieben-we-love-in-concert.feedplace.de/rss+all" />
+ <podcast name="Schlüsselreiz" url="http://pro7-schluesselreiz.feedplace.de/rss+all" />
+ <podcast name="FC Bayern München" url="http://pro7-fcbayern.feedplace.de/rss+all" />
+ </provider>
+ <provider name="RTL" >
+ <podcast name="RTL Aktuell" url="http://rtl-rtl-aktuell.feedplace.de/rss" />
+ <podcast name="RTL Nachtjournal" url="http://rtl-rtl-nachtjournal.feedplace.de/rss" />
+ <podcast name="RTL News kompakt" url="http://rtl-rtl-news-kompakt.feedplace.de/rss" />
+ <podcast name="RTL Aktuell (Audio)" url="http://rtl-rtl-aktuell-audio.feedplace.de/rss" />
+ <podcast name="Die Punkt 12 Reporter" url="http://rtl-punkt-12-reporter.feedplace.de/rss" />
+ <podcast name="Der Punkt 12 Test!" url="http://rtl-punkt-12-test.feedplace.de/rss" />
+ <podcast name="Punkt 12 kompakt" url="http://rtl-punkt-12-kompakt.feedplace.de/rss" />
+ <podcast name="RTL Exclusiv" url="http://rtl-rtl-exclusiv.feedplace.de/rss" />
+ <podcast name="RTL Exclusiv kompakt" url="http://rtl-exclusiv-kompakt.feedplace.de/rss" />
+ <podcast name="RTL Explosiv" url="http://rtl-rtl-explosiv.feedplace.de/rss" />
+ <podcast name="EXTRA kompakt - Das RTL Magazin" url="http://rtl-extra-kompakt.feedplace.de/rss" />
+ <podcast name="AWZ (Vorschau)" url="http://rtl-awz-folgenvorschau.feedplace.de/rss" />
+ <podcast name="GZSZ (Vorschau)" url="http://rtl-gzsz.feedplace.de/rss" />
+ <podcast name="Unter uns (Vorschau)" url="http://rtl-unteruns-folgenvorschau.feedplace.de/rss" />
+ </provider>
+ <provider name="Sat 1" >
+ <podcast name="Bunkershow" url="http://sat1comedy-bunkershow.feedplace.de/rss+all" />
+ <podcast name="Slam Tour mit Kuttner" url="http://sat1comedy-slamtour.feedplace.de/rss+all" />
+ <podcast name="Sat.1 Comedy on Stage" url="http://sat1comedy-onstage.feedplace.de/rss+all" />
+ <podcast name="Poetry Comedy" url="http://sat1-poetrycomedy.feedplace.de/rss+all" />
+ <podcast name="Slam Palast" url="http://sat1comedy-slampalast.feedplace.de/rss+all" />
+ </provider>
+ <provider name="ZDF" >
+ <podcast name="Berlinale 2008" url="http://www.zdf.de/ZDFmediathek/content/426566?view=podcast" />
+ <podcast name="Das aktuelle sportstudio" url="http://www.zdf.de/ZDFmediathek/content/440294?view=podcast" />
+ <podcast name="Forum am freitag" url="http://content.zdf.de/podcast/zdf_podcasts/forum_v.xml" />
+ <podcast name="heute - die aktuelle 19 Uhr-Nachrichtensendung" url="http://content.zdf.de/podcast/zdf_heute/heute.xml" />
+ <podcast name="heute-journal - das aktuelle Nachrichtenmagazin" url="http://content.zdf.de/podcast/zdf_hjo/hjo.xml" />
+ <podcast name="Lanz kocht" url="http://www.zdf.de/ZDFmediathek/content/362696?view=podcast" />
+ <podcast name="logo! Deine Nachrichten" url="http://content.zdf.de/podcast/zdf_logo/logo_v.xml" />
+ <podcast name="Momasurfer vom Morgenmagazin" url="http://www.zdf.de/ZDFmediathek/content/399788?view=podcast" />
+ <podcast name="Neues aus der Anstalt" url="http://content.zdf.de/podcast/zdf_neuada/neuada_v.xml" />
+ <podcast name="Godpod" url="http://content.zdf.de/podcast/zdf_kirche/kirche_v.xml" />
+ <podcast name="Toll! Satire von Doyé und Wiemers" url="http://content.zdf.de/podcast/zdf_f21/f21toll_v.xml" />
+ <podcast name="Wetten, dass...?" url="http://content.zdf.de/podcast/zdf_wd/wd_v.xml" />
+ <podcast name="German Dream - Träumen für Deutschland" url="http://modul.germandream.zdf.de/RSS/" />
+ </provider>
+ </language>
+</podcasts> diff --git a/podcast/po/Makefile.am b/podcast/po/Makefile.am new file mode 100644 index 0000000..eeb585a --- /dev/null +++ b/podcast/po/Makefile.am @@ -0,0 +1,57 @@ +# +# to use this for the localisation of other plugins, +# just change the DOMAIN to the name of the Plugin. +# It is assumed, that the domain ist the same as +# the directory name of the plugin. +# + +DOMAIN=Podcast +installdir = /usr/lib/enigma2/python/Plugins/Extensions/$(DOMAIN) +#GETTEXT=./pygettext.py +GETTEXT=xgettext + +#MSGFMT = ./msgfmt.py +MSGFMT = msgfmt + +LANGS := de tr +LANGPO := $(foreach LANG, $(LANGS),$(LANG).po) +LANGMO := $(foreach LANG, $(LANGS),$(LANG).mo) + +default: $(DOMAIN).pot $(LANGPO) merge $(LANGMO) + for lang in $(LANGS); do \ + mkdir -p $$lang/LC_MESSAGES; \ + cp $$lang.mo $$lang/LC_MESSAGES/$(DOMAIN).mo; \ + done + +merge: + for lang in $(LANGS); do \ + msgmerge --no-location -s -N -U $$lang.po $(DOMAIN).pot; \ + done + + +# the TRANSLATORS: allows putting translation comments before the to-be-translated line. +$(DOMAIN).pot: + $(GETTEXT) -L python --add-comments="TRANSLATORS:" -d $(DOMAIN) -s -o $(DOMAIN).pot ../src/*.py + msguniq -o $(DOMAIN)uniq.pot $(DOMAIN).pot + $(RM) $(DOMAIN).pot + mv $(DOMAIN)uniq.pot $(DOMAIN).pot + +.PHONY: $(DOMAIN).pot + + +%.mo: %.po + $(MSGFMT) -o $@ $< + +%.po: + msginit -l $@ -o $@ -i $(DOMAIN).pot --no-translator + +CLEANFILES = $(foreach LANG, $(LANGS),$(LANG).mo) + +clean-local: + $(RM) -r $(LANGS) + +install-data-am: default + for lang in $(LANGS); do \ + mkdir -p $(DESTDIR)$(installdir)/locale/$$lang/LC_MESSAGES; \ + cp $$lang.mo $(DESTDIR)$(installdir)/locale/$$lang/LC_MESSAGES/$(DOMAIN).mo; \ + done diff --git a/podcast/po/Podcast.pot b/podcast/po/Podcast.pot new file mode 100644 index 0000000..693b7af --- /dev/null +++ b/podcast/po/Podcast.pot @@ -0,0 +1,152 @@ +msgid "" +msgstr "" +"Project-Id-Version: Podcast\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-06 06:40-0000\n" +"PO-Revision-Date: \n" +"Last-Translator: Nabil Hanna <nabil1978@web.de>\n" +"Language-Team: Nabil Hanna <nabil1978@web.de>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast\n" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:207 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:716 +msgid "delete" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +msgid "keep on device" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:209 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:718 +msgid "ask me" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:113 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:164 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:288 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:318 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:347 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:379 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:442 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:498 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:552 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:605 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:661 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:679 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:763 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:820 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:873 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:925 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:956 +msgid "Podcast" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:125 +#, python-format +msgid "Downloading movie: %s" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:210 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:719 +msgid "Delete this movie?" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:243 +msgid "Error getting movies" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Date" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Length" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Type" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:428 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:489 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:538 +msgid "Error getting genres" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:433 +msgid "Error getting rss feed" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:557 +msgid "Select" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:610 +msgid "Save" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:622 +msgid "Buffer:" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:623 +msgid "Buffer device:" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:624 +msgid "Buffer file handling:" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:749 +msgid "Error getting episodes" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:754 +msgid "Error getting podcast url" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:801 +msgid " (Audio)" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:803 +msgid " (Video)" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:811 +msgid "Error getting podcasts" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:864 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:916 +msgid "Error getting categories" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:934 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:941 +msgid "podcast.de" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:935 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:943 +msgid "podcast.com" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:936 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:945 +msgid "from xml" +msgstr "" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:937 +msgid "configuration" +msgstr "" + diff --git a/podcast/po/de.po b/podcast/po/de.po new file mode 100644 index 0000000..bed99ba --- /dev/null +++ b/podcast/po/de.po @@ -0,0 +1,152 @@ +msgid "" +msgstr "" +"Project-Id-Version: Podcast\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-06 06:40-0000\n" +"PO-Revision-Date: \n" +"Last-Translator: Nabil Hanna <nabil1978@web.de>\n" +"Language-Team: Nabil Hanna <nabil1978@web.de>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast\n" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:207 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:716 +msgid "delete" +msgstr "lösche" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +msgid "keep on device" +msgstr "behalte auf Gerät" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:49 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:209 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:718 +msgid "ask me" +msgstr "frage mich" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:113 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:164 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:288 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:318 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:347 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:379 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:442 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:498 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:552 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:605 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:661 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:679 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:763 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:820 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:873 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:925 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:956 +msgid "Podcast" +msgstr "Podcast" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:125 +#, python-format +msgid "Downloading movie: %s" +msgstr "Film wird heruntergeladen: %s" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:210 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:719 +msgid "Delete this movie?" +msgstr "Diesen Film löschen?" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:243 +msgid "Error getting movies" +msgstr "Fehler beim Ermitteln der Filme" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Date" +msgstr "Datum" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Length" +msgstr "Länge" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:252 +msgid "Type" +msgstr "Typ" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:428 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:489 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:538 +msgid "Error getting genres" +msgstr "Fehler beim Ermitteln des Genres" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:433 +msgid "Error getting rss feed" +msgstr "Fehler beim Ermitteln des rss-Feeds" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:557 +msgid "Select" +msgstr "Selektiere" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:610 +msgid "Save" +msgstr "Speichern" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:622 +msgid "Buffer:" +msgstr "Puffer:" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:623 +msgid "Buffer device:" +msgstr "Puffergerät:" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:624 +msgid "Buffer file handling:" +msgstr "Behandlung der Pufferdatei:" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:749 +msgid "Error getting episodes" +msgstr "Fehler beim Ermitteln der Episoden" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:754 +msgid "Error getting podcast url" +msgstr "Fehler beim Ermitteln der podcast url" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:801 +msgid " (Audio)" +msgstr " (Audio)" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:803 +msgid " (Video)" +msgstr " (Video)" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:811 +msgid "Error getting podcasts" +msgstr "Fehler beim Ermitteln der Podcasts" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:864 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:916 +msgid "Error getting categories" +msgstr "Fehler beim Ermitteln der Kategorien" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:934 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:941 +msgid "podcast.de" +msgstr "podcast.de" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:935 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:943 +msgid "podcast.com" +msgstr "podcast.com" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:936 +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:945 +msgid "from xml" +msgstr "aus xml" + +#: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast/plugin.py:937 +msgid "configuration" +msgstr "Konfiguration" + diff --git a/podcast/po/tr.po b/podcast/po/tr.po new file mode 100644 index 0000000..f5b2b26 --- /dev/null +++ b/podcast/po/tr.po @@ -0,0 +1,97 @@ +msgid "" +msgstr "" +"Project-Id-Version: Podcast plugin Turkish locale\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-06 07:30+0000\n" +"PO-Revision-Date: 2009-06-06 23:53+0200\n" +"Last-Translator: Zülfikar VEYİSOĞLU <z.veyisoglu@hobiagaci.com>\n" +"Language-Team: http://hobiagaci.com <z.veyisoglu@hobiagaci.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: /home/aliabdul/dream/ali/enigma2/ali-image/usr/lib/enigma2/python/Plugins/Extensions/Podcast\n" + +msgid " (Audio)" +msgstr " (Ses)" + +msgid " (Video)" +msgstr " (Video)" + +msgid "Buffer device:" +msgstr "Tampon aygıtı:" + +msgid "Buffer file handling:" +msgstr "Tampon dosyası işleme:" + +msgid "Buffer:" +msgstr "Tampon:" + +msgid "Date" +msgstr "Tarih" + +msgid "Delete this movie?" +msgstr "Bu film silmek istiyor musunuz?" + +msgid "Downloading movie: %s" +msgstr "%s filmi indiriliyor!" + +msgid "Error getting categories" +msgstr "Kategoriler getirilirken hata oluştu" + +msgid "Error getting episodes" +msgstr "Bölümler getirilirken hata oluştu" + +msgid "Error getting genres" +msgstr "Türler getirilirken hata oluştu" + +msgid "Error getting movies" +msgstr "Filmler getirilirken hata oluştu" + +msgid "Error getting podcast url" +msgstr "Podcast adresi getirilirken hata oluştu" + +msgid "Error getting podcasts" +msgstr "Podcastler getirilirken hata oluştu" + +msgid "Error getting rss feed" +msgstr "RSS beslemesi getirilirken hata oluştu" + +msgid "Length" +msgstr "Boyut" + +msgid "Podcast" +msgstr "Podcast" + +msgid "Save" +msgstr "Kaydet" + +msgid "Select" +msgstr "Seç" + +msgid "Type" +msgstr "Tip" + +msgid "ask me" +msgstr "sor" + +msgid "configuration" +msgstr "ayarlar" + +msgid "delete" +msgstr "sil" + +msgid "from xml" +msgstr "xml'den al" + +msgid "keep on device" +msgstr "cihazda tut" + +msgid "podcast.com" +msgstr "podcast.com" + +msgid "podcast.de" +msgstr "podcast.de" + diff --git a/podcast/src/LICENSE.txt b/podcast/src/LICENSE.txt new file mode 100644 index 0000000..d36f684 --- /dev/null +++ b/podcast/src/LICENSE.txt @@ -0,0 +1,14 @@ +Author: Nabil Hanna, AliAbdul + +All Files of this Software are licensed under the Creative Commons +Attribution-NonCommercial-ShareAlike 3.0 Unported +License if not stated otherwise in a Files Head. To view a copy of this license, visit +http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + +Alternatively, this plugin may be distributed and executed on hardware which +is licensed by Dream Multimedia GmbH. + +This plugin is NOT free software. It is open source, you are allowed to +modify it (if you keep the license), but it may not be commercially +distributed other than under the conditions noted above. diff --git a/podcast/src/Makefile.am b/podcast/src/Makefile.am new file mode 100644 index 0000000..d67fbc8 --- /dev/null +++ b/podcast/src/Makefile.am @@ -0,0 +1,3 @@ +installdir = /usr/lib/enigma2/python/Plugins/Extensions/Podcast +install_PYTHON = *.py +install_DATA = LICENSE.txt maintainer.info diff --git a/podcast/src/__init__.py b/podcast/src/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/podcast/src/__init__.py diff --git a/podcast/src/maintainer.info b/podcast/src/maintainer.info new file mode 100644 index 0000000..4af9d60 --- /dev/null +++ b/podcast/src/maintainer.info @@ -0,0 +1,2 @@ +nabil1978@web.de +Podcast diff --git a/podcast/src/plugin.py b/podcast/src/plugin.py new file mode 100644 index 0000000..1b629d4 --- /dev/null +++ b/podcast/src/plugin.py @@ -0,0 +1,983 @@ +## +## Podcast +## by AliAbdul +## +from Components.ActionMap import ActionMap +from Components.config import config, ConfigSelection, ConfigSubsection, ConfigText, ConfigYesNo, getConfigListEntry +from Components.ConfigList import ConfigListScreen
+from Components.FileList import FileList +from Components.Label import Label +from Components.Language import language
+from Components.MenuList import MenuList +from Components.PluginComponent import plugins +from Components.ProgressBar import ProgressBar
+from enigma import eServiceReference, eTimer +from os import environ, remove +from Plugins.Plugin import PluginDescriptor +from Screens.InfoBar import MoviePlayer +from Screens.MessageBox import MessageBox +from Screens.Screen import Screen +from Tools.BoundFunction import boundFunction +from Tools.Directories import fileExists, resolveFilename, SCOPE_LANGUAGE, SCOPE_PLUGINS +from Tools.Downloader import downloadWithProgress +from twisted.web.client import getPage +from xml.etree.cElementTree import parse +import gettext, re + +################################################### + +def localeInit(): + lang = language.getLanguage() + environ["LANGUAGE"] = lang[:2]
+ gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))
+ gettext.textdomain("enigma2") + gettext.bindtextdomain("Podcast", "%s%s" % (resolveFilename(SCOPE_PLUGINS), "Extensions/Podcast/locale/")) + +def _(txt):
+ t = gettext.dgettext("Podcast", txt)
+ if t == txt:
+ t = gettext.gettext(txt)
+ return t + +localeInit()
+language.addCallback(localeInit) + +################################################### + +class ChangedMoviePlayer(MoviePlayer): + def __init__(self, session, service): + MoviePlayer.__init__(self, session, service) + + def leavePlayer(self): + self.session.openWithCallback(self.leavePlayerConfirmed, MessageBox, _("Stop playing this movie?")) + + def leavePlayerConfirmed(self, answer): + if answer: + self.close() + + def doEofInternal(self, playing): + pass + + def getPluginList(self): + list = [] + for p in plugins.getPlugins(where=PluginDescriptor.WHERE_EXTENSIONSMENU): + if p.name != _("Podcast"): + list.append(((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None)) + return list + + def showMovies(self): + pass + +################################################### + +config.plugins.Podcast = ConfigSubsection() +config.plugins.Podcast.buffer = ConfigYesNo(default=True) +config.plugins.Podcast.bufferDevice = ConfigText(default="/media/hdd/", fixed_size=False) +config.plugins.Podcast.keepStored = ConfigSelection(choices={"delete": _("delete"), "keep": _("keep on device"), "ask": _("ask me")}, default="delete") + +################################################### + +def encodeUrl(url): + url = url.replace("&", "&") + url = url.replace("<", "<") + url = url.replace(">", ">") + url = url.replace("'", "'") + url = url.replace(""", '"') + url = url.replace("*", "*") + url = url.replace("|", "|") + url = url.replace("'", "'") + url = url.replace("»", ">>") + return url + +################################################### + +class BufferThread(): + def __init__(self): + self.progress = 0 + self.downloading = False + self.error = "" + self.download = None + + def startDownloading(self, url, file): + self.progress = 0 + self.downloading = True + self.error = "" + self.download = downloadWithProgress(url, file) + self.download.addProgress(self.httpProgress) + self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed) + + def httpProgress(self, recvbytes, totalbytes): + self.progress = int(100 * recvbytes / float(totalbytes)) + + def httpFinished(self, string=""): + self.downloading = False + if string is not None: + self.error = str(string) + else: + self.error = "" + + def httpFailed(self, failure_instance=None, error_message=""): + self.downloading = False + if error_message == "" and failure_instance is not None: + error_message = failure_instance.getErrorMessage() + self.error = str(error_message) + + def stop(self): + self.progress = 0 + self.downloading = False + self.error = "" + self.download.stop() + +bufferThread = BufferThread() + +################################################### + +class PodcastBuffer(Screen): + skin = """ + <screen position="center,center" size="520,80" title="%s" >
+ <widget name="info" position="5,5" size="510,40" font="Regular;18" halign="center" valign="center" /> + <widget name="progress" position="100,50" size="320,14" pixmap="skin_default/progress_big.png" borderWidth="2" borderColor="#cccccc" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, url, file): + self.session = session + Screen.__init__(self, session) + + self.url = url + self.file = file + + self.infoTimer = eTimer() + self.infoTimer.timeout.get().append(self.updateInfo) + + self["info"] = Label(_("Downloading movie: %s") % self.file) + self["progress"] = ProgressBar() + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.okClicked, "cancel": self.exit}, -1) + + self.onLayoutFinish.append(self.downloadMovie) + + def downloadMovie(self): + bufferThread.startDownloading(self.url, self.file) + self.infoTimer.start(300, False) + + def updateInfo(self): + if bufferThread.error != "": + self["info"].setText(bufferThread.error) + self.infoTimer.stop() + else: + progress = int(bufferThread.progress) + self["progress"].setValue(progress) + if progress == 100: + self.infoTimer.stop() + self.close(True) + + def okClicked(self): + if int(bufferThread.progress) > 0: + self.infoTimer.stop() + self.close(True) + + def exit(self): + bufferThread.download.stop() + self.close(None) + +################################################### + +class PodcastMovies(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" >
+ <widget name="list" position="5,5" size="410,250" scrollbarMode="showOnDemand" />
+ <eLabel position="5,260" size="420,2" backgroundColor="#ffffff" />
+ <widget name="info" position="5,265" size="420,90" font="Regular;18" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self.url = url + self.list = [] + self.movies = [] + self.working = True + + self["list"] = MenuList([]) + self["list"].onSelectionChanged.append(self.showInfo) + self["info"] = Label() + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + if len(self.list) > 0:
+ idx = self["list"].getSelectionIndex()
+ (url, length, type) = self.splitExtraInfo(self.movies[idx][2]) + if config.plugins.Podcast.buffer.value: + file = url + while file.__contains__("/"): + idx = file.index("/") + file = file[idx+1:] + self.file = "%s%s" % (config.plugins.Podcast.bufferDevice.value, file) + self.session.openWithCallback(self.bufferCallback, PodcastBuffer, url, self.file) + else: + ref = eServiceReference(4097, 0, url) + self.session.open(ChangedMoviePlayer, ref) + + def bufferCallback(self, callback): + if callback is not None: + ref = eServiceReference(4097, 0, self.file) + self.session.openWithCallback(self.delete, ChangedMoviePlayer, ref) + + def delete(self, callback=None): + if bufferThread.downloading: #still downloading? + bufferThread.stop() + if config.plugins.Podcast.keepStored.value == "delete": + remove(self.file) + elif config.plugins.Podcast.keepStored.value == "ask": + self.session.openWithCallback(self.deleteCallback, MessageBox, _("Delete this movie?")) + + def deleteCallback(self, callback): + if callback: + remove(self.file) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage(self.url).addCallback(self.showMovies).addErrback(self.error) + + def showMovies(self, page): + reonecat = re.compile(r'<title>(.+?)</title>.+?<description>(.+?)</description>.+?<pubDate>(.+?)</pubDate>.+?<enclosure(.+?)/>.+?', re.DOTALL)
+ for title, description, pubDate, extra in reonecat.findall(page): + if title.startswith("<![CDATA["): + title = title[9:] + if title.endswith("]]>"): + title = title[:-3] + if description.__contains__("<![CDATA["): + idx = description.index("<![CDATA[") + description = description[idx+10:] + if description.endswith("]]>"): + description = description[:-3]
+ self.list.append(encodeUrl(title))
+ self.movies.append([description, pubDate, extra])
+ self["list"].setList(self.list)
+ self.showInfo() + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting movies")) + self.working = False
+
+ def showInfo(self):
+ if len(self.list) > 0:
+ idx = self["list"].getSelectionIndex()
+ description = self.movies[idx][0]
+ pubDate = self.movies[idx][1]
+ (url, length, type) = self.splitExtraInfo(self.movies[idx][2])
+ self["info"].setText("%s: %s\n%s: %s %s: %s\n%s" % (_("Date"), pubDate, _("Length"), length, _("Type"), type, encodeUrl(description)))
+
+ def splitExtraInfo(self, info):
+ if info.__contains__('url="'):
+ idx = info.index('url="')
+ url = info[idx+5:]
+ idx = url.index('"')
+ url = url[:idx]
+ else:
+ url = "N/A"
+
+ if info.__contains__('length="'):
+ idx = info.index('length="')
+ length = info[idx+8:]
+ idx = length.index('"')
+ length = length[:idx]
+ length = str((int(length) / 1024) / 1024) + " MB"
+ else:
+ length = "N/A"
+
+ if info.__contains__('type="'):
+ idx = info.index('type="')
+ type = info[idx+6:]
+ idx = type.index('"')
+ type = type[:idx]
+ else:
+ type = "N/A"
+
+ return (url, length, type) + +################################################### + +class PodcastPodcasts(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" >
+ <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, provider): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.close}, -1) + + self.urls = [] + list = [] + for podcast in provider.findall("podcast"): + name = podcast.get("name") or None + name = name.encode("UTF-8") or name + url = podcast.get("url") or None + if name and url: + list.append(name) + self.urls.append(url) + self["list"] = MenuList(list) + + def ok(self): + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastMovies, cur) + +################################################### + +class PodcastProvider(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, language): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.close}, -1) + + self.providers = [] + list = [] + for provider in language.findall("provider"): + name = provider.get("name") or None + name = name.encode("UTF-8") or name + if name: + list.append(name) + self.providers.append(provider) + self["list"] = MenuList(list) + + def ok(self): + if len(self.providers) > 0: + cur = self.providers[self["list"].getSelectedIndex()] + self.session.open(PodcastPodcasts, cur) + +################################################### + +class PodcastXML(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" >
+ <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.close}, -1) + + self.languages = [] + list = [] + file = "/etc/podcast/podcasts.xml" + if fileExists(file): + xml = parse(file).getroot() + for language in xml.findall("language"): + name = language.get("name") or None + name = name.encode("UTF-8") or name + if name: + list.append(name) + self.languages.append(language) + self["list"] = MenuList(list) + + def ok(self): + if len(self.languages) > 0: + cur = self.languages[self["list"].getSelectedIndex()] + self.session.open(PodcastProvider, cur) + +################################################### + +class PodcastComGenre2(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" >
+ <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self.url = url + self.urls = [] + self.working = True + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadGenres) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + self.working = True + cur = self.urls[self["list"].getSelectedIndex()] + getPage(cur).addCallback(self.getRssUrl).addErrback(self.error2) + + def getRssUrl(self, page): + idx = page.index('">rss feed</a><br>') + page = page[:idx] + while page.__contains__("http://"): + idx = page.index("http://") + page = page[idx+1:] + self.working = False + self.session.open(PodcastMovies, "h%s"%page) + + def exit(self): + if self.working == False: + self.close() + + def downloadGenres(self): + getPage(self.url).addCallback(self.getGenres).addErrback(self.error) + + def getGenres(self, page): + list = [] + reonecat = re.compile(r'height="19"><a href="(.+?)">(.+?)</a>', re.DOTALL)
+ for url, title in reonecat.findall(page):
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting genres")) + self.working = False + + def error2(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting rss feed")) + self.working = False + +################################################### + +class PodcastComGenre(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self.url = url + self.urls = [] + self.working = True + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadSite) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastComGenre2, cur) + + def exit(self): + if self.working == False: + self.close() + + def downloadSite(self): + getPage(self.url).addCallback(self.getUrl).addErrback(self.error) + + def getUrl(self, page): + reonecat = re.compile(r'Get this podcast channel on your mobile phone:</strong><br><a href="(.+?)"', re.DOTALL) + list = reonecat.findall(page) + if len(list) > 0: + getPage(list[0]).addCallback(self.getGenres).addErrback(self.error) + else: + self.error("Error getting movies-url") + + def getGenres(self, page): + list = [] + reonecat = re.compile(r'height="17"><a title="(.+?)" href="(.+?)">(.+?)</a>', re.DOTALL)
+ for title2, url, title in reonecat.findall(page):
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting genres")) + self.working = False + +################################################### + +class PodcastCom(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self.working = True + self.urls = [] + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastComGenre, cur) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage("http://podcast.com/home.php?subpage=_pages/channels_home.php").addCallback(self.showGenres).addErrback(self.error) + + def showGenres(self, page): + list = [] + reonecat = re.compile(r'<li><a href="(.+?)" title="(.+?)">(.+?)</a></li>', re.DOTALL)
+ for url, title2, title in reonecat.findall(page): + if not title.startswith("<"):
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting genres")) + self.working = False + +################################################### + +class LocationSelection(Screen): + skin = """ + <screen position="center,center" size="560,300" title="%s"> + <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" /> + <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" /> + <widget name="filelist" position="10,45" size="550,255" scrollbarMode="showOnDemand" /> + </screen>""" % _("Podcast")
+
+ def __init__(self, session, dir="/"):
+ Screen.__init__(self, session)
+
+ self["key_green"] = Label(_("Select"))
+
+ try: self["filelist"] = FileList(dir, showDirectories=True, showFiles=False)
+ except: self["filelist"] = FileList("/", showDirectories, showFiles)
+
+ self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],
+ {
+ "ok": self.okClicked,
+ "cancel": self.exit,
+ "green": self.select
+ }, -1) + + self.onLayoutFinish.append(self.updateDirectoryName)
+
+ def okClicked(self):
+ if self["filelist"].canDescent():
+ self["filelist"].descent()
+ self["filelist"].instance.moveSelectionTo(0)
+ self.updateDirectoryName()
+
+ def exit(self):
+ self.close(None)
+
+ def select(self):
+ dir = self["filelist"].getCurrentDirectory()
+ if dir is not None:
+ self.close(dir)
+ else:
+ self.close(None)
+
+ def updateDirectoryName(self): + try: + dir = self["filelist"].getCurrentDirectory() + self.instance.setTitle(dir) + except: + self.instance.setTitle("?") + +################################################### + +class PodcastConfig(ConfigListScreen, Screen): + skin = """ + <screen position="center,center" size="560,180" title="%s"> + <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" /> + <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" /> + <widget name="config" position="10,45" size="550,125" scrollbarMode="showOnDemand" /> + </screen>""" % _("Podcast") + + def __init__(self, session): + Screen.__init__(self, session) + + self["key_green"] = Label(_("Save")) + + ConfigListScreen.__init__(self, []) + + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], {"green": self.save, "cancel": self.exit}, -1) + + self.onLayoutFinish.append(self.createConfig) + + def createConfig(self): + self.deviceEntry = ConfigSelection(choices=[config.plugins.Podcast.bufferDevice.value], default=config.plugins.Podcast.bufferDevice.value) + self["config"].list = [ + getConfigListEntry(_("Buffer:"), config.plugins.Podcast.buffer), + getConfigListEntry(_("Buffer device:"), self.deviceEntry), + getConfigListEntry(_("Buffer file handling:"), config.plugins.Podcast.keepStored)] + + def keyLeft(self): + ConfigListScreen.keyLeft(self) + self.handleKeysLeftAndRight() + + def keyRight(self): + ConfigListScreen.keyRight(self) + self.handleKeysLeftAndRight() + + def handleKeysLeftAndRight(self): + sel = self["config"].getCurrent()[1] + if sel == self.deviceEntry: + self.session.openWithCallback(self.locationSelected, LocationSelection, config.plugins.Podcast.bufferDevice.value) + + def locationSelected(self, dir): + if dir is not None and dir != "?": + config.plugins.Podcast.bufferDevice.value = dir + config.plugins.Podcast.bufferDevice.save() + self.createConfig() + + def save(self): + for x in self["config"].list: + x[1].save() + self.close() + + def exit(self): + for x in self["config"].list: + x[1].cancel() + self.close() + +################################################### + +class PodcastDeEpisodes(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") + + def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self.working = True + self.url = url + self.urls = [] + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + self.instance.setTitle(_("Podcast")) + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.working = True + getPage(cur).addCallback(self.playPodcast).addErrback(self.error2) + + def playPodcast(self, url): + if url.__contains__('" id="control_download"'): + self.working = False + idx = url.index('" id="control_download"') + url = url[:idx] + while url.__contains__("http://"): + idx = url.index("http://") + url = url[idx+1:] + url = "h%s"%url + + if config.plugins.Podcast.buffer.value: + file = url + while file.__contains__("/"): + idx = file.index("/") + file = file[idx+1:] + self.file = "%s%s" % (config.plugins.Podcast.bufferDevice.value, file) + self.session.openWithCallback(self.bufferCallback, PodcastBuffer, url, self.file) + else: + ref = eServiceReference(4097, 0, url) + self.session.open(ChangedMoviePlayer, ref) + else: + self.error2() + + def bufferCallback(self, callback): + if callback is not None: + ref = eServiceReference(4097, 0, self.file) + self.session.openWithCallback(self.delete, ChangedMoviePlayer, ref) + + def delete(self, callback=None): + if bufferThread.downloading: #still downloading? + bufferThread.stop() + if config.plugins.Podcast.keepStored.value == "delete": + remove(self.file) + elif config.plugins.Podcast.keepStored.value == "ask": + self.session.openWithCallback(self.deleteCallback, MessageBox, _("Delete this movie?")) + + def deleteCallback(self, callback): + if callback: + remove(self.file) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage(self.url).addCallback(self.showEpisodes).addErrback(self.error) + + def showEpisodes(self, page): + list = [] + idx = page.index('<h3>') + page = page[idx:] + idx = page.index('</div></div>') + page = page[:idx] + reonecat = re.compile(r'<a href="(.+?)" title="(.+?)">', re.DOTALL)
+ for url, title in reonecat.findall(page): + if title.startswith("Episode: "): + title = title[9:]
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting episodes")) + self.working = False + + def error2(self, error=""): + print "[Podcast] Error: Error getting podcast url" + self.instance.setTitle(_("Error getting podcast url")) + self.working = False + +################################################### + +class PodcastDePodcasts(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") + + def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self.working = True + self.url = url + self.urls = [] + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastDeEpisodes, cur) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage(self.url).addCallback(self.showPodcasts).addErrback(self.error) + + def showPodcasts(self, page): + list = [] + idx = page.index('<h4>Podcasts</h4>') + page = page[idx:] + idx = page.index('</div>') + page = page[:idx] + reonecat = re.compile(r'alt="(.+?)" class="(.+?)<a href="(.+?)" title="(.+?)">(.+?)<span class="(.+?)"></span>', re.DOTALL)
+ for title, x, url, x2, x3, type in reonecat.findall(page): + if type.__contains__("content_type_1_icon"): + text = _(" (Audio)") + else: + text = _(" (Video)")
+ list.append(encodeUrl(title+text))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting podcasts")) + self.working = False + +################################################### + +class PodcastDeCategories(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") + + def __init__(self, session, url): + self.session = session + Screen.__init__(self, session) + + self.working = True + self.url = url + self.urls = [] + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastDePodcasts, cur) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage(self.url).addCallback(self.showCategories).addErrback(self.error) + + def showCategories(self, page): + list = [] + idx = page.index('<h3>') + page = page[idx:] + idx = page.index('</div>') + page = page[:idx] + reonecat = re.compile(r'<a href="(.+?)" title="(.+?)">', re.DOTALL)
+ for url, title in reonecat.findall(page):
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting categories")) + self.working = False + +################################################### + +class PodcastDe(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") + + def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self.working = True + self.urls = [] + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.exit}, -1) + + self["list"] = MenuList([]) + + self.onLayoutFinish.append(self.downloadMovies) + + def ok(self): + if self.working == False: + if len(self.urls) > 0: + cur = self.urls[self["list"].getSelectedIndex()] + self.session.open(PodcastDeCategories, cur) + + def exit(self): + if self.working == False: + self.close() + + def downloadMovies(self): + getPage("http://m.podcast.de/kategorien").addCallback(self.showCategories).addErrback(self.error) + + def showCategories(self, page): + list = [] + idx = page.index('<h3>') + page = page[idx:] + idx = page.index('</div>') + page = page[:idx] + reonecat = re.compile(r'<a href="(.+?)" title="(.+?)">', re.DOTALL)
+ for url, title in reonecat.findall(page):
+ list.append(encodeUrl(title))
+ self.urls.append(url)
+ self["list"].setList(list) + self.working = False + + def error(self, error=""): + print "[Podcast] Error:", error + self.instance.setTitle(_("Error getting categories")) + self.working = False + +################################################### + +class Podcast(Screen): + skin = """ + <screen position="center,center" size="420,360" title="%s" > + <widget name="list" position="0,0" size="420,350" scrollbarMode="showOnDemand" />
+ </screen>""" % _("Podcast") +
+ def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.ok, "cancel": self.close}, -1) + + self["list"] = MenuList([ + _("podcast.de"), + _("podcast.com"), + _("from xml"), + _("configuration")]) + + def ok(self): + cur = self["list"].getCurrent() + if cur == _("podcast.de"): + self.session.open(PodcastDe) + elif cur == _("podcast.com"): + self.session.open(PodcastCom) + elif cur == _("from xml"): + self.session.open(PodcastXML) + else: + self.session.open(PodcastConfig) + +################################################### + +def main(session, **kwargs): + session.open(Podcast) + +def Plugins(**kwargs): + return PluginDescriptor(name=_("Podcast"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main) |