From 656bd374116b0da7e42966647023822dc29ee2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 11 Oct 2014 20:42:19 +0200 Subject: [PATCH 001/106] [Web] remove unused static files --- htdocs/media/16x16/emblem-default.png | Bin 962 -> 0 bytes htdocs/media/16x16/server.png | Bin 583 -> 0 bytes htdocs/media/24x24/opml-icon.png | Bin 32952 -> 0 bytes htdocs/media/32x32/audio-x-generic.png | Bin 938 -> 0 bytes htdocs/media/32x32/computer.png | Bin 1674 -> 0 bytes htdocs/media/32x32/server.png | Bin 1202 -> 0 bytes htdocs/media/FontAwesome.ttf | Bin 23156 -> 0 bytes htdocs/media/charts-new.png | Bin 676 -> 0 bytes htdocs/media/dialog-error.png | Bin 1550 -> 0 bytes htdocs/media/emblem-default.png | Bin 2136 -> 0 bytes htdocs/media/img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes htdocs/media/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes htdocs/media/info.png | Bin 1921 -> 0 bytes htdocs/media/mygpo18.png | Bin 1184 -> 0 bytes 14 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 htdocs/media/16x16/emblem-default.png delete mode 100644 htdocs/media/16x16/server.png delete mode 100644 htdocs/media/24x24/opml-icon.png delete mode 100644 htdocs/media/32x32/audio-x-generic.png delete mode 100644 htdocs/media/32x32/computer.png delete mode 100644 htdocs/media/32x32/server.png delete mode 100644 htdocs/media/FontAwesome.ttf delete mode 100644 htdocs/media/charts-new.png delete mode 100644 htdocs/media/dialog-error.png delete mode 100644 htdocs/media/emblem-default.png delete mode 100644 htdocs/media/img/glyphicons-halflings-white.png delete mode 100644 htdocs/media/img/glyphicons-halflings.png delete mode 100644 htdocs/media/info.png delete mode 100644 htdocs/media/mygpo18.png diff --git a/htdocs/media/16x16/emblem-default.png b/htdocs/media/16x16/emblem-default.png deleted file mode 100644 index fb4362c1ba799559eaa5a5626a27c3e8c2d972dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmV;z13mnSP)l`|bnmYF9mp?N7C} z?SDBmJbj7u+;7}j9L125ilXh*#2VSTrA6I2#kP02!ZxBo}(!;%XvQj1{bgOuHMWHeAfS#bzC$YGd4vFW8>|IIwQS9 zpJ3~G0wGDjl&B2?X@Kv6yQ*(t~S)SS2!Mi^m)Y!-tE7;om0Lo4;Jcc`@lINHbN~>0pq!5m4xwal?bWtzbMg9D zEZBeHczILW&hoJ1~fR{qtU+>lY)AgZF# z2lu*;E3K79wD!0%c8<-Fa>|Rh0pK_enZ-Fyojc0F$hQ=Q%gEclb9Z*?tWnY+XP0wU za%**cVEUgaeC^}=K7(Ty2pb!Tg)5nvy~WAzUf}xet4J?MT}dN1CsO&;e{Bo#qzXwxd{_{Q z9DBH?A`~(U@ccYlgTf?dTcjs%<(BR27uwfvrn=qL`_}kBXpa#PuLvO%N(9T$;FAAS kYyYa}=+9H#?%;a=f6Ekc3g^O}4gdfE07*qoM6N<$f|#Jf8~^|S diff --git a/htdocs/media/16x16/server.png b/htdocs/media/16x16/server.png deleted file mode 100644 index 82c9b4beff0256dfe7b22375e97dd54baa0b61b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 583 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 UT0_FksQ>@~07*qoM6N<$g4C@!?*IS* diff --git a/htdocs/media/32x32/server.png b/htdocs/media/32x32/server.png deleted file mode 100644 index 4f863f99c46c9f4a39c2c21cd2deced312fe242b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1202 zcmV;j1Wo&iP)G`9S688Fd1SL0ETA z;9zG?_75o2i7AYX+(ACCZ5SK?0s%k5;gc9R^^y{gKYY>6)|CJug6dZk#72hE*4~C- zZLKE)E9o@8iw)!4**8Impl+D}0Ei-mZs-Ws)?y<5$P=d4pH2=TpL>eh1xqZ zFfib1J2W&@=Ch*&CMPGo0ed9idJQ)VwiTaEXCNMr|NjI;mmXlunTU)rFvbvz#maoP zO+YFEOC%C&K{@B1e6~%X^fZ=bc>>X#mcqdReO>29LC(u%#9U>rMabXF6 z{qZ;afdKY*Jcp@&W~$on+y5*mmDYY=xH>k>41V^bw|f$0*p~w2KGiHTzg5$8h04*-%V=lzO5CCKs${rX-~C7eE)*NxqIod-1= z24~y`fF?iz04h;D)ABSfd~gwxM6s|mkG781swF7;6y?uFflC6&mp}1UCj)x0CSX2Q zBT4l%^~2%&==|+L8jYVzT8?IPgO+UFMZjq&#w;Y~r~f;pYxwm|_~Vo?&TRX=(72}y4R$U2w?y!ez$%6$t3{JohBs_4c&lG_CePT$Q5+arzn@+>glXT)YCGO zs02dD+LO)Z9G%Hl)PxX7CAYv$Ja5Bw1PXyNRWu=FN7k{jMnI%+s_r~1D_H;p*-WmY z2FT-+P(c-OBT!$Q`;TXUG3KgEGf=>&-z)(cfLa6)L}#!R!2x$IQ3^pMrHe}~V3tX> zLWuw?<{0Q&p;Ts6QE2&kByOMrl63UMm_L8(T-0$|S0B%_0ax6Z%* z+8c6XV-p18sb^tXCKgij7#zH%&(0>J0L%hrnYhi9CRJ5;zx&=h7whZl&e)9Ac#2*G z7DzU|oc`vsPcMI%%jJ>)<~B=!!f75E9=B!%u>j}*mav5k6h+!50n^RkUn(io3b)Ns Q_y7O^07*qoM6N<$f(beyY5)KL diff --git a/htdocs/media/FontAwesome.ttf b/htdocs/media/FontAwesome.ttf deleted file mode 100644 index 793a922a0bca0ebd3fb57529eb27b6a6e4e9e048..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23156 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 ABLDyZ diff --git a/htdocs/media/emblem-default.png b/htdocs/media/emblem-default.png deleted file mode 100644 index 05bff579bbf338fcb92f7e41b49e78353cb3c723..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2136 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 B7G?kd diff --git a/htdocs/media/img/glyphicons-halflings.png b/htdocs/media/img/glyphicons-halflings.png deleted file mode 100644 index a9969993201f9cee63cf9f49217646347297b643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12799 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 diff --git a/htdocs/media/info.png b/htdocs/media/info.png deleted file mode 100644 index c3c07e15de54e222cbee38e5151b1d36a3f13760..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1921 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 yPKS}6%Vp9jGn+{n#=~d|nNN_9j{@oc8vh1CCc) Date: Sat, 11 Oct 2014 20:43:38 +0200 Subject: [PATCH 002/106] [Web] split static and media files This is considered best-practice in recent django versions as well as from a operations perspective. Static files are shipped with the application and do not change. Media files originate from untrusted sources, eg user upload, podcast logos, etc. --- .gitignore | 2 +- mygpo/settings.py | 15 +++++++-- mygpo/web/logo.py | 11 ++++--- mygpo/web/templates/404.html | 2 +- mygpo/web/templates/500.html | 2 +- mygpo/web/templates/episode-history.html | 7 ++-- mygpo/web/templates/skeleton.html | 9 ++--- {htdocs => res}/failpodder.svg | 0 .../22x22/internet-web-browser.png | Bin {htdocs/media => static}/22x22/opml-icon.png | Bin {htdocs/media => static}/28x28/feed-icon.png | Bin {htdocs/media => static}/author_subscribe.png | Bin {htdocs => static}/clientconfig.json | 0 {htdocs/media => static}/clients/amarok.png | Bin .../clients/audio-x-generic.png | Bin {htdocs/media => static}/clients/computer.png | Bin {htdocs/media => static}/clients/gpodder.png | Bin .../clients/multimedia-player.png | Bin {htdocs/media => static}/clients/podax.png | Bin {htdocs/media => static}/clients/server.png | Bin .../clients/stock_cell-phone.png | Bin .../clients/stock_notebook.png | Bin .../css/bootstrap-responsive.css | 0 .../css/bootstrap-responsive.min.css | 0 .../media => static}/css/bootstrap-theme.css | 0 .../css/bootstrap-theme.min.css | 0 {htdocs/media => static}/css/bootstrap.css | 0 .../media => static}/css/bootstrap.min.css | 0 {htdocs/media => static/css}/fail.css | 0 .../media => static}/css/font-awesome-ie7.css | 0 .../css/font-awesome-ie7.min.css | 0 {htdocs/media => static}/css/font-awesome.css | 0 .../media => static}/css/font-awesome.min.css | 0 {htdocs/media => static}/delete.png | Bin {htdocs/media => static}/download.png | Bin {htdocs/media => static}/failpodder.png | Bin {htdocs => static}/favicon.ico | Bin {htdocs => static}/favicon.png | Bin .../font/fontawesome-webfont.eot | Bin .../font/fontawesome-webfont.svg | 0 .../font/fontawesome-webfont.svgz | Bin .../font/fontawesome-webfont.ttf | Bin .../font/fontawesome-webfont.woff | Bin {htdocs/media => static}/gpoddernet_228.png | Bin {htdocs/media => static}/gpoddernet_25.png | Bin {htdocs/media => static}/gpoddernet_64.png | Bin .../media => static}/js/bootstrap-dropdown.js | 0 {htdocs/media => static}/js/bootstrap.js | 0 {htdocs/media => static}/js/bootstrap.min.js | 0 {htdocs/media => static}/js/jquery.js | 0 {htdocs/media => static}/js/json2.js | 0 {htdocs/media => static}/js/swfobject.js | 0 .../media => static}/js/youtube-handler.js | 0 .../pod => static/logo}/podcast-0.png | Bin .../pod => static/logo}/podcast-1.png | Bin .../pod => static/logo}/podcast-2.png | Bin .../pod => static/logo}/podcast-3.png | Bin .../pod => static/logo}/podcast-4.png | Bin {htdocs/media => static}/new.png | Bin {htdocs/media => static}/nothing.png | Bin {htdocs/media => static}/playback.png | Bin {htdocs/media => static}/reset.css | 0 {htdocs => static}/robots.txt | 0 {htdocs/media => static}/screen.css | 31 ++++-------------- {htdocs/media => static}/subscribe.png | Bin {htdocs/media => static}/unsubscribe.png | Bin 66 files changed, 37 insertions(+), 42 deletions(-) rename {htdocs => res}/failpodder.svg (100%) rename {htdocs/media => static}/22x22/internet-web-browser.png (100%) rename {htdocs/media => static}/22x22/opml-icon.png (100%) rename {htdocs/media => static}/28x28/feed-icon.png (100%) rename {htdocs/media => static}/author_subscribe.png (100%) rename {htdocs => static}/clientconfig.json (100%) rename {htdocs/media => static}/clients/amarok.png (100%) rename {htdocs/media => static}/clients/audio-x-generic.png (100%) rename {htdocs/media => static}/clients/computer.png (100%) rename {htdocs/media => static}/clients/gpodder.png (100%) rename {htdocs/media => static}/clients/multimedia-player.png (100%) rename {htdocs/media => static}/clients/podax.png (100%) rename {htdocs/media => static}/clients/server.png (100%) rename {htdocs/media => static}/clients/stock_cell-phone.png (100%) rename {htdocs/media => static}/clients/stock_notebook.png (100%) rename {htdocs/media => static}/css/bootstrap-responsive.css (100%) rename {htdocs/media => static}/css/bootstrap-responsive.min.css (100%) rename {htdocs/media => static}/css/bootstrap-theme.css (100%) rename {htdocs/media => static}/css/bootstrap-theme.min.css (100%) rename {htdocs/media => static}/css/bootstrap.css (100%) rename {htdocs/media => static}/css/bootstrap.min.css (100%) rename {htdocs/media => static/css}/fail.css (100%) rename {htdocs/media => static}/css/font-awesome-ie7.css (100%) rename {htdocs/media => static}/css/font-awesome-ie7.min.css (100%) rename {htdocs/media => static}/css/font-awesome.css (100%) rename {htdocs/media => static}/css/font-awesome.min.css (100%) rename {htdocs/media => static}/delete.png (100%) rename {htdocs/media => static}/download.png (100%) rename {htdocs/media => static}/failpodder.png (100%) rename {htdocs => static}/favicon.ico (100%) rename {htdocs => static}/favicon.png (100%) rename {htdocs/media => static}/font/fontawesome-webfont.eot (100%) rename {htdocs/media => static}/font/fontawesome-webfont.svg (100%) rename {htdocs/media => static}/font/fontawesome-webfont.svgz (100%) rename {htdocs/media => static}/font/fontawesome-webfont.ttf (100%) rename {htdocs/media => static}/font/fontawesome-webfont.woff (100%) rename {htdocs/media => static}/gpoddernet_228.png (100%) rename {htdocs/media => static}/gpoddernet_25.png (100%) rename {htdocs/media => static}/gpoddernet_64.png (100%) rename {htdocs/media => static}/js/bootstrap-dropdown.js (100%) rename {htdocs/media => static}/js/bootstrap.js (100%) rename {htdocs/media => static}/js/bootstrap.min.js (100%) rename {htdocs/media => static}/js/jquery.js (100%) rename {htdocs/media => static}/js/json2.js (100%) rename {htdocs/media => static}/js/swfobject.js (100%) rename {htdocs/media => static}/js/youtube-handler.js (100%) rename {htdocs/media/logo/original/pod => static/logo}/podcast-0.png (100%) rename {htdocs/media/logo/original/pod => static/logo}/podcast-1.png (100%) rename {htdocs/media/logo/original/pod => static/logo}/podcast-2.png (100%) rename {htdocs/media/logo/original/pod => static/logo}/podcast-3.png (100%) rename {htdocs/media/logo/original/pod => static/logo}/podcast-4.png (100%) rename {htdocs/media => static}/new.png (100%) rename {htdocs/media => static}/nothing.png (100%) rename {htdocs/media => static}/playback.png (100%) rename {htdocs/media => static}/reset.css (100%) rename {htdocs => static}/robots.txt (100%) rename {htdocs/media => static}/screen.css (94%) rename {htdocs/media => static}/subscribe.png (100%) rename {htdocs/media => static}/unsubscribe.png (100%) diff --git a/.gitignore b/.gitignore index fe0648c60..a762e0eba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.pyc -htdocs/media/logo/* +media/* logs/* *.mo mygpo/settings_prod.py diff --git a/mygpo/settings.py b/mygpo/settings.py index 9bacce642..cd6a3a866 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -72,13 +72,24 @@ # to load the internationalization machinery. USE_I18N = True + +# Static Files + STATIC_ROOT = 'staticfiles' -STATIC_URL = '/media/' +STATIC_URL = '/static/' STATICFILES_DIRS = ( - os.path.abspath(os.path.join(BASE_DIR, '..', 'htdocs', 'media')), + os.path.abspath(os.path.join(BASE_DIR, '..', 'static')), ) + +# Media Files + +MEDIA_ROOT = os.path.abspath(os.path.join(BASE_DIR, '..', 'media')) + +MEDIA_URL = '/media/' + + # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.app_directories.Loader', diff --git a/mygpo/web/logo.py b/mygpo/web/logo.py index 6a4efb84f..592eba0c8 100644 --- a/mygpo/web/logo.py +++ b/mygpo/web/logo.py @@ -30,11 +30,12 @@ from django.views.generic.base import View from django.utils.decorators import method_decorator from django.views.decorators.http import last_modified +from django.contrib.staticfiles.storage import staticfiles_storage import logging logger = logging.getLogger(__name__) -LOGO_DIR = os.path.join(settings.BASE_DIR, '..', 'htdocs', 'media', 'logo') +LOGO_DIR = os.path.join(settings.MEDIA_ROOT, 'logo') def _last_modified(request, size, prefix, filename): @@ -155,9 +156,9 @@ def get_logo_url(podcast, size): if podcast.logo_url: filename = hashlib.sha1(podcast.logo_url).hexdigest() + prefix = CoverArt.get_prefix(filename) + return reverse('logo', args=[size, prefix, filename]) + else: filename = 'podcast-%d.png' % (hash(podcast.title) % 5, ) - - prefix = CoverArt.get_prefix(filename) - - return reverse('logo', args=[size, prefix, filename]) + return staticfiles_storage.url('logo/{0}'.format(filename)) diff --git a/mygpo/web/templates/404.html b/mygpo/web/templates/404.html index 0767053dd..348214800 100644 --- a/mygpo/web/templates/404.html +++ b/mygpo/web/templates/404.html @@ -2,7 +2,7 @@ 404 Not found (gpodder.net) - +
diff --git a/mygpo/web/templates/500.html b/mygpo/web/templates/500.html index a7c646437..7d4e1063f 100644 --- a/mygpo/web/templates/500.html +++ b/mygpo/web/templates/500.html @@ -3,7 +3,7 @@ 500 Internal server error (gpodder.net) - +
diff --git a/mygpo/web/templates/episode-history.html b/mygpo/web/templates/episode-history.html index b8ee8f1c6..6a005e305 100644 --- a/mygpo/web/templates/episode-history.html +++ b/mygpo/web/templates/episode-history.html @@ -10,6 +10,7 @@ {% load flickr %} {% load charts %} {% load utils %} +{% load static %} {% load menu %} {% block mainmenu %}{{ "/podcast/"|main_menu }}{% endblock %} @@ -23,9 +24,9 @@ {% block head %} {% if episode.url|is_youtube_video %} - - - + + + {% endif %} {% endblock head %} diff --git a/mygpo/web/templates/skeleton.html b/mygpo/web/templates/skeleton.html index bebaa3698..d5f0e32c2 100644 --- a/mygpo/web/templates/skeleton.html +++ b/mygpo/web/templates/skeleton.html @@ -1,5 +1,6 @@ {% load i18n %} {% load menu %} +{% load static %} {% load utils %} @@ -16,7 +17,7 @@ - + - - - + + + - - - {% endblock %} diff --git a/mygpo/web/templates/home.html b/mygpo/web/templates/home.html index 515ef2845..7711e2e14 100644 --- a/mygpo/web/templates/home.html +++ b/mygpo/web/templates/home.html @@ -224,20 +224,4 @@

Features

{% block javascript %}{% endblock javascript %} - - - - {% endblock %} From 7b37a64bc9ab1dab1e429a9f6b58d209ee783f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 28 Oct 2017 16:03:13 +0200 Subject: [PATCH 023/106] Integrate Jupyter Notebooks --- .gitignore | 3 +++ doc/dev/index.rst | 1 + doc/dev/jupyter-notebook.rst | 28 ++++++++++++++++++++++++++++ makefile | 2 ++ mygpo/settings.py | 9 +++++++++ requirements-dev.txt | 2 ++ 6 files changed, 45 insertions(+) create mode 100644 doc/dev/jupyter-notebook.rst diff --git a/.gitignore b/.gitignore index 5adcf824f..90608c9eb 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ venv* # envdirs envs + +# Jupyter Notebooks +notebooks/ diff --git a/doc/dev/index.rst b/doc/dev/index.rst index 976e21e09..0dacb0456 100644 --- a/doc/dev/index.rst +++ b/doc/dev/index.rst @@ -30,3 +30,4 @@ Contents postgres-setup libraries configuration + jupyter-notebook diff --git a/doc/dev/jupyter-notebook.rst b/doc/dev/jupyter-notebook.rst new file mode 100644 index 000000000..9ad2e5033 --- /dev/null +++ b/doc/dev/jupyter-notebook.rst @@ -0,0 +1,28 @@ +.. _jupyter-notebook: + +Jupyter Notebook +================ + +You can use `Jupyter Notebooks `_ during development for +exploring data and prototyping methods. + +To do so, follow these steps + +* Make sure you have all requirements from ``requirements-dev.txt`` installed. + +* Run ``make notebook``, which will start the notebook and open it in the + browser . + +* Navigate to the directory ``notebooks`` (listed in `.gitignore`) and create + a new notebook. + +* Use the following code in the first cell to setup your environment + + .. code-block:: python + + MYPROJECT = '/path/to/mygpo' + import os, sys + sys.path.insert(0, MYPROJECT) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "local_settings.py") + import django + django.setup() diff --git a/makefile b/makefile index da055b289..3c4e140a3 100644 --- a/makefile +++ b/makefile @@ -13,6 +13,8 @@ update-po: --ignore=doc/* --ignore=envs/* --ignore=htdocs/* --ignore=venv/* \ --ignore=res/* --ignore=tools/* --ignore=mygpo/*/migrations/* +notebook: + envdir envs/dev/ python manage.py shell_plus --notebook clean: git clean -fX diff --git a/mygpo/settings.py b/mygpo/settings.py index d7e6624e8..5e77fb955 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -171,6 +171,15 @@ def get_intOrNone(name, default): pass +try: + if DEBUG: + import django_extensions + INSTALLED_APPS += ['django_extensions'] + +except ImportError: + pass + + try: import opbeat diff --git a/requirements-dev.txt b/requirements-dev.txt index 84043a67e..5ce4c9866 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,3 +3,5 @@ sphinx pep8 flake8 django-debug-toolbar==1.8 +django-extensions +jupyter From 60a0ca4d2f8423b7449d86aec386adc556f0976e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 19 Nov 2017 17:12:16 +0100 Subject: [PATCH 024/106] Use latest django-celery-beat 1.1.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 40f056ce0..66ebade08 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,5 +14,5 @@ psycopg2cffi==2.7.6 python-dateutil==2.6.1 redis==2.10.6 django-celery-results==1.0.1 -https://github.com/celery/django-celery-beat/archive/master.zip#egg=django-celery-beat +django-celery-beat==1.1.0 requests==2.18.4 From ca518433b832512e6e1deec7d60a89c2b44f0183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 19 Nov 2017 17:14:44 +0100 Subject: [PATCH 025/106] Use Django 2 RC 1 https://www.djangoproject.com/weblog/2017/nov/15/django-20-release-candidate-1-released/ --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 66ebade08..a90ffadb9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0b1 +Django==2.0rc1 Babel==2.5.0 Pillow==4.2.1 celery[redis]==4.1.0 From c922e38152193997f07752ec5191a7d6de91a0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 26 Nov 2017 22:31:02 +0100 Subject: [PATCH 026/106] Switch to py.test --- .gitignore | 2 ++ gunicorn.conf.py => conf/gunicorn.conf.py | 0 conftest.py | 9 +++++++++ makefile | 4 ++-- mygpo/settings.py | 9 --------- mygpo/users/tests.py | 4 ++-- mygpo/usersettings/tests.py | 4 ++-- pytest.ini | 5 +++++ requirements-test.txt | 4 ++-- 9 files changed, 24 insertions(+), 17 deletions(-) rename gunicorn.conf.py => conf/gunicorn.conf.py (100%) create mode 100644 conftest.py create mode 100644 pytest.ini diff --git a/.gitignore b/.gitignore index 90608c9eb..00fe485e3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ envs # Jupyter Notebooks notebooks/ + +.cache diff --git a/gunicorn.conf.py b/conf/gunicorn.conf.py similarity index 100% rename from gunicorn.conf.py rename to conf/gunicorn.conf.py diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..61629a16d --- /dev/null +++ b/conftest.py @@ -0,0 +1,9 @@ +import pytest + + +@pytest.fixture(autouse=True) +def enable_db_access_for_all_tests(db): + """ Enable DB access for all tests + + http://pytest-django.readthedocs.io/en/latest/faq.html#how-can-i-give-database-access-to-all-my-tests-without-the-django-db-marker """ + pass diff --git a/makefile b/makefile index 3c4e140a3..852771ecd 100644 --- a/makefile +++ b/makefile @@ -5,8 +5,8 @@ help: @echo 'make clean clean up files' test: - envdir envs/dev/ python -Wd -m coverage run ./manage.py test - coverage report + envdir envs/dev/ pytest --cov=mygpo/ --cov-branch + coverage report --show-missing update-po: envdir envs/dev/ python manage.py makemessages \ diff --git a/mygpo/settings.py b/mygpo/settings.py index 5e77fb955..97b5d8222 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -158,7 +158,6 @@ def get_intOrNone(name, default): 'mygpo.pubsub', 'mygpo.podcastlists', 'mygpo.votes', - 'django_nose', ] try: @@ -373,13 +372,5 @@ def get_intOrNone(name, default): PODCAST_AD_ID = os.getenv('PODCAST_AD_ID') -TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' - -NOSE_ARGS = [ - '--with-doctest', - '--stop', - '--where=mygpo', -] - SEARCH_CUTOFF = float(os.getenv('SEARCH_CUTOFF', 0.3)) diff --git a/mygpo/users/tests.py b/mygpo/users/tests.py index 5f65b7b49..5c6800020 100644 --- a/mygpo/users/tests.py +++ b/mygpo/users/tests.py @@ -3,7 +3,7 @@ from collections import Counter from django.urls import reverse -from django.test.client import Client as TestClient +from django.test.client import Client as TClient from django.test import TestCase from django.test.utils import override_settings from django.contrib.auth import get_user_model @@ -100,7 +100,7 @@ class AuthTests(TestCase): def setUp(self): self.user, pwd = create_user() - self.client = TestClient() + self.client = TClient() wrong_pwd = pwd + '1234' self.extra = { 'HTTP_AUTHORIZATION': create_auth_string(self.user.username, diff --git a/mygpo/usersettings/tests.py b/mygpo/usersettings/tests.py index dda1d4be6..0ed32e749 100644 --- a/mygpo/usersettings/tests.py +++ b/mygpo/usersettings/tests.py @@ -5,7 +5,7 @@ import json from django.urls import reverse -from django.test.client import Client as TestClient +from django.test.client import Client as TClient from django.test import TestCase from mygpo.test import create_auth_string, create_user @@ -32,7 +32,7 @@ def setUp(self): user = self.user, uid = self.uid, ) - self.client = TestClient() + self.client = TClient() self.extra = { 'HTTP_AUTHORIZATION': create_auth_string(self.user.username, pwd) } diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..799cee2a2 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +DJANGO_SETTINGS_MODULE = mygpo.settings +python_files = tests.py test_*.py *_tests.py +addopts = --doctest-modules +norecursedirs = tools conf diff --git a/requirements-test.txt b/requirements-test.txt index e103fffea..5936206b8 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,5 +1,5 @@ coverage==4.4.1 django-coverage-plugin==1.5.0 -django-nose==1.4.5 -nose==1.3.7 +pytest-django +pytest-cov responses==0.8.1 From 31187593006d435505168168ee81d7959f8e8faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 2 Dec 2017 20:34:49 +0100 Subject: [PATCH 027/106] Bump to Django 2.0 https://docs.djangoproject.com/en/dev/releases/2.0/ --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a90ffadb9..320d409f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0rc1 +Django==2.0 Babel==2.5.0 Pillow==4.2.1 celery[redis]==4.1.0 From 22f68f22ebbfe0ad7056cc3bfd002f1eef769d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 2 Dec 2017 21:09:34 +0100 Subject: [PATCH 028/106] Test using py.test on Travis-CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 20cd66e8a..4f04c92b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_script: - psql -c 'create database mygpo_test;' -U postgres script: - coverage run --branch --source=mygpo ./manage.py test + - pytest --cov=mygpo/ --cov-branch after_script: - coveralls From 31edcac5808e4635c45ead8a7d9aca51424b7526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 2 Dec 2017 21:15:04 +0100 Subject: [PATCH 029/106] Set SECRET_KEY when running tests with py.test --- mygpo/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/settings.py b/mygpo/settings.py index 97b5d8222..336835ea5 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -217,7 +217,7 @@ def get_intOrNone(name, default): SECRET_KEY = os.getenv('SECRET_KEY', '') -if 'test' in sys.argv: +if 'pytest' in sys.argv[0]: SECRET_KEY = 'test' GOOGLE_ANALYTICS_PROPERTY_ID = os.getenv('GOOGLE_ANALYTICS_PROPERTY_ID', '') From 0662ae39d7b13663981851d94c87637ab5cd62e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 2 Dec 2017 23:10:47 +0100 Subject: [PATCH 030/106] Refactor podcast updates, create PodcastUpdater class --- mygpo/data/feeddownloader.py | 778 ++++++++++-------- .../management/commands/feed-downloader.py | 3 +- mygpo/directory/search.py | 6 +- mygpo/maintenance/management/podcastcmd.py | 14 +- mygpo/share/views.py | 5 +- 5 files changed, 432 insertions(+), 374 deletions(-) diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index 9572eaa61..42b5898a3 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -2,7 +2,9 @@ # -*- coding: utf-8 -*- import os.path -import urllib.request, urllib.error, urllib.parse +import urllib.request +import urllib.error +import urllib.parse from urllib.parse import urljoin import http.client import hashlib @@ -54,7 +56,8 @@ def update_podcasts(queue): continue try: - yield update_podcast(podcast_url) + updater = PodcastUpdater(podcast_url) + yield updater.update_podcast() except NoPodcastCreated as npc: logger.info('No podcast created: %s', npc) @@ -65,444 +68,493 @@ def update_podcasts(queue): raise -def update_podcast(podcast_url): - """ Update the podcast for the supplied URL """ +class PodcastUpdater(object): + """ Updates the podcast specified by the podcast_url """ - try: - parsed = _fetch_feed(podcast_url) - _validate_parsed(parsed) + def __init__(self, podcast_url): + self.podcast_url = podcast_url - except requests.exceptions.RequestException as re: - logging.exception('Error while fetching response from feedservice') + def update_podcast(self): + """ Update the podcast """ - # if we fail to parse the URL, we don't even create the - # podcast object - try: - p = Podcast.objects.get(urls__url=podcast_url) - # if it exists already, we mark it as outdated - _mark_outdated(p, 'error while fetching feed: %s' % str(re)) - p.last_update = datetime.utcnow() - p.save() - return p + parsed = self.parse_feed() + if not parsed: + return + + podcast = Podcast.objects.get_or_create_for_url(self.podcast_url) + + episode_updater = MultiEpisodeUpdater(podcast) + episode_updater.update_episodes(parsed.get('episodes', [])) + + podcast.refresh_from_db() + podcast.episode_count = Episode.objects.filter(podcast=podcast).count() + podcast.save() + + episode_updater.order_episodes() - except Podcast.DoesNotExist: - raise NoPodcastCreated(re) + self._update_podcast(podcast, parsed, episode_updater) - except NoEpisodesException as nee: - logging.warn('No episode found while parsing podcast') + return podcast - # if we fail to parse the URL, we don't even create the - # podcast object + def parse_feed(self): try: - p = Podcast.objects.get(urls__url=podcast_url) - # if it exists already, we mark it as outdated - _mark_outdated(p, 'error while fetching feed: %s' % str(nee)) - return p - - except Podcast.DoesNotExist: - raise NoPodcastCreated(nee) - - assert parsed, 'fetch_feed must return something' - p = Podcast.objects.get_or_create_for_url(podcast_url) - episodes = _update_episodes(p, parsed.get('episodes', [])) - p.refresh_from_db() - p.episode_count = Episode.objects.filter(podcast=p).count() - p.save() - max_episode_order = _order_episodes(p) - _update_podcast(p, parsed, episodes, max_episode_order) - return p - - -def verify_podcast_url(podcast_url): - parsed = _fetch_feed(podcast_url) - _validate_parsed(parsed) - return True + parsed = self._fetch_feed() + self._validate_parsed(parsed) + except requests.exceptions.RequestException as re: + logging.exception('Error while fetching response from feedservice') -def _fetch_feed(podcast_url): - params = { - 'url': podcast_url, - 'process_text': 'markdown', - } - headers = { - 'Accept': 'application/json', - } - url = urljoin(settings.FEEDSERVICE_URL, 'parse') - r = requests.get(url, params=params, headers=headers, timeout=30) - - if r.status_code != 200: - logger.error('Feed-service status code for "%s" was %s', podcast_url, - r.status_code) - return None + # if we fail to parse the URL, we don't even create the + # podcast object + try: + p = Podcast.objects.get(urls__url=podcast_url) + # if it exists already, we mark it as outdated + _mark_outdated(p, 'error while fetching feed: %s' % str(re)) + p.last_update = datetime.utcnow() + p.save() + return None + + except Podcast.DoesNotExist as pdne: + raise NoPodcastCreated(re) from pdne + + except NoEpisodesException as nee: + logging.warn('No episode found while parsing podcast') + + # if we fail to parse the URL, we don't even create the + # podcast object + try: + p = Podcast.objects.get(urls__url=podcast_url) + # if it exists already, we mark it as outdated + self._mark_outdated(p, 'error while fetching feed: {}'.format( + str(nee))) + return None + + except Podcast.DoesNotExist as pdne: + raise NoPodcastCreated(nee) from pdne + + return parsed + + def _fetch_feed(self): + params = { + 'url': self.podcast_url, + 'process_text': 'markdown', + } + headers = { + 'Accept': 'application/json', + } + url = urljoin(settings.FEEDSERVICE_URL, 'parse') + r = requests.get(url, params=params, headers=headers, timeout=30) + + if r.status_code != 200: + logger.error('Feed-service status code for "{}" was {}'.format( + podcast_url, r.status_code)) + return None - try: - return r.json()[0] - except ValueError: - logger.exception( - 'Feed-service error while parsing response for url "%s": %s', - podcast_url, r.text, - ) - raise - - -def _validate_parsed(parsed): - """ validates the parsed results and raises an exception if invalid - - feedparser parses pretty much everything. We reject anything that - doesn't look like a feed""" - - if not parsed or not parsed.get('episodes', []): - raise NoEpisodesException('no episodes found') - - -def _update_podcast(podcast, parsed, episodes, max_episode_order): - """ updates a podcast according to new parser results """ - - # we need that later to decide if we can "bump" a category - prev_latest_episode_timestamp = podcast.latest_episode_timestamp - - # will later be used to see whether the index is outdated - old_index_fields = get_index_fields(podcast) - - podcast.title = parsed.get('title') or podcast.title - podcast.description = parsed.get('description') or podcast.description - podcast.subtitle = parsed.get('subtitle') or podcast.subtitle - podcast.link = parsed.get('link') or podcast.link - podcast.logo_url = parsed.get('logo') or podcast.logo_url - podcast.author = to_maxlength(Podcast, 'author', parsed.get('author') or - podcast.author) - podcast.language = to_maxlength(Podcast, 'language', - parsed.get('language') or podcast.language) - podcast.content_types = ','.join(parsed.get('content_types')) or \ - podcast.content_types - #podcast.tags['feed'] = parsed.tags or podcast.tags.get('feed', []) - podcast.common_episode_title = to_maxlength( - Podcast, - 'common_episode_title', - parsed.get('common_title') or podcast.common_episode_title) - podcast.new_location = parsed.get('new_location') or podcast.new_location - podcast.flattr_url = to_maxlength(Podcast, 'flattr_url', - parsed.get('flattr') or - podcast.flattr_url) - podcast.hub = parsed.get('hub') or podcast.hub - podcast.license = parsed.get('license') or podcast.license - podcast.max_episode_order = max_episode_order - - podcast.add_missing_urls(parsed.get('urls', [])) - - if podcast.new_location: try: - new_podcast = Podcast.objects.get(urls__url=podcast.new_location) - if new_podcast != podcast: - _mark_outdated(podcast, 'redirected to different podcast') - return - except Podcast.DoesNotExist: - podcast.set_url(podcast.new_location) + return r.json()[0] + except ValueError: + logger.exception( + 'Feed-service error while parsing response for url "%s": %s', + podcast_url, r.text, + ) + raise - # latest episode timestamp - episodes = Episode.objects.filter(podcast=podcast, - released__isnull=False)\ - .order_by('released') + def _validate_parsed(self, parsed): + """ validates the parsed results and raises an exception if invalid - podcast.update_interval = get_update_interval(episodes) + feedparser parses pretty much everything. We reject anything that + doesn't look like a feed""" - latest_episode = episodes.last() - if latest_episode: - podcast.latest_episode_timestamp = latest_episode.released + if not parsed or not parsed.get('episodes', []): + raise NoEpisodesException('no episodes found') - # podcast.episode_count is not update here on purpose. It is, instead, - # continuously updated when creating new episodes in - # EpisodeManager.get_or_create_for_url + def _update_podcast(self, podcast, parsed, episode_updater): + """ updates a podcast according to new parser results """ - _update_categories(podcast, prev_latest_episode_timestamp) + # we need that later to decide if we can "bump" a category + prev_latest_episode_timestamp = podcast.latest_episode_timestamp - # try to download the logo and reset logo_url to None on http errors - found = _save_podcast_logo(podcast.logo_url) - if not found: - podcast.logo_url = None + # will later be used to see whether the index is outdated + old_index_fields = get_index_fields(podcast) + podcast.title = parsed.get('title') or podcast.title + podcast.description = parsed.get('description') or podcast.description + podcast.subtitle = parsed.get('subtitle') or podcast.subtitle + podcast.link = parsed.get('link') or podcast.link + podcast.logo_url = parsed.get('logo') or podcast.logo_url - # check if search index should be considered out of date - new_index_fields = get_index_fields(podcast) - if list(old_index_fields.items()) != list(new_index_fields.items()): - podcast.search_index_uptodate = False + podcast.author = to_maxlength( + Podcast, 'author', + parsed.get('author') or podcast.author) - # The podcast is always saved (not just when there are changes) because - # we need to record the last update - logger.info('Saving podcast.') - podcast.last_update = datetime.utcnow() - podcast.save() + podcast.language = to_maxlength( + Podcast, 'language', + parsed.get('language') or podcast.language) - try: - subscribe_at_hub(podcast) - except SubscriptionError as se: - logger.warn('subscribing to hub failed: %s', str(se)) + podcast.content_types = (','.join(parsed.get('content_types')) or + podcast.content_types) - assign_slug(podcast) - assign_missing_episode_slugs(podcast) - update_related_podcasts.delay(podcast.pk) + # podcast.tags['feed'] = parsed.tags or podcast.tags.get('feed', []) + podcast.common_episode_title = to_maxlength( + Podcast, + 'common_episode_title', + parsed.get('common_title') or podcast.common_episode_title) -def assign_slug(podcast): - if podcast.slug: - return + podcast.new_location = (parsed.get('new_location') or + podcast.new_location) + podcast.flattr_url = to_maxlength(Podcast, 'flattr_url', + parsed.get('flattr') or + podcast.flattr_url) + podcast.hub = parsed.get('hub') or podcast.hub + podcast.license = parsed.get('license') or podcast.license + podcast.max_episode_order = episode_updater.max_episode_order - for slug in PodcastSlugs(podcast): - try: - with transaction.atomic(): - podcast.add_slug(slug) - break + podcast.add_missing_urls(parsed.get('urls', [])) - except: - continue + if podcast.new_location: + try: + new_podcast = Podcast.objects.get( + urls__url=podcast.new_location + ) + + if new_podcast != podcast: + _mark_outdated(podcast, 'redirected to different podcast') + return + except Podcast.DoesNotExist: + podcast.set_url(podcast.new_location) + # latest episode timestamp + episodes = Episode.objects.filter(podcast=podcast, + released__isnull=False)\ + .order_by('released') -def assign_missing_episode_slugs(podcast): - common_title = podcast.get_common_episode_title() + podcast.update_interval = episode_updater.get_update_interval(episodes) - episodes = Episode.objects.filter(podcast=podcast, slugs__isnull=True) + latest_episode = episodes.last() + if latest_episode: + podcast.latest_episode_timestamp = latest_episode.released - for episode in episodes: + # podcast.episode_count is not update here on purpose. It is, instead, + # continuously updated when creating new episodes in + # EpisodeManager.get_or_create_for_url - for slug in EpisodeSlugs(episode, common_title): + self._update_categories(podcast, prev_latest_episode_timestamp) + + # try to download the logo and reset logo_url to None on http errors + found = self._save_podcast_logo(podcast.logo_url) + if not found: + podcast.logo_url = None + + # check if search index should be considered out of date + new_index_fields = get_index_fields(podcast) + if list(old_index_fields.items()) != list(new_index_fields.items()): + podcast.search_index_uptodate = False + + # The podcast is always saved (not just when there are changes) because + # we need to record the last update + logger.info('Saving podcast.') + podcast.last_update = datetime.utcnow() + podcast.save() + + try: + subscribe_at_hub(podcast) + except SubscriptionError as se: + logger.warn('subscribing to hub failed: %s', str(se)) + + self.assign_slug(podcast) + episode_updater.assign_missing_episode_slugs() + update_related_podcasts.delay(podcast.pk) + + def assign_slug(self, podcast): + if podcast.slug: + return + + for slug in PodcastSlugs(podcast): try: with transaction.atomic(): - episode.set_slug(slug) + podcast.add_slug(slug) break except: continue + def _update_categories(self, podcast, prev_timestamp): + """ checks some practical requirements and updates a category """ -def _update_categories(podcast, prev_timestamp): - """ checks some practical requirements and updates a category """ + max_timestamp = datetime.utcnow() + timedelta(days=1) - max_timestamp = datetime.utcnow() + timedelta(days=1) + # no episodes at all + if not podcast.latest_episode_timestamp: + return - # no episodes at all - if not podcast.latest_episode_timestamp: - return + # no new episode + if prev_timestamp and \ + (podcast.latest_episode_timestamp <= prev_timestamp): + return - # no new episode - if prev_timestamp and podcast.latest_episode_timestamp <= prev_timestamp: - return + # too far in the future + if podcast.latest_episode_timestamp > max_timestamp: + return - # too far in the future - if podcast.latest_episode_timestamp > max_timestamp: - return + # not enough subscribers + if podcast.subscriber_count() < settings.MIN_SUBSCRIBERS_CATEGORY: + return - # not enough subscribers - if podcast.subscriber_count() < settings.MIN_SUBSCRIBERS_CATEGORY: - return + update_category(podcast) - update_category(podcast) + def _save_podcast_logo(self, cover_art): + if not cover_art: + return + try: + image_sha1 = hashlib.sha1(cover_art.encode('utf-8')).hexdigest() + prefix = CoverArt.get_prefix(image_sha1) -def _update_episodes(podcast, parsed_episodes): + filename = CoverArt.get_original(prefix, image_sha1) + dirname = CoverArt.get_dir(filename) - pid = podcast.get_id() + # get hash of existing file + if os.path.exists(filename): + with open(filename, 'rb') as f: + old_hash = file_hash(f).digest() + else: + old_hash = '' - # list of (obj, fun) where fun is the function to update obj - updated_episodes = [] - episodes_to_update = list(islice(parsed_episodes, 0, MAX_EPISODES_UPDATE)) - logger.info('Parsed %d (%d) episodes', len(parsed_episodes), - len(episodes_to_update)) + logger.info('Logo %s', cover_art) - logger.info('Updating %d episodes', len(episodes_to_update)) - for n, parsed in enumerate(episodes_to_update, 1): + # save new cover art + with open(filename, 'wb') as fp: + fp.write(urllib.request.urlopen(cover_art).read()) - url = get_episode_url(parsed) - if not url: - logger.info('Skipping episode %d for missing URL', n) - continue + # get hash of new file + with open(filename, 'rb') as f: + new_hash = file_hash(f).digest() - logger.info('Updating episode %d / %d', n, len(parsed_episodes)) + # remove thumbnails if cover changed + if old_hash != new_hash: + thumbnails = CoverArt.get_existing_thumbnails(prefix, filename) + logger.info('Removing %d thumbnails', len(thumbnails)) + for f in thumbnails: + os.unlink(f) - episode = Episode.objects.get_or_create_for_url(podcast, url) + return cover_art - update_episode(parsed, episode, podcast) - updated_episodes.append(episode) + except (urllib.error.HTTPError, urllib.error.URLError, ValueError, + http.client.HTTPException, socket.error, IOError) as e: + logger.warn('Exception while updating podcast logo: %s', str(e)) - # and mark the remaining ones outdated - current_episodes = Episode.objects.filter(podcast=podcast, - outdated=False)[:500] - outdated_episodes = set(current_episodes) - set(updated_episodes) + def _mark_outdated(podcast, msg=''): + logger.info('marking podcast outdated: %s', msg) + podcast.outdated = True + podcast.last_update = datetime.utcnow() + podcast.save() + _update_episodes(podcast, []) - logger.info('Marking %d episodes as outdated', len(outdated_episodes)) - for episode in outdated_episodes: - mark_outdated(episode) +class MultiEpisodeUpdater(object): -@transaction.atomic -def _order_episodes(podcast): - """ Reorder the podcast's episode according to release timestamp + def __init__(self, podcast): + self.podcast = podcast + self.updated_episodes = [] + self.max_episode_order = None - Returns the highest order value (corresponding to the most recent - episode) """ + def update_episodes(self, parsed_episodes): - num_episodes = podcast.episode_count - if not num_episodes: - return 0 + pid = self.podcast.get_id() - episodes = podcast.episode_set.all().extra(select={ - 'has_released': 'released IS NOT NULL', - })\ - .order_by('-has_released', '-released', 'pk')\ - .only('pk') + episodes_to_update = list(islice(parsed_episodes, 0, + MAX_EPISODES_UPDATE)) + logger.info('Parsed %d (%d) episodes', len(parsed_episodes), + len(episodes_to_update)) - for n, episode in enumerate(episodes.iterator(), 1): - # assign ``order`` from higher (most recent) to 0 (oldest) - # None means "unknown" - new_order = num_episodes - n + logger.info('Updating %d episodes', len(episodes_to_update)) + for n, parsed in enumerate(episodes_to_update, 1): - # optimize for new episodes that are newer than all existing - if episode.order == new_order: - continue + url = self.get_episode_url(parsed) + if not url: + logger.info('Skipping episode %d for missing URL', n) + continue - logger.info('Updating order from {} to {}'.format(episode.order, - new_order)) - episode.order = new_order - episode.save() + logger.info('Updating episode %d / %d', n, len(parsed_episodes)) - return num_episodes - 1 + episode = Episode.objects.get_or_create_for_url(self.podcast, url) + updater = EpisodeUpdater(episode, self.podcast) + updater.update_episode(parsed) -def _save_podcast_logo(cover_art): - if not cover_art: - return + self.updated_episodes.append(episode) - try: - image_sha1 = hashlib.sha1(cover_art.encode('utf-8')).hexdigest() - prefix = CoverArt.get_prefix(image_sha1) + # and mark the remaining ones outdated + current_episodes = Episode.objects.filter(podcast=self.podcast, + outdated=False)[:500] + outdated_episodes = set(current_episodes) - set(self.updated_episodes) - filename = CoverArt.get_original(prefix, image_sha1) - dirname = CoverArt.get_dir(filename) + logger.info('Marking %d episodes as outdated', len(outdated_episodes)) + for episode in outdated_episodes: + updater = EpisodeUpdater(episode, self.podcast) + updater.mark_outdated() - # get hash of existing file - if os.path.exists(filename): - with open(filename, 'rb') as f: - old_hash = file_hash(f).digest() - else: - old_hash = '' - - logger.info('Logo %s', cover_art) - - # save new cover art - with open(filename, 'wb') as fp: - fp.write(urllib.request.urlopen(cover_art).read()) - - # get hash of new file - with open(filename, 'rb') as f: - new_hash = file_hash(f).digest() - - # remove thumbnails if cover changed - if old_hash != new_hash: - thumbnails = CoverArt.get_existing_thumbnails(prefix, filename) - logger.info('Removing %d thumbnails', len(thumbnails)) - for f in thumbnails: - os.unlink(f) - - return cover_art - - except (urllib.error.HTTPError, urllib.error.URLError, ValueError, - http.client.HTTPException, socket.error, IOError) as e: - logger.warn('Exception while updating podcast logo: %s', str(e)) - - -def _mark_outdated(podcast, msg=''): - logger.info('marking podcast outdated: %s', msg) - podcast.outdated = True - podcast.last_update = datetime.utcnow() - podcast.save() - _update_episodes(podcast, []) - - -def get_episode_url(parsed_episode): - """ returns the URL of a parsed episode """ - for f in parsed_episode.get('files', []): - if f.get('urls', []): - return f['urls'][0] - return None - - -def update_episode(parsed_episode, episode, podcast): - """ updates "episode" with the data from "parsed_episode" """ - - # TODO: check if there have been any changes, to avoid unnecessary updates - episode.guid = to_maxlength(Episode, 'guid', parsed_episode.get('guid') or - episode.guid) - episode.description = parsed_episode.get('description') or \ - episode.description - episode.subtitle = parsed_episode.get('subtitle') or episode.subtitle - episode.content = parsed_episode.get('content') or \ - parsed_episode.get('description') or episode.content - episode.link = to_maxlength(Episode, 'link', - parsed_episode.get('link') or episode.link) - episode.released = datetime.utcfromtimestamp( - parsed_episode.get('released')) if parsed_episode.get('released') \ - else episode.released - episode.author = to_maxlength(Episode, 'author', - parsed_episode.get('author') or - episode.author) - episode.duration = parsed_episode.get('duration') or episode.duration - episode.filesize = parsed_episode['files'][0]['filesize'] - episode.language = parsed_episode.get('language') or \ - episode.language or podcast.language - episode.mimetypes = ','.join(list(set( - filter(None, [f['mimetype'] for f in parsed_episode.get('files', [])]) - ))) - episode.flattr_url = to_maxlength(Episode, 'flattr_url', - parsed_episode.get('flattr') or - episode.flattr_url) - episode.license = parsed_episode.get('license') or episode.license - - episode.title = to_maxlength(Episode, 'title', - parsed_episode.get('title') or - episode.title or - file_basename_no_extension(episode.url)) - - episode.last_update = datetime.utcnow() - episode.save() - - parsed_urls = list(chain.from_iterable( - f.get('urls', []) for f in parsed_episode.get('files', []))) - episode.add_missing_urls(parsed_urls) - - -def mark_outdated(obj): - """ marks obj outdated if its not already """ - if obj.outdated: + @transaction.atomic + def order_episodes(self): + """ Reorder the podcast's episode according to release timestamp + + Returns the highest order value (corresponding to the most recent + episode) """ + + num_episodes = self.podcast.episode_count + if not num_episodes: + return 0 + + episodes = self.podcast.episode_set.all().extra(select={ + 'has_released': 'released IS NOT NULL', + })\ + .order_by('-has_released', '-released', 'pk')\ + .only('pk') + + for n, episode in enumerate(episodes.iterator(), 1): + # assign ``order`` from higher (most recent) to 0 (oldest) + # None means "unknown" + new_order = num_episodes - n + + # optimize for new episodes that are newer than all existing + if episode.order == new_order: + continue + + logger.info('Updating order from {} to {}'.format(episode.order, + new_order)) + episode.order = new_order + episode.save() + + self.max_episode_order = num_episodes - 1 + + def get_episode_url(self, parsed_episode): + """ returns the URL of a parsed episode """ + for f in parsed_episode.get('files', []): + if f.get('urls', []): + return f['urls'][0] return None - obj.outdated = True - obj.last_update = datetime.utcnow() - obj.save() + def get_update_interval(self, episodes): + """ calculates the avg interval between new episodes """ + + count = episodes.count() + if not count: + logger.info('no episodes, using default interval of %dh', + DEFAULT_UPDATE_INTERVAL) + return DEFAULT_UPDATE_INTERVAL + + earliest = episodes.first() + now = datetime.utcnow() + + timespan_s = (now - earliest.released).total_seconds() + timespan_h = timespan_s / 60 / 60 + + interval = int(timespan_h / count) + logger.info('%d episodes in %d days => %dh interval', count, + timespan_h / 24, interval) + + # place interval between {MIN,MAX}_UPDATE_INTERVAL + interval = max(interval, MIN_UPDATE_INTERVAL) + interval = min(interval, MAX_UPDATE_INTERVAL) + + return interval + + def assign_missing_episode_slugs(self): + common_title = self.podcast.get_common_episode_title() + + episodes = Episode.objects.filter(podcast=self.podcast, + slugs__isnull=True) + + for episode in episodes: + + for slug in EpisodeSlugs(episode, common_title): + try: + with transaction.atomic(): + episode.set_slug(slug) + break + + except: + continue -def get_update_interval(episodes): - """ calculates the avg interval between new episodes """ +class EpisodeUpdater(object): + """ Updates an individual episode """ - count = episodes.count() - if not count: - logger.info('no episodes, using default interval of %dh', - DEFAULT_UPDATE_INTERVAL) - return DEFAULT_UPDATE_INTERVAL + def __init__(self, episode, podcast): + self.episode = episode + self.podcast = podcast - earliest = episodes.first() - now = datetime.utcnow() + def update_episode(self, parsed_episode): + """ updates "episode" with the data from "parsed_episode" """ - timespan_s = (now - earliest.released).total_seconds() - timespan_h = timespan_s / 60 / 60 + # TODO: check if there have been any changes, to + # avoid unnecessary updates + self.episode.guid = to_maxlength( + Episode, 'guid', + parsed_episode.get('guid') or self.episode.guid) - interval = int(timespan_h / count) - logger.info('%d episodes in %d days => %dh interval', count, - timespan_h / 24, interval) + self.episode.description = (parsed_episode.get('description') or + self.episode.description) - # place interval between {MIN,MAX}_UPDATE_INTERVAL - interval = max(interval, MIN_UPDATE_INTERVAL) - interval = min(interval, MAX_UPDATE_INTERVAL) + self.episode.subtitle = (parsed_episode.get('subtitle') or + self.episode.subtitle) - return interval + self.episode.content = (parsed_episode.get('content') or + parsed_episode.get('description') or + self.episode.content) + + self.episode.link = to_maxlength( + Episode, 'link', + parsed_episode.get('link') or self.episode.link) + + self.episode.released = (datetime.utcfromtimestamp( + parsed_episode.get('released')) if parsed_episode.get('released') + else self.episode.released) + + self.episode.author = to_maxlength( + Episode, 'author', + parsed_episode.get('author') or self.episode.author) + + self.episode.duration = (parsed_episode.get('duration') or + self.episode.duration) + + self.episode.filesize = parsed_episode['files'][0]['filesize'] + + self.episode.language = (parsed_episode.get('language') or + self.episode.language or + self.podcast.language) + + mimetypes = [f['mimetype'] for f in parsed_episode.get('files', [])] + self.episode.mimetypes = ','.join(list(set(filter(None, mimetypes)))) + + self.episode.flattr_url = to_maxlength( + Episode, 'flattr_url', + parsed_episode.get('flattr') or self.episode.flattr_url) + + self.episode.license = (parsed_episode.get('license') or + self.episode.license) + + self.episode.title = to_maxlength( + Episode, 'title', + parsed_episode.get('title') or self.episode.title or + file_basename_no_extension(self.episode.url)) + + self.episode.last_update = datetime.utcnow() + self.episode.save() + + parsed_urls = list(chain.from_iterable( + f.get('urls', []) for f in parsed_episode.get('files', []))) + self.episode.add_missing_urls(parsed_urls) + + def mark_outdated(self): + """ marks the episode outdated if its not already """ + if self.episode.outdated: + return None + + self.episode.outdated = True + self.episode.last_update = datetime.utcnow() + self.episode.save() def file_basename_no_extension(filename): @@ -517,3 +569,9 @@ def file_basename_no_extension(filename): base = os.path.basename(filename) name, extension = os.path.splitext(base) return name + + +def verify_podcast_url(self): + parsed = _fetch_feed(self.podcast_url) + self._validate_parsed(parsed) + return True diff --git a/mygpo/data/management/commands/feed-downloader.py b/mygpo/data/management/commands/feed-downloader.py index a9a05cb75..3283c7251 100644 --- a/mygpo/data/management/commands/feed-downloader.py +++ b/mygpo/data/management/commands/feed-downloader.py @@ -16,8 +16,7 @@ class Command(PodcastCommand): def add_arguments(self, parser): - parser.add_argument('urls', nargs='+', type=str) - + super().add_arguments(parser) parser.add_argument('--list-only', action='store_true', dest='list', default=False, help="Don't update anything, just list podcasts "), diff --git a/mygpo/directory/search.py b/mygpo/directory/search.py index 483619a36..48d01c15c 100644 --- a/mygpo/directory/search.py +++ b/mygpo/directory/search.py @@ -1,6 +1,6 @@ from mygpo.podcasts.models import Podcast from mygpo.utils import is_url, normalize_feed_url -from mygpo.data.feeddownloader import update_podcast, NoPodcastCreated +from mygpo.data.feeddownloader import PodcastUpdater, NoPodcastCreated from mygpo.search.index import search_podcasts as search @@ -14,9 +14,11 @@ def search_podcasts(q): except Podcast.DoesNotExist: podcast = None + updater = PodcastUpdater(url) + if not podcast or not podcast.title: try: - update_podcast(url) + updater.update_podcast() except NoPodcastCreated as npc: return [] diff --git a/mygpo/maintenance/management/podcastcmd.py b/mygpo/maintenance/management/podcastcmd.py index f59113204..8d68f134d 100644 --- a/mygpo/maintenance/management/podcastcmd.py +++ b/mygpo/maintenance/management/podcastcmd.py @@ -18,7 +18,7 @@ def add_arguments(self, parser): parser.add_argument('--update-new', action='store_true', dest='new', default=False, help="Update all podcasts with new Episodes"), - parser.add_argument('--max', action='store', dest='max', type='int', + parser.add_argument('--max', action='store', dest='max', type=int, default=0, help="Set how many feeds should be updated at maximum"), parser.add_argument('--random', action='store_true', dest='random', @@ -27,6 +27,7 @@ def add_arguments(self, parser): parser.add_argument('--next', action='store_true', dest='next', default=False, help="Podcasts that are due to be updated next"), + parser.add_argument('urls', nargs='+', type=str) def get_podcasts(self, *args, **options): return chain.from_iterable(self._get_podcasts(*args, **options)) @@ -54,17 +55,14 @@ def _get_podcasts(self, *args, **options): podcasts = Podcast.objects.all().order_by_next_update()[:max_podcasts] yield (p.url for p in podcasts) - - if args: - yield args - if options.get('urls'): yield options.get('urls') - if not args and not options.get('toplist') and not options.get('new') \ - and not options.get('random') and not options.get('next'): + if not options.get('urls') and not options.get('toplist') and \ + not options.get('new') and not options.get('random') and \ + not options.get('next'): query = Podcast.objects.order_by('last_update') - podcasts = query.select_related('urls')[:max_podcasts] + podcasts = query[:max_podcasts] yield (p.url for p in podcasts) diff --git a/mygpo/share/views.py b/mygpo/share/views.py index 64b86cbd6..faf37245a 100644 --- a/mygpo/share/views.py +++ b/mygpo/share/views.py @@ -11,7 +11,7 @@ from mygpo.podcasts.models import Podcast from mygpo.publisher.models import PublishedPodcast from mygpo.userfeeds.feeds import FavoriteFeed -from mygpo.data.feeddownloader import update_podcast +from mygpo.data.feeddownloader import PodcastUpdater import logging logger = logging.getLogger(__name__) @@ -100,7 +100,8 @@ def post(self, request): publisher=user, ) - update_podcast(feed_url) + updater = PodcastUpdater(feed_url) + updater.update_podcast() return HttpResponseRedirect(reverse('share-favorites')) From 4cbc611aa9479903ebbde28292242bd157e31ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:42:52 +0100 Subject: [PATCH 031/106] Return created flag from get_or_create_for_url --- mygpo/administration/tests.py | 12 +++++------ mygpo/api/advanced/__init__.py | 4 ++-- mygpo/api/advanced/episode.py | 4 ++-- mygpo/api/advanced/lists.py | 4 ++-- mygpo/api/legacy.py | 4 ++-- mygpo/api/simple.py | 2 +- mygpo/api/subscriptions.py | 2 +- mygpo/api/tests.py | 4 ++-- mygpo/maintenance/tests.py | 28 +++++++++++++------------- mygpo/podcasts/models.py | 35 +++++++++++++++++++++------------ mygpo/podcasts/tests.py | 6 +++--- mygpo/podcasts/views/podcast.py | 2 +- mygpo/share/views.py | 2 +- mygpo/subscriptions/tests.py | 2 +- mygpo/users/tests.py | 7 +++++-- mygpo/usersettings/tests.py | 7 +++++-- mygpo/web/tests.py | 2 +- 17 files changed, 71 insertions(+), 56 deletions(-) diff --git a/mygpo/administration/tests.py b/mygpo/administration/tests.py index a8124dc74..3a181c868 100644 --- a/mygpo/administration/tests.py +++ b/mygpo/administration/tests.py @@ -24,22 +24,22 @@ class SimpleTest(TestCase): def test_merge(self): - p1 = Podcast.objects.get_or_create_for_url('http://example.com/podcast1.rss') - p2 = Podcast.objects.get_or_create_for_url('http://example.com/podcast2.rss') + p1 = Podcast.objects.get_or_create_for_url('http://example.com/podcast1.rss').object + p2 = Podcast.objects.get_or_create_for_url('http://example.com/podcast2.rss').object - e1 = Episode.objects.get_or_create_for_url(p1, 'http://example.com/podcast1/e1.mp3') + e1 = Episode.objects.get_or_create_for_url(p1, 'http://example.com/podcast1/e1.mp3').object e1.title = 'Episode 1' e1.save() - e2 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast1/e2.mp3') + e2 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast1/e2.mp3').object e2.title = 'Episode 2' e2.save() - e3 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast2/e2.mp3') + e3 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast2/e2.mp3').object e3.title = 'Episode 3' e3.save() - e4 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast2/e3.mp3') + e4 = Episode.objects.get_or_create_for_url(p2, 'http://example.com/podcast2/e3.mp3').object e4.title = 'Episode 4' e4.save() diff --git a/mygpo/api/advanced/__init__.py b/mygpo/api/advanced/__init__.py index 9f3cddc90..2687db147 100644 --- a/mygpo/api/advanced/__init__.py +++ b/mygpo/api/advanced/__init__.py @@ -200,8 +200,8 @@ def update_episodes(user, actions, now, ua_string): if not episode_url: continue - podcast = Podcast.objects.get_or_create_for_url(podcast_url) - episode = Episode.objects.get_or_create_for_url(podcast, episode_url) + podcast = Podcast.objects.get_or_create_for_url(podcast_url).object + episode = Episode.objects.get_or_create_for_url(podcast, episode_url).object # parse_episode_action returns a EpisodeHistoryEntry obj history = parse_episode_action(action, user, update_urls, now, diff --git a/mygpo/api/advanced/episode.py b/mygpo/api/advanced/episode.py index 2b12704f2..2741945f2 100644 --- a/mygpo/api/advanced/episode.py +++ b/mygpo/api/advanced/episode.py @@ -54,8 +54,8 @@ def get(self, request, username): def update_chapters(self, req, user): """ Add / remove chapters according to the client's request """ - podcast = Podcast.objects.get_or_create_for_url(podcast_url) - episode = Episode.objects.get_or_create_for_url(podcast, episode_url) + podcast = Podcast.objects.get_or_create_for_url(podcast_url).object + episode = Episode.objects.get_or_create_for_url(podcast, episode_url).object # add chapters for chapter_data in req.get('chapters_add', []): diff --git a/mygpo/api/advanced/lists.py b/mygpo/api/advanced/lists.py index cb586945c..85ac72cf2 100644 --- a/mygpo/api/advanced/lists.py +++ b/mygpo/api/advanced/lists.py @@ -61,7 +61,7 @@ def create(request, username, format): return HttpResponse('List already exists', status=409) urls = parse_subscription(request.body.decode('utf-8'), format) - podcasts = [Podcast.objects.get_or_create_for_url(url) for url in urls] + podcasts = [Podcast.objects.get_or_create_for_url(url).object for url in urls] for podcast in podcasts: plist.add_entry(podcast) @@ -148,7 +148,7 @@ def get_list(request, plist, owner, format): def update_list(request, plist, owner, format): """ Replaces the podcasts in the list and returns 204 No Content """ urls = parse_subscription(request.body.decode('utf-8'), format) - podcasts = [Podcast.objects.get_or_create_for_url(url) for url in urls] + podcasts = [Podcast.objects.get_or_create_for_url(url).object for url in urls] plist.set_entries(podcasts) return HttpResponse(status=204) diff --git a/mygpo/api/legacy.py b/mygpo/api/legacy.py index f7aee4126..d00da2416 100644 --- a/mygpo/api/legacy.py +++ b/mygpo/api/legacy.py @@ -55,11 +55,11 @@ def upload(request): rem = list(set(rem)) for n in new: - p = Podcast.objects.get_or_create_for_url(n) + p = Podcast.objects.get_or_create_for_url(n).object subscribe(p, user, dev) for r in rem: - p = Podcast.objects.get_or_create_for_url(r) + p = Podcast.objects.get_or_create_for_url(r).object unsubscribe(p, user, dev) return HttpResponse('@SUCCESS', content_type='text/plain') diff --git a/mygpo/api/simple.py b/mygpo/api/simple.py index 00970e35a..7105f6d07 100644 --- a/mygpo/api/simple.py +++ b/mygpo/api/simple.py @@ -200,7 +200,7 @@ def set_subscriptions(urls, user, device_uid, user_agent): unsubscribe(podcast, user, device) for url in new: - podcast = Podcast.objects.get_or_create_for_url(url) + podcast = Podcast.objects.get_or_create_for_url(url).object subscribe(podcast, user, device, url) # Only an empty response is a successful response diff --git a/mygpo/api/subscriptions.py b/mygpo/api/subscriptions.py index 5f38984f5..50ac7cf92 100644 --- a/mygpo/api/subscriptions.py +++ b/mygpo/api/subscriptions.py @@ -81,7 +81,7 @@ def update_subscriptions(self, user, device, add, remove): rem_s = filter(lambda x: x not in add_s, rem_s) for add_url in add_s: - podcast = Podcast.objects.get_or_create_for_url(add_url) + podcast = Podcast.objects.get_or_create_for_url(add_url).object subscribe(podcast, user, device, add_url) remove_podcasts = Podcast.objects.filter(urls__url__in=rem_s) diff --git a/mygpo/api/tests.py b/mygpo/api/tests.py index 86504a59d..653126825 100644 --- a/mygpo/api/tests.py +++ b/mygpo/api/tests.py @@ -168,14 +168,14 @@ def setUp(self): defaults = { 'title': 'My Podcast', }, - ) + ).object self.episode = Episode.objects.get_or_create_for_url( self.podcast, 'http://example.com/directory-podcast/1.mp3', defaults = { 'title': 'My Episode', }, - ) + ).object self.client = Client() def test_episode_info(self): diff --git a/mygpo/maintenance/tests.py b/mygpo/maintenance/tests.py index defa14d45..544d7d351 100644 --- a/mygpo/maintenance/tests.py +++ b/mygpo/maintenance/tests.py @@ -22,22 +22,22 @@ def setUp(self): self.podcast1 = Podcast.objects.get_or_create_for_url( 'http://example.com/simple-merge-test-feed.rss', defaults={'title': 'Podcast 1'}, - ) + ).object self.podcast2 = Podcast.objects.get_or_create_for_url( 'http://simple-merge-test.org/podcast/', defaults={'title': 'Podcast 2'}, - ) + ).object self.episode1 = Episode.objects.get_or_create_for_url( self.podcast1, 'http://example.com/simple-merge-test-episode1.mp3', defaults={ 'title': 'Episode 1 A', - }) + }).object self.episode2 = Episode.objects.get_or_create_for_url( self.podcast2, 'http://example.com/simple-merge-test-episode1.mp3', defaults={ 'title': 'Episode 1 B', - }) + }).object def test_merge_podcasts(self): # decide which episodes to merge @@ -55,22 +55,22 @@ def setUp(self): self.podcast1 = Podcast.objects.get_or_create_for_url( 'http://example.com/merge-test-feed.rss', defaults={'title': 'Podcast 1'}, - ) + ).object self.podcast2 = Podcast.objects.get_or_create_for_url( 'http://merge-test.org/podcast/', defaults={'title': 'Podcast 2'}, - ) + ).object self.episode1 = Episode.objects.get_or_create_for_url( self.podcast1, 'http://example.com/merge-test-episode1.mp3', defaults={ 'title': 'Episode 1 A', - }) + }).object self.episode2 = Episode.objects.get_or_create_for_url( self.podcast2, 'http://example.com/merge-test-episode1.mp3', defaults={ 'title': 'Episode 1 B', - }) + }).object User = get_user_model() self.user = User(username='test-merge') @@ -123,38 +123,38 @@ def setUp(self): defaults={ 'title': 'Podcast 1', }, - ) + ).object self.podcast2 = Podcast.objects.get_or_create_for_url( 'http://test.org/group-merge-podcast/', defaults={ 'title': 'Podcast 2', }, - ) + ).object self.podcast3 = Podcast.objects.get_or_create_for_url( 'http://group-test.org/feed/', defaults={ 'title': 'Podcast 3', }, - ) + ).object self.episode1 = Episode.objects.get_or_create_for_url( self.podcast1, 'http://example.com/group-merge-episode1.mp3', defaults={ 'title': 'Episode 1 A', }, - ) + ).object self.episode2 = Episode.objects.get_or_create_for_url( self.podcast2, 'http://example.com/group-merge-episode1.mp3', defaults={ 'title': 'Episode 1 B', }, - ) + ).object self.episode3 = Episode.objects.get_or_create_for_url( self.podcast3, 'http://example.com/group-merge-media.mp3', defaults={ 'title': 'Episode 2', }, - ) + ).object self.podcast2.group_with(self.podcast3, 'My Group', 'Feed1', 'Feed2') diff --git a/mygpo/podcasts/models.py b/mygpo/podcasts/models.py index d5e911516..54fe96c42 100644 --- a/mygpo/podcasts/models.py +++ b/mygpo/podcasts/models.py @@ -1,5 +1,5 @@ - +import collections import uuid import re from datetime import timedelta @@ -22,6 +22,9 @@ logger = logging.getLogger(__name__) +GetCreateResult = collections.namedtuple('GetCreateResult', 'object created') + + # default podcast update interval in hours DEFAULT_UPDATE_INTERVAL = 7 * 24 @@ -395,9 +398,11 @@ def get_or_create_for_url(self, url, defaults={}): url = utils.to_maxlength(URL, 'url', url) try: # try to fetch the podcast - return Podcast.objects.get(urls__url=url, - urls__scope='', - ) + podcast = Podcast.objects.get(urls__url=url, + urls__scope='', + ) + return GetCreateResult(podcast, False) + except Podcast.DoesNotExist: # episode did not exist, try to create it try: @@ -408,13 +413,14 @@ def get_or_create_for_url(self, url, defaults={}): scope='', content_object=podcast, ) - return podcast + return GetCreateResult(podcast, True) # URL could not be created, so it was created since the first get except IntegrityError: - return Podcast.objects.get(urls__url=url, - urls__scope='', - ) + podcast = Podcast.objects.get(urls__url=url, + urls__scope='', + ) + return GetCreateResult(podcast, False) class URL(OrderedModel, ScopedModel): @@ -723,6 +729,7 @@ def get_or_create_for_url(self, podcast, url, defaults={}): try: url = URL.objects.get(url=url, scope=podcast.as_scope) + created = False episode = url.content_object if episode is None: @@ -734,8 +741,9 @@ def get_or_create_for_url(self, podcast, url, defaults={}): url.content_object = episode url.save() + created = True - return episode + return GetCreateResult(episode, created) except URL.DoesNotExist: @@ -758,13 +766,14 @@ def get_or_create_for_url(self, podcast, url, defaults={}): Podcast.objects.filter(pk=podcast.pk)\ .update(episode_count=F('episode_count')+1) - return episode + return GetCreateResult(episode, True) # URL could not be created, so it was created since the first get except IntegrityError: - return Episode.objects.get(urls__url=url, - urls__scope=podcast.as_scope, - ) + episode = Episode.objects.get(urls__url=url, + urls__scope=podcast.as_scope, + ) + return GetCreateResult(episode, False) class Episode(UUIDModel, TitleModel, DescriptionModel, LinkModel, diff --git a/mygpo/podcasts/tests.py b/mygpo/podcasts/tests.py index f0b58307c..9dd3be800 100644 --- a/mygpo/podcasts/tests.py +++ b/mygpo/podcasts/tests.py @@ -33,8 +33,8 @@ def test_next_update(self): def test_get_or_create_for_url(self): """ Test that get_or_create_for_url returns existing Podcast """ URL = 'http://example.com/get_or_create.rss' - p1 = Podcast.objects.get_or_create_for_url(URL) - p2 = Podcast.objects.get_or_create_for_url(URL) + p1 = Podcast.objects.get_or_create_for_url(URL).object + p2 = Podcast.objects.get_or_create_for_url(URL).object self.assertEqual(p1.pk, p2.pk) def test_episode_count(self): @@ -43,7 +43,7 @@ def test_episode_count(self): EPISODE_URL = 'http://example.com/episode%d.mp3' NUM_EPISODES=3 - p = Podcast.objects.get_or_create_for_url(PODCAST_URL) + p = Podcast.objects.get_or_create_for_url(PODCAST_URL).object for n in range(NUM_EPISODES): Episode.objects.get_or_create_for_url(p, EPISODE_URL % (n, )) diff --git a/mygpo/podcasts/views/podcast.py b/mygpo/podcasts/views/podcast.py index ace98826e..14a74854e 100644 --- a/mygpo/podcasts/views/podcast.py +++ b/mygpo/podcasts/views/podcast.py @@ -326,7 +326,7 @@ def subscribe_url(request): if not url: raise Http404('Please specify a valid url') - podcast = Podcast.objects.get_or_create_for_url(url) + podcast = Podcast.objects.get_or_create_for_url(url).object return HttpResponseRedirect(get_podcast_link_target(podcast, 'subscribe')) diff --git a/mygpo/share/views.py b/mygpo/share/views.py index faf37245a..b2a4f8be9 100644 --- a/mygpo/share/views.py +++ b/mygpo/share/views.py @@ -93,7 +93,7 @@ def post(self, request): site = RequestSite(request) feed_url = feed.get_public_url(site.domain) - podcast = Podcast.objects.get_or_create_for_url(feed_url) + podcast = Podcast.objects.get_or_create_for_url(feed_url).object PublishedPodcast.objects.get_or_create( podcast=podcast, diff --git a/mygpo/subscriptions/tests.py b/mygpo/subscriptions/tests.py index 528cf1761..72d37d548 100644 --- a/mygpo/subscriptions/tests.py +++ b/mygpo/subscriptions/tests.py @@ -25,7 +25,7 @@ def setUp(self): user=self.user, uid='dev1', id=uuid.uuid1()) self.url = 'http://www.example.com/pdocast.rss' - self.podcast = Podcast.objects.get_or_create_for_url(self.url) + self.podcast = Podcast.objects.get_or_create_for_url(self.url).object def test_duplicate_subscribe(self): """ Test that a duplicate subscription is skipped """ diff --git a/mygpo/users/tests.py b/mygpo/users/tests.py index 5c6800020..6d5f137c4 100644 --- a/mygpo/users/tests.py +++ b/mygpo/users/tests.py @@ -66,8 +66,11 @@ class UnsubscribeMergeTests(TestCase): P2_URL = 'http://test.org/podcast/' def setUp(self): - self.podcast1 = Podcast.objects.get_or_create_for_url('http://example.com/feed.rss') - self.podcast2 = Podcast.objects.get_or_create_for_url(self.P2_URL) + self.podcast1 = Podcast.objects.get_or_create_for_url( + 'http://example.com/feed.rss').object + + self.podcast2 = Podcast.objects.get_or_create_for_url( + self.P2_URL).object User = get_user_model() self.user = User(username='test-merge') diff --git a/mygpo/usersettings/tests.py b/mygpo/usersettings/tests.py index 0ed32e749..9de6321a0 100644 --- a/mygpo/usersettings/tests.py +++ b/mygpo/usersettings/tests.py @@ -22,11 +22,14 @@ def setUp(self): self.podcast_url = 'http://example.com/podcast.rss' self.episode_url = 'http://example.com/podcast/episode-1.mp3' self.uid = 'client-uid' - self.podcast = Podcast.objects.get_or_create_for_url(self.podcast_url) + self.podcast = Podcast.objects.get_or_create_for_url( + self.podcast_url).object + self.episode = Episode.objects.get_or_create_for_url( self.podcast, self.episode_url, - ) + ).object + self.user_client = Client.objects.create( id = uuid.uuid1(), user = self.user, diff --git a/mygpo/web/tests.py b/mygpo/web/tests.py index 9dd7c2d4a..cca2c226b 100644 --- a/mygpo/web/tests.py +++ b/mygpo/web/tests.py @@ -74,7 +74,7 @@ def setUp(self): episode = Episode.objects.get_or_create_for_url( podcast, 'http://www.example.com/episode%d.mp3' % (n, ), - ) + ).object # we only need (the last) one self.episode_slug = Slug.objects.create(content_object=episode, From b0227c0a975340c3cae9b93fbf9efc4a45b6fa68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:44:30 +0100 Subject: [PATCH 032/106] Update Procfile --- Procfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Procfile b/Procfile index cbbcbbb6e..4dd801905 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,3 @@ -web: gunicorn mygpo.wsgi:application -c gunicorn.conf.py -beat: python manage.py celery beat -S django --pidfile /var/run/mygpo/celerybeat.pid +web: gunicorn mygpo.wsgi:application -c conf/gunicorn.conf.py +beat: celery -A mygpo beat --pidfile /tmp/celerybeat.pid -S django +celery: celery -A mygpo worker --concurrency=3 -l info -Ofair From 43238d0de9e4d6d4909b4d67c17449a9599e5dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:45:55 +0100 Subject: [PATCH 033/106] Format short durations without "0 hours" --- mygpo/web/templatetags/time.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mygpo/web/templatetags/time.py b/mygpo/web/templatetags/time.py index 760f09ef9..3a3d72c34 100644 --- a/mygpo/web/templatetags/time.py +++ b/mygpo/web/templatetags/time.py @@ -29,10 +29,16 @@ def format_duration(sec): """ Converts seconds into a duration string >>> format_duration(1000) - '0h 16m 40s' + '16m 40s' + >>> format_duration(10009) + '2h 46m 49s' """ hours = int(sec / 60 / 60) minutes = int((sec / 60) % 60) seconds = int(sec % 60) - return _('{h}h {m}m {s}s').format(h=hours, m=minutes, s=seconds) + + if hours: + return _('{h}h {m}m {s}s').format(h=hours, m=minutes, s=seconds) + else: + return _('{m}m {s}s').format(m=minutes, s=seconds) From 0309dc17399b6a55e6c7c03838cdcb0af1c58ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:46:36 +0100 Subject: [PATCH 034/106] Fix variable name in update_related_podcasts() --- mygpo/data/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/data/tasks.py b/mygpo/data/tasks.py index 09d241c69..0ee31043e 100644 --- a/mygpo/data/tasks.py +++ b/mygpo/data/tasks.py @@ -25,7 +25,7 @@ def update_podcasts(podcast_urls): def update_related_podcasts(podcast_pk, max_related=20): get_podcast = itemgetter(0) - podcast = Podcast.objects.get(pk=pk) + podcast = Podcast.objects.get(pk=podcast_pk) related = calc_similar_podcasts(podcast)[:max_related] related = map(get_podcast, related) From e8fe4fde046144236df679bb6519e8dadf06aa93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:47:09 +0100 Subject: [PATCH 035/106] Collect results when updating podcasts --- htdocs/media/screen.css | 19 +++++++ mygpo/data/admin.py | 18 +++++++ mygpo/data/feeddownloader.py | 47 +++++++++++------ .../migrations/0002_result_podcast_null.py | 21 ++++++++ .../0003_podcastupdateresult_podcast_url.py | 21 ++++++++ mygpo/data/models.py | 34 ++++++++++++- mygpo/podcasts/models.py | 4 ++ .../templates/publisher/podcast.html | 50 ++++++++++++++++--- mygpo/publisher/views.py | 7 +++ 9 files changed, 200 insertions(+), 21 deletions(-) create mode 100644 mygpo/data/admin.py create mode 100644 mygpo/data/migrations/0002_result_podcast_null.py create mode 100644 mygpo/data/migrations/0003_podcastupdateresult_podcast_url.py diff --git a/htdocs/media/screen.css b/htdocs/media/screen.css index 6a1950933..b2d396193 100644 --- a/htdocs/media/screen.css +++ b/htdocs/media/screen.css @@ -1,3 +1,9 @@ +:root { + --color-status-success: 90; + --color-status-error: 0; + --color-status-neutral: 247; +} + /* Landscape phones and down */ @media (min-width: 980px) @@ -628,3 +634,16 @@ div.podcasts div.podcast:hover div.actions button.btn .hosting { text-align: center; } + +.status-success { + background-color: hsla(var(--color-status-success), 100%, 75%, 1); +} + + +.status-error { + background-color: hsla(var(--color-status-error), 100%, 75%, 1); +} + +.status-neutral { + background-color: hsla(var(--color-status-neutral), 16%, 85%, 1); +} diff --git a/mygpo/data/admin.py b/mygpo/data/admin.py new file mode 100644 index 000000000..cc94ec441 --- /dev/null +++ b/mygpo/data/admin.py @@ -0,0 +1,18 @@ +from django.contrib import admin + +from . import models + + +@admin.register(models.PodcastUpdateResult) +class PodcastUpdateResultAdmin(admin.ModelAdmin): + model = models.PodcastUpdateResult + + list_display = ['title', 'start', 'duration', 'successful', + 'episodes_added'] + + readonly_fields = ['id', 'podcast_url', 'podcast', 'start', 'duration', + 'successful', 'error_message', 'podcast_created', + 'episodes_added'] + + def title(self, res): + return res.podcast or res.podcast_url diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index 42b5898a3..19a5a448d 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -28,6 +28,8 @@ from mygpo.directory.tags import update_category from mygpo.search import get_index_fields +from . import models + import logging logger = logging.getLogger(__name__) @@ -77,22 +79,31 @@ def __init__(self, podcast_url): def update_podcast(self): """ Update the podcast """ - parsed = self.parse_feed() - if not parsed: - return + with models.PodcastUpdateResult(podcast_url=self.podcast_url) as res: - podcast = Podcast.objects.get_or_create_for_url(self.podcast_url) + parsed = self.parse_feed() + if not parsed: + res.podcast_created = False + res.error_message = '"{}" could not be parsed'.format( + self.podcast_url) + return - episode_updater = MultiEpisodeUpdater(podcast) - episode_updater.update_episodes(parsed.get('episodes', [])) + podcast, created = Podcast.objects.get_or_create_for_url( + self.podcast_url) + res.podcast = podcast + res.podcast_created = created - podcast.refresh_from_db() - podcast.episode_count = Episode.objects.filter(podcast=podcast).count() - podcast.save() + res.episodes_added = 0 + episode_updater = MultiEpisodeUpdater(podcast, res) + episode_updater.update_episodes(parsed.get('episodes', [])) + + podcast.refresh_from_db() + podcast.episode_count = episode_updater.count_episodes() + podcast.save() - episode_updater.order_episodes() + episode_updater.order_episodes() - self._update_podcast(podcast, parsed, episode_updater) + self._update_podcast(podcast, parsed, episode_updater) return podcast @@ -123,7 +134,7 @@ def parse_feed(self): # if we fail to parse the URL, we don't even create the # podcast object try: - p = Podcast.objects.get(urls__url=podcast_url) + p = Podcast.objects.get(urls__url=self.podcast_url) # if it exists already, we mark it as outdated self._mark_outdated(p, 'error while fetching feed: {}'.format( str(nee))) @@ -354,8 +365,9 @@ def _mark_outdated(podcast, msg=''): class MultiEpisodeUpdater(object): - def __init__(self, podcast): + def __init__(self, podcast, update_result): self.podcast = podcast + self.update_result = update_result self.updated_episodes = [] self.max_episode_order = None @@ -378,7 +390,11 @@ def update_episodes(self, parsed_episodes): logger.info('Updating episode %d / %d', n, len(parsed_episodes)) - episode = Episode.objects.get_or_create_for_url(self.podcast, url) + episode, created = Episode.objects.get_or_create_for_url( + self.podcast, url) + + if created: + self.update_result.episodes_added += 1 updater = EpisodeUpdater(episode, self.podcast) updater.update_episode(parsed) @@ -435,6 +451,9 @@ def get_episode_url(self, parsed_episode): return f['urls'][0] return None + def count_episodes(self): + return Episode.objects.filter(podcast=self.podcast).count() + def get_update_interval(self, episodes): """ calculates the avg interval between new episodes """ diff --git a/mygpo/data/migrations/0002_result_podcast_null.py b/mygpo/data/migrations/0002_result_podcast_null.py new file mode 100644 index 000000000..4149dfcf4 --- /dev/null +++ b/mygpo/data/migrations/0002_result_podcast_null.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-12-03 17:22 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='podcastupdateresult', + name='podcast', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='podcasts.Podcast'), + ), + ] diff --git a/mygpo/data/migrations/0003_podcastupdateresult_podcast_url.py b/mygpo/data/migrations/0003_podcastupdateresult_podcast_url.py new file mode 100644 index 000000000..89b0d97c5 --- /dev/null +++ b/mygpo/data/migrations/0003_podcastupdateresult_podcast_url.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-12-03 17:28 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0002_result_podcast_null'), + ] + + operations = [ + migrations.AddField( + model_name='podcastupdateresult', + name='podcast_url', + field=models.URLField(default='unknown', max_length=2048), + preserve_default=False, + ), + ] diff --git a/mygpo/data/models.py b/mygpo/data/models.py index 7958f2b5c..02b0bc11e 100644 --- a/mygpo/data/models.py +++ b/mygpo/data/models.py @@ -1,3 +1,5 @@ +import uuid + from datetime import datetime from django.db import models @@ -11,8 +13,11 @@ class PodcastUpdateResult(UUIDModel): Once an instance is stored, the update is assumed to be finished. """ + # URL of the podcast to be updated + podcast_url = models.URLField(max_length=2048) + # The podcast that was updated - podcast = models.ForeignKey(Podcast, on_delete=models.CASCADE) + podcast = models.ForeignKey(Podcast, on_delete=models.CASCADE, null=True) # The timestamp at which the updated started to be executed start = models.DateTimeField(default=datetime.utcnow) @@ -42,3 +47,30 @@ class Meta(object): models.Index(fields=['podcast', 'start']) ] + def __str__(self): + return 'Update Result for "{}" @ {:%Y-%m-%d %H:%M}'.format( + self.podcast, self.start) + + # Use as context manager + + def __enter__(self): + self.id = uuid.uuid4() + self.start = datetime.utcnow() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.duration = datetime.utcnow() - self.start + + success = (exc_type, exc_value, traceback) == (None, None, None) + self.successful = success + + if not success: + self.error_message = str(exc_value) + + if self.podcast_created is None: + self.podcast_created = False + + if self.episodes_added is None: + self.episodes_added = 0 + + self.save() diff --git a/mygpo/podcasts/models.py b/mygpo/podcasts/models.py index 54fe96c42..6b5d1f967 100644 --- a/mygpo/podcasts/models.py +++ b/mygpo/podcasts/models.py @@ -696,6 +696,10 @@ def display_title(self): return _('Unknown Podcast from {domain}'.format( domain=utils.get_domain(self.url))) + @property + def next_update(self): + return self.last_update + timedelta(hours=self.update_interval) + class EpisodeQuerySet(MergedUUIDQuerySet): """ QuerySet for Episodes """ diff --git a/mygpo/publisher/templates/publisher/podcast.html b/mygpo/publisher/templates/publisher/podcast.html index 93c03a38a..314ab388e 100644 --- a/mygpo/publisher/templates/publisher/podcast.html +++ b/mygpo/publisher/templates/publisher/podcast.html @@ -4,6 +4,7 @@ {% load podcasts %} {% load charts %} {% load pcharts %} +{% load time %} {% load static %} {% load menu %} {% load utils %} @@ -56,12 +57,49 @@

Podcast Data

{% trans "The podcast information is regularly retrieved from the podcast feed" %}

{{ podcast.url }}
-

{% trans "Timing" %}

-
    -
  • {% trans "Last update:" %} {{ podcast.last_update|naturaltime }}
  • -
  • {% trans "Update interval:" %} {{ podcast.update_interval|hours_to_str }}
  • -
  • {% trans "Next update:" %} {{ podcast.next_update|naturaltime }}
  • -
+

{% trans "Updates" %}

+ + {% trans "Update interval:" %} {{ podcast.update_interval|hours_to_str }} + + + + + + + + + + + + + + + + + + {% for result in update_results %} + + + + + + + {% empty %} + + + + + + + {% endfor %} + +
StartDurationStatusEpisodes Added
{{ podcast.next_update|naturaltime }}Next
{{ result.start|naturaltime }}{{ result.duration.total_seconds|format_duration }} + {% if result.successful %} + {% trans "Successful" %} + {% else %} + {% trans "Error" %} {{ result.error_message }} + {% endif %} + {{ result.episodes_added }}
{{ podcast.last_update|naturaltime }}
{% csrf_token %} diff --git a/mygpo/publisher/views.py b/mygpo/publisher/views.py index 9e62e98b7..5038cdf8f 100644 --- a/mygpo/publisher/views.py +++ b/mygpo/publisher/views.py @@ -31,6 +31,7 @@ get_episode_link_target from django.contrib.sites.requests import RequestSite from mygpo.data.tasks import update_podcasts +from mygpo.data.models import PodcastUpdateResult from mygpo.decorators import requires_token, allowed_methods from mygpo.pubsub.models import HubSubscription @@ -92,6 +93,11 @@ def podcast(request, podcast): except HubSubscription.DoesNotExist: pubsubscription = None + MAX_UPDATE_RESULTS=10 + + update_results = PodcastUpdateResult.objects.filter(podcast=podcast) + update_results = update_results[:MAX_UPDATE_RESULTS] + site = RequestSite(request) feedurl_quoted = urllib.parse.quote(podcast.url.encode('ascii')) @@ -105,6 +111,7 @@ def podcast(request, podcast): 'update_token': update_token, 'feedurl_quoted': feedurl_quoted, 'pubsubscription': pubsubscription, + 'update_results': update_results, }) From 4460405a640e3fcb400bc096b69a2b646ea61d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 18:54:01 +0100 Subject: [PATCH 036/106] Fix Podcast's order_by_next_update() --- mygpo/podcasts/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mygpo/podcasts/models.py b/mygpo/podcasts/models.py index 6b5d1f967..7e7ea0561 100644 --- a/mygpo/podcasts/models.py +++ b/mygpo/podcasts/models.py @@ -342,8 +342,8 @@ def license(self, license_url=None): def order_by_next_update(self): """ Sort podcasts by next scheduled update """ NEXTUPDATE = "last_update + (update_interval || ' hours')::INTERVAL" - q = self.extra(select={'next_update': NEXTUPDATE}) - return q.order_by('next_update') + q = self.extra(select={'_next_update': NEXTUPDATE}) + return q.order_by('_next_update') @property def next_update(self): From 35490229c1e35eb695cc269b510f823f5a808b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 19:40:12 +0100 Subject: [PATCH 037/106] Fix error when marking podcasts as outdated --- mygpo/data/feeddownloader.py | 59 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index 19a5a448d..a6aae1050 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -81,20 +81,29 @@ def update_podcast(self): with models.PodcastUpdateResult(podcast_url=self.podcast_url) as res: - parsed = self.parse_feed() - if not parsed: + parsed, podcast, created = self.parse_feed() + + if not podcast: res.podcast_created = False res.error_message = '"{}" could not be parsed'.format( self.podcast_url) + return - podcast, created = Podcast.objects.get_or_create_for_url( - self.podcast_url) res.podcast = podcast res.podcast_created = created res.episodes_added = 0 episode_updater = MultiEpisodeUpdater(podcast, res) + + if not parsed: + # if it exists already, we mark it as outdated + self._mark_outdated( + podcast, + 'error while fetching feed', + episode_updater) + return + episode_updater.update_episodes(parsed.get('episodes', [])) podcast.refresh_from_db() @@ -112,38 +121,24 @@ def parse_feed(self): parsed = self._fetch_feed() self._validate_parsed(parsed) - except requests.exceptions.RequestException as re: - logging.exception('Error while fetching response from feedservice') + except (requests.exceptions.RequestException, + NoEpisodesException) as ex: + logging.exception('Error while fetching/parsing feed') # if we fail to parse the URL, we don't even create the # podcast object try: p = Podcast.objects.get(urls__url=podcast_url) - # if it exists already, we mark it as outdated - _mark_outdated(p, 'error while fetching feed: %s' % str(re)) - p.last_update = datetime.utcnow() - p.save() - return None + return (None, p, False) except Podcast.DoesNotExist as pdne: - raise NoPodcastCreated(re) from pdne - - except NoEpisodesException as nee: - logging.warn('No episode found while parsing podcast') - - # if we fail to parse the URL, we don't even create the - # podcast object - try: - p = Podcast.objects.get(urls__url=self.podcast_url) - # if it exists already, we mark it as outdated - self._mark_outdated(p, 'error while fetching feed: {}'.format( - str(nee))) - return None + raise NoPodcastCreated(ex) from pdne - except Podcast.DoesNotExist as pdne: - raise NoPodcastCreated(nee) from pdne + # Parsing went well, get podcast + podcast, created = Podcast.objects.get_or_create_for_url( + self.podcast_url) - return parsed + return (parsed, podcast, created) def _fetch_feed(self): params = { @@ -230,7 +225,11 @@ def _update_podcast(self, podcast, parsed, episode_updater): ) if new_podcast != podcast: - _mark_outdated(podcast, 'redirected to different podcast') + self._mark_outdated( + podcast, + 'redirected to different podcast', + episode_updater, + ) return except Podcast.DoesNotExist: podcast.set_url(podcast.new_location) @@ -355,12 +354,12 @@ def _save_podcast_logo(self, cover_art): http.client.HTTPException, socket.error, IOError) as e: logger.warn('Exception while updating podcast logo: %s', str(e)) - def _mark_outdated(podcast, msg=''): + def _mark_outdated(self, podcast, msg, episode_updater): logger.info('marking podcast outdated: %s', msg) podcast.outdated = True podcast.last_update = datetime.utcnow() podcast.save() - _update_episodes(podcast, []) + episode_updater.update_episodes([]) class MultiEpisodeUpdater(object): From 601bc439d976e3aa7f3e04d7af1076f481cc00c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 19:43:17 +0100 Subject: [PATCH 038/106] Fix scheduling of podcast updates --- mygpo/data/tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mygpo/data/tasks.py b/mygpo/data/tasks.py index 0ee31043e..5235fd28c 100644 --- a/mygpo/data/tasks.py +++ b/mygpo/data/tasks.py @@ -78,5 +78,6 @@ def _schedule_updates(podcasts): for podcast in podcasts: # update_podcasts.delay() seems to block other task execution, # therefore celery.send_task() is used instead + urls = [podcast.url] celery.send_task('mygpo.data.tasks.update_podcasts', - args=[podcast.url]) + args=[urls]) From 294ac46ed502779136395b25141b21e27cb7f2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 20:58:26 +0100 Subject: [PATCH 039/106] Fix variable in podcast updater --- mygpo/data/feeddownloader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index a6aae1050..9e7b3178c 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -128,7 +128,7 @@ def parse_feed(self): # if we fail to parse the URL, we don't even create the # podcast object try: - p = Podcast.objects.get(urls__url=podcast_url) + p = Podcast.objects.get(urls__url=self.podcast_url) return (None, p, False) except Podcast.DoesNotExist as pdne: From cd31eaa62c689c979c06900cab77749ef245d32b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 20:59:06 +0100 Subject: [PATCH 040/106] Modify Podcast.update_interval with factor When no new episodes are found, the factor increases the interval between podcast updates. --- mygpo/data/feeddownloader.py | 11 ++++++++++ .../0040_podcast_update_interval_factor.py | 20 +++++++++++++++++++ mygpo/podcasts/models.py | 20 +++++++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 mygpo/podcasts/migrations/0040_podcast_update_interval_factor.py diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index 9e7b3178c..79dcbab0f 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -239,8 +239,19 @@ def _update_podcast(self, podcast, parsed, episode_updater): released__isnull=False)\ .order_by('released') + # Determine update interval + + # Update interval is based on intervals between episodes podcast.update_interval = episode_updater.get_update_interval(episodes) + # factor is increased / decreased depending on whether the latest + # update has returned episodes + if episode_updater.episodes_added == 0: # no episodes, incr factor + podcast.update_interval_factor *= 1.2 + elif episode_updater.episodes_added > 1: # new episodes, decr factor + newfactor = podcast.update_interval_factor / 1.2 + podcast.update_interval_factor = max(1, newfactor) # never below 1 + latest_episode = episodes.last() if latest_episode: podcast.latest_episode_timestamp = latest_episode.released diff --git a/mygpo/podcasts/migrations/0040_podcast_update_interval_factor.py b/mygpo/podcasts/migrations/0040_podcast_update_interval_factor.py new file mode 100644 index 000000000..57447b2dc --- /dev/null +++ b/mygpo/podcasts/migrations/0040_podcast_update_interval_factor.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-12-03 19:53 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('podcasts', '0039_podcast_search_index_uptodate'), + ] + + operations = [ + migrations.AddField( + model_name='podcast', + name='update_interval_factor', + field=models.FloatField(default=1), + ), + ] diff --git a/mygpo/podcasts/models.py b/mygpo/podcasts/models.py index 7e7ea0561..f4596181f 100644 --- a/mygpo/podcasts/models.py +++ b/mygpo/podcasts/models.py @@ -341,16 +341,20 @@ def license(self, license_url=None): def order_by_next_update(self): """ Sort podcasts by next scheduled update """ - NEXTUPDATE = "last_update + (update_interval || ' hours')::INTERVAL" + NEXTUPDATE = ("last_update + (update_interval * " + "update_interval_factor || ' hours')::INTERVAL") q = self.extra(select={'_next_update': NEXTUPDATE}) return q.order_by('_next_update') @property def next_update(self): - return self.last_update + timedelta(hours=self.update_interval) + interval = (timedelta(hours=self.update_interval) * + self.update_interval_factor) + return self.last_update + interval def next_update_between(self, start, end): - NEXTUPDATE_BETWEEN = ("(last_update + (update_interval || " + NEXTUPDATE_BETWEEN = ("(last_update + (update_interval * " + " update_interval_factor || " "' hours')::INTERVAL) BETWEEN %s AND %s") return self.extra( where=[NEXTUPDATE_BETWEEN], params=[start, end] @@ -570,9 +574,15 @@ class Podcast(UUIDModel, TitleModel, DescriptionModel, LinkModel, latest_episode_timestamp = models.DateTimeField(null=True) episode_count = models.PositiveIntegerField(default=0) hub = models.URLField(null=True) + + # Interval between episodes, within a specified range update_interval = models.PositiveSmallIntegerField(null=False, default=DEFAULT_UPDATE_INTERVAL) + # factor to increase update_interval if an update does not find any + # new episodes + update_interval_factor = models.FloatField(default=1) + # "order" value of the most recent episode (will be the highest of all) max_episode_order = models.PositiveIntegerField(null=True, default=None) @@ -698,7 +708,9 @@ def display_title(self): @property def next_update(self): - return self.last_update + timedelta(hours=self.update_interval) + interval = (timedelta(hours=self.update_interval) * + self.update_interval_factor) + return self.last_update + interval class EpisodeQuerySet(MergedUUIDQuerySet): From 32b14c11d6ca14df777d6376d68d00001b1a2cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 22:15:41 +0100 Subject: [PATCH 041/106] Show waiting celery tasks in admin interface --- mygpo/administration/views.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mygpo/administration/views.py b/mygpo/administration/views.py index 0c9b5c689..d351421c0 100644 --- a/mygpo/administration/views.py +++ b/mygpo/administration/views.py @@ -4,6 +4,8 @@ from collections import Counter from datetime import datetime +import redis + import django from django.shortcuts import render from django.contrib import messages @@ -57,13 +59,6 @@ def get(self, request): hostname = socket.gethostname() django_version = django.VERSION - i = celery.control.inspect() - scheduled = i.scheduled() - if not scheduled: - num_celery_tasks = None - else: - num_celery_tasks = sum(len(node) for node in scheduled.values()) - feed_queue_status = self._get_feed_queue_status() num_index_outdated = self._get_num_outdated_search_index() @@ -73,11 +68,22 @@ def get(self, request): 'base_dir': base_dir, 'hostname': hostname, 'django_version': django_version, - 'num_celery_tasks': num_celery_tasks, + 'num_celery_tasks': self._get_waiting_celery_tasks(), 'feed_queue_status': feed_queue_status, 'num_index_outdated': num_index_outdated, }) + def _get_waiting_celery_tasks(self): + con = celery.broker_connection() + + args = {'host': con.hostname} + if con.port: + args['port'] = con.port + + r = redis.StrictRedis(**args) + return r.llen('celery') + + def _get_feed_queue_status(self): now = datetime.utcnow() next_podcast = Podcast.objects.all().order_by_next_update().first() From 514556a491abef7e5b55ec92245ad263d365a6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 3 Dec 2017 22:23:34 +0100 Subject: [PATCH 042/106] Show avg podcast update duration in admin area --- mygpo/administration/templates/admin/hostinfo.html | 10 ++++++++++ mygpo/administration/views.py | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/mygpo/administration/templates/admin/hostinfo.html b/mygpo/administration/templates/admin/hostinfo.html index e09c45ea3..ad273f682 100644 --- a/mygpo/administration/templates/admin/hostinfo.html +++ b/mygpo/administration/templates/admin/hostinfo.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load i18n %} +{% load time %} {% load podcasts %} {% load menu %} @@ -62,6 +63,15 @@

{% trans "Host Information" %}

{{ num_index_outdated }} + + + + {% trans "Average podcast update duration" %} + + + {{ avg_podcast_update_duration.total_seconds|format_duration}} + + {% trans "Scheduled Celery Tasks" %} {{ num_celery_tasks }} diff --git a/mygpo/administration/views.py b/mygpo/administration/views.py index d351421c0..16353feea 100644 --- a/mygpo/administration/views.py +++ b/mygpo/administration/views.py @@ -7,6 +7,7 @@ import redis import django +from django.db.models import Avg from django.shortcuts import render from django.contrib import messages from django.urls import reverse @@ -28,6 +29,7 @@ from mygpo.administration.clients import UserAgentStats, ClientStats from mygpo.administration.tasks import merge_podcasts from mygpo.utils import get_git_head +from mygpo.data.models import PodcastUpdateResult from mygpo.users.models import UserProxy from mygpo.publisher.models import PublishedPodcast from mygpo.api.httpresponse import JsonResponse @@ -61,6 +63,7 @@ def get(self, request): feed_queue_status = self._get_feed_queue_status() num_index_outdated = self._get_num_outdated_search_index() + avg_podcast_update_duration = self._get_avg_podcast_update_duration() return self.render_to_response({ 'git_commit': commit, @@ -69,6 +72,7 @@ def get(self, request): 'hostname': hostname, 'django_version': django_version, 'num_celery_tasks': self._get_waiting_celery_tasks(), + 'avg_podcast_update_duration': avg_podcast_update_duration, 'feed_queue_status': feed_queue_status, 'num_index_outdated': num_index_outdated, }) @@ -83,6 +87,9 @@ def _get_waiting_celery_tasks(self): r = redis.StrictRedis(**args) return r.llen('celery') + def _get_avg_podcast_update_duration(self): + queryset = PodcastUpdateResult.objects.filter(successful=True) + return queryset.aggregate(avg_duration=Avg('duration'))['avg_duration'] def _get_feed_queue_status(self): now = datetime.utcnow() From e08b59c91c0ebc1e295a2c0ac7d3868145575038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 15 Dec 2017 20:06:00 +0100 Subject: [PATCH 043/106] Remove Opbeat Opbeat is being sunset on May 24, 2018 --- mygpo/settings.py | 10 ---------- requirements-setup.txt | 1 - 2 files changed, 11 deletions(-) diff --git a/mygpo/settings.py b/mygpo/settings.py index 336835ea5..3227c50a7 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -179,16 +179,6 @@ def get_intOrNone(name, default): pass -try: - import opbeat - - if not DEBUG: - INSTALLED_APPS += ['opbeat.contrib.django'] - -except ImportError: - pass - - ACCOUNT_ACTIVATION_DAYS = int(os.getenv('ACCOUNT_ACTIVATION_DAYS', 7)) AUTHENTICATION_BACKENDS = ( diff --git a/requirements-setup.txt b/requirements-setup.txt index 3831a5081..fa834b459 100644 --- a/requirements-setup.txt +++ b/requirements-setup.txt @@ -1,2 +1 @@ envdir -opbeat==3.5.2 From 3def98bc06df9f3ec50786fd4a58d07d5757fd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 15 Dec 2017 20:30:40 +0100 Subject: [PATCH 044/106] Update psycopg2cffi to fix Travis install errors psycopg2cffi 2.7.7 change log: Support installation under Postgres 10 by jimbattin (#90) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6bfe2ef9d..feb5452dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ gunicorn==19.7.1 html2text==2016.9.19 markdown2==2.3.4 oauth2client==4.1.2 -psycopg2cffi==2.7.6 +psycopg2cffi==2.7.7 python-dateutil==2.6.1 redis==2.10.6 django-celery-results==1.0.1 From 5f623b238f1d432dbcb9de2639e3e4f0f20a1a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 30 Dec 2017 16:07:46 +0000 Subject: [PATCH 045/106] Fix podcast updater --- mygpo/data/feeddownloader.py | 23 ++++++++++++++--------- mygpo/data/tasks.py | 1 + 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/mygpo/data/feeddownloader.py b/mygpo/data/feeddownloader.py index 79dcbab0f..c05e0c41c 100755 --- a/mygpo/data/feeddownloader.py +++ b/mygpo/data/feeddownloader.py @@ -64,6 +64,9 @@ def update_podcasts(queue): except NoPodcastCreated as npc: logger.info('No podcast created: %s', npc) + except GeneratorExit: + pass + except: logger.exception('Error while updating podcast "%s"', podcast_url) @@ -112,7 +115,7 @@ def update_podcast(self): episode_updater.order_episodes() - self._update_podcast(podcast, parsed, episode_updater) + self._update_podcast(podcast, parsed, episode_updater, res) return podcast @@ -153,7 +156,7 @@ def _fetch_feed(self): if r.status_code != 200: logger.error('Feed-service status code for "{}" was {}'.format( - podcast_url, r.status_code)) + url, r.status_code)) return None try: @@ -174,7 +177,7 @@ def _validate_parsed(self, parsed): if not parsed or not parsed.get('episodes', []): raise NoEpisodesException('no episodes found') - def _update_podcast(self, podcast, parsed, episode_updater): + def _update_podcast(self, podcast, parsed, episode_updater, update_result): """ updates a podcast according to new parser results """ # we need that later to decide if we can "bump" a category @@ -246,9 +249,10 @@ def _update_podcast(self, podcast, parsed, episode_updater): # factor is increased / decreased depending on whether the latest # update has returned episodes - if episode_updater.episodes_added == 0: # no episodes, incr factor - podcast.update_interval_factor *= 1.2 - elif episode_updater.episodes_added > 1: # new episodes, decr factor + if update_result.episodes_added == 0: # no episodes, incr factor + newfactor = podcast.update_interval_factor * 1.2 + podcast.update_interval_factor = min(1000, newfactor) # never above 1000 + elif update_result.episodes_added > 1: # new episodes, decr factor newfactor = podcast.update_interval_factor / 1.2 podcast.update_interval_factor = max(1, newfactor) # never below 1 @@ -600,7 +604,8 @@ def file_basename_no_extension(filename): return name -def verify_podcast_url(self): - parsed = _fetch_feed(self.podcast_url) - self._validate_parsed(parsed) +def verify_podcast_url(url): + updater = PodcastUpdater(url) + parsed = updater._fetch_feed() + updater._validate_parsed(parsed) return True diff --git a/mygpo/data/tasks.py b/mygpo/data/tasks.py index 5235fd28c..a4e577b12 100644 --- a/mygpo/data/tasks.py +++ b/mygpo/data/tasks.py @@ -18,6 +18,7 @@ def update_podcasts(podcast_urls): """ Task to update a podcast """ from mygpo.data.feeddownloader import update_podcasts as update podcasts = update(podcast_urls) + podcasts = filter(None, podcasts) return [podcast.pk for podcast in podcasts] From 4ad55fb3c3b52a848bbd447959b50714e6ecedcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 30 Dec 2017 18:08:46 +0100 Subject: [PATCH 046/106] Update installation instructions to (fixes #81) --- doc/dev/installation.rst | 61 ++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/doc/dev/installation.rst b/doc/dev/installation.rst index 0cbe2b31b..b1bb8d95a 100644 --- a/doc/dev/installation.rst +++ b/doc/dev/installation.rst @@ -43,20 +43,7 @@ Now install additional dependencies locally: pip install -r requirements-test.txt # for running tests -That's it for the setup. Now to initialize the DB: - -First run the commands from :ref:`db-setup`. Then - -.. code-block:: bash - - cd mygpo - python manage.py migrate - -..and here we go: - -.. code-block:: bash - - python manage.py runserver +That's it for the setup. Configuration @@ -75,6 +62,26 @@ For a development configuration you will probably want to use the following See :ref:`configuration` for further information. +Database Initialization +----------------------- + +Now to initialize the DB: + +First run the commands from :ref:`db-setup`. Then + +.. code-block:: bash + + cd mygpo + envdir envs/local python manage.py migrate + +..and here we go: + +.. code-block:: bash + + envdir envs/local python manage.py runserver + + + Accessing the dev server from other devices ------------------------------------------- @@ -84,7 +91,7 @@ runserver command of manage.py, like this: .. code-block:: bash - python manage.py runserver 0.0.0.0:8000 + envdir envs/local python manage.py runserver 0.0.0.0:8000 Beware, though, that this will expose the web service to your all networks that your machine is connected to. Apply common sense and ideally use only @@ -101,22 +108,22 @@ commands regularly on your development machine: .. code-block:: bash - python manage.py update-categories - python manage.py update-toplist - python manage.py update-episode-toplist + envdir envs/local python manage.py update-categories + envdir envs/local python manage.py update-toplist + envdir envs/local python manage.py update-episode-toplist - python manage.py feed-downloader - python manage.py feed-downloader [...] - python manage.py feed-downloader --max - python manage.py feed-downloader --random --max - python manage.py feed-downloader --toplist --max - python manage.py feed-downloader --update-new --max + envdir envs/local python manage.py feed-downloader + envdir envs/local python manage.py feed-downloader [...] + envdir envs/local python manage.py feed-downloader --max + envdir envs/local python manage.py feed-downloader --random --max + envdir envs/local python manage.py feed-downloader --toplist --max + envdir envs/local python manage.py feed-downloader --update-new --max or to only do a dry run (this won't do any web requests for feeds): .. code-block:: bash - python manage.py feed-downloader --list-only [other parameters] + envdir envs/local python manage.py feed-downloader --list-only [other parameters] Maintaining publisher relationships with user accounts @@ -127,7 +134,7 @@ To set a user as publisher for a given feed URL, use: .. code-block:: bash cd mygpo - python manage.py make-publisher [...] + envdir envs/local python manage.py make-publisher [...] Web-Server @@ -138,7 +145,7 @@ directory with .. code-block:: bash - python manage.py runserver + envdir envs/local python manage.py runserver If you want to run a production server, check out `Deploying Django `_. From 64b1ef4daa5363801da173ee36255379d1642b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 30 Dec 2017 21:28:48 +0100 Subject: [PATCH 047/106] Fix error handling in user check (fixes #81) --- mygpo/users/checks.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mygpo/users/checks.py b/mygpo/users/checks.py index 61d730723..2810d1994 100644 --- a/mygpo/users/checks.py +++ b/mygpo/users/checks.py @@ -1,6 +1,6 @@ from django.core.checks import register, Warning from django.db import connection -from django.db.utils import OperationalError +from django.db.utils import OperationalError, ProgrammingError SQL = """ @@ -37,4 +37,12 @@ def check_case_insensitive_users(app_configs=None, **kwargs): else: raise + except ProgrammingError as pe: + if 'relation "auth_user" does not exist' in str(pe): + # Ignore if the table does not yet exist, eg when initally + # running ``manage.py migrate`` + pass + else: + raise + return errors From 02185513947d8c807600bb01f1ea5ad0d7af5279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 30 Dec 2017 21:47:53 +0100 Subject: [PATCH 048/106] Avoid exceptions at slug assignment during podcast updates --- mygpo/core/slugs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mygpo/core/slugs.py b/mygpo/core/slugs.py index 230fb15ab..f4ec4826d 100644 --- a/mygpo/core/slugs.py +++ b/mygpo/core/slugs.py @@ -7,10 +7,6 @@ class SlugGenerator(object): """ Generates a unique slug for an object """ def __init__(self, obj): - if obj.slug: - raise ValueError('%(obj)s already has slug %(slug)s' % - dict(obj=obj, slug=obj.slug)) - self.obj = obj self.base_slug = self._get_base_slug(obj) @@ -26,6 +22,10 @@ def __iter__(self): The consumer can can consume until it get's an unused one """ + if obj.slug: + # The object already has a slug + raise StopIteration + if not self.base_slug: raise StopIteration From 56fff48d0fcbc696a8c8318ee3f454a07526ed17 Mon Sep 17 00:00:00 2001 From: gpbenton Date: Sat, 13 Jan 2018 19:41:07 +0000 Subject: [PATCH 049/106] obj.slug -> self.obj.slug --- mygpo/core/slugs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/core/slugs.py b/mygpo/core/slugs.py index f4ec4826d..eaaa6bd4b 100644 --- a/mygpo/core/slugs.py +++ b/mygpo/core/slugs.py @@ -22,7 +22,7 @@ def __iter__(self): The consumer can can consume until it get's an unused one """ - if obj.slug: + if self.obj.slug: # The object already has a slug raise StopIteration From 3974f528800a7cdbcbb9e4bbcd4f450b0181ea45 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Mon, 15 Jan 2018 12:36:45 +0100 Subject: [PATCH 050/106] Fix typo and unify translation of "e-mail" --- mygpo/locale/de/LC_MESSAGES/django.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mygpo/locale/de/LC_MESSAGES/django.po b/mygpo/locale/de/LC_MESSAGES/django.po index 06d415a0e..eae06d623 100644 --- a/mygpo/locale/de/LC_MESSAGES/django.po +++ b/mygpo/locale/de/LC_MESSAGES/django.po @@ -1595,7 +1595,7 @@ msgstr "Registrierung abgeschlossen" msgid "" "Please confirm your account using the email you should just have received." msgstr "" -"Du solltest soeben ein Mail bekommen haben. Darin findest du einen Link zum " +"Du solltest soeben eine E-Mail bekommen haben. Darin findest du einen Link zum " "Aktivieren deines Accounts" #: mygpo/users/templates/registration/registration_form.html:8 @@ -1618,7 +1618,7 @@ msgstr "Registrieren" #: mygpo/users/templates/registration/registration_form.html:87 #, fuzzy msgid "Activation Mail" -msgstr "Aktivierungs-Email gesendet" +msgstr "Aktivierungs-E-Mail gesendet" #: mygpo/users/templates/registration/registration_form.html:88 msgid "" @@ -1660,7 +1660,7 @@ msgstr "Aktivierungs-Email gesendet" #: mygpo/users/templates/registration/resent_activation.html:11 msgid "The activation email has been reset." -msgstr "Die Aktivierungs E-Mail wurde zurückgesetzt." +msgstr "Die Aktivierungs-E-Mail wurde zurückgesetzt." #: mygpo/users/views/device.py:80 mygpo/users/views/device.py:170 msgid "Synchronize with the following devices" @@ -1775,7 +1775,7 @@ msgstr "" #: mygpo/web/forms.py:20 mygpo/web/forms.py:184 msgid "E-Mail address" -msgstr "Deine Email-Adresse" +msgstr "Deine E-Mail-Adresse" #: mygpo/web/forms.py:27 msgid "Current password" @@ -3398,7 +3398,7 @@ msgstr "eine andere Seite" #~ msgstr "Wiederherstellungs-Email senden" #~ msgid "Didn't receive your activation mail?" -#~ msgstr "Aktivierungs-Mail nicht erhalten?" +#~ msgstr "Aktivierungs-E-Mail nicht erhalten?" #~ msgid "Not yet a member?" #~ msgstr "Noch kein Mitglied?" From 25a23e66bf56be45dc919803649a84a1965bbc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Tue, 16 Jan 2018 16:49:26 +0000 Subject: [PATCH 051/106] Fix broken Gravatar profile image (#86) --- mygpo/share/templatetags/gravatar.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mygpo/share/templatetags/gravatar.py b/mygpo/share/templatetags/gravatar.py index 43d9a875b..9e01e64b7 100644 --- a/mygpo/share/templatetags/gravatar.py +++ b/mygpo/share/templatetags/gravatar.py @@ -1,5 +1,6 @@ import hashlib +from django.utils.safestring import mark_safe from django import template from mygpo.constants import PODCAST_LOGO_BIG_SIZE @@ -7,10 +8,11 @@ register = template.Library() -GRAVATAR_IMG = 'https://secure.gravatar.com/avatar/{hash_str}?s={size}&d=mm' +GRAVATAR_IMG = 'https://secure.gravatar.com/avatar/{hash_str}?s={size}' @register.simple_tag +@mark_safe def gravatar_img(user): return '{username}'.format( url=gravatar_url(user), From 3aa783dd71a4d068edfe37e6f3507c8897546ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 27 Jan 2018 11:45:22 +0100 Subject: [PATCH 052/106] Bump django-celery-beat to current master (> 1.1.0) --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 320d409f5..da49cf9ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,4 +15,6 @@ python-dateutil==2.6.1 redis==2.10.6 django-celery-results==1.0.1 django-celery-beat==1.1.0 +# django-celery-beat > 1.1.0 +-e git://github.com/celery/django-celery-beat.git@feaf34e2c30e28273b03d754d50e9a1d9f1191c6#egg=django-celery-beat requests==2.18.4 From 2efd1edd1f07cf39bb35e57f8eac360cf4073432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 27 Jan 2018 11:51:44 +0100 Subject: [PATCH 053/106] Fix duplicate requirements --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 966ac8367..dd499b51b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,6 @@ psycopg2cffi==2.7.7 python-dateutil==2.6.1 redis==2.10.6 django-celery-results==1.0.1 -django-celery-beat==1.1.0 # django-celery-beat > 1.1.0 --e git://github.com/celery/django-celery-beat.git@feaf34e2c30e28273b03d754d50e9a1d9f1191c6#egg=django-celery-beat +git+https://github.com/celery/django-celery-beat.git@feaf34e2c30e28273b03d754d50e9a1d9f1191c6#egg=django-celery-beat requests==2.18.4 From eb7fb7834c6a062034827be4b75e544daffaba9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Tue, 30 Jan 2018 21:30:21 +0100 Subject: [PATCH 054/106] Move templates to correct directories --- mygpo/{web => history}/templates/episode-history.html | 0 mygpo/{web => history}/templates/podcast-history.html | 0 mygpo/{web => podcasts}/templates/components/episode-box.html | 0 mygpo/{web => podcasts}/templates/episode.html | 0 mygpo/{web => podcasts}/templates/episodes.html | 0 mygpo/{web => podcasts}/templates/podcast-base.html | 0 mygpo/{web => podcasts}/templates/podcast.html | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename mygpo/{web => history}/templates/episode-history.html (100%) rename mygpo/{web => history}/templates/podcast-history.html (100%) rename mygpo/{web => podcasts}/templates/components/episode-box.html (100%) rename mygpo/{web => podcasts}/templates/episode.html (100%) rename mygpo/{web => podcasts}/templates/episodes.html (100%) rename mygpo/{web => podcasts}/templates/podcast-base.html (100%) rename mygpo/{web => podcasts}/templates/podcast.html (100%) diff --git a/mygpo/web/templates/episode-history.html b/mygpo/history/templates/episode-history.html similarity index 100% rename from mygpo/web/templates/episode-history.html rename to mygpo/history/templates/episode-history.html diff --git a/mygpo/web/templates/podcast-history.html b/mygpo/history/templates/podcast-history.html similarity index 100% rename from mygpo/web/templates/podcast-history.html rename to mygpo/history/templates/podcast-history.html diff --git a/mygpo/web/templates/components/episode-box.html b/mygpo/podcasts/templates/components/episode-box.html similarity index 100% rename from mygpo/web/templates/components/episode-box.html rename to mygpo/podcasts/templates/components/episode-box.html diff --git a/mygpo/web/templates/episode.html b/mygpo/podcasts/templates/episode.html similarity index 100% rename from mygpo/web/templates/episode.html rename to mygpo/podcasts/templates/episode.html diff --git a/mygpo/web/templates/episodes.html b/mygpo/podcasts/templates/episodes.html similarity index 100% rename from mygpo/web/templates/episodes.html rename to mygpo/podcasts/templates/episodes.html diff --git a/mygpo/web/templates/podcast-base.html b/mygpo/podcasts/templates/podcast-base.html similarity index 100% rename from mygpo/web/templates/podcast-base.html rename to mygpo/podcasts/templates/podcast-base.html diff --git a/mygpo/web/templates/podcast.html b/mygpo/podcasts/templates/podcast.html similarity index 100% rename from mygpo/web/templates/podcast.html rename to mygpo/podcasts/templates/podcast.html From 02288dbcc8690a67996b0b77cae35dfd00f9db6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Tue, 30 Jan 2018 21:36:41 +0100 Subject: [PATCH 055/106] Temporarily allow failures on Python 3.7 see https://github.com/chtd/psycopg2cffi/issues/95 --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4f04c92b2..b0a56ea7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,3 +28,11 @@ env: - DATABASE_URL="postgres://postgres@localhost/mygpo_test" sudo: false + +# temporarily allow failures on 3.7 +# see https://github.com/chtd/psycopg2cffi/issues/95 +matrix: + allow_failures: + - python: "3.7-dev" + - python: "nightly" + From 00106924db9531294680fe61d55bf7b73feefc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Tue, 30 Jan 2018 21:48:21 +0100 Subject: [PATCH 056/106] Bump Django to 2.0.1 https://docs.djangoproject.com/en/dev/releases/2.0.1/ --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dd499b51b..2550ca994 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0 +Django==2.0.1 Babel==2.5.0 Pillow==4.2.1 celery[redis]==4.1.0 From 38a5954261326d423266d7795aff3bbb13aa9f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Thu, 15 Feb 2018 18:31:17 +0100 Subject: [PATCH 057/106] Update requirements --- requirements-dev.txt | 4 ++-- requirements-test.txt | 2 +- requirements.txt | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 5ce4c9866..e02c15046 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ -transifex-client==0.12.4 +transifex-client==0.13.1 sphinx pep8 flake8 -django-debug-toolbar==1.8 +django-debug-toolbar==1.9.1 django-extensions jupyter diff --git a/requirements-test.txt b/requirements-test.txt index 5936206b8..b9c0d4dfa 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,4 +1,4 @@ -coverage==4.4.1 +coverage==4.5.1 django-coverage-plugin==1.5.0 pytest-django pytest-cov diff --git a/requirements.txt b/requirements.txt index 2550ca994..06e03194a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +1,14 @@ -Django==2.0.1 -Babel==2.5.0 -Pillow==4.2.1 +Django==2.0.2 +Babel==2.5.3 +Pillow==5.0.0 celery[redis]==4.1.0 dj-database-url==0.4.2 -django-redis-sessions==0.6 +django-redis-sessions==0.6.1 python3-memcached==1.51 feedparser==5.2.1 gunicorn==19.7.1 -html2text==2016.9.19 -markdown2==2.3.4 +html2text==2018.1.9 +markdown2==2.3.5 oauth2client==4.1.2 psycopg2cffi==2.7.7 python-dateutil==2.6.1 From f3f97a1ad33c92ef466b26a88c70b7aa01ab1c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 18 Feb 2018 15:36:42 +0000 Subject: [PATCH 058/106] Update deprecated attribute name of user feed https://docs.djangoproject.com/en/dev/releases/1.9/#deprecated-features-1-9 The ``django.utils.feedgenerator.Atom1Feed.mime_type`` and ``django.utils.feedgenerator.RssFeed.mime_type`` attributes are deprecated in favor of ``content_type``. --- mygpo/subscriptions/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/subscriptions/views.py b/mygpo/subscriptions/views.py index 2fe87c610..dc3939c03 100644 --- a/mygpo/subscriptions/views.py +++ b/mygpo/subscriptions/views.py @@ -85,7 +85,7 @@ def subscriptions_feed(request, username): f = SubscriptionsFeed(username) obj = f.get_object(request, username) feedgen = f.get_feed(obj, request) - response = HttpResponse(content_type=feedgen.mime_type) + response = HttpResponse(content_type=feedgen.content_type) feedgen.write(response, 'utf-8') return response From 8a8f83900132e10d13e1202c76e5ef4c110e8613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Mon, 19 Feb 2018 20:06:10 +0000 Subject: [PATCH 059/106] Add optional `version` parameter to device(s) API --- mygpo/api/advanced/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mygpo/api/advanced/__init__.py b/mygpo/api/advanced/__init__.py index 2687db147..27f1dc428 100644 --- a/mygpo/api/advanced/__init__.py +++ b/mygpo/api/advanced/__init__.py @@ -249,7 +249,7 @@ def parse_episode_action(action, user, update_urls, now, ua_string): # instead of "POST" requests for uploading device settings @allowed_methods(['POST', 'PUT']) @cors_origin() -def device(request, username, device_uid): +def device(request, username, device_uid, version=None): d = get_device(request.user, device_uid, request.META.get('HTTP_USER_AGENT', '')) @@ -295,7 +295,7 @@ def valid_episodeaction(type): @never_cache @allowed_methods(['GET']) @cors_origin() -def devices(request, username): +def devices(request, username, version=None): user = request.user clients = user.client_set.filter(deleted=False) client_data = [get_client_data(user, client) for client in clients] From bf2996c0f5b1d736eb9d3a5c1c031db2190835a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Mon, 19 Feb 2018 21:06:47 +0100 Subject: [PATCH 060/106] Return ID das UUID, instead of its string repr --- mygpo/core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/core/models.py b/mygpo/core/models.py index 2b8c358ba..8d0b730cd 100644 --- a/mygpo/core/models.py +++ b/mygpo/core/models.py @@ -14,7 +14,7 @@ class Meta: def get_id(self): """ String representation of the ID """ - return self.id.hex + return self.id class TwitterModel(models.Model): From a9393534d6ebf00598c5a01846ee158a68dffc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Mon, 19 Feb 2018 21:07:21 +0100 Subject: [PATCH 061/106] Mark filters safe through `is_safe` parameter --- mygpo/publisher/templatetags/pcharts.py | 4 +--- mygpo/web/templatetags/charts.py | 4 +--- mygpo/web/templatetags/devices.py | 8 +++----- mygpo/web/templatetags/episodes.py | 5 ++--- mygpo/web/templatetags/facebook.py | 4 ++-- mygpo/web/templatetags/flickr.py | 5 ++--- mygpo/web/templatetags/googleanalytics.py | 5 ++--- mygpo/web/templatetags/menu.py | 9 ++++----- mygpo/web/templatetags/mygpoutil.py | 4 +--- mygpo/web/templatetags/podcasts.py | 3 +-- mygpo/web/templatetags/time.py | 4 +--- mygpo/web/templatetags/utils.py | 19 ++++++++----------- 12 files changed, 28 insertions(+), 46 deletions(-) diff --git a/mygpo/publisher/templatetags/pcharts.py b/mygpo/publisher/templatetags/pcharts.py index 8d1767722..068c184fa 100644 --- a/mygpo/publisher/templatetags/pcharts.py +++ b/mygpo/publisher/templatetags/pcharts.py @@ -1,10 +1,8 @@ from django import template -from django.utils.safestring import mark_safe register = template.Library() -@register.filter -@mark_safe +@register.filter(is_safe=True) def bar_chart(parts): maxv = max([ int(x['y']) for x in parts ]) diff --git a/mygpo/web/templatetags/charts.py b/mygpo/web/templatetags/charts.py index b4b693827..fd5303cb7 100644 --- a/mygpo/web/templatetags/charts.py +++ b/mygpo/web/templatetags/charts.py @@ -1,5 +1,4 @@ from django import template -from django.utils.safestring import mark_safe from django.utils.html import format_html from django.contrib.staticfiles.storage import staticfiles_storage @@ -36,8 +35,7 @@ def vertical_bar(value, max_value, display=None): ratio, left, right) -@register.filter -@mark_safe +@register.filter(is_safe=True) def timeline(data): s = '\n' s += '""" % property_id - return mark_safe(s) + return s diff --git a/mygpo/web/templatetags/menu.py b/mygpo/web/templatetags/menu.py index 72da8aea2..6d2cf34d6 100644 --- a/mygpo/web/templatetags/menu.py +++ b/mygpo/web/templatetags/menu.py @@ -1,5 +1,4 @@ from django import template -from django.utils.safestring import mark_safe from django.utils.translation import ugettext from django.utils.translation import ugettext_lazy as _ @@ -69,7 +68,7 @@ )), ) -@register.filter +@register.filter(is_safe=True) def main_menu(selected): found_section = False links = [] @@ -87,7 +86,7 @@ def main_menu(selected): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return mark_safe('\n'.join(items)) + return '\n'.join(items) def get_section_items(selected): for label, items in MENU_STRUCTURE: @@ -99,7 +98,7 @@ def get_section_items(selected): (selected, selected), ] -@register.filter +@register.filter(is_safe=True) def section_menu(selected, title=None): items = [] @@ -125,4 +124,4 @@ def section_menu(selected, title=None): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return mark_safe('\n'.join(items)) + return '\n'.join(items) diff --git a/mygpo/web/templatetags/mygpoutil.py b/mygpo/web/templatetags/mygpoutil.py index 06d5eee4e..0c3e2be06 100644 --- a/mygpo/web/templatetags/mygpoutil.py +++ b/mygpo/web/templatetags/mygpoutil.py @@ -2,13 +2,11 @@ from html.entities import entitydefs from django import template -from django.utils.safestring import mark_safe register = template.Library() -@register.filter -@mark_safe +@register.filter(is_safe=True) def remove_html_tags(html): # If we would want more speed, we could make these global re_strip_tags = re.compile('<[^>]*>') diff --git a/mygpo/web/templatetags/podcasts.py b/mygpo/web/templatetags/podcasts.py index 96ae6a1fd..d33735954 100644 --- a/mygpo/web/templatetags/podcasts.py +++ b/mygpo/web/templatetags/podcasts.py @@ -37,8 +37,7 @@ def podcast_logo_medium(podcast): return create_podcast_logo(podcast, PODCAST_LOGO_MEDIUM_SIZE) -@register.filter -@mark_safe +@register.filter(is_safe=True) def podcast_status_icon(action): if action.action == 'subscribe': return '' % (staticfiles_storage.url('subscribe.png'),) diff --git a/mygpo/web/templatetags/time.py b/mygpo/web/templatetags/time.py index 3a3d72c34..1de61323c 100644 --- a/mygpo/web/templatetags/time.py +++ b/mygpo/web/templatetags/time.py @@ -1,6 +1,5 @@ from datetime import time -from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ from django import template @@ -23,8 +22,7 @@ def sec_to_time(sec): return time(hour, minute, sec) -@register.filter -@mark_safe +@register.filter(is_safe=True) def format_duration(sec): """ Converts seconds into a duration string diff --git a/mygpo/web/templatetags/utils.py b/mygpo/web/templatetags/utils.py index 2d2c664b2..562f53750 100644 --- a/mygpo/web/templatetags/utils.py +++ b/mygpo/web/templatetags/utils.py @@ -1,7 +1,6 @@ import urllib.parse from django import template -from django.utils.safestring import mark_safe from mygpo.web.utils import get_page_list, license_info, hours_to_str from mygpo.utils import edit_link @@ -9,8 +8,7 @@ register = template.Library() -@register.filter -@mark_safe +@register.filter(is_safe=True) def lookup(dic, key): return dic.get(key, '') @@ -45,8 +43,7 @@ def append(l, item): def remove(l, item): return [x for x in l if x != item] -@register.filter -@mark_safe +@register.filter(is_safe=True) def format_time(time): from mygpo.utils import format_time as _format_time return _format_time(time) @@ -57,17 +54,17 @@ def is_tuple(obj): return isinstance(obj, tuple) -@register.filter +@register.filter(is_safe=True) def markdown(txt): import markdown2 - return mark_safe(markdown2.markdown(txt, extras={'nofollow': True})) + return markdown2.markdown(txt, extras={'nofollow': True}) -@register.filter +@register.filter(is_safe=True) def nbsp(s): """ collapses multiple whitespaces and replaces them with   """ import re - return mark_safe(re.sub("\s+", " ", s)) + return re.sub("\s+", " ", s) @register.filter @@ -82,12 +79,12 @@ def license_name(license_url): return info.url -@register.filter +@register.filter(is_safe=True) def urlquote(s): """ makes urllib.quote_plus available as a template filter """ if isinstance(s, str): s = s.encode('utf-8') - return mark_safe(urllib.parse.quote_plus(s)) + return urllib.parse.quote_plus(s) hours_to_str = register.filter(hours_to_str) From 39775ac94db2dddffc21217a580f28ba9ca2675f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Mon, 19 Feb 2018 21:11:51 +0100 Subject: [PATCH 062/106] Fix view name View was accidentally renamed when switching to new URL routing syntax --- mygpo/podcasts/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/podcasts/urls.py b/mygpo/podcasts/urls.py index a19091f9d..b6f155bf4 100644 --- a/mygpo/podcasts/urls.py +++ b/mygpo/podcasts/urls.py @@ -129,7 +129,7 @@ path('subscribe', podcast.subscribe_url, - name='subscribe-by-path'), + name='subscribe-by-url'), # Podcast Views with UUIDs path('podcast/', From e527ba3ec6970eb94d808ff709f43c90bfd116e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Tue, 20 Feb 2018 10:20:49 +0000 Subject: [PATCH 063/106] Revert "Mark filters safe through `is_safe` parameter" This reverts commit a9393534d6ebf00598c5a01846ee158a68dffc79. --- mygpo/publisher/templatetags/pcharts.py | 4 +++- mygpo/web/templatetags/charts.py | 4 +++- mygpo/web/templatetags/devices.py | 8 +++++--- mygpo/web/templatetags/episodes.py | 5 +++-- mygpo/web/templatetags/facebook.py | 4 ++-- mygpo/web/templatetags/flickr.py | 5 +++-- mygpo/web/templatetags/googleanalytics.py | 5 +++-- mygpo/web/templatetags/menu.py | 9 +++++---- mygpo/web/templatetags/mygpoutil.py | 4 +++- mygpo/web/templatetags/podcasts.py | 3 ++- mygpo/web/templatetags/time.py | 4 +++- mygpo/web/templatetags/utils.py | 19 +++++++++++-------- 12 files changed, 46 insertions(+), 28 deletions(-) diff --git a/mygpo/publisher/templatetags/pcharts.py b/mygpo/publisher/templatetags/pcharts.py index 068c184fa..8d1767722 100644 --- a/mygpo/publisher/templatetags/pcharts.py +++ b/mygpo/publisher/templatetags/pcharts.py @@ -1,8 +1,10 @@ from django import template +from django.utils.safestring import mark_safe register = template.Library() -@register.filter(is_safe=True) +@register.filter +@mark_safe def bar_chart(parts): maxv = max([ int(x['y']) for x in parts ]) diff --git a/mygpo/web/templatetags/charts.py b/mygpo/web/templatetags/charts.py index fd5303cb7..b4b693827 100644 --- a/mygpo/web/templatetags/charts.py +++ b/mygpo/web/templatetags/charts.py @@ -1,4 +1,5 @@ from django import template +from django.utils.safestring import mark_safe from django.utils.html import format_html from django.contrib.staticfiles.storage import staticfiles_storage @@ -35,7 +36,8 @@ def vertical_bar(value, max_value, display=None): ratio, left, right) -@register.filter(is_safe=True) +@register.filter +@mark_safe def timeline(data): s = '\n' s += '""" % property_id - return s + return mark_safe(s) diff --git a/mygpo/web/templatetags/menu.py b/mygpo/web/templatetags/menu.py index 6d2cf34d6..72da8aea2 100644 --- a/mygpo/web/templatetags/menu.py +++ b/mygpo/web/templatetags/menu.py @@ -1,4 +1,5 @@ from django import template +from django.utils.safestring import mark_safe from django.utils.translation import ugettext from django.utils.translation import ugettext_lazy as _ @@ -68,7 +69,7 @@ )), ) -@register.filter(is_safe=True) +@register.filter def main_menu(selected): found_section = False links = [] @@ -86,7 +87,7 @@ def main_menu(selected): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return '\n'.join(items) + return mark_safe('\n'.join(items)) def get_section_items(selected): for label, items in MENU_STRUCTURE: @@ -98,7 +99,7 @@ def get_section_items(selected): (selected, selected), ] -@register.filter(is_safe=True) +@register.filter def section_menu(selected, title=None): items = [] @@ -124,4 +125,4 @@ def section_menu(selected, title=None): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return '\n'.join(items) + return mark_safe('\n'.join(items)) diff --git a/mygpo/web/templatetags/mygpoutil.py b/mygpo/web/templatetags/mygpoutil.py index 0c3e2be06..06d5eee4e 100644 --- a/mygpo/web/templatetags/mygpoutil.py +++ b/mygpo/web/templatetags/mygpoutil.py @@ -2,11 +2,13 @@ from html.entities import entitydefs from django import template +from django.utils.safestring import mark_safe register = template.Library() -@register.filter(is_safe=True) +@register.filter +@mark_safe def remove_html_tags(html): # If we would want more speed, we could make these global re_strip_tags = re.compile('<[^>]*>') diff --git a/mygpo/web/templatetags/podcasts.py b/mygpo/web/templatetags/podcasts.py index d33735954..96ae6a1fd 100644 --- a/mygpo/web/templatetags/podcasts.py +++ b/mygpo/web/templatetags/podcasts.py @@ -37,7 +37,8 @@ def podcast_logo_medium(podcast): return create_podcast_logo(podcast, PODCAST_LOGO_MEDIUM_SIZE) -@register.filter(is_safe=True) +@register.filter +@mark_safe def podcast_status_icon(action): if action.action == 'subscribe': return '' % (staticfiles_storage.url('subscribe.png'),) diff --git a/mygpo/web/templatetags/time.py b/mygpo/web/templatetags/time.py index 1de61323c..3a3d72c34 100644 --- a/mygpo/web/templatetags/time.py +++ b/mygpo/web/templatetags/time.py @@ -1,5 +1,6 @@ from datetime import time +from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ from django import template @@ -22,7 +23,8 @@ def sec_to_time(sec): return time(hour, minute, sec) -@register.filter(is_safe=True) +@register.filter +@mark_safe def format_duration(sec): """ Converts seconds into a duration string diff --git a/mygpo/web/templatetags/utils.py b/mygpo/web/templatetags/utils.py index 562f53750..2d2c664b2 100644 --- a/mygpo/web/templatetags/utils.py +++ b/mygpo/web/templatetags/utils.py @@ -1,6 +1,7 @@ import urllib.parse from django import template +from django.utils.safestring import mark_safe from mygpo.web.utils import get_page_list, license_info, hours_to_str from mygpo.utils import edit_link @@ -8,7 +9,8 @@ register = template.Library() -@register.filter(is_safe=True) +@register.filter +@mark_safe def lookup(dic, key): return dic.get(key, '') @@ -43,7 +45,8 @@ def append(l, item): def remove(l, item): return [x for x in l if x != item] -@register.filter(is_safe=True) +@register.filter +@mark_safe def format_time(time): from mygpo.utils import format_time as _format_time return _format_time(time) @@ -54,17 +57,17 @@ def is_tuple(obj): return isinstance(obj, tuple) -@register.filter(is_safe=True) +@register.filter def markdown(txt): import markdown2 - return markdown2.markdown(txt, extras={'nofollow': True}) + return mark_safe(markdown2.markdown(txt, extras={'nofollow': True})) -@register.filter(is_safe=True) +@register.filter def nbsp(s): """ collapses multiple whitespaces and replaces them with   """ import re - return re.sub("\s+", " ", s) + return mark_safe(re.sub("\s+", " ", s)) @register.filter @@ -79,12 +82,12 @@ def license_name(license_url): return info.url -@register.filter(is_safe=True) +@register.filter def urlquote(s): """ makes urllib.quote_plus available as a template filter """ if isinstance(s, str): s = s.encode('utf-8') - return urllib.parse.quote_plus(s) + return mark_safe(urllib.parse.quote_plus(s)) hours_to_str = register.filter(hours_to_str) From 16fed47c57709f39fa0a9037a3cd0d7ae1d04c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 18 Mar 2018 19:12:01 +0100 Subject: [PATCH 064/106] Fix usage of mark_safe() --- mygpo/web/templatetags/charts.py | 5 +++-- mygpo/web/templatetags/devices.py | 9 +++++---- mygpo/web/templatetags/episodes.py | 5 +++-- mygpo/web/templatetags/facebook.py | 4 ++-- mygpo/web/templatetags/flickr.py | 5 +++-- mygpo/web/templatetags/googleanalytics.py | 5 +++-- mygpo/web/templatetags/menu.py | 9 +++++---- mygpo/web/templatetags/mygpoutil.py | 5 +++-- mygpo/web/templatetags/podcasts.py | 12 +++++++----- mygpo/web/templatetags/utils.py | 15 ++++++++------- 10 files changed, 42 insertions(+), 32 deletions(-) diff --git a/mygpo/web/templatetags/charts.py b/mygpo/web/templatetags/charts.py index fd5303cb7..630385cab 100644 --- a/mygpo/web/templatetags/charts.py +++ b/mygpo/web/templatetags/charts.py @@ -1,5 +1,6 @@ from django import template from django.utils.html import format_html +from django.utils.safestring import mark_safe from django.contrib.staticfiles.storage import staticfiles_storage @@ -35,7 +36,7 @@ def vertical_bar(value, max_value, display=None): ratio, left, right) -@register.filter(is_safe=True) +@register.filter() def timeline(data): s = '\n' s += '\n' - return s + return mark_safe(s) diff --git a/mygpo/web/templatetags/devices.py b/mygpo/web/templatetags/devices.py index bd5842741..8be60ada5 100644 --- a/mygpo/web/templatetags/devices.py +++ b/mygpo/web/templatetags/devices.py @@ -2,6 +2,7 @@ from django import template from django.utils.translation import ugettext +from django.utils.safestring import mark_safe from django.urls import reverse from django.utils.html import strip_tags from django.contrib.staticfiles.storage import staticfiles_storage @@ -29,7 +30,7 @@ def device_type(device): return DEVICE_TYPES_DICT.get(device.type, _('Unknown')) -@register.filter(is_safe=True) +@register.filter() def device_icon(device): ua_str = (device.user_agent or '').lower() @@ -56,7 +57,7 @@ def device_icon(device): html = '%(caption)s' \ % dict(icon=staticfiles_storage.url(os.path.join('clients', icon)), caption=caption) - return html + return mark_safe(html) return '' @@ -70,10 +71,10 @@ def target_uid(client): return client.uid -@register.filter(is_safe=True) +@register.filter() def device_list(devices): links = map(device_link, devices) - return ''.join(links) + return mark_safe(''.join(links)) def device_link(device): return '{icon}'.format( diff --git a/mygpo/web/templatetags/episodes.py b/mygpo/web/templatetags/episodes.py index b75c19c7b..2145e7b04 100644 --- a/mygpo/web/templatetags/episodes.py +++ b/mygpo/web/templatetags/episodes.py @@ -1,4 +1,5 @@ from django import template +from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ from django.utils.html import strip_tags, format_html from django.contrib.staticfiles.storage import staticfiles_storage @@ -35,7 +36,7 @@ def episode_status_text(episode): return _('Unknown status') -@register.filter(is_safe=True) +@register.filter() def episode_status_icon(action): if not action or not action.action: s = 'nothing' % \ @@ -69,7 +70,7 @@ def episode_status_icon(action): else: return action.action # this is not marked safe by intention - return s + return mark_safe(s) @register.filter diff --git a/mygpo/web/templatetags/facebook.py b/mygpo/web/templatetags/facebook.py index 66916e04f..4e1d963e0 100644 --- a/mygpo/web/templatetags/facebook.py +++ b/mygpo/web/templatetags/facebook.py @@ -58,7 +58,7 @@ def opengraph_episode(episode, podcast): ) return s -@register.filter(is_safe=True) +@register.filter() def opengraph_podcast(podcast): s = OPENGRAPH_STR % dict( title = podcast.title, @@ -68,4 +68,4 @@ def opengraph_podcast(podcast): site_name = 'gpodder.net', admins = '0' ) - return s + return mark_safe(s) diff --git a/mygpo/web/templatetags/flickr.py b/mygpo/web/templatetags/flickr.py index 45405f646..c58d72469 100644 --- a/mygpo/web/templatetags/flickr.py +++ b/mygpo/web/templatetags/flickr.py @@ -1,4 +1,5 @@ from django import template +from django.utils.safestring import mark_safe from mygpo.data import flickr @@ -9,8 +10,8 @@ def is_flickr_photo(url): return flickr.is_flickr_image(url) -@register.filter(is_safe=True) +@register.filter() def embed_flickr_photo(episode): img = flickr.get_display_photo(episode.url) s = '%s' % (episode.link, episode.title, img, episode.title) - return s + return mark_safe(s) diff --git a/mygpo/web/templatetags/googleanalytics.py b/mygpo/web/templatetags/googleanalytics.py index 14db9377a..d9ab4eaae 100644 --- a/mygpo/web/templatetags/googleanalytics.py +++ b/mygpo/web/templatetags/googleanalytics.py @@ -1,8 +1,9 @@ from django import template +from django.utils.safestring import mark_safe register = template.Library() -@register.filter(is_safe=True) +@register.filter() def google_analytics_async(property_id): s = """ """ % property_id - return s + return mark_safe(s) diff --git a/mygpo/web/templatetags/menu.py b/mygpo/web/templatetags/menu.py index 6d2cf34d6..7effd73d8 100644 --- a/mygpo/web/templatetags/menu.py +++ b/mygpo/web/templatetags/menu.py @@ -1,4 +1,5 @@ from django import template +from django.utils.safestring import mark_safe from django.utils.translation import ugettext from django.utils.translation import ugettext_lazy as _ @@ -68,7 +69,7 @@ )), ) -@register.filter(is_safe=True) +@register.filter() def main_menu(selected): found_section = False links = [] @@ -86,7 +87,7 @@ def main_menu(selected): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return '\n'.join(items) + return mark_safe('\n'.join(items)) def get_section_items(selected): for label, items in MENU_STRUCTURE: @@ -98,7 +99,7 @@ def get_section_items(selected): (selected, selected), ] -@register.filter(is_safe=True) +@register.filter() def section_menu(selected, title=None): items = [] @@ -124,4 +125,4 @@ def section_menu(selected, title=None): else: items.append('
  • %s
  • ' % (uri, ugettext(caption))) - return '\n'.join(items) + return mark_safe('\n'.join(items)) diff --git a/mygpo/web/templatetags/mygpoutil.py b/mygpo/web/templatetags/mygpoutil.py index 0c3e2be06..5b2c06493 100644 --- a/mygpo/web/templatetags/mygpoutil.py +++ b/mygpo/web/templatetags/mygpoutil.py @@ -1,12 +1,13 @@ import re from html.entities import entitydefs +from django.utils.safestring import mark_safe from django import template register = template.Library() -@register.filter(is_safe=True) +@register.filter() def remove_html_tags(html): # If we would want more speed, we could make these global re_strip_tags = re.compile('<[^>]*>') @@ -34,4 +35,4 @@ def remove_html_tags(html): # Convert more than two newlines to two newlines result = re.sub('([\r\n]{2})([\r\n])+', '\\1', result) - return result.strip() + return mark_safe(result.strip()) diff --git a/mygpo/web/templatetags/podcasts.py b/mygpo/web/templatetags/podcasts.py index d33735954..b6583f9e9 100644 --- a/mygpo/web/templatetags/podcasts.py +++ b/mygpo/web/templatetags/podcasts.py @@ -37,16 +37,18 @@ def podcast_logo_medium(podcast): return create_podcast_logo(podcast, PODCAST_LOGO_MEDIUM_SIZE) -@register.filter(is_safe=True) +@register.filter() def podcast_status_icon(action): if action.action == 'subscribe': - return '' % (staticfiles_storage.url('subscribe.png'),) + s = '' % (staticfiles_storage.url('subscribe.png'),) elif action.action == 'unsubscribe': - return '' % (staticfiles_storage.url('unsubscribe.png'),) + s = '' % (staticfiles_storage.url('unsubscribe.png'),) elif action.action == 'flattr': - return '' + s = '' + else: + s = '' - return '' + return mark_safe(s) @register.filter diff --git a/mygpo/web/templatetags/utils.py b/mygpo/web/templatetags/utils.py index 562f53750..7d1a8ade4 100644 --- a/mygpo/web/templatetags/utils.py +++ b/mygpo/web/templatetags/utils.py @@ -1,5 +1,6 @@ import urllib.parse +from django.utils.safestring import mark_safe from django import template from mygpo.web.utils import get_page_list, license_info, hours_to_str @@ -8,7 +9,7 @@ register = template.Library() -@register.filter(is_safe=True) +@register.filter() def lookup(dic, key): return dic.get(key, '') @@ -54,17 +55,17 @@ def is_tuple(obj): return isinstance(obj, tuple) -@register.filter(is_safe=True) +@register.filter() def markdown(txt): import markdown2 - return markdown2.markdown(txt, extras={'nofollow': True}) + return mark_safe(markdown2.markdown(txt, extras={'nofollow': True})) -@register.filter(is_safe=True) +@register.filter() def nbsp(s): """ collapses multiple whitespaces and replaces them with   """ import re - return re.sub("\s+", " ", s) + return mark_safe(re.sub("\s+", " ", s)) @register.filter @@ -79,12 +80,12 @@ def license_name(license_url): return info.url -@register.filter(is_safe=True) +@register.filter() def urlquote(s): """ makes urllib.quote_plus available as a template filter """ if isinstance(s, str): s = s.encode('utf-8') - return urllib.parse.quote_plus(s) + return mark_safe(urllib.parse.quote_plus(s)) hours_to_str = register.filter(hours_to_str) From 1123291bd421a2546ad26ce0f130c2357971b5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 18 Mar 2018 19:12:24 +0100 Subject: [PATCH 065/106] Fix adding/removing some tags (fixes #69) --- mygpo/podcasts/views/podcast.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/mygpo/podcasts/views/podcast.py b/mygpo/podcasts/views/podcast.py index 14a74854e..c047e2130 100644 --- a/mygpo/podcasts/views/podcast.py +++ b/mygpo/podcasts/views/podcast.py @@ -24,7 +24,7 @@ get_subscribe_targets ) from mygpo.history.models import HistoryEntry -from mygpo.utils import normalize_feed_url +from mygpo.utils import normalize_feed_url, to_maxlength from mygpo.users.settings import PUBLIC_SUB_PODCAST from mygpo.publisher.utils import check_publisher_permission from mygpo.usersettings.models import UserSettings @@ -186,10 +186,16 @@ def add_tag(request, podcast): tags = tag_str.split(',') tags = map(str.strip, tags) + tags = map(str.lower, tags) + tags = list(filter(None, tags)) ContentType.objects.get_for_model(podcast) for tag in tags: + + # trim to maximum length + tag = to_maxlength(Tag, 'tag', tag) + Tag.objects.get_or_create( tag=tag, source=Tag.USER, @@ -208,8 +214,8 @@ def add_tag(request, podcast): @login_required def remove_tag(request, podcast): - tag_str = request.GET.get('tag', '') - if not tag_str: + tag_str = request.GET.get('tag', None) + if tag_str is None: return HttpResponseBadRequest() user = request.user @@ -219,13 +225,14 @@ def remove_tag(request, podcast): ContentType.objects.get_for_model(podcast) - Tag.objects.filter( - tag__in=tags, - source=Tag.USER, - user=user, - content_type=ContentType.objects.get_for_model(podcast), - object_id=podcast.id, - ).delete() + for tag in tags: + Tag.objects.filter( + tag__iexact=tag, + source=Tag.USER, + user=user, + content_type=ContentType.objects.get_for_model(podcast), + object_id=podcast.id, + ).delete() if request.GET.get('next', '') == 'mytags': return HttpResponseRedirect('/tags/') From 84d135396b73264c02bd1b5abfea1ce9312db91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sun, 18 Mar 2018 18:19:39 +0000 Subject: [PATCH 066/106] Limit podcast logo size --- static/screen.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static/screen.css b/static/screen.css index acb47ed4b..322ae97b3 100644 --- a/static/screen.css +++ b/static/screen.css @@ -218,6 +218,11 @@ div#podcastlogo padding-bottom: 10px; } +#podcastlogo img { + max-height: 128px; + max-width: 128px; +} + .short { From c8c134d69199d6bfe40adbde8508332751a22165 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 24 Mar 2018 11:59:20 +0000 Subject: [PATCH 067/106] Bump dj-database-url from 0.4.2 to 0.5.0 Bumps [dj-database-url](https://github.com/kennethreitz/dj-database-url) from 0.4.2 to 0.5.0. - [Release notes](https://github.com/kennethreitz/dj-database-url/releases) - [Commits](https://github.com/kennethreitz/dj-database-url/compare/v0.4.2...v0.5.0) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 06e03194a..8da47b9be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ Django==2.0.2 Babel==2.5.3 Pillow==5.0.0 celery[redis]==4.1.0 -dj-database-url==0.4.2 +dj-database-url==0.5.0 django-redis-sessions==0.6.1 python3-memcached==1.51 feedparser==5.2.1 From 301bcd728bd4a4a525931da6836de5ad9482363e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 24 Mar 2018 11:59:22 +0000 Subject: [PATCH 068/106] Bump python-dateutil from 2.6.1 to 2.7.0 Bumps [python-dateutil](https://dateutil.readthedocs.io) from 2.6.1 to 2.7.0. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 06e03194a..494240d4e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 psycopg2cffi==2.7.7 -python-dateutil==2.6.1 +python-dateutil==2.7.0 redis==2.10.6 django-celery-results==1.0.1 # django-celery-beat > 1.1.0 From b121d81d5a43cd56a12a64ebd43c49e393b0881a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 24 Mar 2018 12:20:12 +0000 Subject: [PATCH 069/106] Bump Django from 2.0.2 to 2.0.3 Bumps [Django](https://www.djangoproject.com/) from 2.0.2 to 2.0.3. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6dc462342..ce439803f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.2 +Django==2.0.3 Babel==2.5.3 Pillow==5.0.0 celery[redis]==4.1.0 From 04e1a0eff0a87e5f83f9939425bcd26147e347e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 26 Mar 2018 07:15:04 +0000 Subject: [PATCH 070/106] Bump python-dateutil from 2.7.0 to 2.7.1 Bumps [python-dateutil](https://dateutil.readthedocs.io) from 2.7.0 to 2.7.1. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ce439803f..2445cfb08 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 psycopg2cffi==2.7.7 -python-dateutil==2.7.0 +python-dateutil==2.7.1 redis==2.10.6 django-celery-results==1.0.1 # django-celery-beat > 1.1.0 From bb3dfba91943cf108559a5d6cfd6180091efed6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 27 Mar 2018 07:14:18 +0000 Subject: [PATCH 071/106] Bump python-dateutil from 2.7.1 to 2.7.2 Bumps [python-dateutil](https://dateutil.readthedocs.io) from 2.7.1 to 2.7.2. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2445cfb08..d04179bf2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 psycopg2cffi==2.7.7 -python-dateutil==2.7.1 +python-dateutil==2.7.2 redis==2.10.6 django-celery-results==1.0.1 # django-celery-beat > 1.1.0 From 1151e54d0f362e6d51fa092b29c439e7fb337c82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 3 Apr 2018 07:14:21 +0000 Subject: [PATCH 072/106] Bump Django from 2.0.3 to 2.0.4 Bumps [Django](https://www.djangoproject.com/) from 2.0.3 to 2.0.4. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d04179bf2..e84d034ce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.3 +Django==2.0.4 Babel==2.5.3 Pillow==5.0.0 celery[redis]==4.1.0 From cd55db68d61e83ee55b7dfb51b719a8eefb7e610 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 3 Apr 2018 07:14:41 +0000 Subject: [PATCH 073/106] Bump transifex-client from 0.13.1 to 0.13.2 Bumps [transifex-client](https://github.com/transifex/transifex-client) from 0.13.1 to 0.13.2. - [Release notes](https://github.com/transifex/transifex-client/releases) - [Commits](https://github.com/transifex/transifex-client/compare/0.13.1...0.13.2) Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e02c15046..8c336235a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -transifex-client==0.13.1 +transifex-client==0.13.2 sphinx pep8 flake8 From fd51fde13d1d4d058c6ebc2972afe0bf744f53a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 3 Apr 2018 08:12:31 +0000 Subject: [PATCH 074/106] Bump Pillow from 5.0.0 to 5.1.0 Bumps [Pillow](https://github.com/python-pillow/Pillow) from 5.0.0 to 5.1.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/5.0.0...5.1.0) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e84d034ce..c2f68631a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ Django==2.0.4 Babel==2.5.3 -Pillow==5.0.0 +Pillow==5.1.0 celery[redis]==4.1.0 dj-database-url==0.5.0 django-redis-sessions==0.6.1 From bca714148718591192cc75bb14510373790b490e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 5 Apr 2018 07:14:08 +0000 Subject: [PATCH 075/106] Bump responses from 0.8.1 to 0.9.0 Bumps [responses](https://github.com/getsentry/responses) from 0.8.1 to 0.9.0. - [Release notes](https://github.com/getsentry/responses/releases) - [Changelog](https://github.com/getsentry/responses/blob/master/CHANGES) - [Commits](https://github.com/getsentry/responses/compare/0.8.1...0.9.0) Signed-off-by: dependabot[bot] --- requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-test.txt b/requirements-test.txt index b9c0d4dfa..d78a6b6ab 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -2,4 +2,4 @@ coverage==4.5.1 django-coverage-plugin==1.5.0 pytest-django pytest-cov -responses==0.8.1 +responses==0.9.0 From b182db6830b73c64c62e7d8fc760c9431151535d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 1 May 2018 07:13:51 +0000 Subject: [PATCH 076/106] Bump transifex-client from 0.13.2 to 0.13.3 Bumps [transifex-client](https://github.com/transifex/transifex-client) from 0.13.2 to 0.13.3. - [Release notes](https://github.com/transifex/transifex-client/releases) - [Commits](https://github.com/transifex/transifex-client/compare/0.13.2...0.13.3) Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 8c336235a..0b8f05916 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -transifex-client==0.13.2 +transifex-client==0.13.3 sphinx pep8 flake8 From 6654d084b83e132b71ef3351e39a8f4e6bf97d79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 1 May 2018 07:13:54 +0000 Subject: [PATCH 077/106] Bump gunicorn from 19.7.1 to 19.8.1 Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 19.7.1 to 19.8.1. - [Release notes](https://github.com/benoitc/gunicorn/releases) - [Commits](https://github.com/benoitc/gunicorn/compare/19.7.1...19.8.1) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c2f68631a..ab2abf5bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ dj-database-url==0.5.0 django-redis-sessions==0.6.1 python3-memcached==1.51 feedparser==5.2.1 -gunicorn==19.7.1 +gunicorn==19.8.1 html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 From 294e9d442f690021a171a326a91852c24bcd779d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 2 May 2018 07:15:16 +0000 Subject: [PATCH 078/106] Bump Django from 2.0.4 to 2.0.5 Bumps [Django](https://www.djangoproject.com/) from 2.0.4 to 2.0.5. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c2f68631a..d22b0bf5f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.4 +Django==2.0.5 Babel==2.5.3 Pillow==5.1.0 celery[redis]==4.1.0 From 493adbb9e5115970093495dc964ff0ff18af95fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 11 May 2018 07:13:55 +0000 Subject: [PATCH 079/106] Bump python-dateutil from 2.7.2 to 2.7.3 Bumps [python-dateutil](https://dateutil.readthedocs.io) from 2.7.2 to 2.7.3. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c73c020f4..516cb96c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 psycopg2cffi==2.7.7 -python-dateutil==2.7.2 +python-dateutil==2.7.3 redis==2.10.6 django-celery-results==1.0.1 # django-celery-beat > 1.1.0 From 1cf7ba5edd2baab7bd1e22d4c550445d38c1a27d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 4 Jun 2018 07:14:28 +0000 Subject: [PATCH 080/106] Bump django from 2.0.5 to 2.0.6 Bumps [django](https://www.djangoproject.com/) from 2.0.5 to 2.0.6. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c73c020f4..64e1c999a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.5 +Django==2.0.6 Babel==2.5.3 Pillow==5.1.0 celery[redis]==4.1.0 From 933929dcbf039e6eddfee80ccf41f0ef539c8fb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 6 Jun 2018 07:29:14 +0000 Subject: [PATCH 081/106] Bump babel from 2.5.3 to 2.6.0 Bumps [babel](https://github.com/python-babel/babel) from 2.5.3 to 2.6.0. - [Release notes](https://github.com/python-babel/babel/releases) - [Changelog](https://github.com/python-babel/babel/blob/master/docs/changelog.rst) - [Commits](https://github.com/python-babel/babel/compare/v2.5.3...v2.6.0) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 64e1c999a..7ff208951 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ Django==2.0.6 -Babel==2.5.3 +Babel==2.6.0 Pillow==5.1.0 celery[redis]==4.1.0 dj-database-url==0.5.0 From b8977ecc61f9f77bf2319027b976ac5ae3de8ab7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 15 Jun 2018 07:15:06 +0000 Subject: [PATCH 082/106] Bump requests from 2.18.4 to 2.19.1 Bumps [requests](https://github.com/requests/requests) from 2.18.4 to 2.19.1. - [Release notes](https://github.com/requests/requests/releases) - [Changelog](https://github.com/requests/requests/blob/master/HISTORY.rst) - [Commits](https://github.com/requests/requests/compare/v2.18.4...v2.19.1) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cd8a09178..b49f5866e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,4 +16,4 @@ redis==2.10.6 django-celery-results==1.0.1 # django-celery-beat > 1.1.0 git+https://github.com/celery/django-celery-beat.git@feaf34e2c30e28273b03d754d50e9a1d9f1191c6#egg=django-celery-beat -requests==2.18.4 +requests==2.19.1 From cc2a77ff1e92c500c635abcf15430de27c48b2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Mon, 18 Jun 2018 14:41:05 +0200 Subject: [PATCH 083/106] Handle "incorrect padding" when decoding API credentials --- mygpo/api/basic_auth.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mygpo/api/basic_auth.py b/mygpo/api/basic_auth.py index ac76baa94..77308fcab 100644 --- a/mygpo/api/basic_auth.py +++ b/mygpo/api/basic_auth.py @@ -1,4 +1,5 @@ import base64 +import binascii from functools import wraps from django.http import HttpResponse, HttpResponseBadRequest @@ -46,7 +47,7 @@ def view_or_basicauth(view, request, test_func, realm = "", *args, **kwargs): .decode('utf-8')\ .split(':', 1) - except UnicodeDecodeError as e: + except (UnicodeDecodeError, binascii.Error) as e: return HttpResponseBadRequest( 'Could not decode credentials: {msg}'.format(msg=str(e))) From 586f64d43a8d0ae696ef62a5feb547ed2d36a0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 22 Jun 2018 18:10:31 +0200 Subject: [PATCH 084/106] Error on JSON subscription upload with dicts --- mygpo/api/simple.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mygpo/api/simple.py b/mygpo/api/simple.py index 7105f6d07..ecc367be7 100644 --- a/mygpo/api/simple.py +++ b/mygpo/api/simple.py @@ -176,6 +176,9 @@ def parse_subscription(raw_post_data, format): end = raw_post_data.find(']') + 1 urls = json.loads(raw_post_data[begin:end]) + if not isinstance(urls, list): + raise ValueError('A list of feed URLs was expected') + else: return [] From 17ff514b35291537a0be48d6b095e16085a0f439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 22 Jun 2018 18:12:53 +0200 Subject: [PATCH 085/106] Handle invalid JSON response from Flickr API --- mygpo/data/flickr.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mygpo/data/flickr.py b/mygpo/data/flickr.py index ff393b37a..918ae3cf7 100644 --- a/mygpo/data/flickr.py +++ b/mygpo/data/flickr.py @@ -32,7 +32,10 @@ def get_photo_sizes(photo_id): logger.warn('Retrieving Flickr photo sizes failed: %s', str(e)) return [] - resp_obj = resp.json() + try: + resp_obj = resp.json() + except json.JSONDecodeError as jde: + return [] try: return resp_obj['sizes']['size'] From d22d46c4f42d93c2c324f2baa64124d9d69741fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 22 Jun 2018 18:15:06 +0200 Subject: [PATCH 086/106] Fix JSONP search --- mygpo/api/simple.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/api/simple.py b/mygpo/api/simple.py index ecc367be7..d53846e6c 100644 --- a/mygpo/api/simple.py +++ b/mygpo/api/simple.py @@ -138,7 +138,7 @@ def default_get_podcast(p): if any(x not in ALLOWED_FUNCNAME for x in jsonp_padding): return HttpResponseBadRequest('JSONP padding can only contain the characters %(char)s' % {'char': ALLOWED_FUNCNAME}) - objs = map(json_map, obj_list) + objs = list(map(json_map, obj_list)) return JsonResponse(objs, jsonp_padding=jsonp_padding) elif format == 'xml': From bd34a66c7f641cce787f882d8c370c7a81479822 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sat, 23 Jun 2018 08:50:32 +0300 Subject: [PATCH 087/106] Typo fixed Changed reset to resent. --- mygpo/users/templates/registration/resent_activation.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/users/templates/registration/resent_activation.html b/mygpo/users/templates/registration/resent_activation.html index 99d2d3ddf..0a4aa42ed 100644 --- a/mygpo/users/templates/registration/resent_activation.html +++ b/mygpo/users/templates/registration/resent_activation.html @@ -8,6 +8,6 @@

    {% trans "Sent Activation Email" %}

    {% endblock %} {% block content %} -

    {% trans "The activation email has been reset." %}

    +

    {% trans "The activation email has been resent." %}

    {% endblock %} From 528ab591f598566e276070a720a30597f9bf6985 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sat, 23 Jun 2018 09:27:04 +0300 Subject: [PATCH 088/106] Missing parentheses completion --- mygpo/web/templates/subscribe.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/web/templates/subscribe.html b/mygpo/web/templates/subscribe.html index 1028493d7..db12fc7be 100644 --- a/mygpo/web/templates/subscribe.html +++ b/mygpo/web/templates/subscribe.html @@ -38,7 +38,7 @@

    {% trans "Subscribe" %}

    {% else %} -

    {% trans "You can't subscribe to this podcast, because you don't have any devices (on which you don't have subscribed to the podcast already." %}

    +

    {% trans "You can't subscribe to this podcast, because you don't have any devices (on which you don't have subscribed to the podcast already)." %}

    {% trans "Create Device" %} From 097ba4c4c3a2a948081f07d9bd4007af751725f4 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 25 Jun 2018 12:57:02 +0300 Subject: [PATCH 089/106] Added full Hebrew translation Translated using Transifex: https://www.transifex.com/yaron/gpodder/ I'm not 100% sure about the "weeks, days, hours" strings at the end, the might crash the app so if needed I'll change this although this is the preferred native form for Hebrew speakers. Fully compatible with the AntennaPod translation. --- mygpo/locale/he/LC_MESSAGES/django.po | 2702 +++++++++++++++++++++++++ 1 file changed, 2702 insertions(+) create mode 100644 mygpo/locale/he/LC_MESSAGES/django.po diff --git a/mygpo/locale/he/LC_MESSAGES/django.po b/mygpo/locale/he/LC_MESSAGES/django.po new file mode 100644 index 000000000..81a5243ee --- /dev/null +++ b/mygpo/locale/he/LC_MESSAGES/django.po @@ -0,0 +1,2702 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Yaron Shahrabani , 2018\n" +"Language-Team: Hebrew (https://www.transifex.com/yaron/teams/87581/he/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: he\n" +"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n" + +#: mygpo/administration/templates/admin/activate-user.html:9 +#: mygpo/administration/templates/admin/activate-user.html:12 +#: mygpo/administration/templates/admin/overview.html:22 +msgid "Activate User" +msgstr "הפעלת משתמש" + +#: mygpo/administration/templates/admin/activate-user.html:20 +#: mygpo/web/forms.py:179 mygpo/web/templates/account.html:112 +msgid "Username" +msgstr "שם משתמש" + +#: mygpo/administration/templates/admin/activate-user.html:27 +msgid "Email" +msgstr "כתובת" + +#: mygpo/administration/templates/admin/activate-user.html:35 +msgid "Activate" +msgstr "הפעלה" + +#: mygpo/administration/templates/admin/clients.html:10 +#: mygpo/administration/templates/admin/make-publisher-result.html:16 +#: mygpo/administration/templates/admin/merge-grouping.html:10 +#: mygpo/administration/templates/admin/merge-select.html:9 +#: mygpo/administration/templates/admin/overview.html:9 +#: mygpo/administration/templates/admin/overview.html:12 +#: mygpo/administration/templates/admin/stats.html:9 +#: mygpo/administration/templates/admin/useragents.html:9 +msgid "Admin Area" +msgstr "אזור ניהול" + +#: mygpo/administration/templates/admin/clients.html:13 +#: mygpo/administration/templates/admin/useragents.html:12 +msgid "User-Agent Statistics" +msgstr "סטטיסטיקת דפדפנים" + +#: mygpo/administration/templates/admin/clients.html:19 +#: mygpo/administration/templates/admin/filetypes.html:19 +#: mygpo/administration/templates/admin/useragents.html:18 +msgid "#" +msgstr "מס׳" + +#: mygpo/administration/templates/admin/clients.html:20 +msgid "Client" +msgstr "לקוח" + +#: mygpo/administration/templates/admin/clients.html:21 +#: mygpo/administration/templates/admin/clients.html:23 +#: mygpo/administration/templates/admin/clients.html:25 +msgid "Version" +msgstr "גרסה" + +#: mygpo/administration/templates/admin/clients.html:22 +msgid "Library" +msgstr "ספריה" + +#: mygpo/administration/templates/admin/clients.html:24 +msgid "OS" +msgstr "מערכת הפעלה" + +#: mygpo/administration/templates/admin/clients.html:26 +#: mygpo/administration/templates/admin/useragents.html:20 +msgid "Number of Clients" +msgstr "מספר לקוחות" + +#: mygpo/administration/templates/admin/clients.html:53 +#: mygpo/administration/templates/admin/useragents.html:33 +msgid "Total" +msgstr "סך הכול" + +#: mygpo/administration/templates/admin/filetypes.html:10 +#: mygpo/administration/templates/admin/filetypes.html:13 +msgid "File Type Stats" +msgstr "סטטיסטיקת סוגי קבצים" + +#: mygpo/administration/templates/admin/filetypes.html:20 +msgid "File Type" +msgstr "סוג קובץ" + +#: mygpo/administration/templates/admin/filetypes.html:21 +msgid "Episode URLs" +msgstr "כתובות פרקים" + +#: mygpo/administration/templates/admin/hostinfo.html:9 +#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/overview.html:17 +msgid "Host Information" +msgstr "פרטי מארח" + +#: mygpo/administration/templates/admin/hostinfo.html:20 +msgid "mygpo Version" +msgstr "גרסת mygpo" + +#: mygpo/administration/templates/admin/hostinfo.html:31 +msgid "Base Directory" +msgstr "תיקיית בסיס" + +#: mygpo/administration/templates/admin/hostinfo.html:36 +msgid "Hostname" +msgstr "שם מארח" + +#: mygpo/administration/templates/admin/hostinfo.html:41 +msgid "Django Version" +msgstr "גרסת Django" + +#: mygpo/administration/templates/admin/hostinfo.html:46 +msgid "Feed Update Queue" +msgstr "תור עדכון הזנות" + +#: mygpo/administration/templates/admin/hostinfo.html:49 +msgid "min ahead" +msgstr "דקות הקדמה" + +#: mygpo/administration/templates/admin/hostinfo.html:51 +msgid "min behind" +msgstr "דקות איחור" + +#: mygpo/administration/templates/admin/hostinfo.html:59 +msgid "Number of podcasts with outdated search index" +msgstr "מספר הפודקאסטים עם אינדקס חיפוש בלתי עדכני" + +#: mygpo/administration/templates/admin/hostinfo.html:66 +msgid "Scheduled Celery Tasks" +msgstr "משימות מתוזמנות ב־Celery" + +#: mygpo/administration/templates/admin/make-publisher-input.html:9 +#: mygpo/administration/templates/admin/make-publisher-input.html:12 +#: mygpo/administration/templates/admin/make-publisher-result.html:9 +#: mygpo/administration/templates/admin/make-publisher-result.html:12 +#: mygpo/administration/views.py:391 +msgid "Publisher Permissions" +msgstr "הרשאות הפצה" + +#: mygpo/administration/templates/admin/make-publisher-mail.txt:2 +#, python-format +msgid "Hi %(username)s," +msgstr "שלום %(username)s," + +#: mygpo/administration/templates/admin/make-publisher-mail.txt:4 +msgid "You have been assigned as a publisher for the following podcasts:" +msgstr "הוקצית להפצה של הפודקאסטים הבאים:" + +#: mygpo/administration/templates/admin/make-publisher-mail.txt:11 +msgid "You can now access the publisher pages at" +msgstr "כעת באפשרותך לגשת לעמודי ההפצה תחת" + +#: mygpo/administration/templates/admin/make-publisher-mail.txt:15 +#, python-format +msgid "" +"There you can get statistics, insights and additional control over your " +"podcast at %(domain)s." +msgstr "" +"שם ניתן לקבל סטטיסטיקה, תובנות ושליטה נוספת על הפודקאסט שלך ב־%(domain)s." + +#: mygpo/administration/templates/admin/make-publisher-mail.txt:17 +#, python-format +msgid "If you have any questions, please visit %(url)s" +msgstr "אם יש לך שאלות, ניתן לבקר ב־%(url)s" + +#: mygpo/administration/templates/admin/merge-grouping.html:13 +#: mygpo/administration/templates/admin/merge-select.html:12 +#: mygpo/administration/templates/admin/overview.html:18 +msgid "Merge Podcasts and Episodes" +msgstr "מיזוג פודקאסטים ופרקים" + +#: mygpo/administration/templates/admin/merge-grouping.html:24 +msgid "" +"Episodes that have the same number will be merged. Please verify all your " +"changes by clicking on 'Renew Groups' before starting the Merge." +msgstr "" +"פרקים שיש להם את אותו המספר ימוזגו. נא לאמת את כל השינויים שלך על ידי לחיצה " +"על ‚חידוש קבוצות’ בטרם התחלת המיזוג." + +#: mygpo/administration/templates/admin/overview.html:19 +msgid "Client Stats" +msgstr "סטטיסטיקת לקוח" + +#: mygpo/administration/templates/admin/overview.html:19 +#: mygpo/administration/templates/admin/overview.html:21 +msgid "JSON" +msgstr "JSON" + +#: mygpo/administration/templates/admin/overview.html:20 +msgid "User-Agent Stats" +msgstr "סטטיסטיקת דפדפן" + +#: mygpo/administration/templates/admin/overview.html:21 +msgid "General Stats" +msgstr "סטטיסטיקה כללית" + +#: mygpo/administration/templates/admin/overview.html:23 +msgid "Assign Publisher Permissions" +msgstr "הקצאת הרשאות הפצה" + +#: mygpo/administration/templates/admin/stats.html:12 +msgid "Statistics" +msgstr "סטטיסטיקה" + +#: mygpo/administration/templates/admin/stats.html:18 +msgid "Property" +msgstr "מאפיין" + +#: mygpo/administration/templates/admin/stats.html:19 +msgid "Value" +msgstr "ערך" + +#: mygpo/administration/templates/admin/task-status.html:17 +#: mygpo/administration/templates/admin/task-status.html:26 +msgid "Operation Finished" +msgstr "הפעולה הסתיימה" + +#: mygpo/administration/templates/admin/task-status.html:19 +#: mygpo/administration/templates/admin/task-status.html:28 +msgid "Operation Ongoing" +msgstr "הפעולה מתבצעת" + +#: mygpo/administration/templates/admin/task-status.html:37 +msgid "The following actions were recorded:" +msgstr "הפעולות הבאות הוקלטו:" + +#: mygpo/administration/templates/admin/task-status.html:42 +#: mygpo/publisher/templates/publisher/episode.html:80 +msgid "none" +msgstr "אין" + +#: mygpo/administration/templates/admin/task-status.html:47 +msgid "Go to podcast" +msgstr "מעבר לפודקאסט" + +#: mygpo/administration/templates/admin/task-status.html:49 +#: mygpo/directory/templates/directory/add-podcast-status.html:50 +msgid "The operation is still ongoing..." +msgstr "הפעולה עדיין מתבצעת…" + +#: mygpo/administration/templates/admin/task-status.html:51 +#: mygpo/directory/templates/directory/add-podcast-status.html:52 +msgid "Refresh" +msgstr "רענון" + +#: mygpo/administration/templates/admin/useragents.html:19 +msgid "User-Agent" +msgstr "סוכן דפדפן" + +#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#, python-brace-format +msgid "No podcast with URL {url}" +msgstr "אין פודקאסט בכתובת {url}" + +#: mygpo/administration/views.py:316 +msgid "Provide either username or email address" +msgstr "יש לספק שם משתמש או כתובת דוא״ל" + +#: mygpo/administration/views.py:322 +msgid "No user found" +msgstr "לא נמצאו משתמשים" + +#: mygpo/administration/views.py:327 +#, python-brace-format +msgid "User {username} ({email}) activated" +msgstr "המשתמש {username} ‎({email}) עבר עימות" + +#: mygpo/api/constants.py:8 +msgid "downloaded" +msgstr "התקבל" + +#: mygpo/api/constants.py:9 +msgid "played" +msgstr "התנגן" + +#: mygpo/api/constants.py:10 +msgid "deleted" +msgstr "נמחק" + +#: mygpo/api/constants.py:11 +msgid "marked as new" +msgstr "סומן כחדש" + +#: mygpo/api/constants.py:12 +msgid "flattr'd" +msgstr "קיבל flattr" + +#: mygpo/api/constants.py:20 +msgid "subscribed" +msgstr "נרשם" + +#: mygpo/api/constants.py:21 +msgid "unsubscribed" +msgstr "בוטל רישום" + +#: mygpo/api/simple.py:55 mygpo/api/simple.py:90 +#, python-format +msgid "%(username)s's Subscription List" +msgstr "רשימת המינויים של %(username)s" + +#: mygpo/api/simple.py:237 +#, python-format +msgid "gpodder.net - Top %(count)d" +msgstr "gpodder.net - %(count)d המובילים" + +#: mygpo/api/simple.py:272 +msgid "gpodder.net - Search" +msgstr "gpodder.net - חיפוש" + +#: mygpo/api/simple.py:289 +#, python-format +msgid "gpodder.net - %(count)d Suggestions" +msgstr "gpodder.net - %(count)d הצעות" + +#: mygpo/data/mimetype.py:13 +msgid "image" +msgstr "תמונה" + +#: mygpo/data/mimetype.py:13 +msgid "audio" +msgstr "קטע שמיעה" + +#: mygpo/data/mimetype.py:13 +msgid "video" +msgstr "סרטון" + +#: mygpo/directory/templates/carousel.html:43 +#: mygpo/directory/templates/carousel.html:46 +msgid "Explore" +msgstr "עיון" + +#: mygpo/directory/templates/carousel.html:81 +#: mygpo/web/templates/episode.html:150 +msgid "..." +msgstr "…" + +#: mygpo/directory/templates/directory.html:13 +#: mygpo/directory/templates/directory.html:16 +msgid "Podcast Directory" +msgstr "תיקיית פודקאסטים" + +#: mygpo/directory/templates/directory.html:30 +#, python-format +msgid "" +"%(listtitle)s by %(username)s" +msgstr "" +"%(listtitle)s מאת %(username)s" + +#: mygpo/directory/templates/directory.html:46 +#: mygpo/directory/templates/directory.html:48 +#: mygpo/directory/templates/directory.html:133 +#: mygpo/directory/templates/podcast-ad-box.html:23 +#: mygpo/web/templates/dashboard.html:73 +msgid "more..." +msgstr "עוד…" + +#: mygpo/directory/templates/directory.html:85 +msgid "Podcast List by" +msgstr "רשימת פודקאסטים מאת" + +#: mygpo/directory/templates/directory.html:102 +#, python-format +msgid "and %(more)s more" +msgstr "ו־%(more)s נוספים" + +#: mygpo/directory/templates/directory.html:108 +msgid "Create a Podcast List" +msgstr "יצירת רשימת פודקאסטים" + +#: mygpo/directory/templates/directory.html:119 +#: mygpo/web/templates/dashboard.html:59 +msgid "Random" +msgstr "אקראי" + +#: mygpo/directory/templates/directory/add-podcast-status.html:16 +#: mygpo/directory/templates/directory/add-podcast-status.html:25 +msgid "Podcast Added" +msgstr "נוסף פודקאסט" + +#: mygpo/directory/templates/directory/add-podcast-status.html:18 +#: mygpo/directory/templates/directory/add-podcast-status.html:27 +msgid "Adding Podcast" +msgstr "פודקאסט מתווסף" + +#: mygpo/directory/templates/directory/add-podcast-status.html:44 +msgid "No podcasts could be added" +msgstr "לא ניתן להוסיף פודקאסטים" + +#: mygpo/directory/templates/directory/license-podcasts.html:13 +#: mygpo/directory/templates/directory/license-podcasts.html:16 +#, python-format +msgid "Podcasts with License %(licensename)s" +msgstr "פודקאסט עם הרישיון %(licensename)s" + +#: mygpo/directory/templates/directory/license-podcasts.html:24 +msgid "License overview" +msgstr "סקירת רישיון" + +#: mygpo/directory/templates/directory/license-podcasts.html:29 +msgid "View License" +msgstr "הצגת הרישיון" + +#: mygpo/directory/templates/directory/license-podcasts.html:36 +#: mygpo/directory/templates/search.html:35 +#: mygpo/directory/templates/toplist.html:26 +#: mygpo/podcastlists/templates/list.html:48 mygpo/web/templatetags/menu.py:33 +#: mygpo/web/templatetags/menu.py:68 +msgid "Podcast" +msgstr "פודקאסט" + +#: mygpo/directory/templates/directory/license-podcasts.html:37 +#: mygpo/directory/templates/search.html:36 +#: mygpo/directory/templates/toplist.html:27 +#: mygpo/podcastlists/templates/list.html:49 +msgid "Subscribers" +msgstr "מנויים" + +#: mygpo/directory/templates/directory/license-podcasts.html:50 +#: mygpo/directory/templates/episode_toplist.html:41 +#: mygpo/directory/templates/toplist.html:47 +msgid "Currently not available" +msgstr "לא זמין כרגע" + +#: mygpo/directory/templates/directory/licenses.html:13 +#: mygpo/directory/templates/directory/licenses.html:16 +msgid "Podcasts with License Information" +msgstr "פודקאסטים עם פרטי רישיון" + +#: mygpo/directory/templates/directory/licenses.html:23 +#: mygpo/web/templatetags/menu.py:40 +msgid "License" +msgstr "רישיון" + +#: mygpo/directory/templates/directory/licenses.html:24 +#: mygpo/directory/templates/podcast_lists.html:24 +#: mygpo/web/templates/base.html:135 mygpo/web/templates/home.html:155 +#: mygpo/web/templatetags/menu.py:42 +msgid "Podcasts" +msgstr "פודקאסטים" + +#: mygpo/directory/templates/episode_toplist.html:12 +#: mygpo/directory/templates/episode_toplist.html:15 +msgid "Episode-Toplist" +msgstr "רשימת הפרקים המובילים" + +#: mygpo/directory/templates/episode_toplist.html:24 +msgid "Episode" +msgstr "פרק" + +#: mygpo/directory/templates/episode_toplist.html:25 +#: mygpo/publisher/templates/publisher/episodes.html:36 +msgid "Listeners" +msgstr "מאזינים" + +#: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/publisher/templates/publisher/episode.html:33 +#: mygpo/share/templates/userpage.html:118 +#: mygpo/share/templates/userpage.html:138 +#: mygpo/web/templates/episode-history.html:50 +#: mygpo/web/templates/episode.html:51 +msgid "from" +msgstr "מאת" + +#: mygpo/directory/templates/episode_toplist.html:53 +#: mygpo/directory/templates/episode_toplist.html:57 +#: mygpo/directory/templates/toplist.html:60 +#: mygpo/directory/templates/toplist.html:64 +msgid "Language" +msgstr "שפה" + +#: mygpo/directory/templates/episode_toplist.html:61 +#: mygpo/directory/templates/episode_toplist.html:63 +#: mygpo/directory/templates/toplist.html:68 +#: mygpo/directory/templates/toplist.html:70 +msgid "all" +msgstr "הכול" + +#: mygpo/directory/templates/episode_toplist.html:75 +#: mygpo/directory/templates/toplist.html:83 +msgid "OK" +msgstr "אישור" + +#: mygpo/directory/templates/missing.html:11 +#: mygpo/directory/templates/missing.html:14 mygpo/web/templatetags/menu.py:35 +msgid "Missing Podcast" +msgstr "פודקאסט חסר" + +#: mygpo/directory/templates/missing.html:20 +#, python-format +msgid "" +"If you're missing a podcast on %(sitename)s, please enter its feed URL here" +msgstr "אם חסר לך פודקאסט ב־%(sitename)s, נא להקליד את כתובת ההזנה שלו להלן" + +#: mygpo/directory/templates/missing.html:27 +msgid "Check" +msgstr "בדיקה" + +#: mygpo/directory/templates/missing.html:36 +msgid "The podcast already exists" +msgstr "הפודקאסט כבר קיים" + +#: mygpo/directory/templates/missing.html:49 +msgid "Add Podcast" +msgstr "הוספת פודקאסט" + +#: mygpo/directory/templates/podcast-ad-box.html:9 +msgid "Sponsoring Podcast" +msgstr "מימון פודקאסט" + +#: mygpo/directory/templates/podcast_lists.html:13 +#: mygpo/directory/templates/podcast_lists.html:16 +#: mygpo/podcastlists/templates/lists.html:13 +#: mygpo/podcastlists/templates/lists.html:16 +#: mygpo/podcastlists/templates/lists_user.html:9 +#: mygpo/web/templatetags/menu.py:36 mygpo/web/templatetags/menu.py:58 +msgid "Podcast Lists" +msgstr "רשימות פודקאסטים" + +#: mygpo/directory/templates/podcast_lists.html:22 +msgid "List Name" +msgstr "שם רשימה" + +#: mygpo/directory/templates/podcast_lists.html:23 +msgid "User" +msgstr "משתמש" + +#: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/publisher/templates/publisher/episode.html:35 +#: mygpo/web/templates/episode-history.html:52 +#: mygpo/web/templates/episode.html:53 +msgid "Download" +msgstr "הורדה" + +#: mygpo/directory/templates/podcast_lists.html:76 +#: mygpo/podcastlists/templates/lists_user.html:37 +msgid "Know Some Great Podcasts?" +msgstr "ידוע לך על פודקאסטים מעולים?" + +#: mygpo/directory/templates/podcast_lists.html:77 +#: mygpo/podcastlists/templates/lists_user.html:38 +msgid "Create a list of podcasts about a topic you like" +msgstr "יצירת רשימת פודקאסטים על נושא מועדף עליך" + +#: mygpo/directory/templates/search.html:11 +#: mygpo/directory/templates/search.html:14 +#: mygpo/directory/templates/search.html:25 +#: mygpo/podcastlists/templates/list.html:104 +#: mygpo/subscriptions/templates/subscriptions.html:53 +#: mygpo/web/templates/base.html:136 mygpo/web/templates/home.html:156 +#: mygpo/web/templatetags/menu.py:34 +msgid "Search" +msgstr "חיפוש" + +#: mygpo/directory/templates/search.html:23 +#: mygpo/podcastlists/templates/list.html:102 +#: mygpo/subscriptions/templates/subscriptions.html:51 +msgid "Search term or feed URL" +msgstr "ביטוי לחיפוש או כתובת הזנה" + +#: mygpo/directory/templates/search.html:79 +#: mygpo/podcastlists/templates/list_search.html:65 +msgid "Nothing found" +msgstr "לא נמצא שום דבר" + +#: mygpo/directory/templates/search.html:91 +msgid "Search API" +msgstr "API לחיפוש" + +#: mygpo/directory/templates/search.html:92 +msgid "Access the following address to search for tech podcasts." +msgstr "ניתן לגשת לכתובת הבאה לחיפוש אחר פודקאסטים בנושא טכנולוגיה." + +#: mygpo/directory/templates/toplist.html:14 +#: mygpo/directory/templates/toplist.html:17 +msgid "Toplist" +msgstr "רשימות מובילות" + +#: mygpo/directory/templates/toplist.html:88 +msgid "Client Access" +msgstr "גישת לקוח" + +#: mygpo/directory/views.py:321 +#, python-format +msgid "%d podcasts added" +msgstr "נוספו %d פודקאסטים" + +#: mygpo/history/templates/history.html:12 +#: mygpo/history/templates/history.html:15 +#: mygpo/web/templates/podcast-history.html:32 +#: mygpo/web/templates/podcast.html:143 +msgid "Subscription History" +msgstr "היסטוריית מינויים" + +#: mygpo/history/templates/history.html:12 +#: mygpo/history/templates/history.html:15 +msgid "for" +msgstr "עבור" + +#: mygpo/history/templates/history.html:22 +#: mygpo/web/templates/device-edit.html:16 +msgid "Back to" +msgstr "חזרה אל" + +#: mygpo/history/templates/history.html:66 +msgid "Nothing happened yet." +msgstr "שום דבר לא קרה עדיין." + +#: mygpo/history/templates/history.html:73 +#: mygpo/history/templates/history.html:75 +msgid "Later" +msgstr "מאוחר יותר" + +#: mygpo/history/templates/history.html:80 +#: mygpo/history/templates/history.html:82 +msgid "Now" +msgstr "עכשיו" + +#: mygpo/history/templates/history.html:87 +#: mygpo/history/templates/history.html:89 +msgid "Earlier" +msgstr "מוקדם יותר" + +#: mygpo/podcastlists/templates/list.html:28 +#, python-format +msgid "\"%(list_title)s\" by %(ownername)s" +msgstr "„%(list_title)s” מאת %(ownername)s" + +#: mygpo/podcastlists/templates/list.html:35 +#, python-format +msgid "a podcast list by %(ownername)s" +msgstr "רשימת פודקאסטים מאת %(ownername)s" + +#: mygpo/podcastlists/templates/list.html:74 +msgid "No Podcasts" +msgstr "אין פודקאסטים" + +#: mygpo/podcastlists/templates/list.html:84 +msgid "Vote" +msgstr "הצבעה" + +#: mygpo/podcastlists/templates/list.html:90 +msgid "Download as OPML" +msgstr "הורדה כ־OPML" + +#: mygpo/podcastlists/templates/list.html:121 +msgid "Your own Podcast Lists" +msgstr "רשימות הפודקאסטים האישיות שלך" + +#: mygpo/podcastlists/templates/list.html:122 +msgid "Create and share your own podcast lists " +msgstr "יצירה ושיתוף של רשימות פודקאסטים משלך" + +#: mygpo/podcastlists/templates/list.html:123 +#: mygpo/publisher/templates/publisher/home.html:31 +#: mygpo/web/templates/user_subscriptions.html:65 +msgid "Go" +msgstr "להמשיך" + +#: mygpo/podcastlists/templates/lists.html:29 +#: mygpo/podcastlists/templates/lists_user.html:22 +#: mygpo/share/templates/userpage.html:88 +#, python-format +msgid "%(num_podcasts)s Podcasts" +msgstr "%(num_podcasts)s פודקאסטים" + +#: mygpo/podcastlists/templates/lists.html:34 +#: mygpo/web/templates/device-edit.html:77 +msgid "Delete" +msgstr "מחיקה" + +#: mygpo/podcastlists/templates/lists.html:41 +msgid "You don't have any podcast lists yet." +msgstr "אין לך רשימות פודקאסטים עדיין." + +#: mygpo/podcastlists/templates/lists.html:52 +#: mygpo/share/templates/share/favorites.html:57 +#: mygpo/web/templates/devicelist.html:64 +msgid "Create" +msgstr "יצירה" + +#: mygpo/podcastlists/templates/lists.html:60 +msgid "" +"Podcast Lists are intended to share podcasts about certain topics and are " +"therefore always visible to everyone." +msgstr "" +"רשימות פודקאסטים מיועדות לשיתוף פודקאסטים בנושאים מסוימים ולכן הן תמיד " +"גלויות לכולם." + +#: mygpo/podcastlists/templates/lists_user.html:12 +#, python-format +msgid "Podcast Lists by %(username)s" +msgstr "רשימות פודקאסטים מאת %(username)s" + +#: mygpo/podcastlists/templates/lists_user.html:27 +#, python-format +msgid "%(username)s hasn't created any podcast lists yet." +msgstr "לא נוצרו עדיין רשימות פודקאסטים על ידי המשתמש %(username)s." + +#: mygpo/podcastlists/views.py:104 +msgid "You have to specify a title." +msgstr "עליך לציין כותרת." + +#: mygpo/podcastlists/views.py:110 +#, python-brace-format +msgid "\"{title}\" is not a valid title" +msgstr "„{title}” אינה כותרת תקנית" + +#: mygpo/podcastlists/views.py:169 +msgid "Thanks for rating!" +msgstr "תודה לך על הדירוג!" + +#: mygpo/podcasts/admin.py:22 mygpo/web/templates/device-edit.html:28 +msgid "Edit" +msgstr "עריכה" + +#: mygpo/podcasts/models.py:688 +msgid "Unknown Podcast" +msgstr "פודקאסט לא ידוע" + +#: mygpo/podcasts/models.py:690 +#, python-brace-format +msgid "Unknown Podcast from {domain}" +msgstr "פודקאסט לא ידוע מ־{domain}" + +#: mygpo/publisher/forms.py:5 +#: mygpo/publisher/templates/publisher/episode.html:60 +msgid "URL" +msgstr "כתובת" + +#: mygpo/publisher/templates/link.html:8 +msgid "For Podcast Authors" +msgstr "ליוצרי פודקאסטים" + +#: mygpo/publisher/templates/link.html:11 +msgid "Link to" +msgstr "קישור אל" + +#: mygpo/publisher/templates/link.html:17 +#: mygpo/publisher/templates/publisher/podcast.html:171 +#, python-format +msgid "" +"You can paste this code on your website, so users of %(sitename)s can " +"directly subscribe to your podcast." +msgstr "" +"ניתן להדביק את הקוד הזה באתר שלך, כדי שהמשתמשים של %(sitename)s יכולים " +"להירשם ישירות לפודקאסט שלך." + +#: mygpo/publisher/templates/link.html:18 +msgid "Change the field 'YOUR_ADRESS' with the adress of your podcast feed." +msgstr "יש להחליף את השדה ‚YOUR_ADRESS’ בכתובת הזנת הפודקאסט שלך." + +#: mygpo/publisher/templates/publisher/advertise.html:9 +#: mygpo/publisher/templates/publisher/info.html:20 +#: mygpo/web/templates/base.html:153 mygpo/web/templates/base.html:180 +#: mygpo/web/templates/home.html:173 mygpo/web/templates/home.html:200 +#: mygpo/web/templatetags/menu.py:66 +msgid "Advertise" +msgstr "פרסום" + +#: mygpo/publisher/templates/publisher/advertise.html:12 +#, python-format +msgid "Advertise on %(sitename)s" +msgstr "פרסום ב־%(sitename)s" + +#: mygpo/publisher/templates/publisher/advertise.html:18 +#, python-format +msgid "" +"For just € 20,-- your podcast will be shown on the front page of " +"%(sitename)s for a week. Additionally it will be the first podcast " +"in gPodder's list of example podcasts." +msgstr "" +"עבור 20 אירו בלבד הפודקאסט שלך יכול להופיע בעמוד הפתיחה של " +"%(sitename)s למשך שבוע. בנוסף הוא יהיה הפודקאסט הראשון " +"הרשימת הפודקאסטים לדוגמה של gPodder." + +#: mygpo/publisher/templates/publisher/advertise.html:20 +msgid "" +"You can chose when your advertisement will be active, and the text that will" +" be displayed for your podcast." +msgstr "ניתן לבחור אם הפרסום שלך יהיה פעיל, והטקסט שיוצג עבור הפודקאסט שלך." + +#: mygpo/publisher/templates/publisher/advertise.html:22 +msgid "Front Page" +msgstr "עמוד פתיחה" + +#: mygpo/publisher/templates/publisher/advertise.html:23 +#, python-format +msgid "" +"Your podcast will be displayed on the front page of %(sitename)s for both " +"logged-in and anonymous users." +msgstr "" +"הפודקאסט שלך יופיע בעמוד הפתיחה של %(sitename)s גם למשתמשים שנכנסו למערכת " +"וגם למשתמשים אלמוניים." + +#: mygpo/publisher/templates/publisher/advertise.html:25 +msgid "Example Podcasts" +msgstr "פודקאסטים לדוגמה" + +#: mygpo/publisher/templates/publisher/advertise.html:26 +msgid "" +"The gPodder client offers a list of example podcasts when started for the " +"first time. This list is loaded from the web on demand. For the time of your" +" advertisement, your podcast will be the first in the list." +msgstr "" +"הלקוח של gPodder מציע רשימת פודקאסטים לדוגמה כשהוא מופעל בפעם הראשונה. רשימה" +" זו נטענת מהאתר לפי דרישה. לזמן הפרסום שלך, הפודקאסט שלך יהיה הראשון ברשימה." + +#: mygpo/publisher/templates/publisher/advertise.html:28 +msgid "Visitors" +msgstr "מבקרים" + +#: mygpo/publisher/templates/publisher/advertise.html:29 +msgid "" +"Both the front page and the list of example podcasts are accessed by more " +"than 1000 people daily, who are actively looking for interesting podcasts. " +"We do, however, not guarantee a certain number of visitors during your " +"advertisement period." +msgstr "" +"גם עמוד הפתיחה וגם רשימת הדוגמאות מקבלים חשיפה של למעלה מ־1000 איש ביום, " +"שמחפשים באופן פעיל פודקאסטים מעניינים. עם זאת, איננו מתחייבים למספר מסוים של" +" מבקרים במהלך תקופת הפרסום שלך." + +#: mygpo/publisher/templates/publisher/advertise.html:31 +msgid "Start your Advertisement" +msgstr "התחלת הפרסום שלך" + +#: mygpo/publisher/templates/publisher/advertise.html:32 +#, python-format +msgid "" +"Contact stefan@gpodder.net if you " +"would like to advertise on %(sitename)s or if you have any questions. " +"Payments are done via PayPal to thp@perli.net." +msgstr "" +"עליך ליצור קשר עם stefan@gpodder.net אם ברצונך לפרסם " +"באתר %(sitename)s או אם יש לך שאלות. התשלום הוא דרך PayPal לטובת " +"thp@perli.net." + +#: mygpo/publisher/templates/publisher/episode.html:31 +msgid "Unnamed Episode" +msgstr "פרק ללא שם" + +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:26 +#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 +#: mygpo/web/templates/podcast.html:39 +msgid "Publisher Pages" +msgstr "עמודי הפצה" + +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:38 +#: mygpo/web/templates/episode-history.html:57 +#: mygpo/web/templates/episode.html:58 +#: mygpo/web/templates/podcast-base.html:54 +msgid "Website" +msgstr "אתר" + +#: mygpo/publisher/templates/publisher/episode.html:45 +#: mygpo/web/templates/episode-history.html:62 +#: mygpo/web/templates/episode.html:63 +msgid "listeners" +msgstr "מאזינים" + +#: mygpo/publisher/templates/publisher/episode.html:55 +msgid "Episode List" +msgstr "רשימת פרקים" + +#: mygpo/publisher/templates/publisher/episode.html:56 +msgid "Podcast Page" +msgstr "עמוד פודקאסט" + +#: mygpo/publisher/templates/publisher/episode.html:61 +msgid "" +"You can configure the URL of this episode. Previous keys will automatically " +"be added to the alternative keys and always redirect to the current URL." +msgstr "" +"ניתן להגדיר את כתובת הפרק הזה. מפתחות קודמים יתווספו אוטומטית למפתחות " +"החלופיים ותמיד יפנו לכתובת הנוכחית." + +#: mygpo/publisher/templates/publisher/episode.html:72 +#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 +#: mygpo/web/templates/device-edit.html:53 +msgid "Save" +msgstr "שמירה" + +#: mygpo/publisher/templates/publisher/episode.html:86 +msgid "Episode data" +msgstr "נתוני פודקאסט" + +#: mygpo/publisher/templates/publisher/episode.html:87 +msgid "Last update: " +msgstr "עדכון אחרון:" + +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:26 +#: mygpo/web/templates/podcast-base.html:39 +msgid "Unnamed Podcast" +msgstr "פודקאסט ללא שם" + +#: mygpo/publisher/templates/publisher/episodes.html:24 +msgid "Return to Podcast Page" +msgstr "חזרה לעמוד הפודקאסט" + +#: mygpo/publisher/templates/publisher/episodes.html:31 +#: mygpo/share/templates/userpage.html:182 +#: mygpo/share/templates/userpage.html:188 mygpo/web/templatetags/menu.py:43 +msgid "Episodes" +msgstr "פרקים" + +#: mygpo/publisher/templates/publisher/episodes.html:34 +msgid "Title" +msgstr "כותרת" + +#: mygpo/publisher/templates/publisher/episodes.html:35 +msgid "Released" +msgstr "יצא לאור" + +#: mygpo/publisher/templates/publisher/group.html:21 +msgid "Publisher Pages:" +msgstr "עמודי הפצה:" + +#: mygpo/publisher/templates/publisher/group.html:26 +msgid "This is a group of podcasts containing" +msgstr "זו קבוצה של פודקאסטים שמכילה" + +#: mygpo/publisher/templates/publisher/home.html:9 +msgid "Podcasts Published by Me" +msgstr "פודקאסטים שאני פרסמתי" + +#: mygpo/publisher/templates/publisher/home.html:12 +msgid "Publisher Area" +msgstr "אזור הפצה" + +#: mygpo/publisher/templates/publisher/home.html:21 +msgid "Staff only" +msgstr "צוות בלבד" + +#: mygpo/publisher/templates/publisher/home.html:24 +msgid "Go to the publisher page of any podcast by entering its feed URL" +msgstr "" +"ניתן לעבור לעמוד ההפצה של כל פודקאסט שהוא על ידי הקלדת כתובת ההזנה שלו" + +#: mygpo/publisher/templates/publisher/home.html:29 +msgid "http://" +msgstr "http://‎" + +#: mygpo/publisher/templates/publisher/home.html:43 +msgid "Published Podcasts" +msgstr "פודקאסטים שפורסמו" + +#: mygpo/publisher/templates/publisher/home.html:46 +msgid "You have publisher permissions for the following podcasts." +msgstr "יש לך הרשאות הפצה לפודקאסטים הבאים." + +#: mygpo/publisher/templates/publisher/home.html:62 +msgid "Update podcasts" +msgstr "עדכון פודקאסטים" + +#: mygpo/publisher/templates/publisher/home.html:65 +msgid "" +"To update all of your published podcasts automatically, you can request the " +"following URL" +msgstr "כדי לעדכן את כל הפודקאסטים שפרסמת אוטומטית, ניתן לבקש את הכתובת הבאה" + +#: mygpo/publisher/templates/publisher/home.html:69 +msgid "Create a new token" +msgstr "יצירת אסימון חדש" + +#: mygpo/publisher/templates/publisher/info.html:12 +msgid "Publisher Services" +msgstr "שירותי הפצה" + +#: mygpo/publisher/templates/publisher/info.html:18 +#, python-format +msgid "%(sitename)s offers several services for podcast publishers." +msgstr "%(sitename)s מציע מגוון שירותים למפיצי פודקאסטים." + +#: mygpo/publisher/templates/publisher/info.html:21 +#, python-format +msgid "" +"You can place your podcast on the frontpage of %(sitename)s to promote your " +"podcast. Users of the gPodder client will also find your podcast as the " +"first item in the list of example podcast." +msgstr "" +"יש לך אפשרות להציג את הפודקאסט שלך בעמוד הפתיחה של %(sitename)s כדי לקדם את " +"הפודקאסט שלך. המשתמשים בלקוח ה־gPodder גם כן יוכלו למצוא את הפודקאסט שלך " +"בתור הפריט הראשון ברשימת הפודקאסטים לדוגמה." + +#: mygpo/publisher/templates/publisher/info.html:24 +#, python-format +msgid "" +"You can find additional details on the advertisement page." +msgstr "ניתן למצוא פרטים נוספים בעמוד הפרסומות." + +#: mygpo/publisher/templates/publisher/info.html:27 +#, python-format +msgid "" +"On the %(sitename)s Publisher Pages you can find valuable " +"information about the Podcasts published by you." +msgstr "" +"תחת עמודי ההפצה של %(sitename)s ניתן למצוא מידע חשוב בנוגע " +"לפודקאסטים שמופצים על ידיך." + +#: mygpo/publisher/templates/publisher/info.html:30 +#, python-format +msgid "" +"The Publisher Pages are currently in Beta, but if you are publishing a podcast listed on %(sitename)s, feel free to apply by sending a mail with\n" +"
      \n" +"
    • your username on %(sitename)s (register if you don't have one)
    • \n" +"
    • the name and URL of the podcast you are publishing
    • \n" +"
    • an email address that is visible somewhere on the podcast's website (to legitimate you)\n" +"
    \n" +" to stefan@gpodder.net." +msgstr "" +"עמודי ההפצה נמצאים בשלבי ניסוי, אך אם יש לך פודקאסט בהפצתך שרשום תחת %(sitename)s, אפשר להירשם לתכנית על ידי שליחת הודעה בדוא״ל עם\n" +"
      \n" +"
    • שם המשתמש שלך באתר %(sitename)s (עליך להירשם אם עוד אין לך אחד כזה)
    • \n" +"
    • שם כתובת הפודקאסט שמופץ על ידיך
    • \n" +"
    • כתובת דוא״ל שגלויה במקום כלשהו באתר הפודקאסט (כדי לוודא שאכן יש לך קשר ישיר אליו)\n" +"
    \n" +" אל stefan@gpodder.net." + +#: mygpo/publisher/templates/publisher/info.html:39 +#, python-format +msgid "" +"If you already are registered as a publisher, please login." +msgstr "" +"אם כבר נרשמת בתור מפיץ, נא להיכנס." + +#: mygpo/publisher/templates/publisher/info.html:41 +#, python-format +msgid "Link to %(sitename)s" +msgstr "קישור אל %(sitename)s" + +#: mygpo/publisher/templates/publisher/info.html:44 +#, python-format +msgid "" +"If you link to %(sitename)s from your " +"website, you can make it really easy for your visitors to subscribe to your " +"podcast - especially for users of mobile phones." +msgstr "" +"הוספת קישור אל %(sitename)s מהאתר שלך, תקל" +" על המבקרים באתר שלך להירשם לפודקאסט שלך - במיוחד עבור משתמשים בטלפונים " +"ניידים." + +#: mygpo/publisher/templates/publisher/podcast.html:28 +#: mygpo/web/templates/podcast-base.html:44 +msgid "by" +msgstr "מאת" + +#: mygpo/publisher/templates/publisher/podcast.html:34 +#: mygpo/share/templates/share/favorites.html:29 +#: mygpo/web/templates/podcast-base.html:50 +msgid "Feed" +msgstr "הזנה" + +#: mygpo/publisher/templates/publisher/podcast.html:43 +#: mygpo/web/templates/podcast-base.html:65 +msgid "subscribers" +msgstr "מנויים" + +#: mygpo/publisher/templates/publisher/podcast.html:48 +#, python-format +msgid "" +"This is the publisher page of %(ptitle)s. You can see some " +"stats and provide additional data for the podcast page." +msgstr "" +"זה הוא עמוד ההפצה של %(ptitle)s. ניתן לצפות בסטטיסטיקה " +"ולספק נתונים נוספים לעמוד הפודקאסט." + +#: mygpo/publisher/templates/publisher/podcast.html:49 +msgid "Go to Podcast Page" +msgstr "מעבר לעמוד הפודקאסט" + +#: mygpo/publisher/templates/publisher/podcast.html:56 +msgid "The podcast information is regularly retrieved from the podcast feed" +msgstr "פרטי הפודקאסט מתקבלים על פי רוב מהזנת הפודקאסט" + +#: mygpo/publisher/templates/publisher/podcast.html:59 +msgid "Timing" +msgstr "תזמון" + +#: mygpo/publisher/templates/publisher/podcast.html:61 +msgid "Last update:" +msgstr "עדכון אחרון:" + +#: mygpo/publisher/templates/publisher/podcast.html:62 +msgid "Update interval:" +msgstr "מרווח בין עדכונים:" + +#: mygpo/publisher/templates/publisher/podcast.html:63 +msgid "Next update:" +msgstr "העדכון הבא:" + +#: mygpo/publisher/templates/publisher/podcast.html:68 +msgid "Update now" +msgstr "עדכון כעת" + +#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 +msgid "Twitter" +msgstr "טוויטר" + +#: mygpo/publisher/templates/publisher/podcast.html:97 +msgid "Feed Check" +msgstr "בדיקת הזנה" + +#: mygpo/publisher/templates/publisher/podcast.html:105 +msgid "PubSubHubbub" +msgstr "PubSubHubbub" + +#: mygpo/publisher/templates/publisher/podcast.html:114 +#, python-format +msgid "" +"If you publish your podcast feed through a PubSubHubbu hub, " +"%(sitename)s can immediatelly update your podcast when a new episode is " +"released." +msgstr "" +"על ידי פרסום הזנת הפודקאסטים שלך דרך נקודת הריכוז PubSubHubbu, " +"ל־%(sitename)s יש אפשרות לעדכן את הפודקאסט שלך ברגע שפרק חדש מופץ." + +#: mygpo/publisher/templates/publisher/podcast.html:119 +#, python-format +msgid "" +"Your podcast is published through %(hub)s and should" +" update immediatelly for each new episode." +msgstr "" +"הפודקאסט שלך מופץ דרך %(hub)s והוא אמור להתעדכן מיד " +"בכל פרק." + +#: mygpo/publisher/templates/publisher/podcast.html:123 +#, python-format +msgid "" +"Your podcast is published through %(hub)s but our " +"subscription has not yet been verified." +msgstr "" +"הפודקאסט שלך מופץ דרך %(hub)s אך המינוי שלך טרם " +"אומת." + +#: mygpo/publisher/templates/publisher/podcast.html:128 +#, python-format +msgid "" +"We did not find a hub in your podcast feed. Your feed is updated regularly, " +"but there might be some delay until a new episode shows up on %(sitename)s." +msgstr "" +"לא מצאנו נקודת ריכוז להזנת הפודקאסט שלך. ההזנה שלך מתעדכנת באופן סדיר, אך " +"תיתכן השהיה קצרה עד שהפרקים יופיעו ב־%(sitename)s." + +#: mygpo/publisher/templates/publisher/podcast.html:140 +msgid "License Information" +msgstr "פרטי רישיון" + +#: mygpo/publisher/templates/publisher/podcast.html:148 +#, python-format +msgid "" +"You should include license information in your feed so that users and " +"%(sitename)s can know, under which conditions your content can be used." +msgstr "" +"מוטב לכלול פרטי רישיון כחלק מההזנה שלך כדי שהמשתמשים לצד %(sitename)s יוכלו " +"לדעת, תחת אילו תנאים ניתן להשתמש בתוכן שלך." + +#: mygpo/publisher/templates/publisher/podcast.html:152 +#, python-format +msgid "" +"We found the following license in your podcast: %(license)s" +msgstr "" +"מצאנו את הרישיון הבא בפודקאסט שלך: %(license)s" + +#: mygpo/publisher/templates/publisher/podcast.html:156 +msgid "" +"We did not find a license in your podcast feed. Refer to gPodder Podcast Feed Best " +"Practice on how to include license information." +msgstr "" +"לא מצאנו רישיון בהזנת הפודקאסט שלך. יש לפנות אל ההמלצות להזנות פודקאסטים של " +"gPodder על כיצד מוטב להוסיף פרטי רישיון." + +#: mygpo/publisher/templates/publisher/podcast.html:170 +msgid "Link" +msgstr "קישור" + +#: mygpo/publisher/templates/publisher/podcast.html:178 +msgid "Show Group Stats" +msgstr "הצגת סטטיסטיקה קבוצתית" + +#: mygpo/publisher/views.py:141 +msgid "" +"The update has been scheduled. It might take some time until the results are" +" visible." +msgstr "תוזמן עדכון. יכול להיות שיחלוף קצת זמן עד שניתן יהיה לראות תוצאות." + +#: mygpo/publisher/views.py:154 mygpo/users/views/settings.py:98 +msgid "Data updated" +msgstr "נתונים עודכנו" + +#: mygpo/publisher/views.py:165 +msgid "Publisher token updated" +msgstr "אסימון מפרסם עודכן" + +#: mygpo/publisher/views.py:255 +#, python-brace-format +msgid "Removed slug {slug} from {episode}" +msgstr "הוסר השם המופשט {slug} מהפרק {episode}" + +#: mygpo/share/templates/share/components/private-toggle.html:11 +msgid "Public" +msgstr "ציבורי" + +#: mygpo/share/templates/share/components/private-toggle.html:16 +msgid "Private" +msgstr "פרטי" + +#: mygpo/share/templates/share/favorites.html:10 +#: mygpo/share/templates/share/favorites.html:14 +msgid "Share your favorite episodes" +msgstr "שיתוף הפרקים המועדפים עליך" + +#: mygpo/share/templates/share/favorites.html:46 +#: mygpo/share/templates/share/favorites.html:48 +msgid "Directory Entry" +msgstr "רשומה בספרייה" + +#: mygpo/share/templates/share/favorites.html:70 +#, python-format +msgid "" +"To keep your favorites private (from others and from the public pages of " +"%(site)s), you need to use HTTP-Authentication in your client. " +msgstr "" +"כדי לשמור על פרטיות המועדפים שלך (מפני אחרים ומפני העמודים הציבוריים של " +"%(site)s), עליך להשתמש ב־HTTP-Authentication בלקוח שלך." + +#: mygpo/share/templates/share/favorites.html:72 +msgid "Username:" +msgstr "שם משתמש:" + +#: mygpo/share/templates/share/favorites.html:73 +msgid "Password:" +msgstr "ססמה:" + +#: mygpo/share/templates/share/favorites.html:79 +msgid "Remove password" +msgstr "הסרת ססמה" + +#: mygpo/share/templates/share/favorites.html:82 +msgid "Generate new password" +msgstr "יצירת ססמה חדשה" + +#: mygpo/share/templates/share/favorites.html:98 +#, python-format +msgid "" +"You've marked your favorites-feed as public and others can\n" +" subscribe to it. It will also be indexed by %(sitename)s." +msgstr "" +"סימנת את רשימת המועדפים שלך כציבורית ואחרים יכולים\n" +" להירשם אליה. היא גם תופיע באינדקס של %(sitename)s." + +#: mygpo/share/templates/share/favorites.html:110 +msgid "Create password" +msgstr "יצירת ססמה" + +#: mygpo/share/templates/share/overview.html:9 +msgid "Sharing" +msgstr "מתבצע שיתוף" + +#: mygpo/share/templates/share/overview.html:12 +#: mygpo/subscriptions/templates/subscriptions.html:67 +#: mygpo/web/templates/favorites.html:39 +msgid "Share" +msgstr "שיתוף" + +#: mygpo/share/templates/share/overview.html:21 +#: mygpo/web/templates/device.html:19 mygpo/web/templates/privacy.html:25 +#: mygpo/web/templatetags/menu.py:45 mygpo/web/templatetags/menu.py:46 +#: mygpo/web/templatetags/menu.py:57 +msgid "Subscriptions" +msgstr "מינויים" + +#: mygpo/share/templates/share/overview.html:34 +#: mygpo/share/templates/share/overview.html:49 +#: mygpo/share/templates/share/overview.html:76 +msgid "New Token" +msgstr "אסימון חדש" + +#: mygpo/share/templates/share/overview.html:40 +msgid "User Page" +msgstr "דף משתמש" + +#: mygpo/share/templates/share/overview.html:51 +#: mygpo/web/templatetags/menu.py:60 +msgid "Settings" +msgstr "הגדרות" + +#: mygpo/share/templates/share/overview.html:57 +msgid "Favorites Feed" +msgstr "הזנת מועדפים" + +#: mygpo/share/templates/share/overview.html:84 +msgid "" +"Private items are protected by a special token. Only those who know the " +"exact link can access your content" +msgstr "" +"פריטים פרטיים מוגנים באסימון מיוחד. רק אלו שמכירים את הקישור המדויק יוכלו " +"לגשת לתוכן שלך" + +#: mygpo/share/templates/userpage-denied.html:16 +#, python-format +msgid "" +"%(username)s didn't share his user page with you. Maybe you should contact " +"him to get the correct link." +msgstr "" +"עמוד המשתמש של %(username)s לא משותף אתך. אולי עדיף ליצור קשר עם המשתמש כדי " +"לקבל את הקישור הנכון." + +#: mygpo/share/templates/userpage-denied.html:20 +msgid "Want to have your own user page?" +msgstr "מעניין אותך לקבל עמוד משתמש משלך?" + +#: mygpo/share/templates/userpage-denied.html:20 +#, python-format +msgid " Go to your Share Page to get the link." +msgstr "" +" עליך לעבור לשיתוף עמוד כדי לקבל את " +"הקישור." + +#: mygpo/share/templates/userpage.html:24 +#, python-format +msgid "a user on %(site)s" +msgstr "משתמש ב־%(site)s" + +#: mygpo/share/templates/userpage.html:35 +#, python-format +msgid "" +"%(username)s is sharing his favorite podcasts on %(site)s." +msgstr "" +"הפודקאסטים המועדפים של %(username)s משותפים ב־%(site)s." + +#: mygpo/share/templates/userpage.html:47 +#, python-format +msgid "%(subscription_count)s Subscriptions" +msgstr "%(subscription_count)s מינויים" + +#: mygpo/share/templates/userpage.html:52 +msgid "Episodes Listened" +msgstr "פרקים שנוגנו" + +#: mygpo/share/templates/userpage.html:68 +#: mygpo/share/templates/userpage.html:97 +#: mygpo/share/templates/userpage.html:148 +msgid "see all" +msgstr "להציג הכול" + +#: mygpo/share/templates/userpage.html:83 +#, python-format +msgid "%(list_count)s Podcast Lists" +msgstr "%(list_count)s רשימות פודקאסטים" + +#: mygpo/share/templates/userpage.html:110 +#, python-format +msgid "%(num_episodes)s Recently Played Episodes" +msgstr "%(num_episodes)s פרקים שנוגנו לאחרונה" + +#: mygpo/share/templates/userpage.html:131 +#, python-format +msgid "%(num_fav_episodes)s Favorite Episodes" +msgstr "%(num_fav_episodes)s פרקים מועדפים" + +#: mygpo/share/templates/userpage.html:166 +msgid "That's You!" +msgstr "מדובר בך!" + +#: mygpo/share/templates/userpage.html:168 +msgid "Edit your profile" +msgstr "עריכת הפרופיל שלך" + +#: mygpo/share/templates/userpage.html:176 +msgid "Stats" +msgstr "סטטיסטיקה" + +#: mygpo/share/templates/userpage.html:178 +msgid "Total Played:" +msgstr "סך הכול התנגנו:" + +#: mygpo/share/templates/userpage.html:184 +msgid "Played Last Month:" +msgstr "התנגנו בחודש שעבר:" + +#: mygpo/share/templates/userpage.html:190 +msgid "Member Since:" +msgstr "חברות מאז:" + +#: mygpo/share/templates/userpage.html:194 +msgid "the early days" +msgstr "ימי קדם" + +#: mygpo/subscriptions/templates/subscriptions.html:11 +#: mygpo/subscriptions/templates/subscriptions.html:15 +msgid "Podcast Subscriptions" +msgstr "מינויים לפודקאסטים" + +#: mygpo/subscriptions/templates/subscriptions.html:32 +#, python-format +msgid "%(episode_count)s Episodes" +msgstr "%(episode_count)s פרקים" + +#: mygpo/subscriptions/templates/subscriptions.html:42 +#, python-format +msgid "" +"You don't have any subscriptions yet. Set up your podcast clients and discover interesting podcasts." +msgstr "" +"אין לך מינויים עדיין. עליך להגדיר את לקוח " +"הפודקאסטים שלך ואת איתור פודקאסטים " +"מעניינים." + +#: mygpo/subscriptions/templates/subscriptions.html:63 +#: mygpo/suggestions/templates/suggestions.html:54 +#: mygpo/web/templates/device.html:53 +msgid "Download OPML" +msgstr "הורדת OPML" + +#: mygpo/subscriptions/views.py:108 +#, python-format +msgid "%(username)s's Podcast Subscriptions on %(site)s" +msgstr "מינויי הפודקאסטים של %(username)s ב־%(site)s" + +#: mygpo/subscriptions/views.py:112 +#, python-format +msgid "Recent changes to %(username)s's podcast subscriptions on %(site)s" +msgstr "השינויים האחרונים למינויי הפודקאסטים של %(username)s תחת %(site)s" + +#: mygpo/subscriptions/views.py:136 +#, python-format +msgid "%(username)s subscribed to %(podcast)s (%(site)s)" +msgstr "הרשמה אל %(podcast)s מצד %(username)s (%(site)s)" + +#: mygpo/subscriptions/views.py:138 +#, python-format +msgid "%(username)s unsubscribed from %(podcast)s (%(site)s)" +msgstr "ביטול הרשמה אל %(podcast)s מצד %(username)s (%(site)s)" + +#: mygpo/suggestions/templates/suggestions.html:9 +#: mygpo/suggestions/templates/suggestions.html:12 +msgid "Suggested Podcasts" +msgstr "פודקאסטים מומלצים" + +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/podcast.html:59 mygpo/web/templates/subscribe.html:11 +#: mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "הרשמה" + +#: mygpo/suggestions/templates/suggestions.html:36 +msgid "No Interest" +msgstr "אין עניין" + +#: mygpo/suggestions/templates/suggestions.html:47 +msgid "No Suggestions Yet" +msgstr "אין הצעות עדיין" + +#: mygpo/users/models.py:225 +msgid "Desktop" +msgstr "מחשב שולחני" + +#: mygpo/users/models.py:226 +msgid "Laptop" +msgstr "מחשב נייד" + +#: mygpo/users/models.py:227 +msgid "Cell phone" +msgstr "טלפון סלולרי" + +#: mygpo/users/models.py:228 +msgid "Server" +msgstr "שרת" + +#: mygpo/users/models.py:229 +msgid "Tablet" +msgstr "מחשב לוח" + +#: mygpo/users/models.py:230 +msgid "Other" +msgstr "אחר" + +#: mygpo/users/templates/registration/activation_failed.html:8 +msgid "Activation failed" +msgstr "ההפעלה נכשלה" + +#: mygpo/users/templates/registration/activation_failed.html:11 +msgid "Account not activated" +msgstr "החשבון לא הופעל" + +#: mygpo/users/templates/registration/activation_failed.html:16 +msgid "Your account could not be activated." +msgstr "לא ניתן להפעיל את החשבון שלך." + +#: mygpo/users/templates/registration/registration_complete.html:9 +msgid "Registration complete" +msgstr "ההרשמה הושלמה" + +#: mygpo/users/templates/registration/registration_complete.html:13 +msgid "" +"Please confirm your account using the email you should just have received." +msgstr "נא לאמת את החשבון שלך בעזרת ההודעה שקיבלת בדוא״ל." + +#: mygpo/users/templates/registration/registration_form.html:8 +#: mygpo/users/templates/registration/registration_form.html:11 +msgid "Create Account" +msgstr "יצירת חשבון" + +#: mygpo/users/templates/registration/registration_form.html:18 +msgid "You are already registered." +msgstr "כבר נרשמת." + +#: mygpo/users/templates/registration/registration_form.html:72 +#: mygpo/web/templates/base.html:52 mygpo/web/templates/home.html:47 +#: mygpo/web/templates/home.html:103 mygpo/web/templates/login.html:48 +#: mygpo/web/templatetags/menu.py:24 +msgid "Register" +msgstr "הרשמה" + +#: mygpo/users/templates/registration/registration_form.html:87 +msgid "Activation Mail" +msgstr "הודעת הפעלה בדוא״ל" + +#: mygpo/users/templates/registration/registration_form.html:88 +msgid "" +"After registration, you'll receive an activation mail to confirm the " +"validity of your email address." +msgstr "" +"לאחר ההרשמה, תגיע אליך הודעת הפעלה בדוא״ל כדי לאמת את כתובת הדוא״ל שלך." + +#: mygpo/users/templates/registration/registration_form.html:90 +#, python-format +msgid "" +"If it doesn't arrive, you can resend it." +msgstr "" +"אם ההודעה לא מגיעה אליך, ניתן לשלוח " +"אותה מחדש." + +#: mygpo/users/templates/registration/resend_activation.html:4 +#: mygpo/users/templates/registration/resend_activation.html:8 +msgid "Resend activation e-mail" +msgstr "שליחת הודעת הפעלה בדוא״ל מחדש" + +#: mygpo/users/templates/registration/resend_activation.html:18 +#: mygpo/web/templates/restore_password.html:21 +msgid "" +"Please enter either your username or (if you don't know that either) the " +"e-mail address which you used to register your account. An e-mail will be " +"sent to you." +msgstr "" +"נא להקליד את שם משתמש או (או אם הפרט הזה חסר לך) את כתובת הדוא״ל בה השתמשת " +"לטובת רישום לחשבון. תישלח אליך הודעה בדוא״ל." + +#: mygpo/users/templates/registration/resend_activation.html:36 +msgid "Send activation e-mail" +msgstr "שליחת הודעת הפעלה בדוא״ל" + +#: mygpo/users/templates/registration/resent_activation.html:4 +#: mygpo/users/templates/registration/resent_activation.html:7 +msgid "Sent Activation Email" +msgstr "נשלחה הודעה הפעלה בדוא״ל" + +#: mygpo/users/templates/registration/resent_activation.html:11 +msgid "The activation email has been reset." +msgstr "הודעת האימות נשלחה בדוא״ל מחדש." + +#: mygpo/users/views/device.py:80 mygpo/users/views/device.py:170 +msgid "Synchronize with the following devices" +msgstr "סנכרון עם המכשירים הבאים" + +#: mygpo/users/views/device.py:98 +msgid "Please fill out all fields." +msgstr "נא למלא את כל השדות." + +#: mygpo/users/views/device.py:110 +msgid "Device saved" +msgstr "המכשיר נשמר" + +#: mygpo/users/views/device.py:117 mygpo/users/views/device.py:148 +msgid "You can't use the same Device ID for two devices." +msgstr " ניתן להשתמש באותו מזהה המכשיר על שני מכשירים." + +#: mygpo/users/views/device.py:141 +msgid "Device updated" +msgstr "מכשיר עודכן" + +#: mygpo/users/views/device.py:194 +#, python-brace-format +msgid "Could not upload subscriptions: {err}" +msgstr "לא ניתן להעלות מינויים: {err}" + +#: mygpo/users/views/device.py:292 +msgid "Your subscription will be updated in a moment." +msgstr "המינוי שלך יתעדכן בעוד רגע קט." + +#: mygpo/users/views/registration.py:87 +msgid "Username or email address already in use" +msgstr "שם המשתמש או כתובת הדוא״ל כבר נמצאים בשימוש" + +#: mygpo/users/views/registration.py:152 +msgid "The activation link is either not valid or has already expired." +msgstr "קישור ההפעלה שגוי או שתוקפו פג." + +#: mygpo/users/views/registration.py:157 +msgid "Your user has been activated. You can log in now." +msgstr "המשתמש שלך הופעל. כעת יתאפשר לך להיכנס." + +#: mygpo/users/views/registration.py:174 +msgid "Either username or email address are required." +msgstr "נדרשים שם משתמש או כתובת דוא״ל." + +#: mygpo/users/views/registration.py:194 mygpo/users/views/user.py:129 +msgid "User does not exist." +msgstr "משתמש לא קיים." + +#: mygpo/users/views/registration.py:198 +msgid "Your account already has been activated. Go ahead and log in." +msgstr "החשבון שלך כבר הופעל. אפשר לנסות להיכנס לחשבון." + +#: mygpo/users/views/settings.py:57 mygpo/users/views/settings.py:92 +msgid "Oops! Something went wrong. Please double-check the data you entered." +msgstr "אופס! משהו השתבש. נא לבדוק שנית את המידע שהקלדת." + +#: mygpo/users/views/settings.py:110 +msgid "Your account has been disconnected" +msgstr "חשבונך נותק" + +#: mygpo/users/views/user.py:71 +msgid "Username missing" +msgstr "חסר שם משתמש" + +#: mygpo/users/views/user.py:76 +msgid "Password missing" +msgstr "חסרה ססמה" + +#: mygpo/users/views/user.py:83 +msgid "Wrong username or password." +msgstr "שם משתמש או ססמה שגויים." + +#: mygpo/users/views/user.py:89 mygpo/users/views/user.py:134 +msgid "" +"Please activate your account first. We have just re-sent your activation " +"email" +msgstr "" +"נא להפעיל את החשבון שלך תחילה. הרגע שלחנו לך את הודעת ההפעלה בדוא״ל מחדש" + +#: mygpo/users/views/user.py:167 mygpo/users/views/user.py:172 +msgid "Login failed." +msgstr "הכניסה נכשלה." + +#: mygpo/users/views/user.py:180 +msgid "Login with Google is currently not possible." +msgstr "הכניסה עם Google אינה אפשרית כרגע." + +#: mygpo/users/views/user.py:190 +#, python-brace-format +msgid "" +"Your account has been connected with {google}. Open Settings to change this." +msgstr "החשבון שלך התחבר עם {google}. ניתן לפתוח את ההגדרות כדי לשנות את זה." + +#: mygpo/users/views/user.py:202 +#, python-format +msgid "" +"No account connected with your Google account %s. Please log in to connect." +msgstr "אף חשבון לא התחבר לחשבון שלך ב־Google %s. נא להיכנס כדי להתחבר." + +#: mygpo/web/forms.py:20 mygpo/web/forms.py:184 +msgid "E-Mail address" +msgstr "כתובת דוא״ל" + +#: mygpo/web/forms.py:27 +msgid "Current password" +msgstr "ססמה נוכחית" + +#: mygpo/web/forms.py:34 +msgid "New password" +msgstr "ססמה חדשה" + +#: mygpo/web/forms.py:41 +msgid "Confirm password" +msgstr "אימות ססמה" + +#: mygpo/web/forms.py:78 +msgid "A few words about you" +msgstr "כמה מילים עליך" + +#: mygpo/web/forms.py:91 mygpo/web/templates/devicelist.html:23 +msgid "Name" +msgstr "שם" + +#: mygpo/web/forms.py:96 mygpo/web/templates/devicelist.html:24 +msgid "Type" +msgstr "סוג" + +#: mygpo/web/forms.py:100 mygpo/web/templates/devicelist.html:25 +msgid "Device ID" +msgstr "מזהה מכשיר" + +#: mygpo/web/forms.py:103 +msgid "ID on device" +msgstr "מזהה על המכשיר" + +#: mygpo/web/forms.py:115 +msgid "Share this subscription with other users (public)" +msgstr "שיתוף המינוי הזה עם משתמשים אחרים (ציבורי)" + +#: mygpo/web/forms.py:158 +msgid "No device selected" +msgstr "לא נבחר מכשיר" + +#: mygpo/web/forms.py:167 +msgid "Please enter your username" +msgstr "נא להקליד את שם המשתמש שלך" + +#: mygpo/web/forms.py:172 +msgid "or the email address used while registering" +msgstr "או את כתובת הדוא״ל בה השתמשת בעת ההרשמה" + +#: mygpo/web/templates/400.html:4 mygpo/web/templates/400.html:7 +msgid "Bad request" +msgstr "בקשה שגויה" + +#: mygpo/web/templates/400.html:11 +msgid "There has been an error processing your request." +msgstr "אירעה שגיאה בעת עיבוד הבקשה שלך." + +#: mygpo/web/templates/401.html:4 mygpo/web/templates/401.html:7 +msgid "Unauthorized" +msgstr "אין הרשאה" + +#: mygpo/web/templates/401.html:12 +msgid "This page is only available to registered users." +msgstr "עמוד זה זמין ללקוחות רשומים בלבד." + +#: mygpo/web/templates/account.html:8 mygpo/web/templates/account.html:11 +msgid "Account Settings" +msgstr "הגדרות חשבון" + +#: mygpo/web/templates/account.html:73 mygpo/web/templates/account.html:76 +#: mygpo/web/templates/delete_account.html:9 +msgid "Delete Account" +msgstr "מחיקת חשבון" + +#: mygpo/web/templates/account.html:87 +msgid "Google" +msgstr "Google" + +#: mygpo/web/templates/account.html:90 +#, python-format +msgid "Connected with %(gmail)s" +msgstr "מחובר עם %(gmail)s" + +#: mygpo/web/templates/account.html:93 +msgid "Disconnect" +msgstr "ניתוק" + +#: mygpo/web/templates/account.html:96 +msgid "Connect" +msgstr "חיבור" + +#: mygpo/web/templates/base.html:40 mygpo/web/templatetags/menu.py:61 +msgid "Account" +msgstr "חשבון" + +#: mygpo/web/templates/base.html:46 mygpo/web/templates/base.html:50 +#: mygpo/web/templates/home.html:41 mygpo/web/templates/home.html:45 +#: mygpo/web/templates/home.html:102 mygpo/web/templates/login.html:8 +#: mygpo/web/templates/login.html:11 mygpo/web/templates/login.html:46 +#: mygpo/web/templates/restore_password.html:8 +#: mygpo/web/templatetags/menu.py:23 +msgid "Login" +msgstr "כניסה" + +#: mygpo/web/templates/base.html:51 mygpo/web/templates/home.html:46 +#: mygpo/web/templates/login.html:47 +msgid "Login with Google" +msgstr "כניסה עם Google" + +#: mygpo/web/templates/base.html:133 mygpo/web/templates/home.html:153 +#: mygpo/web/templatetags/menu.py:31 +msgid "Discover" +msgstr "עיון" + +#: mygpo/web/templates/base.html:134 mygpo/web/templates/home.html:154 +#: mygpo/web/templatetags/menu.py:32 +msgid "Directory" +msgstr "ספרייה" + +#: mygpo/web/templates/base.html:142 mygpo/web/templates/home.html:162 +msgid "Support" +msgstr "תמיכה" + +#: mygpo/web/templates/base.html:143 mygpo/web/templates/home.html:163 +#: mygpo/web/templatetags/menu.py:25 +msgid "Docs" +msgstr "מסמכים" + +#: mygpo/web/templates/base.html:144 mygpo/web/templates/home.html:164 +msgid "Mailing List" +msgstr "קבוצת דיונים" + +#: mygpo/web/templates/base.html:145 mygpo/web/templates/home.html:165 +msgid "Questions" +msgstr "שאלות" + +#: mygpo/web/templates/base.html:151 mygpo/web/templates/home.html:171 +msgid "Support Us" +msgstr "להביע תמיכה בנו" + +#: mygpo/web/templates/base.html:152 mygpo/web/templates/contribute.html:22 +#: mygpo/web/templates/home.html:172 +msgid "Donate" +msgstr "תרומה" + +#: mygpo/web/templates/base.html:159 mygpo/web/templates/home.html:179 +msgid "Follow" +msgstr "לעקוב" + +#: mygpo/web/templates/base.html:161 mygpo/web/templates/home.html:181 +msgid "Blog" +msgstr "בלוג" + +#: mygpo/web/templates/base.html:162 mygpo/web/templates/home.html:182 +msgid "Blog (RSS)" +msgstr "בלוג (RSS)" + +#: mygpo/web/templates/base.html:168 mygpo/web/templates/home.html:188 +msgid "Develop" +msgstr "פיתוח" + +#: mygpo/web/templates/base.html:169 mygpo/web/templates/home.html:189 +msgid "API" +msgstr "API" + +#: mygpo/web/templates/base.html:170 mygpo/web/templates/home.html:190 +msgid "Libraries" +msgstr "ספריות" + +#: mygpo/web/templates/base.html:171 mygpo/web/templates/home.html:191 +msgid "Clients" +msgstr "לקוחות" + +#: mygpo/web/templates/base.html:177 mygpo/web/templates/home.html:197 +#: mygpo/web/templatetags/menu.py:64 +msgid "Publish" +msgstr "פרסום" + +#: mygpo/web/templates/base.html:178 mygpo/web/templates/home.html:198 +msgid "Get Access" +msgstr "קבלת גישה" + +#: mygpo/web/templates/base.html:179 mygpo/web/templates/home.html:199 +msgid "Link To Us" +msgstr "קישור אלינו" + +#: mygpo/web/templates/base.html:188 mygpo/web/templates/home.html:207 +msgid "hosting provided by prgmr.com" +msgstr "האירוח סופק על ידי prgmr.com" + +#: mygpo/web/templates/contribute.html:8 mygpo/web/templatetags/menu.py:26 +msgid "Contribute" +msgstr "תרומה" + +#: mygpo/web/templates/contribute.html:11 +msgid "Contribute to gpodder.net" +msgstr "תרומה ל־gpodder.net" + +#: mygpo/web/templates/contribute.html:16 +msgid "" +"gpodder.net is run as a hobby project without continuous funding for " +"servers, storage and bandwidth. We rely on contributors and donations to " +"keep the site running and improve it constantly." +msgstr "" +"gpodder.net מופעל כמיזם תחביב ללא מקור מימון מתחדש לשרתים, לאחסון ולתעבורה. " +"אנו סומכים על מתנדבים ותרומות כדי להשאיר את האתר פעיל ולשפר אותו שלב אחר " +"שלב." + +#: mygpo/web/templates/contribute.html:18 +msgid "Work" +msgstr "עבודה" + +#: mygpo/web/templates/contribute.html:19 +msgid "" +"If you want to contribute to gpodder.net by writing code, check out the Development page. We also appreciate contributions " +"of non-coding work, such as web and interface design, server operations, " +"testing, etc. If you are interested, join the mailing list " +"or the IRC channel #gpodder on chat.freenode.net." +msgstr "" +"אם מעניין אותך להתנדב לטובת gpodder.net עם כתיבת קוד, כדאי לבקר בעמוד פיתוח. אנו גם מעריכים צורות התנדבות שאינן בצורת " +"קוד, כגון עיצוב האתר, פעולות בשרת, בדיקות וכו׳. אם כל זה מעניין אותך, " +"באפשרותך להצטרף לרשימת הדיונים או לערוץ ה־IRC בשם ‎#gpodder תחת " +"chat.freenode.net." + +#: mygpo/web/templates/contribute.html:23 +msgid "" +"If you want to support gpodder.net financially, you can donate via PayPal to" +" stefan@skoegl.net. You can also send a book via Amazon (DE, US or UK)." +msgstr "" +"אם ברצונך לתמוך ב־gpodder.net כלכלית, ניתן לתרום דרך PayPal לטובת " +"stefan@skoegl.net. ניתן גם לשלוח ספר דרך Amazon (DE, US או UK)." + +#: mygpo/web/templates/csrf.html:8 +msgid "Attention!" +msgstr "נא לשים לב!" + +#: mygpo/web/templates/csrf.html:11 +msgid "Attention, Attention!" +msgstr "לשים לב בבקשה!" + +#: mygpo/web/templates/csrf.html:17 +#, python-format +msgid "" +"It seems that %(referer)s has linked to %(site)s to get you to change some " +"data. This will possibly change some of your data / " +"settings!. Do you really want to continue? If in doubt, " +"chose No." +msgstr "" +"נראה כי %(referer)s קושר אל %(site)s כדי לנסות לשכנע אותך לשנות נתונים. " +"מצב כזה עשוי לגרום לך לשנות חלק מהנתונים / הגדרות שלך!. " +"להמשיך? במקרה של ספק עדיף לבחור בלא." + +#: mygpo/web/templates/csrf.html:24 +msgid "Yes" +msgstr "כן" + +#: mygpo/web/templates/csrf.html:25 +msgid "No" +msgstr "לא" + +#: mygpo/web/templates/dashboard.html:14 mygpo/web/templatetags/menu.py:54 +msgid "Overview" +msgstr "סקירה" + +#: mygpo/web/templates/dashboard.html:17 +msgid "Hi, " +msgstr "היי," + +#: mygpo/web/templates/dashboard.html:24 +msgid "Newest Episodes" +msgstr "הפרקים החדשים ביותר" + +#: mygpo/web/templates/dashboard.html:39 +#, python-format +msgid "" +"Welcome to %(site)s! If this is your first visit, you should set up your podcast" +" client and try to check as many Explore boxes as you can." +msgstr "" +"ברוך בואך אל %(site)s! אם זה הביקור הראשון שלך, כדאי לך להגדיר את לקוח " +"הפודקאסטים שלך ולנסות לחקור כמה שיותר תיבות סיור שאפשר." + +#: mygpo/web/templates/dashboard.html:44 +#, python-format +msgid "" +"If you have problems, have a look at the docs or " +"ask questions on the mailing list or forum." +msgstr "" +"במקרה של תקלות, מוטב לעיין במסמכים או לשאול שאלות " +"ברשימת " +"הדיונים או בפורום." + +#: mygpo/web/templates/dashboard.html:81 +#, python-format +msgid "Explore %(site)s" +msgstr "סיור ב־%(site)s" + +#: mygpo/web/templates/dashboard.html:85 +#, python-format +msgid "Sign up to %(site)s" +msgstr "הרשמה ל־%(site)s" + +#: mygpo/web/templates/dashboard.html:90 +msgid "Connect your Podcast Clients" +msgstr "חיבור לקוחות הפודקאסטים שלך" + +#: mygpo/web/templates/dashboard.html:95 +msgid "Subscribe to Podcasts" +msgstr "רישום לפודקאסטים" + +#: mygpo/web/templates/dashboard.html:100 +msgid "Mark your Favorite Episodes" +msgstr "סימון הפרקים המועדפים עליך" + +#: mygpo/web/templates/dashboard.html:105 +msgid "Share your Subscriptions" +msgstr "שיתוף המינויים שלך" + +#: mygpo/web/templates/dashboard.html:110 +msgid "Share your Favorite Episodes" +msgstr "שיתוף הפרקים המועדפים עליך" + +#: mygpo/web/templates/dashboard.html:115 +msgid "Share your Userpage" +msgstr "שיתוף עמוד המשתמש שלך" + +#: mygpo/web/templates/dashboard.html:120 +msgid "Tag Podcasts" +msgstr "תיוג פודקאסטים" + +#: mygpo/web/templates/dashboard.html:125 +msgid "Create Podcast Lists" +msgstr "יצירת רשימות פודקאסטים" + +#: mygpo/web/templates/dashboard.html:130 +msgid "Publish your own Podcast" +msgstr "הפצת פודקאסט משלך" + +#: mygpo/web/templates/dashboard.html:140 +msgid "Subscribe in Your Browser" +msgstr "רישום בדפדפן שלך" + +#: mygpo/web/templates/dashboard.html:142 +#, python-format +msgid "" +"Register %(site.domain)s as a feed reader, and subscribe to podcasts " +"directly from your browser" +msgstr "" +"ניתן לרשום את %(site.domain)s כקורא הזנות ולהירשם לפודקאסטים ישירות מהדפדפן " +"שלך." + +#: mygpo/web/templates/dashboard.html:145 +msgid "Install" +msgstr "התקנה" + +#: mygpo/web/templates/delete_account.html:14 +msgid "Delete your Account?" +msgstr "למחוק את החשבון שלך?" + +#: mygpo/web/templates/delete_account.html:20 +msgid "Do you really want to delete your account?" +msgstr "האם באמת רצונך הוא למחוק את החשבון שלך?" + +#: mygpo/web/templates/delete_account.html:23 +msgid "Yes, please" +msgstr "כן, בבקשה" + +#: mygpo/web/templates/deleted_account.html:9 +msgid "Account Deleted" +msgstr "החשבון נמחק" + +#: mygpo/web/templates/deleted_account.html:13 +msgid "Your account has been deleted" +msgstr "חשבונך נמחק" + +#: mygpo/web/templates/deleted_account.html:18 +msgid "Thanks" +msgstr "תודות" + +#: mygpo/web/templates/developer.html:8 mygpo/web/templates/developer.html:11 +#: mygpo/web/templatetags/menu.py:27 +msgid "Development" +msgstr "פיתוח" + +#: mygpo/web/templates/developer.html:17 +msgid "Webservice" +msgstr "שירות מקוון" + +#: mygpo/web/templates/developer.html:18 +msgid "" +"The sourcecode of the webservice gpodder.net is released as open source " +"under the AGPLv3 and hosted at " +"GitHub. Bugs can be reported at the gPodder " +"Bugtracker." +msgstr "" +"קוד המקור של השירות המקוון gpodder.net מופץ לקהל הרחב כקוד פתוח תחת הרישיון " +"AGPLv3 והוא מתארח ב־GitHub." +" ניתן לדווח על תקלות בעוקב " +"המשימות של gPodder." + +#: mygpo/web/templates/developer.html:21 +msgid "Integrating Clients" +msgstr "שילוב לקוחות" + +#: mygpo/web/templates/developer.html:22 +msgid "" +"If you want to integrate gpodder.net in some podcasting client, you might " +"want to use one of the existing client" +" libraries." +msgstr "" +"אם ברצונך לשלב את gpodder.net בלקוח פודקאסטים כלשהו, יכול להיות שעדיף לך " +"להשתמש באחת מספריות" +" הלקוח הקיימות." + +#: mygpo/web/templates/developer.html:23 +msgid "" +"There are already several clients for different platforms which can be used " +"as examples. See " +"list of clients." +msgstr "" +"כבר ישנם מגוון לקוחות לפלטפורמות שונות בהם ניתן להשתמש כדוגמאות. הצגת " +"רשימת הלקוחות." + +#: mygpo/web/templates/device-edit.html:11 mygpo/web/templates/device.html:11 +#, python-format +msgid "Device %(devicename)s" +msgstr "מכשיר %(devicename)s" + +#: mygpo/web/templates/device-edit.html:22 mygpo/web/templates/device.html:18 +msgid "This device was deleted." +msgstr "מכשיר זה נמחק." + +#: mygpo/web/templates/device-edit.html:61 +msgid "Replace Subscriptions" +msgstr "החלפת מינויים" + +#: mygpo/web/templates/device-edit.html:65 +msgid "Replace your current subscriptions by uploading an OPML file." +msgstr "ניתן להחליף את המינויים הנוכחיים שלך על ידי העלאת קובץ OPML." + +#: mygpo/web/templates/device-edit.html:70 +msgid "Upload" +msgstr "העלאה" + +#: mygpo/web/templates/device-edit.html:83 +msgid "Delete Device" +msgstr "מחיקת מכשיר" + +#: mygpo/web/templates/device-edit.html:99 +#: mygpo/web/templates/device-edit.html:117 +#: mygpo/web/templates/device.html:102 mygpo/web/templates/device.html:120 +msgid "Synchronize" +msgstr "סנכרון" + +#: mygpo/web/templates/device-edit.html:100 +#: mygpo/web/templates/device.html:103 +msgid "" +"If you synchronize devices, they will always have the same subscriptions. A " +"podcast that is subscribed on one device, will automatically be added to all" +" synchronized devices." +msgstr "" +"סמקרה של סנכרון מכשירים, תמיד יהיו להם את אותם המינויים. פודקאסט אליו נרשמת " +"במכשיר אחד יתווסף אוטומטית לכל המכשירים המסונכרנים." + +#: mygpo/web/templates/device-edit.html:104 +#: mygpo/web/templates/device.html:107 +#, python-format +msgid "%(devicename)s is currently not synchronized with other devices." +msgstr "%(devicename)s לא מסונכרן כרגע עם מכשירים אחרים." + +#: mygpo/web/templates/device-edit.html:108 +#: mygpo/web/templates/device.html:111 +#, python-format +msgid "%(devicename)s is currently synchronized with %(synclist)s." +msgstr "%(devicename)s מסונכרן כעת עם %(synclist)s." + +#: mygpo/web/templates/device-edit.html:109 +#: mygpo/web/templates/device.html:112 +#, python-format +msgid "Stop synchronisation for %(devicename)s " +msgstr "עצירת סנכרון עבור %(devicename)s" + +#: mygpo/web/templates/device.html:31 mygpo/web/templates/podcast.html:67 +msgid "Unsubscribe" +msgstr "ביטול הרשמה" + +#: mygpo/web/templates/device.html:40 +msgid "You don't have any podcasts subscribed on this device." +msgstr "לא נרשמת לאף פודקאסט במכשיר הזה." + +#: mygpo/web/templates/device.html:63 +msgid "OPML for Nokia Podcasting on Symbian " +msgstr "OPML לפודקאסטים של נוקיה על סימביאן" + +#: mygpo/web/templates/device.html:73 +#: mygpo/web/templates/episode-history.html:46 +#: mygpo/web/templates/episode-history.html:80 +#: mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "היסטוריה" + +#: mygpo/web/templates/device.html:79 +msgid "Trigger Sync" +msgstr "הפעלת סנכרון" + +#: mygpo/web/templates/device.html:87 mygpo/web/templates/devicelist.html:26 +#: mygpo/web/templates/devicelist.html:45 +msgid "Configure" +msgstr "הגדרה" + +#: mygpo/web/templates/devicelist.html:10 +#: mygpo/web/templates/devicelist.html:13 +msgid "Managed Devices" +msgstr "מכשירים מנוהלים" + +#: mygpo/web/templates/devicelist.html:31 +msgid "Synchronized" +msgstr "מסונכרן" + +#: mygpo/web/templates/devicelist.html:33 +msgid "Not Synchronized" +msgstr "לא מסונכרן" + +#: mygpo/web/templates/devicelist.html:53 +msgid "" +"You don't have any devices yet. Go to the clients" +" page to learn how to set up your client applications." +msgstr "" +"לא מוגדרים עבורך מכשירים עדיין. נא לעבור לעמוד הלקוחות" +" כדי ללמוד איך להגדיר את יישומי הלקוח שלך." + +#: mygpo/web/templates/devicelist.html:74 +msgid "Deleted Devices" +msgstr "מכשירים שנמחקו" + +#: mygpo/web/templates/devicelist.html:85 +msgid "Reactivate" +msgstr "הפעלה מחדש" + +#: mygpo/web/templates/devicelist.html:93 +msgid "Delete Permanently" +msgstr "מחיקה לצמיתות" + +#: mygpo/web/templates/episode-history.html:83 +msgid "Time" +msgstr "זמן" + +#: mygpo/web/templates/episode-history.html:84 +msgid "Action" +msgstr "פעולה" + +#: mygpo/web/templates/episode-history.html:85 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "מכשיר" + +#: mygpo/web/templates/episode-history.html:126 +msgid "Add" +msgstr "הוספה" + +#: mygpo/web/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "הסרת מועדף" + +#: mygpo/web/templates/episode.html:95 +msgid "Favorite" +msgstr "הוספה למועדפים" + +#: mygpo/web/templates/episode.html:103 +msgid "Episode History" +msgstr "היסטוריית פרקים" + +#: mygpo/web/templates/favorites.html:10 mygpo/web/templates/favorites.html:13 +#: mygpo/web/templatetags/menu.py:47 mygpo/web/templatetags/menu.py:55 +msgid "Favorite Episodes" +msgstr "פרקים מועדפים" + +#: mygpo/web/templates/login.html:15 +msgid "You need to login to access this page." +msgstr "עליך להיכנס כדי לגשת לעמוד הזה." + +#: mygpo/web/templates/login.html:40 +msgid "Forgot your password?" +msgstr "שכחת את הססמה שלך?" + +#: mygpo/web/templates/maintenance.html:8 +#: mygpo/web/templates/maintenance.html:11 +msgid "Maintenance" +msgstr "תחזוקה" + +#: mygpo/web/templates/maintenance.html:15 +msgid "" +"We are currently doing some work on gpodder.net but we should back online " +"within a few minutes. Just wait a bit and try again!" +msgstr "" +"אנו מבצעים עבודות על gpodder.net אך אנו צפויים לחזור בעוד מספר דקות. עליך " +"פשוט לחכות מעט ולנסות שוב!" + +#: mygpo/web/templates/mytags.html:11 mygpo/web/templates/mytags.html:14 +#: mygpo/web/templatetags/menu.py:48 +msgid "My Tags" +msgstr "התגיות שלי" + +#: mygpo/web/templates/mytags.html:41 +#, python-format +msgid "" +"You didn't tag any podcasts yet. Go to your subscriptions and tag some." +msgstr "" +"לא תייגת אף פודקאסט עדיין. יש לגשת אל המינויים שלך ולתייג כמה מהם." + +#: mygpo/web/templates/password_reset.html:4 +msgid "Password reset" +msgstr "איפוס ססמה" + +#: mygpo/web/templates/password_reset.html:7 +msgid "Your password has been reset" +msgstr "הססמה שלך עברה איפוס" + +#: mygpo/web/templates/password_reset.html:13 +#, python-format +msgid "" +"You should have received an mail with your new password. Please log in now." +msgstr "" +"אמורה הייתה להגיע אליך הודעה עם הססמה החדשה שלך. נא להיכנס כעת." + +#: mygpo/web/templates/password_reset_failed.html:4 +msgid "Password could not be reset" +msgstr "לא ניתן לאפס את הססמה" + +#: mygpo/web/templates/password_reset_failed.html:7 +msgid "Your password could not be reset" +msgstr "לא ניתן לאפס את הססמה שלך" + +#: mygpo/web/templates/password_reset_failed.html:12 +msgid "Unfortunately we were not able to reset your password." +msgstr "לרוע המזל, לא הצלחנו לאפס לך את הססמה." + +#: mygpo/web/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "אין היסטוריה עדיין" + +#: mygpo/web/templates/podcast.html:48 +msgid "Login to Subscribe" +msgstr "יש להיכנס כדי להירשם" + +#: mygpo/web/templates/podcast.html:78 +msgid "Subscribe on all devices" +msgstr "הרשמה בכל המכשירים" + +#: mygpo/web/templates/podcast.html:110 +msgid "Unsubscribe from all devices " +msgstr "ביטול ההרשמה בכל המכשירים" + +#: mygpo/web/templates/podcast.html:149 mygpo/web/templates/podcast.html:164 +msgid "Tags" +msgstr "תגיות" + +#: mygpo/web/templates/podcast.html:199 +msgid "Older Episodes" +msgstr "פרקים ישנים יותר" + +#: mygpo/web/templates/privacy.html:9 mygpo/web/templates/privacy.html:12 +msgid "Privacy Settings" +msgstr "הגדרות פרטיות" + +#: mygpo/web/templates/privacy.html:18 +#, python-format +msgid "%(domain)s distinguishes between public and private subscriptions." +msgstr "ב־%(domain)s קיימת הבדלה בין מינויים ציבוריים לפרטיים." + +#: mygpo/web/templates/privacy.html:20 +msgid "" +"Public subscriptions are included in your shared podcasts and our anonymized public statistics." +msgstr "" +"מינויים ציבוריים נכללים בפודקאסטים " +"המשותפים שלך ובסטטיסטיקה הציבורית האלמונית שלנו." + +#: mygpo/web/templates/privacy.html:21 +msgid "" +"Private subscriptions do neither show up in your list of " +"shared podcasts, nor are considered in our statistics." +msgstr "" +"מינויים פרטיים אינם מופיעים ברשימת הפודקאסטים המשותפים שלך," +" או בסטטיסטיקות שלנו." + +#: mygpo/web/templates/privacy.html:29 +msgid "Default for new subscriptions" +msgstr "בררת מחדל למינויים חדשים" + +#: mygpo/web/templates/privacy.html:68 +msgid "Public Subscriptions" +msgstr "מינויים ציבוריים" + +#: mygpo/web/templates/privacy.html:79 +msgid "Make Private" +msgstr "הסתרה מהציבור" + +#: mygpo/web/templates/privacy.html:90 +msgid "Private Subscriptions" +msgstr "מינויים פרטיים" + +#: mygpo/web/templates/privacy.html:101 +msgid "Make Public" +msgstr "חשיפה לציבור" + +#: mygpo/web/templates/privacy_policy.html:8 mygpo/web/templatetags/menu.py:28 +msgid "Privacy Policy" +msgstr "מדיניות פרטיות" + +#: mygpo/web/templates/restore_password.html:29 +msgid "Reset Password" +msgstr "איפוס ססמה" + +#: mygpo/web/templates/subscribe.html:7 +#, python-format +msgid "Subscribe to %(podcasttitle)s" +msgstr "הרשמה אל %(podcasttitle)s" + +#: mygpo/web/templates/subscribe.html:41 +msgid "" +"You can't subscribe to this podcast, because you don't have any devices (on " +"which you don't have subscribed to the podcast already." +msgstr "" +"אין לך אפשרות להירשום לפודקאסט הזה כיוון שאין לך מכשירים (שבהם לא נרשמת " +"עדיין לפודקאסט)." + +#: mygpo/web/templates/subscribe.html:43 +msgid "Create Device" +msgstr "יצירת התקן" + +#: mygpo/web/templates/subscribe.html:49 +msgid "Why Unnamed Podcast?" +msgstr "למה פודקאסט ללא שם?" + +#: mygpo/web/templates/subscribe.html:49 +msgid "" +"Because we display names after we have fetched the information form the feed" +" -- and this may take some time. Until this is completed, the podcast will " +"simply be called this way." +msgstr "" +"כיוון שאנו מציגים שמות לאחר אחזור המידע מההזנה -- פעולה שעשויה לארוך זמן מה." +" עד להשלמת פעולה זו, הפודקאסט פשוט ייקרא כך." + +#: mygpo/web/templates/user_subscriptions.html:14 +#: mygpo/web/templates/user_subscriptions.html:18 +#: mygpo/web/templates/user_subscriptions_denied.html:10 +#: mygpo/web/templates/user_subscriptions_denied.html:14 +#, python-format +msgid "%(username)s's Subscriptions" +msgstr "המינויים של %(username)s" + +#: mygpo/web/templates/user_subscriptions.html:21 +#, python-format +msgid "" +"%(username)s has %(num_subscriptions)s " +"subscriptions" +msgstr "" +"ל־%(username)s יש %(num_subscriptions)s " +"מינויים" + +#: mygpo/web/templates/user_subscriptions.html:42 +msgid "Download Subscriptions as OPML" +msgstr "הורדת המינויים כ־OPML" + +#: mygpo/web/templates/user_subscriptions.html:45 +msgid "Subscribe to Changes" +msgstr "רישום לשינויים" + +#: mygpo/web/templates/user_subscriptions.html:51 +#, python-format +msgid "%(username)s doesn't have any subscriptions yet." +msgstr "ל־%(username)s אין מינויים עדיין." + +#: mygpo/web/templates/user_subscriptions.html:61 +msgid "Share Your Subscriptions" +msgstr "שיתוף המינויים שלך" + +#: mygpo/web/templates/user_subscriptions.html:62 +msgid "Want to share your own subscriptions?" +msgstr "מעניין אותך לשתף את המינויים שלך?" + +#: mygpo/web/templates/user_subscriptions.html:71 +msgid "Nokia Podcasting" +msgstr "פודקאסטים של נוקיה" + +#: mygpo/web/templates/user_subscriptions.html:72 +msgid "" +"Add &symbian=true#.opml to the OPML URL to get an OPML file for" +" Nokia Podcasting on Symbian devices." +msgstr "" +"יש להוסיף &symbian=true#.opml לכתובת ה־OPML כדי לקבל קובץ OPML " +"עבור פודקאסטים של נוקיה על מכשירי סימביאן." + +#: mygpo/web/templates/user_subscriptions_denied.html:20 +#, python-format +msgid "" +"%(username)s didn't share his subscriptions with you. Maybe you should " +"contact him to get the correct link." +msgstr "" +"המינויים של %(username)s לא שותפו אתך. אולי עדיף ליצור קשר עם המשתמש כדי " +"לקבל את הקישור הנכון." + +#: mygpo/web/templates/user_subscriptions_denied.html:23 +msgid "Want to share your subscriptions?" +msgstr "מעניין אותך לשתף את המינויים שלך?" + +#: mygpo/web/templates/user_subscriptions_denied.html:23 +msgid "" +"Just go to your account settings to get the " +"link." +msgstr "" +"עליך פשוט לגשת אל הגדרות החשבון כדי לקבל את " +"הקישור." + +#: mygpo/web/templatetags/devices.py:31 +msgid "Unknown" +msgstr "לא ידוע" + +#: mygpo/web/templatetags/episodes.py:20 +msgid "New episode" +msgstr "פרק חדש" + +#: mygpo/web/templatetags/episodes.py:23 +#, python-format +msgid "Downloaded to %s" +msgstr "התקבל אל %s" + +#: mygpo/web/templatetags/episodes.py:25 +msgid "Downloaded" +msgstr "התקבל" + +#: mygpo/web/templatetags/episodes.py:28 +#, python-format +msgid "Played on %s" +msgstr "התנגן ב־%s" + +#: mygpo/web/templatetags/episodes.py:30 +msgid "Played" +msgstr "התנגן" + +#: mygpo/web/templatetags/episodes.py:33 +#, python-format +msgid "Deleted on %s" +msgstr "נמחק ב־%s" + +#: mygpo/web/templatetags/episodes.py:35 +msgid "Deleted" +msgstr "נמחק" + +#: mygpo/web/templatetags/episodes.py:37 +msgid "Unknown status" +msgstr "מצב לא ידוע" + +#: mygpo/web/templatetags/episodes.py:43 +msgid "Unplayed episode" +msgstr "פרק שלא התנגן" + +#: mygpo/web/templatetags/episodes.py:46 mygpo/web/templatetags/episodes.py:47 +#, python-format +msgid " on %s" +msgstr "ב־%s" + +#: mygpo/web/templatetags/episodes.py:50 +msgid "The episode has been flattr'd" +msgstr "הפרק קיבל flattr" + +#: mygpo/web/templatetags/episodes.py:53 +msgid "This episode has been marked new" +msgstr "הפרק סומן כחדש" + +#: mygpo/web/templatetags/episodes.py:55 +msgid "This episode has been downloaded" +msgstr "הפרק התקבל" + +#: mygpo/web/templatetags/episodes.py:59 +#, python-format +msgid " from %(start)s to %(end)s" +msgstr " מ־%(start)s עד %(end)s" + +#: mygpo/web/templatetags/episodes.py:63 +#, python-format +msgid " to position %s" +msgstr "למיקום %s" + +#: mygpo/web/templatetags/episodes.py:67 +msgid "This episode has been played" +msgstr "הפרק התנגן" + +#: mygpo/web/templatetags/episodes.py:69 +msgid "This episode has been deleted" +msgstr "הפרק נמחק" + +#: mygpo/web/templatetags/episodes.py:126 +msgid "Unknown Episode" +msgstr "פרק לא ידוע" + +#: mygpo/web/templatetags/menu.py:22 mygpo/web/templatetags/menu.py:65 +msgid "Home" +msgstr "בית" + +#: mygpo/web/templatetags/menu.py:29 +msgid "Help" +msgstr "עזרה" + +#: mygpo/web/templatetags/menu.py:37 +msgid "User subscriptions" +msgstr "מינויי המשתמש" + +#: mygpo/web/templatetags/menu.py:38 +msgid "Suggestions" +msgstr "הצעות" + +#: mygpo/web/templatetags/menu.py:39 +msgid "Features" +msgstr "תכונות" + +#: mygpo/web/templatetags/menu.py:41 +msgid "Toplists" +msgstr "רשימות מובילות" + +#: mygpo/web/templatetags/menu.py:49 +msgid "Devices" +msgstr "התקנים" + +#: mygpo/web/templatetags/menu.py:53 +msgid "Community" +msgstr "קהילה" + +#: mygpo/web/templatetags/menu.py:56 +msgid "My Userpage" +msgstr "עמוד המשתמש שלי" + +#: mygpo/web/templatetags/menu.py:62 +msgid "Privacy" +msgstr "פרטיות" + +#: mygpo/web/templatetags/menu.py:67 +msgid "Link to gpodder.net" +msgstr "מעבר אל gpodder.net" + +#: mygpo/web/templatetags/time.py:38 +#, python-brace-format +msgid "{h}h {m}m {s}s" +msgstr "{h} שע׳ {m} דק׳ {s} שנ׳" + +#: mygpo/web/utils.py:281 +#, python-format +msgid "%(weeks)d week" +msgid_plural "%(weeks)d weeks" +msgstr[0] "שבוע אחד" +msgstr[1] "שבועיים" +msgstr[2] "%(weeks)d שבועות" +msgstr[3] "%(weeks)d שבועות" + +#: mygpo/web/utils.py:285 +#, python-format +msgid "%(days)d day" +msgid_plural "%(days)d days" +msgstr[0] "יום אחד" +msgstr[1] "יומיים" +msgstr[2] "%(days)d ימים" +msgstr[3] "%(days)d ימים" + +#: mygpo/web/utils.py:289 +#, python-format +msgid "%(hours)d hour" +msgid_plural "%(hours)d hours" +msgstr[0] "שעה אחת" +msgstr[1] "שעתיים" +msgstr[2] "%(hours)d שעות" +msgstr[3] "%(hours)d שעות" + +#: mygpo/web/views.py:145 +msgid "another site" +msgstr "אתר אחר" From e400d7549f76a2d060e186f914342c746e1917ae Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 25 Jun 2018 12:59:50 +0300 Subject: [PATCH 090/106] Fixed type form -> from --- mygpo/web/templates/subscribe.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mygpo/web/templates/subscribe.html b/mygpo/web/templates/subscribe.html index db12fc7be..10a3c48b7 100644 --- a/mygpo/web/templates/subscribe.html +++ b/mygpo/web/templates/subscribe.html @@ -46,7 +46,7 @@

    {% trans "Subscribe" %}

    {% endif %} {% if not podcast.title %} -
    {% trans "Why Unnamed Podcast?" %} {% trans "Because we display names after we have fetched the information form the feed -- and this may take some time. Until this is completed, the podcast will simply be called this way." %}
    +
    {% trans "Why Unnamed Podcast?" %} {% trans "Because we display names after we have fetched the information from the feed -- and this may take some time. Until this is completed, the podcast will simply be called this way." %}
    {% endif %} {% endblock %} From 6ae8c6640f9da9c607cd1d7b60e87c4dacc82693 Mon Sep 17 00:00:00 2001 From: Guilherme Date: Wed, 27 Jun 2018 00:02:08 +0200 Subject: [PATCH 091/106] [doc] Fixed wrong http method in list devices api documentation --- doc/api/reference/devices.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/reference/devices.rst b/doc/api/reference/devices.rst index 10d0e29d2..2afdab02a 100644 --- a/doc/api/reference/devices.rst +++ b/doc/api/reference/devices.rst @@ -40,7 +40,7 @@ Update Device Data List Devices ------------ -.. http:post:: /api/2/devices/(username).json +.. http:get:: /api/2/devices/(username).json :synopsis: list the user's devices * Requires HTTP authentication From e23fc3cd754070f33f40fa27867baa1759cab615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 29 Jun 2018 22:16:37 +0200 Subject: [PATCH 092/106] Update translations --- mygpo/locale/de/LC_MESSAGES/django.po | 437 +++++++------- mygpo/locale/en/LC_MESSAGES/django.po | 383 ++++++------ mygpo/locale/es/LC_MESSAGES/django.po | 402 +++++++------ mygpo/locale/fr/LC_MESSAGES/django.po | 431 +++++++------- mygpo/locale/he/LC_MESSAGES/django.po | 724 ++++++++++++----------- mygpo/locale/it/LC_MESSAGES/django.po | 421 ++++++------- mygpo/locale/ko/LC_MESSAGES/django.po | 433 +++++++------- mygpo/locale/nb/LC_MESSAGES/django.po | 430 +++++++------- mygpo/locale/pl/LC_MESSAGES/django.po | 434 +++++++------- mygpo/locale/pt/LC_MESSAGES/django.po | 431 +++++++------- mygpo/locale/tr_TR/LC_MESSAGES/django.po | 396 +++++++------ 11 files changed, 2594 insertions(+), 2328 deletions(-) diff --git a/mygpo/locale/de/LC_MESSAGES/django.po b/mygpo/locale/de/LC_MESSAGES/django.po index eae06d623..cc73a135e 100644 --- a/mygpo/locale/de/LC_MESSAGES/django.po +++ b/mygpo/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2010-07-16 08:51+0200\n" "Last-Translator: Stefan Koegl \n" "Language-Team: DE \n" @@ -105,47 +105,51 @@ msgstr "Typ" msgid "Episode URLs" msgstr "Episoden" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Verzeichnis" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Benutzername" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -153,7 +157,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 #, fuzzy #| msgid "Publisher Pages" msgid "Publisher Permissions" @@ -276,21 +280,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Nicht gefunden" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -328,16 +332,16 @@ msgstr "abonnement gelöscht" msgid "%(username)s's Subscription List" msgstr "%(username)ss Podcast-Abos" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, fuzzy, python-format msgid "gpodder.net - Top %(count)d" msgstr "my.gpodder.org - Top %s" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - Suche" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, fuzzy, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "my.gpodder.org - %s Empfehlungen" @@ -360,7 +364,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 #, fuzzy msgid "..." msgstr "mehr..." @@ -492,11 +496,11 @@ msgid "Listeners" msgstr "Hörer" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "von" @@ -571,9 +575,9 @@ msgid "User" msgstr "Benutzername" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "herunterladen" @@ -632,10 +636,49 @@ msgstr "" msgid "%d podcasts added" msgstr "Podcasts" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Verlauf" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "Website" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +#, fuzzy +msgid "listeners" +msgstr "Hörer" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "Zeitpunkt" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Aktivität" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Geräte" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "Hinzufügen" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Abo-Verlauf" @@ -670,6 +713,10 @@ msgstr "Nein" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -765,17 +812,104 @@ msgstr "" msgid "Edit" msgstr "Bearbeiten" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "Unbenannter Podcast" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "Publisher-Seiten" + +#: mygpo/podcasts/templates/episode.html:91 +#, fuzzy +msgid "Remove Favorite" +msgstr "Favorit" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "Favorit" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "Your Episode History" +msgid "Episode History" +msgstr "Dein Episoden Verlauf" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "Unbenannter Podcast" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "Abonnenten" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +#| msgid "Subscribe" +msgid "Login to Subscribe" +msgstr "Abonnieren" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "Abonnieren" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Entfernen" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "Abonniere neue Podcasts" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "Abonniere neue Podcasts" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "Meine Tags" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Episoden" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -790,7 +924,7 @@ msgid "Link to" msgstr "Link zu" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -898,31 +1032,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Namenlose Episode" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "Publisher-Seiten" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "Website" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -#, fuzzy -msgid "listeners" -msgstr "Hörer" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -940,7 +1049,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -955,12 +1064,6 @@ msgstr "Episoden-Status" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "Unbenannter Podcast" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "Zurück zum Podcast" @@ -1124,77 +1227,59 @@ msgstr "" "Wenn Sie auf %(sitename)s verlinken machen " "Sie es Ihren Besuchern besonders einfach Ihren Podcasts zu abonnieren" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "Abonnenten" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Zurück zum Podcast" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Geräte-Liste" +msgid "Updates" +msgstr "Daten aus dem Feed holen" #: mygpo/publisher/templates/publisher/podcast.html:62 #, fuzzy msgid "Update interval:" msgstr "Daten aus dem Feed holen" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Geräte-Liste" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 #, fuzzy msgid "Update now" msgstr "Daten aus dem Feed holen" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to \n" "Language-Team: LANGUAGE \n" @@ -99,45 +99,49 @@ msgstr "" msgid "Episode URLs" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 msgid "Base Directory" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 msgid "Hostname" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -145,7 +149,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "" @@ -256,20 +260,20 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 msgid "No user found" msgstr "" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -307,16 +311,16 @@ msgstr "" msgid "%(username)s's Subscription List" msgstr "" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "" @@ -339,7 +343,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "" @@ -462,11 +466,11 @@ msgid "Listeners" msgstr "" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "" @@ -534,9 +538,9 @@ msgid "User" msgstr "" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "" @@ -593,10 +597,47 @@ msgstr "" msgid "%d podcasts added" msgstr "" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +msgid "Website" +msgstr "" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 msgid "Subscription History" msgstr "" @@ -629,6 +670,10 @@ msgstr "" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -720,15 +765,91 @@ msgstr "" msgid "Edit" msgstr "" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 msgid "Unknown Podcast" msgstr "" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:103 +msgid "Episode History" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +msgid "subscribers" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:48 +msgid "Login to Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:78 +msgid "Subscribe on all devices" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:110 +msgid "Unsubscribe from all devices " +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +msgid "Tags" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:199 +msgid "Older Episodes" +msgstr "" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -743,7 +864,7 @@ msgid "Link to" msgstr "" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -831,29 +952,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -msgid "Website" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "" - #: mygpo/publisher/templates/publisher/episode.html:55 msgid "Episode List" msgstr "" @@ -869,7 +967,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -883,12 +981,6 @@ msgstr "" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "" @@ -1023,71 +1115,55 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -msgid "subscribers" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 msgid "Go to Podcast Page" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 -msgid "Last update:" +#: mygpo/publisher/templates/publisher/podcast.html:60 +msgid "Updates" msgstr "" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:63 -msgid "Next update:" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to " msgstr "" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "" @@ -2514,11 +2520,16 @@ msgstr "" msgid "Link to gpodder.net" msgstr "" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" diff --git a/mygpo/locale/es/LC_MESSAGES/django.po b/mygpo/locale/es/LC_MESSAGES/django.po index d004978b5..77803859f 100644 --- a/mygpo/locale/es/LC_MESSAGES/django.po +++ b/mygpo/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: my.gpodder.org\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2010-02-08 18:45-0300\n" "Last-Translator: Silvio Sisto \n" "Language-Team: gpodder team \n" @@ -99,46 +99,50 @@ msgstr "" msgid "Episode URLs" msgstr "Mejores podcasts" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Historial" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 msgid "Hostname" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -146,7 +150,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "" @@ -258,21 +262,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "No se encuentra" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -310,16 +314,16 @@ msgstr "" msgid "%(username)s's Subscription List" msgstr "" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "" @@ -342,7 +346,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "" @@ -472,11 +476,11 @@ msgid "Listeners" msgstr "" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "" @@ -548,9 +552,9 @@ msgid "User" msgstr "" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "" @@ -609,10 +613,48 @@ msgstr "" msgid "%d podcasts added" msgstr "" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Historial" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "Dispositivos" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 msgid "Subscription History" msgstr "" @@ -645,6 +687,10 @@ msgstr "" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -739,16 +785,94 @@ msgstr "" msgid "Edit" msgstr "" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy msgid "Unknown Podcast" msgstr "Mejores podcasts" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +msgid "Episode History" +msgstr "Mejores podcasts" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +msgid "subscribers" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:48 +msgid "Login to Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:78 +msgid "Subscribe on all devices" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:110 +msgid "Unsubscribe from all devices " +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +msgid "Tags" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Mejores podcasts" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -763,7 +887,7 @@ msgid "Link to" msgstr "" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -853,30 +977,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "Dispositivos" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -894,7 +994,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -909,12 +1009,6 @@ msgstr "Mejores podcasts" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "" @@ -1051,74 +1145,57 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -msgid "subscribers" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Mejores podcasts" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Dispositivos" +msgid "Updates" +msgstr "Mejores podcasts" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Dispositivos" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to " msgstr "" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "" @@ -2581,11 +2586,16 @@ msgstr "" msgid "Link to gpodder.net" msgstr "" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2611,6 +2621,14 @@ msgstr[1] "" msgid "another site" msgstr "" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "Dispositivos" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "Dispositivos" + #, fuzzy #~ msgid "No Payment URL available" #~ msgstr "No hay logotipo disponible" diff --git a/mygpo/locale/fr/LC_MESSAGES/django.po b/mygpo/locale/fr/LC_MESSAGES/django.po index c53a1b888..c8a55298b 100644 --- a/mygpo/locale/fr/LC_MESSAGES/django.po +++ b/mygpo/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Louis Carlioz Luigi \n" "Language-Team: FR \n" @@ -105,47 +105,51 @@ msgstr "Genre" msgid "Episode URLs" msgstr "Épisodes" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Répertoire" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Nom d'utilisateur" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -153,7 +157,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 #, fuzzy #| msgid "Publisher Pages" msgid "Publisher Permissions" @@ -274,21 +278,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Introuvable" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -326,16 +330,16 @@ msgstr "désabonné" msgid "%(username)s's Subscription List" msgstr "Historique des abonnements" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "gpodder.net - Top %(count)d" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - Recherche" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "gpodder.net - %(count)d Suggestions" @@ -358,7 +362,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 #, fuzzy msgid "..." msgstr "voir plus..." @@ -490,11 +494,11 @@ msgid "Listeners" msgstr "Auditeurs" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "de" @@ -569,9 +573,9 @@ msgid "User" msgstr "Nom d'utilisateur" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "Télécharger" @@ -630,10 +634,49 @@ msgstr "" msgid "%d podcasts added" msgstr "podcasts" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Histoire" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "site web" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +#, fuzzy +msgid "listeners" +msgstr "Auditeurs" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "Temps" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Action" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Périphérique" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "Ajouter" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Historique des abonnements" @@ -668,6 +711,10 @@ msgstr "Non" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -763,17 +810,103 @@ msgstr "" msgid "Edit" msgstr "Éditer" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "Podcast anonyme" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "Pages pour l'éditeur" + +#: mygpo/podcasts/templates/episode.html:91 +#, fuzzy +msgid "Remove Favorite" +msgstr "Favoris" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "Favoris" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +msgid "Episode History" +msgstr "Top des épisodes" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "Podcast anonyme" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "Abonnés" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +#| msgid "Subscribe" +msgid "Login to Subscribe" +msgstr "S'abonner" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "S'abonner" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Se désabonner" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "S'abonner à ce podcast" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "S'abonner à ce podcast" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "Mes Tags" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Épisodes" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -788,7 +921,7 @@ msgid "Link to" msgstr "Lien vers" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -900,31 +1033,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Épisode anonyme" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "Pages pour l'éditeur" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "site web" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -#, fuzzy -msgid "listeners" -msgstr "Auditeurs" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -942,7 +1050,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -957,12 +1065,6 @@ msgstr "Statuts de l'épisode" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "Podcast anonyme" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "Retourner à la page des podcasts" @@ -1126,77 +1228,59 @@ msgstr "" "depuis votre site web, vos visiteurs pourront facilement s'abonner à votre " "podcast - spécialement les utilisateurs de téléphones portables." -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "Abonnés" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Retourner à la page des podcasts" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "ID du périphérique" +msgid "Updates" +msgstr "Mettre à jour le flux" #: mygpo/publisher/templates/publisher/podcast.html:62 #, fuzzy msgid "Update interval:" msgstr "Mettre à jour le flux" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "ID du périphérique" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:106 #, fuzzy msgid "Update now" msgstr "Mettre à jour le flux" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to paramètres de votre compte " "pour obtenir le lien." -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "Inconnu" @@ -2732,11 +2748,16 @@ msgstr "Vie privée" msgid "Link to gpodder.net" msgstr "Lien vers gpodder.net" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2762,6 +2783,14 @@ msgstr[1] "" msgid "another site" msgstr "un autre site" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "ID du périphérique" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "ID du périphérique" + #, fuzzy #~ msgid "You have to login to Flattr to use the Flattr features." #~ msgstr "Vous devez vous identifier pour accéder à cette page" diff --git a/mygpo/locale/he/LC_MESSAGES/django.po b/mygpo/locale/he/LC_MESSAGES/django.po index 81a5243ee..c53fffd23 100644 --- a/mygpo/locale/he/LC_MESSAGES/django.po +++ b/mygpo/locale/he/LC_MESSAGES/django.po @@ -2,21 +2,22 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Yaron Shahrabani , 2018\n" "Language-Team: Hebrew (https://www.transifex.com/yaron/teams/87581/he/)\n" +"Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: he\n" -"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n" +"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % " +"1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n" #: mygpo/administration/templates/admin/activate-user.html:9 #: mygpo/administration/templates/admin/activate-user.html:12 @@ -100,45 +101,49 @@ msgstr "סוג קובץ" msgid "Episode URLs" msgstr "כתובות פרקים" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "פרטי מארח" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "גרסת mygpo" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 msgid "Base Directory" msgstr "תיקיית בסיס" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 msgid "Hostname" msgstr "שם מארח" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "גרסת Django" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "תור עדכון הזנות" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "דקות הקדמה" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "דקות איחור" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "מספר הפודקאסטים עם אינדקס חיפוש בלתי עדכני" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "משימות מתוזמנות ב־Celery" @@ -146,7 +151,7 @@ msgstr "משימות מתוזמנות ב־Celery" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "הרשאות הפצה" @@ -260,20 +265,20 @@ msgstr "רענון" msgid "User-Agent" msgstr "סוכן דפדפן" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "אין פודקאסט בכתובת {url}" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "יש לספק שם משתמש או כתובת דוא״ל" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 msgid "No user found" msgstr "לא נמצאו משתמשים" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "המשתמש {username} ‎({email}) עבר עימות" @@ -311,16 +316,16 @@ msgstr "בוטל רישום" msgid "%(username)s's Subscription List" msgstr "רשימת המינויים של %(username)s" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "gpodder.net - %(count)d המובילים" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - חיפוש" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "gpodder.net - %(count)d הצעות" @@ -343,7 +348,7 @@ msgid "Explore" msgstr "עיון" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "…" @@ -355,11 +360,11 @@ msgstr "תיקיית פודקאסטים" #: mygpo/directory/templates/directory.html:30 #, python-format msgid "" -"%(listtitle)s by %(username)s" +"%(listtitle)s by " +"%(username)s" msgstr "" -"%(listtitle)s מאת %(username)s" +"%(listtitle)s מאת " +"%(username)s" #: mygpo/directory/templates/directory.html:46 #: mygpo/directory/templates/directory.html:48 @@ -468,11 +473,11 @@ msgid "Listeners" msgstr "מאזינים" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "מאת" @@ -540,9 +545,9 @@ msgid "User" msgstr "משתמש" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "הורדה" @@ -599,10 +604,47 @@ msgstr "גישת לקוח" msgid "%d podcasts added" msgstr "נוספו %d פודקאסטים" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "היסטוריה" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +msgid "Website" +msgstr "אתר" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "מאזינים" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "זמן" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "פעולה" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "מכשיר" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "הוספה" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 msgid "Subscription History" msgstr "היסטוריית מינויים" @@ -635,6 +677,10 @@ msgstr "עכשיו" msgid "Earlier" msgstr "מוקדם יותר" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "אין היסטוריה עדיין" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -728,15 +774,91 @@ msgstr "תודה לך על הדירוג!" msgid "Edit" msgstr "עריכה" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 msgid "Unknown Podcast" msgstr "פודקאסט לא ידוע" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "פודקאסט לא ידוע מ־{domain}" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "עמודי הפצה" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "הסרת מועדף" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "הוספה למועדפים" + +#: mygpo/podcasts/templates/episode.html:103 +msgid "Episode History" +msgstr "היסטוריית פרקים" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "פודקאסט ללא שם" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "מאת" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "הזנה" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +msgid "subscribers" +msgstr "מנויים" + +#: mygpo/podcasts/templates/podcast.html:48 +msgid "Login to Subscribe" +msgstr "יש להיכנס כדי להירשם" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "הרשמה" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "ביטול הרשמה" + +#: mygpo/podcasts/templates/podcast.html:78 +msgid "Subscribe on all devices" +msgstr "הרשמה בכל המכשירים" + +#: mygpo/podcasts/templates/podcast.html:110 +msgid "Unsubscribe from all devices " +msgstr "ביטול ההרשמה בכל המכשירים" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +msgid "Tags" +msgstr "תגיות" + +#: mygpo/podcasts/templates/podcast.html:199 +msgid "Older Episodes" +msgstr "פרקים ישנים יותר" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -751,7 +873,7 @@ msgid "Link to" msgstr "קישור אל" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -790,8 +912,8 @@ msgstr "" #: mygpo/publisher/templates/publisher/advertise.html:20 msgid "" -"You can chose when your advertisement will be active, and the text that will" -" be displayed for your podcast." +"You can chose when your advertisement will be active, and the text that will " +"be displayed for your podcast." msgstr "ניתן לבחור אם הפרסום שלך יהיה פעיל, והטקסט שיוצג עבור הפודקאסט שלך." #: mygpo/publisher/templates/publisher/advertise.html:22 @@ -814,11 +936,11 @@ msgstr "פודקאסטים לדוגמה" #: mygpo/publisher/templates/publisher/advertise.html:26 msgid "" "The gPodder client offers a list of example podcasts when started for the " -"first time. This list is loaded from the web on demand. For the time of your" -" advertisement, your podcast will be the first in the list." +"first time. This list is loaded from the web on demand. For the time of your " +"advertisement, your podcast will be the first in the list." msgstr "" -"הלקוח של gPodder מציע רשימת פודקאסטים לדוגמה כשהוא מופעל בפעם הראשונה. רשימה" -" זו נטענת מהאתר לפי דרישה. לזמן הפרסום שלך, הפודקאסט שלך יהיה הראשון ברשימה." +"הלקוח של gPodder מציע רשימת פודקאסטים לדוגמה כשהוא מופעל בפעם הראשונה. רשימה " +"זו נטענת מהאתר לפי דרישה. לזמן הפרסום שלך, הפודקאסט שלך יהיה הראשון ברשימה." #: mygpo/publisher/templates/publisher/advertise.html:28 msgid "Visitors" @@ -832,8 +954,8 @@ msgid "" "advertisement period." msgstr "" "גם עמוד הפתיחה וגם רשימת הדוגמאות מקבלים חשיפה של למעלה מ־1000 איש ביום, " -"שמחפשים באופן פעיל פודקאסטים מעניינים. עם זאת, איננו מתחייבים למספר מסוים של" -" מבקרים במהלך תקופת הפרסום שלך." +"שמחפשים באופן פעיל פודקאסטים מעניינים. עם זאת, איננו מתחייבים למספר מסוים של " +"מבקרים במהלך תקופת הפרסום שלך." #: mygpo/publisher/templates/publisher/advertise.html:31 msgid "Start your Advertisement" @@ -846,39 +968,14 @@ msgid "" "would like to advertise on %(sitename)s or if you have any questions. " "Payments are done via PayPal to thp@perli.net." msgstr "" -"עליך ליצור קשר עם stefan@gpodder.net אם ברצונך לפרסם " -"באתר %(sitename)s או אם יש לך שאלות. התשלום הוא דרך PayPal לטובת " -"thp@perli.net." +"עליך ליצור קשר עם stefan@gpodder.net אם ברצונך לפרסם באתר %(sitename)s או אם יש לך שאלות. התשלום הוא דרך " +"PayPal לטובת thp@perli.net." #: mygpo/publisher/templates/publisher/episode.html:31 msgid "Unnamed Episode" msgstr "פרק ללא שם" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "עמודי הפצה" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 -#: mygpo/web/templates/podcast-base.html:54 -msgid "Website" -msgstr "אתר" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "מאזינים" - #: mygpo/publisher/templates/publisher/episode.html:55 msgid "Episode List" msgstr "רשימת פרקים" @@ -896,7 +993,7 @@ msgstr "" "החלופיים ותמיד יפנו לכתובת הנוכחית." #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -910,12 +1007,6 @@ msgstr "נתוני פודקאסט" msgid "Last update: " msgstr "עדכון אחרון:" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "פודקאסט ללא שם" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "חזרה לעמוד הפודקאסט" @@ -956,8 +1047,7 @@ msgstr "צוות בלבד" #: mygpo/publisher/templates/publisher/home.html:24 msgid "Go to the publisher page of any podcast by entering its feed URL" -msgstr "" -"ניתן לעבור לעמוד ההפצה של כל פודקאסט שהוא על ידי הקלדת כתובת ההזנה שלו" +msgstr "ניתן לעבור לעמוד ההפצה של כל פודקאסט שהוא על ידי הקלדת כתובת ההזנה שלו" #: mygpo/publisher/templates/publisher/home.html:29 msgid "http://" @@ -1008,9 +1098,10 @@ msgstr "" #: mygpo/publisher/templates/publisher/info.html:24 #, python-format msgid "" -"You can find additional details on the advertisement page." -msgstr "ניתן למצוא פרטים נוספים בעמוד הפרסומות." +"You can find additional details on the advertisement page." +msgstr "" +"ניתן למצוא פרטים נוספים בעמוד הפרסומות." #: mygpo/publisher/templates/publisher/info.html:27 #, python-format @@ -1024,30 +1115,36 @@ msgstr "" #: mygpo/publisher/templates/publisher/info.html:30 #, python-format msgid "" -"The Publisher Pages are currently in Beta, but if you are publishing a podcast listed on %(sitename)s, feel free to apply by sending a mail with\n" +"The Publisher Pages are currently in Beta, but if you are publishing a " +"podcast listed on %(sitename)s, feel free to apply by sending a mail with\n" "
      \n" -"
    • your username on %(sitename)s (register if you don't have one)
    • \n" +"
    • your username on %(sitename)s (register " +"if you don't have one)
    • \n" "
    • the name and URL of the podcast you are publishing
    • \n" -"
    • an email address that is visible somewhere on the podcast's website (to legitimate you)\n" +"
    • an email address that is visible somewhere on the podcast's website " +"(to legitimate you)\n" "
    \n" " to stefan@gpodder.net." msgstr "" -"עמודי ההפצה נמצאים בשלבי ניסוי, אך אם יש לך פודקאסט בהפצתך שרשום תחת %(sitename)s, אפשר להירשם לתכנית על ידי שליחת הודעה בדוא״ל עם\n" +"עמודי ההפצה נמצאים בשלבי ניסוי, אך אם יש לך פודקאסט בהפצתך שרשום תחת " +"%(sitename)s, אפשר להירשם לתכנית על ידי שליחת הודעה בדוא״ל עם\n" "
      \n" -"
    • שם המשתמש שלך באתר %(sitename)s (עליך להירשם אם עוד אין לך אחד כזה)
    • \n" +"
    • שם המשתמש שלך באתר %(sitename)s (עליך " +"להירשם אם עוד אין לך אחד כזה)
    • \n" "
    • שם כתובת הפודקאסט שמופץ על ידיך
    • \n" -"
    • כתובת דוא״ל שגלויה במקום כלשהו באתר הפודקאסט (כדי לוודא שאכן יש לך קשר ישיר אליו)\n" +"
    • כתובת דוא״ל שגלויה במקום כלשהו באתר הפודקאסט (כדי לוודא שאכן יש לך " +"קשר ישיר אליו)\n" "
    \n" " אל stefan@gpodder.net." #: mygpo/publisher/templates/publisher/info.html:39 #, python-format msgid "" -"If you already are registered as a publisher, please login." +"If you already are registered as a publisher, please login." msgstr "" -"אם כבר נרשמת בתור מפיץ, נא להיכנס." +"אם כבר נרשמת בתור מפיץ, נא להיכנס." #: mygpo/publisher/templates/publisher/info.html:41 #, python-format @@ -1061,27 +1158,11 @@ msgid "" "website, you can make it really easy for your visitors to subscribe to your " "podcast - especially for users of mobile phones." msgstr "" -"הוספת קישור אל %(sitename)s מהאתר שלך, תקל" -" על המבקרים באתר שלך להירשם לפודקאסט שלך - במיוחד עבור משתמשים בטלפונים " +"הוספת קישור אל %(sitename)s מהאתר שלך, תקל " +"על המבקרים באתר שלך להירשם לפודקאסט שלך - במיוחד עבור משתמשים בטלפונים " "ניידים." -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "מאת" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "הזנה" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -msgid "subscribers" -msgstr "מנויים" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " @@ -1090,78 +1171,78 @@ msgstr "" "זה הוא עמוד ההפצה של %(ptitle)s. ניתן לצפות בסטטיסטיקה " "ולספק נתונים נוספים לעמוד הפודקאסט." -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 msgid "Go to Podcast Page" msgstr "מעבר לעמוד הפודקאסט" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "פרטי הפודקאסט מתקבלים על פי רוב מהזנת הפודקאסט" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "תזמון" - -#: mygpo/publisher/templates/publisher/podcast.html:61 -msgid "Last update:" -msgstr "עדכון אחרון:" +#: mygpo/publisher/templates/publisher/podcast.html:60 +#, fuzzy +#| msgid "Update now" +msgid "Updates" +msgstr "עדכון כעת" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "מרווח בין עדכונים:" -#: mygpo/publisher/templates/publisher/podcast.html:63 -msgid "Next update:" -msgstr "העדכון הבא:" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "עדכון כעת" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "טוויטר" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "בדיקת הזנה" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "PubSubHubbub" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" -"If you publish your podcast feed through a PubSubHubbu hub, " -"%(sitename)s can immediatelly update your podcast when a new episode is " -"released." +"If you publish your podcast feed through a PubSubHubbu hub, %(sitename)s can immediatelly update " +"your podcast when a new episode is released." msgstr "" -"על ידי פרסום הזנת הפודקאסטים שלך דרך נקודת הריכוז PubSubHubbu, " -"ל־%(sitename)s יש אפשרות לעדכן את הפודקאסט שלך ברגע שפרק חדש מופץ." +"על ידי פרסום הזנת הפודקאסטים שלך דרך נקודת הריכוז PubSubHubbu, ל־%(sitename)s יש אפשרות לעדכן " +"את הפודקאסט שלך ברגע שפרק חדש מופץ." -#: mygpo/publisher/templates/publisher/podcast.html:119 +#: mygpo/publisher/templates/publisher/podcast.html:157 #, python-format msgid "" -"Your podcast is published through %(hub)s and should" -" update immediatelly for each new episode." +"Your podcast is published through %(hub)s and should " +"update immediatelly for each new episode." msgstr "" "הפודקאסט שלך מופץ דרך %(hub)s והוא אמור להתעדכן מיד " "בכל פרק." -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -"הפודקאסט שלך מופץ דרך %(hub)s אך המינוי שלך טרם " -"אומת." +"הפודקאסט שלך מופץ דרך %(hub)s אך המינוי שלך טרם אומת." -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " @@ -1170,11 +1251,11 @@ msgstr "" "לא מצאנו נקודת ריכוז להזנת הפודקאסט שלך. ההזנה שלך מתעדכנת באופן סדיר, אך " "תיתכן השהיה קצרה עד שהפרקים יופיעו ב־%(sitename)s." -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "פרטי רישיון" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " @@ -1183,49 +1264,49 @@ msgstr "" "מוטב לכלול פרטי רישיון כחלק מההזנה שלך כדי שהמשתמשים לצד %(sitename)s יוכלו " "לדעת, תחת אילו תנאים ניתן להשתמש בתוכן שלך." -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" -"We found the following license in your podcast: %(license)s" +"We found the following license in your podcast: " +"%(license)s" msgstr "" "מצאנו את הרישיון הבא בפודקאסט שלך: %(license)s" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" -"We did not find a license in your podcast feed. Refer to gPodder Podcast Feed Best " -"Practice on how to include license information." +"We did not find a license in your podcast feed. Refer to gPodder Podcast Feed Best Practice on how to " +"include license information." msgstr "" -"לא מצאנו רישיון בהזנת הפודקאסט שלך. יש לפנות אל ההמלצות להזנות פודקאסטים של " -"gPodder על כיצד מוטב להוסיף פרטי רישיון." +"לא מצאנו רישיון בהזנת הפודקאסט שלך. יש לפנות אל ההמלצות להזנות פודקאסטים של gPodder על כיצד מוטב להוסיף " +"פרטי רישיון." -#: mygpo/publisher/templates/publisher/podcast.html:170 +#: mygpo/publisher/templates/publisher/podcast.html:208 msgid "Link" msgstr "קישור" -#: mygpo/publisher/templates/publisher/podcast.html:178 +#: mygpo/publisher/templates/publisher/podcast.html:216 msgid "Show Group Stats" msgstr "הצגת סטטיסטיקה קבוצתית" -#: mygpo/publisher/views.py:141 +#: mygpo/publisher/views.py:148 msgid "" -"The update has been scheduled. It might take some time until the results are" -" visible." +"The update has been scheduled. It might take some time until the results are " +"visible." msgstr "תוזמן עדכון. יכול להיות שיחלוף קצת זמן עד שניתן יהיה לראות תוצאות." -#: mygpo/publisher/views.py:154 mygpo/users/views/settings.py:98 +#: mygpo/publisher/views.py:161 mygpo/users/views/settings.py:98 msgid "Data updated" msgstr "נתונים עודכנו" -#: mygpo/publisher/views.py:165 +#: mygpo/publisher/views.py:172 msgid "Publisher token updated" msgstr "אסימון מפרסם עודכן" -#: mygpo/publisher/views.py:255 +#: mygpo/publisher/views.py:262 #, python-brace-format msgid "Removed slug {slug} from {episode}" msgstr "הוסר השם המופשט {slug} מהפרק {episode}" @@ -1345,10 +1426,10 @@ msgstr "מעניין אותך לקבל עמוד משתמש משלך?" #: mygpo/share/templates/userpage-denied.html:20 #, python-format -msgid " Go to your Share Page to get the link." +msgid "" +" Go to your Share Page to get the link." msgstr "" -" עליך לעבור לשיתוף עמוד כדי לקבל את " -"הקישור." +" עליך לעבור לשיתוף עמוד כדי לקבל את הקישור." #: mygpo/share/templates/userpage.html:24 #, python-format @@ -1433,13 +1514,13 @@ msgstr "%(episode_count)s פרקים" #: mygpo/subscriptions/templates/subscriptions.html:42 #, python-format msgid "" -"You don't have any subscriptions yet. Set up your podcast clients and discover interesting podcasts." +"You don't have any subscriptions yet. Set up your podcast clients and discover interesting " +"podcasts." msgstr "" "אין לך מינויים עדיין. עליך להגדיר את לקוח " -"הפודקאסטים שלך ואת איתור פודקאסטים " -"מעניינים." +"הפודקאסטים שלך ואת איתור פודקאסטים מעניינים." #: mygpo/subscriptions/templates/subscriptions.html:63 #: mygpo/suggestions/templates/suggestions.html:54 @@ -1472,12 +1553,6 @@ msgstr "ביטול הרשמה אל %(podcast)s מצד %(username)s (%(site)s)" msgid "Suggested Podcasts" msgstr "פודקאסטים מומלצים" -#: mygpo/suggestions/templates/suggestions.html:31 -#: mygpo/web/templates/podcast.html:59 mygpo/web/templates/subscribe.html:11 -#: mygpo/web/templates/subscribe.html:36 -msgid "Subscribe" -msgstr "הרשמה" - #: mygpo/suggestions/templates/suggestions.html:36 msgid "No Interest" msgstr "אין עניין" @@ -1486,27 +1561,27 @@ msgstr "אין עניין" msgid "No Suggestions Yet" msgstr "אין הצעות עדיין" -#: mygpo/users/models.py:225 +#: mygpo/users/models.py:226 msgid "Desktop" msgstr "מחשב שולחני" -#: mygpo/users/models.py:226 +#: mygpo/users/models.py:227 msgid "Laptop" msgstr "מחשב נייד" -#: mygpo/users/models.py:227 +#: mygpo/users/models.py:228 msgid "Cell phone" msgstr "טלפון סלולרי" -#: mygpo/users/models.py:228 +#: mygpo/users/models.py:229 msgid "Server" msgstr "שרת" -#: mygpo/users/models.py:229 +#: mygpo/users/models.py:230 msgid "Tablet" msgstr "מחשב לוח" -#: mygpo/users/models.py:230 +#: mygpo/users/models.py:231 msgid "Other" msgstr "אחר" @@ -1561,8 +1636,8 @@ msgstr "" #: mygpo/users/templates/registration/registration_form.html:90 #, python-format msgid "" -"If it doesn't arrive, you can resend it." +"If it doesn't arrive, you can resend it." msgstr "" "אם ההודעה לא מגיעה אליך, ניתן לשלוח " "אותה מחדש." @@ -1575,9 +1650,9 @@ msgstr "שליחת הודעת הפעלה בדוא״ל מחדש" #: mygpo/users/templates/registration/resend_activation.html:18 #: mygpo/web/templates/restore_password.html:21 msgid "" -"Please enter either your username or (if you don't know that either) the " -"e-mail address which you used to register your account. An e-mail will be " -"sent to you." +"Please enter either your username or (if you don't know that either) the e-" +"mail address which you used to register your account. An e-mail will be sent " +"to you." msgstr "" "נא להקליד את שם משתמש או (או אם הפרט הזה חסר לך) את כתובת הדוא״ל בה השתמשת " "לטובת רישום לחשבון. תישלח אליך הודעה בדוא״ל." @@ -1592,7 +1667,9 @@ msgid "Sent Activation Email" msgstr "נשלחה הודעה הפעלה בדוא״ל" #: mygpo/users/templates/registration/resent_activation.html:11 -msgid "The activation email has been reset." +#, fuzzy +#| msgid "The activation email has been reset." +msgid "The activation email has been resent." msgstr "הודעת האימות נשלחה בדוא״ל מחדש." #: mygpo/users/views/device.py:80 mygpo/users/views/device.py:170 @@ -1903,8 +1980,7 @@ msgid "" "keep the site running and improve it constantly." msgstr "" "gpodder.net מופעל כמיזם תחביב ללא מקור מימון מתחדש לשרתים, לאחסון ולתעבורה. " -"אנו סומכים על מתנדבים ותרומות כדי להשאיר את האתר פעיל ולשפר אותו שלב אחר " -"שלב." +"אנו סומכים על מתנדבים ותרומות כדי להשאיר את האתר פעיל ולשפר אותו שלב אחר שלב." #: mygpo/web/templates/contribute.html:18 msgid "Work" @@ -1915,30 +1991,29 @@ msgid "" "If you want to contribute to gpodder.net by writing code, check out the Development page. We also appreciate contributions " "of non-coding work, such as web and interface design, server operations, " -"testing, etc. If you are interested, join the mailing list " -"or the IRC channel #gpodder on chat.freenode.net." +"testing, etc. If you are interested, join the mailing list or the IRC channel " +"#gpodder on chat.freenode.net." msgstr "" "אם מעניין אותך להתנדב לטובת gpodder.net עם כתיבת קוד, כדאי לבקר בעמוד פיתוח. אנו גם מעריכים צורות התנדבות שאינן בצורת " "קוד, כגון עיצוב האתר, פעולות בשרת, בדיקות וכו׳. אם כל זה מעניין אותך, " -"באפשרותך להצטרף לרשימת הדיונים או לערוץ ה־IRC בשם ‎#gpodder תחת " -"chat.freenode.net." +"באפשרותך להצטרף לרשימת הדיונים או לערוץ ה־IRC בשם ‎#gpodder תחת chat.freenode.net." #: mygpo/web/templates/contribute.html:23 msgid "" -"If you want to support gpodder.net financially, you can donate via PayPal to" -" stefan@skoegl.net. You can also send a book via Amazon (DE, US or UK)." +"If you want to support gpodder.net financially, you can donate via PayPal to " +"stefan@skoegl.net. You can also send a book via Amazon (DE, US or UK)." msgstr "" "אם ברצונך לתמוך ב־gpodder.net כלכלית, ניתן לתרום דרך PayPal לטובת " -"stefan@skoegl.net. ניתן גם לשלוח ספר דרך Amazon (DE, US או UK)." +"stefan@skoegl.net. ניתן גם לשלוח ספר דרך Amazon (DE, US או UK)." #: mygpo/web/templates/csrf.html:8 msgid "Attention!" @@ -1952,9 +2027,9 @@ msgstr "לשים לב בבקשה!" #, python-format msgid "" "It seems that %(referer)s has linked to %(site)s to get you to change some " -"data. This will possibly change some of your data / " -"settings!. Do you really want to continue? If in doubt, " -"chose No." +"data. This will possibly change some of your data / settings!. Do you really want to continue? If in doubt, chose No." msgstr "" "נראה כי %(referer)s קושר אל %(site)s כדי לנסות לשכנע אותך לשנות נתונים. " "מצב כזה עשוי לגרום לך לשנות חלק מהנתונים / הגדרות שלך!. " @@ -1984,25 +2059,25 @@ msgstr "הפרקים החדשים ביותר" #, python-format msgid "" "Welcome to %(site)s! If this is your first visit, you should set up your podcast" -" client and try to check as many Explore boxes as you can." +"href=\"https://gpoddernet.readthedocs.io/en/latest/user/clients.html" +"\">podcast client and try to check as many Explore boxes as you " +"can." msgstr "" -"ברוך בואך אל %(site)s! אם זה הביקור הראשון שלך, כדאי לך להגדיר את לקוח " +"ברוך בואך אל %(site)s! אם זה הביקור הראשון שלך, כדאי לך להגדיר את לקוח " "הפודקאסטים שלך ולנסות לחקור כמה שיותר תיבות סיור שאפשר." #: mygpo/web/templates/dashboard.html:44 #, python-format msgid "" "If you have problems, have a look at the docs or " -"ask questions on the mailing list or forum." +"ask questions on the mailing list or forum." msgstr "" "במקרה של תקלות, מוטב לעיין במסמכים או לשאול שאלות " -"ברשימת " -"הדיונים או בפורום." +"ברשימת הדיונים או בפורום." #: mygpo/web/templates/dashboard.html:81 #, python-format @@ -2104,15 +2179,13 @@ msgstr "שירות מקוון" msgid "" "The sourcecode of the webservice gpodder.net is released as open source " "under the AGPLv3 and hosted at " -"GitHub. Bugs can be reported at the gPodder " -"Bugtracker." +"GitHub. Bugs can be reported at the gPodder Bugtracker." msgstr "" "קוד המקור של השירות המקוון gpodder.net מופץ לקהל הרחב כקוד פתוח תחת הרישיון " -"AGPLv3 והוא מתארח ב־GitHub." -" ניתן לדווח על תקלות בעוקב " -"המשימות של gPodder." +"AGPLv3 והוא מתארח ב־GitHub. " +"ניתן לדווח על תקלות בעוקב המשימות של gPodder." #: mygpo/web/templates/developer.html:21 msgid "Integrating Clients" @@ -2121,25 +2194,22 @@ msgstr "שילוב לקוחות" #: mygpo/web/templates/developer.html:22 msgid "" "If you want to integrate gpodder.net in some podcasting client, you might " -"want to use one of the existing client" -" libraries." +"want to use one of the existing client libraries." msgstr "" "אם ברצונך לשלב את gpodder.net בלקוח פודקאסטים כלשהו, יכול להיות שעדיף לך " -"להשתמש באחת מספריות" -" הלקוח הקיימות." +"להשתמש באחת מספריות הלקוח הקיימות." #: mygpo/web/templates/developer.html:23 msgid "" "There are already several clients for different platforms which can be used " -"as examples. See " -"list of clients." +"as examples. See list of clients." msgstr "" -"כבר ישנם מגוון לקוחות לפלטפורמות שונות בהם ניתן להשתמש כדוגמאות. הצגת " -"רשימת הלקוחות." +"כבר ישנם מגוון לקוחות לפלטפורמות שונות בהם ניתן להשתמש כדוגמאות. הצגת רשימת " +"הלקוחות." #: mygpo/web/templates/device-edit.html:11 mygpo/web/templates/device.html:11 #, python-format @@ -2167,43 +2237,35 @@ msgid "Delete Device" msgstr "מחיקת מכשיר" #: mygpo/web/templates/device-edit.html:99 -#: mygpo/web/templates/device-edit.html:117 -#: mygpo/web/templates/device.html:102 mygpo/web/templates/device.html:120 +#: mygpo/web/templates/device-edit.html:117 mygpo/web/templates/device.html:102 +#: mygpo/web/templates/device.html:120 msgid "Synchronize" msgstr "סנכרון" -#: mygpo/web/templates/device-edit.html:100 -#: mygpo/web/templates/device.html:103 +#: mygpo/web/templates/device-edit.html:100 mygpo/web/templates/device.html:103 msgid "" "If you synchronize devices, they will always have the same subscriptions. A " -"podcast that is subscribed on one device, will automatically be added to all" -" synchronized devices." +"podcast that is subscribed on one device, will automatically be added to all " +"synchronized devices." msgstr "" "סמקרה של סנכרון מכשירים, תמיד יהיו להם את אותם המינויים. פודקאסט אליו נרשמת " "במכשיר אחד יתווסף אוטומטית לכל המכשירים המסונכרנים." -#: mygpo/web/templates/device-edit.html:104 -#: mygpo/web/templates/device.html:107 +#: mygpo/web/templates/device-edit.html:104 mygpo/web/templates/device.html:107 #, python-format msgid "%(devicename)s is currently not synchronized with other devices." msgstr "%(devicename)s לא מסונכרן כרגע עם מכשירים אחרים." -#: mygpo/web/templates/device-edit.html:108 -#: mygpo/web/templates/device.html:111 +#: mygpo/web/templates/device-edit.html:108 mygpo/web/templates/device.html:111 #, python-format msgid "%(devicename)s is currently synchronized with %(synclist)s." msgstr "%(devicename)s מסונכרן כעת עם %(synclist)s." -#: mygpo/web/templates/device-edit.html:109 -#: mygpo/web/templates/device.html:112 +#: mygpo/web/templates/device-edit.html:109 mygpo/web/templates/device.html:112 #, python-format msgid "Stop synchronisation for %(devicename)s " msgstr "עצירת סנכרון עבור %(devicename)s" -#: mygpo/web/templates/device.html:31 mygpo/web/templates/podcast.html:67 -msgid "Unsubscribe" -msgstr "ביטול הרשמה" - #: mygpo/web/templates/device.html:40 msgid "You don't have any podcasts subscribed on this device." msgstr "לא נרשמת לאף פודקאסט במכשיר הזה." @@ -2212,13 +2274,6 @@ msgstr "לא נרשמת לאף פודקאסט במכשיר הזה." msgid "OPML for Nokia Podcasting on Symbian " msgstr "OPML לפודקאסטים של נוקיה על סימביאן" -#: mygpo/web/templates/device.html:73 -#: mygpo/web/templates/episode-history.html:46 -#: mygpo/web/templates/episode-history.html:80 -#: mygpo/web/templatetags/menu.py:51 -msgid "History" -msgstr "היסטוריה" - #: mygpo/web/templates/device.html:79 msgid "Trigger Sync" msgstr "הפעלת סנכרון" @@ -2243,13 +2298,13 @@ msgstr "לא מסונכרן" #: mygpo/web/templates/devicelist.html:53 msgid "" -"You don't have any devices yet. Go to the clients" -" page to learn how to set up your client applications." +"You don't have any devices yet. Go to the clients page to learn how " +"to set up your client applications." msgstr "" -"לא מוגדרים עבורך מכשירים עדיין. נא לעבור לעמוד הלקוחות" -" כדי ללמוד איך להגדיר את יישומי הלקוח שלך." +"לא מוגדרים עבורך מכשירים עדיין. נא לעבור לעמוד הלקוחות כדי ללמוד איך להגדיר " +"את יישומי הלקוח שלך." #: mygpo/web/templates/devicelist.html:74 msgid "Deleted Devices" @@ -2263,35 +2318,6 @@ msgstr "הפעלה מחדש" msgid "Delete Permanently" msgstr "מחיקה לצמיתות" -#: mygpo/web/templates/episode-history.html:83 -msgid "Time" -msgstr "זמן" - -#: mygpo/web/templates/episode-history.html:84 -msgid "Action" -msgstr "פעולה" - -#: mygpo/web/templates/episode-history.html:85 -#: mygpo/web/templatetags/menu.py:50 -msgid "Device" -msgstr "מכשיר" - -#: mygpo/web/templates/episode-history.html:126 -msgid "Add" -msgstr "הוספה" - -#: mygpo/web/templates/episode.html:91 -msgid "Remove Favorite" -msgstr "הסרת מועדף" - -#: mygpo/web/templates/episode.html:95 -msgid "Favorite" -msgstr "הוספה למועדפים" - -#: mygpo/web/templates/episode.html:103 -msgid "Episode History" -msgstr "היסטוריית פרקים" - #: mygpo/web/templates/favorites.html:10 mygpo/web/templates/favorites.html:13 #: mygpo/web/templatetags/menu.py:47 mygpo/web/templatetags/menu.py:55 msgid "Favorite Episodes" @@ -2326,11 +2352,11 @@ msgstr "התגיות שלי" #: mygpo/web/templates/mytags.html:41 #, python-format msgid "" -"You didn't tag any podcasts yet. Go to your subscriptions and tag some." +"You didn't tag any podcasts yet. Go to your subscriptions and tag some." msgstr "" -"לא תייגת אף פודקאסט עדיין. יש לגשת אל המינויים שלך ולתייג כמה מהם." +"לא תייגת אף פודקאסט עדיין. יש לגשת אל המינויים שלך ולתייג כמה מהם." #: mygpo/web/templates/password_reset.html:4 msgid "Password reset" @@ -2343,11 +2369,11 @@ msgstr "הססמה שלך עברה איפוס" #: mygpo/web/templates/password_reset.html:13 #, python-format msgid "" -"You should have received an mail with your new password. Please log in now." +"You should have received an mail with your new password. Please log in now." msgstr "" -"אמורה הייתה להגיע אליך הודעה עם הססמה החדשה שלך. נא להיכנס כעת." +"אמורה הייתה להגיע אליך הודעה עם הססמה החדשה שלך. נא להיכנס כעת." #: mygpo/web/templates/password_reset_failed.html:4 msgid "Password could not be reset" @@ -2361,30 +2387,6 @@ msgstr "לא ניתן לאפס את הססמה שלך" msgid "Unfortunately we were not able to reset your password." msgstr "לרוע המזל, לא הצלחנו לאפס לך את הססמה." -#: mygpo/web/templates/podcast-history.html:47 -msgid "no history yet" -msgstr "אין היסטוריה עדיין" - -#: mygpo/web/templates/podcast.html:48 -msgid "Login to Subscribe" -msgstr "יש להיכנס כדי להירשם" - -#: mygpo/web/templates/podcast.html:78 -msgid "Subscribe on all devices" -msgstr "הרשמה בכל המכשירים" - -#: mygpo/web/templates/podcast.html:110 -msgid "Unsubscribe from all devices " -msgstr "ביטול ההרשמה בכל המכשירים" - -#: mygpo/web/templates/podcast.html:149 mygpo/web/templates/podcast.html:164 -msgid "Tags" -msgstr "תגיות" - -#: mygpo/web/templates/podcast.html:199 -msgid "Older Episodes" -msgstr "פרקים ישנים יותר" - #: mygpo/web/templates/privacy.html:9 mygpo/web/templates/privacy.html:12 msgid "Privacy Settings" msgstr "הגדרות פרטיות" @@ -2396,8 +2398,8 @@ msgstr "ב־%(domain)s קיימת הבדלה בין מינויים ציבורי #: mygpo/web/templates/privacy.html:20 msgid "" -"Public subscriptions are included in your shared podcasts and our anonymized public statistics." +"Public subscriptions are included in your shared podcasts and our anonymized public statistics." msgstr "" "מינויים ציבוריים נכללים בפודקאסטים " "המשותפים שלך ובסטטיסטיקה הציבורית האלמונית שלנו." @@ -2407,8 +2409,8 @@ msgid "" "Private subscriptions do neither show up in your list of " "shared podcasts, nor are considered in our statistics." msgstr "" -"מינויים פרטיים אינם מופיעים ברשימת הפודקאסטים המשותפים שלך," -" או בסטטיסטיקות שלנו." +"מינויים פרטיים אינם מופיעים ברשימת הפודקאסטים המשותפים שלך, " +"או בסטטיסטיקות שלנו." #: mygpo/web/templates/privacy.html:29 msgid "Default for new subscriptions" @@ -2444,9 +2446,13 @@ msgid "Subscribe to %(podcasttitle)s" msgstr "הרשמה אל %(podcasttitle)s" #: mygpo/web/templates/subscribe.html:41 +#, fuzzy +#| msgid "" +#| "You can't subscribe to this podcast, because you don't have any devices " +#| "(on which you don't have subscribed to the podcast already." msgid "" "You can't subscribe to this podcast, because you don't have any devices (on " -"which you don't have subscribed to the podcast already." +"which you don't have subscribed to the podcast already)." msgstr "" "אין לך אפשרות להירשום לפודקאסט הזה כיוון שאין לך מכשירים (שבהם לא נרשמת " "עדיין לפודקאסט)." @@ -2460,13 +2466,18 @@ msgid "Why Unnamed Podcast?" msgstr "למה פודקאסט ללא שם?" #: mygpo/web/templates/subscribe.html:49 +#, fuzzy +#| msgid "" +#| "Because we display names after we have fetched the information form the " +#| "feed -- and this may take some time. Until this is completed, the podcast " +#| "will simply be called this way." msgid "" -"Because we display names after we have fetched the information form the feed" -" -- and this may take some time. Until this is completed, the podcast will " +"Because we display names after we have fetched the information from the feed " +"-- and this may take some time. Until this is completed, the podcast will " "simply be called this way." msgstr "" -"כיוון שאנו מציגים שמות לאחר אחזור המידע מההזנה -- פעולה שעשויה לארוך זמן מה." -" עד להשלמת פעולה זו, הפודקאסט פשוט ייקרא כך." +"כיוון שאנו מציגים שמות לאחר אחזור המידע מההזנה -- פעולה שעשויה לארוך זמן מה. " +"עד להשלמת פעולה זו, הפודקאסט פשוט ייקרא כך." #: mygpo/web/templates/user_subscriptions.html:14 #: mygpo/web/templates/user_subscriptions.html:18 @@ -2512,8 +2523,8 @@ msgstr "פודקאסטים של נוקיה" #: mygpo/web/templates/user_subscriptions.html:72 msgid "" -"Add &symbian=true#.opml to the OPML URL to get an OPML file for" -" Nokia Podcasting on Symbian devices." +"Add &symbian=true#.opml to the OPML URL to get an OPML file for " +"Nokia Podcasting on Symbian devices." msgstr "" "יש להוסיף &symbian=true#.opml לכתובת ה־OPML כדי לקבל קובץ OPML " "עבור פודקאסטים של נוקיה על מכשירי סימביאן." @@ -2533,13 +2544,13 @@ msgstr "מעניין אותך לשתף את המינויים שלך?" #: mygpo/web/templates/user_subscriptions_denied.html:23 msgid "" -"Just go to your account settings to get the " -"link." +"Just go to your account settings to get the link." msgstr "" -"עליך פשוט לגשת אל הגדרות החשבון כדי לקבל את " -"הקישור." +"עליך פשוט לגשת אל הגדרות החשבון כדי לקבל את הקישור." +"" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "לא ידוע" @@ -2665,11 +2676,17 @@ msgstr "פרטיות" msgid "Link to gpodder.net" msgstr "מעבר אל gpodder.net" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "{h} שע׳ {m} דק׳ {s} שנ׳" +#: mygpo/web/templatetags/time.py:44 +#, fuzzy, python-brace-format +#| msgid "{h}h {m}m {s}s" +msgid "{m}m {s}s" +msgstr "{h} שע׳ {m} דק׳ {s} שנ׳" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2700,3 +2717,12 @@ msgstr[3] "%(hours)d שעות" #: mygpo/web/views.py:145 msgid "another site" msgstr "אתר אחר" + +#~ msgid "Timing" +#~ msgstr "תזמון" + +#~ msgid "Last update:" +#~ msgstr "עדכון אחרון:" + +#~ msgid "Next update:" +#~ msgstr "העדכון הבא:" diff --git a/mygpo/locale/it/LC_MESSAGES/django.po b/mygpo/locale/it/LC_MESSAGES/django.po index 5d28862a6..5f04d645d 100644 --- a/mygpo/locale/it/LC_MESSAGES/django.po +++ b/mygpo/locale/it/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -101,46 +101,50 @@ msgstr "Tipo" msgid "Episode URLs" msgstr "Podcasts" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Corso temporale" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 msgid "Hostname" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -148,7 +152,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "" @@ -263,21 +267,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Non trovato" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -317,16 +321,16 @@ msgstr "Disdire" msgid "%(username)s's Subscription List" msgstr "I tuoi abbonamenti" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, fuzzy, python-format msgid "gpodder.net - Top %(count)d" msgstr "my.gpodder.org - Top %s" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, fuzzy, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "my.gpodder.org - %s suggerimenti" @@ -349,7 +353,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "" @@ -480,11 +484,11 @@ msgid "Listeners" msgstr "" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "" @@ -557,9 +561,9 @@ msgid "User" msgstr "" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "" @@ -618,10 +622,49 @@ msgstr "" msgid "%d podcasts added" msgstr "Podcasts" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Corso temporale" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "Podcasts" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "" + +#: mygpo/history/templates/episode-history.html:84 +#, fuzzy +msgid "Time" +msgstr "Titolo" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Azione" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Strumento tecnico" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Corso degli abbonamenti" @@ -655,6 +698,10 @@ msgstr "" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -750,16 +797,100 @@ msgstr "" msgid "Edit" msgstr "" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy msgid "Unknown Podcast" msgstr "Podcasts" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "Your Episode History" +msgid "Episode History" +msgstr "Il tuo corso episodico." + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "abboni" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +msgid "Login to Subscribe" +msgstr "abboni" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +#, fuzzy +msgid "Subscribe" +msgstr "abboni" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Disdire" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "Abbonato su" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "Abbonato su" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +msgid "Tags" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Ultimo episodio" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -775,7 +906,7 @@ msgid "Link to" msgstr "" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -869,30 +1000,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Perchè episodi non nominati?" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "Podcasts" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -910,7 +1017,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -925,12 +1032,6 @@ msgstr "Ultimo episodio" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "" @@ -1068,75 +1169,57 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "abboni" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Podcast" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Lista strumenti tecnici" +msgid "Updates" +msgstr "Podcast" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Lista strumenti tecnici" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to " msgstr "" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "" @@ -2644,11 +2654,16 @@ msgstr "" msgid "Link to gpodder.net" msgstr "" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2674,6 +2689,14 @@ msgstr[1] "" msgid "another site" msgstr "" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "Lista strumenti tecnici" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "Lista strumenti tecnici" + #, fuzzy #~ msgid "You have to login to Flattr to use the Flattr features." #~ msgstr "Ti sei abbonato i podcats seguenti sul tuo strumento tecnico." diff --git a/mygpo/locale/ko/LC_MESSAGES/django.po b/mygpo/locale/ko/LC_MESSAGES/django.po index 94bda2421..dce4ac011 100644 --- a/mygpo/locale/ko/LC_MESSAGES/django.po +++ b/mygpo/locale/ko/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: mygpo\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2017-07-06 17:10+0900\n" "Last-Translator: Changwoo Ryu \n" "Language-Team: Changwoo Ryu \n" @@ -100,47 +100,51 @@ msgstr "파일 종류" msgid "Episode URLs" msgstr "에피소드 URL" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "호스트 정보" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "mygpo 버전" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 msgid "Base Directory" msgstr "베이스 디렉터리" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 msgid "Hostname" msgstr "호스트 이름" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "Django 버전" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 #, fuzzy #| msgid "Admin Area" msgid "min ahead" msgstr "관리 영역" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "예정된 Celery 작업" @@ -148,7 +152,7 @@ msgstr "예정된 Celery 작업" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 #, fuzzy #| msgid "Publisher Pages" msgid "Publisher Permissions" @@ -272,22 +276,22 @@ msgstr "새로 고침" msgid "User-Agent" msgstr "User-Agent" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "{url} URL의 팟캐스트 없음" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy #| msgid "Nothing found" msgid "No user found" msgstr "검색 결과가 없습니다" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -325,16 +329,16 @@ msgstr "구독 해지함" msgid "%(username)s's Subscription List" msgstr "%(username)s의 구독 목록" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "gpodder.net - 톱 %(count)d" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - 검색" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "gpodder.net - 제안 %(count)d개" @@ -357,7 +361,7 @@ msgid "Explore" msgstr "둘러보기" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "..." @@ -485,11 +489,11 @@ msgid "Listeners" msgstr "청취자" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "위치" @@ -559,9 +563,9 @@ msgid "User" msgstr "사용자" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "다운로드" @@ -618,10 +622,47 @@ msgstr "클라이언트 접근" msgid "%d podcasts added" msgstr "팟캐스트 %d개 추가함" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "기록" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +msgid "Website" +msgstr "웹사이트" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "청취자" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "시간" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "동작" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "장치" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "추가" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 msgid "Subscription History" msgstr "구독 기록" @@ -655,6 +696,10 @@ msgstr "지금" msgid "Earlier" msgstr "더 예전" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -748,17 +793,103 @@ msgstr "평가해 주셔서 감사합니다!" msgid "Edit" msgstr "편집" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "이름 없는 팟캐스트" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "제작자 페이지" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "즐겨 듣기 삭제" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "즐겨 듣기" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "Episodes" +msgid "Episode History" +msgstr "에피소드" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "이름 없는 팟캐스트" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "by" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "피드" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +msgid "subscribers" +msgstr "구독자" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +#| msgid "Subscribe" +msgid "Login to Subscribe" +msgstr "구독" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "구독" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "구독 해제" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +#| msgid "Subscribe on devices" +msgid "Subscribe on all devices" +msgstr "장치에서 구독" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +#| msgid "Subscribe on devices" +msgid "Unsubscribe from all devices " +msgstr "장치에서 구독" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "내 태그" + +#: mygpo/podcasts/templates/podcast.html:199 +msgid "Older Episodes" +msgstr "더 예전 에피소드" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -773,7 +904,7 @@ msgid "Link to" msgstr "연결하기" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -878,29 +1009,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "이름 없는 에피소드" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "제작자 페이지" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -msgid "Website" -msgstr "웹사이트" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "청취자" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy #| msgid "Episode URLs" @@ -922,7 +1030,7 @@ msgstr "" "고 현재 URL로 리다이렉트됩니다." #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -936,12 +1044,6 @@ msgstr "에피소드 데이터" msgid "Last update: " msgstr "최근 업데이트: " -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "이름 없는 팟캐스트" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "팟캐스트 페이지로 돌아가기" @@ -1105,23 +1207,7 @@ msgstr "" "면, 웹 방문자가 팟캐스트에 아주 쉽게 구독할 수 있습니다. 특히 휴대폰 사용자" "의 경우 그렇습니다." -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "by" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "피드" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -msgid "subscribers" -msgstr "구독자" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " @@ -1130,23 +1216,19 @@ msgstr "" "%(ptitle)s의 제작자 페이지입니다. 팟캐스트 페이지에 대한 통" "계와 추가 정보를 볼 수 있습니다." -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 msgid "Go to Podcast Page" msgstr "팟캐스트 페이지로 이동" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "팟캐스트 정보는 주기적으로 팟캐스트 피드에서 가져옵니다" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -#| msgid "Last update: " -msgid "Last update:" -msgstr "최근 업데이트: " +#| msgid "Update now" +msgid "Updates" +msgstr "지금 업데이트" #: mygpo/publisher/templates/publisher/podcast.html:62 #, fuzzy @@ -1154,32 +1236,34 @@ msgstr "최근 업데이트: " msgid "Update interval:" msgstr "지금 업데이트" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -#| msgid "Last update: " -msgid "Next update:" -msgstr "최근 업데이트: " +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "지금 업데이트" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "Twitter" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 #, fuzzy #| msgid "Check" msgid "Feed Check" msgstr "확인" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 #, fuzzy #| msgid "Host Information" msgid "License Information" msgstr "호스트 정보" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to " msgstr "계정 설정에서 링크를 알아내십시오." -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "알 수 없음" @@ -2717,11 +2732,17 @@ msgstr "개인 정보" msgid "Link to gpodder.net" msgstr "gpodder.net에 링크" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "{h}시간 {m}분 {s}초" +#: mygpo/web/templatetags/time.py:44 +#, fuzzy, python-brace-format +#| msgid "{h}h {m}m {s}s" +msgid "{m}m {s}s" +msgstr "{h}시간 {m}분 {s}초" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2747,6 +2768,16 @@ msgstr[1] "" msgid "another site" msgstr "다른 사이트" +#, fuzzy +#~| msgid "Last update: " +#~ msgid "Last update:" +#~ msgstr "최근 업데이트: " + +#, fuzzy +#~| msgid "Last update: " +#~ msgid "Next update:" +#~ msgstr "최근 업데이트: " + #~ msgid "Flattr" #~ msgstr "Flattr" diff --git a/mygpo/locale/nb/LC_MESSAGES/django.po b/mygpo/locale/nb/LC_MESSAGES/django.po index 9eeb7a234..9fc06d07e 100644 --- a/mygpo/locale/nb/LC_MESSAGES/django.po +++ b/mygpo/locale/nb/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2010-02-28 18:33+0100\n" "Last-Translator: Jim Nygård \n" "Language-Team: gpodder <>\n" @@ -103,47 +103,51 @@ msgstr "Type" msgid "Episode URLs" msgstr "Episoder" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Historikk" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Velg et brukernavn" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -151,7 +155,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "" @@ -268,21 +272,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Ikke funnet" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -320,16 +324,16 @@ msgstr "avabonnement" msgid "%(username)s's Subscription List" msgstr "%(username)s sine Abonnement" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, fuzzy, python-format msgid "gpodder.net - Top %(count)d" msgstr "my.gpodder.org - Topp %s" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, fuzzy, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "my.gpodder.org - %s Forslag" @@ -352,7 +356,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "" @@ -482,11 +486,11 @@ msgid "Listeners" msgstr "Lyttere" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "" @@ -560,9 +564,9 @@ msgid "User" msgstr "Velg et brukernavn" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 #, fuzzy msgid "Download" msgstr "lastet ned" @@ -622,10 +626,50 @@ msgstr "" msgid "%d podcasts added" msgstr "Podkaster" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Historikk" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "Podkast nettjeneste" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +#, fuzzy +msgid "listeners" +msgstr "Lyttere" + +#: mygpo/history/templates/episode-history.html:84 +#, fuzzy +msgid "Time" +msgstr "Tittel" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Handling" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Enhet" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Abonnementshistorikk" @@ -659,6 +703,10 @@ msgstr "" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -755,17 +803,101 @@ msgstr "" msgid "Edit" msgstr "Rediger" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "Podkast uten navn" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "Your Episode History" +msgid "Episode History" +msgstr "Din episodehistorikk" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "Podkast uten navn" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "Abonnenter" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +#| msgid "Subscribe" +msgid "Login to Subscribe" +msgstr "Abonnenter" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "Abonnenter" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Avslutt abonnement" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "Abonner på nye podkaster" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "Abonner på nye podkaster" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +msgid "Tags" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Episoder" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -780,7 +912,7 @@ msgid "Link to" msgstr "" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -873,31 +1005,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Episoden uten navn" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "Podkast nettjeneste" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -#, fuzzy -msgid "listeners" -msgstr "Lyttere" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -915,7 +1022,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -930,12 +1037,6 @@ msgstr "Episoder" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "Podkast uten navn" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "" @@ -1077,75 +1178,57 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "Abonnenter" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Podkast" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Enhetsliste" +msgid "Updates" +msgstr "Podkast" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Enhetsliste" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to konto innstillinger for å få " "lenken." -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "Ukjent" @@ -2702,11 +2717,16 @@ msgstr "Personvern" msgid "Link to gpodder.net" msgstr "" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2732,6 +2752,14 @@ msgstr[1] "" msgid "another site" msgstr "" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "Enhetsliste" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "Enhetsliste" + #, fuzzy #~ msgid "No Payment URL available" #~ msgstr "Ingen logo tilgjengelig" diff --git a/mygpo/locale/pl/LC_MESSAGES/django.po b/mygpo/locale/pl/LC_MESSAGES/django.po index c688d0c3b..9191a38d4 100644 --- a/mygpo/locale/pl/LC_MESSAGES/django.po +++ b/mygpo/locale/pl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: mygpo\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2010-01-27 17:38+0100\n" "Last-Translator: Tomasz Dominikowski \n" "Language-Team: Polish \n" @@ -106,49 +106,53 @@ msgstr "Typ" msgid "Episode URLs" msgstr "Odcinki" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Historia" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Nazwa użytkownika" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 #, fuzzy #| msgid "Admin Area" msgid "min ahead" msgstr "Strefa Admina" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -156,7 +160,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 #, fuzzy #| msgid "Publisher Pages" msgid "Publisher Permissions" @@ -280,21 +284,21 @@ msgstr "" msgid "User-Agent" msgstr "User-Agent" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "Brak podcastu z URL {url}" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Nie odnaleziono" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -335,16 +339,16 @@ msgstr "Anuluj subskrypcję" msgid "%(username)s's Subscription List" msgstr "Twoje subskrypcje" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, fuzzy, python-format msgid "gpodder.net - Top %(count)d" msgstr "my.gpodder.org - najlepszych %s" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - Szukaj" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, fuzzy, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "my.gpodder.org - %s sugestii" @@ -367,7 +371,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 #, fuzzy msgid "..." msgstr "więcej..." @@ -503,11 +507,11 @@ msgid "Listeners" msgstr "Słuchacze" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "od" @@ -580,9 +584,9 @@ msgid "User" msgstr "Użytkownik" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "Pobierz" @@ -642,10 +646,50 @@ msgstr "Dostęp klienta" msgid "%d podcasts added" msgstr "Podcasty" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Historia" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "strona" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +#, fuzzy +msgid "listeners" +msgstr "Słuchacze" + +#: mygpo/history/templates/episode-history.html:84 +#, fuzzy +msgid "Time" +msgstr "Tytuł" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Działanie" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Urządzenie" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "Dodaj" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Historia subskrypcji" @@ -679,6 +723,10 @@ msgstr "Teraz" msgid "Earlier" msgstr "Wcześniej" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -776,17 +824,103 @@ msgstr "Dzięki za ocenę!" msgid "Edit" msgstr "Edytuj" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "Podcast bez nazwy" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "Strony Publikującego" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "Usuń ulubione" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "Ulubione" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "Your Episode History" +msgid "Episode History" +msgstr "Historia odcinków" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "Podcast bez nazwy" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "Kanał" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "Subkrybenci" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +msgid "Login to Subscribe" +msgstr "Subkrybenci" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +#, fuzzy +msgid "Subscribe" +msgstr "Subkrybenci" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Anuluj subskrypcję" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "Subskrypcja tego podcastu" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "Subskrypcja tego podcastu" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "Moje Tagi" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Odcinki" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -802,7 +936,7 @@ msgid "Link to" msgstr "Link do" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -913,31 +1047,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Dlaczego odcinek bez nazwy?" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "Strony Publikującego" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "strona" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -#, fuzzy -msgid "listeners" -msgstr "Słuchacze" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -955,7 +1064,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -970,12 +1079,6 @@ msgstr "Odcinki" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "Podcast bez nazwy" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "Powrót na Stronę Podcastów" @@ -1137,77 +1240,59 @@ msgstr "" "strony możesz sprawić by Twoi odwiedzający mogli łatwo subskrybować się do " "Twojego podcastu - szczególnie użytkownicy telefonów komórkowych." -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "Kanał" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "Subkrybenci" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Powrót na Stronę Podcastów" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Lista urządzeń" +msgid "Updates" +msgstr "Zaktualizuj z kanału" #: mygpo/publisher/templates/publisher/podcast.html:62 #, fuzzy msgid "Update interval:" msgstr "Zaktualizuj z kanału" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Lista urządzeń" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 #, fuzzy msgid "Update now" msgstr "Zaktualizuj z kanału" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "Twitter" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to ustawień konta żeby otrzymać link." "" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "Nieznane" @@ -2830,11 +2846,17 @@ msgstr "Prywatność" msgid "Link to gpodder.net" msgstr "Link do gpodder.net" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "{h}h {m}m {s}s" +#: mygpo/web/templatetags/time.py:44 +#, fuzzy, python-brace-format +#| msgid "{h}h {m}m {s}s" +msgid "{m}m {s}s" +msgstr "{h}h {m}m {s}s" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2860,6 +2882,14 @@ msgstr[1] "" msgid "another site" msgstr "inna strona" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "Lista urządzeń" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "Lista urządzeń" + #~ msgid "Flattr" #~ msgstr "Flattr" diff --git a/mygpo/locale/pt/LC_MESSAGES/django.po b/mygpo/locale/pt/LC_MESSAGES/django.po index bd28bd909..a8712bfea 100644 --- a/mygpo/locale/pt/LC_MESSAGES/django.po +++ b/mygpo/locale/pt/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gpodder.net\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2010-06-17 17:01-0000\n" "Last-Translator: Sérgio Marques \n" "Language-Team: PT\n" @@ -107,47 +107,51 @@ msgstr "Tipo" msgid "Episode URLs" msgstr "Episódios" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 #, fuzzy msgid "Base Directory" msgstr "Directório" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Nome de utilizador" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -155,7 +159,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 #, fuzzy #| msgid "Publisher Pages" msgid "Publisher Permissions" @@ -275,21 +279,21 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 #, fuzzy msgid "No user found" msgstr "Não encontrado" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -327,16 +331,16 @@ msgstr "não subscrito" msgid "%(username)s's Subscription List" msgstr "Subscrições de %(username)s's" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "gpodder.net - Top %(count)d" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - Procura" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "gpodder.net - %(count)d sugestões" @@ -359,7 +363,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 #, fuzzy msgid "..." msgstr "mais..." @@ -490,11 +494,11 @@ msgid "Listeners" msgstr "Ouvintes" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "de" @@ -569,9 +573,9 @@ msgid "User" msgstr "Nome de utilizador" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 #, fuzzy msgid "Download" msgstr "Transferido" @@ -631,10 +635,49 @@ msgstr "" msgid "%d podcasts added" msgstr "podcasts" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Histórico" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "sítio web" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +#, fuzzy +msgid "listeners" +msgstr "Ouvintes" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "Hora" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Acção" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Dispositivo" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "Adicionar" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 #, fuzzy msgid "Subscription History" msgstr "Histório de subscrição" @@ -669,6 +712,10 @@ msgstr "Não" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -765,17 +812,103 @@ msgstr "" msgid "Edit" msgstr "Editar" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unnamed Podcast" msgid "Unknown Podcast" msgstr "Podcasts Sem Nome" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "Páginas dos Publicadores" + +#: mygpo/podcasts/templates/episode.html:91 +#, fuzzy +msgid "Remove Favorite" +msgstr "Favorito" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "Favorito" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +msgid "Episode History" +msgstr "Os Melhores Episódios" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "Podcasts Sem Nome" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +#, fuzzy +msgid "subscribers" +msgstr "Subscritores" + +#: mygpo/podcasts/templates/podcast.html:48 +#, fuzzy +#| msgid "Subscribe" +msgid "Login to Subscribe" +msgstr "Subscrever" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "Subscrever" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "Não Subscrito" + +#: mygpo/podcasts/templates/podcast.html:78 +#, fuzzy +msgid "Subscribe on all devices" +msgstr "Subscrever novo(s) Podcast(s)" + +#: mygpo/podcasts/templates/podcast.html:110 +#, fuzzy +msgid "Unsubscribe from all devices " +msgstr "Subscrever novo(s) Podcast(s)" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "As minhas marcações" + +#: mygpo/podcasts/templates/podcast.html:199 +#, fuzzy +msgid "Older Episodes" +msgstr "Episódios" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -790,7 +923,7 @@ msgid "Link to" msgstr "Ligação a" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, fuzzy, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -895,31 +1028,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "Episódio Sem Nome" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "Páginas dos Publicadores" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "sítio web" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -#, fuzzy -msgid "listeners" -msgstr "Ouvintes" - #: mygpo/publisher/templates/publisher/episode.html:55 #, fuzzy msgid "Episode List" @@ -937,7 +1045,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -952,12 +1060,6 @@ msgstr "Estado dos Episódios" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "Podcasts Sem Nome" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "Voltar à Página de Podcasts" @@ -1109,77 +1211,59 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -#, fuzzy -msgid "subscribers" -msgstr "Subscritores" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 #, fuzzy msgid "Go to Podcast Page" msgstr "Voltar à Página de Podcasts" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 +#: mygpo/publisher/templates/publisher/podcast.html:60 #, fuzzy -msgid "Last update:" -msgstr "Lista de Dispositivos" +msgid "Updates" +msgstr "Actualizar da Fonte" #: mygpo/publisher/templates/publisher/podcast.html:62 #, fuzzy msgid "Update interval:" msgstr "Actualizar da Fonte" -#: mygpo/publisher/templates/publisher/podcast.html:63 -#, fuzzy -msgid "Next update:" -msgstr "Lista de Dispositivos" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:106 #, fuzzy msgid "Update now" msgstr "Actualizar da Fonte" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to definicões de conta para obter a " "ligação." -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "Desconhecido" @@ -2726,11 +2742,16 @@ msgstr "Privacidade" msgid "Link to gpodder.net" msgstr "Ligação para gpodder.net" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" @@ -2756,6 +2777,14 @@ msgstr[1] "" msgid "another site" msgstr "outo sítio" +#, fuzzy +#~ msgid "Last update:" +#~ msgstr "Lista de Dispositivos" + +#, fuzzy +#~ msgid "Next update:" +#~ msgstr "Lista de Dispositivos" + #, fuzzy #~ msgid "No Payment URL available" #~ msgstr "Nenhum Logo Disponível" diff --git a/mygpo/locale/tr_TR/LC_MESSAGES/django.po b/mygpo/locale/tr_TR/LC_MESSAGES/django.po index f2e880e8f..f8fe14e48 100644 --- a/mygpo/locale/tr_TR/LC_MESSAGES/django.po +++ b/mygpo/locale/tr_TR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gpodder.net\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-12 18:58+0000\n" +"POT-Creation-Date: 2018-06-29 20:11+0000\n" "PO-Revision-Date: 2012-10-13 12:53+0000\n" "Last-Translator: zeugma \n" "Language-Team: Turkish (Turkey) (http://www.transifex.com/projects/p/mygpo/" @@ -102,46 +102,50 @@ msgstr "Türü" msgid "Episode URLs" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:9 -#: mygpo/administration/templates/admin/hostinfo.html:12 +#: mygpo/administration/templates/admin/hostinfo.html:10 +#: mygpo/administration/templates/admin/hostinfo.html:13 #: mygpo/administration/templates/admin/overview.html:17 msgid "Host Information" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:20 +#: mygpo/administration/templates/admin/hostinfo.html:21 msgid "mygpo Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:31 +#: mygpo/administration/templates/admin/hostinfo.html:32 msgid "Base Directory" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:36 +#: mygpo/administration/templates/admin/hostinfo.html:37 #, fuzzy msgid "Hostname" msgstr "Kullanıcı adı" -#: mygpo/administration/templates/admin/hostinfo.html:41 +#: mygpo/administration/templates/admin/hostinfo.html:42 msgid "Django Version" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:46 +#: mygpo/administration/templates/admin/hostinfo.html:47 msgid "Feed Update Queue" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:49 +#: mygpo/administration/templates/admin/hostinfo.html:50 msgid "min ahead" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:51 +#: mygpo/administration/templates/admin/hostinfo.html:52 msgid "min behind" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:59 +#: mygpo/administration/templates/admin/hostinfo.html:60 msgid "Number of podcasts with outdated search index" msgstr "" -#: mygpo/administration/templates/admin/hostinfo.html:66 +#: mygpo/administration/templates/admin/hostinfo.html:69 +msgid "Average podcast update duration" +msgstr "" + +#: mygpo/administration/templates/admin/hostinfo.html:76 msgid "Scheduled Celery Tasks" msgstr "" @@ -149,7 +153,7 @@ msgstr "" #: mygpo/administration/templates/admin/make-publisher-input.html:12 #: mygpo/administration/templates/admin/make-publisher-result.html:9 #: mygpo/administration/templates/admin/make-publisher-result.html:12 -#: mygpo/administration/views.py:391 +#: mygpo/administration/views.py:404 msgid "Publisher Permissions" msgstr "" @@ -260,20 +264,20 @@ msgstr "" msgid "User-Agent" msgstr "" -#: mygpo/administration/views.py:140 mygpo/administration/views.py:162 +#: mygpo/administration/views.py:153 mygpo/administration/views.py:175 #, python-brace-format msgid "No podcast with URL {url}" msgstr "" -#: mygpo/administration/views.py:316 +#: mygpo/administration/views.py:329 msgid "Provide either username or email address" msgstr "" -#: mygpo/administration/views.py:322 +#: mygpo/administration/views.py:335 msgid "No user found" msgstr "" -#: mygpo/administration/views.py:327 +#: mygpo/administration/views.py:340 #, python-brace-format msgid "User {username} ({email}) activated" msgstr "" @@ -311,16 +315,16 @@ msgstr "" msgid "%(username)s's Subscription List" msgstr "" -#: mygpo/api/simple.py:237 +#: mygpo/api/simple.py:240 #, python-format msgid "gpodder.net - Top %(count)d" msgstr "" -#: mygpo/api/simple.py:272 +#: mygpo/api/simple.py:275 msgid "gpodder.net - Search" msgstr "gpodder.net - Arama" -#: mygpo/api/simple.py:289 +#: mygpo/api/simple.py:292 #, python-format msgid "gpodder.net - %(count)d Suggestions" msgstr "" @@ -343,7 +347,7 @@ msgid "Explore" msgstr "" #: mygpo/directory/templates/carousel.html:81 -#: mygpo/web/templates/episode.html:150 +#: mygpo/podcasts/templates/episode.html:150 msgid "..." msgstr "" @@ -467,11 +471,11 @@ msgid "Listeners" msgstr "" #: mygpo/directory/templates/episode_toplist.html:36 +#: mygpo/history/templates/episode-history.html:51 +#: mygpo/podcasts/templates/episode.html:51 #: mygpo/publisher/templates/publisher/episode.html:33 #: mygpo/share/templates/userpage.html:118 #: mygpo/share/templates/userpage.html:138 -#: mygpo/web/templates/episode-history.html:50 -#: mygpo/web/templates/episode.html:51 msgid "from" msgstr "" @@ -541,9 +545,9 @@ msgid "User" msgstr "" #: mygpo/directory/templates/podcast_lists.html:25 +#: mygpo/history/templates/episode-history.html:53 +#: mygpo/podcasts/templates/episode.html:53 #: mygpo/publisher/templates/publisher/episode.html:35 -#: mygpo/web/templates/episode-history.html:52 -#: mygpo/web/templates/episode.html:53 msgid "Download" msgstr "" @@ -600,10 +604,48 @@ msgstr "" msgid "%d podcasts added" msgstr "Bir podcast ekle" +#: mygpo/history/templates/episode-history.html:47 +#: mygpo/history/templates/episode-history.html:81 +#: mygpo/web/templates/device.html:73 mygpo/web/templatetags/menu.py:51 +msgid "History" +msgstr "Geçmiş" + +#: mygpo/history/templates/episode-history.html:58 +#: mygpo/podcasts/templates/episode.html:58 +#: mygpo/podcasts/templates/podcast-base.html:54 +#: mygpo/publisher/templates/publisher/episode.html:40 +#: mygpo/publisher/templates/publisher/podcast.html:39 +#, fuzzy +msgid "Website" +msgstr "web sitesi" + +#: mygpo/history/templates/episode-history.html:63 +#: mygpo/podcasts/templates/episode.html:63 +#: mygpo/publisher/templates/publisher/episode.html:45 +msgid "listeners" +msgstr "" + +#: mygpo/history/templates/episode-history.html:84 +msgid "Time" +msgstr "Zaman" + +#: mygpo/history/templates/episode-history.html:85 +msgid "Action" +msgstr "Eylem" + +#: mygpo/history/templates/episode-history.html:86 +#: mygpo/web/templatetags/menu.py:50 +msgid "Device" +msgstr "Cihaz" + +#: mygpo/history/templates/episode-history.html:127 +msgid "Add" +msgstr "Ekle" + #: mygpo/history/templates/history.html:12 #: mygpo/history/templates/history.html:15 -#: mygpo/web/templates/podcast-history.html:32 -#: mygpo/web/templates/podcast.html:143 +#: mygpo/history/templates/podcast-history.html:32 +#: mygpo/podcasts/templates/podcast.html:143 msgid "Subscription History" msgstr "" @@ -636,6 +678,10 @@ msgstr "" msgid "Earlier" msgstr "" +#: mygpo/history/templates/podcast-history.html:47 +msgid "no history yet" +msgstr "" + #: mygpo/podcastlists/templates/list.html:28 #, python-format msgid "\"%(list_title)s\" by %(ownername)s" @@ -727,17 +773,97 @@ msgstr "" msgid "Edit" msgstr "Düzenle" -#: mygpo/podcasts/models.py:688 +#: mygpo/podcasts/models.py:704 #, fuzzy #| msgid "Unknown" msgid "Unknown Podcast" msgstr "Bilinmeyen" -#: mygpo/podcasts/models.py:690 +#: mygpo/podcasts/models.py:706 #, python-brace-format msgid "Unknown Podcast from {domain}" msgstr "" +#: mygpo/podcasts/templates/episode.html:85 +#: mygpo/podcasts/templates/episodes.html:27 +#: mygpo/podcasts/templates/podcast.html:39 +#: mygpo/publisher/templates/publisher/episode.html:31 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/info.html:9 +#: mygpo/publisher/templates/publisher/info.html:26 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Publisher Pages" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:91 +msgid "Remove Favorite" +msgstr "" + +#: mygpo/podcasts/templates/episode.html:95 +msgid "Favorite" +msgstr "Favori" + +#: mygpo/podcasts/templates/episode.html:103 +#, fuzzy +#| msgid "History" +msgid "Episode History" +msgstr "Geçmiş" + +#: mygpo/podcasts/templates/podcast-base.html:39 +#: mygpo/publisher/templates/publisher/episodes.html:23 +#: mygpo/publisher/templates/publisher/podcast.html:27 +msgid "Unnamed Podcast" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:44 +#: mygpo/publisher/templates/publisher/podcast.html:29 +msgid "by" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:50 +#: mygpo/publisher/templates/publisher/podcast.html:35 +#: mygpo/share/templates/share/favorites.html:29 +msgid "Feed" +msgstr "" + +#: mygpo/podcasts/templates/podcast-base.html:65 +#: mygpo/publisher/templates/publisher/podcast.html:44 +msgid "subscribers" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:48 +msgid "Login to Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:59 +#: mygpo/suggestions/templates/suggestions.html:31 +#: mygpo/web/templates/subscribe.html:11 mygpo/web/templates/subscribe.html:36 +msgid "Subscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:67 mygpo/web/templates/device.html:31 +msgid "Unsubscribe" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:78 +msgid "Subscribe on all devices" +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:110 +msgid "Unsubscribe from all devices " +msgstr "" + +#: mygpo/podcasts/templates/podcast.html:149 +#: mygpo/podcasts/templates/podcast.html:164 +#, fuzzy +#| msgid "My Tags" +msgid "Tags" +msgstr "Etiketlerim" + +#: mygpo/podcasts/templates/podcast.html:199 +msgid "Older Episodes" +msgstr "" + #: mygpo/publisher/forms.py:5 #: mygpo/publisher/templates/publisher/episode.html:60 msgid "URL" @@ -752,7 +878,7 @@ msgid "Link to" msgstr "" #: mygpo/publisher/templates/link.html:17 -#: mygpo/publisher/templates/publisher/podcast.html:171 +#: mygpo/publisher/templates/publisher/podcast.html:209 #, python-format msgid "" "You can paste this code on your website, so users of %(sitename)s can " @@ -840,30 +966,6 @@ msgstr "" msgid "Unnamed Episode" msgstr "" -#: mygpo/publisher/templates/publisher/episode.html:31 -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/info.html:9 -#: mygpo/publisher/templates/publisher/info.html:26 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/episode.html:85 mygpo/web/templates/episodes.html:27 -#: mygpo/web/templates/podcast.html:39 -msgid "Publisher Pages" -msgstr "" - -#: mygpo/publisher/templates/publisher/episode.html:40 -#: mygpo/publisher/templates/publisher/podcast.html:38 -#: mygpo/web/templates/episode-history.html:57 -#: mygpo/web/templates/episode.html:58 mygpo/web/templates/podcast-base.html:54 -#, fuzzy -msgid "Website" -msgstr "web sitesi" - -#: mygpo/publisher/templates/publisher/episode.html:45 -#: mygpo/web/templates/episode-history.html:62 -#: mygpo/web/templates/episode.html:63 -msgid "listeners" -msgstr "" - #: mygpo/publisher/templates/publisher/episode.html:55 msgid "Episode List" msgstr "" @@ -880,7 +982,7 @@ msgid "" msgstr "" #: mygpo/publisher/templates/publisher/episode.html:72 -#: mygpo/publisher/templates/publisher/podcast.html:91 +#: mygpo/publisher/templates/publisher/podcast.html:129 #: mygpo/web/templates/account.html:65 mygpo/web/templates/account.html:142 #: mygpo/web/templates/device-edit.html:53 msgid "Save" @@ -894,12 +996,6 @@ msgstr "" msgid "Last update: " msgstr "" -#: mygpo/publisher/templates/publisher/episodes.html:23 -#: mygpo/publisher/templates/publisher/podcast.html:26 -#: mygpo/web/templates/podcast-base.html:39 -msgid "Unnamed Podcast" -msgstr "" - #: mygpo/publisher/templates/publisher/episodes.html:24 msgid "Return to Podcast Page" msgstr "" @@ -1036,71 +1132,56 @@ msgid "" "podcast - especially for users of mobile phones." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:28 -#: mygpo/web/templates/podcast-base.html:44 -msgid "by" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:34 -#: mygpo/share/templates/share/favorites.html:29 -#: mygpo/web/templates/podcast-base.html:50 -msgid "Feed" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:43 -#: mygpo/web/templates/podcast-base.html:65 -msgid "subscribers" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:48 +#: mygpo/publisher/templates/publisher/podcast.html:49 #, python-format msgid "" "This is the publisher page of %(ptitle)s. You can see some " "stats and provide additional data for the podcast page." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:49 +#: mygpo/publisher/templates/publisher/podcast.html:50 msgid "Go to Podcast Page" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:56 +#: mygpo/publisher/templates/publisher/podcast.html:57 msgid "The podcast information is regularly retrieved from the podcast feed" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:59 -msgid "Timing" -msgstr "" - -#: mygpo/publisher/templates/publisher/podcast.html:61 -msgid "Last update:" -msgstr "" +#: mygpo/publisher/templates/publisher/podcast.html:60 +#, fuzzy +msgid "Updates" +msgstr "Bir podcast ekle" #: mygpo/publisher/templates/publisher/podcast.html:62 msgid "Update interval:" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:63 -msgid "Next update:" +#: mygpo/publisher/templates/publisher/podcast.html:86 +msgid "Successful" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:68 +#: mygpo/publisher/templates/publisher/podcast.html:88 +msgid "Error" +msgstr "" + +#: mygpo/publisher/templates/publisher/podcast.html:106 msgid "Update now" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:79 mygpo/web/forms.py:70 +#: mygpo/publisher/templates/publisher/podcast.html:117 mygpo/web/forms.py:70 #: mygpo/web/templates/base.html:160 mygpo/web/templates/home.html:180 msgid "Twitter" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:97 +#: mygpo/publisher/templates/publisher/podcast.html:135 msgid "Feed Check" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:105 +#: mygpo/publisher/templates/publisher/podcast.html:143 msgid "PubSubHubbub" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:114 +#: mygpo/publisher/templates/publisher/podcast.html:152 #, python-format msgid "" "If you publish your podcast feed through a %(hub)s and should " "update immediatelly for each new episode." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:123 +#: mygpo/publisher/templates/publisher/podcast.html:161 #, python-format msgid "" "Your podcast is published through %(hub)s but our " "subscription has not yet been verified." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:128 +#: mygpo/publisher/templates/publisher/podcast.html:166 #, python-format msgid "" "We did not find a hub in your podcast feed. Your feed is updated regularly, " "but there might be some delay until a new episode shows up on %(sitename)s." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:140 +#: mygpo/publisher/templates/publisher/podcast.html:178 msgid "License Information" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:148 +#: mygpo/publisher/templates/publisher/podcast.html:186 #, python-format msgid "" "You should include license information in your feed so that users and " "%(sitename)s can know, under which conditions your content can be used." msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:152 +#: mygpo/publisher/templates/publisher/podcast.html:190 #, python-format msgid "" "We found the following license in your podcast: " "%(license)s" msgstr "" -#: mygpo/publisher/templates/publisher/podcast.html:156 +#: mygpo/publisher/templates/publisher/podcast.html:194 msgid "" "We did not find a license in your podcast feed. Refer to " msgstr "" -#: mygpo/web/templatetags/devices.py:31 +#: mygpo/web/templatetags/devices.py:32 msgid "Unknown" msgstr "Bilinmeyen" @@ -2536,11 +2543,16 @@ msgstr "Gizlilik" msgid "Link to gpodder.net" msgstr "" -#: mygpo/web/templatetags/time.py:38 +#: mygpo/web/templatetags/time.py:42 #, python-brace-format msgid "{h}h {m}m {s}s" msgstr "" +#: mygpo/web/templatetags/time.py:44 +#, python-brace-format +msgid "{m}m {s}s" +msgstr "" + #: mygpo/web/utils.py:281 #, python-format msgid "%(weeks)d week" From 6f71f0141ec223e45b44d3f1ba1df08f64e0f87b Mon Sep 17 00:00:00 2001 From: Guilherme Date: Sun, 1 Jul 2018 23:32:24 +0200 Subject: [PATCH 093/106] [clientconfig] Changed mygpo to https --- static/clientconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/clientconfig.json b/static/clientconfig.json index 052d9797d..dabc11639 100644 --- a/static/clientconfig.json +++ b/static/clientconfig.json @@ -1,6 +1,6 @@ { "mygpo": { - "baseurl": "http://gpodder.net/" + "baseurl": "https://gpodder.net/" }, "mygpo-feedservice": { From 9d4c868acc82285a0ee4a01daeb8515743893fef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 4 Jul 2018 07:15:08 +0000 Subject: [PATCH 094/106] Bump transifex-client from 0.13.3 to 0.13.4 Bumps [transifex-client](https://github.com/transifex/transifex-client) from 0.13.3 to 0.13.4. - [Release notes](https://github.com/transifex/transifex-client/releases) - [Commits](https://github.com/transifex/transifex-client/compare/0.13.3...0.13.4) Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 0b8f05916..a6a5465fc 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -transifex-client==0.13.3 +transifex-client==0.13.4 sphinx pep8 flake8 From 9868450f2fd533072b049fc5447dad8f97c878e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 4 Jul 2018 07:15:30 +0000 Subject: [PATCH 095/106] Bump gunicorn from 19.8.1 to 19.9.0 Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 19.8.1 to 19.9.0. - [Release notes](https://github.com/benoitc/gunicorn/releases) - [Commits](https://github.com/benoitc/gunicorn/compare/19.8.1...19.9.0) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6f9d855eb..c8569cb57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ dj-database-url==0.5.0 django-redis-sessions==0.6.1 python3-memcached==1.51 feedparser==5.2.1 -gunicorn==19.8.1 +gunicorn==19.9.0 html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 From 6b264bba6443fc989882c4942f9d4a4cbf1c18d4 Mon Sep 17 00:00:00 2001 From: Guilherme Date: Wed, 4 Jul 2018 23:19:44 +0200 Subject: [PATCH 096/106] [config,doc] Added make option to configure development --- doc/dev/installation.rst | 6 ++++++ makefile | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/doc/dev/installation.rst b/doc/dev/installation.rst index b1bb8d95a..4ec2219ca 100644 --- a/doc/dev/installation.rst +++ b/doc/dev/installation.rst @@ -59,6 +59,12 @@ For a development configuration you will probably want to use the following echo postgres://mygpo:mygpo@localhost/mygpo > envs/local/DATABASE_URL echo True > envs/local/DEBUG +On an Debian/Ubuntu based system, you can perform this configuration with + +.. code-block:: bash + + make dev-config + See :ref:`configuration` for further information. diff --git a/makefile b/makefile index 2f50348c1..e9bf59b45 100644 --- a/makefile +++ b/makefile @@ -4,6 +4,13 @@ help: @echo 'make test run tests and show coverage report' @echo 'make clean clean up files' +dev-config: + mkdir -p envs/local + echo django.core.mail.backends.console.EmailBackend > envs/local/EMAIL_BACKEND + echo secret > envs/local/SECRET_KEY + echo postgres://mygpo:mygpo@localhost/mygpo > envs/local/DATABASE_URL + echo True > envs/local/DEBUG + test: envs/test/MEDIA_ROOT # assume defined media root directory, empty before running tests rm -rf $(shell cat envs/test/MEDIA_ROOT) From 72f1c3ba0edb51dcadc1eb06b68a54aeda1e41a1 Mon Sep 17 00:00:00 2001 From: Guilherme Date: Thu, 5 Jul 2018 21:58:05 +0200 Subject: [PATCH 097/106] Added .pytest_cache to .gitignore .pytest_cache seems to be generated when running integration tests --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d818cf3cf..98c8ecfac 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ envs notebooks/ .cache +.pytest_cache \ No newline at end of file From e28c0d759d13722619618f50a55665e2412450ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 19 Jul 2018 07:37:03 +0000 Subject: [PATCH 098/106] Bump celery from 4.1.0 to 4.2.1 Bumps [celery](https://github.com/celery/celery) from 4.1.0 to 4.2.1. - [Release notes](https://github.com/celery/celery/releases) - [Changelog](https://github.com/celery/celery/blob/master/Changelog) - [Commits](https://github.com/celery/celery/compare/v4.1.0...v4.2.1) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6f9d855eb..5dfd563bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Django==2.0.6 Babel==2.6.0 Pillow==5.1.0 -celery[redis]==4.1.0 +celery[redis]==4.2.1 dj-database-url==0.5.0 django-redis-sessions==0.6.1 python3-memcached==1.51 From dfdf87b328c67e1191364c460042fb5c87d3422e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 31 Jul 2018 05:54:53 +0000 Subject: [PATCH 099/106] Bump pillow from 5.1.0 to 5.2.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/5.1.0...5.2.0) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5dfd563bc..65113be80 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ Django==2.0.6 Babel==2.6.0 -Pillow==5.1.0 +Pillow==5.2.0 celery[redis]==4.2.1 dj-database-url==0.5.0 django-redis-sessions==0.6.1 From 3f75d54e71e65bdd692c2ae9d83bdf80fe844603 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 31 Jul 2018 05:55:22 +0000 Subject: [PATCH 100/106] Bump django from 2.0.6 to 2.0.7 Bumps [django](https://www.djangoproject.com/) from 2.0.6 to 2.0.7. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5dfd563bc..9505a24d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.6 +Django==2.0.7 Babel==2.6.0 Pillow==5.1.0 celery[redis]==4.2.1 From 5736e20a88c56e08ab05a127dbea5c79a5d3a11a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 1 Aug 2018 07:34:31 +0000 Subject: [PATCH 101/106] Bump psycopg2cffi from 2.7.7 to 2.8.1 Bumps [psycopg2cffi](https://github.com/chtd/psycopg2cffi) from 2.7.7 to 2.8.1. - [Release notes](https://github.com/chtd/psycopg2cffi/releases) - [Commits](https://github.com/chtd/psycopg2cffi/compare/2.7.7...2.8.1) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 231842cd1..26aebc523 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ gunicorn==19.9.0 html2text==2018.1.9 markdown2==2.3.5 oauth2client==4.1.2 -psycopg2cffi==2.7.7 +psycopg2cffi==2.8.1 python-dateutil==2.7.3 redis==2.10.6 django-celery-results==1.0.1 From b622f2fb88e33f38614511c5cfe0801b6ae34121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Fri, 3 Aug 2018 18:45:19 +0200 Subject: [PATCH 102/106] Fix broken test --- mygpo/api/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mygpo/api/tests.py b/mygpo/api/tests.py index 5bff249a0..9956d0864 100644 --- a/mygpo/api/tests.py +++ b/mygpo/api/tests.py @@ -201,14 +201,14 @@ def setUp(self): defaults = { 'title': 'My Podcast', }, - ) + ).object self.episode = Episode.objects.get_or_create_for_url( self.podcast, 'http://example.com/directory-podcast/1.mp3', defaults = { 'title': 'My Episode', }, - ) + ).object User = get_user_model() self.password = 'asdf' self.username = 'adv-api-user' From a2b587217d5288fc579941568cfd6ed8289223cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 15 Aug 2018 15:48:14 +0000 Subject: [PATCH 103/106] Bump django from 2.0.7 to 2.0.8 Bumps [django](https://www.djangoproject.com/) from 2.0.7 to 2.0.8. Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 26aebc523..8a12d4b8c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==2.0.7 +Django==2.0.8 Babel==2.6.0 Pillow==5.2.0 celery[redis]==4.2.1 From 99c8b1ca376afcc74d3b5cba9e76a1119349e25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Wed, 15 Aug 2018 18:19:31 +0200 Subject: [PATCH 104/106] Remove support for Python 3.5 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b0a56ea7e..3b7c25855 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: python python: - - "3.5" - "3.6" - "3.6-dev" - "3.7-dev" From f334e3c21668414b1da695e48f1e044421e06cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Wed, 15 Aug 2018 20:34:27 +0200 Subject: [PATCH 105/106] Fix API response when there are no actions to return --- mygpo/api/advanced/__init__.py | 8 ++++++-- mygpo/api/tests.py | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mygpo/api/advanced/__init__.py b/mygpo/api/advanced/__init__.py index a4b0d20df..26bb1fae9 100644 --- a/mygpo/api/advanced/__init__.py +++ b/mygpo/api/advanced/__init__.py @@ -171,8 +171,12 @@ def get_episode_changes(user, podcast, device, since, until, aggregated, version if aggregated: actions = list(dict( (a['episode'], a) for a in actions ).values()) - timestamp = history[-1].timestamp - return {'actions': actions, 'timestamp': get_timestamp(timestamp)} + if history: + ts = get_timestamp(history[-1].timestamp) + else: + ts = get_timestamp(until) + + return {'actions': actions, 'timestamp': ts} def episode_action_json(history, user): diff --git a/mygpo/api/tests.py b/mygpo/api/tests.py index 9956d0864..7f093f471 100644 --- a/mygpo/api/tests.py +++ b/mygpo/api/tests.py @@ -267,3 +267,28 @@ def test_limit_actions(self): get_timestamp(timestamps[9]), response_obj['timestamp'] ) + + + def test_no_actions(self): + """ Test when there are no actions to return """ + + t1 = get_timestamp(datetime.utcnow()) + + url = reverse(episodes, kwargs={ + 'version': '2', + 'username': self.user.username, + }) + response = self.client.get(url, {'since': '0'}, **self.extra) + self.assertEqual(response.status_code, 200, response.content) + response_obj = json.loads(response.content.decode('utf-8')) + actions = response_obj['actions'] + + # 10 actions should be returned + self.assertEqual(len(actions), 0) + + returned = response_obj['timestamp'] + t2 = get_timestamp(datetime.utcnow()) + # the `timestamp` field in the response should be the timestamp of the + # last returned action + self.assertGreaterEqual(returned, t1) + self.assertGreaterEqual(t2, returned) From 6a53bdda4f669412b5cfb2ba3bf28a02daf6bb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Wed, 15 Aug 2018 22:00:24 +0200 Subject: [PATCH 106/106] Add admin function to resend activation email --- .../templates/admin/overview.html | 1 + .../templates/admin/resend-acivation.html | 41 +++++++++++++++++++ mygpo/administration/urls.py | 4 ++ mygpo/administration/views.py | 39 +++++++++++++++++- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 mygpo/administration/templates/admin/resend-acivation.html diff --git a/mygpo/administration/templates/admin/overview.html b/mygpo/administration/templates/admin/overview.html index 1c542533b..4fea5e4ba 100644 --- a/mygpo/administration/templates/admin/overview.html +++ b/mygpo/administration/templates/admin/overview.html @@ -20,6 +20,7 @@

    {% trans "Admin Area" %}

  • {% trans "User-Agent Stats" %}
  • {% trans "General Stats" %} ({% trans "JSON" %})
  • {% trans "Activate User" %}
  • +
  • {% trans "Resend Activation Email" %}
  • {% trans "Assign Publisher Permissions" %}
  • diff --git a/mygpo/administration/templates/admin/resend-acivation.html b/mygpo/administration/templates/admin/resend-acivation.html new file mode 100644 index 000000000..054508139 --- /dev/null +++ b/mygpo/administration/templates/admin/resend-acivation.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{% load i18n %} +{% load podcasts %} + +{% load menu %} +{% block mainmenu %}{{ "/admin/"|main_menu }}{% endblock %} +{% block sectionmenu %}{{ "/admin/"|section_menu:"Admin" }}{% endblock %} + +{% block title %}{% trans "Activate User" %}{% endblock %} + +{% block header %} +

    {% trans "Resend Activation email" %}

    +{% endblock %} + +{% block content %} +
    + {% csrf_token %} + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    + +{% endblock %} + diff --git a/mygpo/administration/urls.py b/mygpo/administration/urls.py index 1e033b84f..36a241ac7 100644 --- a/mygpo/administration/urls.py +++ b/mygpo/administration/urls.py @@ -52,6 +52,10 @@ views.ActivateUserView.as_view(), name='admin-activate-user'), + path('resend-activation-email', + views.ResendActivationEmail.as_view(), + name='admin-resend-activation'), + path('make-publisher/input', views.MakePublisherInput.as_view(), name='admin-make-publisher-input'), diff --git a/mygpo/administration/views.py b/mygpo/administration/views.py index 16353feea..2a19d7b37 100644 --- a/mygpo/administration/views.py +++ b/mygpo/administration/views.py @@ -27,6 +27,7 @@ from mygpo.administration.group import PodcastGrouper from mygpo.maintenance.merge import PodcastMerger, IncorrectMergeException from mygpo.administration.clients import UserAgentStats, ClientStats +from mygpo.users.views.registration import send_activation_email from mygpo.administration.tasks import merge_podcasts from mygpo.utils import get_git_head from mygpo.data.models import PodcastUpdateResult @@ -330,7 +331,7 @@ def post(self, request): return HttpResponseRedirect(reverse('admin-activate-user')) try: - user = UserProxy.objects.by_username_or_email(username, email) + user = UserProxy.objects.all().by_username_or_email(username, email) except UserProxy.DoesNotExist: messages.error(request, _('No user found')) return HttpResponseRedirect(reverse('admin-activate-user')) @@ -342,6 +343,42 @@ def post(self, request): return HttpResponseRedirect(reverse('admin-activate-user')) +class ResendActivationEmail(AdminView): + """ Resends the users activation email """ + + template_name = 'admin/resend-acivation.html' + + def get(self, request): + return self.render_to_response({}) + + def post(self, request): + + username = request.POST.get('username') + email = request.POST.get('email') + + if not (username or email): + messages.error(request, + _('Provide either username or email address')) + return HttpResponseRedirect(reverse('admin-resend-activation')) + + try: + user = UserProxy.objects.all().by_username_or_email(username, email) + except UserProxy.DoesNotExist: + messages.error(request, _('No user found')) + return HttpResponseRedirect(reverse('admin-resend-activation')) + + if user.is_active: + messages.success(request, 'User {username} is already activated') + + else: + send_activation_email(user, request) + messages.success(request, + _('Email for {username} ({email}) resent'.format( + username=user.username, email=user.email))) + + return HttpResponseRedirect(reverse('admin-resend-activation')) + + class MakePublisherInput(AdminView): """ Get all information necessary for making someone publisher """