Author SHA1 Message Date
Jordan Petridis f50ea21499 wip 2019-10-23 20:42:05 +03:00
Jordan Petridis 630804c5b5 meson: Bump the required version of deps in order to build 2019-10-23 18:40:38 +03:00
Jordan Petridis 6cce4183e9 Flatpak: disable handy introspection generation 2019-10-20 20:25:18 +03:00
Jordan Petridis 35bd0d625c p-data: Update the user agent 2019-10-20 20:22:36 +03:00
Jordan Petridis 073d00b45b Update cargo deps 2019-10-20 20:21:32 +03:00
Jordan Petridis 982cb13e7e shows_view: remove reduntant import 2019-10-20 20:14:11 +03:00
Jordan Petridis 6d3d4c8339 meson: install nightly icon 2019-10-20 20:03:07 +03:00
Jordan Petridis 911e420c24 Flatpak: remove dri access
There was a time where an inline videoplayer was a possibility,
and this would be needed for the GL widget, but it ain't
happening.
2019-10-20 19:40:46 +03:00
Jordan Petridis e69ff0325e Flatpak: remove dconf permissions.
Yay 🎉🎉🎉
2019-10-20 19:38:15 +03:00
Jordan Petridis 7c1353a8aa Flatpak: Add fallback-x11 socket
This makes it so the x11 socket is made available only when
there is no wayland socket available in the system.
2019-10-20 19:35:05 +03:00
Jordan Petridis 4ce9a172b8 Merge branch 'wip/sadiq/small-width' into 'master'
Let the window work on smaller screens

See merge request World/podcasts!122
2019-10-20 16:22:16 +00:00
Mohammed Sadiq 61a7b24084 headerbar: Use a smaller width for entry
So that it fits better on smaller screens
2019-10-19 15:26:29 +00:00
Mohammed Sadiq 8b2ca19f1a episode_widget: Allow reaching smaller widths
So that the window fits fine on smaller screens
2019-10-19 15:26:29 +00:00
Jordan Petridis deafa8f4d3 Merge branch 'fix-142' into 'master'
Show app icon in PulseAudio settings

Closes #142

See merge request World/podcasts!125
2019-10-19 15:25:59 +00:00
James Westman c739935335 Show app icon in PulseAudio settings
According to the docs, `gtk::Window::set_default_icon_name` should take care of
this, but it evidently isn't. So we'll use the environment variable method
instead.

Fixes #142
2019-10-19 01:26:46 -05:00
Asier Sarasua Garmendia 34e4a4f483 Add Basque translation 2019-10-18 08:00:51 +00:00
Jordan Petridis 85c485509c Merge branch 'update_mpris_permissions' into 'master'
Remove unnecessary MPRIS Flatpak permissions

See merge request World/podcasts!124
2019-10-10 13:08:12 +00:00
Felix Häcker 026145e0c7 Remove unnecessary MPRIS Flatpak permissions 2019-10-09 21:03:13 +02:00
Jordan Petridis bb0cf5b547 Merge branch 'update-coc' into 'master'
Update the Code of Conduct to the official GNOME CoC

See merge request World/podcasts!123
2019-10-08 17:37:43 +00:00
Christopher Davis d8acffa844 Update the Code of Conduct to the official GNOME CoC 2019-10-08 09:55:20 -07:00
Jordan Petridis a1f1cddcbe Merge branch 'revert-d8496fe4' into 'master'
Revert "Flatpak: use the 3.32 runtime version"

See merge request World/podcasts!115
2019-10-04 12:28:24 +00:00
Christopher Davis d19612bb3c README: use new nightly and rust-stable locations
freedeskop-sdk is at 19.08 now, and sdk.g.o -> nightly.g.o
2019-10-04 11:53:05 +00:00
Christopher Davis 30e81961e8 Revert "Flatpak: use the 3.32 runtime version"
This reverts commit d8496fe4c4
2019-10-04 11:53:05 +00:00
Jordan Petridis a9873da802 cargo fmt 2019-10-04 14:52:19 +03:00
Jordan Petridis 6046e62f11 Flatpak: update libhandy version to 0.11 2019-10-04 14:52:19 +03:00
Jordan Petridis eb032619a0 Merge branch 'fix-link-and-typo' into 'master'
Fix link and typo

See merge request World/podcasts!121
2019-09-29 16:02:43 +00:00
Julian Hofer d98f0a20a8 Fix link and typo 2019-09-24 21:34:10 +02:00
Jordan Petridis 945b40249c Do not hardcode deny(warnings) in the source code
When a new version of the compiler introduces a new warning
it makes your perfectly fine older release require manual
patching in order to build again.
2019-09-13 03:05:38 +03:00
Jordan Petridis 1192642811 update cargo deps 2019-09-13 02:55:10 +03:00
Jordan Petridis 70772a61a9 meson.build: stop checking for cargo vendor
Since rust 1.37 release its now part of cargo itself.
2019-09-13 01:24:25 +03:00
Sabri Ünal 66b3f031a5 Update Turkish translation 2019-09-09 06:49:59 +00:00
Jordan Petridis 56a9c115f8 Merge branch 'reset-playback-rate' into 'master'
player:	Playback rate is reset when episode is started

Closes #65

See merge request World/podcasts!116
2019-09-04 14:45:45 +00:00
Julian Hofer bd10ed93af player: Playback rate is reset when episode is started
When an episode	is started the "radio_normal"-button is
set to true.
Fixes #65
2019-09-04 17:10:45 +03:00
Jordan Petridis c3351f01e4 Merge branch 'url-parsing' into 'master'
headerbar: Refactor 'add' styling after url parsing

See merge request World/podcasts!119
2019-09-04 14:04:50 +00:00
FeuRenard 1d13384f6c headerbar: Refactor 'add' styling after url parsing
The current code includes many duplications.

I extract a single parameterized style function
accompanied by two delegate functions.

https://gitlab.gnome.org/World/podcasts/issues/45
2019-09-03 22:11:24 +02:00
Jordan Petridis 598e225b00 Merge branch 'zbrown/subclass-gtkapp' into 'master'
Subclass GtkApp

See merge request World/podcasts!113
2019-09-02 21:35:43 +00:00
Jordan Petridis d8090a8172 Upgrade some cargo deps 2019-09-02 23:55:56 +03:00
Zander Brown f47413686c Use a custom GtkApplication instead of GtkApplication direct 2019-09-02 23:55:56 +03:00
Zander Brown c8a194cf32 Use gtk-rs 0.7.0 2019-09-02 23:55:56 +03:00
Jordan Petridis f07ac1f322 Merge branch 'url-creds' into 'master'
Parse url login info into basic auth header

Closes #124

See merge request World/podcasts!120
2019-09-02 18:49:42 +00:00
Peter Rice 02561b614f Parse url login info into basic auth header 2019-09-01 08:11:23 -04:00
Anders Jonsson 6ca2d02c69 Update Swedish translation 2019-08-22 15:54:41 +00:00
Jordan Petridis 300e103fed Merge branch 'cargo-update' into 'master'
build: Update Cargo.lock

Closes #147

See merge request World/podcasts!118
2019-08-05 00:34:13 +00:00
Christopher Davis a77c0e5f32 build: Update Cargo.lock
Fixes https://gitlab.gnome.org/World/podcasts/issues/147
2019-08-04 04:04:15 -07:00
Jordan Petridis cf644d508d Merge branch '145-contributing-merge-request-process' into 'master'
Resolve "CONTRIBUTING - Merge Request Process"

Closes #145

See merge request World/podcasts!117
2019-07-29 15:49:46 +00:00
Zander 452be8a22f Switch make for meson/ninja 2019-07-27 20:00:11 +00:00
Jordan Petridis 1e816f65a5 Merge branch 'alatiera/ci-3-32' into 'master'
Flatpak: use the 3.32 runtime version

See merge request World/podcasts!114
2019-07-16 08:05:17 +00:00
Jordan Petridis d8496fe4c4 Flatpak: use the 3.32 runtime version
Until somebody find time to fix the CI image to work
with the 19.08 fd.o base.
2019-07-16 10:34:23 +03:00
Kukuh Syafaat ca10956014 Update Indonesian translation 2019-07-11 08:22:04 +00:00
Goran Vidović 3984b84b6c Update Croatian translation 2019-06-22 20:30:46 +00:00
Daniel Mustieles 493114e825 Update Spanish translation 2019-06-19 10:34:04 +00:00
Yuri Gomes 7856b6fd27 Update Brazilian Portuguese translation 2019-06-13 18:42:37 +00:00
Jordan Petridis 957b47680d Merge branch 'empty-url' into 'master'
headerbar: Don't show error when add input is empty

See merge request World/podcasts!108
2019-06-09 04:18:48 +00:00
FeuRenard 86f6a944ff headerbar: Don't show error when add input is empty
When you add a feed url and clear the input after entering some
characters, then the error label is shown. The empty url check in the
code is broken, because it is performed on a version of the url which
is not the original input and instead a version modified in the code.

I store in a variable whether the original input url is empty.

part of #45
2019-06-09 06:17:22 +03:00
Jordan Petridis 2631173a0d Merge branch 'red-border' into 'master'
headerbar: Add ERROR style to Add entry

See merge request World/podcasts!109
2019-06-09 03:12:33 +00:00
FeuRenard 0dc1f810d2 headerbar: Add ERROR style to Add entry
When you enter an invalid or duplicate URL an error message is shown.
But GTK's error style is not applied to the entry.

This commit applies GTK's error style to the URL entry when appropriate.

part of #45
2019-06-09 05:48:02 +03:00
Jordan Petridis 0b8d19fbbe Merge branch 'replace-label' into 'master'
headerbar: Replace Add error label with icon

See merge request World/podcasts!110
2019-06-09 02:38:40 +00:00
FeuRenard 51bbe4193b headerbar: Replace Add error label with icon
Validation errors of an entry should be displayed by an icon with a
tooltip explaining the reason.

For the situation when you add a podcast URL I remove the existing
error label and show the former label text as tooltip of an error icon
in the entry.
2019-06-09 05:29:53 +03:00
Jordan Petridis d5945f6ac6 Merge branch 'patreon_rss_fix' into 'master'
p-data/utils/url_cleaner: Keep query pairs in URLs

Closes #139

See merge request World/podcasts!111
2019-06-09 01:54:56 +00:00
Liban Hannan 539f8824d1 p-data/utils/url_cleaner: Keep query pairs in URLs
Removing query pairs prevents some podcasts from downloading. Patreon
private feeds (perhaps others) use tokens in query pairs to
authenticate downloads.
2019-06-09 01:27:10 +00:00
Jordan Petridis 539efc3f7b Merge branch 'code-of-conduct' into 'master'
Add Code Of Conduct

See merge request World/podcasts!112
2019-06-07 23:37:16 +00:00
Christopher Davis c0861ba796 Add Code Of Conduct
This adopts the Contributor Covenant as the Code of Conduct
for all project spaces.
2019-06-07 16:03:45 -07:00
Balázs Úr 52d308e5ae Update Hungarian translation 2019-06-03 20:27:55 +00:00
Jiri Grönroos 57f3afae97 Update Finnish translation 2019-06-01 17:21:14 +00:00
Ask Hjorth Larsen 80ff75debc Update Danish translation 2019-05-28 01:34:31 +00:00
Piotr Drąg d3a3bd2784 Update Polish translation 2019-05-19 10:38:13 +00:00
Jordan Petridis 2dcccb804e Merge branch 'piotrdrag/unicode-typography' into 'master'
Use a Unicode apostrophe in a new translatable string

See merge request World/podcasts!107
2019-05-18 12:55:23 +00:00
Piotr Drąg ed7ac04d64 Use a Unicode apostrophe in a new translatable string
See https://developer.gnome.org/hig/stable/typography.html
2019-05-18 13:29:37 +02:00
Rodrigo Lledó baf4d2bde6 Update Spanish translation 2019-05-16 16:24:52 +00:00
Jordan Petridis ff047c5823 Merge branch 'alatiera/checkmark' into 'master'
episode: add a checkmark symbol to further indicate played state

Closes #106 and #69

See merge request World/podcasts!106
2019-05-14 09:11:16 +00:00
Christopher Davis 6c701e0c41 build: Add missing source file
In the transition to tightening our meson integration this
file was left untracked by meson.
2019-05-14 08:28:23 +00:00
Jordan Petridis 28ea14f2e9 episode: add a checkmark symbol to further indicate played state
Using only a dim styleclass on the widget is too light and does
not work with the HighContrast theme.

Close #69 #106
2019-05-14 08:28:23 +00:00
Jordan Petridis f00f9b104c Merge branch 'piotrdrag/potfiles-190511' into 'master'
Update POTFILES.in

See merge request World/podcasts!105
2019-05-13 21:45:42 +00:00
Piotr Drąg 78d91826b1 Update POTFILES.in 2019-05-11 13:00:18 +02:00
Jordan Petridis a5be789745 Merge branch 'alatiera/nuke-preferences' into 'master'
app: remove preferences dialog

Closes #67

See merge request World/podcasts!104
2019-05-10 16:05:46 +00:00
Jordan Petridis 028e318bd3 app: remove preferences dialog
The dark theme option is broken with themes that don't ship a
dark variant.

The episode garbage collection doesn't seem useful being
configurable at all.

The gsettings are still there, this just removes the ui
dialog since nothing useful made it into it ever.

Also, less toggles the better.

http://www.islinuxaboutchoice.com/
2019-05-10 17:08:35 +02:00
Jordan Petridis b2b0b0f2c8 update dependencies 2019-05-10 15:57:55 +02:00
Jordan Petridis 42e73cb7e9 use mpris-player from crates.io 2019-05-10 15:56:28 +02:00
Jordan Petridis 89c3733ce8 Merge branch 'fix-#114' into 'master'
utils: use generic image when a show has no cover

See merge request World/podcasts!103
2019-05-10 13:40:59 +00:00
ZephOne 4be473dcea utils: use generic image when a show has no cover
When an episode from a show that has a cover is played. Switching to an
episode of a show that has no cover does not load the generic image in the
player. utils::set_image_from_path implementation does not deal with
DownloadError::NoImageLocation

utils::set_image_from_path deals with DownloadError::NoImageLocation,
this generic is set in this case.

https://gitlab.gnome.org/World/podcasts/issues/114
2019-05-10 14:01:47 +01:00
Jordan Petridis 97bdc32cce Merge branch 'master' into 'master'
Update CONTRIBUTING.md

See merge request World/podcasts!99
2019-04-07 15:55:20 +00:00
Julian Hofer d2da46854e Update CONTRIBUTING.md 2019-04-07 13:17:39 +02:00
Jordan Petridis 150d3622e4 Merge branch 'patch-1' into 'master'
Fix  small errors in CONTRIBUTING.md

See merge request World/podcasts!98
2019-04-06 21:23:05 +00:00
Julian Hofer 990ab29200 Update CONTRIBUTING.md 2019-04-06 20:55:16 +00:00
Jordan Petridis 80d3bc84b8 cargo fmt 2019-04-06 23:54:17 +03:00
Jordan Petridis b31c79431e Fix the tests for Rust 2018 for real this time 2019-04-06 22:58:03 +03:00
Jordan Petridis 73587ff47b Fix tests for Rust2018 2019-04-06 22:22:03 +03:00
Jordan Petridis 53e9db2f42 scripts/test.sh: export the rust binaries iniside flatpak environments
This allows the script to be able to be run directly from GNOME Builder's
build terminals.
2019-04-06 22:22:02 +03:00
Jordan Petridis b290441956 scripts/cargo: fix debug build check 2019-04-06 21:33:42 +03:00
Jordan Petridis 9d0d20afbd update deps 2019-03-30 18:13:39 +02:00
Jordan Petridis 4a7d3d5fc2 Use 2018 edition for the crates 2019-03-30 17:49:29 +02:00
Jordan Petridis 32ecb05902 don't export private macro 2019-03-30 17:08:28 +02:00
Jordan Petridis 644ca7d0d0 widgets/episode: replace deprecated method 2019-03-30 16:59:15 +02:00
Jordan Petridis 7dc1b25ee7 don't error on warnings
Nice and all when you keep up with development,
but can cause random errors by the addition of new
errors to the compiler.
2019-03-30 16:34:55 +02:00
Goran Vidović 3f28b9abc4 Update Croatian translation 2019-03-27 15:20:05 +00:00
Jordan Petridis cf36d91da4 Merge branch 'patch-1' into 'master'
Fix typo in README.md

See merge request World/podcasts!97
2019-03-25 09:23:30 +00:00
Torkel Rogstad 8c1465d3a2 Fix typo in README.md 2019-03-25 08:52:22 +00:00
Jordan Petridis bed7a4d6be CI: fix the app_id that I forgot in the last commit 2019-03-20 23:54:40 +02:00
Jordan Petridis 23a91cca16 CI: fix the flatpak manifest path 2019-03-20 23:23:00 +02:00
Jordan Petridis 82c99e2cfa meson: remove outdated fixme 2019-03-20 23:17:34 +02:00
Jordan Petridis 7d745179d4 app: Use a dot to separate the .Devel suffix in the app-id 2019-03-20 23:15:20 +02:00
Jordan Petridis 78283e51f6 app: remove .present() workaround
This should no longer be needed now.
https://gitlab.gnome.org/GNOME/gtk/issues/1754
2019-03-20 23:06:44 +02:00
Jordan Petridis 5a9ff8e331 Merge branch 'piotrdrag/update-potfiles-190307' into 'master'
Update POTFILES.in

See merge request World/podcasts!95
2019-03-16 12:42:21 +00:00
Piotr Drąg 814ddaa532 Update POTFILES.in 2019-03-16 12:29:47 +00:00
Bruce Cowan b927b5fac2 Add British English translation 2019-03-16 11:47:15 +00:00
Anders Jonsson e9cf140177 Update Swedish translation 2019-03-13 22:01:05 +00:00
Jordan Petridis 9ee9de7911 Flatpak: use ☢ emoji instead of the Nightly prefix 2019-03-10 21:07:29 +02:00
Nathan Follens 53844aa0ff Add Dutch translation 2019-03-10 12:54:18 +00:00
Jordan Petridis f527f743fc build: Require libhandy 0.0.9
Else libhandy breaks tranlations
2019-03-10 13:18:36 +01:00
Rafael Fontenelle 5801736955 Update Brazilian Portuguese translation 2019-03-10 01:32:30 +00:00
Tim Sabsch 11afc4c37d Update German translation 2019-03-09 18:58:46 +00:00
Jordan Petridis 5f1427cabd Merge branch 'wip/christopherdavis/tighten-meson-integration' into 'master'
build: Tighten integration between cargo and meson

Closes #55

See merge request World/podcasts!94
2019-03-07 05:16:03 +00:00
Jordan Petridis 27008e0f18 Flatpak: add builddir: true to the manifests
GNOME Builder carries a reimplementation of flatpak-builder.
flatpak-builder assumes that builddir is true for meson, but
Builder does not since it also supports out-of-tre builds.

This helps indicated to Builder that builddir can indeed be used.
2019-03-07 07:04:24 +02:00
Christopher Davis 8898fd6e2f build: use build_by_default in cargo-build target
build_always_stale is deprecated and build_by_default can be
used now that we don't have build.rs.

Requires that we list our sources.
2019-03-07 07:04:24 +02:00
Christopher Davis 96d4cd50d4 CI: create blank versions of configured files before lint
Required now that we have dynamically generated
sources.
2019-03-07 07:04:24 +02:00
Christopher Davis 7a77f31aa3 build: Place target in meson build dir
Instead of putting target/ and target_test/ in the source
directory, we can tell our cargo script to put both target
and our cargo-home in meson's build directory.

In addition, makes tests and builds use the same target
directory, significantly reducing the time it takes to run tests.
2019-03-07 07:04:23 +02:00
Christopher Davis 78f29e726e build: use add_dist_script for vendoring
Our workaround for getting meson and cargo working together
included a separate 'release' target that replaced
'ninja dist' so that we could vendor dependencies.

Now we use meson's add_dist_script to vendor the
dependencies as part of 'ninja dist', so we no longer need
the 'release' target.
2019-03-07 07:04:23 +02:00
Christopher Davis 92e2006782 build: hook up tests with meson
Adds our cargo test to meson's testing system so that
`ninja test` runs it in addition to our resource validation tests.
2019-03-07 07:04:23 +02:00
Christopher Davis 5b2edc73ec build: Build resources with meson instead of build.rs
Allows us to get rid of build.rs, which was only used to
compile resources. static_resource.rs is now created by
meson, and the meson path is used for include_bytes!.

Closes https://gitlab.gnome.org/World/podcasts/issues/55
2019-03-07 04:35:31 +00:00
Christopher Davis 395e31ff85 build: Use config.rs instead of env! macro
Previously we were using the env! macro to determine
build-time variables like version, app ID, and locale dir.
Instead of relying on env vars, we can create a configuration
file with meson and import it.
2019-03-07 04:35:31 +00:00
Sabri Ünal dd0d828794 Update Turkish translation 2019-03-06 10:46:39 +00:00
Jordan Petridis 15bb1a2335 Merge branch 'escape-opml-export' into 'master'
p-data: Escape titles in OPML exports

See merge request World/podcasts!93
2019-03-04 04:26:38 +00:00
Christopher Davis 0a7b7880da opml: escape characters when exporting
OPML is XML after all and parsers yell at us when we don't
escape &amps.
2019-03-04 05:54:01 +02:00
Jordan Petridis 277f324cf0 cargo fmt 2019-03-03 17:47:11 +02:00
Jordan Petridis e496d5bf36 cargo: build debug symbols for release builds as well 2019-03-03 17:46:33 +02:00
Jordan Petridis 0ed6c8979e Upgrade crossbeam-channel 2019-03-03 17:45:43 +02:00
Jordan Petridis 075dd1adeb cargo: change email metadata of the crates 2019-03-03 04:59:52 +02:00
Jordan Petridis 027faf1949 Change formatting of podcasts-gtk/Cargo.toml 2019-03-03 04:58:40 +02:00
Jordan Petridis 54e049874c html2text: Use upstream git repo 2019-03-03 04:54:42 +02:00
Jordan Petridis c4c6ba9ea4 Update dependencies 2019-03-03 04:46:19 +02:00
Jordan Petridis a77bf0b8fb Update gtk-rs family of crates 2019-03-03 04:46:19 +02:00
Jordan Petridis b9bad14df6 build: Update libhandy to 0.0.8 at least
Earlier versions of libhandy broke translations for all apps.
sadly we can't require 0.0.9 yet as it hasn't been released yet.

https://mail.gnome.org/archives/desktop-devel-list/2019-March/msg00000.html
2019-03-03 04:10:47 +02:00
Kukuh Syafaat b1058933b8 Update Indonesian translation 2019-03-02 12:18:56 +00:00
Jiri Grönroos 32c7f6b29e Update Finnish translation 2019-03-02 08:51:28 +00:00
Milo Casagrande 137705450b Update Italian translation 2019-02-28 08:25:39 +00:00
Ask Hjorth Larsen 4dc6034de8 Add Danish translation 2019-02-24 17:46:33 +00:00
Daniel Mustieles 7fa18fe38f Update Spanish translation 2019-02-19 15:05:09 +00:00
Jordan Petridis 7e34347ed7 Merge branch 'mpris-fix' into 'master'
add missing mpris callbacks / fix #115

Closes #115

See merge request World/podcasts!92
2019-02-05 21:52:55 +00:00
Felix Häcker 68fa547b06 Implement MPRIS pause and play methods.
Till now we were only using the play_pause method and
was enough for most of the usecases, but looks like
some mpris clients only use the individual methods.

https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Method:PlayPause

Close #115
2019-02-05 20:47:56 +00:00
Balázs Úr a113ed049d Update Hungarian translation 2019-02-05 20:45:43 +00:00
Piotr Drąg 2f8a6a91f8 Update Polish translation 2019-02-02 15:31:37 +00:00
Jordan Petridis f75ed257f2 Merge branch 'piotrdrag/unicode-typography' into 'master'
Use Unicode ellipsis in a user-visible string

See merge request World/podcasts!91
2019-02-02 15:17:22 +00:00
Piotr Drąg 06091d1af4 Use Unicode ellipsis in a user-visible string
See https://developer.gnome.org/hig/stable/typography.html
2019-02-02 12:14:29 +01:00
Daniel Mustieles fb4e550122 Update Spanish translation 2019-01-29 15:28:41 +00:00
Balázs Úr a74301f479 Update Hungarian translation 2019-01-28 22:42:49 +00:00
Rafael Fontenelle c49f417d00 Update Brazilian Portuguese translation 2019-01-28 21:22:53 +00:00
Jordan Petridis a2bcd8aa30 Merge branch 'opml-export' into 'master'
Add support for exporting to opml format

See merge request World/podcasts!77
2019-01-27 04:48:26 +00:00
Christopher Davis 6c34686d8d p-data: Implment support for exporting the shows to an OPML file
Close #41
2019-01-27 06:06:46 +02:00
Jordan Petridis 86ec6f43cb scripts:test.sh: fail upon exit code, and print stuff 2019-01-27 06:01:35 +02:00
Jordan Petridis e9c7a3b99e Flatpak: Add a nightly manifest 2019-01-27 01:44:06 +02:00
Jordan Petridis f0ac63cd96 CI: add color to the test output 2019-01-21 03:13:51 +02:00
Jordan Petridis b1e8663ba9 cargo update 2019-01-21 03:13:51 +02:00
Jordan Petridis 2cb6bf2b98 p-gtk: Update the libhandy bindings 2019-01-21 03:13:51 +02:00
Jordan Petridis b35c63d1c8 Flatpak: Update libhandy to 0.0.7 and pin the commit
Lets avoid rolling git repos breaking the CI
2019-01-21 03:13:50 +02:00
Jordan Petridis 96b929b313 Flatpak: move USE_PLAYBIN3 env var to a finish arg 2019-01-21 03:13:50 +02:00
Jiri Grönroos d8cddfafa0 Update Finnish translation 2019-01-16 18:04:16 +00:00
Jordan Petridis de7d12d2c8 Merge branch 'patch-2' into 'master'
appdata: Improve the appdata file per the specs

See merge request World/podcasts!90
2019-01-10 06:18:19 +00:00
Bilal Elmoussaoui bc8d521853 appdata: Improve the appdata file per the specs
freedesktop specs:https://freedesktop.org/software/appstream/docs/chap-Quickstart.html
kudos documentation: https://gitlab.gnome.org/GNOME/gnome-software/blob/master/doc/kudos.md
2019-01-09 19:21:29 +00:00
Jordan Petridis a6c2666c82 Merge branch 'patch-1' into 'master'
Meson: add tests to validate desktop & appdata files

See merge request World/podcasts!89
2019-01-09 19:00:56 +00:00
Bilal Elmoussaoui 32424e7938 Meson: add tests to validate desktop & appdata files 2019-01-09 18:24:11 +00:00
Jordan Petridis ca4a3d64eb meson: remove dependency on gstreamer-bad-video-1.0
This has been moved to gst-base now.
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/commit/b9e15fddb14b2cde6470255794ef130523885e9f
2019-01-05 15:41:46 +02:00
Jordan Petridis 2257688c65 Use rustfmt from the stable rustup channel 2019-01-05 15:11:27 +02:00
Jordan Petridis ea9ddc58c0 scripts/test.sh: Minor tweaks 2019-01-05 15:11:27 +02:00
Milo Casagrande c47d375a58 Update Italian translation 2018-12-11 16:49:14 +00:00
Jordan Petridis 36f97a5300 Flatpak: minor cleanup 2018-12-09 20:40:41 +02:00
Jordan Petridis 4adc3fadaa Flatpak: Set an env var so gstreamer uses playbin3 2018-12-09 20:39:17 +02:00
Jordan Petridis d9c64e7f87 CI: move the rustfmt check before the build/test 2018-12-09 04:02:29 +02:00
Jordan Petridis 9f8ae75691 Remove depricated lints 2018-12-09 03:53:17 +02:00
Jordan Petridis 7e0b88ddbd Merge branch 'remove-custom-devel-class' into 'master'
style.css: Remove custom .devel style class

See merge request World/podcasts!87
2018-12-08 23:00:14 +00:00
Christopher Davis ed62f2b1f2 style.css: Remove custom .devel style class
GTK includes it's own .devel style class, so we don't need to
override by creating our own.
2018-12-06 00:30:00 -05:00
Jordan Petridis 4e89cdaca1 Merge branch 'alatiera/cargo-check' into 'master'
Boring build system stuff

Closes #109

See merge request World/podcasts!86
2018-12-02 00:40:49 +00:00
Jordan Petridis b72ba8c66a podcasts-gtk: make it possible to compile with just cargo
This is not supported at all, and it still won't run with cargo
run, thankfully, you should use meson instead...

The only purpose of this commit is to make it possible for
cargo check, and by extension rls, to function and work
properly.

Part of #110
2018-12-02 02:10:09 +02:00
Jordan Petridis fc9de568bd meson: remove dead code 2018-12-02 02:03:34 +02:00
Jordan Petridis fe5a542e08 meson: Declare dependencies
Close #109
2018-12-02 02:03:33 +02:00
Jordan Petridis 5d86693d98 Merge branch 'fix/error-format' into 'master'
Remap rustc output to show errors in GNOME Builder sidebar

See merge request World/podcasts!81
2018-12-01 12:18:41 +00:00
Ricardo Silva Veloso 4caefdb3fd Remap rustc output to show errors in GNOME Builder sidebar 2018-12-01 13:36:26 +02:00
Jordan Petridis 2f843a4d40 Merge branch 'patch-1' into 'master'
Support vendored builds / distribution packaging

See merge request World/podcasts!85
2018-11-30 11:25:59 +00:00
Michael Aaron Murphy 0175609f02 Support vendored builds / distribution packaging 2018-11-30 11:25:59 +00:00
Jordan Petridis f9f0dad203 cargo fmt 2018-11-29 14:36:06 +02:00
Jordan Petridis fdb064ffc8 Update dependancies 2018-11-29 11:57:27 +02:00
Jordan Petridis e98231c327 Merge branch 'cleanups' into 'master'
Cleanups

See merge request World/podcasts!84
2018-11-18 13:27:59 +00:00
Jordan Petridis 0888da2197 Upgrade dependencies 2018-11-18 12:59:02 +00:00
Jordan Petridis 2d231ad989 Update dependancies 2018-11-18 12:59:01 +00:00
Jordan Petridis 19e0b7e565 Further preparations for Rusto 2018 edition 2018-11-18 12:59:01 +00:00
Jordan Petridis fd4128c364 Prepare for Rust 2018 edition 2018-11-18 12:59:01 +00:00
Jordan Petridis 98f105fda0 Player: Use a wrapper struct to write methods on &self
Previously, methods that required the Player to be ref counted,
were using static methods with s: &Rc<Self> as the first argument.

Now the wrapper type auto-derefs to the inner struct and you can
declare methods on just &self.
2018-11-18 12:59:01 +00:00
Kukuh Syafaat 201f2e23c7 Update Indonesian translation 2018-11-15 16:42:30 +00:00
Jordan Petridis 32b257ec30 cargo fmt 2018-11-13 15:29:20 +02:00
Jordan Petridis 53bceb89cd Merge branch 'Ophirr33/podcasts-master'
See !82 for more.
2018-11-07 01:34:06 +02:00
Jordan Petridis 04770a1e8f Merge branch 'ZanderBrown/hammond-wip/zbrown/jump-to-start'
See !83 for more.
2018-11-07 00:49:47 +02:00
Zander Brown fbda4c76f0 player.rs: Improve the fast-forward handling
Previously if you hit fast-forward but the offset remaining was
let that the amount you wanted to seek, it would do nothing.
Now it resets the stream and seekbar to the start.

Eventually this will just move on to the next episode in the
Queue once that's implemented.
2018-11-07 00:46:40 +02:00
Zander Brown 85387a0a9b Fix for https://gitlab.gnome.org/World/podcasts/issues/105
Wow that was a quick one
2018-11-05 17:55:46 +00:00
Jordan Petridis 5ac4f6dcf9 Mpris: Actually raise the window
This fixes a bug where can_raise was never registered on dbus,
but it also works around a wayland issue with the .present()
method.

https://gitlab.gnome.org/GNOME/gtk/issues/624
2018-11-04 21:05:09 +02:00
Jordan Petridis 6671f8c6fe podcasts-gtk: Add per file license annotations 2018-11-04 19:35:35 +02:00
Jordan Petridis 5b77bb4649 podcasts-downloader: Add per file license annotations 2018-11-04 19:35:35 +02:00
Jordan Petridis 8f6329d71d podcasts-data: Add per file license annotations 2018-11-04 19:35:35 +02:00
Ty Coghlan 5d71ac584c gnome-podcasts: DRY out From impls in errors
From impls for errors generally just take some error type and map
it into a variant of some podcast error enum. This removes the duplicate
impls by using a pattern macro to make the impls from the type of the
enum, the given error type, and the desired enum variant.
2018-11-03 01:13:35 -04:00
Daniel Mustieles 534c627300 Update Spanish translation 2018-11-02 12:26:05 +00:00
Jordan Petridis 1a1e5ecd3f Update App icon. Close #102 2018-10-30 20:34:47 +02:00
Alexandre Franke 3e555c64d9 Add French translation 2018-10-29 12:54:45 +00:00
Dušan Kazik 8d6b5f7105 Update Slovak translation 2018-10-28 21:00:26 +00:00
Dušan Kazik 4692be663e Add Slovak translation 2018-10-28 15:31:17 +00:00
gogo 5ae0fb1b0e Update Croatian translation 2018-10-24 19:46:48 +00:00
Jordan Petridis 990d830f24 cargo fmt 2018-10-23 13:23:01 +03:00
Jordan Petridis c6aa90db3e Merge branch 'master' into 'master'
fix typo

See merge request World/podcasts!79
2018-10-23 09:56:48 +00:00
lightning1141 c1eed45194 fix typo 2018-10-23 10:52:33 +08:00
Anders Jonsson 31ee668311 Update Swedish translation 2018-10-16 19:53:58 +00:00
Jordan Petridis 9f60121609 Flatpak: Cleanup libhandy headers 2018-10-09 12:58:40 +03:00
Piotr Drąg a61d04f445 Update Polish translation 2018-10-07 14:57:18 +00:00
Marek Černocký 8ba8ada253 Update Czech translation 2018-10-07 14:48:24 +00:00
Jordan Petridis 885b796f85 New release 0.4.6 2018-10-07 10:18:15 +03:00
Jordan Petridis fa47806c93 Update Changelog 2018-10-07 10:18:14 +03:00
Emin Tufan Çetin 5997666bad Update Turkish translation 2018-10-06 15:53:09 +00:00
Jordan Petridis 40186ce155 Update dependancies 2018-10-06 11:29:52 +03:00
Jordan Petridis 9cfdb35224 AboutDialog: Update contributors list 2018-10-06 11:09:07 +03:00
Jordan Petridis 64860c4624 Update screenshots 2018-10-06 10:32:46 +03:00
Jordan Petridis 32bd2a89a3 Stacks: Check if there episodes insteads of shows
If you added a Feed where a Show exists but it had no episodes
entries, the stack would end up in a populated state, but the
HomeView would be blank without widgets.

This changes it so the stack state depends upon the episodes
table being populated instead of the show. The downside
is that if your only feed is one without episodes you can
no longer navigate and interact with it.
2018-10-06 10:22:24 +03:00
Rafael Fontenelle 1e6eca307b Update Brazilian Portuguese translation 2018-10-05 14:19:31 +00:00
Jordan Petridis fc23fcd7c1 Merge branch 'patch-1' into 'master'
Fix typo

See merge request World/podcasts!78
2018-10-05 11:47:38 +00:00
Alexandre Franke ab52825c71 Fix typo 2018-10-05 10:04:44 +00:00
Jordan Petridis 28def30510 Update CHANGELOG.md 2018-10-05 09:25:56 +00:00
Florian Heiser 8f4d017180 Update German translation 2018-10-05 04:41:29 +00:00
Jordan Petridis df302ad517 Pipeline: Do not terminate the stream upon errors
Stream::for_each terminated the stream upon the first error. This
was causing feeds to not update if any one returned a non-200ish
result. To work around this, we create a succesfull result for
every entry regardless at the end.

While we are at it, aslo switch from FuturesOrdered stream
to FuturesUnordered. There is no reason to use Ordered, this was
a typo initially.
2018-10-04 18:48:11 +03:00
Jordan Petridis 357d99ac7c Remove temporary file 2018-10-04 17:18:07 +03:00
Jordan Petridis 7e3fecc44a Source: Refactor the clear_etags method api 2018-10-04 16:46:04 +03:00
Jordan Petridis e0b3dd9795 Mpris: Implement the raise method 2018-10-04 16:46:04 +03:00
Jordan Petridis 6a52a2bc46 Merge branch 'alatiera/player-timeout' into 'master'
Player: Tweak the smart rewind behavior

See merge request World/podcasts!76
2018-10-04 07:55:21 +00:00
Jordan Petridis cd2b087006 Player: Check the episode id before triggering a smart rewind 2018-10-04 05:27:11 +00:00
Jordan Petridis ef2940142c PlayerInfo: Store the id of the current playing episode 2018-10-04 05:27:11 +00:00
Jordan Petridis e13b8b8827 Player: Tweak the smart rewind behavior
Check if time interval passed since the last pause, and only
rewind if the delta to indicates that the user had
switched their focus.

In other words, avoid rewinding if the track was just paused and
resumed.
2018-10-04 05:27:11 +00:00
Jordan Petridis 43fce2e89a CI: Use generic bundle name
When run an environment CI_COMMIT_SHA is not resolved and results
into a 404 url in the review apps
2018-10-04 08:25:50 +03:00
Jordan Petridis 7856f0d602 Merge branch 'mpris' into 'master'
Implement MPRIS, Close #68

See merge request World/podcasts!74
2018-10-04 03:26:03 +00:00
Jordan Petridis bcc6ab50e2 PlayerInfo: Minor refactor of the mpris cover 2018-10-04 02:19:56 +00:00
Jordan Petridis 23aa8c05ab Player: Do not duplicate the mpris instance 2018-10-04 02:19:56 +00:00
Jordan Petridis 986d898217 Player: Remove an unwrap 2018-10-04 02:19:56 +00:00
Jordan Petridis 654c0e5e56 Player: Remove Initialization test
When constucting Player in the Sandbox, it tries to use X-11
for dbus-autolaunch which is disabled in the flatpak environment.

It fails with the following error:
D-Bus error: Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead (org.freedesktop.DBus.Error.NotSupported)
2018-10-04 02:19:56 +00:00
Felix Häcker fed0edbf16 Player: use crates.io package of mpris 2018-10-04 02:19:56 +00:00
Felix Häcker ede91da6f8 cargo fmt 2018-10-04 02:19:56 +00:00
Felix Häcker 1f18d4291f Player: implement fast forward / rewind for mpris 2018-10-04 02:19:56 +00:00
Felix Häcker d066e8939d Player: implement mpris play/pause callbacks 2018-10-04 02:19:56 +00:00
Felix Häcker e4c3435d34 Player: add basic mpris support 2018-10-04 02:19:56 +00:00
Jordan Petridis fc80b180bc CI: Allow rusftm check to fail for now
Stuff broke with rustfmt nightly 0.99.5 and I haven't found time
to look into it yet.
2018-10-04 05:17:21 +03:00
Jordan Petridis 0d9dca99e9 Meson: capture the output of the custom target
Previously meson would withhold the stdout output, and only
print it once the job was finished. This was a bit problematic
with the current way we wire cargo into meson, cause you have
no output of whats going on till then causing a degraded UX.

With this change output is printed directly to stdout and
behaves as expected.

https://mesonbuild.com/Reference-manual.html#custom_target
2018-10-04 04:58:57 +03:00
Kukuh Syafaat 2ff921cc1a Update Indonesian translation 2018-10-02 13:34:32 +00:00
Piotr Drąg e0e66fa6af Update Polish translation 2018-09-30 17:17:46 +00:00
Marek Černocký 110e29ec5a Update Czech translation 2018-09-29 19:31:22 +00:00
Jordan Petridis a2b6d622de Update dependancies 2018-09-29 13:58:45 +03:00
Jordan Petridis 0887789f5e Pipeline: Complete the move to Tokio Runtime 2018-09-29 13:35:45 +03:00
Jordan Petridis 3c4574f2ec scripts/test.sh: Don't keep build-dirs 2018-09-29 12:07:21 +03:00
Jordan Petridis 62029f6164 Pipeline: Minor refactor
Use the proper Stream API to return a future to run on the
executor. Previously I was using a workaround to convert the
Stream into a future and run it to completion in the Executor,
since I was not aware of a better API.
2018-09-29 12:03:00 +03:00
Jordan Petridis ba986847d6 Merge branch 'wip/hyper-12.X-update'
See merge request World/podcasts!75
2018-09-29 11:42:53 +03:00
Jordan Petridis fded78ce6f Flatpak: Switch to the master runtime again 2018-09-29 11:18:39 +03:00
Jordan Petridis 8d44649a1e Update dependancies 2018-09-29 09:54:06 +03:00
Jordan Petridis f4d0c51dc2 podcasts-downloader: Upgrade reqwests to 0.9 2018-09-29 09:54:06 +03:00
Jordan Petridis ba60db9977 podcasts-gtk: Upgrade reqwests to 0.9 2018-09-29 09:54:06 +03:00
Jordan Petridis 0a5a7a684d podcasts-downloader: Remove direct dependancy on hyper 2018-09-29 09:54:06 +03:00
Christopher Davis 7181c46ed5 podcasts-data: Upgrade hyper to 12.X
This also allows us to bump hyper_tls and native_tls, bringing
support for openssl 1.1.
2018-09-29 09:54:06 +03:00
Jordan Petridis afa7e69347 Update CHANGELOG.md 2018-09-28 23:56:51 +00:00
Jordan Petridis 5050dda4d2 Hamburger: Update to reflect the latest HIG changes
Preferences are now grouped with the application actions.
The About label was renamed to "About Podcasts".

https://mail.gnome.org/archives/desktop-devel-list/2018-September/msg00015.html
2018-09-29 02:43:19 +03:00
Florian Heiser 9ea1e16ac8 Update German translation 2018-09-27 15:32:33 +00:00
Rodrigo Lledó 922f44f605 Update Spanish translation 2018-09-24 10:17:44 +00:00
Adolfo Jayme Barrientos 6ea3fc918b Add Catalan translation 2018-09-24 07:52:18 +00:00
Kukuh Syafaat 0c201533f0 Update Indonesian translation 2018-09-22 08:20:38 +00:00
Jordan Petridis b1e99b96c4 CI: Switch the flatpak image 2018-09-22 04:53:08 +03:00
Jordan Petridis de1c8485ae Fix rustc warnings
New warnings were introduced with rustc 1.29.0

podcasts-data/src/lib.rs: this one can be removed once diesel is
upgraded.
https://github.com/diesel-rs/diesel/issues/1785#issuecomment-422577018

podcasts-gtk/src/i18n.rs: This is just a deprication warning
2018-09-22 04:47:24 +03:00
Jordan Petridis 565d1d0388 Build against the 3.28 runtime for now
Freedesktop 18.08.11 dropped openssl 1.0 which caused hyper to
no longer build. Reverting to the old runtime till hyper is
upgraded. See #84 for more.
2018-09-22 04:47:24 +03:00
gogo a15fea1d65 Update Croatian translation 2018-09-19 12:24:57 +00:00
Jordan Petridis da3cf6ca27 Flatpak: Pass configuration to libhandy
Do not build what we don't need.
2018-09-18 12:43:51 +03:00
Emin Tufan Çetin d8dbbc6832 Update Turkish translation 2018-09-15 20:11:23 +00:00
Marek Černocký 3563a964ef Add Czech translation 2018-09-15 05:15:51 +00:00
Jordan Petridis 208f0c248d Update rest of the dependancies 2018-09-13 15:47:40 +03:00
Jordan Petridis c0e034726a Upgrade gtk-rs and friends
Upgrade gtk-rs, and everything dependings on it like gst-rs and
libhandy bindigns
2018-09-13 15:47:40 +03:00
Rafael Fontenelle d676a7071a Update Brazilian Portuguese translation 2018-09-11 00:12:22 +00:00
Rūdolfs Mazurs a681b2c944 Add Latvian translation 2018-09-10 17:34:18 +00:00
Mario Blättermann c53701d56b Update German translation 2018-09-10 07:50:51 +00:00
Anders Jonsson a8c1f2eccc Update Swedish translation 2018-09-09 17:39:22 +00:00
Piotr Drąg cf7ee44efc Update Polish translation 2018-09-09 17:00:14 +00:00
Jordan Petridis 2e4a9eaaeb Update dependancies 2018-09-08 21:41:39 +03:00
Jordan Petridis 569a2b5694 Update CHANGELOG.md 2018-09-08 20:17:48 +03:00
Jordan Petridis baa84773a5 EpisodeWidget: Change the "cancel" action icon 2018-09-08 20:17:47 +03:00
Jordan Petridis a39e642b5a EpisodeWidget: Change cacnel button to an icon
This also reworks the button_box to be just a GtkBox instead.
I couldn't get ButtonBox to behave the way I wanted.

Fixes #89
2018-09-08 20:17:47 +03:00
Jordan Petridis e42cb49cbe EpisodeWidget: Hide total_size if request fails
This moves the rest of the methods of Progress struct to the downloader
trait and cancels the Progress if the request does nto succed.

Close #90
2018-09-08 20:17:47 +03:00
Jordan Petridis b40c12efbd Pipeline: Avoid spamming stderr when not needed
This commit add a new DataError Variant for feeds that return 304.
Its expected behaviror and the current API of Source::into_feed
is kinda limiting the return type to make it easier to handle.

Up till now 304 was returning an Error to early return. Ideally
Source::into_feed will return a Multi variant Result Enum.

example:

enum FeedResult {
    Ok(Success(feed)),
    Ok(NotModified),
    Err(err),
}

Hopefully in a refactor in the near Future™

Till then we will just have to match and ignore
DataError::FeedNotModified.
2018-09-08 20:17:47 +03:00
Jordan Petridis 3c5ddad133 DataError: Improve the FeedRedirect variant 2018-09-08 20:17:47 +03:00
Jordan Petridis 1ca4cb40dd Pipeline: clear the imports of fututres 2018-09-08 20:17:47 +03:00
Jordan Petridis 678b0b9db1 BaseView: Set minimum width to 360
While the HomeView and ShowView can't yet scale that low,
the ShowWidget could get to about 270p already which is not
desirable.

This commit sets the minimum width of all the Views to 360p,
which is our mobile target size.
2018-09-08 20:17:47 +03:00
Jordan Petridis e633fa41ac Pipeline: Minor formatting improvment 2018-09-08 20:17:47 +03:00
Jordan Petridis dac303e33b Pipeline: Use a custom tokio threadpool
This reverts commit e64883eecb
and 40dd2d6923

Seems like core.run() returns once its done even if there
are still tasks in the Runtime underneath. A way to solve that
would be to call the shutdown_on_idle method.

We need ownership of the threadpool in order to invoke
`shutdown_on_idle` method but core.runtime only returns a
referrence so we need to create our own threadpool.
2018-09-08 20:17:46 +03:00
Jordan Petridis fd77d672c5 Update Changelog 2018-09-08 20:17:46 +03:00
Jordan Petridis a991d9f512 DataError: Remove unused error variant
This was added due to Threadpool::spawn returning errors, but its
no longer used.
2018-09-08 20:17:46 +03:00
Jordan Petridis 674b3b54dc Pipeline: reuse the prexisting runtime executor
Instead of creating our own threadpool, we should reuse the executor
of the tokio::runtime::Runtime that backs the tokio::reactor::Core.
2018-09-08 20:17:46 +03:00
Jordan Petridis 09948845ca Pipeline: Remove use of clone! macro 2018-09-08 20:17:46 +03:00
Jordan Petridis 0b8a0695f7 Pipeline: Use tokio threadpool to index feeds 2018-09-08 20:17:46 +03:00
Jordan Petridis a7c95d5718 Pipeline: Remove dependancy on rayon_futures
This requires a RUSTFLAG to be set before hand for rayon to build.
This brakes a lot of tools like rls and clippy by default and
require special configs for itnegration.

Additionally, rayon_futures is still 0.1 and not much work seem
to have gone into it. Ideally it should be replased with the tokio
runtime/threadpool.
2018-09-08 20:17:46 +03:00
Jordan Petridis 8a05597e52 Feed: Remove another unnecessary wrapper 2018-09-08 20:17:45 +03:00
Jordan Petridis 145d45f800 Feed: Remove unnecessary function wrapper 2018-09-08 20:17:45 +03:00
gogo 0476b67b2f Add Croatian translation 2018-09-06 18:29:14 +00:00
Balázs Meskó 2751a828e0 Add Hungarian translation 2018-09-05 22:09:46 +00:00
Jordan Petridis a3f5dbfe07 CI: cache only the sources from flatpak-builder
Gitlab CI zips its cache target which causes it to strip
xattributes. This breaks ostree and the cache artifacts.

Cache only the sources instead.
2018-09-05 00:47:45 +03:00
Fabio Tomat 60e09c0dd7 Add Friulian translation 2018-09-04 18:18:27 +00:00
Milo Casagrande a23297e56a Add Italian translation 2018-09-03 13:42:38 +00:00
Jordan Petridis b05163632b test.sh: build with devel profile as well 2018-09-03 11:17:03 +03:00
Daniel Mustieles f59be31ded Update Spanish translation 2018-09-03 06:32:14 +00:00
Anders Jonsson 2e527250de Add Swedish translation 2018-09-02 23:35:41 +00:00
Piotr Drąg 91dd378f5d Update Polish translation 2018-09-01 17:49:54 +00:00
Jiri Grönroos f5b3d033a3 Update Finnish translation 2018-09-01 16:59:07 +00:00
Rafael Fontenelle db98e3b722 Add Brazilian Portuguese translation 2018-09-01 13:29:55 +00:00
Mario Blättermann 586cf16fdc Update German translation 2018-08-31 19:05:31 +00:00
112 changed files with 12236 additions and 4170 deletions
+4
View File
@@ -17,3 +17,7 @@ target_*/
.flatpak-builder/ .flatpak-builder/
app/ app/
repo/ repo/
# Files configured by meson
podcasts-gtk/src/config.rs
podcasts-gtk/src/static_resource.rs
+18 -19
View File
@@ -1,25 +1,22 @@
stages: stages:
- test
- lint - lint
- test
- review - review
variables: variables:
BUNDLE: "org.gnome.Podcasts.${CI_COMMIT_SHA}.flatpak" BUNDLE: "org.gnome.Podcasts.Devel.flatpak"
flatpak: flatpak:
image: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/rust_bundle:master" image: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/rust_bundle:master"
stage: "test" stage: "test"
variables: variables:
MANIFEST_PATH: "org.gnome.PodcastsDevel.json" MANIFEST_PATH: "org.gnome.Podcasts.Devel.json"
FLATPAK_MODULE: "gnome-podcasts" FLATPAK_MODULE: "gnome-podcasts"
CONFIGURE_ARGS: "-Dprofile=development" CONFIGURE_ARGS: "-Dprofile=development"
DBUS_ID: "org.gnome.PodcastsDevel" DBUS_ID: "org.gnome.Podcasts.Devel"
script: script:
- flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH} - flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH}
# https://gitlab.gnome.org/World/podcasts/issues/55
# Force regeneration of gresources regardless of artifacts chage
- flatpak-builder --run app ${MANIFEST_PATH} glib-compile-resources --sourcedir=podcasts-gtk/resources/ podcasts-gtk/resources/resources.xml
# Build the flatpak repo # Build the flatpak repo
- flatpak-builder --run app ${MANIFEST_PATH} meson --prefix=/app ${CONFIGURE_ARGS} _build - flatpak-builder --run app ${MANIFEST_PATH} meson --prefix=/app ${CONFIGURE_ARGS} _build
@@ -29,14 +26,10 @@ flatpak:
- | - |
xvfb-run -a -s "-screen 0 1024x768x24" \ xvfb-run -a -s "-screen 0 1024x768x24" \
flatpak-builder --run \ flatpak-builder --run \
--env=APP_ID="org.gnome.PodcastsDevel" \ --env=CARGO_HOME="${CI_PROJECT_DIR}/target/cargo-home" \
--env=LOCALEDIR="./podcasts-gtk/po" \ --env=CARGO_TARGET_DIR="${CI_PROJECT_DIR}/target/" \
--env=VERSION="0.0.0" \
--env=RUSTFLAGS="--cfg rayon_unstable" \
--env=CARGO_HOME="target/cargo-home" \
--env=CARGO_TARGET_DIR="target_test/" \
app ${MANIFEST_PATH} \ app ${MANIFEST_PATH} \
cargo test -j 1 -- --test-threads=1 ninja -C _build test
# Create a flatpak bundle # Create a flatpak bundle
- flatpak-builder --finish-only app ${MANIFEST_PATH} - flatpak-builder --finish-only app ${MANIFEST_PATH}
@@ -51,7 +44,8 @@ flatpak:
cache: cache:
key: "flatpak" key: "flatpak"
paths: paths:
- .flatpak-builder/cache/ - .flatpak-builder/downloads/
- .flatpak-builder/git/
- target/ - target/
- target_test/ - target_test/
@@ -85,12 +79,17 @@ stop_review:
- master@World/podcasts - master@World/podcasts
- tags - tags
# Configure and run rustfmt on nightly # Configure and run rustfmt
# Exits and builds fails if on bad format # Exits and builds fails if on bad format
rustfmt: rustfmt:
image: "registry.gitlab.com/alatiera/rustfmt-oci-image/rustfmt:nightly" image: "rust:slim"
stage: lint stage: "lint"
script: script:
- rustup component add rustfmt
# Create blank versions of our configured files
# so rustfmt does not yell about non-existent files or completely empty files
- echo -e "" >> podcasts-gtk/src/config.rs
- echo -e "" >> podcasts-gtk/src/static_resource.rs
- rustc -Vv && cargo -Vv - rustc -Vv && cargo -Vv
- cargo fmt --version - cargo fmt --version
- cargo fmt --all -- --check - cargo fmt --all -- --color=always --check
+41
View File
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
### Added: ### Added:
### Changed: ### Changed:
@@ -13,8 +14,48 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Removed: ### Removed:
## [0.4.6] - 2018-10-07
### Added:
- Felix, @haecker-felix, wrote an [mpris crate](https://crates.io/crates/mpris-player) and implemented MPRIS2 client side support! !74 #68
### Changed:
- Download Cancel button was changed to an Icon instead of a label !72
- The applciation will no longer scale below 360p in width 1933c79f7a87d8261d91ca4e14eb51c1ddc66624
- Update to the latest HIG 5050dda4d2f75b706842de8507d115dd5a1bd0a9
- Chris, @brainblasted, upgraded hyper to 0.12, this brings openssl 1.1 support !75
- Pipeline backend is now completly migrated to tokio-runtime 0887789f5e653dd92ad397fb39561df6dffcb45c
- Resume playing an episode will attempt to rewind the track only if more than a minute has passed since the last pause !76
### Fixed:
- Fixed a regression where indexing feeds was blocking the `tokio reactor` #88 !70
- Episodeds Listbox no longer resizes when a download starts #89 !72
- The `total_size` label of the `EpisodeWidget` now behaves correctly if the request fails #90 !73
- The Pipeline will no longer log things in stderr for Requests that returned 304 and are expected to be skipped da361d0cb93cd8edd076859b2c607509a96dac8d
- A bug where the HomeView wold get into an invalid state if your only shows had no episodes 32bd2a89a34e8e940b3b260c6be76defe11835ed
### Translations: ### Translations:
**Added**
- Brazilian Portuguese translation 586cf16f
- Swedish translation 2e527250
- Italian translation a23297e5
- Friulian translation 60e09c0d
- Hungarian translation 2751a828
- Croatian translation 0476b67b
- Latvian translation a681b2c9
- Czech translation 3563a964
- Catalan translation 6ea3fc91
**Updated**
- German translation
- Finnish translation
- Polish translation
- Turkish translation
- Croatian translation
- Indonesian translation
- Spanish translation
## [0.4.5] - 2018-08-31 ## [0.4.5] - 2018-08-31
+15 -12
View File
@@ -5,9 +5,9 @@ Thank you for looking in this file!
When contributing to the development of GNOME Podcasts, please first discuss the change you wish to make via issue, email, or any other method with the maintainers before making a change. When contributing to the development of GNOME Podcasts, please first discuss the change you wish to make via issue, email, or any other method with the maintainers before making a change.
If you have any questions regarding the use or development of GNOME Podcasts, If you have any questions regarding the use or development of GNOME Podcasts,
want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) want to discuss design or simply hang out, please join us in [#gnome-podcasts:matrix.org](https://matrix.to/#/#gnome-podcasts:matrix.org) or [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond)
Please note we have a [code of conduct](https://wiki.gnome.org/Foundation/CodeOfConduc), please follow it in all your interactions with the project. Please note we have a [code of conduct](/code-of-conduct.md), please follow it in all your interactions with the project.
## Source repository ## Source repository
@@ -26,9 +26,12 @@ makes things easier for the maintainers.
We use [rustfmt](https://github.com/rust-lang-nursery/rustfmt) for code formatting and we enforce it on the gitlab-CI server. We use [rustfmt](https://github.com/rust-lang-nursery/rustfmt) for code formatting and we enforce it on the gitlab-CI server.
Quick setup ***Installing rustfmt*** As of 2019/Jan, our continuous integration
pipeline assumes the version of rustfmt that is distributed through the
stable channel of [rustup](rustup.rs). You can install it with
``` ```
cargo install rustfmt-nightly rustup component add rustfmt
cargo fmt --all cargo fmt --all
``` ```
@@ -36,7 +39,7 @@ It is recommended to add a pre-commit hook to run cargo test and `cargo fmt`.
Don't forget to `git add` again after `cargo fmt`. Don't forget to `git add` again after `cargo fmt`.
``` ```
#!/bin/sh #!/bin/sh
cargo test -- --test-threads=1 && cargo fmt --all -- --write-mode=diff cargo test -- --test-threads=1 && cargo fmt --all -- --check
``` ```
## Running the test suite ## Running the test suite
@@ -44,7 +47,7 @@ cargo test -- --test-threads=1 && cargo fmt --all -- --write-mode=diff
Running the tests requires an internet connection and it it will download some files from the [Internet Archive](archive.org) Running the tests requires an internet connection and it it will download some files from the [Internet Archive](archive.org)
The test suite sets a temporary sqlite database in the `/tmp` folder. The test suite sets a temporary sqlite database in the `/tmp` folder.
Due to that it's not possible to run them in parrallel. Due to that it's not possible to run them in parallel.
In order to run the test suite use the following: `cargo test -- --test-threads=1` In order to run the test suite use the following: `cargo test -- --test-threads=1`
@@ -91,13 +94,13 @@ Steps to reproduce:
* [ ] qa (quality assurance) tasks * [ ] qa (quality assurance) tasks
``` ```
## Pull Request Process ## Merge Request Process
1. Ensure your code compiles. Run `make` before creating the pull request. 1. Ensure your code compiles. Run `meson` & `ninja` before creating the merge request.
2. Ensure the test suit passes. Run `cargo test -- --test-threads=1`. 2. Ensure the test suit passes. Run `cargo test -- --test-threads=1`.
3. Ensure your code is properly formated. Run `cargo fmt --all`. 3. Ensure your code is properly formatted. Run `cargo fmt --all`.
4. If you're adding new API, it must be properly documented. 4. If you're adding new API, it must be properly documented.
5. The commit message is formatted as follows: 5. The commit message has to be formatted as follows:
``` ```
component: <summary> component: <summary>
@@ -107,8 +110,8 @@ Steps to reproduce:
<link to the bug ticket> <link to the bug ticket>
``` ```
6. You may merge the pull request in once you have the sign-off of the maintainers, or if you 6. You may merge the merge request once you have the sign-off of the maintainers, or if you
do not have permission to do that, you may request the second reviewer to merge it for you. do not have permission to do that, you may request the second reviewer to merge it for you.
## Code of Conduct ## Code of Conduct
We follow the Gnome [Code of Conduct.](https://wiki.gnome.org/Foundation/CodeOfConduct) We follow the [GNOME Foundation Code of Conduct](/code-of-conduct.md).
Generated
+1585 -1433
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,4 +6,4 @@ members = [
] ]
[profile.release] [profile.release]
debug = false debug = true
+7 -7
View File
@@ -33,18 +33,18 @@ want to discuss design or simply hang out, please join us on our [irc][irc] or [
### Flatpak ### Flatpak
Flatpak is the recommended way of building and installing GNOME Podcasts. Flatpak is the recommended way of building and installing GNOME Podcasts.
Here are the depencancies you will need. Here are the dependencies you will need.
```sh ```sh
# Add flathub and the gnome-nightly repo # Add flathub and the gnome-nightly repo
flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --user --if-not-exists gnome-nightly https://sdk.gnome.org/gnome-nightly.flatpakrepo flatpak remote-add --user --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
# Install the gnome-nightly Sdk and Platform runtime # Install the gnome-nightly Sdk and Platform runtime
flatpak install --user gnome-nightly org.gnome.Sdk org.gnome.Platform flatpak install --user gnome-nightly org.gnome.Sdk org.gnome.Platform
# Install the required rust-stable extension from flathub # Install the required rust-stable extension from flathub
flatpak install --user flathub org.freedesktop.Sdk.Extension.rust-stable//18.08 flatpak install --user flathub org.freedesktop.Sdk.Extension.rust-stable//19.08
``` ```
To install the resulting flatpak you can do: To install the resulting flatpak you can do:
@@ -65,10 +65,10 @@ sudo ninja -C build install
#### Dependencies #### Dependencies
* Rust stable 1.27 or later along with cargo. * Rust stable 1.34 or later along with cargo.
* Gtk+ 3.22 or later * Gtk+ 3.24.11 or later
* Gstreamer 1.12 or later * Gstreamer 1.16 or later
* libhandy * libhandy 0.0.11 or later
* Meson * Meson
* A network connection * A network connection
+126
View File
@@ -0,0 +1,126 @@
# GNOME Code of Conduct
Thank you for being a part of the GNOME project. We value your participation and want everyone to have an enjoyable and fulfilling experience. Accordingly, all participants are expected to follow this Code of Conduct, and to show respect, understanding, and consideration to one another. Thank you for helping make this a welcoming, friendly community for everyone.
## Scope
This Code of Conduct applies to all online GNOME community spaces, including, but not limited to:
* Issue tracking systems - bugzilla.gnome.org
* Documentation and tutorials - developer.gnome.org
* Code repositories - git.gnome.org and gitlab.gnome.org
* Mailing lists - mail.gnome.org
* Wikis - wiki.gnome.org
* Chat and forums - irc.gnome.org, discourse.gnome.org, GNOME Telegram channels, and GNOME groups and channels on Matrix.org (including bridges to GNOME IRC channels)
* Community spaces hosted on gnome.org infrastructure
* Any other channels or groups which exist in order to discuss GNOME project activities
Communication channels and private conversations that are normally out of scope may be considered in scope if a GNOME participant is being stalked or harassed. Social media conversations may be considered in-scope if the incident occurred under a GNOME event hashtag, or when an official GNOME account on social media is tagged, or within any other discussion about GNOME. The GNOME Foundation reserves the right to take actions against behaviors that happen in any context, if they are deemed to be relevant to the GNOME project and its participants.
All participants in GNOME online community spaces are subject to the Code of Conduct. This includes GNOME Foundation board members, corporate sponsors, and paid employees. This also includes volunteers, maintainers, leaders, contributors, contribution reviewers, issue reporters, GNOME users, and anyone participating in discussion in GNOME online spaces.
## Reporting an Incident
If you believe that someone is violating the Code of Conduct, or have
any other concerns, please [contact the Code of Conduct committee](https://wiki.gnome.org/Foundation/CodeOfConduct/ReporterGuide).
## Our Standards
The GNOME online community is dedicated to providing a positive experience for everyone, regardless of:
* age
* body size
* caste
* citizenship
* disability
* education
* ethnicity
* familial status
* gender expression
* gender identity
* genetic information
* immigration status
* level of experience
* nationality
* personal appearance
* pregnancy
* race
* religion
* sex characteristics
* sexual orientation
* sexual identity
* socio-economic status
* tribe
* veteran status
### Community Guidelines
Examples of behavior that contributes to creating a positive environment include:
* **Be friendly.** Use welcoming and inclusive language.
* **Be empathetic.** Be respectful of differing viewpoints and experiences.
* **Be respectful.** When we disagree, we do so in a polite and constructive manner.
* **Be considerate.** Remember that decisions are often a difficult choice between competing priorities. Focus on what is best for the community. Keep discussions around technology choices constructive and respectful.
* **Be patient and generous.** If someone asks for help it is because they need it. When documentation is available that answers the question, politely point them to it. If the question is off-topic, suggest a more appropriate online space to seek help.
* **Try to be concise.** Read the discussion before commenting in order to not repeat a point that has been made.
### Inappropriate Behavior
Community members asked to stop any inappropriate behavior are expected to comply immediately.
We want all participants in the GNOME community have the best possible experience they can. In order to be clear what that means, we've provided a list of examples of behaviors that are inappropriate for GNOME community spaces:
* **Deliberate intimidation, stalking, or following.**
* **Sustained disruption of online discussion, talks, or other events.** Sustained disruption of events, online discussions, or meetings, including talks and presentations, will not be tolerated. This includes 'Talking over' or 'heckling' event speakers or influencing crowd actions that cause hostility in event sessions. Sustained disruption also includes drinking alcohol to excess or using recreational drugs to excess, or pushing others to do so.
* **Harassment of people who don't drink alcohol.** We do not tolerate derogatory comments about those who abstain from alcohol or other substances. We do not tolerate pushing people to drink, talking about their abstinence or preferences to others, or pressuring them to drink - physically or through jeering.
* **Sexist, racist, homophobic, transphobic, ableist language or otherwise exclusionary language.** This includes deliberately referring to someone by a gender that they do not identify with, and/or questioning the legitimacy of an individual's gender identity. If you're unsure if a word is derogatory, don't use it. This also includes repeated subtle and/or indirect discrimination.
* **Unwelcome sexual attention or behavior that contributes to a sexualized environment.** This includes sexualized comments, jokes or imagery in interactions, communications or presentation materials, as well as inappropriate touching, groping, or sexual advances. Sponsors should not use sexualized images, activities, or other material. Meetup organizing staff and other volunteer organizers should not use sexualized clothing/uniforms/costumes, or otherwise create a sexualized environment.
* **Unwelcome physical contact.** This includes touching a person without permission, including sensitive areas such as their hair, pregnant stomach, mobility device (wheelchair, scooter, etc) or tattoos. This also includes physically blocking or intimidating another person. Physical contact or simulated physical contact (such as emojis like "kiss") without affirmative consent is not acceptable. This includes sharing or distribution of sexualized images or text.
* **Violence or threats of violence.** Violence and threats of violence are not acceptable - online or offline. This includes incitement of violence toward any individual, including encouraging a person to commit self-harm. This also includes posting or threatening to post other people's personally identifying information ("doxxing") online.
* **Influencing or encouraging inappropriate behavior.** If you influence or encourage another person to violate the Code of Conduct, you may face the same consequences as if you had violated the Code of Conduct.
* **Possession of an offensive weapon at a GNOME event.** This includes anything deemed to be a weapon by the event organizers.
The GNOME community prioritizes marginalized people's safety over privileged people's comfort. The committee will not act on complaints regarding:
* "Reverse"-isms, including "reverse racism," "reverse sexism," and "cisphobia"
* Reasonable communication of boundaries, such as "leave me alone," "go away," or "I'm not discussing this with you."
* Criticizing racist, sexist, cissexist, or otherwise oppressive behavior or assumptions
* Communicating boundaries or criticizing oppressive behavior in a "tone" you don't find congenial
The examples listed above are not against the Code of Conduct. If you have questions about the above statements, please [read this document](https://github.com/sagesharp/code-of-conduct-template/blob/master/code-of-conduct/example-reversisms.md#supporting-diversity).
If a participant engages in behavior that violates this code of conduct, the GNOME Code of Conduct committee may take any action they deem appropriate. Examples of consequences are outlined in the [Committee Procedures Guide](https://wiki.gnome.org/Foundation/CodeOfConduct/CommitteeProcedures).
## Procedure for Handling Incidents
* [Reporter Guide](https://wiki.gnome.org/Foundation/CodeOfConduct/ReporterGuide)
* [Moderator Procedures](https://wiki.gnome.org/Foundation/CodeOfConduct/ModeratorProcedures)
* [Committee Procedures Guide](https://wiki.gnome.org/Foundation/CodeOfConduct/CommitteeProcedures)
## License
The GNOME Online Code of Conduct is licensed under a [Creative Commons Attribution Share-Alike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/)
![Creative Commons License](http://i.creativecommons.org/l/by-sa/3.0/88x31.png)
## Attribution
The GNOME Online Code of Conduct was forked from the example policy from the [Geek Feminism wiki, created by the Ada Initiative and other volunteers](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy), which is under a Creative Commons Zero license.
Additional language was incorporated and modified from the following Codes of Conduct:
* [Citizen Code of Conduct](http://citizencodeofconduct.org/) is licensed [Creative Commons Attribution Share-Alike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/).
* [Code of Conduct template](https://github.com/sagesharp/code-of-conduct-template/) is licensed [Creative Commons Attribution Share-Alike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/) by [Otter Tech](https://otter.technology/code-of-conduct-training)
* [Contributor Covenant version 1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct) (licensed [CC BY 4.0](https://github.com/ContributorCovenant/contributor_covenant/blob/master/LICENSE.md))
* [Data Carpentry Code of Conduct](https://docs.carpentries.org/topic_folders/policies/index_coc.html) is licensed [Creative Commons Attribution 4.0 License](https://creativecommons.org/licenses/by/4.0/)
* [Django Project Code of Conduct](https://www.djangoproject.com/conduct/) is licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/)
* [Fedora Code of Conduct](http://fedoraproject.org/code-of-conduct)
* [Geek Feminism Anti-harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy) which is under a [Creative Commons Zero license](https://creativecommons.org/publicdomain/zero/1.0/)
* [Previous GNOME Foundation Code of Conduct](https://wiki.gnome.org/action/recall/Foundation/CodeOfConduct/Old)
* [LGBTQ in Technology Slack Code of Conduct](https://lgbtq.technology/coc.html) licensed [Creative Commons Zero](https://creativecommons.org/publicdomain/zero/1.0/)
* [Mozilla Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) is licensed [Creative Commons Attribution-ShareAlike 3.0 Unported License](https://creativecommons.org/licenses/by-sa/3.0/).
* [Python Mentors Code of Conduct](http://pythonmentors.com/)
* [Speak Up! Community Code of Conduct](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html), licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/)
+43 -28
View File
@@ -1,14 +1,34 @@
# Adatped from:
# https://gitlab.gnome.org/danigm/fractal/blob/6e2911f9d2353c99a18a6c19fab7f903c4bbb431/meson.build
project( project(
'gnome-podcasts', 'rust', 'gnome-podcasts', 'rust',
version: '0.4.5', version: '0.4.6',
license: 'GPLv3', license: 'GPLv3',
) )
dependency('sqlite3', version: '>= 3.20')
dependency('openssl', version: '>= 1.0')
dependency('dbus-1')
dependency('glib-2.0', version: '>= 2.56')
dependency('gio-2.0', version: '>= 2.56')
dependency('gdk-pixbuf-2.0')
dependency('gtk+-3.0', version: '>= 3.24.11')
dependency('libhandy-0.0', version: '>= 0.0.11')
dependency('gstreamer-1.0', version: '>= 1.16')
dependency('gstreamer-base-1.0', version: '>= 1.16')
dependency('gstreamer-audio-1.0', version: '>= 1.16')
dependency('gstreamer-video-1.0', version: '>= 1.16')
dependency('gstreamer-player-1.0', version: '>= 1.16')
dependency('gstreamer-plugins-base-1.0', version: '>= 1.16')
dependency('gstreamer-plugins-bad-1.0', version: '>= 1.16')
dependency('gstreamer-bad-audio-1.0', version: '>= 1.16')
cargo = find_program('cargo', required: true)
gresource = find_program('glib-compile-resources', required: true)
gschemas = find_program('glib-compile-schemas', required: true)
if get_option('profile') == 'development' if get_option('profile') == 'development'
profile = 'Devel' profile = '.Devel'
vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip() vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip()
if vcs_tag == '' if vcs_tag == ''
version_suffix = '-devel' version_suffix = '-devel'
@@ -22,15 +42,12 @@ endif
application_id = 'org.gnome.Podcasts@0@'.format(profile) application_id = 'org.gnome.Podcasts@0@'.format(profile)
i18n = import('i18n') i18n = import('i18n')
gnome = import('gnome')
subdir('podcasts-gtk/po') subdir('podcasts-gtk/po')
podir = join_paths (meson.source_root (), 'podcasts-gtk', 'po') podir = join_paths (meson.source_root (), 'podcasts-gtk', 'po')
podcasts_version = meson.project_version() podcasts_version = meson.project_version()
version_array = podcasts_version.split('.')
podcasts_major_version = version_array[0].to_int()
podcasts_minor_version = version_array[1].to_int()
podcasts_version_micro = version_array[2].to_int()
podcasts_prefix = get_option('prefix') podcasts_prefix = get_option('prefix')
podcasts_bindir = join_paths(podcasts_prefix, get_option('bindir')) podcasts_bindir = join_paths(podcasts_prefix, get_option('bindir'))
@@ -43,25 +60,23 @@ podcasts_conf.set('bindir', podcasts_bindir)
datadir = get_option('datadir') datadir = get_option('datadir')
subdir('podcasts-gtk/resources') subdir('podcasts-gtk/resources')
cargo = find_program('cargo', required: false)
gresource = find_program('glib-compile-resources', required: false)
cargo_vendor = find_program('cargo-vendor', required: false)
cargo_script = find_program('scripts/cargo.sh') cargo_script = find_program('scripts/cargo.sh')
test_script = find_program('scripts/test.sh')
cargo_release = custom_target('cargo-build', subdir('podcasts-data/src')
build_always_stale: true, subdir('podcasts-downloader/src')
output: ['gnome-podcasts'], subdir('podcasts-gtk/src')
install: true,
install_dir: podcasts_bindir,
command: [cargo_script,
'@CURRENT_SOURCE_DIR@',
'@OUTPUT@',
podcasts_localedir,
application_id,
podcasts_version + version_suffix,
profile
])
run_target('release', command: ['scripts/release.sh', meson.add_dist_script(
meson.project_name() + '-' + podcasts_version 'scripts/dist-vendor.sh',
]) meson.source_root(),
join_paths(meson.build_root(), 'meson-dist', meson.project_name() + '-' + podcasts_version)
)
test(
'cargo-test',
test_script,
args: meson.build_root(),
workdir: meson.source_root(),
timeout: 3000
)
+72
View File
@@ -0,0 +1,72 @@
{
"app-id" : "org.gnome.Podcasts.Devel",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"sdk-extensions" : [
"org.freedesktop.Sdk.Extension.rust-stable"
],
"command" : "gnome-podcasts",
"tags" : [
"nightly"
],
"finish-args" : [
"--share=network",
"--share=ipc",
"--socket=x11",
"--socket=fallback-x11",
"--socket=wayland",
"--socket=pulseaudio",
"--env=USE_PLAYBING3=1"
],
"build-options" : {
"append-path" : "/usr/lib/sdk/rust-stable/bin",
"build-args" : [
"--share=network"
],
"env" : {
"RUSTFLAGS" : "--error-format=short --remap-path-prefix =../",
"CARGO_HOME" : "/run/build/Podcasts/cargo",
"RUST_BACKTRACE" : "1"
}
},
"modules" : [
{
"name" : "libhandy",
"buildsystem" : "meson",
"config-opts" : [
"-Dintrospection=disabled",
"-Dgtk_doc=false",
"-Dtests=false",
"-Dexamples=false",
"-Dvapi=false",
"-Dglade_catalog=disabled"
],
"cleanup" : [
"/include",
"/lib/pkgconfig"
],
"sources" : [
{
"type" : "git",
"url" : "https://source.puri.sm/Librem5/libhandy.git",
"commit" : "f5909a897f70143bdd2f89f47a63c1bf848330ce"
}
]
},
{
"name" : "gnome-podcasts",
"buildsystem" : "meson",
"builddir" : "true",
"config-opts" : [
"-Dprofile=development"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/World/podcasts.git"
}
]
}
]
}
@@ -1,5 +1,5 @@
{ {
"app-id" : "org.gnome.PodcastsDevel", "app-id" : "org.gnome.Podcasts",
"runtime" : "org.gnome.Platform", "runtime" : "org.gnome.Platform",
"runtime-version" : "master", "runtime-version" : "master",
"sdk" : "org.gnome.Sdk", "sdk" : "org.gnome.Sdk",
@@ -10,18 +10,15 @@
"tags" : [ "tags" : [
"nightly" "nightly"
], ],
"desktop-file-name-prefix" : "(Nightly) ", "desktop-file-name-suffix" : " ☢️",
"finish-args" : [ "finish-args" : [
"--filesystem=xdg-run/dconf",
"--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf",
"--share=network", "--share=network",
"--share=ipc", "--share=ipc",
"--socket=x11", "--socket=x11",
"--socket=fallback-x11",
"--socket=wayland", "--socket=wayland",
"--socket=pulseaudio", "--socket=pulseaudio",
"--device=dri" "--env=USE_PLAYBING3=1"
], ],
"build-options" : { "build-options" : {
"append-path" : "/usr/lib/sdk/rust-stable/bin", "append-path" : "/usr/lib/sdk/rust-stable/bin",
@@ -30,6 +27,7 @@
], ],
"env" : { "env" : {
"CARGO_HOME" : "/run/build/Podcasts/cargo", "CARGO_HOME" : "/run/build/Podcasts/cargo",
"RUSTFLAGS" : "--error-format=short --remap-path-prefix =../",
"RUST_BACKTRACE" : "1" "RUST_BACKTRACE" : "1"
} }
}, },
@@ -37,22 +35,34 @@
{ {
"name" : "libhandy", "name" : "libhandy",
"buildsystem" : "meson", "buildsystem" : "meson",
"config-opts" : [
"-Dintrospection=disabled",
"-Dgtk_doc=false",
"-Dtests=false",
"-Dexamples=false",
"-Dvapi=false",
"-Dglade_catalog=disabled"
],
"cleanup" : [
"/include",
"/lib/pkgconfig"
],
"sources" : [ "sources" : [
{ {
"type" : "git", "type" : "git",
"url" : "https://source.puri.sm/Librem5/libhandy.git" "url" : "https://source.puri.sm/Librem5/libhandy.git",
"commit" : "f5909a897f70143bdd2f89f47a63c1bf848330ce"
} }
] ]
}, },
{ {
"name" : "gnome-podcasts", "name" : "gnome-podcasts",
"builddir" : "true",
"buildsystem" : "meson", "buildsystem" : "meson",
"config-opts" : [ "-Dprofile=development" ],
"sources" : [ "sources" : [
{ {
"type" : "git", "type" : "git",
"url" : "https://gitlab.gnome.org/World/podcasts.git", "url" : "https://gitlab.gnome.org/World/podcasts.git"
"branch" : "master"
} }
] ]
} }
+26 -25
View File
@@ -1,41 +1,42 @@
[package] [package]
authors = ["Jordan Petridis <jordanpetridis@protonmail.com>"] authors = ["Jordan Petridis <jpetridis@gnome.org>"]
name = "podcasts-data" name = "podcasts-data"
version = "0.1.0" version = "0.1.0"
workspace = "../" edition = "2018"
[dependencies] [dependencies]
ammonia = "1.2.0" ammonia = "3.0.0"
chrono = "0.4.6" chrono = "0.4.9"
derive_builder = "0.5.1" derive_builder = "0.8.0"
lazy_static = "1.1.0" lazy_static = "1.4.0"
log = "0.4.4" log = "0.4.8"
rayon = "1.0.2" rayon = "1.2.0"
rayon-futures = "0.1.0"
rfc822_sanitizer = "0.3.3" rfc822_sanitizer = "0.3.3"
rss = "1.5.0" rss = "1.8.0"
url = "1.7.1" url = "2.1.0"
xdg = "2.1.0" xdg = "2.2.0"
xml-rs = "0.8.0" xml-rs = "0.8.0"
futures = "0.1.23" futures = "0.1.29"
hyper = "0.11.27" hyper = "0.12.35"
tokio-core = "0.1.17" http = "0.1.19"
hyper-tls = "0.1.3" tokio = "0.1.22"
native-tls = "0.1.5" hyper-tls = "0.3.2"
num_cpus = "1.8.0" native-tls = "0.2.3"
failure = "0.1.2" num_cpus = "1.10.1"
failure_derive = "0.1.2" failure = "0.1.6"
failure_derive = "0.1.6"
base64 = "0.10.1"
[dependencies.diesel] [dependencies.diesel]
features = ["sqlite", "r2d2"] features = ["sqlite", "r2d2"]
version = "1.3.2" version = "1.4.3"
[dependencies.diesel_migrations] [dependencies.diesel_migrations]
features = ["sqlite"] features = ["sqlite"]
version = "1.3.0" version = "1.4.0"
[dev-dependencies] [dev-dependencies]
rand = "0.5.5" rand = "0.7.2"
tempdir = "0.3.7" tempdir = "0.3.7"
pretty_assertions = "0.5.1" pretty_assertions = "0.6.1"
maplit = "1.0.1" maplit = "1.0.2"
+23 -6
View File
@@ -1,3 +1,22 @@
// database.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//! Database Setup. This is only public to help with some unit tests. //! Database Setup. This is only public to help with some unit tests.
// Diesel embed_migrations! triggers the lint // Diesel embed_migrations! triggers the lint
#![allow(unused_imports)] #![allow(unused_imports)]
@@ -9,10 +28,10 @@ use diesel::r2d2::ConnectionManager;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
use errors::DataError; use crate::errors::DataError;
#[cfg(not(test))] #[cfg(not(test))]
use xdg_dirs; use crate::xdg_dirs;
type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>; type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
@@ -29,12 +48,10 @@ lazy_static! {
.unwrap(); .unwrap();
} }
#[cfg(test)]
extern crate tempdir;
#[cfg(test)] #[cfg(test)]
lazy_static! { lazy_static! {
static ref TEMPDIR: tempdir::TempDir = { tempdir::TempDir::new("podcasts_unit_test").unwrap() }; pub(crate) static ref TEMPDIR: tempdir::TempDir =
{ tempdir::TempDir::new("podcasts_unit_test").unwrap() };
static ref DB_PATH: PathBuf = TEMPDIR.path().join("podcasts.db"); static ref DB_PATH: PathBuf = TEMPDIR.path().join("podcasts.db");
} }
+60 -41
View File
@@ -1,3 +1,22 @@
// dbqueries.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//! Random CRUD helper functions. //! Random CRUD helper functions.
use chrono::prelude::*; use chrono::prelude::*;
@@ -5,15 +24,14 @@ use diesel::prelude::*;
use diesel; use diesel;
use diesel::dsl::exists; use diesel::dsl::exists;
use diesel::query_builder::AsQuery;
use diesel::select; use diesel::select;
use database::connection; use crate::database::connection;
use errors::DataError; use crate::errors::DataError;
use models::*; use crate::models::*;
pub fn get_sources() -> Result<Vec<Source>, DataError> { pub fn get_sources() -> Result<Vec<Source>, DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -24,7 +42,7 @@ pub fn get_sources() -> Result<Vec<Source>, DataError> {
} }
pub fn get_podcasts() -> Result<Vec<Show>, DataError> { pub fn get_podcasts() -> Result<Vec<Show>, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -35,7 +53,7 @@ pub fn get_podcasts() -> Result<Vec<Show>, DataError> {
} }
pub fn get_podcasts_filter(filter_ids: &[i32]) -> Result<Vec<Show>, DataError> { pub fn get_podcasts_filter(filter_ids: &[i32]) -> Result<Vec<Show>, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -47,7 +65,7 @@ pub fn get_podcasts_filter(filter_ids: &[i32]) -> Result<Vec<Show>, DataError> {
} }
pub fn get_episodes() -> Result<Vec<Episode>, DataError> { pub fn get_episodes() -> Result<Vec<Episode>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -58,7 +76,7 @@ pub fn get_episodes() -> Result<Vec<Episode>, DataError> {
} }
pub(crate) fn get_downloaded_episodes() -> Result<Vec<EpisodeCleanerModel>, DataError> { pub(crate) fn get_downloaded_episodes() -> Result<Vec<EpisodeCleanerModel>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -81,7 +99,7 @@ pub(crate) fn get_downloaded_episodes() -> Result<Vec<EpisodeCleanerModel>, Data
// } // }
pub(crate) fn get_played_cleaner_episodes() -> Result<Vec<EpisodeCleanerModel>, DataError> { pub(crate) fn get_played_cleaner_episodes() -> Result<Vec<EpisodeCleanerModel>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -93,7 +111,7 @@ pub(crate) fn get_played_cleaner_episodes() -> Result<Vec<EpisodeCleanerModel>,
} }
pub fn get_episode_from_rowid(ep_id: i32) -> Result<Episode, DataError> { pub fn get_episode_from_rowid(ep_id: i32) -> Result<Episode, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -104,20 +122,21 @@ pub fn get_episode_from_rowid(ep_id: i32) -> Result<Episode, DataError> {
} }
pub fn get_episode_widget_from_rowid(ep_id: i32) -> Result<EpisodeWidgetModel, DataError> { pub fn get_episode_widget_from_rowid(ep_id: i32) -> Result<EpisodeWidgetModel, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
episodes episodes
.select(( .select((
rowid, title, uri, local_uri, epoch, length, duration, played, show_id, rowid, title, uri, local_uri, epoch, length, duration, played, show_id,
)).filter(rowid.eq(ep_id)) ))
.filter(rowid.eq(ep_id))
.get_result::<EpisodeWidgetModel>(&con) .get_result::<EpisodeWidgetModel>(&con)
.map_err(From::from) .map_err(From::from)
} }
pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result<Option<String>, DataError> { pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result<Option<String>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -132,7 +151,7 @@ pub fn get_episodes_widgets_filter_limit(
filter_ids: &[i32], filter_ids: &[i32],
limit: u32, limit: u32,
) -> Result<Vec<EpisodeWidgetModel>, DataError> { ) -> Result<Vec<EpisodeWidgetModel>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
let columns = ( let columns = (
@@ -149,7 +168,7 @@ pub fn get_episodes_widgets_filter_limit(
} }
pub fn get_podcast_from_id(pid: i32) -> Result<Show, DataError> { pub fn get_podcast_from_id(pid: i32) -> Result<Show, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -160,7 +179,7 @@ pub fn get_podcast_from_id(pid: i32) -> Result<Show, DataError> {
} }
pub fn get_podcast_cover_from_id(pid: i32) -> Result<ShowCoverModel, DataError> { pub fn get_podcast_cover_from_id(pid: i32) -> Result<ShowCoverModel, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -172,7 +191,7 @@ pub fn get_podcast_cover_from_id(pid: i32) -> Result<ShowCoverModel, DataError>
} }
pub fn get_pd_episodes(parent: &Show) -> Result<Vec<Episode>, DataError> { pub fn get_pd_episodes(parent: &Show) -> Result<Vec<Episode>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -193,7 +212,7 @@ pub fn get_pd_episodes_count(parent: &Show) -> Result<i64, DataError> {
} }
pub fn get_pd_episodeswidgets(parent: &Show) -> Result<Vec<EpisodeWidgetModel>, DataError> { pub fn get_pd_episodeswidgets(parent: &Show) -> Result<Vec<EpisodeWidgetModel>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
let columns = ( let columns = (
@@ -209,7 +228,7 @@ pub fn get_pd_episodeswidgets(parent: &Show) -> Result<Vec<EpisodeWidgetModel>,
} }
pub fn get_pd_unplayed_episodes(parent: &Show) -> Result<Vec<Episode>, DataError> { pub fn get_pd_unplayed_episodes(parent: &Show) -> Result<Vec<Episode>, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -234,7 +253,7 @@ pub fn get_pd_unplayed_episodes(parent: &Show) -> Result<Vec<Episode>, DataError
// } // }
pub fn get_source_from_uri(uri_: &str) -> Result<Source, DataError> { pub fn get_source_from_uri(uri_: &str) -> Result<Source, DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -245,7 +264,7 @@ pub fn get_source_from_uri(uri_: &str) -> Result<Source, DataError> {
} }
pub fn get_source_from_id(id_: i32) -> Result<Source, DataError> { pub fn get_source_from_id(id_: i32) -> Result<Source, DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -256,7 +275,7 @@ pub fn get_source_from_id(id_: i32) -> Result<Source, DataError> {
} }
pub fn get_podcast_from_source_id(sid: i32) -> Result<Show, DataError> { pub fn get_podcast_from_source_id(sid: i32) -> Result<Show, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -267,7 +286,7 @@ pub fn get_podcast_from_source_id(sid: i32) -> Result<Show, DataError> {
} }
pub fn get_episode_from_pk(title_: &str, pid: i32) -> Result<Episode, DataError> { pub fn get_episode_from_pk(title_: &str, pid: i32) -> Result<Episode, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -282,7 +301,7 @@ pub(crate) fn get_episode_minimal_from_pk(
title_: &str, title_: &str,
pid: i32, pid: i32,
) -> Result<EpisodeMinimal, DataError> { ) -> Result<EpisodeMinimal, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -299,7 +318,7 @@ pub(crate) fn get_episode_cleaner_from_pk(
title_: &str, title_: &str,
pid: i32, pid: i32,
) -> Result<EpisodeCleanerModel, DataError> { ) -> Result<EpisodeCleanerModel, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -325,25 +344,25 @@ pub(crate) fn remove_feed(pd: &Show) -> Result<(), DataError> {
} }
fn delete_source(con: &SqliteConnection, source_id: i32) -> QueryResult<usize> { fn delete_source(con: &SqliteConnection, source_id: i32) -> QueryResult<usize> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
diesel::delete(source.filter(id.eq(source_id))).execute(con) diesel::delete(source.filter(id.eq(source_id))).execute(con)
} }
fn delete_podcast(con: &SqliteConnection, show_id: i32) -> QueryResult<usize> { fn delete_podcast(con: &SqliteConnection, show_id: i32) -> QueryResult<usize> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
diesel::delete(shows.filter(id.eq(show_id))).execute(con) diesel::delete(shows.filter(id.eq(show_id))).execute(con)
} }
fn delete_podcast_episodes(con: &SqliteConnection, parent_id: i32) -> QueryResult<usize> { fn delete_podcast_episodes(con: &SqliteConnection, parent_id: i32) -> QueryResult<usize> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
diesel::delete(episodes.filter(show_id.eq(parent_id))).execute(con) diesel::delete(episodes.filter(show_id.eq(parent_id))).execute(con)
} }
pub fn source_exists(url: &str) -> Result<bool, DataError> { pub fn source_exists(url: &str) -> Result<bool, DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -354,7 +373,7 @@ pub fn source_exists(url: &str) -> Result<bool, DataError> {
} }
pub(crate) fn podcast_exists(source_id_: i32) -> Result<bool, DataError> { pub(crate) fn podcast_exists(source_id_: i32) -> Result<bool, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -366,7 +385,7 @@ pub(crate) fn podcast_exists(source_id_: i32) -> Result<bool, DataError> {
#[cfg_attr(rustfmt, rustfmt_skip)] #[cfg_attr(rustfmt, rustfmt_skip)]
pub(crate) fn episode_exists(title_: &str, show_id_: i32) -> Result<bool, DataError> { pub(crate) fn episode_exists(title_: &str, show_id_: i32) -> Result<bool, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -379,13 +398,13 @@ pub(crate) fn episode_exists(title_: &str, show_id_: i32) -> Result<bool, DataEr
/// Check if the `episodes table contains any rows /// Check if the `episodes table contains any rows
/// ///
/// Return true if `episodes` table is populated. /// Return true if `episodes` table is populated.
pub fn is_episodes_populated() -> Result<bool, DataError> { pub fn is_episodes_populated(filter_show_ids: &[i32]) -> Result<bool, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
select(exists(episodes.as_query())) select(exists(episodes.filter(show_id.ne_all(filter_show_ids))))
.get_result(&con) .get_result(&con)
.map_err(From::from) .map_err(From::from)
} }
@@ -394,7 +413,7 @@ pub fn is_episodes_populated() -> Result<bool, DataError> {
/// ///
/// Return true if `shows` table is populated. /// Return true if `shows` table is populated.
pub fn is_podcasts_populated(filter_ids: &[i32]) -> Result<bool, DataError> { pub fn is_podcasts_populated(filter_ids: &[i32]) -> Result<bool, DataError> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -408,7 +427,7 @@ pub fn is_podcasts_populated(filter_ids: &[i32]) -> Result<bool, DataError> {
/// ///
/// Return true if `source` table is populated. /// Return true if `source` table is populated.
pub fn is_source_populated(filter_ids: &[i32]) -> Result<bool, DataError> { pub fn is_source_populated(filter_ids: &[i32]) -> Result<bool, DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -419,7 +438,7 @@ pub fn is_source_populated(filter_ids: &[i32]) -> Result<bool, DataError> {
} }
pub(crate) fn index_new_episodes(eps: &[NewEpisode]) -> Result<(), DataError> { pub(crate) fn index_new_episodes(eps: &[NewEpisode]) -> Result<(), DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -431,7 +450,7 @@ pub(crate) fn index_new_episodes(eps: &[NewEpisode]) -> Result<(), DataError> {
} }
pub fn update_none_to_played_now(parent: &Show) -> Result<usize, DataError> { pub fn update_none_to_played_now(parent: &Show) -> Result<usize, DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -447,9 +466,9 @@ pub fn update_none_to_played_now(parent: &Show) -> Result<usize, DataError> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use database::*; use crate::database::*;
use crate::pipeline;
use failure::Error; use failure::Error;
use pipeline;
#[test] #[test]
fn test_update_none_to_played_now() -> Result<(), Error> { fn test_update_none_to_played_now() -> Result<(), Error> {
+56 -72
View File
@@ -1,6 +1,26 @@
// errors.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use diesel; use diesel;
use diesel::r2d2; use diesel::r2d2;
use diesel_migrations::RunMigrationsError; use diesel_migrations::RunMigrationsError;
use http;
use hyper; use hyper;
use native_tls; use native_tls;
use rss; use rss;
@@ -9,13 +29,11 @@ use xml;
use std::io; use std::io;
use models::Source; use crate::models::Source;
#[fail( #[fail(
display = "Request to {} returned {}. Context: {}", display = "Request to {} returned {}. Context: {}",
url, url, status_code, context
status_code,
context
)] )]
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub struct HttpStatusError { pub struct HttpStatusError {
@@ -46,6 +64,8 @@ pub enum DataError {
R2D2PoolError(#[cause] r2d2::PoolError), R2D2PoolError(#[cause] r2d2::PoolError),
#[fail(display = "Hyper Error: {}", _0)] #[fail(display = "Hyper Error: {}", _0)]
HyperError(#[cause] hyper::Error), HyperError(#[cause] hyper::Error),
#[fail(display = "ToStr Error: {}", _0)]
HttpToStr(#[cause] http::header::ToStrError),
#[fail(display = "Failed to parse a url: {}", _0)] #[fail(display = "Failed to parse a url: {}", _0)]
UrlError(#[cause] url::ParseError), UrlError(#[cause] url::ParseError),
#[fail(display = "TLS Error: {}", _0)] #[fail(display = "TLS Error: {}", _0)]
@@ -60,79 +80,43 @@ pub enum DataError {
Bail(String), Bail(String),
#[fail(display = "{}", _0)] #[fail(display = "{}", _0)]
HttpStatusGeneral(HttpStatusError), HttpStatusGeneral(HttpStatusError),
#[fail(display = "FIXME: This should be better")] #[fail(display = "Source redirects to a new url")]
F301(Source), FeedRedirect(Source),
#[fail( #[fail(display = "Feed is up to date")]
display = "Error occured while Parsing an Episode. Reason: {}", FeedNotModified(Source),
reason #[fail(display = "Error occured while Parsing an Episode. Reason: {}", reason)]
)]
ParseEpisodeError { reason: String, parent_id: i32 }, ParseEpisodeError { reason: String, parent_id: i32 },
#[fail(display = "Episode was not changed and thus skipped.")] #[fail(display = "Episode was not changed and thus skipped.")]
EpisodeNotChanged, EpisodeNotChanged,
} }
impl From<RunMigrationsError> for DataError { // Maps a type to a variant of the DataError enum
fn from(err: RunMigrationsError) -> Self { macro_rules! easy_from_impl {
DataError::DieselMigrationError(err) ($outer_type:ty, $from:ty => $to:expr) => (
impl From<$from> for $outer_type {
fn from(err: $from) -> Self {
$to(err)
} }
}
);
($outer_type:ty, $from:ty => $to:expr, $($f:ty => $t:expr),+) => (
easy_from_impl!($outer_type, $from => $to);
easy_from_impl!($outer_type, $($f => $t),+);
);
} }
impl From<diesel::result::Error> for DataError { easy_from_impl!(
fn from(err: diesel::result::Error) -> Self { DataError,
DataError::DieselResultError(err) RunMigrationsError => DataError::DieselMigrationError,
} diesel::result::Error => DataError::DieselResultError,
} r2d2::Error => DataError::R2D2Error,
r2d2::PoolError => DataError::R2D2PoolError,
impl From<r2d2::Error> for DataError { hyper::Error => DataError::HyperError,
fn from(err: r2d2::Error) -> Self { http::header::ToStrError => DataError::HttpToStr,
DataError::R2D2Error(err) url::ParseError => DataError::UrlError,
} native_tls::Error => DataError::TLSError,
} io::Error => DataError::IOError,
rss::Error => DataError::RssError,
impl From<r2d2::PoolError> for DataError { xml::reader::Error => DataError::XmlReaderError,
fn from(err: r2d2::PoolError) -> Self { String => DataError::Bail
DataError::R2D2PoolError(err) );
}
}
impl From<hyper::Error> for DataError {
fn from(err: hyper::Error) -> Self {
DataError::HyperError(err)
}
}
impl From<url::ParseError> for DataError {
fn from(err: url::ParseError) -> Self {
DataError::UrlError(err)
}
}
impl From<native_tls::Error> for DataError {
fn from(err: native_tls::Error) -> Self {
DataError::TLSError(err)
}
}
impl From<io::Error> for DataError {
fn from(err: io::Error) -> Self {
DataError::IOError(err)
}
}
impl From<rss::Error> for DataError {
fn from(err: rss::Error) -> Self {
DataError::RssError(err)
}
}
impl From<xml::reader::Error> for DataError {
fn from(err: xml::reader::Error) -> Self {
DataError::XmlReaderError(err)
}
}
impl From<String> for DataError {
fn from(err: String) -> Self {
DataError::Bail(err)
}
}
+38 -24
View File
@@ -1,3 +1,23 @@
// feed.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![cfg_attr(feature = "cargo-clippy", allow(unit_arg))] #![cfg_attr(feature = "cargo-clippy", allow(unit_arg))]
//! Index Feeds. //! Index Feeds.
@@ -6,10 +26,10 @@ use futures::prelude::*;
use futures::stream; use futures::stream;
use rss; use rss;
use dbqueries; use crate::dbqueries;
use errors::DataError; use crate::errors::DataError;
use models::{Index, IndexState, Update}; use crate::models::{Index, IndexState, Update};
use models::{NewEpisode, NewEpisodeMinimal, NewShow, Show}; use crate::models::{NewEpisode, NewEpisodeMinimal, NewShow, Show};
/// Wrapper struct that hold a `Source` id and the `rss::Channel` /// Wrapper struct that hold a `Source` id and the `rss::Channel`
/// that corresponds to the `Source.uri` field. /// that corresponds to the `Source.uri` field.
@@ -26,7 +46,7 @@ pub struct Feed {
impl Feed { impl Feed {
/// Index the contents of the RSS `Feed` into the database. /// Index the contents of the RSS `Feed` into the database.
pub fn index(self) -> impl Future<Item = (), Error = DataError> + Send { pub fn index(self) -> impl Future<Item = (), Error = DataError> + Send {
self.parse_podcast_async() ok(self.parse_podcast())
.and_then(|pd| pd.to_podcast()) .and_then(|pd| pd.to_podcast())
.and_then(move |pd| self.index_channel_items(pd)) .and_then(move |pd| self.index_channel_items(pd))
} }
@@ -35,16 +55,13 @@ impl Feed {
NewShow::new(&self.channel, self.source_id) NewShow::new(&self.channel, self.source_id)
} }
fn parse_podcast_async(&self) -> impl Future<Item = NewShow, Error = DataError> + Send {
ok(self.parse_podcast())
}
fn index_channel_items(self, pd: Show) -> impl Future<Item = (), Error = DataError> + Send { fn index_channel_items(self, pd: Show) -> impl Future<Item = (), Error = DataError> + Send {
let stream = stream::iter_ok::<_, DataError>(self.channel.into_items()); let stream = stream::iter_ok::<_, DataError>(self.channel.into_items());
// Parse the episodes // Parse the episodes
let episodes = stream.filter_map(move |item| { let episodes = stream.filter_map(move |item| {
glue(&item, pd.id()) NewEpisodeMinimal::new(&item, pd.id())
.and_then(move |ep| determine_ep_state(ep, &item))
.map_err(|err| error!("Failed to parse an episode: {}", err)) .map_err(|err| error!("Failed to parse an episode: {}", err))
.ok() .ok()
}); });
@@ -56,10 +73,6 @@ impl Feed {
} }
} }
fn glue(item: &rss::Item, id: i32) -> Result<IndexState<NewEpisode>, DataError> {
NewEpisodeMinimal::new(item, id).and_then(move |ep| determine_ep_state(ep, item))
}
fn determine_ep_state( fn determine_ep_state(
ep: NewEpisodeMinimal, ep: NewEpisodeMinimal,
item: &rss::Item, item: &rss::Item,
@@ -115,7 +128,8 @@ fn batch_insert_episodes(episodes: &[NewEpisode]) {
.map_err(|err| { .map_err(|err| {
error!("Failed batch indexng: {}", err); error!("Failed batch indexng: {}", err);
info!("Fallign back to individual indexing."); info!("Fallign back to individual indexing.");
}).unwrap_or_else(|_| { })
.unwrap_or_else(|_| {
episodes.iter().for_each(|ep| { episodes.iter().for_each(|ep| {
ep.index() ep.index()
.map_err(|err| error!("Error: {}.", err)) .map_err(|err| error!("Error: {}.", err))
@@ -129,12 +143,12 @@ fn batch_insert_episodes(episodes: &[NewEpisode]) {
mod tests { mod tests {
use failure::Error; use failure::Error;
use rss::Channel; use rss::Channel;
use tokio_core::reactor::Core; use tokio::{self, prelude::*};
use database::truncate_db; use crate::database::truncate_db;
use dbqueries; use crate::dbqueries;
use utils::get_feed; use crate::utils::get_feed;
use Source; use crate::Source;
use std::fs; use std::fs;
use std::io::BufReader; use std::io::BufReader;
@@ -181,12 +195,12 @@ mod tests {
// Create and insert a Source into db // Create and insert a Source into db
let s = Source::from_url(url).unwrap(); let s = Source::from_url(url).unwrap();
get_feed(path, s.id()) get_feed(path, s.id())
}).collect(); })
.collect();
let mut core = Core::new()?;
// Index the channes // Index the channes
let list: Vec<_> = feeds.into_iter().map(|x| x.index()).collect(); let stream_ = stream::iter_ok(feeds).for_each(|x| x.index());
let _foo = core.run(join_all(list)); tokio::run(stream_.map_err(|_| ()));
// Assert the index rows equal the controlled results // Assert the index rows equal the controlled results
assert_eq!(dbqueries::get_sources()?.len(), 5); assert_eq!(dbqueries::get_sources()?.len(), 5);
+27 -27
View File
@@ -1,10 +1,28 @@
// lib.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![cfg_attr( #![cfg_attr(
all(test, feature = "clippy"), all(test, feature = "clippy"),
allow(option_unwrap_used, result_unwrap_used) allow(option_unwrap_used, result_unwrap_used)
)] )]
#![cfg_attr(feature = "cargo-clippy", allow(option_map_unit_fn))]
#![cfg_attr( #![cfg_attr(
feature = "clippy", feature = "clippy",
warn( warn(
@@ -24,7 +42,7 @@
)] )]
// Enable lint group collections // Enable lint group collections
#![warn(nonstandard_style, bad_style, unused)] #![warn(nonstandard_style, bad_style, unused)]
#![allow(edition_2018, rust_2018_idioms)] #![warn(edition_2018, rust_2018_idioms)]
// standalone lints // standalone lints
#![warn( #![warn(
const_err, const_err,
@@ -33,8 +51,6 @@
no_mangle_generic_items, no_mangle_generic_items,
overflowing_literals, overflowing_literals,
plugin_as_library, plugin_as_library,
private_no_mangle_fns,
private_no_mangle_statics,
unconditional_recursion, unconditional_recursion,
unions_with_drop_fields, unions_with_drop_fields,
while_true, while_true,
@@ -45,7 +61,7 @@
elided_lifetime_in_paths, elided_lifetime_in_paths,
missing_copy_implementations missing_copy_implementations
)] )]
#![deny(warnings)] #![allow(proc_macro_derive_resolution_fallback)]
//! FIXME: Docs //! FIXME: Docs
@@ -64,7 +80,7 @@ extern crate diesel;
#[macro_use] #[macro_use]
extern crate diesel_migrations; extern crate diesel_migrations;
// #[macro_use] // #[macro_use]
extern crate failure; // extern crate failure;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[macro_use] #[macro_use]
@@ -72,22 +88,6 @@ extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate ammonia;
extern crate chrono;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate native_tls;
extern crate num_cpus;
extern crate rayon;
extern crate rayon_futures;
extern crate rfc822_sanitizer;
extern crate rss;
extern crate tokio_core;
extern crate url;
extern crate xdg;
extern crate xml;
pub mod database; pub mod database;
#[allow(missing_docs)] #[allow(missing_docs)]
pub mod dbqueries; pub mod dbqueries;
@@ -101,15 +101,15 @@ pub mod pipeline;
mod schema; mod schema;
pub mod utils; pub mod utils;
pub use feed::{Feed, FeedBuilder}; pub use crate::feed::{Feed, FeedBuilder};
pub use models::Save; pub use crate::models::Save;
pub use models::{Episode, EpisodeWidgetModel, Show, ShowCoverModel, Source}; pub use crate::models::{Episode, EpisodeWidgetModel, Show, ShowCoverModel, Source};
// Set the user agent, See #53 for more // Set the user agent, See #53 for more
// Keep this in sync with Tor-browser releases // Keep this in sync with Tor-browser releases
/// The user-agent to be used for all the requests. /// The user-agent to be used for all the requests.
/// It originates from the Tor-browser UA. /// It originates from the Tor-browser UA.
pub const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0"; pub const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0";
/// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths.
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
@@ -117,7 +117,7 @@ pub mod xdg_dirs {
use std::path::PathBuf; use std::path::PathBuf;
use xdg; use xdg;
lazy_static!{ lazy_static! {
pub(crate) static ref PODCASTS_XDG: xdg::BaseDirectories = { pub(crate) static ref PODCASTS_XDG: xdg::BaseDirectories = {
xdg::BaseDirectories::with_prefix("gnome-podcasts").unwrap() xdg::BaseDirectories::with_prefix("gnome-podcasts").unwrap()
}; };
+19
View File
@@ -0,0 +1,19 @@
data_sources = files(
'models/episode.rs',
'models/mod.rs',
'models/new_episode.rs',
'models/new_show.rs',
'models/new_source.rs',
'models/show.rs',
'models/source.rs',
'database.rs',
'dbqueries.rs',
'errors.rs',
'feed.rs',
'lib.rs',
'opml.rs',
'parser.rs',
'pipeline.rs',
'schema.rs',
'utils.rs',
)
+25 -6
View File
@@ -1,12 +1,31 @@
// episode.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use chrono::prelude::*; use chrono::prelude::*;
use diesel; use diesel;
use diesel::prelude::*; use diesel::prelude::*;
use diesel::SaveChangesDsl; use diesel::SaveChangesDsl;
use database::connection; use crate::database::connection;
use errors::DataError; use crate::errors::DataError;
use models::{Save, Show}; use crate::models::{Save, Show};
use schema::episodes; use crate::schema::episodes;
#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)]
#[table_name = "episodes"] #[table_name = "episodes"]
@@ -153,7 +172,7 @@ impl Save<usize> for EpisodeWidgetModel {
/// Helper method to easily save/"sync" current state of self to the /// Helper method to easily save/"sync" current state of self to the
/// Database. /// Database.
fn save(&self) -> Result<usize, Self::Error> { fn save(&self) -> Result<usize, Self::Error> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let tempdb = db.get()?; let tempdb = db.get()?;
@@ -266,7 +285,7 @@ impl Save<usize> for EpisodeCleanerModel {
/// Helper method to easily save/"sync" current state of self to the /// Helper method to easily save/"sync" current state of self to the
/// Database. /// Database.
fn save(&self) -> Result<usize, Self::Error> { fn save(&self) -> Result<usize, Self::Error> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let tempdb = db.get()?; let tempdb = db.get()?;
+20 -1
View File
@@ -1,3 +1,22 @@
// mod.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
mod new_episode; mod new_episode;
mod new_show; mod new_show;
mod new_source; mod new_source;
@@ -39,7 +58,7 @@ pub trait Insert<T> {
pub trait Update<T> { pub trait Update<T> {
type Error; type Error;
fn update(&self, i32) -> Result<T, Self::Error>; fn update(&self, _: i32) -> Result<T, Self::Error>;
} }
// This might need to change in the future // This might need to change in the future
+50 -22
View File
@@ -1,16 +1,35 @@
// new_episode.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use ammonia; use ammonia;
use diesel; use diesel;
use diesel::prelude::*; use diesel::prelude::*;
use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822;
use rss; use rss;
use database::connection; use crate::database::connection;
use dbqueries; use crate::dbqueries;
use errors::DataError; use crate::errors::DataError;
use models::{Episode, EpisodeMinimal, Index, Insert, Update}; use crate::models::{Episode, EpisodeMinimal, Index, Insert, Update};
use parser; use crate::parser;
use schema::episodes; use crate::schema::episodes;
use utils::url_cleaner; use crate::utils::url_cleaner;
#[derive(Insertable, AsChangeset)] #[derive(Insertable, AsChangeset)]
#[table_name = "episodes"] #[table_name = "episodes"]
@@ -47,7 +66,7 @@ impl Insert<()> for NewEpisode {
type Error = DataError; type Error = DataError;
fn insert(&self) -> Result<(), DataError> { fn insert(&self) -> Result<(), DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -64,7 +83,7 @@ impl Update<()> for NewEpisode {
type Error = DataError; type Error = DataError;
fn update(&self, episode_id: i32) -> Result<(), DataError> { fn update(&self, episode_id: i32) -> Result<(), DataError> {
use schema::episodes::dsl::*; use crate::schema::episodes::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -311,11 +330,11 @@ impl NewEpisodeMinimal {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use database::truncate_db; use crate::database::truncate_db;
use dbqueries; use crate::dbqueries;
use crate::models::new_episode::{NewEpisodeMinimal, NewEpisodeMinimalBuilder};
use crate::models::*;
use failure::Error; use failure::Error;
use models::new_episode::{NewEpisodeMinimal, NewEpisodeMinimalBuilder};
use models::*;
use rss::Channel; use rss::Channel;
@@ -332,7 +351,8 @@ mod tests {
.title("The Super Bowl of Racism") .title("The Super Bowl of Racism")
.uri(Some(String::from( .uri(Some(String::from(
"http://traffic.megaphone.fm/PPY6458293736.mp3", "http://traffic.megaphone.fm/PPY6458293736.mp3",
))).guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24"))) )))
.guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24")))
.epoch(1505296800) .epoch(1505296800)
.length(Some(66738886)) .length(Some(66738886))
.duration(Some(4171)) .duration(Some(4171))
@@ -345,7 +365,8 @@ mod tests {
.title("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America") .title("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America")
.uri(Some(String::from( .uri(Some(String::from(
"http://traffic.megaphone.fm/FL5331443769.mp3", "http://traffic.megaphone.fm/FL5331443769.mp3",
))).guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d"))) )))
.guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d")))
.epoch(1502272800) .epoch(1502272800)
.length(Some(67527575)) .length(Some(67527575))
.duration(Some(4415)) .duration(Some(4415))
@@ -364,7 +385,8 @@ mod tests {
.title("The Super Bowl of Racism") .title("The Super Bowl of Racism")
.uri(Some(String::from( .uri(Some(String::from(
"http://traffic.megaphone.fm/PPY6458293736.mp3", "http://traffic.megaphone.fm/PPY6458293736.mp3",
))).description(Some(String::from(descr))) )))
.description(Some(String::from(descr)))
.guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24"))) .guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24")))
.length(Some(66738886)) .length(Some(66738886))
.epoch(1505296800) .epoch(1505296800)
@@ -387,7 +409,8 @@ mod tests {
.title("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America") .title("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America")
.uri(Some(String::from( .uri(Some(String::from(
"http://traffic.megaphone.fm/FL5331443769.mp3", "http://traffic.megaphone.fm/FL5331443769.mp3",
))).description(Some(String::from(descr))) )))
.description(Some(String::from(descr)))
.guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d"))) .guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d")))
.length(Some(67527575)) .length(Some(67527575))
.epoch(1502272800) .epoch(1502272800)
@@ -401,7 +424,8 @@ mod tests {
.title("The Super Bowl of Racism") .title("The Super Bowl of Racism")
.uri(Some(String::from( .uri(Some(String::from(
"http://traffic.megaphone.fm/PPY6458293736.mp3", "http://traffic.megaphone.fm/PPY6458293736.mp3",
))).description(Some(String::from("New description"))) )))
.description(Some(String::from("New description")))
.guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24"))) .guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24")))
.length(Some(66738886)) .length(Some(66738886))
.epoch(1505296800) .epoch(1505296800)
@@ -415,7 +439,8 @@ mod tests {
.title("Hacking Devices with Kali Linux | LUP 214") .title("Hacking Devices with Kali Linux | LUP 214")
.uri(Some(String::from( .uri(Some(String::from(
"http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3", "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3",
))).guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D"))) )))
.guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D")))
.length(Some(46479789)) .length(Some(46479789))
.epoch(1505280282) .epoch(1505280282)
.duration(Some(5733)) .duration(Some(5733))
@@ -428,7 +453,8 @@ mod tests {
.title("Gnome Does it Again | LUP 213") .title("Gnome Does it Again | LUP 213")
.uri(Some(String::from( .uri(Some(String::from(
"http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3", "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3",
))).guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B"))) )))
.guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B")))
.epoch(1504670247) .epoch(1504670247)
.length(Some(36544272)) .length(Some(36544272))
.duration(Some(4491)) .duration(Some(4491))
@@ -446,7 +472,8 @@ mod tests {
.title("Hacking Devices with Kali Linux | LUP 214") .title("Hacking Devices with Kali Linux | LUP 214")
.uri(Some(String::from( .uri(Some(String::from(
"http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3", "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3",
))).description(Some(String::from(descr))) )))
.description(Some(String::from(descr)))
.guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D"))) .guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D")))
.length(Some(46479789)) .length(Some(46479789))
.epoch(1505280282) .epoch(1505280282)
@@ -467,7 +494,8 @@ mod tests {
.title("Gnome Does it Again | LUP 213") .title("Gnome Does it Again | LUP 213")
.uri(Some(String::from( .uri(Some(String::from(
"http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3", "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3",
))).description(Some(String::from(descr))) )))
.description(Some(String::from(descr)))
.guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B"))) .guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B")))
.length(Some(36544272)) .length(Some(36544272))
.epoch(1504670247) .epoch(1504670247)
+36 -14
View File
@@ -1,16 +1,35 @@
// new_show.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use ammonia; use ammonia;
use diesel; use diesel;
use diesel::prelude::*; use diesel::prelude::*;
use rss; use rss;
use errors::DataError; use crate::errors::DataError;
use models::Show; use crate::models::Show;
use models::{Index, Insert, Update}; use crate::models::{Index, Insert, Update};
use schema::shows; use crate::schema::shows;
use database::connection; use crate::database::connection;
use dbqueries; use crate::dbqueries;
use utils::url_cleaner; use crate::utils::url_cleaner;
#[derive(Insertable, AsChangeset)] #[derive(Insertable, AsChangeset)]
#[table_name = "shows"] #[table_name = "shows"]
@@ -30,7 +49,7 @@ impl Insert<()> for NewShow {
type Error = DataError; type Error = DataError;
fn insert(&self) -> Result<(), Self::Error> { fn insert(&self) -> Result<(), Self::Error> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -46,7 +65,7 @@ impl Update<()> for NewShow {
type Error = DataError; type Error = DataError;
fn update(&self, show_id: i32) -> Result<(), Self::Error> { fn update(&self, show_id: i32) -> Result<(), Self::Error> {
use schema::shows::dsl::*; use crate::schema::shows::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
@@ -160,8 +179,8 @@ mod tests {
use failure::Error; use failure::Error;
use rss::Channel; use rss::Channel;
use database::truncate_db; use crate::database::truncate_db;
use models::NewShowBuilder; use crate::models::NewShowBuilder;
use std::fs::File; use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
@@ -200,7 +219,8 @@ mod tests {
.description(descr) .description(descr)
.image_uri(Some(String::from( .image_uri(Some(String::from(
"http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg", "http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg",
))).source_id(42) )))
.source_id(42)
.build() .build()
.unwrap() .unwrap()
}; };
@@ -222,7 +242,8 @@ mod tests {
.image_uri(Some(String::from( .image_uri(Some(String::from(
"https://imagecdn.acast.com/image?h=1500&w=1500&source=http%3A%2F%2Fi1.sndcdn.\ "https://imagecdn.acast.com/image?h=1500&w=1500&source=http%3A%2F%2Fi1.sndcdn.\
com%2Favatars-000317856075-a2coqz-original.jpg", com%2Favatars-000317856075-a2coqz-original.jpg",
))).source_id(42) )))
.source_id(42)
.build() .build()
.unwrap() .unwrap()
}; };
@@ -256,7 +277,8 @@ mod tests {
.description(descr) .description(descr)
.image_uri(Some(String::from( .image_uri(Some(String::from(
"http://www.greaterthancode.com/wp-content/uploads/2016/10/code1400-4.jpg", "http://www.greaterthancode.com/wp-content/uploads/2016/10/code1400-4.jpg",
))).source_id(42) )))
.source_id(42)
.build() .build()
.unwrap() .unwrap()
}; };
+25 -6
View File
@@ -1,13 +1,32 @@
// new_source.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use diesel; use diesel;
use diesel::prelude::*; use diesel::prelude::*;
use url::Url; use url::Url;
use database::connection; use crate::database::connection;
use dbqueries; use crate::dbqueries;
// use models::{Insert, Update}; // use models::{Insert, Update};
use errors::DataError; use crate::errors::DataError;
use models::Source; use crate::models::Source;
use schema::source; use crate::schema::source;
#[derive(Insertable)] #[derive(Insertable)]
#[table_name = "source"] #[table_name = "source"]
@@ -31,7 +50,7 @@ impl NewSource {
} }
pub(crate) fn insert_or_ignore(&self) -> Result<(), DataError> { pub(crate) fn insert_or_ignore(&self) -> Result<(), DataError> {
use schema::source::dsl::*; use crate::schema::source::dsl::*;
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
+21 -2
View File
@@ -1,5 +1,24 @@
use models::Source; // show.rs
use schema::shows; //
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::models::Source;
use crate::schema::shows;
#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)]
#[belongs_to(Source, foreign_key = "source_id")] #[belongs_to(Source, foreign_key = "source_id")]
+114 -64
View File
@@ -1,25 +1,48 @@
// source.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use diesel::SaveChangesDsl; use diesel::SaveChangesDsl;
// use failure::ResultExt; // use failure::ResultExt;
use rss::Channel; use rss::Channel;
use url::Url; use url::Url;
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
use hyper::header::{ use hyper::{Body, Client};
ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified, Location, UserAgent,
};
use hyper::{Client, Method, Request, Response, StatusCode, Uri};
use hyper_tls::HttpsConnector; use hyper_tls::HttpsConnector;
use http::header::{
HeaderValue, AUTHORIZATION, ETAG, IF_MODIFIED_SINCE, IF_NONE_MATCH, LAST_MODIFIED, LOCATION,
USER_AGENT as USER_AGENT_HEADER,
};
use http::{Request, Response, StatusCode, Uri};
// use futures::future::ok; // use futures::future::ok;
use futures::future::{loop_fn, Future, Loop}; use futures::future::{loop_fn, Future, Loop};
use futures::prelude::*; use futures::prelude::*;
use database::connection; use base64::{encode_config, URL_SAFE};
use errors::*;
use feed::{Feed, FeedBuilder}; use crate::database::connection;
use models::{NewSource, Save}; use crate::errors::*;
use schema::source; use crate::feed::{Feed, FeedBuilder};
use USER_AGENT; use crate::models::{NewSource, Save};
use crate::schema::source;
use crate::USER_AGENT;
use std::str::FromStr; use std::str::FromStr;
@@ -44,7 +67,7 @@ impl Save<Source> for Source {
let db = connection(); let db = connection();
let con = db.get()?; let con = db.get()?;
self.save_changes::<Source>(&con).map_err(From::from) self.save_changes::<Source>(&*con).map_err(From::from)
} }
} }
@@ -91,11 +114,17 @@ impl Source {
/// Extract Etag and LastModifier from res, and update self and the /// Extract Etag and LastModifier from res, and update self and the
/// corresponding db row. /// corresponding db row.
fn update_etag(mut self, res: &Response) -> Result<Self, DataError> { fn update_etag(mut self, res: &Response<Body>) -> Result<Self, DataError> {
let headers = res.headers(); let headers = res.headers();
let etag = headers.get::<ETag>().map(|x| x.tag()); let etag = headers
let lmod = headers.get::<LastModified>().map(|x| format!("{}", x)); .get(ETAG)
.and_then(|h| h.to_str().ok())
.map(From::from);
let lmod = headers
.get(LAST_MODIFIED)
.and_then(|h| h.to_str().ok())
.map(From::from);
if (self.http_etag() != etag) || (self.last_modified != lmod) { if (self.http_etag() != etag) || (self.last_modified != lmod) {
self.set_http_etag(etag); self.set_http_etag(etag);
@@ -107,17 +136,12 @@ impl Source {
} }
/// Clear the `HTTP` `Etag` and `Last-modified` headers. /// Clear the `HTTP` `Etag` and `Last-modified` headers.
fn clear_etags(mut self) -> Result<Self, DataError> { /// This method does not sync the state of self in the database, call
if self.http_etag().is_some() || self.last_modified().is_some() { /// .save() method explicitly
fn clear_etags(&mut self) {
debug!("Source etags before clear: {:#?}", &self); debug!("Source etags before clear: {:#?}", &self);
self.http_etag = None; self.http_etag = None;
self.last_modified = None; self.last_modified = None;
self = self.save()?;
debug!("Source etags after clear: {:#?}", &self);
info!("Etag fields cleared succesfully for Source: {}", self.uri);
}
Ok(self)
} }
fn make_err(self, context: &str, code: StatusCode) -> DataError { fn make_err(self, context: &str, code: StatusCode) -> DataError {
@@ -134,48 +158,62 @@ impl Source {
// 408: Timeout // 408: Timeout
// 410: Feed deleted // 410: Feed deleted
// TODO: Rething this api, // TODO: Rething this api,
fn match_status(mut self, res: Response) -> Result<Response, DataError> { fn match_status(mut self, res: Response<Body>) -> Result<Response<Body>, DataError> {
let code = res.status(); let code = res.status();
match code {
if code.is_success() {
// If request is succesful save the etag // If request is succesful save the etag
StatusCode::NotModified | StatusCode::Ok => self = self.update_etag(&res)?, self = self.update_etag(&res)?
} else {
match code.as_u16() {
// Save etags if it returns NotModified
304 => self = self.update_etag(&res)?,
// Clear the Etag/lmod else // Clear the Etag/lmod else
_ => self = self.clear_etags()?, _ => {
self.clear_etags();
self = self.save()?;
}
};
}; };
match code { match code.as_u16() {
StatusCode::NotModified => return Err(self.make_err("304: skipping..", code)), 304 => {
StatusCode::MovedPermanently | StatusCode::Found | StatusCode::PermanentRedirect => { info!("304: Source, (id: {}), is up to date", self.id());
error!("Feed was moved permanently."); return Err(DataError::FeedNotModified(self));
}
301 | 302 | 308 => {
warn!("Feed was moved permanently.");
self = self.update_url(&res)?; self = self.update_url(&res)?;
return Err(DataError::F301(self)); return Err(DataError::FeedRedirect(self));
} }
StatusCode::TemporaryRedirect => { 307 => {
debug!("307: Temporary Redirect."); warn!("307: Temporary Redirect.");
return Err(DataError::F301(self)); // FIXME: How is it actually handling the redirect?
return Err(DataError::FeedRedirect(self));
} }
StatusCode::Unauthorized => return Err(self.make_err("401: Unauthorized.", code)), 401 => return Err(self.make_err("401: Unauthorized.", code)),
StatusCode::Forbidden => return Err(self.make_err("403: Forbidden.", code)), 403 => return Err(self.make_err("403: Forbidden.", code)),
StatusCode::NotFound => return Err(self.make_err("404: Not found.", code)), 404 => return Err(self.make_err("404: Not found.", code)),
StatusCode::RequestTimeout => return Err(self.make_err("408: Request Timeout.", code)), 408 => return Err(self.make_err("408: Request Timeout.", code)),
StatusCode::Gone => return Err(self.make_err("410: Feed was deleted..", code)), 410 => return Err(self.make_err("410: Feed was deleted..", code)),
_ => info!("HTTP StatusCode: {}", code), _ => info!("HTTP StatusCode: {}", code),
}; };
Ok(res) Ok(res)
} }
fn update_url(mut self, res: &Response) -> Result<Self, DataError> { fn update_url(mut self, res: &Response<Body>) -> Result<Self, DataError> {
let code = res.status(); let code = res.status();
let headers = res.headers(); let headers = res.headers();
info!("HTTP StatusCode: {}", code); info!("HTTP StatusCode: {}", code);
debug!("Headers {:#?}", headers); debug!("Headers {:#?}", headers);
if let Some(url) = headers.get::<Location>() { if let Some(url) = headers.get(LOCATION) {
debug!("Previous Source: {:#?}", &self); debug!("Previous Source: {:#?}", &self);
self.set_uri(url.to_string()); self.set_uri(url.to_str()?.into());
self = self.clear_etags()?; self.clear_etags();
self = self.save()?;
debug!("Updated Source: {:#?}", &self); debug!("Updated Source: {:#?}", &self);
info!("Feed url of Source {}, was updated succesfully.", self.id()); info!("Feed url of Source {}, was updated succesfully.", self.id());
@@ -212,7 +250,7 @@ impl Source {
.then(|res| match res { .then(|res| match res {
Ok(response) => Ok(Loop::Break(response)), Ok(response) => Ok(Loop::Break(response)),
Err(err) => match err { Err(err) => match err {
DataError::F301(s) => { DataError::FeedRedirect(s) => {
info!("Following redirect..."); info!("Following redirect...");
Ok(Loop::Continue(s)) Ok(Loop::Continue(s))
} }
@@ -235,23 +273,35 @@ impl Source {
fn request_constructor( fn request_constructor(
self, self,
client: &Client<HttpsConnector<HttpConnector>>, client: &Client<HttpsConnector<HttpConnector>>,
) -> impl Future<Item = Response, Error = DataError> { ) -> impl Future<Item = Response<Body>, Error = DataError> {
// FIXME: remove unwrap somehow // FIXME: remove unwrap somehow
let uri = Uri::from_str(self.uri()).unwrap(); let uri = Uri::from_str(self.uri()).unwrap();
let mut req = Request::new(Method::Get, uri); let mut req = Request::get(uri).body(Body::empty()).unwrap();
if let Ok(url) = Url::parse(self.uri()) {
if let Some(password) = url.password() {
let mut auth = "Basic ".to_owned();
auth.push_str(&encode_config(
&format!("{}:{}", url.username(), password),
URL_SAFE,
));
req.headers_mut()
.insert(AUTHORIZATION, HeaderValue::from_str(&auth).unwrap());
}
}
// Set the UserAgent cause ppl still seem to check it for some reason... // Set the UserAgent cause ppl still seem to check it for some reason...
req.headers_mut().set(UserAgent::new(USER_AGENT)); req.headers_mut()
.insert(USER_AGENT_HEADER, HeaderValue::from_static(USER_AGENT));
if let Some(etag) = self.http_etag() { if let Some(etag) = self.http_etag() {
let tag = vec![EntityTag::new(true, etag.to_owned())]; req.headers_mut()
req.headers_mut().set(IfNoneMatch::Items(tag)); .insert(IF_NONE_MATCH, HeaderValue::from_str(etag).unwrap());
} }
if let Some(lmod) = self.last_modified() { if let Some(lmod) = self.last_modified() {
if let Ok(date) = lmod.parse::<HttpDate>() { req.headers_mut()
req.headers_mut().set(IfModifiedSince(date)); .insert(IF_MODIFIED_SINCE, HeaderValue::from_str(lmod).unwrap());
}
} }
client client
@@ -261,9 +311,10 @@ impl Source {
} }
} }
#[allow(needless_pass_by_value)] fn response_to_channel(
fn response_to_channel(res: Response) -> impl Future<Item = Channel, Error = DataError> + Send { res: Response<Body>,
res.body() ) -> impl Future<Item = Channel, Error = DataError> + Send {
res.into_body()
.concat2() .concat2()
.map(|x| x.into_iter()) .map(|x| x.into_iter())
.map_err(From::from) .map_err(From::from)
@@ -276,27 +327,26 @@ fn response_to_channel(res: Response) -> impl Future<Item = Channel, Error = Dat
mod tests { mod tests {
use super::*; use super::*;
use failure::Error; use failure::Error;
use tokio_core::reactor::Core; use num_cpus;
use tokio;
use database::truncate_db; use crate::database::truncate_db;
use utils::get_feed; use crate::utils::get_feed;
#[test] #[test]
fn test_into_feed() -> Result<(), Error> { fn test_into_feed() -> Result<(), Error> {
truncate_db()?; truncate_db()?;
let mut core = Core::new()?; let mut rt = tokio::runtime::Runtime::new()?;
let client = Client::configure() let https = HttpsConnector::new(num_cpus::get())?;
.connector(HttpsConnector::new(4, &core.handle())?) let client = Client::builder().build::<_, Body>(https);
.build(&core.handle());
let url = "https://web.archive.org/web/20180120083840if_/https://feeds.feedburner.\ let url = "https://web.archive.org/web/20180120083840if_/https://feeds.feedburner.\
com/InterceptedWithJeremyScahill"; com/InterceptedWithJeremyScahill";
let source = Source::from_url(url)?; let source = Source::from_url(url)?;
let id = source.id(); let id = source.id();
let feed = source.into_feed(client); let feed = source.into_feed(client);
let feed = core.run(feed)?; let feed = rt.block_on(feed)?;
let expected = get_feed("tests/feeds/2018-01-20-Intercepted.xml", id); let expected = get_feed("tests/feeds/2018-01-20-Intercepted.xml", id);
assert_eq!(expected, feed); assert_eq!(expected, feed);
+197 -9
View File
@@ -1,19 +1,45 @@
// opml.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//! FIXME: Docs //! FIXME: Docs
// #![allow(unused)] // #![allow(unused)]
use errors::DataError; use crate::dbqueries;
use models::Source; use crate::errors::DataError;
use xml::reader; use crate::models::Source;
use xml::{
common::XmlVersion,
reader,
writer::{events::XmlEvent, EmitterConfig},
};
use std::collections::HashSet; use std::collections::HashSet;
use std::fs; use std::fs;
use std::io::Read; use std::io::{Read, Write};
use std::path::Path; use std::path::Path;
// use std::fs::{File, OpenOptions}; use std::fs::File;
// use std::io::BufReader; // use std::io::BufReader;
use failure::Error;
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
// FIXME: Make it a Diesel model // FIXME: Make it a Diesel model
/// Represents an `outline` xml element as per the `OPML` [specification][spec] /// Represents an `outline` xml element as per the `OPML` [specification][spec]
@@ -42,7 +68,8 @@ pub fn import_to_db<R: Read>(reader: R) -> Result<Vec<Source>, reader::Error> {
} }
s.ok() s.ok()
}).collect(); })
.collect();
Ok(feeds) Ok(feeds)
} }
@@ -55,6 +82,87 @@ pub fn import_from_file<P: AsRef<Path>>(path: P) -> Result<Vec<Source>, DataErro
import_to_db(content.as_slice()).map_err(From::from) import_to_db(content.as_slice()).map_err(From::from)
} }
/// Export a file to `P`, taking the feeds from the database and outputing
/// them in opml format.
pub fn export_from_db<P: AsRef<Path>>(path: P, export_title: &str) -> Result<(), Error> {
let file = File::create(path)?;
export_to_file(&file, export_title)
}
/// Export from `Source`s and `Show`s into `F` in OPML format
pub fn export_to_file<F: Write>(file: F, export_title: &str) -> Result<(), Error> {
let config = EmitterConfig::new().perform_indent(true);
let mut writer = config.create_writer(file);
let mut events: Vec<XmlEvent<'_>> = Vec::new();
// Set up headers
let doc = XmlEvent::StartDocument {
version: XmlVersion::Version10,
encoding: Some("UTF-8"),
standalone: Some(false),
};
events.push(doc);
let opml: XmlEvent<'_> = XmlEvent::start_element("opml")
.attr("version", "2.0")
.into();
events.push(opml);
let head: XmlEvent<'_> = XmlEvent::start_element("head").into();
events.push(head);
let title_ev: XmlEvent<'_> = XmlEvent::start_element("title").into();
events.push(title_ev);
let title_chars: XmlEvent<'_> = XmlEvent::characters(export_title).into();
events.push(title_chars);
// Close <title> & <head>
events.push(XmlEvent::end_element().into());
events.push(XmlEvent::end_element().into());
let body: XmlEvent<'_> = XmlEvent::start_element("body").into();
events.push(body);
for event in events {
writer.write(event)?;
}
// FIXME: Make this a model of a joined query (http://docs.diesel.rs/diesel/macro.joinable.html)
let shows = dbqueries::get_podcasts()?.into_iter().map(|show| {
let source = dbqueries::get_source_from_id(show.source_id()).unwrap();
(source, show)
});
for (ref source, ref show) in shows {
let title = show.title();
let link = show.link();
let xml_url = source.uri();
let s_ev: XmlEvent<'_> = XmlEvent::start_element("outline")
.attr("text", title)
.attr("title", title)
.attr("type", "rss")
.attr("xmlUrl", xml_url)
.attr("htmlUrl", link)
.into();
let end_ev: XmlEvent<'_> = XmlEvent::end_element().into();
writer.write(s_ev)?;
writer.write(end_ev)?;
}
// Close <body> and <opml>
let end_bod: XmlEvent<'_> = XmlEvent::end_element().into();
writer.write(end_bod)?;
let end_opml: XmlEvent<'_> = XmlEvent::end_element().into();
writer.write(end_opml)?;
Ok(())
}
/// Extracts the `outline` elemnts from a reader `R` and returns a `HashSet` of `Opml` structs. /// Extracts the `outline` elemnts from a reader `R` and returns a `HashSet` of `Opml` structs.
pub fn extract_sources<R: Read>(reader: R) -> Result<HashSet<Opml>, reader::Error> { pub fn extract_sources<R: Read>(reader: R) -> Result<HashSet<Opml>, reader::Error> {
let mut list = HashSet::new(); let mut list = HashSet::new();
@@ -91,7 +199,8 @@ pub fn extract_sources<R: Read>(reader: R) -> Result<HashSet<Opml>, reader::Erro
} }
Err(err) => Err(err), Err(err) => Err(err),
_ => Ok(()), _ => Ok(()),
}).collect::<Result<Vec<_>, reader::Error>>()?; })
.collect::<Result<Vec<_>, reader::Error>>()?;
Ok(list) Ok(list)
} }
@@ -101,13 +210,49 @@ mod tests {
use super::*; use super::*;
use chrono::Local; use chrono::Local;
use failure::Error; use failure::Error;
use futures::Future;
use crate::database::{truncate_db, TEMPDIR};
use crate::utils::get_feed;
const URLS: &[(&str, &str)] = {
&[
(
"tests/feeds/2018-01-20-Intercepted.xml",
"https://web.archive.org/web/20180120083840if_/https://feeds.feedburner.\
com/InterceptedWithJeremyScahill",
),
(
"tests/feeds/2018-01-20-LinuxUnplugged.xml",
"https://web.archive.org/web/20180120110314if_/https://feeds.feedburner.\
com/linuxunplugged",
),
(
"tests/feeds/2018-01-20-TheTipOff.xml",
"https://web.archive.org/web/20180120110727if_/https://rss.acast.com/thetipoff",
),
(
"tests/feeds/2018-01-20-StealTheStars.xml",
"https://web.archive.org/web/20180120104957if_/https://rss.art19.\
com/steal-the-stars",
),
(
"tests/feeds/2018-01-20-GreaterThanCode.xml",
"https://web.archive.org/web/20180120104741if_/https://www.greaterthancode.\
com/feed/podcast",
),
(
"tests/feeds/2019-01-27-ACC.xml",
"https://web.archive.org/web/20190127005213if_/https://anticapitalistchronicles.libsyn.com/rss"
),
]
};
#[test] #[test]
fn test_extract() -> Result<(), Error> { fn test_extract() -> Result<(), Error> {
let int_title = String::from("Intercepted with Jeremy Scahill"); let int_title = String::from("Intercepted with Jeremy Scahill");
let int_url = String::from("https://feeds.feedburner.com/InterceptedWithJeremyScahill"); let int_url = String::from("https://feeds.feedburner.com/InterceptedWithJeremyScahill");
let int_desc = let int_desc = String::from(
String::from(
"The people behind The Intercept’s fearless reporting and incisive \ "The people behind The Intercept’s fearless reporting and incisive \
commentary—Jeremy Scahill, Glenn Greenwald, Betsy Reed and others—discuss the \ commentary—Jeremy Scahill, Glenn Greenwald, Betsy Reed and others—discuss the \
crucial issues of our time: national security, civil liberties, foreign policy, \ crucial issues of our time: national security, civil liberties, foreign policy, \
@@ -164,4 +309,47 @@ mod tests {
assert_eq!(extract_sources(sample1.as_bytes())?, map); assert_eq!(extract_sources(sample1.as_bytes())?, map);
Ok(()) Ok(())
} }
#[test]
fn text_export() -> Result<(), Error> {
truncate_db()?;
URLS.iter().for_each(|&(path, url)| {
// Create and insert a Source into db
let s = Source::from_url(url).unwrap();
let feed = get_feed(path, s.id());
feed.index().wait().unwrap();
});
let mut map: HashSet<Opml> = HashSet::new();
let shows = dbqueries::get_podcasts()?.into_iter().map(|show| {
let source = dbqueries::get_source_from_id(show.source_id()).unwrap();
(source, show)
});
for (ref source, ref show) in shows {
let title = show.title().to_string();
// description is an optional field that we don't export
let description = String::new();
let url = source.uri().to_string();
map.insert(Opml {
title,
description,
url,
});
}
let opml_path = TEMPDIR.path().join("podcasts.opml");
export_from_db(opml_path.as_path(), "GNOME Podcasts Subscriptions")?;
let opml_file = File::open(opml_path.as_path())?;
assert_eq!(extract_sources(&opml_file)?, map);
// extract_sources drains the reader its passed
let mut opml_file = File::open(opml_path.as_path())?;
let mut opml_str = String::new();
opml_file.read_to_string(&mut opml_str)?;
assert_eq!(opml_str, include_str!("../tests/export_test.opml"));
Ok(())
}
} }
+19 -1
View File
@@ -1,3 +1,22 @@
// parser.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use rss::extension::itunes::ITunesItemExtension; use rss::extension::itunes::ITunesItemExtension;
/// Parses an Item Itunes extension and returns it's duration value in seconds. /// Parses an Item Itunes extension and returns it's duration value in seconds.
@@ -77,5 +96,4 @@ mod tests {
let item = Some(&extension); let item = Some(&extension);
assert_eq!(parse_itunes_duration(item), Some(6970)); assert_eq!(parse_itunes_duration(item), Some(6970));
} }
} }
+56 -52
View File
@@ -1,42 +1,38 @@
// pipeline.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
// FIXME: // FIXME:
//! Docs. //! Docs.
use futures::future::*; use futures::{future::ok, lazy, prelude::*, stream::FuturesUnordered};
use futures::prelude::*; use tokio;
use futures::stream::*;
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
use hyper::Client; use hyper::{Body, Client};
use hyper_tls::HttpsConnector; use hyper_tls::HttpsConnector;
use tokio_core::reactor::Core;
use num_cpus; use num_cpus;
use rayon;
use rayon_futures::ScopeFutureExt;
use errors::DataError; use crate::errors::DataError;
use Source; use crate::Source;
// use std::sync::{Arc, Mutex}; use std::iter::FromIterator;
// http://gtk-rs.org/tuto/closures
#[macro_export]
macro_rules! clone {
(@param _) => ( _ );
(@param $x:ident) => ( $x );
($($n:ident),+ => move || $body:expr) => (
{
$( let $n = $n.clone(); )+
move || $body
}
);
($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
{
$( let $n = $n.clone(); )+
move |$(clone!(@param $p),)+| $body
}
);
}
type HttpsClient = Client<HttpsConnector<HttpConnector>>; type HttpsClient = Client<HttpsConnector<HttpConnector>>;
@@ -46,21 +42,29 @@ type HttpsClient = Client<HttpsConnector<HttpConnector>>;
/// Messy temp diagram: /// Messy temp diagram:
/// Source -> GET Request -> Update Etags -> Check Status -> Parse `xml/Rss` -> /// Source -> GET Request -> Update Etags -> Check Status -> Parse `xml/Rss` ->
/// Convert `rss::Channel` into `Feed` -> Index Podcast -> Index Episodes. /// Convert `rss::Channel` into `Feed` -> Index Podcast -> Index Episodes.
pub fn pipeline<'a, S>( pub fn pipeline<'a, S>(sources: S, client: HttpsClient) -> impl Future<Item = (), Error = ()> + 'a
sources: S,
client: &HttpsClient,
) -> impl Future<Item = Vec<()>, Error = DataError> + 'a
where where
S: Stream<Item = Source, Error = DataError> + 'a, S: Stream<Item = Source, Error = DataError> + Send + 'a,
{ {
sources sources
.and_then(clone!(client => move |s| s.into_feed(client.clone()))) .and_then(move |s| s.into_feed(client.clone()))
.and_then(|feed| rayon::scope(|s| s.spawn_future(feed.index()))) .map_err(|err| {
// the stream will stop at the first error so match err {
// we ensure that everything will succeded regardless. // Avoid spamming the stderr when its not an eactual error
.map_err(|err| error!("Error: {}", err)) DataError::FeedNotModified(_) => (),
.then(|_| ok::<(), DataError>(())) _ => error!("Error: {}", err),
.collect() }
})
.and_then(move |feed| {
let fut = lazy(|| feed.index().map_err(|err| error!("Error: {}", err)));
tokio::spawn(fut);
Ok(())
})
// For each terminates the stream at the first error so we make sure
// we pass good values regardless
.then(move |_| ok(()))
// Convert the stream into a Future to later execute as a tokio task
.for_each(move |_| ok(()))
} }
/// Creates a tokio `reactor::Core`, and a `hyper::Client` and /// Creates a tokio `reactor::Core`, and a `hyper::Client` and
@@ -69,24 +73,24 @@ pub fn run<S>(sources: S) -> Result<(), DataError>
where where
S: IntoIterator<Item = Source>, S: IntoIterator<Item = Source>,
{ {
let mut core = Core::new()?; let https = HttpsConnector::new(num_cpus::get())?;
let handle = core.handle(); let client = Client::builder().build::<_, Body>(https);
let client = Client::configure()
.connector(HttpsConnector::new(num_cpus::get(), &handle)?)
.build(&handle);
let stream = iter_ok::<_, DataError>(sources); let foo = sources.into_iter().map(ok::<_, _>);
let p = pipeline(stream, &client); let stream = FuturesUnordered::from_iter(foo);
core.run(p).map(|_| ()) let p = pipeline(stream, client);
tokio::run(p);
Ok(())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use database::truncate_db; use crate::database::truncate_db;
use dbqueries; use crate::dbqueries;
use crate::Source;
use failure::Error; use failure::Error;
use Source;
// (path, url) tuples. // (path, url) tuples.
const URLS: &[&str] = &[ const URLS: &[&str] = &[
+33 -15
View File
@@ -1,3 +1,22 @@
// utils.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//! Helper utilities for accomplishing various tasks. //! Helper utilities for accomplishing various tasks.
use chrono::prelude::*; use chrono::prelude::*;
@@ -5,10 +24,10 @@ use rayon::prelude::*;
use url::{Position, Url}; use url::{Position, Url};
use dbqueries; use crate::dbqueries;
use errors::DataError; use crate::errors::DataError;
use models::{EpisodeCleanerModel, Save, Show}; use crate::models::{EpisodeCleanerModel, Save, Show};
use xdg_dirs::DL_DIR; use crate::xdg_dirs::DL_DIR;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
@@ -25,7 +44,8 @@ fn download_checker() -> Result<(), DataError> {
return Some(ep); return Some(ep);
} }
None None
}).for_each(|ep| { })
.for_each(|ep| {
ep.set_local_uri(None); ep.set_local_uri(None);
ep.save() ep.save()
.map_err(|err| error!("{}", err)) .map_err(|err| error!("{}", err))
@@ -102,7 +122,7 @@ pub fn url_cleaner(s: &str) -> String {
// https://rust-lang-nursery.github.io/rust-cookbook/net.html // https://rust-lang-nursery.github.io/rust-cookbook/net.html
// #remove-fragment-identifiers-and-query-pairs-from-a-url // #remove-fragment-identifiers-and-query-pairs-from-a-url
match Url::parse(s) { match Url::parse(s) {
Ok(parsed) => parsed[..Position::AfterPath].to_owned(), Ok(parsed) => parsed[..Position::AfterQuery].to_owned(),
_ => s.trim().to_owned(), _ => s.trim().to_owned(),
} }
} }
@@ -133,13 +153,13 @@ pub fn delete_show(pd: &Show) -> Result<(), DataError> {
} }
#[cfg(test)] #[cfg(test)]
use Feed; use crate::Feed;
#[cfg(test)] #[cfg(test)]
/// Helper function that open a local file, parse the rss::Channel and gives back a Feed object. /// Helper function that open a local file, parse the rss::Channel and gives back a Feed object.
/// Alternative Feed constructor to be used for tests. /// Alternative Feed constructor to be used for tests.
pub fn get_feed(file_path: &str, id: i32) -> Feed { pub fn get_feed(file_path: &str, id: i32) -> Feed {
use feed::FeedBuilder; use crate::feed::FeedBuilder;
use rss::Channel; use rss::Channel;
use std::fs; use std::fs;
use std::io::BufReader; use std::io::BufReader;
@@ -157,15 +177,13 @@ pub fn get_feed(file_path: &str, id: i32) -> Feed {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
extern crate tempdir;
use self::tempdir::TempDir;
use super::*; use super::*;
use chrono::Duration; use chrono::Duration;
use failure::Error; use failure::Error;
use tempdir::TempDir;
use database::truncate_db; use crate::database::truncate_db;
use models::NewEpisodeBuilder; use crate::models::NewEpisodeBuilder;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@@ -272,8 +290,8 @@ mod tests {
#[test] #[test]
fn test_url_cleaner() -> Result<(), Error> { fn test_url_cleaner() -> Result<(), Error> {
let good_url = "http://traffic.megaphone.fm/FL8608731318.mp3"; let good_url = "http://traffic.megaphone.fm/FL8608731318.mp3?updated=1484685184";
let bad_url = "http://traffic.megaphone.fm/FL8608731318.mp3?updated=1484685184"; let bad_url = "http://traffic.megaphone.fm/FL8608731318.mp3?updated=1484685184#foobar";
assert_eq!(url_cleaner(bad_url), good_url); assert_eq!(url_cleaner(bad_url), good_url);
assert_eq!(url_cleaner(good_url), good_url); assert_eq!(url_cleaner(good_url), good_url);
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<opml version="2.0">
<head>
<title>GNOME Podcasts Subscriptions</title>
</head>
<body>
<outline text="David Harvey&apos;s Anti-Capitalist Chronicles" title="David Harvey&apos;s Anti-Capitalist Chronicles" type="rss" xmlUrl="https://web.archive.org/web/20190127005213if_/https://anticapitalistchronicles.libsyn.com/rss" htmlUrl="https://www.democracyatwork.info/acc" />
<outline text="Greater Than Code" title="Greater Than Code" type="rss" xmlUrl="https://web.archive.org/web/20180120104741if_/https://www.greaterthancode.com/feed/podcast" htmlUrl="https://www.greaterthancode.com/" />
<outline text="Intercepted with Jeremy Scahill" title="Intercepted with Jeremy Scahill" type="rss" xmlUrl="https://web.archive.org/web/20180120083840if_/https://feeds.feedburner.com/InterceptedWithJeremyScahill" htmlUrl="https://theintercept.com/podcasts" />
<outline text="LINUX Unplugged Podcast" title="LINUX Unplugged Podcast" type="rss" xmlUrl="https://web.archive.org/web/20180120110314if_/https://feeds.feedburner.com/linuxunplugged" htmlUrl="http://www.jupiterbroadcasting.com/" />
<outline text="Steal the Stars" title="Steal the Stars" type="rss" xmlUrl="https://web.archive.org/web/20180120104957if_/https://rss.art19.com/steal-the-stars" htmlUrl="http://tor-labs.com/" />
<outline text="The Tip Off" title="The Tip Off" type="rss" xmlUrl="https://web.archive.org/web/20180120110727if_/https://rss.acast.com/thetipoff" htmlUrl="http://www.acast.com/thetipoff" />
</body>
</opml>
@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cc="http://web.resource.org/cc/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<channel>
<atom:link href="https://anticapitalistchronicles.libsyn.com/rss" rel="self" type="application/rss+xml"/>
<title>David Harvey's Anti-Capitalist Chronicles</title>
<pubDate>Thu, 17 Jan 2019 05:00:00 +0000</pubDate>
<lastBuildDate>Thu, 17 Jan 2019 05:06:40 +0000</lastBuildDate>
<generator>Libsyn WebEngine 2.0</generator>
<link>https://www.democracyatwork.info/acc</link>
<language>en</language>
<copyright><![CDATA[Democracy at Work 2018]]></copyright>
<docs>https://www.democracyatwork.info/acc</docs>
<managingEditor>info@democracyatwork.info (info@democracyatwork.info)</managingEditor>
<itunes:summary><![CDATA[The Anti-Capitalist Chronicles look at capitalism through a Marxist lens. Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc]]></itunes:summary>
<image>
<url>https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png</url>
<title>David Harvey's Anti-Capitalist Chronicles</title>
<link><![CDATA[https://www.democracyatwork.info/acc]]></link>
</image>
<itunes:author>David Harvey</itunes:author>
<itunes:keywords>capitalism,economics,marxism,politics</itunes:keywords>
<itunes:category text="News &amp; Politics"/>
<itunes:category text="Education"></itunes:category>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png" />
<itunes:explicit>clean</itunes:explicit>
<itunes:owner>
<itunes:name><![CDATA[Democracy at Work]]></itunes:name>
<itunes:email>acc@democracyatwork.info</itunes:email>
</itunes:owner>
<description><![CDATA[The Anti-Capitalist Chronicles look at capitalism through a Marxist lens. Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc ]]></description>
<itunes:subtitle><![CDATA[]]></itunes:subtitle>
<itunes:type>episodic</itunes:type>
<item>
<title>The significance of China in the Global Economy</title>
<itunes:title>The significance of China in the Global Economy</itunes:title>
<pubDate>Thu, 17 Jan 2019 05:00:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[b64981bbe26247e19e66f1c9c14a332a]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/the-significance-of-china-in-the-global-economy]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png" />
<description><![CDATA[<p>The Chinese economy is now the 2nd largest in the world. Prof. Harvey argues that China's expansion saved capitalism after the 2008 crash.</p>]]></description>
<content:encoded><![CDATA[<p>The Chinese economy is now the 2nd largest in the world. Prof. Harvey argues that China's expansion saved capitalism after the 2008 crash.</p>]]></content:encoded>
<enclosure length="106240847" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/ACC_S1_E07.mp3?dest-id=796288" />
<itunes:duration>44:15</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[The Chinese economy is now the 2nd largest in the world. Prof. Harvey argues that China's expansion saved capitalism after the 2008 crash.]]></itunes:subtitle>
<itunes:summary>The Chinese economy is now the 2nd largest in the world. Prof. Harvey argues that China's expansion saved capitalism after the 2008 crash.</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>7</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>Does Socialism Affect Freedom?</title>
<itunes:title>Does Socialism Affect Freedom? </itunes:title>
<pubDate>Thu, 03 Jan 2019 05:00:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[3fe5b10d8f6045d7a65bc3de64f23277]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/does-socialism-affect-freedom]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png" />
<description><![CDATA[<p>Does socialism require the surrender of individual freedom? The realm of freedom begins when the realm of necessity is left behind. Is freedom of the market real freedom?  And what about justice?  Prof. Harvey tries to answer these questions and more.</p>]]></description>
<content:encoded><![CDATA[<p>Does socialism require the surrender of individual freedom? The realm of freedom begins when the realm of necessity is left behind. Is freedom of the market real freedom?  And what about justice?  Prof. Harvey tries to answer these questions and more.</p>]]></content:encoded>
<enclosure length="60112942" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep06_Does_socialism_affect_freedom.mp3?dest-id=796288" />
<itunes:duration>25:02</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[Does socialism require the surrender of individual freedom? The realm of freedom begins when the realm of necessity is left behind. Is freedom of the market real freedom?  And what about justice?  Prof. Harvey tries to answer these questions...]]></itunes:subtitle>
<itunes:summary>Does socialism require the surrender of individual freedom? The realm of freedom begins when the realm of necessity is left behind. Is freedom of the market real freedom?  And what about justice?  Prof. Harvey tries to answer these questions and more.</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>6</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>The Value of Everything</title>
<itunes:title>"The Value of Everything</itunes:title>
<pubDate>Thu, 13 Dec 2018 05:00:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[6ca8e36116924b4f8b1ebeb1b6c35bae]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/the-value-of-everything]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png" />
<description><![CDATA[<p>Prof. Harvey talks about Mariana Mazzucato's new book "The Value of Everything: Making and Taking in the Global Economy."</p>]]></description>
<content:encoded><![CDATA[<p>Prof. Harvey talks about Mariana Mazzucato's new book "The Value of Everything: Making and Taking in the Global Economy."</p>]]></content:encoded>
<enclosure length="60810663" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep05_2018.10_pt2.mp3?dest-id=796288" />
<itunes:duration>25:19</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[Prof. Harvey talks about Mariana Mazzucato's new book "The Value of Everything: Making and Taking in the Global Economy."]]></itunes:subtitle>
<itunes:summary>Prof. Harvey talks about Mariana Mazzucato's new book "The Value of Everything: Making and Taking in the Global Economy."</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>5</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>The Brazilian Elections</title>
<itunes:title>The Brazilian Elections</itunes:title>
<pubDate>Thu, 29 Nov 2018 05:00:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[f76a6e81de1c44db847b5424f7b338de]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/the-brazilian-elections]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/9/2/b/092b811513b710af/ACC_Logo_Final_LibsynSize.png" />
<description><![CDATA[<p>Prof. Harvey talks about the recent Brazilian elections and the growing alliance between Neo-liberalism and Right-Wing Populism.</p>]]></description>
<content:encoded><![CDATA[<p>Prof. Harvey talks about the recent Brazilian elections and the growing alliance between Neo-liberalism and Right-Wing Populism.</p>]]></content:encoded>
<enclosure length="72984484" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep04_2018.10_pt1.mp3?dest-id=796288" />
<itunes:duration>30:23</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[Prof. Harvey talks about the recent Brazilian elections and the growing alliance between Neo-liberalism and Right-Wing Populism.]]></itunes:subtitle>
<itunes:summary>Prof. Harvey talks about the recent Brazilian elections and the growing alliance between Neo-liberalism and Right-Wing Populism.</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>4</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>The Financialization of Power</title>
<itunes:title>The Financialization of Power</itunes:title>
<pubDate>Thu, 15 Nov 2018 13:10:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[e4641accc886461dbcbef94775532adc]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/the-financialization-of-power]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/a/4/d/7/a4d743af97f5ad8e/ACC_Logo_IconOnly_LibsynSize.png" />
<description><![CDATA[<p>Financial services become part of GDP in the 1970s and legitimize the power of financial institutions. </p>]]></description>
<content:encoded><![CDATA[<p>Financial services become part of GDP in the 1970s and legitimize the power of financial institutions. </p>]]></content:encoded>
<enclosure length="46686237" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep03_2018.09.mp3?dest-id=796288" />
<itunes:duration>19:27</itunes:duration>
<itunes:explicit>no</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[Financial services become part of GDP in the 1970s and legitimize the power of financial institutions. ]]></itunes:subtitle>
<itunes:summary>Financial services become part of GDP in the 1970s and legitimize the power of financial institutions. </itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>3</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>Contradictions of Neo-Liberalism</title>
<itunes:title>The Contradictions of Neo-Liberalism</itunes:title>
<pubDate>Thu, 15 Nov 2018 13:05:00 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[a4f0d0206b8d4572b8e54764a39c8a48]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/contradictions-of-neo-liberalism]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/9/b/e/d/9bed97160a2d6344/ACC_Logo_IconOnly_LibsynSize.png" />
<description><![CDATA[<p>The crash of 2008 challenges Neo-Liberalism.</p>]]></description>
<content:encoded><![CDATA[<p>The crash of 2008 challenges Neo-Liberalism.</p>]]></content:encoded>
<enclosure length="45500801" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep02_2018.09.mp3?dest-id=796288" />
<itunes:duration>18:58</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[The crash of 2008 challenges Neo-Liberalism.]]></itunes:subtitle>
<itunes:summary>The crash of 2008 challenge Neo-Liberalism.</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>2</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
<item>
<title>A brief history of Neo-Liberalism</title>
<itunes:title>A brief history of Neo-Liberalism</itunes:title>
<pubDate>Mon, 12 Nov 2018 22:01:39 +0000</pubDate>
<guid isPermaLink="false"><![CDATA[3daeb566cd964764a5847da4f2a6a309]]></guid>
<link><![CDATA[http://anticapitalistchronicles.libsyn.com/a-brief-history-of-neo-liberalism]]></link>
<itunes:image href="https://ssl-static.libsyn.com/p/assets/0/7/e/0/07e073ebe1b26e3f/ACC_Logo_IconOnly_LibsynSize.png" />
<description><![CDATA[<p>Prof. David Harvey's pilot episode. He provides a quick history of the rise and growth of Neo-Liberalism. </p> <p>Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc</p>]]></description>
<content:encoded><![CDATA[<p>Prof. David Harvey's pilot episode. He provides a quick history of the rise and growth of Neo-Liberalism. </p> <p>Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc</p>]]></content:encoded>
<enclosure length="47001933" type="audio/mpeg" url="https://traffic.libsyn.com/secure/anticapitalistchronicles/acc_ep01_2018.09.mp3?dest-id=796288" />
<itunes:duration>19:35</itunes:duration>
<itunes:explicit>clean</itunes:explicit>
<itunes:keywords />
<itunes:subtitle><![CDATA[Prof. David Harvey's pilot episode. He provides a quick history of the rise and growth of Neo-Liberalism.  Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc]]></itunes:subtitle>
<itunes:summary>Prof. David Harvey's pilot episode. He provides a quick history of the rise and growth of Neo-Liberalism.
Support the show on Patreon and get early access to episodes and more: https://www.patreon.com/davidharveyacc</itunes:summary>
<itunes:season>1</itunes:season>
<itunes:episode>1</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
<itunes:author>Democracy at Work</itunes:author>
</item>
</channel>
</rss>
+6
View File
@@ -43,3 +43,9 @@ Raw file: https://web.archive.org/web/20180120104741if_/https://www.greaterthanc
Web view: https://web.archive.org/web/20180328083913/https://ellinofreneia.sealabs.net/audio/podcast.rss Web view: https://web.archive.org/web/20180328083913/https://ellinofreneia.sealabs.net/audio/podcast.rss
Raw file: https://web.archive.org/web/20180328083913if_/https://ellinofreneia.sealabs.net/audio/podcast.rss Raw file: https://web.archive.org/web/20180328083913if_/https://ellinofreneia.sealabs.net/audio/podcast.rss
#### David Harvey's Anti-Capitalist Chronicles
Web view: https://web.archive.org/web/20190127005213/https://anticapitalistchronicles.libsyn.com/rss
Raw file: https://web.archive.org/web/20190127005213if_/https://anticapitalistchronicles.libsyn.com/rss
+10 -11
View File
@@ -1,22 +1,21 @@
[package] [package]
authors = ["Jordan Petridis <jordanpetridis@protonmail.com>"] authors = ["Jordan Petridis <jpetridis@gnome.org>"]
name = "podcasts-downloader" name = "podcasts-downloader"
version = "0.1.0" version = "0.1.0"
workspace = "../" edition = "2018"
[dependencies] [dependencies]
error-chain = "0.12.0" error-chain = "0.12.1"
hyper = "0.11.27" log = "0.4.8"
log = "0.4.4" mime_guess = "2.0.1"
mime_guess = "1.8.6" reqwest = "0.9.22"
reqwest = "0.8.8"
tempdir = "0.3.7" tempdir = "0.3.7"
glob = "0.2.11" glob = "0.3.0"
failure = "0.1.2" failure = "0.1.6"
failure_derive = "0.1.2" failure_derive = "0.1.6"
[dependencies.podcasts-data] [dependencies.podcasts-data]
path = "../podcasts-data" path = "../podcasts-data"
[dev-dependencies] [dev-dependencies]
pretty_assertions = "0.5.1" pretty_assertions = "0.6.1"
+51 -15
View File
@@ -1,7 +1,26 @@
// downloader.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use glob::glob; use glob::glob;
use hyper::header::*;
use mime_guess; use mime_guess;
use reqwest; use reqwest;
use reqwest::header::*;
use reqwest::RedirectPolicy; use reqwest::RedirectPolicy;
use tempdir::TempDir; use tempdir::TempDir;
@@ -15,16 +34,19 @@ use podcasts_data::xdg_dirs::PODCASTS_CACHE;
use podcasts_data::{EpisodeWidgetModel, Save, ShowCoverModel}; use podcasts_data::{EpisodeWidgetModel, Save, ShowCoverModel};
// use failure::Error; // use failure::Error;
use errors::DownloadError; use crate::errors::DownloadError;
// TODO: Replace path that are of type &str with std::path. // TODO: Replace path that are of type &str with std::path.
// TODO: Have a convention/document absolute/relative paths, if they should end // TODO: Have a convention/document absolute/relative paths, if they should end
// with / or not. // with / or not.
pub trait DownloadProgress { pub trait DownloadProgress {
fn get_downloaded(&self) -> u64;
fn set_downloaded(&mut self, downloaded: u64); fn set_downloaded(&mut self, downloaded: u64);
fn get_size(&self) -> u64;
fn set_size(&mut self, bytes: u64); fn set_size(&mut self, bytes: u64);
fn should_cancel(&self) -> bool; fn should_cancel(&self) -> bool;
fn cancel(&mut self);
} }
// Adapted from https://github.com/mattgathu/rget . // Adapted from https://github.com/mattgathu/rget .
@@ -63,16 +85,29 @@ fn download_into(
info!("Status Resp: {}", resp.status()); info!("Status Resp: {}", resp.status());
if !resp.status().is_success() { if !resp.status().is_success() {
if let Some(ref prog) = progress {
if let Ok(mut m) = prog.lock() {
m.cancel();
}
}
return Err(DownloadError::UnexpectedResponse(resp.status())); return Err(DownloadError::UnexpectedResponse(resp.status()));
} }
let headers = resp.headers().clone(); let headers = resp.headers().clone();
let ct_len = headers.get::<ContentLength>().map(|ct_len| **ct_len); let ct_len = headers
let ct_type = headers.get::<ContentType>(); .get(CONTENT_LENGTH)
.and_then(|h| h.to_str().ok())
.and_then(|len| len.parse().ok());
let ct_type = headers
.get(CONTENT_TYPE)
.and_then(|h| h.to_str().ok())
.map(From::from);
ct_len.map(|x| info!("File Lenght: {}", x)); ct_len.map(|x| info!("File Lenght: {}", x));
ct_type.map(|x| info!("Content Type: {}", x)); ct_type.map(|x| info!("Content Type: {}", x));
let ext = get_ext(ct_type.cloned()).unwrap_or_else(|| String::from("unknown")); let ext = get_ext(ct_type).unwrap_or_else(|| String::from("unknown"));
info!("Extension: {}", ext); info!("Extension: {}", ext);
// Construct a temp file to save desired content. // Construct a temp file to save desired content.
@@ -82,10 +117,11 @@ fn download_into(
let out_file = format!("{}/temp.part", tempdir.path().to_str().unwrap(),); let out_file = format!("{}/temp.part", tempdir.path().to_str().unwrap(),);
ct_len.map(|x| { ct_len.map(|x| {
if let Some(p) = progress.clone() { if let Some(ref p) = progress {
let mut m = p.lock().unwrap(); if let Ok(mut m) = p.lock() {
m.set_size(x); m.set_size(x);
} }
}
}); });
// Save requested content into the file. // Save requested content into the file.
@@ -100,15 +136,15 @@ fn download_into(
} }
/// Determine the file extension from the http content-type header. /// Determine the file extension from the http content-type header.
fn get_ext(content: Option<ContentType>) -> Option<String> { fn get_ext(content: Option<&str>) -> Option<String> {
let cont = content.clone()?; let mut iter = content?.split("/");
content let type_ = iter.next()?;
.and_then(|c| mime_guess::get_extensions(c.type_().as_ref(), c.subtype().as_ref())) let subtype = iter.next()?;
.and_then(|c| { mime_guess::get_extensions(type_, subtype).and_then(|c| {
if c.contains(&cont.subtype().as_ref()) { if c.contains(&&subtype) {
Some(cont.subtype().as_ref().to_string()) Some(subtype.to_string())
} else { } else {
Some(c.first().unwrap().to_string()) Some(c.first()?.to_string())
} }
}) })
} }
+38 -14
View File
@@ -1,3 +1,23 @@
// errors.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![allow(bare_trait_objects)] #![allow(bare_trait_objects)]
use podcasts_data::errors::DataError; use podcasts_data::errors::DataError;
@@ -24,20 +44,24 @@ pub enum DownloadError {
InvalidCachedImageLocation, InvalidCachedImageLocation,
} }
impl From<reqwest::Error> for DownloadError { // Maps a type to a variant of the DataError enum
fn from(err: reqwest::Error) -> Self { macro_rules! easy_from_impl {
DownloadError::RequestError(err) ($outer_type:ty, $from:ty => $to:expr) => (
impl From<$from> for $outer_type {
fn from(err: $from) -> Self {
$to(err)
} }
}
);
($outer_type:ty, $from:ty => $to:expr, $($f:ty => $t:expr),+) => (
easy_from_impl!($outer_type, $from => $to);
easy_from_impl!($outer_type, $($f => $t),+);
);
} }
impl From<io::Error> for DownloadError { easy_from_impl!(
fn from(err: io::Error) -> Self { DownloadError,
DownloadError::IoError(err) reqwest::Error => DownloadError::RequestError,
} io::Error => DownloadError::IoError,
} DataError => DownloadError::DataError
);
impl From<DataError> for DownloadError {
fn from(err: DataError) -> Self {
DownloadError::DataError(err)
}
}
+21 -22
View File
@@ -1,17 +1,27 @@
// lib.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![cfg_attr( #![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
feature = "cargo-clippy",
allow(blacklisted_name, option_map_unit_fn)
)]
// Enable lint group collections // Enable lint group collections
#![warn( #![warn(nonstandard_style, edition_2018, rust_2018_idioms, bad_style, unused)]
nonstandard_style,
edition_2018,
rust_2018_idioms,
bad_style,
unused
)]
// standalone lints // standalone lints
#![warn( #![warn(
const_err, const_err,
@@ -20,8 +30,6 @@
no_mangle_generic_items, no_mangle_generic_items,
overflowing_literals, overflowing_literals,
plugin_as_library, plugin_as_library,
private_no_mangle_fns,
private_no_mangle_statics,
unconditional_recursion, unconditional_recursion,
unions_with_drop_fields, unions_with_drop_fields,
while_true, while_true,
@@ -31,9 +39,7 @@
elided_lifetime_in_paths, elided_lifetime_in_paths,
missing_copy_implementations missing_copy_implementations
)] )]
#![deny(warnings)]
extern crate failure;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[macro_use] #[macro_use]
@@ -43,12 +49,5 @@ extern crate log;
#[macro_use] #[macro_use]
extern crate pretty_assertions; extern crate pretty_assertions;
extern crate glob;
extern crate hyper;
extern crate mime_guess;
extern crate podcasts_data;
extern crate reqwest;
extern crate tempdir;
pub mod downloader; pub mod downloader;
pub mod errors; pub mod errors;
+5
View File
@@ -0,0 +1,5 @@
downloader_sources = files(
'downloader.rs',
'errors.rs',
'lib.rs'
)
+44 -30
View File
@@ -1,45 +1,59 @@
[package] [package]
authors = ["Jordan Petridis <jordanpetridis@protonmail.com>"] authors = ["Jordan Petridis <jpetridis@gnome.com>"]
build = "build.rs"
name = "podcasts-gtk" name = "podcasts-gtk"
version = "0.1.0" version = "0.1.0"
workspace = "../" edition = "2018"
[dependencies] [dependencies]
chrono = "0.4.6" chrono = "0.4.9"
crossbeam-channel = "0.2.4" crossbeam-channel = "0.3.9"
gdk = "0.8.0" gdk = "0.11.0"
gdk-pixbuf = "0.4.0" gdk-pixbuf = "0.7.0"
glib = "0.5.0" gobject-sys = "0.9.0"
gstreamer = "0.11.6" glib-sys = "0.9.0"
gstreamer-player = "0.11.3" gst = { version = "0.14.0", package = "gstreamer" }
gst-player = { version = "0.14.0", package = "gstreamer-player" }
humansize = "1.1.0" humansize = "1.1.0"
lazy_static = "1.1.0" lazy_static = "1.4.0"
log = "0.4.4" log = "0.4.8"
loggerv = "0.7.1" loggerv = "0.7.2"
open = "1.2.2" open = "1.3.2"
rayon = "1.0.2" rayon = "1.2.0"
url = "1.7.1" url = "2.1.0"
failure = "0.1.2" failure = "0.1.6"
failure_derive = "0.1.2" failure_derive = "0.1.6"
fragile = "0.3.0" fragile = "0.3.0"
regex = "1.0.4" regex = "1.3.1"
reqwest = "0.8.8" reqwest = "0.9.22"
serde_json = "1.0.26" serde_json = "1.0.41"
# html2text = "0.1.8" # html2text = "0.1.8"
html2text = { git = "https://github.com/alatiera/rust-html2text" } html2text = { git = "https://github.com/jugglerchris/rust-html2text" }
gettext-rs = { git = "https://github.com/danigm/gettext-rs", branch = "no-gettext", features = ["gettext-system"] } mpris-player = "0.4.0"
[dependencies.gtk] [dependencies.gettext-rs]
features = ["v3_22"] git = "https://github.com/danigm/gettext-rs"
version = "0.4.1" branch = "no-gettext"
features = ["gettext-system"]
[dependencies.glib]
features = ["subclassing"]
version = "0.8.2"
[dependencies.gio] [dependencies.gio]
features = ["v2_50"] features = ["v2_50", "subclassing"]
version = "0.4.1" version = "0.7.0"
[dependencies.gtk]
features = ["v3_24", "subclassing"]
version = "0.7.0"
[dependencies.libhandy] [dependencies.libhandy]
git = "https://gitlab.gnome.org/jsparber/libhandy-rs" version = "0.4.0"
features = [ "v0_0_10"]
# [dependencies.mpris-player]
# version = "0.4.0"
# git = "https://gitlab.gnome.org/World/Rust/mpris-player"
[dependencies.podcasts-data] [dependencies.podcasts-data]
path = "../podcasts-data" path = "../podcasts-data"
@@ -48,4 +62,4 @@ path = "../podcasts-data"
path = "../podcasts-downloader" path = "../podcasts-downloader"
[dev-dependencies] [dev-dependencies]
pretty_assertions = "0.5.1" pretty_assertions = "0.6.1"
-14
View File
@@ -1,14 +0,0 @@
use std::process::Command;
fn main() {
// Rerun the build script when files in the resources folder are changed.
println!("cargo:rerun-if-changed=resources");
println!("cargo:rerun-if-changed=resources/*");
let out = Command::new("glib-compile-resources")
.args(&["--generate", "resources.xml"])
.current_dir("resources")
.status()
.expect("failed to generate resources");
assert!(out.success());
}
+15
View File
@@ -1,10 +1,25 @@
# please keep this list sorted alphabetically # please keep this list sorted alphabetically
# #
ca
cs
da
de de
en_GB
es es
eu
fi fi
fr
fur
gl gl
hr
hu
id id
it
ko ko
lv
nl
pl pl
pt_BR
sk
sv
tr tr
+1 -3
View File
@@ -14,7 +14,6 @@ podcasts-gtk/resources/gtk/home_episode.ui
podcasts-gtk/resources/gtk/home_view.ui podcasts-gtk/resources/gtk/home_view.ui
podcasts-gtk/resources/gtk/inapp_notif.ui podcasts-gtk/resources/gtk/inapp_notif.ui
podcasts-gtk/resources/gtk/player_toolbar.ui podcasts-gtk/resources/gtk/player_toolbar.ui
podcasts-gtk/resources/gtk/prefs.ui
podcasts-gtk/resources/gtk/secondary_menu.ui podcasts-gtk/resources/gtk/secondary_menu.ui
podcasts-gtk/resources/gtk/show_menu.ui podcasts-gtk/resources/gtk/show_menu.ui
podcasts-gtk/resources/gtk/show_widget.ui podcasts-gtk/resources/gtk/show_widget.ui
@@ -24,14 +23,13 @@ podcasts-gtk/src/app.rs
podcasts-gtk/src/headerbar.rs podcasts-gtk/src/headerbar.rs
podcasts-gtk/src/main.rs podcasts-gtk/src/main.rs
podcasts-gtk/src/manager.rs podcasts-gtk/src/manager.rs
podcasts-gtk/src/prefs.rs
podcasts-gtk/src/settings.rs podcasts-gtk/src/settings.rs
podcasts-gtk/src/stacks/content.rs podcasts-gtk/src/stacks/content.rs
podcasts-gtk/src/stacks/home.rs podcasts-gtk/src/stacks/home.rs
podcasts-gtk/src/stacks/mod.rs podcasts-gtk/src/stacks/mod.rs
podcasts-gtk/src/stacks/populated.rs podcasts-gtk/src/stacks/populated.rs
podcasts-gtk/src/stacks/show.rs podcasts-gtk/src/stacks/show.rs
podcasts-gtk/src/static_resource.rs podcasts-gtk/src/static_resource.rs.in
podcasts-gtk/src/utils.rs podcasts-gtk/src/utils.rs
podcasts-gtk/src/widgets/aboutdialog.rs podcasts-gtk/src/widgets/aboutdialog.rs
podcasts-gtk/src/widgets/appnotif.rs podcasts-gtk/src/widgets/appnotif.rs
+404
View File
@@ -0,0 +1,404 @@
# Catalan translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-09-23 15:55+0000\n"
"PO-Revision-Date: 2018-09-23 23:03-0500\n"
"Language-Team: Catalan <gnome@llistes.softcatala.org>\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Last-Translator: Adolfo Jayme Barrientos <fitojb@ubuntu.com>\n"
"X-Generator: Poedit 2.1.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Posició superior de l'última finestra principal oberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Posició esquerra de l'última finestra principal oberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Alçada de l'última finestra principal oberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Amplada de l'última finestra principal oberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Estat de maximització de l'ultima finestra principal oberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Habilita o inhabilita el tema fosc"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Si s'ha d'actualitzar periòdicament el contingut"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Quants períodes de temps esperar entre les actualitzacions automàtiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Quin període de temps esperar entre les actualitzacions automàtiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Si s'ha d'actualitzar el contingut després d'iniciar"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Quants períodes de temps esperar entre les neteges automàtiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Quin període de temps esperar entre les neteges automàtiques"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:91 podcasts-gtk/src/app.rs:414
#: podcasts-gtk/src/widgets/aboutdialog.rs:31
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Escolteu els vostres podcasts predilectes, sense sortir del vostre escriptori."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Aplicació de podcasts per al GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:51
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Aquest programa no té cap episodi encara"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Si sospiteu que això és un error, considereu crear un informe."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Cerqueu-vos alguns programes"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Afegeix programes nous mitjançant l'URL del canal"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importa programes des d'un altre dispositiu"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "S'està calculant la mida de l'episodi…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Reprodueix aquest episodi"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download proccess"
msgstr "Cancel·la el procés de baixada"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Baixa aquest episodi"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Comprova si hi ha episodis nous"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importa programes"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Preferències"
#: podcasts-gtk/resources/gtk/hamburger.ui:29
msgid "_Keyboard Shortcuts"
msgstr "_Dreceres de teclat"
#: podcasts-gtk/resources/gtk/hamburger.ui:37
msgid "_About"
msgstr "_Quant a"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Afegeix un canal nou"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Introduïu l'adreça del canal que s'ha d'afegir"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Afegeix"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Ja us heu subscrit a aquest canal."
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Títol del programa"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Enrere"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "General"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Comprova si hi ha episodis nous"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferències"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Surt de l'aplicació"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Avui"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Ahir"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Aquesta setmana"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Aquest mes"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Més antics"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Una notificació d'acció dins l'aplicació"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Desfés"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Rebobina 10 segons"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Reprodueix"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Posa en pausa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Avança 10 segons"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Canvia la velocitat de la reproducció"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "Velocitat d'1,5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "Velocitat d'1,25"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Velocitat normal"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferències"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Aparença"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tema fosc"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Suprimeix els episodis reproduïts"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Després"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Marca tots els episodis com a reproduïts"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Lloc web"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Cancel·la la subscripció"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Obre el lloc web"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Marca'ls tots com a reproduïts"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Cancel·la la subscripció"
#: podcasts-gtk/src/app.rs:332
msgid "Fetching new episodes"
msgstr "S'estan recuperant els episodis nous"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Ja us heu subscrit a aquest programa"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "L'URL no és vàlid"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "Segons"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minuts"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Hores"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Dies"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Setmanes"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Nous"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Programes"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Seleccioneu el fitxer des del qual voleu importar els programes."
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "_Importa"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "Fitxer OPML"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "No s'ha pogut analitzar el fitxer importat"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "No s'ha pogut accedir al fitxer seleccionat."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26
msgid "Podcast Client for the GNOME Desktop."
msgstr "Client de podcasts per a l'escriptori GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:33
msgid "Learn more about GNOME Podcasts"
msgstr "Més informació sobre el GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:38
msgid "translator-credits"
msgstr "Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2018"
#: podcasts-gtk/src/widgets/episode.rs:130
msgid "{} min"
msgstr "{} m"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301
msgid "The media player was unable to execute an action."
msgstr "El reproductor multimèdia ha sigut incapaç d'executar cap acció."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "S'han marcat tots els episodis com a escoltats"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Heu cancel·lat la subscripció a {}"
+405
View File
@@ -0,0 +1,405 @@
# Czech translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Marek Černocký <marek@manet.cz>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-10-05 11:47+0000\n"
"PO-Revision-Date: 2018-10-07 16:42+0200\n"
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
"Language-Team: čeština <gnome-cs-list@gnome.org>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Gtranslator 2.91.7\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Horní souřadnice naposledy otevřeného hlavního okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Levá souřadnice naposledy otevřeného hlavního okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Výška naposledy otevřeného hlavního okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Šířka naposledy otevřeného hlavního okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Stav maximalizace naposledy otevřeného hlavního okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Vypnutý nebo zapnutý tmavý motiv"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Zda pravidelně aktualizovat obsah"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Kolik časových jednotek čekat mezi automatickými aktualizacemi"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Jaká je časová jednotka pro čekání mezi automatickými aktualizacemi"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Zda aktualizovat obsah po spuštění"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Kolik časových jednotek čekat mezi automatickými vymazáními"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Jaká je časová jednotka pro čekání mezi automatickými vymazáními"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:416
#: podcasts-gtk/src/widgets/aboutdialog.rs:31
msgid "Podcasts"
msgstr "Podcasty"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Poslouchejte své oblíbené podcasty přímo z počítače"
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "podcast;RSS;pořad;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcastová aplikace pro GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:51
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Pořad zatím nemá žádné epizody"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Pokud si myslíte, že se jedná o chybu, zvažte její nahlášení."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Doplňte si pořady"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Přidat nové pořady pomocí URL kanálu"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Naimportovat pořady z jiného zařízení"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Počítá se velikost epizody…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Přehrát tuto epizodu"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Zrušit probíhající stahování"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Stáhnout tuto epizodu"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "Vy_hledat nové epizody"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "Na_importovat pořady"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Předvolby"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Klávesové zkratky"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "O _aplikaci Podcasty"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Přidat nový kanál"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Zadejte adresu kanálu, který chcete přidat"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Přidat"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Z tohoto kanálu již odebíráte!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Název pořadu"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Zpět"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Obecné"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Vyhledat nové epizody"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Předvolby"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Ukončit aplikaci"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Dnes"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Včera"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Tento týden"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Tento měsíc"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Starší"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Oznámení o činnosti v aplikaci"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Zpět"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Převinout zpět o 10 sekund"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Přehrát"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pozastavit"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Posunou rychle vpřed o 10 sekund"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Změnit rychlost přehrávání"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 násobek rychlosti"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 násobek rychlosti"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normální rychlost"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Předvolby"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Vzhled"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tmavý motiv"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Smazat přehrané epizody"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Po uplynutí"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "Oz_načit všechny epizody jako přehrané"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Webové stránky"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "O_dhlásit odběr"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Otevřít webové stránky"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Označit vše jako přehrané"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Odhlásit odběr"
#: podcasts-gtk/src/app.rs:333
msgid "Fetching new episodes"
msgstr "Stahují se nové epizody"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Již jste přihlášeni k odběru tohoto pořadu"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "Neplatná adresa URL"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "sekund"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "minut"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "hodin"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "dnů"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "týdnů"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Nový"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Pořady"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Výběr soubor pro import pořadu"
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "Na_importovat"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "Soubor OPML"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "Selhalo zpracování naimportovaného souboru"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "K vybranému souboru není přístup"
#: podcasts-gtk/src/widgets/aboutdialog.rs:26
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcastový klient pro uživatelské prostředí GNOME"
#: podcasts-gtk/src/widgets/aboutdialog.rs:33
msgid "Learn more about GNOME Podcasts"
msgstr "Dozvědět se více o Podcastech GNOME"
#: podcasts-gtk/src/widgets/aboutdialog.rs:38
msgid "translator-credits"
msgstr "Marek Černocký <marek@manet.cz>"
#: podcasts-gtk/src/widgets/episode.rs:130
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:363
msgid "The media player was unable to execute an action."
msgstr "Multimediální přehrávač nebyl schopen provést žádnou činnost."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "Všechny epizody byly označené jak přehrané"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Byl odhlášen odběr z {}"
+377
View File
@@ -0,0 +1,377 @@
# Danish translation for podcasts.
# Copyright (C) 2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# scootergrisen, 2019.
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-05-19 10:38+0000\n"
"PO-Revision-Date: 2019-05-22 14:50+0200\n"
"Last-Translator: scootergrisen\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Øverste placering af hovedvindue som sidst var åbent"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Venstre placering af hovedvindue som sidst var åbent"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Højde på hovedvindue som sidst var åbent"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Bredde på hovedvindue som sidst var åbent"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Maksimeret tilstand på hovedvindue som sidst var åbent"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Aktivér eller deaktivér mørkt tema"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Om indholdet jævnligt skal opdateres"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Hvor lang tid der skal gå mellem automatiske opdateringer"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Hvor lang tid der skal gå mellem automatiske opdateringer"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Om indholdet skal opdateres efter opstart"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Hvor lang tid der skal gå mellem automatiske oprydninger"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Hvor lang tid der skal gå mellem automatiske oprydninger"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Lyt til dine favorit podcasts fra dit skrivebord."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast-program til GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Udsendelsen har endnu ikke nogen episoder"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr ""
"Hvis du tror det er en fejl, så overvej venligst at skrive en fejlrapport."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Hent nogen udsendelser"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Tilføj nye udsendelser via feed-URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importér udsendelser fra en anden enhed"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Du har allerede lyttet til episoden."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Udregner episodestørrelse …"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Afspil episoden"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Annuller downloadprocessen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Download episoden"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Søg efter nye episoder"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importér udsendelser"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Eksportér udsendelser"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "_Tastaturgenveje"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "_Om Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Tilføj et nyt feed"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Indtast adresse på feed der skal tilføjes"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Tilføj"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Du har allerede abonneret på feedet!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Vis titel"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Tilbage"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Generelt"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Søg efter nye episoder"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Afslut programmet"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "I dag"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "I går"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Denne uge"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Denne måned"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Ældre"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "En notifikation om programindbygget handling"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Fortryd"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Spol 10 sekunder tilbage"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Afspil"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pause"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Spol 10 sekunder fremad"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Skift afspilningshastigheden"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 hastighed"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 hastighed"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normal hastighed"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Markér alle episoder som afspillet"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Websted"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Afmeld abonnement"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Åbn websted"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Markér alle som afspillet"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Afmeld abonnement"
#: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes"
msgstr "Henter nye episoder"
#: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show"
msgstr "Du har allerede abonneret på udsendelsen"
#: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL"
msgstr "Ugyldig URL"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Nyt"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Udsendelser"
#: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows."
msgstr "Vælg den fil du vil importere udsendelser fra."
#: podcasts-gtk/src/utils.rs:400
msgid "_Import"
msgstr "_Importér"
#: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file"
msgstr "OPML-fil"
#: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file"
msgstr "Kunne ikke fortolke den importerede fil"
#: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed."
msgstr "Kunne ikke tilgå den valgte fil."
#: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Eksportér udsendelser til …"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Eksportér"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Annuller"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Abonneringer for GNOME Podcasts"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Kunne ikke eksportere podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast-klient til GNOME-skrivebordet."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Lær mere om GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr "scootergrisen"
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action."
msgstr "Medieafspilleren kunne ikke udføre en handling."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Markerede alle episoder som hørt"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Afmeldte abonnement fra {}"
+90 -63
View File
@@ -2,22 +2,22 @@
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER # Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package. # This file is distributed under the same license as the podcasts package.
# Mario Blättermann <mario.blaettermann@gmail.com>, 2018. # Mario Blättermann <mario.blaettermann@gmail.com>, 2018.
# Tim Sabsch <tim@sabsch.com>, 2018. # Tim Sabsch <tim@sabsch.com>, 2018-2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: podcasts master\n" "Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-22 05:29+0000\n" "POT-Creation-Date: 2019-02-02 15:17+0000\n"
"PO-Revision-Date: 2018-08-25 23:26+0200\n" "PO-Revision-Date: 2019-03-09 17:13+0100\n"
"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n" "Last-Translator: Tim Sabsch <tim@sabsch.com>\n"
"Language-Team: German <gnome-de@gnome.org>\n" "Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n" "X-Generator: Poedit 2.2.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window" msgid "Top position of the last open main window"
@@ -69,39 +69,39 @@ msgid "What period of time to wait between automatic cleanups"
msgstr "Zeitintervall zwischen automatischen Löschvorgängen" msgstr "Zeitintervall zwischen automatischen Löschvorgängen"
#. Weird magic I copy-pasted that sets the Application Name in the Shell. #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:406 #: podcasts-gtk/src/app.rs:124 podcasts-gtk/src/app.rs:455
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcasts" msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:10 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Hören Sie Ihre Lieblings-Podcasts direkt in Ihrer Arbeitsumgebung." msgstr "Hören Sie Ihre Lieblings-Podcasts direkt in Ihrer Arbeitsumgebung."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:6 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "org.gnome.Podcasts" msgid "@icon@"
msgstr "org.gnome.Podcasts" msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
msgstr "Podcast;RSS;" msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:8 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "Podcast-Anwendung für GNOME" msgstr "Podcast-Anwendung für GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis" msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46 #: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet" msgid "This show does not have episodes yet"
msgstr "Diese Show hat noch keine Folgen" msgstr "Dieser Podcast hat noch keine Folgen"
#: podcasts-gtk/resources/gtk/empty_view.ui:62 #: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
@@ -109,53 +109,57 @@ msgstr ""
"Falls Sie meinen, dass es sich um einen Fehler handeln könnte, schreiben Sie " "Falls Sie meinen, dass es sich um einen Fehler handeln könnte, schreiben Sie "
"bitte einen Fehlerbericht." "bitte einen Fehlerbericht."
#: podcasts-gtk/resources/gtk/empty_view.ui:107 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
msgstr "Shows holen" msgstr "Podcasts abonnieren"
#: podcasts-gtk/resources/gtk/empty_view.ui:144 #: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL" msgid "Add new shows via feed URL"
msgstr "Neue Shows mittels Quellen-Adresse hinzufügen" msgstr "Neue Podcasts mittels Quellen-Adresse hinzufügen"
#: podcasts-gtk/resources/gtk/empty_view.ui:173 #: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Shows von einem anderen Gerät importieren" msgstr "Podcasts von einem anderen Gerät importieren"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Größe der Folge wird ermittelt …" msgstr "Größe der Folge wird ermittelt …"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Cancel"
msgstr "Abbrechen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Diese Folge herunterladen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Diese Folge abspielen" msgstr "Diese Folge abspielen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Herunterladen abbrechen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Diese Folge herunterladen"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "Auf neue Folgen _prüfen" msgstr "Auf neue Folgen _prüfen"
#: podcasts-gtk/resources/gtk/hamburger.ui:12 #: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows" msgid "_Import Shows"
msgstr "Shows _importieren" msgstr "Podcasts _importieren"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "Podcasts e_xportieren"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences" msgid "_Preferences"
msgstr "_Einstellungen" msgstr "_Einstellungen"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "Tasten_kürzel" msgstr "Tasten_kürzel"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About" msgid "_About Podcasts"
msgstr "I_nfo" msgstr "Info zu _Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189 #: podcasts-gtk/resources/gtk/headerbar.ui:189
@@ -319,93 +323,116 @@ msgstr "Alle als angehört markieren"
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Abbestellen" msgstr "Abbestellen"
#: podcasts-gtk/src/app.rs:331 #: podcasts-gtk/src/app.rs:369
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Neue Folgen werden abgerufen" msgstr "Neue Folgen werden abgerufen"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Sie haben diese Show nun abonniert" msgstr "Sie haben diese Show nun abonniert"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL" msgid "Invalid URL"
msgstr "Ungültige Adresse" msgstr "Ungültige Adresse"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/prefs.rs:78
msgid "Seconds" msgid "Seconds"
msgstr "Sekunden" msgstr "Sekunden"
#: podcasts-gtk/src/prefs.rs:60 #: podcasts-gtk/src/prefs.rs:79
msgid "Minutes" msgid "Minutes"
msgstr "Minuten" msgstr "Minuten"
#: podcasts-gtk/src/prefs.rs:61 #: podcasts-gtk/src/prefs.rs:80
msgid "Hours" msgid "Hours"
msgstr "Stunden" msgstr "Stunden"
#: podcasts-gtk/src/prefs.rs:62 #: podcasts-gtk/src/prefs.rs:81
msgid "Days" msgid "Days"
msgstr "Tage" msgstr "Tage"
#: podcasts-gtk/src/prefs.rs:63 #: podcasts-gtk/src/prefs.rs:82
msgid "Weeks" msgid "Weeks"
msgstr "Wochen" msgstr "Wochen"
#: podcasts-gtk/src/stacks/content.rs:35 #: podcasts-gtk/src/stacks/content.rs:54
msgid "New" msgid "New"
msgstr "Neu" msgstr "Neu"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Shows" msgstr "Podcasts"
#: podcasts-gtk/src/utils.rs:350 #: podcasts-gtk/src/utils.rs:377
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Wählen Sie die Datei aus, aus der Sie Shows importieren wollen." msgstr "Wählen Sie die Datei aus, aus der Sie Shows importieren wollen."
#: podcasts-gtk/src/utils.rs:353 #: podcasts-gtk/src/utils.rs:380
msgid "_Import" msgid "_Import"
msgstr "_Importieren" msgstr "_Importieren"
#: podcasts-gtk/src/utils.rs:362 #: podcasts-gtk/src/utils.rs:389 podcasts-gtk/src/utils.rs:435
msgid "OPML file" msgid "OPML file"
msgstr "OPML-Datei" msgstr "OPML-Datei"
#: podcasts-gtk/src/utils.rs:379 #: podcasts-gtk/src/utils.rs:406
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "Die importierte Datei konnte nicht ausgewertet werden" msgstr "Die importierte Datei konnte nicht ausgewertet werden"
#: podcasts-gtk/src/utils.rs:384 #: podcasts-gtk/src/utils.rs:411 podcasts-gtk/src/utils.rs:453
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "Auf die gewählte Datei konnte nicht zugegriffen werden." msgstr "Auf die gewählte Datei konnte nicht zugegriffen werden."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:423
msgid "Export shows to…"
msgstr "Podcasts exportieren nach …"
#: podcasts-gtk/src/utils.rs:426
msgid "_Export"
msgstr "E_xportieren"
#: podcasts-gtk/src/utils.rs:427
msgid "_Cancel"
msgstr "A_bbrechen"
#: podcasts-gtk/src/utils.rs:447
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcasts Abonnements"
#: podcasts-gtk/src/utils.rs:448
msgid "Failed to export podcasts"
msgstr "Export der Podcasts ist fehlgeschlagen"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast-Client für die GNOME-Arbeitsumgebung." msgstr "Podcast-Client für die GNOME-Arbeitsumgebung."
#: podcasts-gtk/src/widgets/aboutdialog.rs:35 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "Erfahren Sie mehr über GNOME Podcasts" msgstr "Erfahren Sie mehr über GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:40 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "" msgstr ""
"Mario Blättermann <mario.blaettermann@gmail.com>\n" "Mario Blättermann <mario.blaettermann@gmail.com>\n"
"Tim Sabsch <tim@sabsch.com>" "Tim Sabsch <tim@sabsch.com>"
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:149
msgid "{} min" msgid "{} min"
msgstr "{} min" msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:536
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "Die Medienwiedergabe konnte eine Aktion nicht ausführen." msgstr "Die Medienwiedergabe konnte eine Aktion nicht ausführen."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:169
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Alle Folgen als angehört markieren" msgstr "Alle Folgen als angehört markieren"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:174
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "Abonnement von {} gekündigt" msgstr "Abonnement von {} gekündigt"
#~ msgid "_About"
#~ msgstr "I_nfo"
+433
View File
@@ -0,0 +1,433 @@
# British English translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# zbrown <zbrown@gnome.org>, 2018.
# FULL NAME <EMAIL@ADDRESS>, 2018.
# Zander Brown <zbrown@gnome.org>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-03-03 16:03+0000\n"
"PO-Revision-Date: 2019-03-16 11:46+0000\n"
"Last-Translator: Bruce Cowan <bruce@bcowan.me.uk>\n"
"Language-Team: British English <en_GB@li.org>\n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);;\n"
"X-Generator: Poedit 2.2.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Top position of the last open main window"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Left position of the last open main window"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Height of the last open main window"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Width of the last open main window"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Maximised state of the last open main window"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Enable or disable dark theme"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Whether to periodically refresh content"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "How many periods of time to wait between automatic refreshes"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "What period of time to wait between automatic refreshes"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Whether to refresh content after startup"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "How many periods of time to wait between automatic cleanups"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "What period of time to wait between automatic cleanups"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:124 podcasts-gtk/src/app.rs:463
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Listen to your favorite podcasts, right from your desktop."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast app for GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "This show does not have episodes yet"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "If you think this is an error, please consider writing a bug report."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Get some shows"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Add new shows via feed URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Import shows from another device"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Calculating episode size…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Play this episode"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Cancel download"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Download this episode"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Check for New Episodes"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Import Shows"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
#| msgid "_Import Shows"
msgid "_Export Shows"
msgstr "_Export Shows"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Preferences"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Keyboard Shortcuts"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "_About Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Add a new feed"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Enter feed address to add"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Add"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "You are already subscribed to that feed!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Show Title"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Back"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "General"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Check for new episodes"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferences"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Quit the application"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Today"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Yesterday"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "This Week"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "This Month"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Older"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "An in-app action notification"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Undo"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Rewind 10 seconds"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Play"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pause"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Fast forward 10 seconds"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Change the playback speed"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1.00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1.50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1.5 speed rate"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1.25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1.25 speed rate"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normal speed"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferences"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Appearance"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Dark Theme"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Delete played episodes"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "After"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Mark All Episodes as Played"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Website"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Unsubscribe"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Open Website"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Mark All as Played"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Unsubscribe"
#: podcasts-gtk/src/app.rs:378
msgid "Fetching new episodes"
msgstr "Fetching new episodes"
#: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show"
msgstr "You are already subscribed to this show"
#: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL"
msgstr "Invalid URL"
#: podcasts-gtk/src/prefs.rs:78
msgid "Seconds"
msgstr "Seconds"
#: podcasts-gtk/src/prefs.rs:79
msgid "Minutes"
msgstr "Minutes"
#: podcasts-gtk/src/prefs.rs:80
msgid "Hours"
msgstr "Hours"
#: podcasts-gtk/src/prefs.rs:81
msgid "Days"
msgstr "Days"
#: podcasts-gtk/src/prefs.rs:82
msgid "Weeks"
msgstr "Weeks"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "New"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Shows"
#: podcasts-gtk/src/utils.rs:387
msgid "Select the file from which to you want to import shows."
msgstr "Select the file from which to you want to import shows."
#: podcasts-gtk/src/utils.rs:390
msgid "_Import"
msgstr "_Import"
#: podcasts-gtk/src/utils.rs:399 podcasts-gtk/src/utils.rs:447
msgid "OPML file"
msgstr "OPML file"
#: podcasts-gtk/src/utils.rs:416
msgid "Failed to parse the imported file"
msgstr "Failed to parse the imported file"
#: podcasts-gtk/src/utils.rs:421 podcasts-gtk/src/utils.rs:465
msgid "Selected file could not be accessed."
msgstr "Selected file could not be accessed."
#: podcasts-gtk/src/utils.rs:435
msgid "Export shows to…"
msgstr "Export shows to…"
#: podcasts-gtk/src/utils.rs:438
#| msgid "_Import"
msgid "_Export"
msgstr "_Export"
#: podcasts-gtk/src/utils.rs:439
msgid "_Cancel"
msgstr "_Cancel"
#: podcasts-gtk/src/utils.rs:459
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcasts Subscriptions"
#: podcasts-gtk/src/utils.rs:460
msgid "Failed to export podcasts"
msgstr "Failed to export podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast Client for the GNOME Desktop."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Learn more about GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr "Zander Brown"
#: podcasts-gtk/src/widgets/episode.rs:145
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:536
msgid "The media player was unable to execute an action."
msgstr "The media player was unable to execute an action."
#: podcasts-gtk/src/widgets/show_menu.rs:175
msgid "Marked all episodes as listened"
msgstr "Marked all episodes as listened"
#: podcasts-gtk/src/widgets/show_menu.rs:180
msgid "Unsubscribed from {}"
msgstr "Unsubscribed from {}"
+170 -161
View File
@@ -3,21 +3,24 @@
# This file is distributed under the same license as the gnome-podcasts package. # This file is distributed under the same license as the gnome-podcasts package.
# Automatically generated, 2018. # Automatically generated, 2018.
# Daniel Garcia Moreno <danigm@wadobo.com>, 2018. # Daniel Garcia Moreno <danigm@wadobo.com>, 2018.
# Rodrigo <rodhos92@gmail.com>, 2018.
# Rodrigo Lledó <rodhos92@gmail.com>, 2019.
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2018-2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-podcasts\n" "Project-Id-Version: gnome-podcasts\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-22 06:50+0300\n" "POT-Creation-Date: 2019-06-15 10:55+0000\n"
"PO-Revision-Date: 2018-08-02 11:46+0200\n" "PO-Revision-Date: 2019-06-19 12:19+0200\n"
"Last-Translator: Daniel Garcia Moreno <danigm@wadobo.com>\n" "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Español; Castellano <info@wadobo.com>\n" "Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n" "Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.7\n" "X-Generator: Gtranslator 3.32.0\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window" msgid "Top position of the last open main window"
@@ -29,11 +32,11 @@ msgstr "Posición izquierda de la última ventana abierta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window" msgid "Height of the last open main window"
msgstr "Alto de la última ventana abierta" msgstr "Altura de la última ventana abierta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window" msgid "Width of the last open main window"
msgstr "Ancho de la última ventana abierta" msgstr "Anchura de la última ventana abierta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window" msgid "Maximized state of the last open main window"
@@ -45,142 +48,135 @@ msgstr "Activar o desactivar el tema oscuro"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content" msgid "Whether to periodically refresh content"
msgstr "Si refrescar el contenido periódicamente" msgstr "Indica si se debe actualizar el contenido periódicamente"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes" msgid "How many periods of time to wait between automatic refreshes"
msgstr "Cuántos periodos de tiempo a esperar entre refrescos automáticos" msgstr ""
"Cuántos periodos de tiempo hay que esperar entre actualizaciones automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes" msgid "What period of time to wait between automatic refreshes"
msgstr "Qué periodo de tiempo hay que esperar entre refrescos automáticos" msgstr ""
"Qué periodo de tiempo hay que esperar entre actualizaciones automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup" msgid "Whether to refresh content after startup"
msgstr "Si refrescar el contenido al iniciar" msgstr "Indica si se debe actualizar el contenido al iniciar"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups" msgid "How many periods of time to wait between automatic cleanups"
msgstr "Cuántos periodos de tiempo hay que esperar entre limpiados automáticos" msgstr "Cuántos periodos de tiempo hay que esperar entre limpiezas automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups" msgid "What period of time to wait between automatic cleanups"
msgstr "Cuántos periodos de tiempo hay que esperar entre limpiados automáticos" msgstr "Cuántos periodos de tiempo hay que esperar entre limpiezas automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3 #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:406 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcasts" msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:10 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Escucha tus podcasts favoritos, directamente desde tu escritorio." msgstr "Escuche sus podcasts favoritos, directamente desde su escritorio."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:6
msgid "org.gnome.Podcasts"
msgstr "org.gnome.Podcasts"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
msgstr "Podcast;RSS;" msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:8 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "Aplicación de Podcast para GNOME" msgstr "Aplicación de Podcast para GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
#, fuzzy
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis y otros" msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46 #: podcasts-gtk/resources/gtk/empty_view.ui:46
#, fuzzy
msgid "This show does not have episodes yet" msgid "This show does not have episodes yet"
msgstr "Este programa no tiene episodios todavía" msgstr "Este programa no tiene episodios todavía"
#: podcasts-gtk/resources/gtk/empty_view.ui:62 #: podcasts-gtk/resources/gtk/empty_view.ui:62
#, fuzzy
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
msgstr "" msgstr "Si cree que esto es un error considere abrir un informe de error."
"Si crees que esto es un error, por favor, considera abrir un bug report."
#: podcasts-gtk/resources/gtk/empty_view.ui:107 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
msgstr "Consigue algún programa" msgstr "Consiga algún programa"
#: podcasts-gtk/resources/gtk/empty_view.ui:144 #: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL" msgid "Add new shows via feed URL"
msgstr "Añadir nuevo programa a través de canal URL" msgstr "Añadir un programa nuevo a través de canal URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:173 #: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Importar programas de otro dispositivo" msgstr "Importar programas de otro dispositivo"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:79
#, fuzzy #| msgid "You've already listened to this episode."
msgid "You’ve already listened to this episode."
msgstr "Ya ha escuchado este episodio."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Calculando tamaño del episodio..." msgstr "Calculando tamaño del episodio…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Cancel"
msgstr "Cancelar"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Descargar este episodio"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Reproducir este episodio" msgstr "Reproducir este episodio"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Cancelar el proceso de descarga"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Descargar este episodio"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
#, fuzzy
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "_Comprobar si hay nuevos episodios" msgstr "Comprobar si hay nuevos episodios"
#: podcasts-gtk/resources/gtk/hamburger.ui:12 #: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows" msgid "_Import Shows"
msgstr "_Importar programas" msgstr "_Importar programas"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Preferences" msgid "_Export Shows"
msgstr "_Preferencias" msgstr "_Exportar programas"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "Atajos de _teclado" msgstr "Atajos de _teclado"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About" msgid "_About Podcasts"
msgstr "_Acerca de" msgstr "_Acerca de Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189 #: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed" msgid "Add a new feed"
msgstr "Añadir un nuevo canal" msgstr "Añadir un canal nuevo"
#: podcasts-gtk/resources/gtk/headerbar.ui:53 #: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add" msgid "Enter feed address to add"
msgstr "Introduce la dirección del canal a añadir" msgstr "Introduzca la dirección del canal que añadir"
#: podcasts-gtk/resources/gtk/headerbar.ui:89 #: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add" msgid "Add"
msgstr "Añadir" msgstr "Añadir"
#: podcasts-gtk/resources/gtk/headerbar.ui:133 #: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "You are already subscribed to that feed!"
msgstr "¡Ya estás suscrito a este canal!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title" msgid "Show Title"
msgstr "Título de Programa" msgstr "Título del programa"
#: podcasts-gtk/resources/gtk/headerbar.ui:210 #: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back" msgid "Back"
msgstr "Atrás" msgstr "Atrás"
@@ -191,15 +187,10 @@ msgstr "General"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18 #: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Check for new episodes" msgid "Check for new episodes"
msgstr "Comprobar si hay nuevos episodios" msgstr "Comprobar si hay episodios nuevos"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25 #: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferencias"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application" msgid "Quit the application"
msgstr "Salir de la aplicación" msgstr "Salir de la aplicación"
@@ -225,7 +216,7 @@ msgstr "Antiguo"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101 #: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification" msgid "An in-app action notification"
msgstr "Una notificación de acción in-app" msgstr "Una notificación de acción dentro de la aplicación"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112 #: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo" msgid "Undo"
@@ -233,7 +224,7 @@ msgstr "Deshacer"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72 #: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds" msgid "Rewind 10 seconds"
msgstr "Atrás 10 segundos" msgstr "Retroceder 10 segundos"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87 #: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play" msgid "Play"
@@ -244,34 +235,29 @@ msgid "Pause"
msgstr "Pausa" msgstr "Pausa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119 #: podcasts-gtk/resources/gtk/player_toolbar.ui:119
#, fuzzy
msgid "Fast forward 10 seconds" msgid "Fast forward 10 seconds"
msgstr "Adelante 10 segundos" msgstr "Avanzar 10 segundos"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285 #: podcasts-gtk/resources/gtk/player_toolbar.ui:285
#, fuzzy
msgid "Change the playback speed" msgid "Change the playback speed"
msgstr "Cambiar velocidad de reproducción" msgstr "Cambiar velocidad de reproducción"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300 #: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380 #: podcasts-gtk/resources/gtk/player_toolbar.ui:380
#, fuzzy
msgid "1.00×" msgid "1.00×"
msgstr "1.00x" msgstr "1.00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344 #: podcasts-gtk/resources/gtk/player_toolbar.ui:344
#, fuzzy
msgid "1.50×" msgid "1.50×"
msgstr "1.50x" msgstr "1.50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348 #: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate" msgid "1.5 speed rate"
msgstr "velocidad 1.5" msgstr "velocidad 1.5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362 #: podcasts-gtk/resources/gtk/player_toolbar.ui:362
#, fuzzy
msgid "1.25×" msgid "1.25×"
msgstr "1.25x" msgstr "1.25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366 #: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate" msgid "1.25 speed rate"
@@ -281,29 +267,7 @@ msgstr "velocidad 1.25"
msgid "Normal speed" msgid "Normal speed"
msgstr "Velocidad normal" msgstr "Velocidad normal"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferencias"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Aspecto"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tema oscuro"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Eliminar episodios reproducidos"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Después"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7 #: podcasts-gtk/resources/gtk/secondary_menu.ui:7
#, fuzzy
msgid "_Mark All Episodes as Played" msgid "_Mark All Episodes as Played"
msgstr "_Marcar todos los episodios como reproducidos" msgstr "_Marcar todos los episodios como reproducidos"
@@ -320,108 +284,153 @@ msgid "Open Website"
msgstr "Abrir Web" msgstr "Abrir Web"
#: podcasts-gtk/resources/gtk/show_menu.ui:64 #: podcasts-gtk/resources/gtk/show_menu.ui:64
#, fuzzy
msgid "Mark All as Played" msgid "Mark All as Played"
msgstr "Marcar como reproducido" msgstr "Marcar todo como reproducido"
#: podcasts-gtk/resources/gtk/show_menu.ui:89 #: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Cancelar suscripción" msgstr "Cancelar suscripción"
#: podcasts-gtk/src/app.rs:331 #: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Obteniendo nuevos episodios" msgstr "Obteniendo nuevos episodios"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:127
#, fuzzy
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Ya estás suscrito a este programa" msgstr "Ya está suscrito a este programa"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:145
#, fuzzy
msgid "Invalid URL" msgid "Invalid URL"
msgstr "Url no válida" msgstr "URL no válido"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/stacks/content.rs:54
msgid "Seconds"
msgstr "Segundos"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minutos"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Horas"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Días"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Semanas"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New" msgid "New"
msgstr "Nuevo" msgstr "Nuevo"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Programas" msgstr "Programas"
#: podcasts-gtk/src/utils.rs:350 #: podcasts-gtk/src/utils.rs:397
#, fuzzy
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Selecciona el fichero desde el cual quieres importar programas." msgstr "Selecciona el fichero desde el que quiere importar programas."
#: podcasts-gtk/src/utils.rs:353 #: podcasts-gtk/src/utils.rs:400
msgid "_Import" msgid "_Import"
msgstr "_Importar" msgstr "_Importar"
#: podcasts-gtk/src/utils.rs:362 #: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file" msgid "OPML file"
msgstr "fichero OPML" msgstr "fichero OPML"
#: podcasts-gtk/src/utils.rs:379 #: podcasts-gtk/src/utils.rs:426
#, fuzzy
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "Fallo al leer el fichero importado" msgstr "Fallo al analizar el fichero importado"
#: podcasts-gtk/src/utils.rs:384 #: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
#, fuzzy
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "El fichero seleccionado no es accesible." msgstr "No se ha podido acceder al archivo seleccionado."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Exportar programas a…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Exportar"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Cancelar"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Suscripciones a podcasts de GNOME"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Falló al exportar podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "Aplicación de Podcast para el escritorio GNOME." msgstr "Aplicación de Podcast para el escritorio GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:35 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "" msgstr "Aprenda más sobre GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:40 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "\"Daniel García Moreno <danigm@wadobo.com>\"" msgstr ""
"Daniel Mustieles <daniel.mustieles@gmail.com>, 2018-2019\n"
"Daniel García Moreno <danigm@wadobo.com>"
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min" msgid "{} min"
msgstr "{} min" msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "El reproductor no ha podido reproducir una acción." msgstr "El reproductor no ha podido reproducir una acción."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Marcar todos los episodios como escuchados" msgstr "Marcar todos los episodios como escuchados"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "Suscripción cancelada para {}" msgstr "Suscripción cancelada para {}"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "¡Ya está suscrito a este canal!"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "_Preferencias"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Preferencias"
#~ msgid "Preferences"
#~ msgstr "Preferencias"
#~ msgid "Appearance"
#~ msgstr "Aspecto"
#~ msgid "Dark Theme"
#~ msgstr "Tema oscuro"
#~ msgid "Delete played episodes"
#~ msgstr "Eliminar episodios reproducidos"
#~ msgid "After"
#~ msgstr "Después"
#~ msgid "Seconds"
#~ msgstr "Segundos"
#~ msgid "Minutes"
#~ msgstr "Minutos"
#~ msgid "Hours"
#~ msgstr "Horas"
#~ msgid "Days"
#~ msgstr "Días"
#~ msgid "Weeks"
#~ msgstr "Semanas"
#~ msgid "_About"
#~ msgstr "_Acerca de"
#~ msgid "org.gnome.Podcasts"
#~ msgstr "org.gnome.Podcasts"
#~ msgid "Mark all episodes as listened" #~ msgid "Mark all episodes as listened"
#~ msgstr "Marcar todos los episodios como escuchados" #~ msgstr "Marcar todos los episodios como escuchados"
+362
View File
@@ -0,0 +1,362 @@
# Basque translation for podcasts.
# Copyright (C) 2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Asier Sarasua Garmendia <asier.sarasua@gmail.com>, 2019.
#
msgid ""
msgstr "Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-10-10 13:08+0000\n"
"PO-Revision-Date: 2019-10-18 10:00+0100\n"
"Last-Translator: Asier Sarasua Garmendia <asier.sarasua@gmail.com>\n"
"Language-Team: Basque <librezale@librezale.eus>\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Irekitako azken leiho nagusiaren goiko posizioa"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Irekitako azken leiho nagusiaren ezkerreko posizioa"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Irekitako azken leiho nagusiaren altuera"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Irekitako azken leiho nagusiaren zabalera"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Irekitako azken leiho nagusiaren egoera maximizatua"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Gaitu edo desgaitu gai iluna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Edukia aldizka freskatuko den ala ez"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Zenbat denbora-tarte itxarongo den freskatze automatikoen artean"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Zenbat denbora itxarongo den freskatze automatikoen artean"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Abioaren ondoren edukia freskatuko den ala ez"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Zenbat denbora-tarte itxarongo den garbitze automatikoen artean"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Zenbat denbora itxarongo den garbitze automatikoen artean"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:327 podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcast-ak"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Entzun zure podcast gogokoenak zuzenean zure mahaigainetik."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast-en aplikazioa GNOMErako"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Saio honek ez du pasarterik oraindik"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Errorea dela uste baduzu, idatzi akatsaren jakinarazpen bat."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Eskuratu zenbait saio"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Gehitu saio berriak jarioen URL baten bidez"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Inportatu saioak beste gailu batetik"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Dagoeneko entzun duzu pasarte hau"
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Pasartearen tamaina kalkulatzen…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Erreproduzitu pasarte hau"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Utzi deskarga-prozesua"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Deskargatu pasarte hau"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Begiratu pasarte berriak dauden"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Inportatu saioak"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Esportatu saioak"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "Las_ter-teklak"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "Podcasts aplikazioari _buruz"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed"
msgstr "Gehitu jario berria"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Sartu gehituko den jarioaren helbidea"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Gehitu"
#: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "Show Title"
msgstr "Erakutsi titulua"
#: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back"
msgstr "Atzera"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Orokorra"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Begiratu pasarte berriak dauden"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Irten aplikaziotik"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Gaur"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Atzo"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Aste honetan"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Hilabete honetan"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Zaharragoa"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Aplikazioaren jakinarazpen bat"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Desegin"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Joan 10 segundo atzera"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Erreproduzitu"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pausatu"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Joan 10 segundo aurrera"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Aldatu erreprodukzioaren abiadura"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1.00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1.50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1.5 abiadura-tasa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1.25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1.25 abiadura-tasa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Abiadura normala"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Markatu pasarte guztiak erreproduzitu gisa"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Webgunea"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "Harpidetza _kendu"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Ireki webgunea"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Markatu dena erreproduzitu gisa"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Harpidetza kendu"
#: podcasts-gtk/src/app.rs:265
msgid "Fetching new episodes"
msgstr "Pasarte berriak eskuratzen"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Berria"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Saioak"
#: podcasts-gtk/src/utils.rs:396
msgid "Select the file from which to you want to import shows."
msgstr "Hautatu saioak inportatzeko erabiliko duzun fitxategia."
#: podcasts-gtk/src/utils.rs:399
msgid "_Import"
msgstr "_Inportatu"
#: podcasts-gtk/src/utils.rs:408 podcasts-gtk/src/utils.rs:456
msgid "OPML file"
msgstr "OPML fitxategia"
#: podcasts-gtk/src/utils.rs:425
msgid "Failed to parse the imported file"
msgstr "Huts egin du inportatuko fitxategia analizatzeak"
#: podcasts-gtk/src/utils.rs:430 podcasts-gtk/src/utils.rs:474
msgid "Selected file could not be accessed."
msgstr "Hautatutako fitxategia ezin da eskuratu."
#: podcasts-gtk/src/utils.rs:444
msgid "Export shows to…"
msgstr "Esportatu saioak hona…"
#: podcasts-gtk/src/utils.rs:447
msgid "_Export"
msgstr "_Esportatu"
#: podcasts-gtk/src/utils.rs:448
msgid "_Cancel"
msgstr "_Utzi"
#: podcasts-gtk/src/utils.rs:468
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcasts harpidetzak"
#: podcasts-gtk/src/utils.rs:469
msgid "Failed to export podcasts"
msgstr "Huts egin du podcast-ak esportatzeak"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast-en bezeroa GNOME mahaigainerako."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Ikasi gehiago GNOME Podcasts aplikazioari buruz"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr "Asier Sarasua Garmendia <asier.sarasua@gmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:535
msgid "The media player was unable to execute an action."
msgstr "Multimedia-erreproduzigailuak ezin izan da ekintza bat exekutatu."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Markatu pasarte guztiak entzundako gisa"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Kendu {} podcast-eko harpidetza"
+127 -110
View File
@@ -6,9 +6,9 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: podcasts master\n" "Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-22 06:50+0300\n" "POT-Creation-Date: 2019-05-18 12:55+0000\n"
"PO-Revision-Date: 2018-08-11 17:09+0300\n" "PO-Revision-Date: 2019-06-01 20:20+0300\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n" "Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n"
"Language-Team: Finnish <lokalisointi-lista@googlegroups.com>\n" "Language-Team: Finnish <lokalisointi-lista@googlegroups.com>\n"
"Language: fi\n" "Language: fi\n"
@@ -20,19 +20,19 @@ msgstr ""
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window" msgid "Top position of the last open main window"
msgstr "" msgstr "Viimeksi avoinna olleen pääikkunan yläsijainti"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window" msgid "Left position of the last open main window"
msgstr "" msgstr "Viimeksi avoinna olleen pääikkunan vasen sijainti"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window" msgid "Height of the last open main window"
msgstr "" msgstr "Viimeksi avoinna olleen pääikkunan korkeus"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window" msgid "Width of the last open main window"
msgstr "" msgstr "Viimeksi avoinna olleen pääikkunan leveys"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window" msgid "Maximized state of the last open main window"
@@ -44,7 +44,7 @@ msgstr "Ota käyttöön tai poista käytöstä tumma teema"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content" msgid "Whether to periodically refresh content"
msgstr "" msgstr "Päivitetäänkö sisältö säännöllisesti"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes" msgid "How many periods of time to wait between automatic refreshes"
@@ -67,74 +67,71 @@ msgid "What period of time to wait between automatic cleanups"
msgstr "" msgstr ""
#. Weird magic I copy-pasted that sets the Application Name in the Shell. #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:406 #: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcastit" msgstr "Podcastit"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:10 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Kuuntele suosikkipodcastejasi suoraan työpöydältäsi." msgstr "Kuuntele suosikkipodcastejasi suoraan työpöydältäsi."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:6
msgid "org.gnome.Podcasts"
msgstr "org.gnome.Podcasts"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
msgstr "Podcast;RSS;" msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:8 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "Podcast-sovellus Gnomelle" msgstr "Podcast-sovellus Gnomelle"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis" msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46 #: podcasts-gtk/resources/gtk/empty_view.ui:46
#, fuzzy
msgid "This show does not have episodes yet" msgid "This show does not have episodes yet"
msgstr "Tässä ohjelmassa ei ole yhtäkään jaksoa" msgstr "Tässä ohjelmassa ei ole vielä yhtäkään jaksoa"
#: podcasts-gtk/resources/gtk/empty_view.ui:62 #: podcasts-gtk/resources/gtk/empty_view.ui:62
#, fuzzy
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
msgstr "Jos luulet tämän olevan virhe, teethän bugiraportin." msgstr "Jos tämä on mielestäsi virhe, teethän bugiraportin."
#: podcasts-gtk/resources/gtk/empty_view.ui:107 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
msgstr "Hanki ohjelmia" msgstr "Hanki ohjelmia"
#: podcasts-gtk/resources/gtk/empty_view.ui:144 #: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL" msgid "Add new shows via feed URL"
msgstr "Lisää uusia ohjelmia syötteen osoitteen avulla" msgstr "Lisää uusia ohjelmia syötteen osoitteen avulla"
#: podcasts-gtk/resources/gtk/empty_view.ui:173 #: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Tuo ohjelmia toiselta laitteelta" msgstr "Tuo ohjelmia toiselta laitteelta"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Olet jo kuunnellut tämän jakson."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Lasketaan jakson kokoa…" msgstr "Lasketaan jakson kokoa…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Cancel"
msgstr "Peru"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Lataa tämä jakso"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Toista tämä jakso" msgstr "Toista tämä jakso"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Peru lataaminen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Lataa tämä jakso"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "Ta_rkista uudet jaksot" msgstr "Ta_rkista uudet jaksot"
@@ -143,17 +140,17 @@ msgstr "Ta_rkista uudet jaksot"
msgid "_Import Shows" msgid "_Import Shows"
msgstr "Tu_o jaksoja" msgstr "Tu_o jaksoja"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Preferences" msgid "_Export Shows"
msgstr "_Asetukset" msgstr "_Vie jaksoja"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "_Pikanäppäimet" msgstr "_Pikanäppäimet"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About" msgid "_About Podcasts"
msgstr "_Tietoja" msgstr "_Tietoja - Podcastit"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189 #: podcasts-gtk/resources/gtk/headerbar.ui:189
@@ -191,11 +188,6 @@ msgstr "Tarkista uudet jaksot"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25 #: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Preferences"
msgstr "Asetukset"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application" msgid "Quit the application"
msgstr "Lopeta sovellus" msgstr "Lopeta sovellus"
@@ -272,27 +264,6 @@ msgstr "1,25-kertainen nopeus"
msgid "Normal speed" msgid "Normal speed"
msgstr "Tavallinen nopeus" msgstr "Tavallinen nopeus"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Asetukset"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Ulkoasu"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tumma teema"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Poista toistetut jaksot"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Viive"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7 #: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played" msgid "_Mark All Episodes as Played"
msgstr "_Merkitse kaikki jaksot toistetuiksi" msgstr "_Merkitse kaikki jaksot toistetuiksi"
@@ -317,94 +288,140 @@ msgstr "Merkitse kaikki toistetuiksi"
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Lopeta tilaus" msgstr "Lopeta tilaus"
#: podcasts-gtk/src/app.rs:331 #: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Noudetaan uusia jaksoja" msgstr "Noudetaan uusia jaksoja"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Olet jo tilannut tämän ohjelman" msgstr "Olet jo tilannut tämän ohjelman"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL" msgid "Invalid URL"
msgstr "Virheellinen osoite" msgstr "Virheellinen osoite"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/stacks/content.rs:54
msgid "Seconds"
msgstr "sekuntia"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "minuuttia"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "tuntia"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "päivää"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "viikkoa"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New" msgid "New"
msgstr "Uudet" msgstr "Uudet"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Ohjelmat" msgstr "Ohjelmat"
#: podcasts-gtk/src/utils.rs:350 #: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Valitse tiedosto, josta haluat tuoda ohjelmia." msgstr "Valitse tiedosto, josta haluat tuoda ohjelmia."
#: podcasts-gtk/src/utils.rs:353 #: podcasts-gtk/src/utils.rs:400
msgid "_Import" msgid "_Import"
msgstr "_Tuo" msgstr "_Tuo"
#: podcasts-gtk/src/utils.rs:362 #: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file" msgid "OPML file"
msgstr "OPML-tiedosto" msgstr "OPML-tiedosto"
#: podcasts-gtk/src/utils.rs:379 #: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "Tuotua tiedostoa ei voitu jäsentää" msgstr "Tuotua tiedostoa ei voitu jäsentää"
#: podcasts-gtk/src/utils.rs:384 #: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "Valittua tiedostoa ei voitu käyttää." msgstr "Valittua tiedostoa ei voitu käyttää."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Vie jaksot…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Vie"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Peru"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Gnomen podcastsovelluksen tilaukset"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Podcastien vienti epäonnistui"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast-sovellus Gnome-työpöydlle." msgstr "Podcast-sovellus Gnome-työpöydlle."
#: podcasts-gtk/src/widgets/aboutdialog.rs:35 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "" msgstr "Lisätietoja Gnomen podcast-sovelluksesta"
#: podcasts-gtk/src/widgets/aboutdialog.rs:40 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "Jiri Grönroos" msgstr "Jiri Grönroos"
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min" msgid "{} min"
msgstr "{} min" msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "Mediasoitin ei kyennyt suorittamaan toimintoa." msgstr "Mediasoitin ei kyennyt suorittamaan toimintoa."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Merkitse kaikki jaksot toistetuiksi" msgstr "Merkitse kaikki jaksot toistetuiksi"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "Lopeta syötteen {} tilaus" msgstr "Lopeta syötteen {} tilaus"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "_Asetukset"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Asetukset"
#~ msgid "Preferences"
#~ msgstr "Asetukset"
#~ msgid "Appearance"
#~ msgstr "Ulkoasu"
#~ msgid "Dark Theme"
#~ msgstr "Tumma teema"
#~ msgid "Delete played episodes"
#~ msgstr "Poista toistetut jaksot"
#~ msgid "After"
#~ msgstr "Viive"
#~ msgid "Seconds"
#~ msgstr "sekuntia"
#~ msgid "Minutes"
#~ msgstr "minuuttia"
#~ msgid "Hours"
#~ msgstr "tuntia"
#~ msgid "Days"
#~ msgstr "päivää"
#~ msgid "Weeks"
#~ msgstr "viikkoa"
#~ msgid "_About"
#~ msgstr "_Tietoja"
#~ msgid "org.gnome.Podcasts"
#~ msgstr "org.gnome.Podcasts"
#~ msgid "Episode Title" #~ msgid "Episode Title"
#~ msgstr "Jakson nimi" #~ msgstr "Jakson nimi"
+407
View File
@@ -0,0 +1,407 @@
# French translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# arverne73 <arverne@wanadoo.fr>, 2018.
# Alexandre Franke <alexandre.franke@gmail.com>, 2018
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-10-23 10:23+0000\n"
"PO-Revision-Date: 2018-10-29 13:53+0100\n"
"Last-Translator: Alexandre Franke <alexandre.franke@gmail.com>\n"
"Language-Team: French <gnomefr@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 2.0.6\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Position supérieure de la dernière fenêtre principale ouverte"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Position gauche de la dernière fenêtre principale ouverte"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Hauteur de la dernière fenêtre principale ouverte"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Largeur de la dernière fenêtre principale ouverte"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "État maximisé de la dernière fenêtre principale ouverte"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Activer ou désactiver le thème sombre"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Indique s’il faut actualiser périodiquement le contenu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr ""
"Nombre de périodes de délais à attendre entre les actualisations automatiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Délai entre les actualisations automatiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Indique s’il faut actualiser le contenu au démarrage"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Nombre de périodes de délai entre les nettoyages automatiques"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Délai entre les nettoyages automatiques"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:416
#: podcasts-gtk/src/widgets/aboutdialog.rs:37
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Écouter vos podcasts favoris directement sur votre bureau."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;Baladodiffusion;Émissions;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Application de podcast pour GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:68
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Cette émission n’a pas encore d’épisodes"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Si vous pensez qu’il s’agit d’une erreur, faites un rapport de bogue."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Obtenir des émissions"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Ajouter de nouvelles émissions via une URL de flux"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importer des émissions à partir d’un autre appareil"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Calcul de la taille de l’épisode…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Lire cet épisode"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Annuler le téléchargement"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Télécharger cet épisode"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Chercher de nouveaux épisodes"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importer les émissions"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Préférences"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Raccourcis clavier"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "À _propos de Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Ajouter un nouveau flux"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Entrer l’adresse du flux à ajouter"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Ajouter"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Vous êtes déjà abonné à ce flux !"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Titre de l’émission"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Retour"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Général"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Chercher de nouveaux épisodes"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Préférences"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Quitter l’application"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Aujourd’hui"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Hier"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Cette semaine"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Ce mois-ci"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Plus ancien"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Une notification d’action intégrée à l’application"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Annuler"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Reculer de 10 secondes"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Lire"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pause"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Avancer de 10 secondes"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Changer la vitesse de lecture"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "Débit × 1,5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "Débit × 1,25"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Vitesse normale"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Préférences"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Apparence"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Thème sombre"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Supprimer les épisodes lus"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Après"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Marquer tous les épisodes comme lus"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "Site _Web"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "Se _désabonner"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Aller sur le site Web"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Marquer tout comme lu"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Se désabonner"
#: podcasts-gtk/src/app.rs:333
msgid "Fetching new episodes"
msgstr "Récupérer les nouveaux épisodes"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Vous êtes déjà abonné à cette émission"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "URL non valide"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "Secondes"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minutes"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Heures"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Jours"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Semaines"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Nouveau"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Émissions"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Sélectionnez le fichier à partir duquel importer les émissions."
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "_Importer"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "Fichier OPML"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "Échec de l’analyse du fichier importé"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "Le fichier sélectionné n’est pas accessible."
#: podcasts-gtk/src/widgets/aboutdialog.rs:32
msgid "Podcast Client for the GNOME Desktop."
msgstr "Client de podcast pour le bureau GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:39
msgid "Learn more about GNOME Podcasts"
msgstr "En apprendre plus sur GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:44
msgid "translator-credits"
msgstr "Alexandre Franke"
#: podcasts-gtk/src/widgets/episode.rs:130
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:365
msgid "The media player was unable to execute an action."
msgstr "Le lecteur n’a pas pu réaliser l’action."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "Marquer tous les épisodes comme écoutés"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Se désabonner de {}"
+404
View File
@@ -0,0 +1,404 @@
# Friulian translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Fabio Tomat <f.t.public@gmail.com>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-09-03 13:42+0000\n"
"PO-Revision-Date: 2018-09-04 20:17+0200\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Last-Translator: \n"
"X-Generator: Poedit 2.0.7\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Posizion superiôr dal ultin barcon principâl viert"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Posizion de çampe dal ultin barcon principâl viert"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Altece dal ultin barcon principâl viert"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Largjece dal ultin barcon principâl viert"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Stât slargjât dal ultin barcon principâl viert"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Abilite o disabilite il teme scûr"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Indiche se inzornâ in maniere periodiche il contignût"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Trops periodis di timp di spietâ tra i inzornaments automatics"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Ce periodi di timp di spietâ tra i inzornaments automatics"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Indiche se inzornâ il contignût dopo dal inviament"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Trops periodis di timp di spietâ tra lis netisiis automatichis"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Ce periodi di timp di spietâ tra lis netisiis automatichis"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:91 podcasts-gtk/src/app.rs:414
#: podcasts-gtk/src/widgets/aboutdialog.rs:31
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Scolte i tiei podcast preferîts, daurman dal to scritori."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;Regjistrazion;Trasmission;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Aplicazion podcast par GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:51
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Chest spetacul nol à ancjemò episodis"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Se tu pensis che chest al sedi un erôr, considere di scrivi une segnalazion di erôr."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Oten cualchi spetacul"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Zonte gnûfs spetacui vie URL di feed"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Impuarte i spetacui di un altri dispositîf"
#: podcasts-gtk/resources/gtk/episode_widget.ui:178
msgid "Calculating episode size…"
msgstr "Calcul de dimension dal episodi…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:214
msgid "Cancel"
msgstr "Anule"
#: podcasts-gtk/resources/gtk/episode_widget.ui:232
msgid "Download this episode"
msgstr "Discjarie chest episodi"
#: podcasts-gtk/resources/gtk/episode_widget.ui:256
msgid "Play this episode"
msgstr "Viôt chest episodi"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Controle par gnûfs episodis"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Impuarte spetacui"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Preferencis"
#: podcasts-gtk/resources/gtk/hamburger.ui:29
msgid "_Keyboard Shortcuts"
msgstr "_Scurtis tastiere"
#: podcasts-gtk/resources/gtk/hamburger.ui:37
msgid "_About"
msgstr "_Informazions"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Zonte un gnûf feed"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Inserìs la direzion dal feed di zontâ"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Zonte"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Tu sês za sotscrit a chest feed!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Titul dal spetacul"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Indaûr"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Gjenerâl"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Controle se a son gnûfs episodis"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferencis"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Jes de aplicazion"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Vuê"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Îr"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Cheste setemane"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Chest mês"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Plui vecjo"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Une notifiche di aplicazion in-app"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Disfe"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Torne indaûr di 10 seconts"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Riprodûs"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pause"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Va indenant di 10 minûts"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Cambie la velocitât di riproduzion"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1.00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1.50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "rapuart di velocitât 1.5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1.25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "rapuart di velocitât 1.25"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Velocitât normâl"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferencis"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Aspiet"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Teme scûr"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Elimine i episodis viodûts"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Dopo"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Segne ducj i episodis come viodûts"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "Sît _web"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Anule sotscrizion"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Vierç sît web"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Segne dut come viodût"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Anule sotscrizion"
#: podcasts-gtk/src/app.rs:332
msgid "Fetching new episodes"
msgstr "Daûr a recuperâ i gnûfs episodis"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Tu sês za sotscrit a chest spetacul"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "URL no valit"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "Seconts"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minûts"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Oris"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Diis"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Setemanis"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Gnûf"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Spetacui"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Selezione il file che di chei si desidere impuartâ i spetacui."
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "_Impuarte"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "File OPML"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "No si è rivâts a analizâ il file impuartât"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "Il file selezionât nol pues jessi doprât."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26
msgid "Podcast Client for the GNOME Desktop."
msgstr "Client podcast pal scritori GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:33
msgid "Learn more about GNOME Podcasts"
msgstr "Plui informazions su GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:38
msgid "translator-credits"
msgstr "Fabio Tomat <f.t.public@gmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:129
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301
msgid "The media player was unable to execute an action."
msgstr "Il riprodutôr multimediâl nol è stât bon di eseguî une azion."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "Segnât ducj i episodis come scoltâts"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Sotscrizion anulade di {}"
+426
View File
@@ -0,0 +1,426 @@
# Croatian translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-06-15 10:55+0000\n"
"PO-Revision-Date: 2019-06-22 22:30+0200\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 2.2.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Gornji položaj posljednjeg otvorenog prozora"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Lijevi položaj posljednjeg otvorenog prozora"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Visina posljednjeg otvorenog prozora"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Širina posljednjeg otvorenog prozora"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Stanje uvećanja posljednjeg otvorenog prozora"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Omogući ili onemogući tamnu temu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Treba li povremeno osvježiti sadržaj"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr ""
"Koliko vremenskih razdoblja treba pričekati između automatskih osvježavanja"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr ""
"Koliko vremensko razdoblje treba pričekati između automatskih osvježavanja"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Treba li osvježiti sadržaj nakon pokretanja"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr ""
"Koliko vremenskih razdoblja treba pričekati između automatskih čišćenja"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Koliko vremensko razdoblje treba pričekati između automatskih čišćenja"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcasti"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Slušajte svoje omiljene podcaste."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast aplikacija za GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Ova emisjia još nema epizoda"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Ako mislite da je ovo greška, prijavite izvještaj greške."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Nabavite nove emisije"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Dodaj novu emisiju putem kanala ili URL-a"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Uvezi emisije iz drugog uređaja"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Već ste poslušali ovu epizodu."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Izračunavanje veličine emisjie…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Slušaj ovu epizodu"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Prekini preuzimanja"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Preuzmi ovu epizodu"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Provjeri ima li novih epizoda"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Uvezi emisije"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Izvezi emisije"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "_Prečaci tipkovnice"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "_O Podcasti"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed"
msgstr "Dodaj novi kanal"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Upišite adresu kanala za dodavanje"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Dodaj"
#: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "Show Title"
msgstr "Prikaži naslov"
#: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back"
msgstr "Natrag"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Općenito"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Provjeri ima li novih epizoda"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Zatvori aplikaciju"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Danas"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Jučer"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Ovaj tjedan"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Ovaj mjesec"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Starije"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Obavijesti radnja iz aplikacije"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Vrati"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Premotaj 10 sekundi"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Reproduciraj"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pauziraj"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Brzo premotaj 10 sekundi"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Promijeni brzinu reprodukcije"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1.00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1.50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1.5 brže"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1.25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1.25 brže"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normalna brzina"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Označi se epizode kao odslušane"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Web stranica"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Ukini pretplatu"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Otvori web stranicu"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Označi sve kao odslušano"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Ukini pretplatu"
#: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes"
msgstr "Preuzimanje novi epizoda"
#: podcasts-gtk/src/headerbar.rs:127
msgid "You are already subscribed to this show"
msgstr "Već ste pretplaćeni na ovu emisiju"
#: podcasts-gtk/src/headerbar.rs:145
msgid "Invalid URL"
msgstr "Nevažeći URL"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Novo"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Emisije"
#: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows."
msgstr "Odaberite datoteku iz koje želite uvesti emisije."
#: podcasts-gtk/src/utils.rs:400
msgid "_Import"
msgstr "_Uvoz"
#: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file"
msgstr "OPML datoteka"
#: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file"
msgstr "Neuspjela obrada uvezene datoteke"
#: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed."
msgstr "Nemoguć pristup dabranoj datoteci."
#: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "_Izvezi emisije u…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Uvoz"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Odustani"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcast pretplate"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Neuspjeli uvoz podcasta"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast klijent za GNOME radnu površinu."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Saznajte više o GNOME Podcasti"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr ""
"Launchpad Contributions:\n"
" gogo https://launchpad.net/~trebelnik-stefina"
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action."
msgstr "Medijski reproduktor nije uspio izvršiti radnju."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Označi sve epizodae kao odslušane"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Ukini pretplatu za {}"
#~ msgid "_Preferences"
#~ msgstr "_Osobitosti"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "Već ste pretplaćeni na ovaj kanal!"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Osobitosti"
#~ msgid "Preferences"
#~ msgstr "Osobitosti"
#~ msgid "Appearance"
#~ msgstr "Izgled"
#~ msgid "Dark Theme"
#~ msgstr "Tamna tema"
#~ msgid "Delete played episodes"
#~ msgstr "Obriši poslušane epizode"
#~ msgid "After"
#~ msgstr "Poslije"
#~ msgid "Seconds"
#~ msgstr "Sekunda"
#~ msgid "Minutes"
#~ msgstr "Minuta"
#~ msgid "Hours"
#~ msgstr "Sata"
#~ msgid "Days"
#~ msgstr "Dana"
#~ msgid "Weeks"
#~ msgstr "Tjedana"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_About"
#~ msgstr "_O programu"
+380
View File
@@ -0,0 +1,380 @@
# Hungarian translation for podcasts.
# Copyright (C) 2018, 2019. Free Software Foundation, Inc.
# This file is distributed under the same license as the podcasts package.
#
# Meskó Balázs <mesko.balazs at fsf dot hu>, 2018.
# Balázs Úr <ur.balazs at fsf dot hu>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-05-18 12:55+0000\n"
"PO-Revision-Date: 2019-06-03 22:27+0200\n"
"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 18.12.3\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "A legutóbbi nyitott főablak fenti pozíciója"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "A legutóbbi nyitott főablak bal oldali pozíciója"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "A legutóbbi nyitott főablak magassága"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "A legutóbbi nyitott főablak szélessége"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "A legutóbbi nyitott főablak maximalizálási állapota"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Sötét téma engedélyezése vagy letiltása"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Időközönként frissüljön-e a tartalom"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Mennyi időközt várjon az automatikus frissítések között"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Milyen időközöket várjon az automatikus frissítések között"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Indításkor frissüljön-e a tartalom"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Mennyi időközt várjon az automatikus tisztítások között"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Milyen időközöket várjon az automatikus tisztítások között"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcastok"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Hallgassa kedvenc podcastjait, közvetlenül az asztalán."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast alkalmazás a GNOME-hoz"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Ennek a műsornak még nincsenek epizódjai"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Ha úgy gondolja hogy ez hiba, akkor írjon egy hibajelentést."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Szerezzen be néhány műsort"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Új műsorok hozzáadása csatorna URL-ből"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Műsorok importálása egy másik eszközről"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
#| msgid "You are already subscribed to this show"
msgid "You’ve already listened to this episode."
msgstr "Már meghallgatta ezt az epizódot."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Epizódméret kiszámítása…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Ezen epizód lejátszása"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "A letöltési folyamat megszakítása"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Ezen epizód letöltése"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "Új epizódok _keresése"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "Műsorok _importálása"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "Műsorok _exportálása"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "Gyorsbille_ntyűk"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "A Podcastok _névjegye"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Új csatorna hozzáadása"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Adja meg a hozzáadandó csatorna címét"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Hozzáadás"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Már feliratkozott erre a csatornára."
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Műsor címe"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Vissza"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Általános"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Új epizódok keresése"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Kilépés az alkalmazásból"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Ma"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Tegnap"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Ezen a héten"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Ebben a hónapban"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Régebbi"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Alkalmazáson belüli műveletértesítések"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Visszavonás"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Visszatekerés 10 másodperccel"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Lejátszás"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Szünet"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Előretekerés 10 másodperccel"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Lejátszási sebesség módosítása"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5-szeres sebesség"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25-szörös sebesség"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normál sebesség"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "Összes epizód meg_jelölése lejátszottként"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Webhely"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Leiratkozás"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Webhely megnyitása"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Összes megjelölése lejátszottként"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Leiratkozás"
#: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes"
msgstr "Új epizódok lekérése"
#: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show"
msgstr "Már feliratkozott erre a műsorra"
#: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL"
msgstr "Érvénytelen URL"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Új"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Műsorok"
#: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows."
msgstr "Válasszon egy fájlt, amelyből műsorokat akar importálni."
#: podcasts-gtk/src/utils.rs:400
msgid "_Import"
msgstr "_Importálás"
#: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file"
msgstr "OPML fájl"
#: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file"
msgstr "Az importált fájl feldolgozása meghiúsult"
#: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed."
msgstr "A kiválasztott fájlok nem érhetőek el."
#: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Műsorok exportálása ide…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Exportálás"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Mégse"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcastok feliratkozások"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "A podcastok exportálása meghiúsult"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcast-kliens a GNOME asztali környezethez."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "További tudnivalók a GNOME Podcastokról"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr "Meskó Balázs <mesko dot balazs at fsf dot hu>"
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} perc"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action."
msgstr "A médialejátszó nem tudott végrehajtani egy műveletet."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Összes epizód megjelölve meghallgatottként"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Leiratkozott innen: {}"
+119 -102
View File
@@ -1,21 +1,21 @@
# Indonesian translation for podcasts. # Indonesian translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER # Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package. # This file is distributed under the same license as the podcasts package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2018, 2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: podcasts master\n" "Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-30 08:45+0000\n" "POT-Creation-Date: 2019-06-15 10:55+0000\n"
"PO-Revision-Date: 2018-08-30 17:37+0700\n" "PO-Revision-Date: 2019-07-11 15:21+0700\n"
"Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n" "Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n" "Language: id\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n" "X-Generator: Poedit 2.2.3\n"
"X-Generator: Poedit 2.0.6\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window" msgid "Top position of the last open main window"
@@ -68,8 +68,8 @@ msgstr "Berapa lama waktu untuk menunggu di antara pembersihan otomatis"
#. Weird magic I copy-pasted that sets the Application Name in the Shell. #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:91 podcasts-gtk/src/app.rs:414 #: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:31 #: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcast" msgstr "Podcast"
@@ -78,11 +78,6 @@ msgstr "Podcast"
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Dengarkan podcast favorit Anda, langsung dari destop Anda." msgstr "Dengarkan podcast favorit Anda, langsung dari destop Anda."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
@@ -92,7 +87,7 @@ msgstr "Podcast;RSS;"
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "Aplikasi Podcast untuk GNOME" msgstr "Aplikasi Podcast untuk GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis" msgstr "Jordan Petridis"
@@ -102,7 +97,9 @@ msgstr "Acara ini belum memiliki episode"
#: podcasts-gtk/resources/gtk/empty_view.ui:62 #: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
msgstr "Jika Anda pikir ini adalah kesalahan, silakan mempertimbangkan untuk menulis laporan kutu." msgstr ""
"Jika Anda pikir ini adalah kesalahan, silakan mempertimbangkan untuk menulis "
"laporan kutu."
#: podcasts-gtk/resources/gtk/empty_view.ui:106 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
@@ -116,22 +113,26 @@ msgstr "Tambahkan acara baru melalui URL feed"
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Impor acara dari perangkat lain" msgstr "Impor acara dari perangkat lain"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Anda sudah mendengarkan episode ini."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Menghitung ukuran episode…" msgstr "Menghitung ukuran episode…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Cancel"
msgstr "Batal"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Unduh episode ini"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Putar episode ini" msgstr "Putar episode ini"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Batalkan proses pengunduhan"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Unduh episode ini"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "Periksa Episode _Baru" msgstr "Periksa Episode _Baru"
@@ -140,20 +141,20 @@ msgstr "Periksa Episode _Baru"
msgid "_Import Shows" msgid "_Import Shows"
msgstr "_Impor Acara" msgstr "_Impor Acara"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Preferences" msgid "_Export Shows"
msgstr "_Preferensi" msgstr "_Ekspor Acara"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "Pintasan Papan _Ketik" msgstr "Pintasan Papan _Ketik"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About" msgid "_About Podcasts"
msgstr "Tent_ang" msgstr "Tent_ang Podcast"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189 #: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed" msgid "Add a new feed"
msgstr "Tambahkan feed baru" msgstr "Tambahkan feed baru"
@@ -165,15 +166,11 @@ msgstr "Masukkan alamat feed untuk ditambahkan"
msgid "Add" msgid "Add"
msgstr "Tambah" msgstr "Tambah"
#: podcasts-gtk/resources/gtk/headerbar.ui:133 #: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "You are already subscribed to that feed!"
msgstr "Anda sudah berlangganan feed itu!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title" msgid "Show Title"
msgstr "Tampilkan Judul" msgstr "Tampilkan Judul"
#: podcasts-gtk/resources/gtk/headerbar.ui:210 #: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back" msgid "Back"
msgstr "Kembali" msgstr "Kembali"
@@ -188,11 +185,6 @@ msgstr "Periksa episode baru"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25 #: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferensi"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application" msgid "Quit the application"
msgstr "Keluar dari aplikasi" msgstr "Keluar dari aplikasi"
@@ -269,27 +261,6 @@ msgstr "tingkat kecepatan 1.25"
msgid "Normal speed" msgid "Normal speed"
msgstr "Kecepatan normal" msgstr "Kecepatan normal"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferensi"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Penampilan"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tema Gelap"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Hapus episode yang diputar"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Sesudah"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7 #: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played" msgid "_Mark All Episodes as Played"
msgstr "Tandai Se_mua Episode sebagai Sudah Diputar" msgstr "Tandai Se_mua Episode sebagai Sudah Diputar"
@@ -314,91 +285,137 @@ msgstr "Tandai Semua sebagai Sudah Diputar"
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Berhenti Berlangganan" msgstr "Berhenti Berlangganan"
#: podcasts-gtk/src/app.rs:332 #: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Mengambil episode baru" msgstr "Mengambil episode baru"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:127
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Anda sudah berlangganan ke acara ini" msgstr "Anda sudah berlangganan ke acara ini"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:145
msgid "Invalid URL" msgid "Invalid URL"
msgstr "URL tak valid" msgstr "URL tak valid"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/stacks/content.rs:54
msgid "Seconds"
msgstr "Detik"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Menit"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Jam"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Hari"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Minggu"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New" msgid "New"
msgstr "Baru" msgstr "Baru"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Acara" msgstr "Acara"
#: podcasts-gtk/src/utils.rs:357 #: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Pilih berkas dari mana Anda ingin mengimpor acara." msgstr "Pilih berkas dari mana Anda ingin mengimpor acara."
#: podcasts-gtk/src/utils.rs:360 #: podcasts-gtk/src/utils.rs:400
msgid "_Import" msgid "_Import"
msgstr "_Impor" msgstr "_Impor"
#: podcasts-gtk/src/utils.rs:369 #: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file" msgid "OPML file"
msgstr "Berkas OPML" msgstr "Berkas OPML"
#: podcasts-gtk/src/utils.rs:386 #: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "Gagal mengurai berkas yang diimpor" msgstr "Gagal mengurai berkas yang diimpor"
#: podcasts-gtk/src/utils.rs:391 #: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "Berkas yang dipilih tidak dapat diakses." msgstr "Berkas yang dipilih tidak dapat diakses."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Ekspor acara ke…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Ekspor"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Batal"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Berlangganan GNOME Podcast"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Gagal mengekspor podcast"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "Klien Podcast untuk Destop GNOME." msgstr "Klien Podcast untuk Destop GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "Pelajari lebih lanjut tentang GNOME Podcast" msgstr "Pelajari lebih lanjut tentang GNOME Podcast"
#: podcasts-gtk/src/widgets/aboutdialog.rs:38 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2018." msgstr "Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2018, 2019."
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min" msgid "{} min"
msgstr "{} mnt" msgstr "{} mnt"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "Pemutar media tidak dapat melakukan aksi." msgstr "Pemutar media tidak dapat melakukan aksi."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Tandai semua episode sebagai sudah didengarkan" msgstr "Tandai semua episode sebagai sudah didengarkan"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "Berhenti berlangganan dari {}" msgstr "Berhenti berlangganan dari {}"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "_Preferensi"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "Anda sudah berlangganan feed itu!"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Preferensi"
#~ msgid "Preferences"
#~ msgstr "Preferensi"
#~ msgid "Appearance"
#~ msgstr "Penampilan"
#~ msgid "Dark Theme"
#~ msgstr "Tema Gelap"
#~ msgid "Delete played episodes"
#~ msgstr "Hapus episode yang diputar"
#~ msgid "After"
#~ msgstr "Sesudah"
#~ msgid "Seconds"
#~ msgstr "Detik"
#~ msgid "Minutes"
#~ msgstr "Menit"
#~ msgid "Hours"
#~ msgstr "Jam"
#~ msgid "Days"
#~ msgstr "Hari"
#~ msgid "Weeks"
#~ msgstr "Minggu"
#~ msgid "_About"
#~ msgstr "Tent_ang"
+432
View File
@@ -0,0 +1,432 @@
# Italian translation for podcasts.
# Copyright (C) 2018, 2019 podcasts's Free Software Foundation, Inc.
# This file is distributed under the same license as the podcasts package.
# Milo Casagrande <milo@milo.name>, 2018, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-02-02 15:17+0000\n"
"PO-Revision-Date: 2019-02-28 09:25+0100\n"
"Last-Translator: Milo Casagrande <milo@milo.name>\n"
"Language-Team: Italian <gnome-it-list@gnome.org>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Posizione superiore dell'ultima finestra principale aperta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Posizione sinistra dell'ultima finestra principale aperta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Altezza dell'ultima finestra principale aperta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Larghezza dell'ultima finestra principale aperta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Stato di massimizzazione dell'ultima finestra principale aperta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Abilita/Disabilita il tema scuro"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Indica se aggiornare i contenuti periodicamente"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Quanto tempo aspettare tra gli aggiornamenti automatici"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Che periodo di tempo aspettare tra gli aggiornamenti automatici"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Indica se aggiornare i contenuti dopo l'avvio"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Quanto tempo aspettare tra la pulizia automatica"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Che periodi di tempo aspettare tra la pulizia automatica"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:124 podcasts-gtk/src/app.rs:455
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcast"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Ascoltare i propri podcast preferiti, direttamente proprio computer."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Applicazione per podcast per GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Questo show non ha ancora episodi"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Se considerate questo evento un errore, inviare una segnalazione."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Ottieni show"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Aggiungi nuovi show via URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importa show da un altro dispositivo"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Calcolo dimensione episodio…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Riproduci questo episodio"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Annulla lo scaricamento"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Scarica questo episodio"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "Controlla per _nuovi episodi"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importa show"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Esporta show"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "Preferen_ze"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Scorciatoie da tastiera"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "I_nformazioni su Podcast"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Aggiungi nuovo feed"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Inserire un indirizzo da aggiungere"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Aggiungi"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Si è già abbonati a questo feed."
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Titolo show"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Indietro"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Generale"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Controlla presenza nuovi episodi"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferenze"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Esce dall'applicazione"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Oggi"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Ieri"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Questa settimana"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Questo mese"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Più vecchi"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Una notifica"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Annulla"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Indietro 10 secondi"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Riproduci"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pausa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Avanti veloce 10 secondi"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Modifica la velocità di riproduzione"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 volte la velocità"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 volte la velocità"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Velocità normale"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferenze"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Aspetto"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tema scuro"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Eliminare episodi ascoltati"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Dopo"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Segna tutti gli episodi come ascoltati"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "Sito _web"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Annulla abbonamento"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Apri sito web"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Segna tutti ascoltati"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Annulla abbonamento"
#: podcasts-gtk/src/app.rs:369
msgid "Fetching new episodes"
msgstr "Scaricamento nuovi episodi"
#: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show"
msgstr "Si è già abbonati a questo show"
#: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL"
msgstr "URL non valido"
#: podcasts-gtk/src/prefs.rs:78
msgid "Seconds"
msgstr "Secondi"
#: podcasts-gtk/src/prefs.rs:79
msgid "Minutes"
msgstr "Minuti"
#: podcasts-gtk/src/prefs.rs:80
msgid "Hours"
msgstr "Ore"
#: podcasts-gtk/src/prefs.rs:81
msgid "Days"
msgstr "Giorni"
#: podcasts-gtk/src/prefs.rs:82
msgid "Weeks"
msgstr "Settimane"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Nuovo"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Show"
#: podcasts-gtk/src/utils.rs:377
msgid "Select the file from which to you want to import shows."
msgstr "Selezionare il file da cui importare gli show."
#: podcasts-gtk/src/utils.rs:380
msgid "_Import"
msgstr "_Importa"
#: podcasts-gtk/src/utils.rs:389 podcasts-gtk/src/utils.rs:435
msgid "OPML file"
msgstr "File OPML"
#: podcasts-gtk/src/utils.rs:406
msgid "Failed to parse the imported file"
msgstr "Analisi del file importato non riuscita"
#: podcasts-gtk/src/utils.rs:411 podcasts-gtk/src/utils.rs:453
msgid "Selected file could not be accessed."
msgstr "Impossibile accedere al file selezionato."
#: podcasts-gtk/src/utils.rs:423
msgid "Export shows to…"
msgstr "Esporta show su…"
#: podcasts-gtk/src/utils.rs:426
msgid "_Export"
msgstr "_Esporta"
#: podcasts-gtk/src/utils.rs:427
msgid "_Cancel"
msgstr "A_nnulla"
#: podcasts-gtk/src/utils.rs:447
msgid "GNOME Podcasts Subscriptions"
msgstr "Abbonamenti Podcast GNOME"
#: podcasts-gtk/src/utils.rs:448
msgid "Failed to export podcasts"
msgstr "Esportazioni podcast non riuscita"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Client podcast per l'ambiente grafico GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Maggiori informazioni su Podcast GNOME"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr "Milo Casagrande <milo@milo.name>"
#: podcasts-gtk/src/widgets/episode.rs:149
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:536
msgid "The media player was unable to execute an action."
msgstr "Il riproduttore multimediale non può eseguire un'azione."
#: podcasts-gtk/src/widgets/show_menu.rs:169
msgid "Marked all episodes as listened"
msgstr "Episodi segnati come letti"
#: podcasts-gtk/src/widgets/show_menu.rs:174
msgid "Unsubscribed from {}"
msgstr "Abbonamento a {} annullato"
#~ msgid "_About"
#~ msgstr "I_nformazioni"
+407
View File
@@ -0,0 +1,407 @@
# Latvian translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
#
# Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-09-10 07:51+0000\n"
"PO-Revision-Date: 2018-09-10 20:15+0200\n"
"Last-Translator: Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>\n"
"Language-Team: Latvian <lata-l10n@googlegroups.com>\n"
"Language: lv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :"
" 2);\n"
"X-Generator: Lokalize 2.0\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Augšējais novietojums pēdējam atvērtajam galvenajam logam"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Kreisais novietojums pēdējam atvērtajam galvenajam logam"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Pēdējā atvērtā galvenā loga augstums"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Pēdējā atvērtā galvenā loga platums"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Pēdējā atvērtā galvenā loga maksimizēšanas stāvoklis"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Ieslēgt vai izslēgt tumšo motīvu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Vai ik pa laikam atsvaidzināt saturu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Cik laika periodus gaidīt starp automātisko atsvaidzināšanu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Cik ilgi gaidīt starp automātisko atsvaidzināšanu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Vai atsvaidzināt saturu pēc palaišanas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Cik laika periodus gaidīt starp automātisko uzkopšanu"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Cik ilgi gaidīt starp automātisko uzkopšanu"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:91 podcasts-gtk/src/app.rs:414
#: podcasts-gtk/src/widgets/aboutdialog.rs:31
msgid "Podcasts"
msgstr "Podraides"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Klausieties savas iecienītās podraides savā darbvirsmā."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Aplāde;Podraide;Podkāsts;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podraižu lietotne GNOME videi"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:51
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Šim raidījumam vēl nav epizožu"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Ja domājat, ka šī ir kļūda, apsveriet sūtīt kļūdas ziņojumu."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Tikt pie dažiem raidījumiem"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Pievienojiet jaunus raidījumus ar plūsmu URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importēt raidījumus no citas ierīces"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Aprēķina epizodes izmēru…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Atskaņot šo epizodi"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download proccess"
msgstr "Atcelt lejupielādēšanu"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Lejupielādēt šo epizodi"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "Pārbaudīt jau_nos raidījumus"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importēt raidījumus"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Iestatījumi"
#: podcasts-gtk/resources/gtk/hamburger.ui:29
msgid "_Keyboard Shortcuts"
msgstr "_Tastatūras īsinājumtaustiņi"
#: podcasts-gtk/resources/gtk/hamburger.ui:37
msgid "_About"
msgstr "P_ar"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Pievienot jaunu plūsmu"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Ievadiet pievienojamās plūsmas adresi"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Pievienot"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Jūs jau esat abonējis šo plūsmu!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Rādīt virsrakstu"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Atpakaļ"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Vispārīgi"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Pārbaudīt jaunos raidījumus"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Iestatījumi"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Iziet no lietotnes"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Šodien"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Vakar"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Šonedēļ"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Šomēnes"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Vecākas"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Paziņojumi lietotnē"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Atsaukt"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Attīt 10 sekundes"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Atskaņot"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pauzēt"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Patīt uz priekšu 10 sekundes"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Mainīt atskaņošanas ātrumu"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 ātrums"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 ātrums"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normāls ātrums"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Iestatījumi"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Izskats"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tumšais motīvs"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Dzēst atskaņotās epizodes"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Pēc"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "Atzī_mēt visas epizodes kā atskaņotas"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Tīmekļa vietne"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "An_ulēt abonementu"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Atvērt tīmekļa vietni"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Atzīmēt visu kā atskaņotu"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Anulēt abonementu"
#: podcasts-gtk/src/app.rs:332
msgid "Fetching new episodes"
msgstr "Saņem jaunas epizodes"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Jūs jau esat abonējis šo raidījumu"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "Nederīgs URL"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "Sekundes"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minūtes"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Stundas"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Dienas"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Nedēļas"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Jauns"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Raidījumi"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Izvēlieties datni, no kuras vēlaties importēt raidījumus."
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "_Importēt"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "OPML datne"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "Neizdevās parsēt importēto datni"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "Nevarēja piekļūt izvēlētajai datnei."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podraižu klients GNOME darbvirsmai."
#: podcasts-gtk/src/widgets/aboutdialog.rs:33
msgid "Learn more about GNOME Podcasts"
msgstr "Uzziniet vairāk par GNOME podraidēm"
#: podcasts-gtk/src/widgets/aboutdialog.rs:38
msgid "translator-credits"
msgstr "Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:130
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301
msgid "The media player was unable to execute an action."
msgstr "Mediju atskaņotājs nevarēja izpildīt darbību."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "Visas epizodes ir atzīmētas kā noklausītas"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Anulēt abonementu"
+432
View File
@@ -0,0 +1,432 @@
# Dutch translation for podcasts.
# Copyright (C) 2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Nathan Follens <nthn@unseen.is>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-02-02 15:17+0000\n"
"PO-Revision-Date: 2019-02-26 12:47+0100\n"
"Last-Translator: Nathan Follens <nthn@unseen.is>\n"
"Language-Team: Dutch <gnome-nl-list@gnome.org>\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2.1\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Toppositie van laatst geopend hoofdvenster"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Linkerpositie van laatst geopend hoofdvenster"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Hoogte van laatst geopend hoofdvenster"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Breedte van laatst geopend hoofdvenster"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Gemaximaliseerde status van laatst geopend hoofdvenster"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Donker thema in- of uitschakelen"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Of inhoud automatisch vernieuwd moet worden"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Hoeveel tijd te wachten tussen automatisch vernieuwen"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Hoe lang te wachten tussen automatisch vernieuwen"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Of inhoud vernieuwd moet worden na opstarten"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Hoeveel tijd te wachten tussen automatische opruimbeurten"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Hoe lang te wachten tussen automatische opruimbeurten"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:124 podcasts-gtk/src/app.rs:455
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Luister naar uw favoriete podcasts, rechtstreeks vanop uw bureaublad."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Podcast-toepassing voor Gnome"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Deze show heeft nog geen afleveringen"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Als u denkt dat dit een fout is, overweeg dan een foutmelding in te dienen."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Haal enkele shows op"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Nieuwe shows toevoegen via feed-URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Shows importeren van een ander apparaat"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Grootte van aflevering berekenen…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Deze aflevering afspelen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Downloadproces annuleren"
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Deze aflevering downloaden"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Controleren op nieuwe afleveringen"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "Shows _importeren"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "Shows _exporteren"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Voorkeuren"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Sneltoetsen"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "_Over Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Nieuwe feed toevoegen"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Voer het toe te voegen feedadres in"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Toevoegen"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "U bent reeds geabonneerd op die feed!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Titel tonen"
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Terug"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Algemeen"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Controleren op nieuwe afleveringen"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Voorkeuren"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "De toepassing afsluiten"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Vandaag"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Gisteren"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Deze week"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Deze maand"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Ouder"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Een in-app-actiemelding"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Ongedaan maken"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "10 seconden terugspoelen"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Afspelen"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pauzeren"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "10 seconden doorspoelen"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "De afspeelsnelheid wijzigen"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 snelheid"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 snelheid"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normale snelheid"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Voorkeuren"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Uiterlijk"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Donker thema"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Afgespeelde afleveringen verwijderen"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Na"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "Alle afleveringen _markeren als afgespeeld"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Website"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "_Opzeggen"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Website openen"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Alles markeren als afgespeeld"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Opzeggen"
#: podcasts-gtk/src/app.rs:369
msgid "Fetching new episodes"
msgstr "Nieuwe afleveringen worden opgehaald"
#: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show"
msgstr "U bent reeds geabonneerd op deze show"
#: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL"
msgstr "Ongeldige URL"
#: podcasts-gtk/src/prefs.rs:78
msgid "Seconds"
msgstr "Seconden"
#: podcasts-gtk/src/prefs.rs:79
msgid "Minutes"
msgstr "Minuten"
#: podcasts-gtk/src/prefs.rs:80
msgid "Hours"
msgstr "Uur"
#: podcasts-gtk/src/prefs.rs:81
msgid "Days"
msgstr "Dagen"
#: podcasts-gtk/src/prefs.rs:82
msgid "Weeks"
msgstr "Weken"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Nieuw"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Shows"
#: podcasts-gtk/src/utils.rs:377
msgid "Select the file from which to you want to import shows."
msgstr "Selecteer het bestand waaruit u shows wilt importeren."
#: podcasts-gtk/src/utils.rs:380
msgid "_Import"
msgstr "_Importeren"
#: podcasts-gtk/src/utils.rs:389 podcasts-gtk/src/utils.rs:435
msgid "OPML file"
msgstr "OPML-bestand"
#: podcasts-gtk/src/utils.rs:406
msgid "Failed to parse the imported file"
msgstr "Verwerken van geïmporteerd bestand mislukt"
#: podcasts-gtk/src/utils.rs:411 podcasts-gtk/src/utils.rs:453
msgid "Selected file could not be accessed."
msgstr "Kon geen toegang verkrijgen tot geselecteerd bestand."
#: podcasts-gtk/src/utils.rs:423
msgid "Export shows to…"
msgstr "Shows exporteren naar…"
#: podcasts-gtk/src/utils.rs:426
msgid "_Export"
msgstr "_Exporteren"
#: podcasts-gtk/src/utils.rs:427
msgid "_Cancel"
msgstr "_Annuleren"
#: podcasts-gtk/src/utils.rs:447
msgid "GNOME Podcasts Subscriptions"
msgstr "Gnome Podcasts-abonnementen"
#: podcasts-gtk/src/utils.rs:448
msgid "Failed to export podcasts"
msgstr "Exporteren van podcasts mislukt"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Podcastcliënt voor het Gnome-bureaublad."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Kom meer te weten over Gnome Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr ""
"Nathan Follens <nthn@unseen.is>\n"
"\n"
"Meer info over Gnome-NL http://nl.gnome.org/"
#: podcasts-gtk/src/widgets/episode.rs:149
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:536
msgid "The media player was unable to execute an action."
msgstr "De mediaspeler kon een handeling niet uitvoeren."
#: podcasts-gtk/src/widgets/show_menu.rs:169
msgid "Marked all episodes as listened"
msgstr "Alle afleveringen markeren als beluisterd"
#: podcasts-gtk/src/widgets/show_menu.rs:174
msgid "Unsubscribed from {}"
msgstr "Abonnement op {} opgezegd"
+76 -103
View File
@@ -1,15 +1,15 @@
# Polish translation for podcasts. # Polish translation for podcasts.
# Copyright © 2018 the podcasts authors. # Copyright © 2018-2019 the podcasts authors.
# This file is distributed under the same license as the podcasts package. # This file is distributed under the same license as the podcasts package.
# Piotr Drąg <piotrdrag@gmail.com>, 2018. # Piotr Drąg <piotrdrag@gmail.com>, 2018-2019.
# Aviary.pl <community-poland@mozilla.org>, 2018. # Aviary.pl <community-poland@mozilla.org>, 2018-2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: podcasts\n" "Project-Id-Version: podcasts\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-22 05:29+0000\n" "POT-Creation-Date: 2019-05-18 12:55+0000\n"
"PO-Revision-Date: 2018-08-26 18:30+0200\n" "PO-Revision-Date: 2019-05-19 12:37+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n" "Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n" "Language: pl\n"
@@ -68,33 +68,28 @@ msgid "What period of time to wait between automatic cleanups"
msgstr "Jaki okres czekać między automatycznym czyszczeniem" msgstr "Jaki okres czekać między automatycznym czyszczeniem"
#. Weird magic I copy-pasted that sets the Application Name in the Shell. #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:406 #: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcasty" msgstr "Podcasty"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:10 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Słuchanie ulubionych podcastów prosto z komputera." msgstr "Słuchanie ulubionych podcastów prosto z komputera."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:6
msgid "org.gnome.Podcasts"
msgstr "org.gnome.Podcasts"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
msgstr "Podcast;Podkasty;RSS;Atom;" msgstr "Podcast;Podkasty;RSS;Atom;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:8 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "Aplikacja do słuchania podcastów w GNOME" msgstr "Aplikacja do słuchania podcastów w GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis" msgstr "Jordan Petridis"
@@ -106,34 +101,38 @@ msgstr "Ten program nie ma jeszcze odcinków"
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
msgstr "Jeśli to błąd, to prosimy go zgłosić." msgstr "Jeśli to błąd, to prosimy go zgłosić."
#: podcasts-gtk/resources/gtk/empty_view.ui:107 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
msgstr "Pobierz programy" msgstr "Pobierz programy"
#: podcasts-gtk/resources/gtk/empty_view.ui:144 #: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL" msgid "Add new shows via feed URL"
msgstr "Dodaj nowe programy za pomocą adresu kanału" msgstr "Dodaj nowe programy za pomocą adresu kanału"
#: podcasts-gtk/resources/gtk/empty_view.ui:173 #: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Zaimportuj programy z innego urządzenia" msgstr "Zaimportuj programy z innego urządzenia"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Ten odcinek został już odsłuchany"
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Obliczanie rozmiaru odcinka…" msgstr "Obliczanie rozmiaru odcinka…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Cancel"
msgstr "Anuluj"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Pobiera ten odcinek"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Odtwarza ten odcinek" msgstr "Odtwarza ten odcinek"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Anuluje pobieranie"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Pobiera ten odcinek"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "_Wyszukaj nowe odcinki" msgstr "_Wyszukaj nowe odcinki"
@@ -142,16 +141,16 @@ msgstr "_Wyszukaj nowe odcinki"
msgid "_Import Shows" msgid "_Import Shows"
msgstr "Zai_mportuj programy" msgstr "Zai_mportuj programy"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Preferences" msgid "_Export Shows"
msgstr "_Preferencje" msgstr "Wy_eksportuj programy"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "_Skróty klawiszowe" msgstr "_Skróty klawiszowe"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About" msgid "_About Podcasts"
msgstr "_O programie" msgstr "_O programie"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
@@ -190,11 +189,6 @@ msgstr "Wyszukanie nowych odcinków"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25 #: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Preferences"
msgstr "Preferencje"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application" msgid "Quit the application"
msgstr "Zakończenie działania programu" msgstr "Zakończenie działania programu"
@@ -271,27 +265,6 @@ msgstr "Prędkość 1,25"
msgid "Normal speed" msgid "Normal speed"
msgstr "Zwykła prędkość" msgstr "Zwykła prędkość"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Preferencje"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Wygląd"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Ciemny motyw"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Usuwanie odtworzonych odcinków"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Po"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7 #: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played" msgid "_Mark All Episodes as Played"
msgstr "_Oznacz wszystkie odcinki jako odtworzone" msgstr "_Oznacz wszystkie odcinki jako odtworzone"
@@ -316,93 +289,93 @@ msgstr "Oznacz wszystkie jako odtworzone"
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Zrezygnuj z subskrypcji" msgstr "Zrezygnuj z subskrypcji"
#: podcasts-gtk/src/app.rs:331 #: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Pobieranie nowych odcinków" msgstr "Pobieranie nowych odcinków"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:117
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Ten program jest już subskrybowany" msgstr "Ten program jest już subskrybowany"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:125
msgid "Invalid URL" msgid "Invalid URL"
msgstr "Nieprawidłowy adres" msgstr "Nieprawidłowy adres"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/stacks/content.rs:54
msgid "Seconds"
msgstr "Sekundy"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minuty"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Godziny"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Dni"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Tygodnie"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New" msgid "New"
msgstr "Nowe" msgstr "Nowe"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Programy" msgstr "Programy"
#: podcasts-gtk/src/utils.rs:350 #: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Proszę wybrać plik, z którego zaimportować programy." msgstr "Proszę wybrać plik, z którego zaimportować programy."
#: podcasts-gtk/src/utils.rs:353 #: podcasts-gtk/src/utils.rs:400
msgid "_Import" msgid "_Import"
msgstr "Zai_mportuj" msgstr "Zai_mportuj"
#: podcasts-gtk/src/utils.rs:362 #: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file" msgid "OPML file"
msgstr "Plik OPML" msgstr "Plik OPML"
#: podcasts-gtk/src/utils.rs:379 #: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "Przetworzenie zaimportowanego pliku się nie powiodło" msgstr "Przetworzenie zaimportowanego pliku się nie powiodło"
#: podcasts-gtk/src/utils.rs:384 #: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "Nie można uzyskać dostępu do wybranego pliku." msgstr "Nie można uzyskać dostępu do wybranego pliku."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Eksport programów do…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "Wy_eksportuj"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Anuluj"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Subskrypcje Podcastów GNOME"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Wyeksportowanie podcastów się nie powiodło"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "Klient podcastów dla środowiska GNOME." msgstr "Klient podcastów dla środowiska GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:35 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "Więcej informacji o Podcastach GNOME" msgstr "Więcej informacji o Podcastach GNOME"
#: podcasts-gtk/src/widgets/aboutdialog.rs:40 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "" msgstr ""
"Piotr Drąg <piotrdrag@gmail.com>, 2018\n" "Piotr Drąg <piotrdrag@gmail.com>, 2018-2019\n"
"Aviary.pl <community-poland@mozilla.org>, 2018" "Aviary.pl <community-poland@mozilla.org>, 2018-2019"
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min" msgid "{} min"
msgstr "{} min" msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "Odtwarzacz multimediów nie może wykonać działania." msgstr "Odtwarzacz multimediów nie może wykonać działania."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Oznaczono wszystkie odcinki jako odsłuchane" msgstr "Oznaczono wszystkie odcinki jako odsłuchane"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "Zrezygnowano z subskrypcji „{}”" msgstr "Zrezygnowano z subskrypcji „{}”"
+426
View File
@@ -0,0 +1,426 @@
# Brazilian Portuguese translation for podcasts.
# Copyright (C) 2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Yuri Otávio Lopes Gomes <yuriotavio@hotmail.com>, 2018.
# Rafael Fontenelle <rafaelff@gnome.org>, 2018-2019.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-06-09 02:38+0000\n"
"PO-Revision-Date: 2019-06-13 15:32-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Portuguese - Brazil <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 2.2.3\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Posição acima da janela da última principal aberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Posição à esquerda da última janela principal aberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Altura da última janela principal aberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Largura da última janela principal aberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Estado maximizado da última janela principal aberta"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Habilitar ou desabilitar o tema escuro"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Se deve atualizar periodicamente o conteúdo"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr ""
"Quantos períodos de tempo deve esperar entre as atualizações automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Qual período de tempo deve esperar entre as atualizações automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Se deve atualizar o conteúdo após a inicialização"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Quantos períodos de tempo deve esperar entre limpezas automáticas"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Qual período de tempo deve esperar entre limpezas automáticas"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Podcasts"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Ouça seus podcasts favoritos diretamente da sua área de trabalho."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Aplicativo de podcast para o GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Este podcast ainda não tem episódios"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr ""
"Se você acredita que isso é um erro, por favor considere preencher um "
"relatório de erro."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Obter alguns podcasts"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Adicionar novos podcasts via URL do feed"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importar podcasts de outro dispositivo"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Você já ouviu este episódio."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Calculando o tamanho do episódio…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Inicia este episódio"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Cancela o processo de download"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Faz download deste episódio"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Procurar novos episódios"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importar podcasts"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Exportar podcasts"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "Atal_hos de teclado"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "_Sobre Podcasts"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed"
msgstr "Adiciona um novo feed"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Insira o endereço do feed para adicioná-lo"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Adicionar"
#: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "Show Title"
msgstr "Mostrar título"
#: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back"
msgstr "Voltar"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Geral"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Procura por novos episódios"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Sai do aplicativo"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Hoje"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Ontem"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Essa semana"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Esse mês"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Antigos"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Uma notificação de ação no aplicativo"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Desfazer"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Retroceder 10 segundos"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Reproduz"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pausa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Adianta 10 segundos"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Altera a velocidade de reprodução"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "Taxa de velocidade de 1,5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "Taxa de velocidade de 1,25"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Velocidade normal"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Marcar todos os episódios como reproduzidos"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Site"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "Se _desinscrever"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Abrir o site"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Marcar todos como reproduzidos"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Desinscrever"
#: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes"
msgstr "Buscando novos episódios"
#: podcasts-gtk/src/headerbar.rs:120
msgid "You are already subscribed to this show"
msgstr "Você já está inscrito neste podcast"
#: podcasts-gtk/src/headerbar.rs:135
msgid "Invalid URL"
msgstr "URL inválida"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Novo"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Podcasts"
#: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows."
msgstr "Selecione o arquivo a partir do qual você deseja importar podcasts."
#: podcasts-gtk/src/utils.rs:400
msgid "_Import"
msgstr "_Importar"
#: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file"
msgstr "Arquivo OPML"
#: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file"
msgstr "Falha ao analisar o arquivo importado"
#: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed."
msgstr "O arquivo selecionado não pôde ser acessado."
#: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Exportar podcasts para…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Exportar"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_Cancelar"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "Inscrições do GNOME Podcasts"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Falha ao exportar podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Cliente de podcast para o ambiente GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Aprenda mais sobre o GNOME Podcasts"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr ""
"Rafael Fontenelle <rafaelff@gnome.org>\n"
"Yuri Otávio Lopes Gomes <yuriotavio@hotmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action."
msgstr "O reprodutor de mídia não conseguiu executar uma ação."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Marcados todos os episódios como ouvidos"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Desinscrito de {}"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "_Preferências"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "Você já está inscrito naquele feed!"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Preferências"
#~ msgid "Preferences"
#~ msgstr "Preferências"
#~ msgid "Appearance"
#~ msgstr "Aparência"
#~ msgid "Dark Theme"
#~ msgstr "Tema escuro"
#~ msgid "Delete played episodes"
#~ msgstr "Excluir episódios já reproduzidos"
#~ msgid "After"
#~ msgstr "Após"
#~ msgid "Seconds"
#~ msgstr "Segundos"
#~ msgid "Minutes"
#~ msgstr "Minutos"
#~ msgid "Hours"
#~ msgstr "Horas"
#~ msgid "Days"
#~ msgstr "Dias"
#~ msgid "Weeks"
#~ msgstr "Semanas"
#~ msgid "_About"
#~ msgstr "_Sobre"
+417
View File
@@ -0,0 +1,417 @@
# Slovak translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Dušan Kazik <prescott66@gmail.com>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-10-28 15:31+0000\n"
"PO-Revision-Date: 2018-10-28 22:00+0100\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
"X-Generator: Poedit 2.2\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Horná pozícia naposledy otvoreného hlavného okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Pozícia vľavo naposledy otvoreného hlavného okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Výška naposledy otvoreného hlavného okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Šírka naposledy otvoreného hlavného okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Maximalizovaný stav naposledy otvoreného hlavného okna"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Povoliť alebo zakázať tmavú tému"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Určuje, či sa má pravidelne obnovovať obsah"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Ako dlho sa má čakať medzi automatickými obnoveniami"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Aká je doba čakania medzi automatickými obnoveniami"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Určuje, či sa má obnoviť obsah po spustení"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Ako dlho sa má čakať medzi automatickými čisteniami"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Aká je doba čakania medzi automatickými čisteniami"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:416
#: podcasts-gtk/src/widgets/aboutdialog.rs:37
msgid "Podcasts"
msgstr "Podcasty"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Počúvajte vaše obľúbené podcasty priamo z vášho pracovného prostredia."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:6
msgid "@icon@"
msgstr "@icon@"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Aplikácia na správu podcastov pre prostredie GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:68
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Táto relácia zatiaľ nemá žiadne epizódy"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Ak si myslíte, že je to chyba, prosím, zvážte nahlásenie chyby."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Zaobstarajte si nejaké relácie"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Pridajte nové relácie prostredníctvom URL kanálu"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importujte relácie z iného zariadenia"
#: podcasts-gtk/resources/gtk/episode_widget.ui:180
msgid "Calculating episode size…"
msgstr "Vypočítava sa veľkosť epizódy…"
# tooltip
#: podcasts-gtk/resources/gtk/episode_widget.ui:220
msgid "Play this episode"
msgstr "Prehrá túto epizódu"
# tooltip
#: podcasts-gtk/resources/gtk/episode_widget.ui:241
msgid "Cancel the download process"
msgstr "Zruší preberanie"
# tooltip
#: podcasts-gtk/resources/gtk/episode_widget.ui:264
msgid "Download this episode"
msgstr "Preberie túto epizódu"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "_Skontrolovať nové epizódy"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importovať relácie"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Preferences"
msgstr "_Nastavenia"
#: podcasts-gtk/resources/gtk/hamburger.ui:27
msgid "_Keyboard Shortcuts"
msgstr "_Klávesové skratky"
#: podcasts-gtk/resources/gtk/hamburger.ui:35
msgid "_About Podcasts"
msgstr "_O aplikácii Podcasty"
# tooltip
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189
msgid "Add a new feed"
msgstr "Pridá nový kanál"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Zadajte adresu kanálu, ktorý sa má pridať"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Pridať"
#: podcasts-gtk/resources/gtk/headerbar.ui:133
msgid "You are already subscribed to that feed!"
msgstr "Už ste prihlásený na odber tohoto kanálu!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title"
msgstr "Zobrazenie názvu"
# tooltip
#: podcasts-gtk/resources/gtk/headerbar.ui:210
msgid "Back"
msgstr "Prejde späť"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Všeobecné"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Kontrola nových epizód"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Preferences"
msgstr "Nastavenia"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Ukončenie aplikácie"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Dnes"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Včera"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Tento týždeň"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Tento mesiac"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Staršie"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "Oznámenie o činnosti v aplikácii"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Vrátiť späť"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Previnie o 10 sekúnd dozadu"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Prehrá"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pozastaví"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Previnie o 10 sekúnd dopredu"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Zmení rýchlosť prehrávania"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "1,5 násobná rýchlosť"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "1,25 násobná rýchlosť"
# tooltip
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normálna rýchlosť"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Nastavenia"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Vzhľad"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Tmavá téma"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Odstránenie prehraných epizód"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Po"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "Oz_načiť všetky epizódy ako prehrané"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Webová stránka"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "O_dhlásiť sa z odberu"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Otvoriť webovú stránku"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Označiť všetko ako prehrané"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Odhlásiť sa z odberu"
#: podcasts-gtk/src/app.rs:333
msgid "Fetching new episodes"
msgstr "Získavajú sa nové epizódy"
#: podcasts-gtk/src/headerbar.rs:98
msgid "You are already subscribed to this show"
msgstr "Už ste prihlásený na odber tejto relácie"
#: podcasts-gtk/src/headerbar.rs:106
msgid "Invalid URL"
msgstr "Neplatná URL"
#: podcasts-gtk/src/prefs.rs:59
msgid "Seconds"
msgstr "Sekundách"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Minútach"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Hodinách"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Dňoch"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Týždňoch"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New"
msgstr "Nové"
#: podcasts-gtk/src/stacks/content.rs:36
msgid "Shows"
msgstr "Relácie"
#: podcasts-gtk/src/utils.rs:357
msgid "Select the file from which to you want to import shows."
msgstr "Vyberte súbor, z ktorého chcete importovať relácie."
#: podcasts-gtk/src/utils.rs:360
msgid "_Import"
msgstr "_Importovať"
#: podcasts-gtk/src/utils.rs:369
msgid "OPML file"
msgstr "Súbor OPML"
#: podcasts-gtk/src/utils.rs:386
msgid "Failed to parse the imported file"
msgstr "Zlyhala analýza importovaného súboru"
#: podcasts-gtk/src/utils.rs:391
msgid "Selected file could not be accessed."
msgstr "Nedá sa získať prístup k vybranému súboru."
#: podcasts-gtk/src/widgets/aboutdialog.rs:32
msgid "Podcast Client for the GNOME Desktop."
msgstr "Klient pre podcasty prostredia GNOME."
#: podcasts-gtk/src/widgets/aboutdialog.rs:39
msgid "Learn more about GNOME Podcasts"
msgstr "Zistite viac o aplikácii Podcasty prostredia GNOME"
#: podcasts-gtk/src/widgets/aboutdialog.rs:44
msgid "translator-credits"
msgstr "Dušan Kazik <prescott66@gmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:130
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:365
msgid "The media player was unable to execute an action."
msgstr "Prehrávač médií nedokázal vykonať akciu."
#: podcasts-gtk/src/widgets/show_menu.rs:150
msgid "Marked all episodes as listened"
msgstr "Všetky epizódy boli označené ako vypočuté"
#: podcasts-gtk/src/widgets/show_menu.rs:155
msgid "Unsubscribed from {}"
msgstr "Bol odhlásený odber z kanálu {}"
+424
View File
@@ -0,0 +1,424 @@
# Swedish translation for podcasts.
# Copyright © 2018, 2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package.
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2018, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2019-06-15 10:55+0000\n"
"PO-Revision-Date: 2019-08-22 17:54+0200\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2.3\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window"
msgstr "Topposition för det senast öppna huvudfönstret"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
msgid "Left position of the last open main window"
msgstr "Vänsterposition för det senast öppna huvudfönstret"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
msgid "Height of the last open main window"
msgstr "Höjden för det senast öppna huvudfönstret"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
msgid "Width of the last open main window"
msgstr "Bredden för det senast öppna huvudfönstret"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
msgid "Maximized state of the last open main window"
msgstr "Maximeringstillstånd för det senast öppna huvudfönstret"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
msgid "Enable or disable dark theme"
msgstr "Aktivera eller inaktivera mörkt tema"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
msgid "Whether to periodically refresh content"
msgstr "Huruvida innehåll ska uppdateras periodiskt"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes"
msgstr "Hur många tidsperioder att vänta mellan automatiska uppdateringar"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes"
msgstr "Vilken sorts tidsperiod att vänta mellan automatiska uppdateringar"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup"
msgstr "Huruvida innehåll ska uppdateras efter uppstart"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups"
msgstr "Hur många tidsperioder att vänta mellan automatiska upprensningar"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups"
msgstr "Vilken sorts tidsperiod att vänta mellan automatiska upprensningar"
#. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts"
msgstr "Poddsändningar"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Lyssna på dina favoritpoddsändningar, direkt från ditt skrivbord."
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;"
msgstr "Poddsändning;Podcast;RSS;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME"
msgstr "Poddsändningsprogram för GNOME"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis"
msgstr "Jordan Petridis"
#: podcasts-gtk/resources/gtk/empty_view.ui:46
msgid "This show does not have episodes yet"
msgstr "Denna show har inga avsnitt ännu"
#: podcasts-gtk/resources/gtk/empty_view.ui:62
msgid "If you think this is an error, please consider writing a bug report."
msgstr "Överväg att skriva en felrapport om du tror att detta är ett fel."
#: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows"
msgstr "Få tag på några shower"
#: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL"
msgstr "Lägg till nya shower via flödes-URL"
#: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device"
msgstr "Importera shower från en annan enhet"
#: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Du har redan lyssnat på detta avsnitt."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…"
msgstr "Beräknar avsnittsstorlek…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Play this episode"
msgstr "Spela detta avsnitt"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "Avbryt hämtningsprocessen"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Hämta detta avsnitt"
#: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes"
msgstr "Sö_k efter nya avsnitt"
#: podcasts-gtk/resources/gtk/hamburger.ui:12
msgid "_Import Shows"
msgstr "_Importera shower"
#: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Export Shows"
msgstr "_Exportera shower"
#: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts"
msgstr "_Tangentbordsgenvägar"
#: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About Podcasts"
msgstr "_Om Poddsändningar"
#: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed"
msgstr "Lägg till ett nytt flöde"
#: podcasts-gtk/resources/gtk/headerbar.ui:53
msgid "Enter feed address to add"
msgstr "Ange flödesadress att lägga till"
#: podcasts-gtk/resources/gtk/headerbar.ui:89
msgid "Add"
msgstr "Lägg till"
#: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "Show Title"
msgstr "Visa titel"
#: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back"
msgstr "Bakåt"
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
msgid "General"
msgstr "Allmänt"
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
msgctxt "shortcut window"
msgid "Check for new episodes"
msgstr "Sök efter nya avsnitt"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window"
msgid "Quit the application"
msgstr "Avsluta programmet"
#: podcasts-gtk/resources/gtk/home_view.ui:56
msgid "Today"
msgstr "Idag"
#: podcasts-gtk/resources/gtk/home_view.ui:112
msgid "Yesterday"
msgstr "Igår"
#: podcasts-gtk/resources/gtk/home_view.ui:168
msgid "This Week"
msgstr "Denna vecka"
#: podcasts-gtk/resources/gtk/home_view.ui:224
msgid "This Month"
msgstr "Denna månad"
#: podcasts-gtk/resources/gtk/home_view.ui:281
msgid "Older"
msgstr "Äldre"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:101
msgid "An in-app action notification"
msgstr "En åtgärdsavisering i programmet"
#: podcasts-gtk/resources/gtk/inapp_notif.ui:112
msgid "Undo"
msgstr "Ångra"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:72
msgid "Rewind 10 seconds"
msgstr "Spola tillbaka 10 sekunder"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:87
msgid "Play"
msgstr "Spela"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:103
msgid "Pause"
msgstr "Pausa"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:119
msgid "Fast forward 10 seconds"
msgstr "Spola framåt 10 sekunder"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:285
msgid "Change the playback speed"
msgstr "Ändra uppspelningshastigheten"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:300
#: podcasts-gtk/resources/gtk/player_toolbar.ui:380
msgid "1.00×"
msgstr "1,00×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:344
msgid "1.50×"
msgstr "1,50×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:348
msgid "1.5 speed rate"
msgstr "Hastighetsfaktor 1,5"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:362
msgid "1.25×"
msgstr "1,25×"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:366
msgid "1.25 speed rate"
msgstr "Hastighetsfaktor 1,25"
#: podcasts-gtk/resources/gtk/player_toolbar.ui:384
msgid "Normal speed"
msgstr "Normal hastighet"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played"
msgstr "_Markera alla avsnitt som spelade"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
msgid "_Website"
msgstr "_Webbplats"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
msgid "_Unsubscribe"
msgstr "Säg _upp prenumeration"
#: podcasts-gtk/resources/gtk/show_menu.ui:51
msgid "Open Website"
msgstr "Öppna webbplats"
#: podcasts-gtk/resources/gtk/show_menu.ui:64
msgid "Mark All as Played"
msgstr "Markera alla som spelade"
#: podcasts-gtk/resources/gtk/show_menu.ui:89
msgid "Unsubscribe"
msgstr "Säg upp prenumeration"
#: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes"
msgstr "Hämtar nya avsnitt"
#: podcasts-gtk/src/headerbar.rs:127
msgid "You are already subscribed to this show"
msgstr "Du prenumererar redan på denna show"
#: podcasts-gtk/src/headerbar.rs:145
msgid "Invalid URL"
msgstr "Ogiltig URL"
#: podcasts-gtk/src/stacks/content.rs:54
msgid "New"
msgstr "Nytt"
#: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows"
msgstr "Shower"
#: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows."
msgstr "Välj filen från vilken du vill importera shower."
#: podcasts-gtk/src/utils.rs:400
msgid "_Import"
msgstr "_Importera"
#: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file"
msgstr "OPML-fil"
#: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file"
msgstr "Misslyckades med att tolka den importerade filen"
#: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed."
msgstr "Den markerade filen kunde inte kommas åt."
#: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Exportera shower till…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Exportera"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "A_vbryt"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Poddsändningar-prenumerationer"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Misslyckades med att exportera poddsändningar"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop."
msgstr "Poddsändningsklient för GNOME-skrivbordet."
#: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts"
msgstr "Lär dig mer om GNOME Poddsändningar"
#: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits"
msgstr ""
"Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"\n"
"Skicka synpunkter på översättningen till\n"
"<tp-sv@listor.tp-sv.se>."
#: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min"
msgstr "{} min"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action."
msgstr "Mediaspelaren kunde inte utföra en åtgärd."
#: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened"
msgstr "Markerade alla avsnitt som lyssnade"
#: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}"
msgstr "Sade upp prenumeration från {}"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "I_nställningar"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "Du prenumererar redan på det flödet!"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Inställningar"
#~ msgid "Preferences"
#~ msgstr "Inställningar"
#~ msgid "Appearance"
#~ msgstr "Utseende"
#~ msgid "Dark Theme"
#~ msgstr "Mörkt tema"
#~ msgid "Delete played episodes"
#~ msgstr "Ta bort spelade avsnitt"
#~ msgid "After"
#~ msgstr "Efter"
#~ msgid "Seconds"
#~ msgstr "Sekunder"
#~ msgid "Minutes"
#~ msgstr "Minuter"
#~ msgid "Hours"
#~ msgstr "Timmar"
#~ msgid "Days"
#~ msgstr "Dagar"
#~ msgid "Weeks"
#~ msgstr "Veckor"
#~ msgid "_About"
#~ msgstr "_Om"
+138 -116
View File
@@ -1,22 +1,24 @@
# Turkish translation for podcasts. # Turkish translation for podcasts.
# Copyright (C) 2018 podcasts's COPYRIGHT HOLDER # Copyright (C) 2018-2019 podcasts's COPYRIGHT HOLDER
# This file is distributed under the same license as the podcasts package. # This file is distributed under the same license as the podcasts package.
# Emin Tufan Çetin <etcetin@gmail.com>, 2018. #
# Emin Tufan Çetin <etcetin@gmail.com>, 2018-2019.
# Sabri Ünal <libreajans@gmail.com>, 2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: podcasts master\n" "Project-Id-Version: podcasts master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/podcasts/issues\n"
"POT-Creation-Date: 2018-08-22 05:29+0000\n" "POT-Creation-Date: 2019-06-15 10:55+0000\n"
"PO-Revision-Date: 2018-08-27 11:42+0300\n" "PO-Revision-Date: 2019-09-04 15:16+0300\n"
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n" "Last-Translator: Sabri Ünal <libreajans@gmail.com>\n"
"Language-Team: Türkçe <gnome-turk@gnome.org>\n" "Language-Team: Türkçe <gnome-turk@gnome.org>\n"
"Language: tr\n" "Language: tr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Gtranslator 2.91.7\n" "X-Generator: Poedit 2.0.6\n"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
msgid "Top position of the last open main window" msgid "Top position of the last open main window"
@@ -48,11 +50,11 @@ msgstr "Belirli aralıklarla içeriğin yenilenmesi"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
msgid "How many periods of time to wait between automatic refreshes" msgid "How many periods of time to wait between automatic refreshes"
msgstr "" msgstr "Kendiliğinden yenilemeler arasında kaç zaman aralığı beklenecek"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
msgid "What period of time to wait between automatic refreshes" msgid "What period of time to wait between automatic refreshes"
msgstr "" msgstr "Kendiliğinden yenilemeler arasında beklenecek zaman aralığı"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
msgid "Whether to refresh content after startup" msgid "Whether to refresh content after startup"
@@ -60,40 +62,35 @@ msgstr "Başlangıçtan sonra içeriğin yenilenmesi"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
msgid "How many periods of time to wait between automatic cleanups" msgid "How many periods of time to wait between automatic cleanups"
msgstr "" msgstr "Kendiliğinden temizlemeler arasında kaç zaman aralığı beklenecek"
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64 #: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
msgid "What period of time to wait between automatic cleanups" msgid "What period of time to wait between automatic cleanups"
msgstr "" msgstr "Kendiliğinden temizlemeler arasında beklenecek zaman aralığı"
#. Weird magic I copy-pasted that sets the Application Name in the Shell. #. Weird magic I copy-pasted that sets the Application Name in the Shell.
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:3
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:4
#: podcasts-gtk/src/app.rs:92 podcasts-gtk/src/app.rs:406 #: podcasts-gtk/src/app.rs:109 podcasts-gtk/src/app.rs:433
#: podcasts-gtk/src/widgets/aboutdialog.rs:33 #: podcasts-gtk/src/widgets/aboutdialog.rs:56
msgid "Podcasts" msgid "Podcasts"
msgstr "Podcastler" msgstr "Podcastler"
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:4
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:10 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:10
msgid "Listen to your favorite podcasts, right from your desktop." msgid "Listen to your favorite podcasts, right from your desktop."
msgstr "Gözde podcastlerinizi masaüstünüzden dinleyin." msgstr "Gözde podcastlerinizi masaüstünüzden dinleyin."
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:6
msgid "org.gnome.Podcasts"
msgstr "org.gnome.Podcasts"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! #. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:13 #: podcasts-gtk/resources/org.gnome.Podcasts.desktop.in.in:13
msgid "Podcast;RSS;" msgid "Podcast;RSS;"
msgstr "Podcast;RSS;Pod Yayını;" msgstr "Podcast;RSS;Pod Yayını;"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:8 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:8
msgid "Podcast app for GNOME" msgid "Podcast app for GNOME"
msgstr "GNOME için Podcast uygulaması" msgstr "GNOME için Podcast uygulaması"
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:31 #: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml.in.in:77
msgid "Jordan Petridis" msgid "Jordan Petridis"
msgstr "Jordan Petridis" msgstr "Jordan Petridis"
@@ -105,34 +102,38 @@ msgstr "Bu gösterinin henüz herhangi bir bölümü yok"
msgid "If you think this is an error, please consider writing a bug report." msgid "If you think this is an error, please consider writing a bug report."
msgstr "Bunun bir hata olduğunu düşünüyorsanız lütfen hata bildirimi yazın." msgstr "Bunun bir hata olduğunu düşünüyorsanız lütfen hata bildirimi yazın."
#: podcasts-gtk/resources/gtk/empty_view.ui:107 #: podcasts-gtk/resources/gtk/empty_view.ui:106
msgid "Get some shows" msgid "Get some shows"
msgstr "Birkaç gösteri edinin" msgstr "Birkaç gösteri edinin"
#: podcasts-gtk/resources/gtk/empty_view.ui:144 #: podcasts-gtk/resources/gtk/empty_view.ui:143
msgid "Add new shows via feed URL" msgid "Add new shows via feed URL"
msgstr "Besleme URLʼsi ile yeni gösteriler ekle" msgstr "Besleme URLʼsi ile yeni gösteriler ekle"
#: podcasts-gtk/resources/gtk/empty_view.ui:173 #: podcasts-gtk/resources/gtk/empty_view.ui:172
msgid "Import shows from another device" msgid "Import shows from another device"
msgstr "Gösterileri başka aygıttan içe aktar" msgstr "Gösterileri başka aygıttan içe aktar"
#: podcasts-gtk/resources/gtk/episode_widget.ui:177 #: podcasts-gtk/resources/gtk/episode_widget.ui:79
msgid "You’ve already listened to this episode."
msgstr "Bu bölümü zaten dinlediniz."
#: podcasts-gtk/resources/gtk/episode_widget.ui:208
msgid "Calculating episode size…" msgid "Calculating episode size…"
msgstr "Bölüm boyutu hesaplanıyor…" msgstr "Bölüm boyutu hesaplanıyor…"
#: podcasts-gtk/resources/gtk/episode_widget.ui:212 #: podcasts-gtk/resources/gtk/episode_widget.ui:248
msgid "Cancel"
msgstr "İptal"
#: podcasts-gtk/resources/gtk/episode_widget.ui:230
msgid "Download this episode"
msgstr "Bu bölümü indir"
#: podcasts-gtk/resources/gtk/episode_widget.ui:254
msgid "Play this episode" msgid "Play this episode"
msgstr "Bu bölümü oynat" msgstr "Bu bölümü oynat"
#: podcasts-gtk/resources/gtk/episode_widget.ui:269
msgid "Cancel the download process"
msgstr "İndirme sürecini iptal et"
#: podcasts-gtk/resources/gtk/episode_widget.ui:292
msgid "Download this episode"
msgstr "Bu bölümü indir"
#: podcasts-gtk/resources/gtk/hamburger.ui:7 #: podcasts-gtk/resources/gtk/hamburger.ui:7
msgid "_Check for New Episodes" msgid "_Check for New Episodes"
msgstr "Yeni Bölümleri _Denetle" msgstr "Yeni Bölümleri _Denetle"
@@ -141,20 +142,20 @@ msgstr "Yeni Bölümleri _Denetle"
msgid "_Import Shows" msgid "_Import Shows"
msgstr "_Gösterileri İçe Aktar" msgstr "_Gösterileri İçe Aktar"
#: podcasts-gtk/resources/gtk/hamburger.ui:22 #: podcasts-gtk/resources/gtk/hamburger.ui:16
msgid "_Preferences" msgid "_Export Shows"
msgstr "_Tercihler" msgstr "_Gösterileri Dışa Aktar"
#: podcasts-gtk/resources/gtk/hamburger.ui:29 #: podcasts-gtk/resources/gtk/hamburger.ui:22
msgid "_Keyboard Shortcuts" msgid "_Keyboard Shortcuts"
msgstr "_Klavye Kısayolları" msgstr "_Klavye Kısayolları"
#: podcasts-gtk/resources/gtk/hamburger.ui:37 #: podcasts-gtk/resources/gtk/hamburger.ui:30
msgid "_About" msgid "_About Podcasts"
msgstr "_Hakkında" msgstr "Podcastler _Hakkında"
#: podcasts-gtk/resources/gtk/headerbar.ui:35 #: podcasts-gtk/resources/gtk/headerbar.ui:35
#: podcasts-gtk/resources/gtk/headerbar.ui:189 #: podcasts-gtk/resources/gtk/headerbar.ui:177
msgid "Add a new feed" msgid "Add a new feed"
msgstr "Yeni besleme ekle" msgstr "Yeni besleme ekle"
@@ -166,15 +167,11 @@ msgstr "Eklenecek besleme adresini gir"
msgid "Add" msgid "Add"
msgstr "Ekle" msgstr "Ekle"
#: podcasts-gtk/resources/gtk/headerbar.ui:133 #: podcasts-gtk/resources/gtk/headerbar.ui:157
msgid "You are already subscribed to that feed!"
msgstr "Bu beslemeye zaten abonesiniz!"
#: podcasts-gtk/resources/gtk/headerbar.ui:169
msgid "Show Title" msgid "Show Title"
msgstr "Gösteri Başlığı" msgstr "Gösteri Başlığı"
#: podcasts-gtk/resources/gtk/headerbar.ui:210 #: podcasts-gtk/resources/gtk/headerbar.ui:198
msgid "Back" msgid "Back"
msgstr "Geri" msgstr "Geri"
@@ -189,11 +186,6 @@ msgstr "Yeni bölümleri denetle"
#: podcasts-gtk/resources/gtk/help-overlay.ui:25 #: podcasts-gtk/resources/gtk/help-overlay.ui:25
msgctxt "shortcut window" msgctxt "shortcut window"
msgid "Preferences"
msgstr "Tercihler"
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
msgctxt "shortcut window"
msgid "Quit the application" msgid "Quit the application"
msgstr "Uygulamadan çık" msgstr "Uygulamadan çık"
@@ -270,27 +262,6 @@ msgstr "1.25 hız oranı"
msgid "Normal speed" msgid "Normal speed"
msgstr "Olağan hız" msgstr "Olağan hız"
#: podcasts-gtk/resources/gtk/prefs.ui:42
#: podcasts-gtk/resources/gtk/prefs.ui:295
msgid "Preferences"
msgstr "Tercihler"
#: podcasts-gtk/resources/gtk/prefs.ui:76
msgid "Appearance"
msgstr "Görünüm"
#: podcasts-gtk/resources/gtk/prefs.ui:120
msgid "Dark Theme"
msgstr "Karanlık Gövde"
#: podcasts-gtk/resources/gtk/prefs.ui:166
msgid "Delete played episodes"
msgstr "Oynatılan bölümleri sil"
#: podcasts-gtk/resources/gtk/prefs.ui:211
msgid "After"
msgstr "Şundan Sonra"
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7 #: podcasts-gtk/resources/gtk/secondary_menu.ui:7
msgid "_Mark All Episodes as Played" msgid "_Mark All Episodes as Played"
msgstr "Tüm Bölümleri Oynatıldı Olarak _İmle" msgstr "Tüm Bölümleri Oynatıldı Olarak _İmle"
@@ -315,94 +286,145 @@ msgstr "Tümünü Oynatıldı Olarak İmle"
msgid "Unsubscribe" msgid "Unsubscribe"
msgstr "Abonelikten Çık" msgstr "Abonelikten Çık"
#: podcasts-gtk/src/app.rs:331 #: podcasts-gtk/src/app.rs:351
msgid "Fetching new episodes" msgid "Fetching new episodes"
msgstr "Yeni bölümler alınıyor" msgstr "Yeni bölümler alınıyor"
#: podcasts-gtk/src/headerbar.rs:98 #: podcasts-gtk/src/headerbar.rs:127
msgid "You are already subscribed to this show" msgid "You are already subscribed to this show"
msgstr "Bu gösteriye zaten abonesiniz" msgstr "Bu gösteriye zaten abonesiniz"
#: podcasts-gtk/src/headerbar.rs:106 #: podcasts-gtk/src/headerbar.rs:145
msgid "Invalid URL" msgid "Invalid URL"
msgstr "Geçersiz URL" msgstr "Geçersiz URL"
#: podcasts-gtk/src/prefs.rs:59 #: podcasts-gtk/src/stacks/content.rs:54
msgid "Seconds"
msgstr "Saniye"
#: podcasts-gtk/src/prefs.rs:60
msgid "Minutes"
msgstr "Dakika"
#: podcasts-gtk/src/prefs.rs:61
msgid "Hours"
msgstr "Saat"
#: podcasts-gtk/src/prefs.rs:62
msgid "Days"
msgstr "Gün"
#: podcasts-gtk/src/prefs.rs:63
msgid "Weeks"
msgstr "Hafta"
#: podcasts-gtk/src/stacks/content.rs:35
msgid "New" msgid "New"
msgstr "Yeni" msgstr "Yeni"
#: podcasts-gtk/src/stacks/content.rs:36 #: podcasts-gtk/src/stacks/content.rs:55
msgid "Shows" msgid "Shows"
msgstr "Gösteriler" msgstr "Gösteriler"
#: podcasts-gtk/src/utils.rs:350 #: podcasts-gtk/src/utils.rs:397
msgid "Select the file from which to you want to import shows." msgid "Select the file from which to you want to import shows."
msgstr "Gösterileri içe aktarmak istediğiniz dosyayı seçin" msgstr "Gösterileri içe aktarmak istediğiniz dosyayı seçin."
#: podcasts-gtk/src/utils.rs:353 #: podcasts-gtk/src/utils.rs:400
msgid "_Import" msgid "_Import"
msgstr "_İçe Aktar" msgstr "_İçe Aktar"
#: podcasts-gtk/src/utils.rs:362 #: podcasts-gtk/src/utils.rs:409 podcasts-gtk/src/utils.rs:457
msgid "OPML file" msgid "OPML file"
msgstr "OPML dosyası" msgstr "OPML dosyası"
#: podcasts-gtk/src/utils.rs:379 #: podcasts-gtk/src/utils.rs:426
msgid "Failed to parse the imported file" msgid "Failed to parse the imported file"
msgstr "İçe aktarılan dosya ayrıştırılamadı" msgstr "İçe aktarılan dosya ayrıştırılamadı"
#: podcasts-gtk/src/utils.rs:384 #: podcasts-gtk/src/utils.rs:431 podcasts-gtk/src/utils.rs:475
msgid "Selected file could not be accessed." msgid "Selected file could not be accessed."
msgstr "Seçilen dosyaya erişilemedi." msgstr "Seçilen dosyaya erişilemedi."
#: podcasts-gtk/src/widgets/aboutdialog.rs:26 #: podcasts-gtk/src/utils.rs:445
msgid "Export shows to…"
msgstr "Gösterileri dışa aktar…"
#: podcasts-gtk/src/utils.rs:448
msgid "_Export"
msgstr "_Dışa Aktar"
#: podcasts-gtk/src/utils.rs:449
msgid "_Cancel"
msgstr "_İptal"
#: podcasts-gtk/src/utils.rs:469
msgid "GNOME Podcasts Subscriptions"
msgstr "GNOME Podcastler Abonelikleri"
#: podcasts-gtk/src/utils.rs:470
msgid "Failed to export podcasts"
msgstr "Podcastler dışa aktarılamadı"
#: podcasts-gtk/src/widgets/aboutdialog.rs:51
msgid "Podcast Client for the GNOME Desktop." msgid "Podcast Client for the GNOME Desktop."
msgstr "GNOME Masaüstü için Podcast İstemcisi." msgstr "GNOME Masaüstü için Podcast İstemcisi."
#: podcasts-gtk/src/widgets/aboutdialog.rs:35 #: podcasts-gtk/src/widgets/aboutdialog.rs:58
msgid "Learn more about GNOME Podcasts" msgid "Learn more about GNOME Podcasts"
msgstr "GNOME Podcastler hakkında daha çoğunu öğrenin" msgstr "GNOME Podcastler hakkında daha çoğunu öğrenin"
#: podcasts-gtk/src/widgets/aboutdialog.rs:40 #: podcasts-gtk/src/widgets/aboutdialog.rs:63
msgid "translator-credits" msgid "translator-credits"
msgstr "Emin Tufan Çetin <etcetin@gmail.com>" msgstr ""
"Emin Tufan Çetin <etcetin@gmail.com>\n"
"Sabri Ünal <libreajans@gmail.com>"
#: podcasts-gtk/src/widgets/episode.rs:129 #: podcasts-gtk/src/widgets/episode.rs:148
msgid "{} min" msgid "{} min"
msgstr "{} dak" msgstr "{} dak"
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); #. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
#: podcasts-gtk/src/widgets/player.rs:301 #: podcasts-gtk/src/widgets/player.rs:534
msgid "The media player was unable to execute an action." msgid "The media player was unable to execute an action."
msgstr "Ortam oynatıcı eylemi yürütemiyor." msgstr "Ortam oynatıcı eylemi yürütemiyor."
#: podcasts-gtk/src/widgets/show_menu.rs:150 #: podcasts-gtk/src/widgets/show_menu.rs:179
msgid "Marked all episodes as listened" msgid "Marked all episodes as listened"
msgstr "Tüm bölümler dinlendi olarak imlendi" msgstr "Tüm bölümler dinlendi olarak imlendi"
#: podcasts-gtk/src/widgets/show_menu.rs:155 #: podcasts-gtk/src/widgets/show_menu.rs:184
msgid "Unsubscribed from {}" msgid "Unsubscribed from {}"
msgstr "{} aboneliğinden çıkıldı" msgstr "{} aboneliğinden çıkıldı"
#~ msgid "@icon@"
#~ msgstr "@icon@"
#~ msgid "_Preferences"
#~ msgstr "_Tercihler"
#~ msgid "You are already subscribed to that feed!"
#~ msgstr "Bu beslemeye zaten abonesiniz!"
#~ msgctxt "shortcut window"
#~ msgid "Preferences"
#~ msgstr "Tercihler"
#~ msgid "Preferences"
#~ msgstr "Tercihler"
#~ msgid "Appearance"
#~ msgstr "Görünüm"
#~ msgid "Dark Theme"
#~ msgstr "Karanlık Gövde"
#~ msgid "Delete played episodes"
#~ msgstr "Oynatılan bölümleri sil"
#~ msgid "After"
#~ msgstr "Şundan Sonra"
#~ msgid "Seconds"
#~ msgstr "Saniye"
#~ msgid "Minutes"
#~ msgstr "Dakika"
#~ msgid "Hours"
#~ msgstr "Saat"
#~ msgid "Days"
#~ msgstr "Gün"
#~ msgid "Weeks"
#~ msgstr "Hafta"
#~ msgid "_About"
#~ msgstr "_Hakkında"
#~ msgid "org.gnome.Podcasts"
#~ msgstr "org.gnome.Podcasts"
#~ msgid "Episode Title" #~ msgid "Episode Title"
#~ msgstr "Bölüm Başlığı" #~ msgstr "Bölüm Başlığı"
+66 -30
View File
@@ -44,10 +44,17 @@ Tobias Bernard
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkBox" id="info_container"> <object class="GtkBox" id="info_container">
<property name="width_request">200</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child> <child>
<object class="GtkLabel" id="title_label"> <object class="GtkLabel" id="title_label">
<property name="visible">True</property> <property name="visible">True</property>
@@ -65,6 +72,29 @@ Tobias Bernard
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkImage" id="played_checkmark">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">You’ve already listened to this episode.</property>
<property name="icon_name">object-select-symbolic</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
@@ -205,23 +235,53 @@ Tobias Bernard
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButtonBox" id="button_box"> <object class="GtkBox" id="button_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="layout_style">center</property> <property name="halign">end</property>
<property name="spacing">6</property>
<child> <child>
<object class="GtkButton" id="cancel_button"> <object class="GtkButton" id="play_button">
<property name="label" translatable="yes">Cancel</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Play this episode</property>
<property name="halign">center</property> <property name="halign">center</property>
<property name="valign">center</property> <property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-start-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancel_button">
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Cancel the download process</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-stop-symbolic</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="pack_type">end</property> <property name="pack_type">end</property>
<property name="position">0</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@@ -241,34 +301,10 @@ Tobias Bernard
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="non_homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="play_button">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Play this episode</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playback-start-symbolic</property>
</object>
</child>
</object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">2</property> <property name="position">2</property>
<property name="non_homogeneous">True</property>
</packing> </packing>
</child> </child>
</object> </object>
+4 -10
View File
@@ -12,16 +12,9 @@
<attribute name="label" translatable="yes">_Import Shows</attribute> <attribute name="label" translatable="yes">_Import Shows</attribute>
<attribute name="action">win.import</attribute> <attribute name="action">win.import</attribute>
</item> </item>
<!-- <item> -->
<!-- <attribute name="label" translatable="yes">_Export Shows</attribute> -->
<!-- <attribute name="action">win.export</attribute> -->
<!-- </item> -->
</section>
<section>
<item> <item>
<attribute name="label" translatable="yes">_Preferences</attribute> <attribute name="label" translatable="yes">_Export Shows</attribute>
<attribute name="action">win.preferences</attribute> <attribute name="action">win.export</attribute>
<attribute name="accel">&lt;primary&gt;e</attribute>
</item> </item>
</section> </section>
<section> <section>
@@ -34,9 +27,10 @@
<!-- <attribute name="action">win.help</attribute> --> <!-- <attribute name="action">win.help</attribute> -->
<!-- </item> --> <!-- </item> -->
<item> <item>
<attribute name="label" translatable="yes">_About</attribute> <attribute name="label" translatable="yes">_About Podcasts</attribute>
<attribute name="action">win.about</attribute> <attribute name="action">win.about</attribute>
</item> </item>
</section> </section>
</menu> </menu>
</interface> </interface>
+6 -18
View File
@@ -3,20 +3,20 @@
Copyright (C) 2017 - 2018 Copyright (C) 2017 - 2018
This file is part of GNOEM Podcasts. This file is part of GNOME Podcasts.
GNOEM Podcasts is free software: you can redistribute it and/or modify GNOME Podcasts is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
GNOEM Podcasts is distributed in the hope that it will be useful, GNOME Podcasts is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with GNOEM Podcasts. If not, see <http://www.gnu.org/licenses/>. along with GNOME Podcasts. If not, see <http://www.gnu.org/licenses/>.
Authors: Authors:
Jordan Petridis Jordan Petridis
@@ -26,7 +26,7 @@ Tobias Bernard
<interface> <interface>
<requires lib="gtk+" version="3.22"/> <requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 --> <!-- interface-license-type gplv3 -->
<!-- interface-name GNOEM Podcasts --> <!-- interface-name GNOME Podcasts -->
<!-- interface-description A podcast client for the GNOME Desktop --> <!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 --> <!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard --> <!-- interface-authors Jordan Petridis\nTobias Bernard -->
@@ -70,7 +70,7 @@ Tobias Bernard
<object class="GtkEntry" id="new_url"> <object class="GtkEntry" id="new_url">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="width_chars">30</property> <property name="width_chars">26</property>
<property name="input_purpose">url</property> <property name="input_purpose">url</property>
</object> </object>
<packing> <packing>
@@ -126,18 +126,6 @@ Tobias Bernard
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="result_label">
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">You are already subscribed to that feed!</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object> </object>
</child> </child>
</object> </object>
@@ -18,13 +18,6 @@
<property name="title" translatable="yes" context="shortcut window">Check for new episodes</property> <property name="title" translatable="yes" context="shortcut window">Check for new episodes</property>
</object> </object>
</child> </child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">True</property>
<property name="accelerator">&lt;primary&gt;e</property>
<property name="title" translatable="yes" context="shortcut window">Preferences</property>
</object>
</child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">True</property> <property name="visible">True</property>
-310
View File
@@ -1,310 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0
Copyright (C) 2017 - 2018
This file is part of GNOME Podcasts.
GNOME Podcasts is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GNOME Podcasts is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNOME Podcasts. If not, see <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name GNOME Podcasts -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkAdjustment" id="cleanup_value_adj">
<property name="lower">1</property>
<property name="upper">100</property>
<property name="value">1</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkWindow" id="prefs">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Preferences</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="min_content_width">480</property>
<property name="min_content_height">200</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">10</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Appearance</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="width_request">450</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkListBoxRow">
<property name="height_request">50</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Dark Theme</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="dark_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">20</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">Delete played episodes</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="width_request">300</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkListBoxRow">
<property name="width_request">100</property>
<property name="height_request">50</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">After</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkSpinButton" id="cleanup_value">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="input_purpose">digits</property>
<property name="adjustment">cleanup_value_adj</property>
<property name="climb_rate">1</property>
<property name="value">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cleanup_type">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="linked"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Preferences</property>
<property name="show_close_button">True</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="refresh_value_adj">
<property name="lower">1</property>
<property name="upper">100</property>
<property name="value">1</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
</interface>
-12
View File
@@ -18,15 +18,3 @@ list, border {
.player-show-label { .player-show-label {
font-size: smaller; font-size: smaller;
} }
.devel headerbar {
background: transparent -gtk-icontheme("system-run-symbolic") 80% 0/128px 128px no-repeat,
linear-gradient(to left,
mix(@theme_selected_bg_color, @theme_bg_color, 0.5) 8%,
@theme_bg_color 25%);
color: alpha(@theme_fg_color, 0.1);
}
.devel headerbar label {
color: @theme_fg_color;
}
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1">
<defs>
<linearGradient id="linear0" gradientUnits="userSpaceOnUse" x1="8" y1="264" x2="120" y2="264" gradientTransform="matrix(1,0,0,1,0,-160.000006)">
<stop offset="0" style="stop-color:rgb(64.705884%,11.372549%,17.647059%);stop-opacity:1;"/>
<stop offset="0.0343218" style="stop-color:rgb(92.941177%,20%,23.137255%);stop-opacity:1;"/>
<stop offset="0.0706241" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
<stop offset="0.927675" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
<stop offset="0.964286" style="stop-color:rgb(92.941177%,20%,23.137255%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
</linearGradient>
<clipPath id="clip1">
<path d="M 52 62 L 76 62 L 76 74 L 52 74 Z M 52 62 "/>
</clipPath>
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="mask0">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.5;stroke:none;"/>
</g>
</mask>
<clipPath id="clip2">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface29618" clip-path="url(#clip2)">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 76 84 C 76 99.464844 63.464844 112 48 112 C 32.535156 112 20 99.464844 20 84 C 20 68.535156 32.535156 56 48 56 C 63.464844 56 76 68.535156 76 84 Z M 76 84 "/>
</g>
<linearGradient id="linear1" gradientUnits="userSpaceOnUse" x1="8" y1="264" x2="120" y2="264" gradientTransform="matrix(1,0,0,1,0,-160.000006)">
<stop offset="0" style="stop-color:rgb(64.705884%,11.372549%,17.647059%);stop-opacity:1;"/>
<stop offset="0.0343218" style="stop-color:rgb(92.941177%,20%,23.137255%);stop-opacity:1;"/>
<stop offset="0.0706241" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
<stop offset="0.927675" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
<stop offset="0.964286" style="stop-color:rgb(92.941177%,20%,23.137255%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(75.294119%,10.980392%,15.686275%);stop-opacity:1;"/>
</linearGradient>
<clipPath id="clip5">
<path d="M 52 62 L 76 62 L 76 74 L 52 74 Z M 52 62 "/>
</clipPath>
<mask id="mask2">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.5;stroke:none;"/>
</g>
</mask>
<clipPath id="clip6">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface29618" clip-path="url(#clip6)">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 76 84 C 76 99.464844 63.464844 112 48 112 C 32.535156 112 20 99.464844 20 84 C 20 68.535156 32.535156 56 48 56 C 63.464844 56 76 68.535156 76 84 Z M 76 84 "/>
</g>
<clipPath id="clip4">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface29630" clip-path="url(#clip4)">
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear1);" d="M 16 92 L 112 92 C 116.417969 92 120 95.582031 120 100 L 120 108 C 120 112.417969 116.417969 116 112 116 L 16 116 C 11.582031 116 8 112.417969 8 108 L 8 100 C 8 95.582031 11.582031 92 16 92 Z M 16 92 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(92.941177%,20%,23.137255%);fill-opacity:1;" d="M 16 28 L 112 28 C 116.417969 28 120 31.957031 120 36.84375 L 120 103.15625 C 120 108.042969 116.417969 112 112 112 L 16 112 C 11.582031 112 8 108.042969 8 103.15625 L 8 36.84375 C 8 31.957031 11.582031 28 16 28 Z M 16 28 "/>
<path style="fill-rule:nonzero;fill:rgb(36.862746%,36.078432%,39.215687%);fill-opacity:1;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(36.862746%,36.078432%,39.215687%);stroke-opacity:1;stroke-miterlimit:4;" d="M 36 281.999994 L 92 281.999994 L 88 271.999994 L 40 271.999994 Z M 36 281.999994 " transform="matrix(1,0,0,1,0,-171.999994)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 32 110 L 96 110 L 96 116 L 32 116 Z M 32 110 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 24 36 L 104 36 L 112 44 L 112 96 L 16 96 L 16 44 Z M 24 36 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 16 52 L 112 52 L 112 84 L 16 84 Z M 16 52 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 46 68 C 46 71.3125 43.3125 74 40 74 C 36.6875 74 34 71.3125 34 68 C 34 64.6875 36.6875 62 40 62 C 43.3125 62 46 64.6875 46 68 Z M 46 68 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 94 68 C 94 71.3125 91.3125 74 88 74 C 84.6875 74 82 71.3125 82 68 C 82 64.6875 84.6875 62 88 62 C 91.3125 62 94 64.6875 94 68 Z M 94 68 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(58.039218%,57.647061%,56.470591%);fill-opacity:1;" d="M 52 62 L 76 62 L 76 74 L 52 74 Z M 52 62 "/>
<g clip-path="url(#clip5)" clip-rule="nonzero">
<use xlink:href="#surface29618" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask2)"/>
</g>
</g>
<clipPath id="clip3">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface29633" clip-path="url(#clip3)" filter="url(#alpha)">
<use xlink:href="#surface29630"/>
</g>
<mask id="mask1">
<use xlink:href="#surface29633"/>
</mask>
<mask id="mask3">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.8;stroke:none;"/>
</g>
</mask>
<linearGradient id="linear2" gradientUnits="userSpaceOnUse" x1="300" y1="235" x2="428" y2="235" gradientTransform="matrix(0.000000000000000023,0.37,-0.98462,0.00000000000000006,295.38501,-30.360001)">
<stop offset="0" style="stop-color:rgb(97.647059%,94.117647%,41.960785%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(96.078432%,76.078433%,6.666667%);stop-opacity:1;"/>
</linearGradient>
<clipPath id="clip8">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface29627" clip-path="url(#clip8)">
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear2);" d="M 128 80.640625 L 128 128 L 0 128 L 0 80.640625 Z M 128 80.640625 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 13.308594 80.640625 L 60.664062 128 L 81.878906 128 L 34.519531 80.640625 Z M 55.730469 80.640625 L 103.09375 128 L 124.308594 128 L 76.945312 80.640625 Z M 98.160156 80.640625 L 128 110.480469 L 128 89.269531 L 119.371094 80.640625 Z M 0 88.546875 L 0 109.761719 L 18.238281 128 L 39.453125 128 Z M 0 88.546875 "/>
</g>
<clipPath id="clip7">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface29632" clip-path="url(#clip7)">
<use xlink:href="#surface29627" mask="url(#mask3)"/>
</g>
</defs>
<g id="surface29613">
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear0);" d="M 16 92 L 112 92 C 116.417969 92 120 95.582031 120 100 L 120 108 C 120 112.417969 116.417969 116 112 116 L 16 116 C 11.582031 116 8 112.417969 8 108 L 8 100 C 8 95.582031 11.582031 92 16 92 Z M 16 92 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(92.941177%,20%,23.137255%);fill-opacity:1;" d="M 16 28 L 112 28 C 116.417969 28 120 31.957031 120 36.84375 L 120 103.15625 C 120 108.042969 116.417969 112 112 112 L 16 112 C 11.582031 112 8 108.042969 8 103.15625 L 8 36.84375 C 8 31.957031 11.582031 28 16 28 Z M 16 28 "/>
<path style="fill-rule:nonzero;fill:rgb(36.862746%,36.078432%,39.215687%);fill-opacity:1;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(36.862746%,36.078432%,39.215687%);stroke-opacity:1;stroke-miterlimit:4;" d="M 36 281.999994 L 92 281.999994 L 88 271.999994 L 40 271.999994 Z M 36 281.999994 " transform="matrix(1,0,0,1,0,-171.999994)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 32 110 L 96 110 L 96 116 L 32 116 Z M 32 110 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 24 36 L 104 36 L 112 44 L 112 96 L 16 96 L 16 44 Z M 24 36 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.882354%,25.098041%,28.235295%);fill-opacity:1;" d="M 16 52 L 112 52 L 112 84 L 16 84 Z M 16 52 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 46 68 C 46 71.3125 43.3125 74 40 74 C 36.6875 74 34 71.3125 34 68 C 34 64.6875 36.6875 62 40 62 C 43.3125 62 46 64.6875 46 68 Z M 46 68 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.470588%,96.078432%,95.686275%);fill-opacity:1;" d="M 94 68 C 94 71.3125 91.3125 74 88 74 C 84.6875 74 82 71.3125 82 68 C 82 64.6875 84.6875 62 88 62 C 91.3125 62 94 64.6875 94 68 Z M 94 68 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(58.039218%,57.647061%,56.470591%);fill-opacity:1;" d="M 52 62 L 76 62 L 76 74 L 52 74 Z M 52 62 "/>
<g clip-path="url(#clip1)" clip-rule="nonzero">
<use xlink:href="#surface29618" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask0)"/>
</g>
<use xlink:href="#surface29632" mask="url(#mask1)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

@@ -18,7 +18,7 @@
id="svg11300" id="svg11300"
sodipodi:version="0.32" sodipodi:version="0.32"
inkscape:version="0.92.3 (2405546, 2018-03-11)" inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="org.gnome.Podcasts.svg" sodipodi:docname="org.gnome.Podcasts_clean.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0" version="1.0"
style="display:inline;enable-background:new" style="display:inline;enable-background:new"
@@ -27,6 +27,71 @@
id="title4162">Adwaita Icon Template</title> id="title4162">Adwaita Icon Template</title>
<defs <defs
id="defs3"> id="defs3">
<linearGradient
y2="236"
x2="96"
y1="236"
x1="32"
gradientTransform="translate(604.81684,170.58641)"
gradientUnits="userSpaceOnUse"
id="linearGradient1099"
xlink:href="#linearGradient1036" />
<linearGradient
id="linearGradient1036">
<stop
id="stop1032"
offset="0"
style="stop-color:#d5d3cf;stop-opacity:1;" />
<stop
id="stop1034"
offset="1"
style="stop-color:#f6f5f4;stop-opacity:1" />
</linearGradient>
<radialGradient
r="32"
fy="-76"
fx="-244"
cy="-76"
cx="-244"
gradientTransform="matrix(0.88333331,0,0,0.88333331,-460.35018,463.11973)"
gradientUnits="userSpaceOnUse"
id="radialGradient1103"
xlink:href="#linearGradient1069" />
<linearGradient
id="linearGradient1069">
<stop
id="stop1065"
offset="0"
style="stop-color:#d5d3cf;stop-opacity:1" />
<stop
id="stop1067-1"
offset="1"
style="stop-color:#949390;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="232"
x2="64"
y1="262.5"
x1="64"
id="linearGradient1027"
xlink:href="#linearGradient1025"
gradientTransform="translate(-470.5864,432.81685)" />
<linearGradient
id="linearGradient1025">
<stop
id="stop1021"
offset="0"
style="stop-color:#9a9996;stop-opacity:1" />
<stop
id="stop1023"
offset="1"
style="stop-color:#77767b;stop-opacity:1" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect35304-9"
is_visible="true" />
<clipPath <clipPath
clipPathUnits="userSpaceOnUse" clipPathUnits="userSpaceOnUse"
id="clipPath1017"> id="clipPath1017">
@@ -55,7 +120,7 @@
</clipPath> </clipPath>
<clipPath <clipPath
clipPathUnits="userSpaceOnUse" clipPathUnits="userSpaceOnUse"
id="clipPath945"> id="clipPath1043">
<rect <rect
ry="31.999998" ry="31.999998"
rx="32" rx="32"
@@ -63,9 +128,47 @@
x="32.5" x="32.5"
height="320" height="320"
width="447" width="447"
id="rect943" id="rect1041"
style="opacity:1;fill:#fb8c14;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.9999998, 1.9999999;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#fb8c14;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.9999998, 1.9999999;stroke-dashoffset:0;stroke-opacity:1" />
</clipPath> </clipPath>
<linearGradient
gradientTransform="translate(0,11.999989)"
inkscape:collect="always"
xlink:href="#linearGradient1654"
id="linearGradient1640"
x1="8"
y1="264"
x2="120"
y2="264"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient1654">
<stop
style="stop-color:#a51d2d;stop-opacity:1"
offset="0"
id="stop1642" />
<stop
id="stop1644"
offset="0.03432177"
style="stop-color:#ed333b;stop-opacity:1" />
<stop
style="stop-color:#c01c28;stop-opacity:1"
offset="0.07062413"
id="stop1646" />
<stop
id="stop1648"
offset="0.92767543"
style="stop-color:#c01c28;stop-opacity:1" />
<stop
style="stop-color:#ed333b;stop-opacity:1"
offset="0.96428573"
id="stop1650" />
<stop
style="stop-color:#c01c28;stop-opacity:1"
offset="1"
id="stop1652" />
</linearGradient>
<clipPath <clipPath
clipPathUnits="userSpaceOnUse" clipPathUnits="userSpaceOnUse"
id="clipPath904"> id="clipPath904">
@@ -77,111 +180,50 @@
id="rect906" id="rect906"
style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" /> style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" />
</clipPath> </clipPath>
<linearGradient
id="linearGradient1093"
inkscape:collect="always">
<stop
id="stop1089"
offset="0"
style="stop-color:#4fd2fd;stop-opacity:1" />
<stop
id="stop1091"
offset="1"
style="stop-color:#0aa8dc;stop-opacity:1" />
</linearGradient>
<clipPath <clipPath
id="clipPath1567" clipPathUnits="userSpaceOnUse"
clipPathUnits="userSpaceOnUse"> id="clipPath1057">
<circle <rect
transform="rotate(-135)" y="4"
r="24" x="208"
cy="-134.35028" height="48"
cx="-196.57568" width="96"
id="circle1569" id="rect1055"
style="display:inline;opacity:1;vector-effect:none;fill:url(#radialGradient1571);fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" /> style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" />
</clipPath> </clipPath>
<radialGradient
r="24"
fy="222.27728"
fx="40.287689"
cy="222.27728"
cx="40.287689"
gradientTransform="matrix(1.3314563,0,0,1.3314563,-253.92929,-440.0255)"
gradientUnits="userSpaceOnUse"
id="radialGradient1571"
xlink:href="#linearGradient1093"
inkscape:collect="always" />
<clipPath <clipPath
id="clipPath1584" clipPathUnits="userSpaceOnUse"
clipPathUnits="userSpaceOnUse"> id="clipPath1061">
<circle <rect
transform="rotate(-45)" y="4"
r="24" x="208"
cy="195.16147" height="48"
cx="-132.93608" width="96"
id="circle1586" id="rect1059"
style="display:inline;opacity:1;vector-effect:none;fill:url(#radialGradient1588);fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" /> style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" />
</clipPath> </clipPath>
<radialGradient
r="24"
fy="222.27728"
fx="40.287689"
cy="222.27728"
cx="40.287689"
gradientTransform="matrix(1.3314563,0,0,1.3314563,-190.28968,-110.51374)"
gradientUnits="userSpaceOnUse"
id="radialGradient1588"
xlink:href="#linearGradient1093"
inkscape:collect="always" />
<clipPath <clipPath
id="clipPath1757" clipPathUnits="userSpaceOnUse"
clipPathUnits="userSpaceOnUse"> id="clipPath904-3">
<circle <rect
r="120.00001" y="4"
cy="-200" x="208"
cx="36" height="48"
id="circle1759" width="96"
style="display:inline;opacity:1;fill:#424048;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.99999981, 1.99999992;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" id="rect906-6"
transform="rotate(90)" /> style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1091">
<rect
y="4"
x="208"
height="48"
width="96"
id="rect1088"
style="opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:15.99999905;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1" />
</clipPath> </clipPath>
<linearGradient
gradientTransform="translate(114.19091,0.00682385)"
inkscape:collect="always"
xlink:href="#linearGradient1654-6"
id="linearGradient1640-3"
x1="8"
y1="264"
x2="120"
y2="264"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient1654-6">
<stop
style="stop-color:#a51d2d;stop-opacity:1"
offset="0"
id="stop1642-7" />
<stop
id="stop1644-5"
offset="0.03432177"
style="stop-color:#ed333b;stop-opacity:1" />
<stop
style="stop-color:#c01c28;stop-opacity:1"
offset="0.07062413"
id="stop1646-3" />
<stop
id="stop1648-5"
offset="0.92767543"
style="stop-color:#c01c28;stop-opacity:1" />
<stop
style="stop-color:#ed333b;stop-opacity:1"
offset="0.96428573"
id="stop1650-6" />
<stop
style="stop-color:#c01c28;stop-opacity:1"
offset="1"
id="stop1652-2" />
</linearGradient>
</defs> </defs>
<sodipodi:namedview <sodipodi:namedview
stroke="#ef2929" stroke="#ef2929"
@@ -192,9 +234,9 @@
borderopacity="0.25490196" borderopacity="0.25490196"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="4" inkscape:zoom="0.99999999"
inkscape:cx="72.243614" inkscape:cx="-59.599388"
inkscape:cy="53.509759" inkscape:cy="168.31056"
inkscape:current-layer="layer9" inkscape:current-layer="layer9"
showgrid="false" showgrid="false"
inkscape:grid-bbox="true" inkscape:grid-bbox="true"
@@ -202,12 +244,12 @@
inkscape:showpageshadow="false" inkscape:showpageshadow="false"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1016" inkscape:window-height="1016"
inkscape:window-x="0" inkscape:window-x="1600"
inkscape:window-y="27" inkscape:window-y="27"
width="400px" width="400px"
height="300px" height="300px"
inkscape:snap-nodes="true" inkscape:snap-nodes="true"
inkscape:snap-bbox="false" inkscape:snap-bbox="true"
objecttolerance="7" objecttolerance="7"
gridtolerance="12" gridtolerance="12"
guidetolerance="13" guidetolerance="13"
@@ -229,7 +271,8 @@
inkscape:snap-center="true" inkscape:snap-center="true"
inkscape:snap-object-midpoints="true" inkscape:snap-object-midpoints="true"
inkscape:snap-midpoints="true" inkscape:snap-midpoints="true"
inkscape:snap-smooth-nodes="true"> inkscape:snap-smooth-nodes="true"
inkscape:snap-text-baseline="true">
<inkscape:grid <inkscape:grid
type="xygrid" type="xygrid"
id="grid5883" id="grid5883"
@@ -248,14 +291,14 @@
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="12,39" position="12,64"
orientation="1,0" orientation="1,0"
id="guide1075" id="guide1075"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="72,104" position="64,104"
orientation="0,1" orientation="0,1"
id="guide1099" id="guide1099"
inkscape:locked="false" inkscape:locked="false"
@@ -276,21 +319,21 @@
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="0,72" position="9.2651362e-08,64"
orientation="1,0" orientation="1,0"
id="guide867" id="guide867"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="120,58" position="120,64"
orientation="1,0" orientation="1,0"
id="guide869" id="guide869"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="84.25,116" position="64,116"
orientation="0,1" orientation="0,1"
id="guide871" id="guide871"
inkscape:locked="false" inkscape:locked="false"
@@ -308,14 +351,14 @@
empopacity="0.08627451" empopacity="0.08627451"
dotted="true" /> dotted="true" />
<sodipodi:guide <sodipodi:guide
position="24,37" position="24,64"
orientation="1,0" orientation="1,0"
id="guide877" id="guide877"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="116,58" position="116,64"
orientation="1,0" orientation="1,0"
id="guide879" id="guide879"
inkscape:locked="false" inkscape:locked="false"
@@ -329,21 +372,21 @@
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="59.75,12" position="64,12"
orientation="0,1" orientation="0,1"
id="guide883" id="guide883"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="8,39" position="8,64"
orientation="1,0" orientation="1,0"
id="guide885" id="guide885"
inkscape:locked="false" inkscape:locked="false"
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="128,56" position="128,64"
orientation="1,0" orientation="1,0"
id="guide887" id="guide887"
inkscape:locked="false" inkscape:locked="false"
@@ -357,7 +400,7 @@
inkscape:label="" inkscape:label=""
inkscape:color="rgb(0,0,255)" /> inkscape:color="rgb(0,0,255)" />
<sodipodi:guide <sodipodi:guide
position="56,24" position="64,24"
orientation="0,1" orientation="0,1"
id="guide899" id="guide899"
inkscape:locked="false" inkscape:locked="false"
@@ -439,183 +482,94 @@
</metadata> </metadata>
<g <g
id="layer1" id="layer1"
inkscape:label="Icon" inkscape:label="App Icon"
inkscape:groupmode="layer" inkscape:groupmode="layer"
style="display:inline" style="display:inline"
transform="translate(0,-172)"> transform="translate(0,-172)">
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="baseplate"
style="display:none"
sodipodi:insensitive="true">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.08791494px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.33264872;enable-background:new"
x="7.9499588"
y="148.65199"
id="context"
inkscape:label="context"><tspan
sodipodi:role="line"
id="tspan2716"
x="7.9499588"
y="148.65199"
style="stroke-width:0.33264872">apps</tspan></text>
<text
inkscape:label="icon-name"
id="text3021"
y="157.23398"
x="7.7533054"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:6.08791494px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.33264872;enable-background:new"
xml:space="preserve"><tspan
y="157.23398"
x="7.7533054"
id="tspan3023"
sodipodi:role="line"
style="stroke-width:0.33264872">org.gnome.Podcasts</tspan></text>
<g
style="display:inline;fill:#000000;enable-background:new"
transform="matrix(7.9911709,0,0,8.0036407,-167.7909,-4846.0776)"
id="g12027"
inkscape:export-xdpi="12"
inkscape:export-ydpi="12" />
<rect
style="display:inline;overflow:visible;visibility:visible;fill:#f0f0f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate"
id="rect13805"
width="128"
height="128"
x="9.2651362e-08"
y="172"
inkscape:label="512x512" />
<g
id="g883"
style="fill:none;fill-opacity:0.25098039;stroke:#a579b3;stroke-opacity:1"
transform="translate(-24,24)" />
<g
id="g900"
style="fill:none;fill-opacity:0.25098039;stroke:#a579b3;stroke-opacity:1"
transform="translate(-24,24)" />
<g
id="g1168"
transform="matrix(0.25,0,0,0.25,6.9488522e-8,225)">
<rect
ry="32"
rx="32"
y="-180"
x="96"
height="448"
width="319.99979"
id="rect1110"
style="opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
<rect
ry="32"
rx="32"
y="-164"
x="48"
height="416"
width="416"
id="rect1110-8"
style="display:inline;opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
<rect
ry="32"
rx="32"
y="-116"
x="32"
height="320"
width="448"
id="rect1110-8-9"
style="display:inline;opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
<circle
cx="256"
cy="44"
r="240"
id="path1142"
style="opacity:0.1;fill:#2864b0;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
</g>
</g>
<g <g
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer9" id="layer9"
inkscape:label="hires" inkscape:label="icons"
style="display:inline"> style="display:inline">
<g <g
id="g915" id="g1050">
transform="translate(-114.19091,-0.00683594)">
<rect <rect
style="display:inline;opacity:1;fill:url(#linearGradient1640-3);fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999995, 0.49999997;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" style="display:inline;opacity:1;fill:url(#linearGradient1640);fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999995, 0.49999997;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
id="rect1025-9" id="rect1025"
width="112" width="112"
height="24" height="24"
x="122.19091" x="8"
y="252.00684" y="264"
rx="8" rx="8"
ry="8" /> ry="8" />
<rect <rect
ry="8" ry="8.8421059"
rx="8" rx="8"
y="196.00685" y="200"
x="122.19091" x="8"
height="75.999992" height="83.999992"
width="112" width="112"
id="rect927-7-1" id="rect927-7"
style="display:inline;opacity:1;fill:#ed333b;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999995, 0.49999997;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" /> style="display:inline;opacity:1;fill:#ed333b;fill-opacity:1;stroke:none;stroke-width:0.26282874;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.05131493, 0.52565746;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
</g>
<path <path
clip-path="none" sodipodi:nodetypes="ccccc"
style="display:inline;fill:#949390;fill-opacity:1;stroke:#949390;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new" inkscape:connector-curvature="0"
d="m 35.999995,270 h 56 l -4,-10 h -48 z"
id="path1083-9" id="path1083-9"
inkscape:connector-curvature="0" d="m 36,281.99999 h 56 l -4,-10 H 40 Z"
sodipodi:nodetypes="ccccc" /> style="display:inline;fill:#5e5c64;fill-opacity:1;stroke:#5e5c64;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new"
clip-path="none" />
<rect <rect
style="display:inline;opacity:1;fill:#6b696c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" y="282"
id="rect915"
width="64"
height="6.0000076"
x="32" x="32"
y="270" /> height="6.0000076"
<path width="64"
style="display:inline;enable-background:new;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999997;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999998, 0.49999998000000001;stroke-dashoffset:0;stroke-opacity:1" id="rect915"
d="M 23.999999,204 H 104 l 8,8 v 44.00001 H 15.999999 V 212 Z"
id="path1203-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<g
id="g1565">
<rect
y="218"
x="16"
height="28"
width="96"
id="rect1050"
style="display:inline;opacity:1;fill:#424048;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" /> style="display:inline;opacity:1;fill:#424048;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path1203-6"
d="m 24,207.99999 h 80 l 8,8 V 268 H 16 v -52.00001 z"
style="display:inline;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999997;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999998, 0.49999998;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
<g
id="g1565"
style="display:inline;enable-background:new"
transform="translate(0,7.999989)">
<rect
style="display:inline;opacity:1;fill:#424048;fill-opacity:1;stroke:none;stroke-width:1.06904471;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
id="rect1050"
width="96"
height="31.999985"
x="16"
y="216.00002" />
<circle
style="display:inline;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999996, 0.49999998;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
id="path1060-5"
cx="39.999992"
cy="232"
r="6" />
<circle <circle
r="6" r="6"
cy="232" cy="232"
cx="39.999992"
id="path1060-5"
style="display:inline;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999996, 0.49999998;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
<circle
style="display:inline;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999996, 0.49999998;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
id="circle1062-6"
cx="87.999992" cx="87.999992"
cy="232" id="circle1062-6"
r="6" /> style="display:inline;opacity:1;fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.99999996, 0.49999998;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
<rect <rect
y="226" style="display:inline;opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:3.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1;enable-background:new"
x="51.999992"
height="12"
width="24"
id="rect1271-3" id="rect1271-3"
style="display:inline;opacity:1;fill:#949390;fill-opacity:1;stroke:none;stroke-width:3.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:11.19999981;stroke-opacity:1;enable-background:new" /> width="24"
height="12"
x="51.999992"
y="226" />
<path <path
sodipodi:nodetypes="sssss" transform="matrix(0.25,0,0,0.25,-4.5e-6,225.00001)"
inkscape:connector-curvature="0"
id="ellipse900"
d="M 272,28 C 272,89.855892 221.85589,140 160,140 98.144108,140 48,89.855892 48,28 48,-33.855892 98.144108,-84 160,-84 c 61.85589,0 112,50.144108 112,112 z"
clip-path="url(#clipPath904)"
style="display:inline;opacity:0.5;fill:#424048;fill-opacity:1;stroke:none;stroke-width:0.99999982;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.99999983, 1.99999994;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" style="display:inline;opacity:0.5;fill:#424048;fill-opacity:1;stroke:none;stroke-width:0.99999982;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.99999983, 1.99999994;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
transform="matrix(0.25,0,0,0.25,-4.5e-6,225.00001)" /> clip-path="url(#clipPath904)"
d="M 272,28 C 272,89.855892 221.85589,140 160,140 98.144108,140 48,89.855892 48,28 48,-33.855892 98.144108,-84 160,-84 c 61.85589,0 112,50.144108 112,112 z"
id="ellipse900"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssss" />
</g>
</g> </g>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 19 KiB

+5 -1
View File
@@ -3,7 +3,11 @@ scalable_dir = join_paths('hicolor', 'scalable', 'apps')
install_data( install_data(
join_paths(scalable_dir, 'org.gnome.Podcasts.svg'), join_paths(scalable_dir, 'org.gnome.Podcasts.svg'),
install_dir: join_paths(datadir, 'icons', scalable_dir), install_dir: join_paths(datadir, 'icons', scalable_dir),
rename: '@0@.svg'.format(application_id) )
install_data(
join_paths(scalable_dir, 'org.gnome.Podcasts.Devel.svg'),
install_dir: join_paths(datadir, 'icons', scalable_dir),
) )
symbolic_dir = join_paths('hicolor', 'symbolic', 'apps') symbolic_dir = join_paths('hicolor', 'symbolic', 'apps')
+29 -2
View File
@@ -2,7 +2,7 @@ subdir('icons')
desktop_conf = configuration_data() desktop_conf = configuration_data()
desktop_conf.set('icon', application_id) desktop_conf.set('icon', application_id)
i18n.merge_file ('desktop-file', desktop_file = i18n.merge_file ('desktop-file',
type: 'desktop', type: 'desktop',
input: configure_file( input: configure_file(
input: files('org.gnome.Podcasts.desktop.in.in'), input: files('org.gnome.Podcasts.desktop.in.in'),
@@ -14,10 +14,20 @@ i18n.merge_file ('desktop-file',
install: true, install: true,
install_dir: join_paths (datadir, 'applications') install_dir: join_paths (datadir, 'applications')
) )
desktop_file_validate = find_program('desktop-file-validate', required: false)
if desktop_file_validate.found()
test(
'validate-desktop',
desktop_file_validate,
args: [
desktop_file.full_path()
]
)
endif
appdata_conf = configuration_data() appdata_conf = configuration_data()
appdata_conf.set('appid', application_id) appdata_conf.set('appid', application_id)
i18n.merge_file ('appdata-file', appdata_file = i18n.merge_file ('appdata-file',
input: configure_file( input: configure_file(
input: files('org.gnome.Podcasts.appdata.xml.in.in'), input: files('org.gnome.Podcasts.appdata.xml.in.in'),
output: 'org.gnome.Podcasts.appdata.xml.in', output: 'org.gnome.Podcasts.appdata.xml.in',
@@ -28,6 +38,16 @@ i18n.merge_file ('appdata-file',
install: true, install: true,
install_dir: join_paths (datadir, 'metainfo') install_dir: join_paths (datadir, 'metainfo')
) )
appstream_util = find_program('appstream-util', required: false)
if appstream_util.found()
test(
'validate-appdata', appstream_util,
args: [
'validate-relax', '--nonet', appdata_file.full_path()
]
)
endif
install_data('org.gnome.Podcasts.gschema.xml', install_dir: join_paths(datadir, 'glib-2.0', 'schemas')) install_data('org.gnome.Podcasts.gschema.xml', install_dir: join_paths(datadir, 'glib-2.0', 'schemas'))
@@ -38,4 +58,11 @@ configure_file(
install_dir: join_paths(datadir,'dbus-1', 'services') install_dir: join_paths(datadir,'dbus-1', 'services')
) )
podcasts_resources = gnome.compile_resources(
'resources',
'resources.xml',
gresource_bundle: true,
source_dir: meson.current_build_dir()
)
meson.add_install_script('../../scripts/compile-gschema.py') meson.add_install_script('../../scripts/compile-gschema.py')
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<component type="desktop"> <component type="desktop-application">
<id>@appid@</id> <id>@appid@</id>
<name>Podcasts</name> <name>Podcasts</name>
<project_license>GPL-3.0</project_license> <project_license>GPL-3.0</project_license>
@@ -24,13 +24,30 @@
</screenshot> </screenshot>
</screenshots> </screenshots>
<releases> <releases>
<release version="0.4.6" date="2018-10-07">
<description>
<p>
After a month of work, the new version of Podcasts brings Desktop integration with MPRIS,
further UX polish, and a couple bugfixes and improvements.
Additionally existing translations were updated and 9 new were added.
</p>
<ul>
<li>Brazilian Portuguese, Swedish, Italian, Friulian, Hungarian, Croatian, Latvian, Czech and Catalan Translations were added.</li>
<li>The audio player now can integrate with Desktop Environments (MPRIS2)</li>
<li>Further UI and UX polishing and a handful bug fixes</li>
<li>Update to account for the GNOME 3.32 HIG changes</li>
<li>Openssl 1.1 support</li>
<li>Fixed a performance regression when updating RSS Feeds</li>
</ul>
</description>
</release>
<release version="0.4.5" date="2018-08-31"> <release version="0.4.5" date="2018-08-31">
<description> <description>
<p> <p>
Podcasts 0.4.5 brings a month of bug fixes, performance improvements and initial tranlations support. Podcasts 0.4.5 brings a month of bug fixes, performance improvements and initial tranlations support.
</p> </p>
<ul> <ul>
<li>Finish, Polish, Turkish, Spanish, German, Galician, Indonesian, Korean Translations were added.</li> <li>Finish, Polish, Turkish, Spanish, German, Galician, Indonesian and Korean Translations were added.</li>
<li>Views now adapt better to different window sizes, thanks to libhandy HdyColumn</li> <li>Views now adapt better to different window sizes, thanks to libhandy HdyColumn</li>
<li>The update indacator was moved to an In-App notification</li> <li>The update indacator was moved to an In-App notification</li>
<li>Performance improvments when loading Show Cover images.</li> <li>Performance improvments when loading Show Cover images.</li>
@@ -46,7 +63,18 @@
</description> </description>
</release> </release>
</releases> </releases>
<kudos>
<kudo>ModernToolkit</kudo>
<kudo>HiDpiIcon</kudo>
</kudos>
<launchable type="desktop-id">@appid@.desktop</launchable>
<url type="homepage">https://wiki.gnome.org/Apps/Podcasts</url> <url type="homepage">https://wiki.gnome.org/Apps/Podcasts</url>
<url type="bugtracker">https://gitlab.gnome.org/World/podcasts/issues/</url>
<url type="donation">http://www.gnome.org/friends/</url>
<translation type="gettext">gnome-podcasts</translation>
<project_group>GNOME</project_group>
<update_contact>jpetridis@gnome.org</update_contact> <update_contact>jpetridis@gnome.org</update_contact>
<developer_name>Jordan Petridis</developer_name> <developer_name>Jordan Petridis</developer_name>
</component> </component>
-1
View File
@@ -14,7 +14,6 @@
<file compressed="true" preprocess="xml-stripblanks">gtk/player_toolbar.ui</file> <file compressed="true" preprocess="xml-stripblanks">gtk/player_toolbar.ui</file>
<file compressed="true" preprocess="xml-stripblanks">icons/skip-back-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks">icons/skip-back-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks">icons/skip-forward-symbolic.svg</file> <file compressed="true" preprocess="xml-stripblanks">icons/skip-forward-symbolic.svg</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/prefs.ui</file>
<file compressed="true">gtk/style.css</file> <file compressed="true">gtk/style.css</file>
</gresource> </gresource>
</gresources> </gresources>
+190 -274
View File
@@ -1,48 +1,129 @@
// app.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![allow(new_without_default)] #![allow(new_without_default)]
use gio::{self, prelude::*, ActionMapExt, SettingsExt}; use glib::subclass;
use glib::{self, Variant}; use glib::subclass::prelude::*;
use glib::translate::*;
use glib::{glib_object_impl, glib_object_subclass, glib_object_wrapper, glib_wrapper};
use gio::subclass::application::ApplicationImplExt;
use gio::{self, prelude::*, ActionMapExt, ApplicationFlags, SettingsExt};
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use gettextrs::{bindtextdomain, setlocale, textdomain, LocaleCategory}; use gettextrs::{bindtextdomain, setlocale, textdomain, LocaleCategory};
use crossbeam_channel::{unbounded, Receiver, Sender}; use crossbeam_channel::Receiver;
use fragile::Fragile; use fragile::Fragile;
use podcasts_data::Show; use podcasts_data::Show;
use headerbar::Header; use crate::settings;
use prefs::Prefs; use crate::stacks::PopulatedState;
use settings::{self, WindowGeometry}; use crate::utils;
use stacks::{Content, PopulatedState}; use crate::widgets::appnotif::{InAppNotification, SpinnerState, State};
use utils; use crate::widgets::show_menu::{mark_all_notif, remove_show_notif, ShowMenu};
use widgets::about_dialog; use crate::window::MainWindow;
use widgets::appnotif::{InAppNotification, SpinnerState, State};
use widgets::player;
use widgets::show_menu::{mark_all_notif, remove_show_notif, ShowMenu};
use std::cell::RefCell; use std::cell::RefCell;
use std::env; use std::env;
use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use i18n::i18n; use crate::config::{APP_ID, LOCALEDIR};
use crate::i18n::i18n;
pub(crate) const APP_ID: &str = env!("APP_ID"); pub struct PdApplicationPrivate {
pub(crate) const VERSION: &str = env!("VERSION"); window: RefCell<Option<MainWindow>>,
settings: RefCell<Option<gio::Settings>>,
}
/// Creates an action named `name` in the action map `T with the handler `F` impl ObjectSubclass for PdApplicationPrivate {
fn action<T, F>(thing: &T, name: &str, action: F) const NAME: &'static str = "PdApplication";
where type ParentType = gtk::Application;
T: ActionMapExt, type Instance = subclass::simple::InstanceStruct<Self>;
for<'r, 's> F: Fn(&'r gio::SimpleAction, &'s Option<Variant>) + 'static, type Class = subclass::simple::ClassStruct<Self>;
{
// Create a stateless, parameterless action glib_object_subclass!();
let act = gio::SimpleAction::new(name, None);
// Connect the handler fn new() -> Self {
act.connect_activate(action); Self {
// Add it to the map window: RefCell::new(None),
thing.add_action(&act); settings: RefCell::new(None),
}
}
}
impl ObjectImpl for PdApplicationPrivate {
glib_object_impl!();
}
impl gio::subclass::prelude::ApplicationImpl for PdApplicationPrivate {
fn activate(&self, app: &gio::Application) {
debug!("GtkApplication<PdApplication>::activate");
if let Some(ref window) = *self.window.borrow() {
// Ideally Gtk4/GtkBuilder make this irrelvent
window.show_all();
window.present();
info!("Window presented");
return;
}
let app = app.clone().downcast::<PdApplication>().expect("How?");
let window = MainWindow::new(&app);
window.setup_gactions();
window.show_all();
window.present();
self.window.replace(Some(window));
// Setup the Action channel
gtk::timeout_add(25, clone!(app => move || app.setup_action_channel()));
}
fn startup(&self, app: &gio::Application) {
debug!("GtkApplication<PdApplication>::startup");
self.parent_startup(app);
let settings = gio::Settings::new("org.gnome.Podcasts");
let cleanup_date = settings::get_cleanup_date(&settings);
// Garbage collect watched episodes from the disk
utils::cleanup(cleanup_date);
self.settings.replace(Some(settings));
let app = app.clone().downcast::<PdApplication>().expect("How?");
app.setup_timed_callbacks();
}
}
impl gtk::subclass::application::GtkApplicationImpl for PdApplicationPrivate {}
glib_wrapper! {
pub struct PdApplication(Object<subclass::simple::InstanceStruct<PdApplicationPrivate>, subclass::simple::ClassStruct<PdApplicationPrivate>, PdApplicationClass>) @extends gio::Application, gtk::Application;
match fn {
get_type => || PdApplicationPrivate::get_type().to_glib(),
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -65,219 +146,69 @@ pub(crate) enum Action {
InitShowMenu(Fragile<ShowMenu>), InitShowMenu(Fragile<ShowMenu>),
EmptyState, EmptyState,
PopulatedState, PopulatedState,
RaiseWindow,
} }
#[derive(Debug, Clone)] impl PdApplication {
pub(crate) struct App { pub(crate) fn new() -> Self {
instance: gtk::Application, let application = glib::Object::new(
window: gtk::ApplicationWindow, PdApplication::static_type(),
overlay: gtk::Overlay, &[
settings: gio::Settings, ("application-id", &Some(APP_ID)),
content: Rc<Content>, ("flags", &ApplicationFlags::empty()),
headerbar: Rc<Header>, ],
player: Rc<player::PlayerWidget>, )
updater: RefCell<Option<InAppNotification>>, .expect("Application initialization failed...")
sender: Sender<Action>, .downcast::<PdApplication>()
receiver: Receiver<Action>, .expect("Congrats, you have won a prize for triggering an impossible outcome");
}
impl App { application.set_resource_base_path(Some("/org/gnome/Podcasts"));
pub(crate) fn new(application: &gtk::Application) -> Rc<Self> {
let settings = gio::Settings::new("org.gnome.Podcasts");
let (sender, receiver) = unbounded(); application
let window = gtk::ApplicationWindow::new(application);
window.set_title(&i18n("Podcasts"));
if APP_ID.ends_with("Devel") {
window.get_style_context().map(|c| c.add_class("devel"));
}
let weak_s = settings.downgrade();
let weak_app = application.downgrade();
window.connect_delete_event(move |window, _| {
let app = match weak_app.upgrade() {
Some(a) => a,
None => return Inhibit(false),
};
let settings = match weak_s.upgrade() {
Some(s) => s,
None => return Inhibit(false),
};
info!("Saving window position");
WindowGeometry::from_window(&window).write(&settings);
info!("Application is exiting");
app.quit();
Inhibit(false)
});
// Create a content instance
let content = Content::new(&sender).expect("Content initialization failed.");
// Create the headerbar
let header = Header::new(&content, &sender);
// Add the Headerbar to the window.
window.set_titlebar(&header.container);
// Add the content main stack to the overlay.
let overlay = gtk::Overlay::new();
overlay.add(&content.get_stack());
let wrap = gtk::Box::new(gtk::Orientation::Vertical, 0);
// Add the overlay to the main Box
wrap.add(&overlay);
let player = player::PlayerWidget::new(&sender);
// Add the player to the main Box
wrap.add(&player.action_bar);
let updater = RefCell::new(None);
window.add(&wrap);
let app = App {
instance: application.clone(),
window,
settings,
overlay,
headerbar: header,
content,
player,
updater,
sender,
receiver,
};
Rc::new(app)
}
fn init(app: &Rc<Self>) {
let cleanup_date = settings::get_cleanup_date(&app.settings);
// Garbage collect watched episodes from the disk
utils::cleanup(cleanup_date);
app.setup_gactions();
app.setup_timed_callbacks();
// Retrieve the previous window position and size.
WindowGeometry::from_settings(&app.settings).apply(&app.window);
// Setup the Action channel
gtk::timeout_add(25, clone!(app => move || app.setup_action_channel()));
} }
fn setup_timed_callbacks(&self) { fn setup_timed_callbacks(&self) {
self.setup_dark_theme(); self.setup_dark_theme();
self.setup_refresh_on_startup();
self.setup_auto_refresh();
} }
fn setup_dark_theme(&self) { fn setup_dark_theme(&self) {
let data = PdApplicationPrivate::from_instance(self);
if let Some(ref settings) = *data.settings.borrow() {
let gtk_settings = gtk::Settings::get_default().unwrap(); let gtk_settings = gtk::Settings::get_default().unwrap();
self.settings.bind( settings.bind(
"dark-theme", "dark-theme",
&gtk_settings, &gtk_settings,
"gtk-application-prefer-dark-theme", "gtk-application-prefer-dark-theme",
gio::SettingsBindFlags::DEFAULT, gio::SettingsBindFlags::DEFAULT,
); );
} else {
debug_assert!(false, "Well how'd you manage that?");
} }
fn setup_refresh_on_startup(&self) {
// Update the feeds right after the Application is initialized.
let sender = self.sender.clone();
if self.settings.get_boolean("refresh-on-startup") {
info!("Refresh on startup.");
let s: Option<Vec<_>> = None;
utils::refresh(s, sender.clone());
}
}
fn setup_auto_refresh(&self) {
let refresh_interval = settings::get_refresh_interval(&self.settings).num_seconds() as u32;
info!("Auto-refresh every {:?} seconds.", refresh_interval);
let sender = self.sender.clone();
gtk::timeout_add_seconds(refresh_interval, move || {
let s: Option<Vec<_>> = None;
utils::refresh(s, sender.clone());
glib::Continue(true)
});
}
/// Define the `GAction`s.
///
/// Used in menus and the keyboard shortcuts dialog.
#[cfg_attr(rustfmt, rustfmt_skip)]
fn setup_gactions(&self) {
let sender = &self.sender;
let weak_win = self.window.downgrade();
// Create the `refresh` action.
//
// This will trigger a refresh of all the shows in the database.
action(&self.window, "refresh", clone!(sender => move |_, _| {
gtk::idle_add(clone!(sender => move || {
let s: Option<Vec<_>> = None;
utils::refresh(s, sender.clone());
glib::Continue(false)
}));
}));
self.instance.set_accels_for_action("win.refresh", &["<primary>r"]);
// Create the `OPML` import action
action(&self.window, "import", clone!(sender, weak_win => move |_, _| {
weak_win.upgrade().map(|win| utils::on_import_clicked(&win, &sender));
}));
// Create the action that shows a `gtk::AboutDialog`
action(&self.window, "about", clone!(weak_win => move |_, _| {
weak_win.upgrade().map(|win| about_dialog(&win));
}));
// Create the quit action
let weak_instance = self.instance.downgrade();
action(&self.window, "quit", move |_, _| {
weak_instance.upgrade().map(|app| app.quit());
});
self.instance.set_accels_for_action("win.quit", &["<primary>q"]);
let weak_settings = self.settings.downgrade();
action(&self.window, "preferences", clone!(weak_win => move |_, _| {
let (win, settings) = match (weak_win.upgrade(), weak_settings.upgrade()) {
(Some(win), Some(settings)) => (win, settings),
_ => return,
};
let dialog = Prefs::new(&settings);
dialog.show(&win);
}));
self.instance.set_accels_for_action("win.preferences", &["<primary>e"]);
// Create the menu action
let header = Rc::downgrade(&self.headerbar);
action(&self.window, "menu", move |_, _| {
header.upgrade().map(|h| h.open_menu());
});
// Bind the hamburger menu button to `F10`
self.instance.set_accels_for_action("win.menu", &["F10"]);
} }
fn setup_action_channel(&self) -> glib::Continue { fn setup_action_channel(&self) -> glib::Continue {
if let Some(action) = self.receiver.try_recv() { use crossbeam_channel::TryRecvError;
let data = PdApplicationPrivate::from_instance(self);
if let Some(ref window) = *data.window.borrow() {
let action = match window.receiver.try_recv() {
Ok(a) => a,
Err(TryRecvError::Empty) => return glib::Continue(true),
Err(TryRecvError::Disconnected) => {
unreachable!("How the hell was the action channel dropped.")
}
};
trace!("Incoming channel action: {:?}", action); trace!("Incoming channel action: {:?}", action);
match action { match action {
Action::RefreshAllViews => self.content.update(), Action::RefreshAllViews => window.content.update(),
Action::RefreshShowsView => self.content.update_shows_view(), Action::RefreshShowsView => window.content.update_shows_view(),
Action::RefreshWidgetIfSame(id) => self.content.update_widget_if_same(id), Action::RefreshWidgetIfSame(id) => window.content.update_widget_if_same(id),
Action::RefreshEpisodesView => self.content.update_home(), Action::RefreshEpisodesView => window.content.update_home(),
Action::RefreshEpisodesViewBGR => self.content.update_home_if_background(), Action::RefreshEpisodesViewBGR => window.content.update_home_if_background(),
Action::ReplaceWidget(pd) => { Action::ReplaceWidget(pd) => {
let shows = self.content.get_shows(); let shows = window.content.get_shows();
let mut pop = shows.borrow().populated(); let pop = shows.borrow().populated();
pop.borrow_mut() pop.borrow_mut()
.replace_widget(pd.clone()) .replace_widget(pd.clone())
.map_err(|err| error!("Failed to update ShowWidget: {}", err)) .map_err(|err| error!("Failed to update ShowWidget: {}", err))
@@ -285,28 +216,28 @@ impl App {
.ok(); .ok();
} }
Action::ShowWidgetAnimated => { Action::ShowWidgetAnimated => {
let shows = self.content.get_shows(); let shows = window.content.get_shows();
let mut pop = shows.borrow().populated(); let pop = shows.borrow().populated();
pop.borrow_mut().switch_visible( pop.borrow_mut().switch_visible(
PopulatedState::Widget, PopulatedState::Widget,
gtk::StackTransitionType::SlideLeft, gtk::StackTransitionType::SlideLeft,
); );
} }
Action::ShowShowsAnimated => { Action::ShowShowsAnimated => {
let shows = self.content.get_shows(); let shows = window.content.get_shows();
let mut pop = shows.borrow().populated(); let pop = shows.borrow().populated();
pop.borrow_mut() pop.borrow_mut()
.switch_visible(PopulatedState::View, gtk::StackTransitionType::SlideRight); .switch_visible(PopulatedState::View, gtk::StackTransitionType::SlideRight);
} }
Action::HeaderBarShowTile(title) => self.headerbar.switch_to_back(&title), Action::HeaderBarShowTile(title) => window.headerbar.switch_to_back(&title),
Action::HeaderBarNormal => self.headerbar.switch_to_normal(), Action::HeaderBarNormal => window.headerbar.switch_to_normal(),
Action::MarkAllPlayerNotification(pd) => { Action::MarkAllPlayerNotification(pd) => {
let notif = mark_all_notif(pd, &self.sender); let notif = mark_all_notif(pd, &window.sender);
notif.show(&self.overlay); notif.show(&window.overlay);
} }
Action::RemoveShow(pd) => { Action::RemoveShow(pd) => {
let notif = remove_show_notif(pd, self.sender.clone()); let notif = remove_show_notif(pd, window.sender.clone());
notif.show(&self.overlay); notif.show(&window.overlay);
} }
Action::ErrorNotification(err) => { Action::ErrorNotification(err) => {
error!("An error notification was triggered: {}", err); error!("An error notification was triggered: {}", err);
@@ -316,18 +247,20 @@ impl App {
}; };
let undo_cb: Option<fn()> = None; let undo_cb: Option<fn()> = None;
let notif = InAppNotification::new(&err, 6000, callback, undo_cb); let notif = InAppNotification::new(&err, 6000, callback, undo_cb);
notif.show(&self.overlay); notif.show(&window.overlay);
} }
Action::ShowUpdateNotif(receiver) => { Action::ShowUpdateNotif(receiver) => {
let sender = self.sender.clone(); let sender = window.sender.clone();
let callback = move |revealer: gtk::Revealer| { let callback = move |revealer: gtk::Revealer| match receiver.try_recv() {
if let Some(_) = receiver.try_recv() { Err(TryRecvError::Empty) => glib::Continue(true),
Err(TryRecvError::Disconnected) => glib::Continue(false),
Ok(_) => {
revealer.set_reveal_child(false); revealer.set_reveal_child(false);
sender.send(Action::RefreshAllViews); sender
return glib::Continue(false); .send(Action::RefreshAllViews)
.expect("Action channel blew up somehow");
glib::Continue(false)
} }
glib::Continue(true)
}; };
let txt = i18n("Fetching new episodes"); let txt = i18n("Fetching new episodes");
let undo_cb: Option<fn()> = None; let undo_cb: Option<fn()> = None;
@@ -335,42 +268,48 @@ impl App {
updater.set_close_state(State::Hidden); updater.set_close_state(State::Hidden);
updater.set_spinner_state(SpinnerState::Active); updater.set_spinner_state(SpinnerState::Active);
let old = self.updater.replace(Some(updater)); let old = window.updater.replace(Some(updater));
old.map(|i| i.destroy()); old.map(|i| i.destroy());
self.updater window
.updater
.borrow() .borrow()
.as_ref() .as_ref()
.map(|i| i.show(&self.overlay)); .map(|i| i.show(&window.overlay));
} }
Action::InitEpisode(rowid) => { Action::InitEpisode(rowid) => {
let res = self.player.initialize_episode(rowid); let res = window.player.initialize_episode(rowid);
debug_assert!(res.is_ok()); debug_assert!(res.is_ok());
} }
Action::InitShowMenu(s) => { Action::InitShowMenu(s) => {
let menu = &s.get().container; let menu = &s.get().container;
self.headerbar.set_secondary_menu(menu); window.headerbar.set_secondary_menu(menu);
} }
Action::EmptyState => { Action::EmptyState => {
self.window window
.window
.lookup_action("refresh") .lookup_action("refresh")
.and_then(|action| action.downcast::<gio::SimpleAction>().ok()) .and_then(|action| action.downcast::<gio::SimpleAction>().ok())
// Disable refresh action // Disable refresh action
.map(|action| action.set_enabled(false)); .map(|action| action.set_enabled(false));
self.headerbar.switch.set_sensitive(false); window.headerbar.switch.set_sensitive(false);
self.content.switch_to_empty_views(); window.content.switch_to_empty_views();
} }
Action::PopulatedState => { Action::PopulatedState => {
self.window window
.window
.lookup_action("refresh") .lookup_action("refresh")
.and_then(|action| action.downcast::<gio::SimpleAction>().ok()) .and_then(|action| action.downcast::<gio::SimpleAction>().ok())
// Enable refresh action // Enable refresh action
.map(|action| action.set_enabled(true)); .map(|action| action.set_enabled(true));
self.headerbar.switch.set_sensitive(true); window.headerbar.switch.set_sensitive(true);
self.content.switch_to_populated(); window.content.switch_to_populated();
}
} }
Action::RaiseWindow => window.window.present(),
};
} else {
debug_assert!(false, "Huh that's odd then");
} }
glib::Continue(true) glib::Continue(true)
@@ -379,36 +318,13 @@ impl App {
pub(crate) fn run() { pub(crate) fn run() {
// Set up the textdomain for gettext // Set up the textdomain for gettext
setlocale(LocaleCategory::LcAll, ""); setlocale(LocaleCategory::LcAll, "");
bindtextdomain("gnome-podcasts", env!("LOCALEDIR")); bindtextdomain("gnome-podcasts", LOCALEDIR);
textdomain("gnome-podcasts"); textdomain("gnome-podcasts");
let application = gtk::Application::new(APP_ID, gio::ApplicationFlags::empty()) // Make sure the app icon shows up in PulseAudio settings
.expect("Application initialization failed..."); env::set_var("PULSE_PROP_application.icon_name", APP_ID);
application.set_resource_base_path("/org/gnome/Podcasts");
let weak_app = application.downgrade(); let application = Self::new();
application.connect_startup(move |_| {
info!("GApplication::startup");
weak_app.upgrade().map(|application| {
let app = Self::new(&application);
Self::init(&app);
let weak = Rc::downgrade(&app);
application.connect_activate(move |_| {
info!("GApplication::activate");
if let Some(app) = weak.upgrade() {
// Ideally Gtk4/GtkBuilder make this irrelvent
app.window.show_all();
app.window.present();
info!("Window presented");
} else {
debug_assert!(false, "I hate computers");
}
});
info!("Init complete");
});
});
// Weird magic I copy-pasted that sets the Application Name in the Shell. // Weird magic I copy-pasted that sets the Application Name in the Shell.
glib::set_application_name(&i18n("Podcasts")); glib::set_application_name(&i18n("Podcasts"));
+23
View File
@@ -0,0 +1,23 @@
/* config.rs.in
*
* Copyright 2019 Christopher Davis <brainblasted@disroot.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
pub static APP_ID: &'static str = @APP_ID@;
pub static VERSION: &'static str = @VERSION@;
pub static LOCALEDIR: &'static str = @LOCALEDIR@;
+70 -24
View File
@@ -1,3 +1,22 @@
// headerbar.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gio; use gio;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@@ -9,13 +28,13 @@ use url::Url;
use podcasts_data::{dbqueries, Source}; use podcasts_data::{dbqueries, Source};
use app::Action; use crate::app::Action;
use stacks::Content; use crate::stacks::Content;
use utils::{itunes_to_rss, refresh}; use crate::utils::{itunes_to_rss, refresh};
use std::rc::Rc; use std::rc::Rc;
use i18n::i18n; use crate::i18n::i18n;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
// TODO: Make a proper state machine for the headerbar states // TODO: Make a proper state machine for the headerbar states
@@ -32,7 +51,6 @@ pub(crate) struct Header {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct AddPopover { struct AddPopover {
container: gtk::Popover, container: gtk::Popover,
result: gtk::Label,
entry: gtk::Entry, entry: gtk::Entry,
add: gtk::Button, add: gtk::Button,
toggle: gtk::MenuButton, toggle: gtk::MenuButton,
@@ -47,7 +65,7 @@ impl AddPopover {
.ok_or_else(|| format_err!("GtkEntry blew up somehow."))?; .ok_or_else(|| format_err!("GtkEntry blew up somehow."))?;
if !(url.starts_with("https://") || url.starts_with("http://")) { if !(url.starts_with("https://") || url.starts_with("http://")) {
url = format!("http://{}", url); url = format!("http://{}", url).into();
}; };
debug!("Url: {}", url); debug!("Url: {}", url);
@@ -78,41 +96,71 @@ impl AddPopover {
.entry .entry
.get_text() .get_text()
.ok_or_else(|| format_err!("GtkEntry blew up somehow."))?; .ok_or_else(|| format_err!("GtkEntry blew up somehow."))?;
let is_input_url_empty = url.is_empty();
debug!("Url: {}", url); debug!("Url: {}", url);
if !(url.starts_with("https://") || url.starts_with("http://")) { if !(url.starts_with("https://") || url.starts_with("http://")) {
url = format!("http://{}", url); url = format!("http://{}", url).into();
}; };
debug!("Url: {}", url); debug!("Url: {}", url);
// TODO: refactor to avoid duplication
match Url::parse(&url) { match Url::parse(&url) {
Ok(u) => { Ok(u) => {
if !dbqueries::source_exists(u.as_str())? { if !dbqueries::source_exists(u.as_str())? {
self.add.set_sensitive(true); self.style_neutral(true);
self.result.hide();
self.result.set_label("");
} else { } else {
self.add.set_sensitive(false); self.style_error("You are already subscribed to this show");
self.result
.set_label(i18n("You are already subscribed to this show").as_str());
self.result.show();
} }
Ok(()) Ok(())
} }
Err(err) => { Err(err) => {
self.add.set_sensitive(false); if !is_input_url_empty {
if !url.is_empty() { self.style_error("Invalid URL");
self.result.set_label(i18n("Invalid URL").as_str());
self.result.show();
error!("Error: {}", err); error!("Error: {}", err);
} else { } else {
self.result.hide(); self.style_neutral(false);
} }
Ok(()) Ok(())
} }
} }
} }
fn style_error(&self, icon_tooltip: &str) {
self.style(
true,
false,
Some("dialog-error-symbolic"),
Some(icon_tooltip),
);
}
fn style_neutral(&self, sensitive: bool) {
self.style(false, sensitive, None, None);
}
fn style(
&self,
error: bool,
sensitive: bool,
icon_name: Option<&str>,
icon_tooltip: Option<&str>,
) {
let entry = &self.entry;
let icon_position = gtk::EntryIconPosition::Secondary;
entry.set_icon_from_icon_name(icon_position, icon_name);
if let Some(icon_tooltip_text) = icon_tooltip {
entry.set_icon_tooltip_text(icon_position, Some(i18n(icon_tooltip_text).as_str()));
}
self.add.set_sensitive(sensitive);
let error_style_class = &gtk::STYLE_CLASS_ERROR;
let style_context = entry.get_style_context();
if error {
style_context.add_class(error_style_class);
} else {
style_context.remove_class(error_style_class);
}
}
} }
impl Default for Header { impl Default for Header {
@@ -137,13 +185,11 @@ impl Default for Header {
let add_popover = builder.get_object("add_popover").unwrap(); let add_popover = builder.get_object("add_popover").unwrap();
let new_url = builder.get_object("new_url").unwrap(); let new_url = builder.get_object("new_url").unwrap();
let add_button = builder.get_object("add_button").unwrap(); let add_button = builder.get_object("add_button").unwrap();
let result = builder.get_object("result_label").unwrap();
let add = AddPopover { let add = AddPopover {
container: add_popover, container: add_popover,
entry: new_url, entry: new_url,
toggle: add_toggle, toggle: add_toggle,
add: add_button, add: add_button,
result,
}; };
Header { Header {
@@ -169,7 +215,7 @@ impl Header {
pub(crate) fn init(s: &Rc<Self>, content: &Content, sender: &Sender<Action>) { pub(crate) fn init(s: &Rc<Self>, content: &Content, sender: &Sender<Action>) {
let weak = Rc::downgrade(s); let weak = Rc::downgrade(s);
s.switch.set_stack(&content.get_stack()); s.switch.set_stack(Some(&content.get_stack()));
s.add.entry.connect_changed(clone!(weak => move |_| { s.add.entry.connect_changed(clone!(weak => move |_| {
weak.upgrade().map(|h| { weak.upgrade().map(|h| {
@@ -185,7 +231,7 @@ impl Header {
s.back.connect_clicked(clone!(weak, sender => move |_| { s.back.connect_clicked(clone!(weak, sender => move |_| {
weak.upgrade().map(|h| h.switch_to_normal()); weak.upgrade().map(|h| h.switch_to_normal());
sender.send(Action::ShowShowsAnimated); sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow");
})); }));
} }
+24 -7
View File
@@ -1,9 +1,26 @@
extern crate gettextrs; // i18n.rs
extern crate regex; //
use self::gettextrs::gettext; // Copyright 2018 Daniel Garcia Moreno <danigm@wadobo.com>
use self::gettextrs::ngettext; //
use self::regex::Captures; // This program is free software: you can redistribute it and/or modify
use self::regex::Regex; // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gettextrs::gettext;
use gettextrs::ngettext;
use regex::Captures;
use regex::Regex;
#[allow(dead_code)] #[allow(dead_code)]
fn freplace(input: String, args: &[&str]) -> String { fn freplace(input: String, args: &[&str]) -> String {
@@ -21,7 +38,7 @@ fn kreplace(input: String, kwargs: &[(&str, &str)]) -> String {
for (k, v) in kwargs { for (k, v) in kwargs {
if let Ok(re) = Regex::new(&format!("\\{{{}\\}}", k)) { if let Ok(re) = Regex::new(&format!("\\{{{}\\}}", k)) {
s = re s = re
.replace_all(&s, |_: &Captures| v.to_string().clone()) .replace_all(&s, |_: &Captures<'_>| v.to_string().clone())
.to_string(); .to_string();
} }
} }
+29 -49
View File
@@ -1,21 +1,29 @@
// main.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(clone_on_ref_ptr, blacklisted_name, match_same_arms,)
clone_on_ref_ptr,
blacklisted_name,
match_same_arms,
option_map_unit_fn
)
)] )]
#![allow(unknown_lints)] #![allow(unknown_lints)]
// Enable lint group collections // Enable lint group collections
#![warn( #![warn(nonstandard_style, edition_2018, rust_2018_idioms, bad_style, unused)]
nonstandard_style,
edition_2018,
rust_2018_idioms,
bad_style,
unused
)]
// standalone lints // standalone lints
#![warn( #![warn(
const_err, const_err,
@@ -24,8 +32,6 @@
no_mangle_generic_items, no_mangle_generic_items,
overflowing_literals, overflowing_literals,
plugin_as_library, plugin_as_library,
private_no_mangle_fns,
private_no_mangle_statics,
unconditional_recursion, unconditional_recursion,
unions_with_drop_fields, unions_with_drop_fields,
while_true, while_true,
@@ -35,15 +41,6 @@
elided_lifetime_in_paths, elided_lifetime_in_paths,
missing_copy_implementations missing_copy_implementations
)] )]
#![deny(warnings)]
extern crate gdk;
extern crate gdk_pixbuf;
extern crate gio;
extern crate glib;
extern crate gstreamer as gst;
extern crate gstreamer_player as gst_player;
extern crate gtk;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
@@ -58,28 +55,11 @@ extern crate log;
#[macro_use] #[macro_use]
extern crate pretty_assertions; extern crate pretty_assertions;
extern crate chrono;
extern crate crossbeam_channel;
extern crate fragile;
extern crate gettextrs;
extern crate html2text;
extern crate humansize;
extern crate libhandy;
extern crate loggerv;
extern crate open;
extern crate podcasts_data;
extern crate podcasts_downloader;
extern crate rayon;
extern crate regex;
extern crate reqwest;
extern crate serde_json;
extern crate url;
use log::Level; use log::Level;
use gtk::prelude::*; use gtk::prelude::*;
// http://gtk-rs.org/tuto/closures // https://gtk-rs.org/docs-src/tutorial/closures
#[macro_export] #[macro_export]
macro_rules! clone { macro_rules! clone {
(@param _) => ( _ ); (@param _) => ( _ );
@@ -102,8 +82,9 @@ mod stacks;
mod widgets; mod widgets;
mod app; mod app;
mod config;
mod headerbar; mod headerbar;
mod prefs; mod window;
mod manager; mod manager;
mod settings; mod settings;
@@ -112,7 +93,7 @@ mod utils;
mod i18n; mod i18n;
use app::App; use crate::app::PdApplication;
#[cfg(test)] #[cfg(test)]
fn init_gtk_tests() -> Result<(), failure::Error> { fn init_gtk_tests() -> Result<(), failure::Error> {
@@ -130,7 +111,7 @@ fn init_gtk_tests() -> Result<(), failure::Error> {
} }
fn main() { fn main() {
// TODO: make the the logger a cli -vv option // TODO: make the logger a cli -vv option
loggerv::init_with_level(Level::Info).expect("Error initializing loggerv."); loggerv::init_with_level(Level::Info).expect("Error initializing loggerv.");
gtk::init().expect("Error initializing gtk."); gtk::init().expect("Error initializing gtk.");
gst::init().expect("Error initializing gstreamer"); gst::init().expect("Error initializing gstreamer");
@@ -145,7 +126,7 @@ fn main() {
600, 600,
); );
App::run(); PdApplication::run();
} }
#[test] #[test]
@@ -153,8 +134,8 @@ fn main() {
// cargo seems to create new threads and gtk refuses to initialize again. // cargo seems to create new threads and gtk refuses to initialize again.
// So we run every gtk related test here. // So we run every gtk related test here.
fn test_stuff() -> Result<(), failure::Error> { fn test_stuff() -> Result<(), failure::Error> {
use headerbar::Header; use crate::headerbar::Header;
use widgets::*; use crate::widgets::*;
init_gtk_tests()?; init_gtk_tests()?;
@@ -170,7 +151,6 @@ fn test_stuff() -> Result<(), failure::Error> {
appnotif::InAppNotification::default(); appnotif::InAppNotification::default();
show_menu::ShowMenu::default(); show_menu::ShowMenu::default();
player::PlayerWidget::default();
Ok(()) Ok(())
} }
+31 -12
View File
@@ -1,3 +1,22 @@
// manager.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use failure::Error; use failure::Error;
use rayon; use rayon;
@@ -41,21 +60,13 @@ impl Progress {
}; };
ratio ratio
} }
pub(crate) fn get_total_size(&self) -> u64 {
self.total_bytes
}
pub(crate) fn get_downloaded(&self) -> u64 {
self.downloaded_bytes
}
pub(crate) fn cancel(&mut self) {
self.cancel = true;
}
} }
impl DownloadProgress for Progress { impl DownloadProgress for Progress {
fn get_downloaded(&self) -> u64 {
self.downloaded_bytes
}
fn set_downloaded(&mut self, downloaded: u64) { fn set_downloaded(&mut self, downloaded: u64) {
self.downloaded_bytes = downloaded self.downloaded_bytes = downloaded
} }
@@ -64,9 +75,17 @@ impl DownloadProgress for Progress {
self.total_bytes = bytes; self.total_bytes = bytes;
} }
fn get_size(&self) -> u64 {
self.total_bytes
}
fn should_cancel(&self) -> bool { fn should_cancel(&self) -> bool {
self.cancel self.cancel
} }
fn cancel(&mut self) {
self.cancel = true;
}
} }
lazy_static! { lazy_static! {
+77
View File
@@ -0,0 +1,77 @@
global_conf = configuration_data()
global_conf.set_quoted('APP_ID', application_id)
global_conf.set_quoted('VERSION', podcasts_version + version_suffix)
global_conf.set_quoted('LOCALEDIR', podcasts_localedir)
config_rs = configure_file(
input: 'config.rs.in',
output: 'config.rs',
configuration: global_conf
)
run_command(
'cp',
config_rs,
meson.current_source_dir(),
check: true
)
# include_bytes! only takes a string literal
resource_conf = configuration_data()
resource_conf.set_quoted('RESOURCEFILE', podcasts_resources.full_path())
resource_rs = configure_file(
input: 'static_resource.rs.in',
output: 'static_resource.rs',
configuration: resource_conf
)
run_command(
'cp',
resource_rs,
meson.current_source_dir(),
check: true
)
podcasts_sources = files(
'stacks/content.rs',
'stacks/home.rs',
'stacks/mod.rs',
'stacks/populated.rs',
'stacks/show.rs',
'widgets/aboutdialog.rs',
'widgets/appnotif.rs',
'widgets/base_view.rs',
'widgets/empty.rs',
'widgets/episode.rs',
'widgets/home_view.rs',
'widgets/mod.rs',
'widgets/player.rs',
'widgets/show.rs',
'widgets/show_menu.rs',
'widgets/shows_view.rs',
'app.rs',
'headerbar.rs',
'i18n.rs',
'main.rs',
'manager.rs',
'settings.rs',
'utils.rs'
)
cargo_release = custom_target('cargo-build',
build_by_default: true,
input: [
data_sources,
downloader_sources,
podcasts_sources,
],
output: ['gnome-podcasts'],
install: true,
install_dir: podcasts_bindir,
console: true,
depends: podcasts_resources,
command: [cargo_script,
'@SOURCE_ROOT@',
'@OUTPUT@',
meson.build_root(),
profile
])
-101
View File
@@ -1,101 +0,0 @@
use gio;
use gio::{Settings, SettingsExt};
use gtk;
use gtk::prelude::*;
use i18n::i18n;
#[derive(Debug, Clone)]
pub(crate) struct Prefs {
dialog: gtk::Window,
dark_toggle: gtk::Switch,
cleanup_value: gtk::SpinButton,
cleanup_type: gtk::ComboBox,
}
impl Default for Prefs {
fn default() -> Prefs {
let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/prefs.ui");
let dialog = builder.get_object("prefs").unwrap();
let dark_toggle = builder.get_object("dark_toggle").unwrap();
let cleanup_value = builder.get_object("cleanup_value").unwrap();
let cleanup_type = builder.get_object("cleanup_type").unwrap();
Prefs {
dialog,
dark_toggle,
cleanup_value,
cleanup_type,
}
}
}
// TODO: Refactor components into smaller state machines
impl Prefs {
pub(crate) fn new(settings: &Settings) -> Prefs {
let h = Prefs::default();
h.init(settings);
h
}
pub(crate) fn init(&self, settings: &Settings) {
settings.bind(
"dark-theme",
&self.dark_toggle,
"active",
gio::SettingsBindFlags::DEFAULT,
);
settings.bind(
"cleanup-age-time",
&self.cleanup_value,
"value",
gio::SettingsBindFlags::DEFAULT,
);
let cleanup_p = settings.get_string("cleanup-age-period").unwrap();
let mut cleanup_pos = 0;
let store = gtk::ListStore::new(&[gtk::Type::String]);
for (i, item) in [
i18n("Seconds"),
i18n("Minutes"),
i18n("Hours"),
i18n("Days"),
i18n("Weeks"),
]
.iter()
.enumerate()
{
let row: &[&dyn ToValue] = &[item];
if item.to_lowercase() == cleanup_p {
cleanup_pos = i as i32;
}
store.insert_with_values(None, &[0], &row);
}
self.cleanup_type.set_model(Some(&store));
let renderer = gtk::CellRendererText::new();
self.cleanup_type.pack_start(&renderer, true);
self.cleanup_type.add_attribute(&renderer, "text", 0);
self.cleanup_type.set_active(cleanup_pos);
let weak_settings = settings.downgrade();
let weak_store = store.downgrade();
// Totally the prettiest stairway you ever saw
self.cleanup_type.connect_changed(move |combo| {
if let Some(ref treeiter) = combo.get_active_iter() {
if let Some(store) = weak_store.upgrade() {
if let Some(s) = store.get_value(treeiter, 0).get::<&str>() {
if let Some(settings) = weak_settings.upgrade() {
settings.set_string("cleanup-age-period", &s.to_lowercase());
}
}
}
};
});
}
pub(crate) fn show(&self, parent: &gtk::ApplicationWindow) {
self.dialog.set_transient_for(Some(parent));
self.dialog.set_modal(true);
self.dialog.show_all();
}
}
+19
View File
@@ -1,3 +1,22 @@
// prefs.rs
//
// Copyright 2018 Measly Twerp <measlytwerp@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gio; use gio;
use gio::{Settings, SettingsExt}; use gio::{Settings, SettingsExt};
use gtk; use gtk;
+22 -3
View File
@@ -1,16 +1,35 @@
// content.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
use app::Action; use crate::app::Action;
use stacks::{HomeStack, ShowStack}; use crate::stacks::{HomeStack, ShowStack};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use i18n::i18n; use crate::i18n::i18n;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(crate) enum State { pub(crate) enum State {
+22 -3
View File
@@ -1,3 +1,22 @@
// home.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::StackTransitionType; use gtk::StackTransitionType;
@@ -5,9 +24,9 @@ use gtk::StackTransitionType;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
use app::Action; use crate::app::Action;
use stacks::State; use crate::stacks::State;
use widgets::{EmptyView, HomeView}; use crate::widgets::{EmptyView, HomeView};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
+89
View File
@@ -0,0 +1,89 @@
// main_stack.rs
//
// Copyright 2019 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![allow(unused)]
use crossbeam_channel::Sender;
use failure::Error;
use crate::app::Action;
use std::cell::RefCell;
use std::rc::Rc;
use crate::i18n::i18n;
use gtk::{self, prelude::*};
use crate:: widgets::{EpisodeWidget, EmptyView, ShowWidget, HomeView, ShowsView};
#[derive(Debug, Clone, Copy)]
pub (crate) enum State {
Empty, // Empty view in case you are not subbed into any shows
Home, // ListBox with the latests episodes
ShowsFlwobox, // Flowbox to browse all the shows you are subbed
ShowDetails, // 2 States, either empty or episodes list
EpisodeDetails, // WebView that shows the html description
DisoverView, // Way into the future view ??
}
struct StackWrapper {
state: State,
stack: gtk::Stack,
}
pub struct PodcastsStack {
sender: Sender<Action>,
stack: StackWrapper,
empty_view: Rc<EmptyView>,
home: Rc<HomeView>,
shows_flowbox: Rc<ShowsView>,
show_details: Rc<ShowWidget>,
// episdoe: Rc<EpisodeDetails>,
// discover: unimplemented!(),
}
impl PodcastsStack {
fn new(sender: Sender<Action>) -> Self {
let stack = StackWrapper {
state: State::Empty,
stack: gtk::Stack::new(),
};
let empty = Rc::new(EmptyView::default());
let home = HomeView::new(sender.clone(), None).expect("Could not create a HomeView");
let shows = ShowsView::new(sender.clone(), None);
let show = Rc::new(ShowWidget::default());
// let episode = EpisodeDetails::default();
// stack.add_titled(&home.borrow().get_stack(), "home", &i18n("New"));
// stack.add_titled(&shows.borrow().get_stack(), "shows", &i18n("Shows"));
PodcastsStack {
sender,
stack,
empty_view: empty,
home,
shows_flowbox: shows,
show_details: show,
}
}
}
+19
View File
@@ -1,3 +1,22 @@
// mod.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
mod content; mod content;
mod home; mod home;
mod populated; mod populated;
+21 -2
View File
@@ -1,3 +1,22 @@
// populated.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::StackTransitionType; use gtk::StackTransitionType;
@@ -8,8 +27,8 @@ use failure::Error;
use podcasts_data::dbqueries; use podcasts_data::dbqueries;
use podcasts_data::Show; use podcasts_data::Show;
use app::Action; use crate::app::Action;
use widgets::{ShowWidget, ShowsView}; use crate::widgets::{ShowWidget, ShowsView};
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
+32 -9
View File
@@ -1,15 +1,34 @@
// show.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
use podcasts_data::dbqueries::is_podcasts_populated; use podcasts_data::dbqueries::is_episodes_populated;
use app::Action; use crate::app::Action;
use stacks::content::State; use crate::stacks::content::State;
use stacks::PopulatedStack; use crate::stacks::PopulatedStack;
use utils::get_ignored_shows; use crate::utils::get_ignored_shows;
use widgets::EmptyView; use crate::widgets::EmptyView;
use std::cell::RefCell; use std::cell::RefCell;
use std::ops::Deref; use std::ops::Deref;
@@ -78,10 +97,14 @@ impl ShowStack {
fn determine_state(&mut self) -> Result<(), Error> { fn determine_state(&mut self) -> Result<(), Error> {
let ign = get_ignored_shows()?; let ign = get_ignored_shows()?;
debug!("IGNORED SHOWS {:?}", ign); debug!("IGNORED SHOWS {:?}", ign);
if is_podcasts_populated(&ign)? { if is_episodes_populated(&ign)? {
self.sender.send(Action::PopulatedState); self.sender
.send(Action::PopulatedState)
.expect("Action channel blew up somehow");
} else { } else {
self.sender.send(Action::EmptyState); self.sender
.send(Action::EmptyState)
.expect("Action channel blew up somehow");
}; };
Ok(()) Ok(())
-18
View File
@@ -1,18 +0,0 @@
use gio::{resources_register, Error, Resource};
use glib::Bytes;
pub(crate) fn init() -> Result<(), Error> {
// load the gresource binary at build time and include/link it into the final
// binary.
let res_bytes = include_bytes!("../resources/resources.gresource");
// Create Resource it will live as long the value lives.
let gbytes = Bytes::from_static(res_bytes.as_ref());
let resource = Resource::new_from_data(&gbytes)?;
// Register the resource so it won't be dropped and will continue to live in
// memory.
resources_register(&resource);
Ok(())
}
+37
View File
@@ -0,0 +1,37 @@
// static_resource.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gio::{resources_register, Error, Resource};
use glib::Bytes;
pub(crate) fn init() -> Result<(), Error> {
// load the gresource binary at build time and include/link it into the final
// binary.
let res_bytes = include_bytes!(@RESOURCEFILE@);
// Create Resource it will live as long the value lives.
let gbytes = Bytes::from_static(res_bytes.as_ref());
let resource = Resource::new_from_data(&gbytes)?;
// Register the resource so it won't be dropped and will continue to live in
// memory.
resources_register(&resource);
Ok(())
}
+103 -18
View File
@@ -1,6 +1,24 @@
// utils.rs
//
// Copyright 2018 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))] #![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
use gdk::FrameClockExt;
use gdk_pixbuf::{Object, Pixbuf}; use gdk_pixbuf::{Object, Pixbuf};
use glib::{self, object::WeakRef}; use glib::{self, object::WeakRef};
use gtk; use gtk;
@@ -23,13 +41,14 @@ use podcasts_data::pipeline;
use podcasts_data::utils::checkup; use podcasts_data::utils::checkup;
use podcasts_data::Source; use podcasts_data::Source;
use podcasts_downloader::downloader; use podcasts_downloader::downloader;
use podcasts_downloader::errors::DownloadError;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use app::Action; use crate::app::Action;
use i18n::i18n; use crate::i18n::i18n;
/// Lazy evaluates and loads widgets to the parent `container` widget. /// Lazy evaluates and loads widgets to the parent `container` widget.
/// ///
@@ -135,10 +154,10 @@ pub(crate) fn smooth_scroll_to(view: &gtk::ScrolledWindow, target: &gtk::Adjustm
let mut t = (now - start_time) as f64 / (end_time - start_time) as f64; let mut t = (now - start_time) as f64 / (end_time - start_time) as f64;
t = ease_out_cubic(t); t = ease_out_cubic(t);
adj.set_value(start + t * (end - start)); adj.set_value(start + t * (end - start));
glib::Continue(true) Continue(true)
} else { } else {
adj.set_value(end); adj.set_value(end);
glib::Continue(false) Continue(false)
} }
}); });
} }
@@ -211,7 +230,9 @@ where
{ {
rayon::spawn(move || { rayon::spawn(move || {
let (up_sender, up_receiver) = bounded(1); let (up_sender, up_receiver) = bounded(1);
sender.send(Action::ShowUpdateNotif(up_receiver)); sender
.send(Action::ShowUpdateNotif(up_receiver))
.expect("Action channel blew up somehow");
if let Some(s) = source { if let Some(s) = source {
// Refresh only specified feeds // Refresh only specified feeds
@@ -228,7 +249,9 @@ where
.ok(); .ok();
}; };
up_sender.send(true); up_sender
.send(true)
.expect("Channel was dropped unexpectedly");
}); });
} }
@@ -261,7 +284,7 @@ pub(crate) fn set_image_from_path(
.and_then(|fragile| { .and_then(|fragile| {
fragile fragile
.try_get() .try_get()
.map(|px| image.set_from_pixbuf(px)) .map(|px| image.set_from_pixbuf(Some(px)))
.map_err(From::from) .map_err(From::from)
})?; })?;
@@ -293,7 +316,9 @@ pub(crate) fn set_image_from_path(
THREADPOOL.spawn(move || { THREADPOOL.spawn(move || {
// This operation is polling and will block the thread till the download is finished // This operation is polling and will block the thread till the download is finished
if let Ok(pd) = dbqueries::get_podcast_cover_from_id(show_id) { if let Ok(pd) = dbqueries::get_podcast_cover_from_id(show_id) {
sender.send(downloader::cache_image(&pd)); sender
.send(downloader::cache_image(&pd))
.expect("channel was dropped unexpectedly");
} }
if let Ok(mut guard) = COVER_DL_REGISTRY.write() { if let Ok(mut guard) = COVER_DL_REGISTRY.write() {
@@ -305,18 +330,32 @@ pub(crate) fn set_image_from_path(
let image = image.clone(); let image = image.clone();
let s = size as i32; let s = size as i32;
gtk::timeout_add(25, move || { gtk::timeout_add(25, move || {
if let Some(path) = receiver.try_recv() { use crossbeam_channel::TryRecvError;
if let Ok(path) = path {
match receiver.try_recv() {
Err(TryRecvError::Empty) => glib::Continue(true),
Err(TryRecvError::Disconnected) => glib::Continue(false),
Ok(path) => {
match path {
Ok(path) => {
if let Ok(px) = Pixbuf::new_from_file_at_scale(&path, s, s, true) { if let Ok(px) = Pixbuf::new_from_file_at_scale(&path, s, s, true) {
if let Ok(mut hashmap) = CACHED_PIXBUFS.write() { if let Ok(mut hashmap) = CACHED_PIXBUFS.write() {
hashmap.insert((show_id, size), Mutex::new(Fragile::new(px.clone()))); hashmap
image.set_from_pixbuf(&px); .insert((show_id, size), Mutex::new(Fragile::new(px.clone())));
image.set_from_pixbuf(Some(&px));
} }
} }
} }
Err(DownloadError::NoImageLocation) => {
image.set_from_icon_name(
Some("image-x-generic-symbolic"),
gtk::IconSize::__Unknown(s),
);
}
_ => {}
}
glib::Continue(false) glib::Continue(false)
} else { }
glib::Continue(true)
} }
}); });
Ok(()) Ok(())
@@ -366,7 +405,7 @@ pub(crate) fn on_import_clicked(window: &gtk::ApplicationWindow, sender: &Sender
// Set a filter to show only xml files // Set a filter to show only xml files
let filter = FileFilter::new(); let filter = FileFilter::new();
FileFilterExt::set_name(&filter, Some(i18n("OPML file").as_str())); FileFilter::set_name(&filter, Some(i18n("OPML file").as_str()));
filter.add_mime_type("application/xml"); filter.add_mime_type("application/xml");
filter.add_mime_type("text/xml"); filter.add_mime_type("text/xml");
dialog.add_filter(&filter); dialog.add_filter(&filter);
@@ -384,12 +423,58 @@ pub(crate) fn on_import_clicked(window: &gtk::ApplicationWindow, sender: &Sender
refresh(Some(sources), sender) refresh(Some(sources), sender)
} else { } else {
let text = i18n("Failed to parse the imported file"); let text = i18n("Failed to parse the imported file");
sender.send(Action::ErrorNotification(text)); sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow");;
} }
})) }))
} else { } else {
let text = i18n("Selected file could not be accessed."); let text = i18n("Selected file could not be accessed.");
sender.send(Action::ErrorNotification(text)); sender
.send(Action::ErrorNotification(text))
.expect("Action channel blew up somehow");
}
}
}
pub(crate) fn on_export_clicked(window: &gtk::ApplicationWindow, sender: &Sender<Action>) {
use glib::translate::ToGlib;
use gtk::{FileChooserAction, FileChooserNative, FileFilter, ResponseType};
// Create the FileChooser Dialog
let dialog = FileChooserNative::new(
Some(i18n("Export shows to…").as_str()),
Some(window),
FileChooserAction::Save,
Some(i18n("_Export").as_str()),
Some(i18n("_Cancel").as_str()),
);
// Do not show hidden(.thing) files
dialog.set_show_hidden(false);
// Set a filter to show only xml files
let filter = FileFilter::new();
FileFilter::set_name(&filter, Some(i18n("OPML file").as_str()));
filter.add_mime_type("application/xml");
filter.add_mime_type("text/xml");
dialog.add_filter(&filter);
let resp = dialog.run();
debug!("Dialog Response {}", resp);
if resp == ResponseType::Accept.to_glib() {
if let Some(filename) = dialog.get_filename() {
debug!("File selected: {:?}", filename);
rayon::spawn(clone!(sender => move || {
if opml::export_from_db(filename, i18n("GNOME Podcasts Subscriptions").as_str()).is_err() {
let text = i18n("Failed to export podcasts");
sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow");
}
}))
} else {
let text = i18n("Selected file could not be accessed.");
sender
.send(Action::ErrorNotification(text))
.expect("Action channel blew up somehow");
} }
} }
} }
+35 -10
View File
@@ -1,41 +1,66 @@
use app::{APP_ID, VERSION}; // aboutdialog.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::config::{APP_ID, VERSION};
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use i18n::i18n; use crate::i18n::i18n;
// Totally copied it from fractal. // Totally copied it from fractal.
// https://gitlab.gnome.org/danigm/fractal/blob/503e311e22b9d7540089d735b92af8e8f93560c5/fractal-gtk/src/app.rs#L1883-1912 // https://gitlab.gnome.org/danigm/fractal/blob/503e311e22b9d7540089d735b92af8e8f93560c5/fractal-gtk/src/app.rs#L1883-1912
/// Given a `window` create and attach an `gtk::AboutDialog` to it. /// Given a `window` create and attach an `gtk::AboutDialog` to it.
pub(crate) fn about_dialog(window: &gtk::ApplicationWindow) { pub(crate) fn about_dialog(window: &gtk::ApplicationWindow) {
// Feel free to add yourself if you contributed. // Feel free to add yourself if you contributed.
// Please keep it sorted alphabetically
let authors = &[ let authors = &[
"Alexandre Franke",
"Carlos Soriano", "Carlos Soriano",
"Constantin Nickel", "Constantin Nickel",
"Daniel García Moreno",
"Felix Häcker",
"Gabriele Musco", "Gabriele Musco",
"Ivan Augusto", "Ivan Augusto",
"James Wykeham-Martin", "James Wykeham-Martin",
"Jordan Petridis", "Jordan Petridis",
"Julian Sparber", "Julian Sparber",
"Matthew Martin",
"Piotr Drąg",
"Rowan Lewis", "Rowan Lewis",
"Zander Brown", "Zander Brown",
]; ];
let dialog = gtk::AboutDialog::new(); let dialog = gtk::AboutDialog::new();
dialog.set_logo_icon_name(APP_ID); dialog.set_logo_icon_name(Some(APP_ID));
dialog.set_comments(i18n("Podcast Client for the GNOME Desktop.").as_str()); dialog.set_comments(Some(i18n("Podcast Client for the GNOME Desktop.").as_str()));
dialog.set_copyright("© 2017, 2018 Jordan Petridis"); dialog.set_copyright(Some("© 2017, 2018 Jordan Petridis"));
dialog.set_license_type(gtk::License::Gpl30); dialog.set_license_type(gtk::License::Gpl30);
dialog.set_modal(true); dialog.set_modal(true);
dialog.set_version(VERSION); dialog.set_version(Some(VERSION));
dialog.set_program_name(&i18n("Podcasts")); dialog.set_program_name(&i18n("Podcasts"));
dialog.set_website("https://wiki.gnome.org/Apps/Podcasts"); dialog.set_website(Some("https://wiki.gnome.org/Apps/Podcasts"));
dialog.set_website_label(i18n("Learn more about GNOME Podcasts").as_str()); dialog.set_website_label(Some(i18n("Learn more about GNOME Podcasts").as_str()));
dialog.set_transient_for(window); dialog.set_transient_for(Some(window));
dialog.set_artists(&["Tobias Bernard", "Sam Hewitt"]); dialog.set_artists(&["Tobias Bernard", "Sam Hewitt"]);
dialog.set_authors(authors); dialog.set_authors(authors);
dialog.set_translator_credits(i18n("translator-credits").as_str()); dialog.set_translator_credits(Some(i18n("translator-credits").as_str()));
dialog.connect_response(|dlg, _| dlg.destroy()); dialog.connect_response(|dlg, _| dlg.destroy());
+19
View File
@@ -1,3 +1,22 @@
// appnotif.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use glib; use glib;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
+33 -2
View File
@@ -1,5 +1,24 @@
// base_view.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::utils::smooth_scroll_to;
use gtk::{self, prelude::*, Adjustment, Orientation, PolicyType}; use gtk::{self, prelude::*, Adjustment, Orientation, PolicyType};
use utils::smooth_scroll_to;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct BaseView { pub(crate) struct BaseView {
@@ -10,9 +29,21 @@ pub(crate) struct BaseView {
impl Default for BaseView { impl Default for BaseView {
fn default() -> Self { fn default() -> Self {
let container = gtk::Box::new(Orientation::Horizontal, 0); let container = gtk::Box::new(Orientation::Horizontal, 0);
let scrolled_window = gtk::ScrolledWindow::new(None, None); // TODO: Remember to file an issue about this API
// error[E0283]: type annotations required: cannot resolve `_: gdk_pixbuf::IsA<gtk::Adjustment>`
// --> ../podcasts-gtk/src/widgets/base_view.rs:32:31
// |
// 32 | let scrolled_window = gtk::ScrolledWindow::new(None, None);
// | ^^^^^^^^^^^^^^^^^^^^^^^^
// |
// = note: required by `gtk::ScrolledWindow::new`
//
// error: aborting due to previous error
let foo: Option<&Adjustment> = None;
let scrolled_window = gtk::ScrolledWindow::new(foo.clone(), foo.clone());
scrolled_window.set_policy(PolicyType::Never, PolicyType::Automatic); scrolled_window.set_policy(PolicyType::Never, PolicyType::Automatic);
container.set_size_request(360, -1);
container.add(&scrolled_window); container.add(&scrolled_window);
container.show_all(); container.show_all();
+24 -2
View File
@@ -1,4 +1,23 @@
use app::APP_ID; // empty.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::config::APP_ID;
use gtk::{self, prelude::*}; use gtk::{self, prelude::*};
use std::ops::Deref; use std::ops::Deref;
@@ -17,7 +36,10 @@ impl Default for EmptyView {
let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/empty_view.ui"); let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/empty_view.ui");
let view: gtk::Box = builder.get_object("empty_view").unwrap(); let view: gtk::Box = builder.get_object("empty_view").unwrap();
let image: gtk::Image = builder.get_object("image").unwrap(); let image: gtk::Image = builder.get_object("image").unwrap();
image.set_from_icon_name(format!("{}-symbolic", APP_ID).as_str(), 256); image.set_from_icon_name(
Some(format!("{}-symbolic", APP_ID).as_str()),
gtk::IconSize::__Unknown(256),
);
EmptyView(view) EmptyView(view)
} }
} }
+60 -17
View File
@@ -1,3 +1,22 @@
// episode.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use glib; use glib;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@@ -13,15 +32,16 @@ use open;
use podcasts_data::dbqueries; use podcasts_data::dbqueries;
use podcasts_data::utils::get_download_folder; use podcasts_data::utils::get_download_folder;
use podcasts_data::EpisodeWidgetModel; use podcasts_data::EpisodeWidgetModel;
use podcasts_downloader::downloader::DownloadProgress;
use app::Action; use crate::app::Action;
use manager; use crate::manager;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::sync::{Arc, Mutex, TryLockError}; use std::sync::{Arc, Mutex, TryLockError};
use i18n::i18n_f; use crate::i18n::i18n_f;
lazy_static! { lazy_static! {
static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = { static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
@@ -60,11 +80,12 @@ struct InfoLabels {
local_size: gtk::Label, local_size: gtk::Label,
size_separator: gtk::Label, size_separator: gtk::Label,
total_size: gtk::Label, total_size: gtk::Label,
played_checkmark: gtk::Image,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct Buttons { struct Buttons {
container: gtk::ButtonBox, container: gtk::Box,
play: gtk::Button, play: gtk::Button,
download: gtk::Button, download: gtk::Button,
cancel: gtk::Button, cancel: gtk::Button,
@@ -89,13 +110,11 @@ impl InfoLabels {
self.title.set_text(episode.title()); self.title.set_text(episode.title());
if episode.played().is_some() { if episode.played().is_some() {
self.title self.title.get_style_context().add_class("dim-label");
.get_style_context() self.played_checkmark.show();
.map(|c| c.add_class("dim-label"));
} else { } else {
self.title self.title.get_style_context().remove_class("dim-label");
.get_style_context() self.played_checkmark.hide();
.map(|c| c.remove_class("dim-label"));
} }
} }
@@ -179,6 +198,7 @@ impl Default for EpisodeWidget {
let duration = builder.get_object("duration_label").unwrap(); let duration = builder.get_object("duration_label").unwrap();
let local_size = builder.get_object("local_size").unwrap(); let local_size = builder.get_object("local_size").unwrap();
let total_size = builder.get_object("total_size").unwrap(); let total_size = builder.get_object("total_size").unwrap();
let played_checkmark = builder.get_object("played_checkmark").unwrap();
let separator1 = builder.get_object("separator1").unwrap(); let separator1 = builder.get_object("separator1").unwrap();
let separator2 = builder.get_object("separator2").unwrap(); let separator2 = builder.get_object("separator2").unwrap();
@@ -196,6 +216,7 @@ impl Default for EpisodeWidget {
local_size, local_size,
total_size, total_size,
size_separator, size_separator,
played_checkmark,
}, },
buttons: Buttons { buttons: Buttons {
container: buttons_container, container: buttons_container,
@@ -468,7 +489,9 @@ fn on_download_clicked(ep: &EpisodeWidgetModel, sender: &Sender<Action>) -> Resu
manager::add(ep.rowid(), download_fold)?; manager::add(ep.rowid(), download_fold)?;
// Update Views // Update Views
sender.send(Action::RefreshEpisodesViewBGR); sender
.send(Action::RefreshEpisodesViewBGR)
.expect("Action channel blew up somehow");;
Ok(()) Ok(())
} }
@@ -487,9 +510,13 @@ fn on_play_bttn_clicked(
widget.info.set_title(&episode); widget.info.set_title(&episode);
// Play the episode // Play the episode
sender.send(Action::InitEpisode(episode.rowid())); sender
.send(Action::InitEpisode(episode.rowid()))
.expect("Action channel blew up somehow");;
// Refresh background views to match the normal/greyout title state // Refresh background views to match the normal/greyout title state
sender.send(Action::RefreshEpisodesViewBGR); sender
.send(Action::RefreshEpisodesViewBGR)
.expect("Action channel blew up somehow");;
Ok(()) Ok(())
} }
@@ -519,8 +546,12 @@ fn progress_bar_helper(
None => return Ok(glib::Continue(false)), None => return Ok(glib::Continue(false)),
}; };
let (fraction, downloaded) = match prog.try_lock() { let (fraction, downloaded, cancel) = match prog.try_lock() {
Ok(guard) => (guard.get_fraction(), guard.get_downloaded()), Ok(guard) => (
guard.get_fraction(),
guard.get_downloaded(),
guard.should_cancel(),
),
Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)), Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")), Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
}; };
@@ -547,7 +578,19 @@ fn progress_bar_helper(
if (fraction >= 1.0) && (!fraction.is_nan()) { if (fraction >= 1.0) && (!fraction.is_nan()) {
Ok(glib::Continue(false)) Ok(glib::Continue(false))
} else if !active { } else if !active || cancel {
// if the total size is not a number, hide it
if widget
.info
.total_size
.get_text()
.as_ref()
.map(|s| s.trim_end_matches(" MB"))
.and_then(|s| s.parse::<i32>().ok())
.is_none()
{
widget.info.total_size.hide();
}
Ok(glib::Continue(false)) Ok(glib::Continue(false))
} else { } else {
Ok(glib::Continue(true)) Ok(glib::Continue(true))
@@ -576,7 +619,7 @@ fn total_size_helper(
// Get the total_bytes. // Get the total_bytes.
let total_bytes = match prog.try_lock() { let total_bytes = match prog.try_lock() {
Ok(guard) => guard.get_total_size(), Ok(guard) => guard.get_size(),
Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)), Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")), Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
}; };
+22 -3
View File
@@ -1,3 +1,22 @@
// home_view.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use chrono::prelude::*; use chrono::prelude::*;
use failure::Error; use failure::Error;
@@ -8,9 +27,9 @@ use libhandy::{Column, ColumnExt};
use podcasts_data::dbqueries; use podcasts_data::dbqueries;
use podcasts_data::EpisodeWidgetModel; use podcasts_data::EpisodeWidgetModel;
use app::Action; use crate::app::Action;
use utils::{self, lazy_load_full}; use crate::utils::{self, lazy_load_full};
use widgets::{BaseView, EpisodeWidget}; use crate::widgets::{BaseView, EpisodeWidget};
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
+19
View File
@@ -1,3 +1,22 @@
// mod.rs
//
// Copyright 2017 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
mod aboutdialog; mod aboutdialog;
pub(crate) mod appnotif; pub(crate) mod appnotif;
mod base_view; mod base_view;
+282 -115
View File
@@ -1,6 +1,23 @@
use gst::prelude::*; // player.rs
//
// Copyright 2018 Jordan Petridis <jpetridis@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use gst::ClockTime; use gst::ClockTime;
use gst_player;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@@ -8,7 +25,7 @@ use gtk::prelude::*;
use gio::{File, FileExt}; use gio::{File, FileExt};
use glib::{SignalHandlerId, WeakRef}; use glib::{SignalHandlerId, WeakRef};
use chrono::NaiveTime; use chrono::{prelude::*, NaiveTime};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
use fragile::Fragile; use fragile::Fragile;
@@ -16,14 +33,20 @@ use fragile::Fragile;
use podcasts_data::{dbqueries, USER_AGENT}; use podcasts_data::{dbqueries, USER_AGENT};
use podcasts_data::{EpisodeWidgetModel, ShowCoverModel}; use podcasts_data::{EpisodeWidgetModel, ShowCoverModel};
use app::Action; use crate::app::Action;
use utils::set_image_from_path; use crate::config::APP_ID;
use crate::utils::set_image_from_path;
use std::cell::RefCell;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex;
use i18n::i18n; use crate::i18n::i18n;
use mpris_player::{Metadata, MprisPlayer, OrgMprisMediaPlayer2Player, PlaybackStatus};
use std::sync::Arc;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
enum SeekDirection { enum SeekDirection {
@@ -38,7 +61,7 @@ trait PlayerExt {
fn seek(&self, offset: ClockTime, direction: SeekDirection); fn seek(&self, offset: ClockTime, direction: SeekDirection);
fn fast_forward(&self); fn fast_forward(&self);
fn rewind(&self); fn rewind(&self);
fn set_playback_rate(&self, f64); fn set_playback_rate(&self, _: f64);
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -47,24 +70,37 @@ struct PlayerInfo {
show: gtk::Label, show: gtk::Label,
episode: gtk::Label, episode: gtk::Label,
cover: gtk::Image, cover: gtk::Image,
mpris: Arc<MprisPlayer>,
episode_id: RefCell<Option<i32>>,
} }
impl PlayerInfo { impl PlayerInfo {
// FIXME: create a Diesel Model of the joined episode and podcast query instead // FIXME: create a Diesel Model of the joined episode and podcast query instead
fn init(&self, episode: &EpisodeWidgetModel, podcast: &ShowCoverModel) { fn init(&self, episode: &EpisodeWidgetModel, podcast: &ShowCoverModel) {
self.episode_id.replace(Some(episode.rowid()));
self.set_cover_image(podcast); self.set_cover_image(podcast);
self.set_show_title(podcast); self.set_show_title(podcast);
self.set_episode_title(episode); self.set_episode_title(episode);
let mut metadata = Metadata::new();
metadata.artist = Some(vec![podcast.title().to_string()]);
metadata.title = Some(episode.title().to_string());
// FIXME: .image_uri() returns an http url, we should instead
// pass it the local path to the downloaded cover image.
metadata.art_url = podcast.image_uri().clone().map(From::from);
self.mpris.set_metadata(metadata);
self.mpris.set_can_play(true);
} }
fn set_episode_title(&self, episode: &EpisodeWidgetModel) { fn set_episode_title(&self, episode: &EpisodeWidgetModel) {
self.episode.set_text(episode.title()); self.episode.set_text(episode.title());
self.episode.set_tooltip_text(episode.title()); self.episode.set_tooltip_text(Some(episode.title()));
} }
fn set_show_title(&self, show: &ShowCoverModel) { fn set_show_title(&self, show: &ShowCoverModel) {
self.show.set_text(show.title()); self.show.set_text(show.title());
self.show.set_tooltip_text(show.title()); self.show.set_tooltip_text(Some(show.title()));
} }
fn set_cover_image(&self, show: &ShowCoverModel) { fn set_cover_image(&self, show: &ShowCoverModel) {
@@ -155,6 +191,7 @@ struct PlayerControls {
pause: gtk::Button, pause: gtk::Button,
forward: gtk::Button, forward: gtk::Button,
rewind: gtk::Button, rewind: gtk::Button,
last_pause: RefCell<Option<DateTime<Local>>>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -176,6 +213,16 @@ impl Default for PlayerWidget {
Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()), Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()),
); );
let mpris = MprisPlayer::new(
APP_ID.to_string(),
"GNOME Podcasts".to_string(),
format!("{}.desktop", APP_ID).to_string(),
);
mpris.set_can_raise(true);
mpris.set_can_play(false);
mpris.set_can_seek(false);
mpris.set_can_set_fullscreen(false);
let mut config = player.get_config(); let mut config = player.get_config();
config.set_user_agent(USER_AGENT); config.set_user_agent(USER_AGENT);
config.set_position_update_interval(250); config.set_position_update_interval(250);
@@ -196,6 +243,7 @@ impl Default for PlayerWidget {
pause, pause,
forward, forward,
rewind, rewind,
last_pause: RefCell::new(None),
}; };
let timer_container = builder.get_object("timer").unwrap(); let timer_container = builder.get_object("timer").unwrap();
@@ -220,10 +268,12 @@ impl Default for PlayerWidget {
let episode = builder.get_object("episode_label").unwrap(); let episode = builder.get_object("episode_label").unwrap();
let cover = builder.get_object("show_cover").unwrap(); let cover = builder.get_object("show_cover").unwrap();
let info = PlayerInfo { let info = PlayerInfo {
mpris,
container: labels, container: labels,
show, show,
episode, episode,
cover, cover,
episode_id: RefCell::new(None),
}; };
let radio150 = builder.get_object("rate_1_50").unwrap(); let radio150 = builder.get_object("rate_1_50").unwrap();
@@ -253,103 +303,6 @@ impl Default for PlayerWidget {
} }
impl PlayerWidget { impl PlayerWidget {
pub(crate) fn new(sender: &Sender<Action>) -> Rc<Self> {
let w = Rc::new(Self::default());
Self::init(&w, sender);
w
}
fn init(s: &Rc<Self>, sender: &Sender<Action>) {
Self::connect_control_buttons(s);
Self::connect_rate_buttons(s);
Self::connect_gst_signals(s, sender);
}
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
fn connect_control_buttons(s: &Rc<Self>) {
let weak = Rc::downgrade(s);
// Connect the play button to the gst Player.
s.controls.play.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.play());
}));
// Connect the pause button to the gst Player.
s.controls.pause.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.pause());
}));
// Connect the rewind button to the gst Player.
s.controls.rewind.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.rewind());
}));
// Connect the fast-forward button to the gst Player.
s.controls.forward.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.fast_forward());
}));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
fn connect_gst_signals(s: &Rc<Self>, sender: &Sender<Action>) {
// Log gst warnings.
s.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
// Log gst errors.
s.player.connect_error(clone!(sender => move |_, _error| {
// sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
let s = i18n("The media player was unable to execute an action.");
sender.send(Action::ErrorNotification(s));
}));
// The following callbacks require `Send` but are handled by the gtk main loop
let weak = Fragile::new(Rc::downgrade(s));
// Update the duration label and the slider
s.player.connect_duration_changed(clone!(weak => move |_, clock| {
weak.get()
.upgrade()
.map(|p| p.timer.on_duration_changed(Duration(clock)));
}));
// Update the position label and the slider
s.player.connect_position_updated(clone!(weak => move |_, clock| {
weak.get()
.upgrade()
.map(|p| p.timer.on_position_updated(Position(clock)));
}));
// Reset the slider to 0 and show a play button
s.player.connect_end_of_stream(clone!(weak => move |_| {
weak.get()
.upgrade()
.map(|p| p.stop());
}));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
fn connect_rate_buttons(s: &Rc<Self>) {
let weak = Rc::downgrade(s);
s.rate
.radio_normal
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.00));
}));
s.rate
.radio125
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.25));
}));
s.rate
.radio150
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.50));
}));
}
fn on_rate_changed(&self, rate: f64) { fn on_rate_changed(&self, rate: f64) {
self.set_playback_rate(rate); self.set_playback_rate(rate);
self.rate.label.set_text(&format!("{:.2}×", rate)); self.rate.label.set_text(&format!("{:.2}×", rate));
@@ -371,13 +324,13 @@ impl PlayerWidget {
// path is an absolute fs path ex. "foo/bar/baz". // path is an absolute fs path ex. "foo/bar/baz".
// Convert it so it will have a "file:///" // Convert it so it will have a "file:///"
// FIXME: convert it properly // FIXME: convert it properly
if let Some(uri) = File::new_for_path(path).get_uri() { let uri = File::new_for_path(path).get_uri();
// play the file // play the file
self.player.set_uri(&uri); self.player.set_uri(uri.as_str());
self.rate.radio_normal.set_active(true);
self.play(); self.play();
return Ok(()); return Ok(());
} }
}
// TODO: log an error // TODO: log an error
} }
@@ -400,6 +353,36 @@ impl PlayerWidget {
player.seek(ClockTime::from_seconds(value)); player.seek(ClockTime::from_seconds(value));
}) })
} }
fn smart_rewind(&self) -> Option<()> {
lazy_static! {
static ref LAST_KNOWN_EPISODE: Mutex<Option<i32>> = Mutex::new(None);
};
// Figure out the time delta, in seconds, between the last pause and now
let now = Local::now();
let last: &Option<DateTime<_>> = &*self.controls.last_pause.borrow();
let last = last.clone()?;
let delta = (now - last).num_seconds();
// Get interval passed in the gst stream
let seconds_passed = self.player.get_position().seconds()?;
// get the last known episode id
let mut last = LAST_KNOWN_EPISODE.lock().unwrap();
// get the current playing episode id
let current_id = *self.info.episode_id.borrow();
// Only rewind on pause if the stream position is passed a certain point,
// and the player has been paused for more than a minute,
// and the episode id is the same
if seconds_passed >= 90 && delta >= 60 && current_id == *last {
self.seek(ClockTime::from_seconds(5), SeekDirection::Backwards);
}
// Set the last knows episode to the current one
*last = current_id;
Some(())
}
} }
impl PlayerExt for PlayerWidget { impl PlayerExt for PlayerWidget {
@@ -409,7 +392,9 @@ impl PlayerExt for PlayerWidget {
self.controls.pause.show(); self.controls.pause.show();
self.controls.play.hide(); self.controls.play.hide();
self.smart_rewind();
self.player.play(); self.player.play();
self.info.mpris.set_playback_status(PlaybackStatus::Playing);
} }
fn pause(&self) { fn pause(&self) {
@@ -417,13 +402,9 @@ impl PlayerExt for PlayerWidget {
self.controls.play.show(); self.controls.play.show();
self.player.pause(); self.player.pause();
self.info.mpris.set_playback_status(PlaybackStatus::Paused);
// Only rewind on pause if the stream position is passed a certain point. self.controls.last_pause.replace(Some(Local::now()));
if let Some(sec) = self.player.get_position().seconds() {
if sec >= 90 {
self.seek(ClockTime::from_seconds(5), SeekDirection::Backwards);
}
}
} }
#[cfg_attr(rustfmt, rustfmt_skip)] #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -432,6 +413,7 @@ impl PlayerExt for PlayerWidget {
self.controls.play.show(); self.controls.play.show();
self.player.stop(); self.player.stop();
self.info.mpris.set_playback_status(PlaybackStatus::Paused);
// Reset the slider bar to the start // Reset the slider bar to the start
self.timer.on_position_updated(Position(ClockTime::from_seconds(0))); self.timer.on_position_updated(Position(ClockTime::from_seconds(0)));
@@ -439,20 +421,32 @@ impl PlayerExt for PlayerWidget {
// Adapted from https://github.com/philn/glide/blob/b52a65d99daeab0b487f79a0e1ccfad0cd433e22/src/player_context.rs#L219-L245 // Adapted from https://github.com/philn/glide/blob/b52a65d99daeab0b487f79a0e1ccfad0cd433e22/src/player_context.rs#L219-L245
fn seek(&self, offset: ClockTime, direction: SeekDirection) { fn seek(&self, offset: ClockTime, direction: SeekDirection) {
// How far into the podcast we are
let position = self.player.get_position(); let position = self.player.get_position();
if position.is_none() || offset.is_none() { if position.is_none() || offset.is_none() {
return; return;
} }
// How much podcast we have
let duration = self.player.get_duration(); let duration = self.player.get_duration();
let destination = match direction { let destination = match direction {
// If we are more than `offset` into the podcast, jump back that far
SeekDirection::Backwards if position >= offset => Some(position - offset), SeekDirection::Backwards if position >= offset => Some(position - offset),
// If we haven't played `offset` yet just restart the podcast
SeekDirection::Backwards if position < offset => Some(ClockTime::from_seconds(0)),
// If we have more than `offset` remaining jump forward they amount
SeekDirection::Forward if !duration.is_none() && position + offset <= duration => { SeekDirection::Forward if !duration.is_none() && position + offset <= duration => {
Some(position + offset) Some(position + offset)
} }
// We don't have `offset` remaining just move to the end (ending playback)
SeekDirection::Forward if !duration.is_none() && position + offset > duration => {
Some(duration)
}
// Who knows what's going on ¯\_(ツ)_/¯
_ => None, _ => None,
}; };
// If we calucated a new position, jump to it
destination.map(|d| self.player.seek(d)); destination.map(|d| self.player.seek(d));
} }
@@ -468,3 +462,176 @@ impl PlayerExt for PlayerWidget {
self.player.set_rate(rate); self.player.set_rate(rate);
} }
} }
#[derive(Debug, Clone)]
pub(crate) struct PlayerWrapper(pub Rc<PlayerWidget>);
impl Default for PlayerWrapper {
fn default() -> Self {
PlayerWrapper(Rc::new(PlayerWidget::default()))
}
}
impl Deref for PlayerWrapper {
type Target = Rc<PlayerWidget>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl PlayerWrapper {
pub(crate) fn new(sender: &Sender<Action>) -> Self {
let w = Self::default();
w.init(sender);
w
}
fn init(&self, sender: &Sender<Action>) {
self.connect_control_buttons();
self.connect_rate_buttons();
self.connect_mpris_buttons(sender);
self.connect_gst_signals(sender);
}
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
fn connect_control_buttons(&self) {
let weak = Rc::downgrade(self);
// Connect the play button to the gst Player.
self.controls.play.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.play());
}));
// Connect the pause button to the gst Player.
self.controls
.pause
.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.pause());
}));
// Connect the rewind button to the gst Player.
self.controls
.rewind
.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.rewind());
}));
// Connect the fast-forward button to the gst Player.
self.controls
.forward
.connect_clicked(clone!(weak => move |_| {
weak.upgrade().map(|p| p.fast_forward());
}));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
fn connect_gst_signals(&self, sender: &Sender<Action>) {
// Log gst warnings.
self.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
// Log gst errors.
self.player.connect_error(clone!(sender => move |_, _error| {
// sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
let s = i18n("The media player was unable to execute an action.");
sender.send(Action::ErrorNotification(s)).expect("Action channel blew up somehow");
}));
// The following callbacks require `Send` but are handled by the gtk main loop
let weak = Fragile::new(Rc::downgrade(self));
// Update the duration label and the slider
self.player.connect_duration_changed(clone!(weak => move |_, clock| {
weak.get()
.upgrade()
.map(|p| p.timer.on_duration_changed(Duration(clock)));
}));
// Update the position label and the slider
self.player.connect_position_updated(clone!(weak => move |_, clock| {
weak.get()
.upgrade()
.map(|p| p.timer.on_position_updated(Position(clock)));
}));
// Reset the slider to 0 and show a play button
self.player.connect_end_of_stream(clone!(weak => move |_| {
weak.get()
.upgrade()
.map(|p| p.stop());
}));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
fn connect_rate_buttons(&self) {
let weak = Rc::downgrade(self);
self.rate
.radio_normal
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.00));
}));
self.rate
.radio125
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.25));
}));
self.rate
.radio150
.connect_toggled(clone!(weak => move |_| {
weak.upgrade().map(|p| p.on_rate_changed(1.50));
}));
}
fn connect_mpris_buttons(&self, sender: &Sender<Action>) {
let weak = Rc::downgrade(self);
// FIXME: Reference cycle with mpris
let mpris = self.info.mpris.clone();
self.info.mpris.connect_play_pause(clone!(weak => move || {
let player = match weak.upgrade() {
Some(s) => s,
None => return
};
if let Ok(status) = mpris.get_playback_status() {
match status.as_ref() {
"Paused" => player.play(),
"Stopped" => player.play(),
_ => player.pause(),
};
}
}));
self.info.mpris.connect_play(clone!(weak => move || {
let player = match weak.upgrade() {
Some(s) => s,
None => return
};
player.play();
}));
self.info.mpris.connect_pause(clone!(weak => move || {
let player = match weak.upgrade() {
Some(s) => s,
None => return
};
player.pause();
}));
self.info.mpris.connect_next(clone!(weak => move || {
weak.upgrade().map(|p| p.fast_forward());
}));
self.info.mpris.connect_previous(clone!(weak => move || {
weak.upgrade().map(|p| p.rewind());
}));
self.info.mpris.connect_raise(clone!(sender => move || {
sender.send(Action::RaiseWindow).expect("Action channel blew up somehow");
}));
}
}

Some files were not shown because too many files have changed in this diff Show More