From c0beac896b07fad0d6945d8c49fce41ab6f44116 Mon Sep 17 00:00:00 2001 From: Thilo Kogge Date: Tue, 28 Jun 2022 16:58:28 +0200 Subject: [PATCH 1/5] fixes #79 --- python/podcast/podpost.py | 3 ++- qml/components/PlayerHandler.qml | 2 ++ qml/harbour-podqast.qml | 4 +--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/python/podcast/podpost.py b/python/podcast/podpost.py index 27fd594..c7aae45 100644 --- a/python/podcast/podpost.py +++ b/python/podcast/podpost.py @@ -252,7 +252,8 @@ class Podpost(BaseModel): "loaded": loaded, "haschapters": haschapters, "listened": self.listened or self.position > 0 and ( - self.duration - self.position < Constants().markListenedBeforeEndThreshold * 1000) + self.duration - self.position < Constants().markListenedBeforeEndThreshold * 1000), + "podcastTitle": self.podcast.title if not self.isaudio else "" } def get_image_descriptor(self): diff --git a/qml/components/PlayerHandler.qml b/qml/components/PlayerHandler.qml index 56df622..2b7ab69 100644 --- a/qml/components/PlayerHandler.qml +++ b/qml/components/PlayerHandler.qml @@ -16,6 +16,7 @@ Python { property string playtext: "" property string firstid: "" property string firsttitle: "" + property string firstPodcastTitle: "" property var chapters property int aktchapter property double playpos: 0 @@ -90,6 +91,7 @@ Python { function setEpisode(data, chapterlist) { firstid = data.id firsttitle = data.title + firstPodcastTitle=data.podcastTitle chapters = chapterlist playicon = data.logo_url playtext = data.title diff --git a/qml/harbour-podqast.qml b/qml/harbour-podqast.qml index 1c612a0..472a2b4 100644 --- a/qml/harbour-podqast.qml +++ b/qml/harbour-podqast.qml @@ -500,11 +500,9 @@ ApplicationWindow { playbackStatus: playerHandler.isPlaying ? Mpris.Playing : Mpris.Paused onTitleChanged: { - metaData.title = playerHandler.firsttitle - // metaData.albumArtist = playerHandler. - var metadata = mprisPlayer.metadata metadata[Mpris.metadataToString(Mpris.Title)] = playerHandler.firsttitle + metadata[Mpris.metadataToString(Mpris.AlbumArtist)] = playerHandler.firstPodcastTitle mprisPlayer.metadata = metadata } -- GitLab From 3370a85ccb0c585d8d71576d38f4057c81a80091 Mon Sep 17 00:00:00 2001 From: Thilo Kogge Date: Tue, 28 Jun 2022 18:06:25 +0200 Subject: [PATCH 2/5] removed wild character --- qml/components/PlayerHandler.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qml/components/PlayerHandler.qml b/qml/components/PlayerHandler.qml index 56df622..34ed64d 100644 --- a/qml/components/PlayerHandler.qml +++ b/qml/components/PlayerHandler.qml @@ -111,7 +111,7 @@ Python { return } } - aktchapter = chapters.length -\ 1 + aktchapter = chapters.length - 1 } function nextchapter() { -- GitLab From bec8b344b62863abaf489e96c34f9ff746697739 Mon Sep 17 00:00:00 2001 From: Thilo Kogge Date: Sun, 17 Jul 2022 12:19:14 +0200 Subject: [PATCH 3/5] fixed missing position override after pause, rewinding a bit after pause, fixed tests --- qml/components/PlayerHandler.qml | 29 ++++++++++++--------- qml/components/QueueHandlerPython.qml | 10 +++++--- qml/harbour-podqast.qml | 36 +++++++++++++-------------- test/__init__.py | 6 +++-- test/test_podcast.py | 8 ------ test/test_podpost.py | 26 ++++++++++--------- test/testdata/freakshow.rss | 2 +- 7 files changed, 60 insertions(+), 57 deletions(-) diff --git a/qml/components/PlayerHandler.qml b/qml/components/PlayerHandler.qml index 04c260c..f545584 100644 --- a/qml/components/PlayerHandler.qml +++ b/qml/components/PlayerHandler.qml @@ -4,8 +4,8 @@ import io.thp.pyotherside 1.4 Python { id: playerHandler - property real position: (mediaplayer.position <= 0)?positionFromDb:mediaplayer.position - property real duration: (mediaplayer.duration <= 0)?durationFromDb:mediaplayer.duration + property real position: (mediaplayer.position <= 0) ? positionFromDb : mediaplayer.position + property real duration: (mediaplayer.duration <= 0) ? durationFromDb : mediaplayer.duration property real positionSeconds: position / 1000 property real durationSeconds: duration / 1000 property real durationFromDb: 0 @@ -53,10 +53,10 @@ Python { onPlaying: { console.info("Playing audio_url: " + audio_url + " @ rate " + playrate) - + positionFromDb = position if (audio_url != "") { - mediaplayer.source = audio_url - mediaplayer.seek(positionFromDb - 15 * 1000) + if (mediaplayer.source != audio_url) + mediaplayer.source = audio_url if (!only_start_if_playing || mediaplayer.isPlaying) { mediaplayer.play() } @@ -75,8 +75,12 @@ Python { onPausing: { mediaplayer.pause() + var pauseRewindTime = 1000 + var positionToSave = mediaplayer.position + if (mediaplayer.position > pauseRewindTime) + positionToSave = mediaplayer.position - pauseRewindTime isPlaying = false - queuehandler.updatePlayingPosition() + queuehandler.updatePlayingPosition(positionToSave) } onStopping: { mediaplayer.pause() @@ -91,14 +95,15 @@ Python { function setEpisode(data, chapterlist) { firstid = data.id firsttitle = data.title - firstPodcastTitle=data.podcastTitle + firstPodcastTitle = data.podcastTitle chapters = chapterlist playicon = data.logo_url playtext = data.title durationFromDb = data.duration positionFromDb = data.position - console.log("setting episode: " + data.title + " url:" + data.audio_url + " duration:"+data.duration+"/"+duration) + console.log("setting episode: " + data.title + " url:" + data.audio_url + + " duration:" + data.duration + "/" + duration) } function getaktchapter() { @@ -152,7 +157,7 @@ Python { function play() { isPlaying = true - call("QueueHandler.instance.queue_play", function () {}) + call("QueueHandler.instance.queue_play", function () { }) } function pause() { @@ -182,9 +187,9 @@ Python { } function setDuration() { - if(mediaplayer.duration > 0){ - call("QueueHandler.instance.set_duration", - [mediaplayer.duration], function () {}) + if (mediaplayer.duration > 0) { + call("QueueHandler.instance.set_duration", [mediaplayer.duration], + function () {}) } } diff --git a/qml/components/QueueHandlerPython.qml b/qml/components/QueueHandlerPython.qml index 62de938..62e488a 100644 --- a/qml/components/QueueHandlerPython.qml +++ b/qml/components/QueueHandlerPython.qml @@ -62,7 +62,8 @@ Python { call("QueueHandler.instance.queue_to_archive", [id], function () {}) } function queueTopToArchive(playnext) { - call("QueueHandler.instance.queue_top_to_archive",[playnext], function () {}) + call("QueueHandler.instance.queue_top_to_archive", [playnext], + function () {}) } function getQueueEntries() { @@ -71,8 +72,11 @@ Python { function getFirstEntry() { call("QueueHandler.instance.get_first_entry", function () {}) } - function updatePlayingPosition() { - call("QueueHandler.instance.update_position", [playerHandler.position], + function updatePlayingPosition(position) { + if (position === undefined) { + position = playerHandler.position + } + call("QueueHandler.instance.update_position", [position], function () {}) } function downloadAudio(podpost) { diff --git a/qml/harbour-podqast.qml b/qml/harbour-podqast.qml index 472a2b4..32ce031 100644 --- a/qml/harbour-podqast.qml +++ b/qml/harbour-podqast.qml @@ -437,10 +437,9 @@ ApplicationWindow { id: loghandler } -// PodqastAudioPlayer { -// id: mediaplayer -// } - + // PodqastAudioPlayer { + // id: mediaplayer + // } PlayerHandler { id: playerHandler onAudioNotExist: { @@ -470,12 +469,11 @@ ApplicationWindow { interval: 400 repeat: false onTriggered: { - interval=10 - updateMprisMetadata() - + interval = 10 + mprisPlayer.updateMetadata() } } - + MprisPlayer { id: mprisPlayer property string title: playerHandler.firsttitle @@ -484,12 +482,7 @@ ApplicationWindow { identity: "podQast" supportedUriSchemes: ["file", "http"] - supportedMimeTypes: ["audio/x-vorbis-ogg", - "audio/mpeg", - "audio/mp4a-latm", - "audio/x-aiff", - "audio/ogg", - "audio/opus"] + supportedMimeTypes: ["audio/x-vorbis-ogg", "audio/mpeg", "audio/mp4a-latm", "audio/x-aiff", "audio/ogg", "audio/opus"] canControl: true canGoNext: true @@ -500,9 +493,15 @@ ApplicationWindow { playbackStatus: playerHandler.isPlaying ? Mpris.Playing : Mpris.Paused onTitleChanged: { + updateMetadata() + } + + function updateMetadata() { var metadata = mprisPlayer.metadata - metadata[Mpris.metadataToString(Mpris.Title)] = playerHandler.firsttitle - metadata[Mpris.metadataToString(Mpris.AlbumArtist)] = playerHandler.firstPodcastTitle + metadata[Mpris.metadataToString( + Mpris.Title)] = playerHandler.firsttitle + metadata[Mpris.metadataToString( + Mpris.AlbumArtist)] = playerHandler.firstPodcastTitle mprisPlayer.metadata = metadata } @@ -512,9 +511,8 @@ ApplicationWindow { onPlayPauseRequested: playerHandler.playpause() onStopRequested: playerHandler.stop() onPlayRequested: playerHandler.play() - onNextRequested: podqast.fast_forward() - onPreviousRequested: podqast.fast_backward() - + onNextRequested: playerHandler.fast_forward() + onPreviousRequested: playerHandler.fast_backward() } } diff --git a/test/__init__.py b/test/__init__.py index 4f1416b..8e25072 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -12,6 +12,7 @@ from httpretty.utils import utf8 from test.conftest import cleanup_podcast +logger = logging.getLogger(__name__) def mock_pyotherside(): module_name = "pyotherside" @@ -19,7 +20,6 @@ def mock_pyotherside(): sys.modules[module_name] = module module.send = Mock(name=module_name + '.send') - mock_pyotherside() from podcast.archive import ArchiveFactory @@ -28,7 +28,7 @@ from podcast.podcast import Podcast from podcast.podpost import PodpostFactory os.environ["PODQAST_HOME"] = tempfile.mkdtemp() -logging.info("tempdir: %s",os.environ["PODQAST_HOME"]) +logger.info("tempdir: %s",os.environ["PODQAST_HOME"]) from podcast.constants import Constants from podcast.data_migration import setup_db @@ -51,6 +51,7 @@ def setup_inbox_with_2_posts(): @httprettified def setup_and_get_2_posts(): + logger.info("setup with dummy feed") HTTPretty.register_uri(HTTPretty.GET, 'https://freakshow.fm/feed/opus/', body=read_testdata('testdata/freakshow.rss'), adding_headers=xml_headers) cleanup_podcast() @@ -62,6 +63,7 @@ def setup_and_get_2_posts(): entry2 = podcast.get_entry(podcast.entry_ids_old_to_new[1]) assert entry2 PodpostFactory().persist(entry2) + logger.info("persisted dummy feed") return entry1, entry2 diff --git a/test/test_podcast.py b/test/test_podcast.py index 3eda9cb..f52cde8 100644 --- a/test/test_podcast.py +++ b/test/test_podcast.py @@ -233,14 +233,6 @@ def refreshable_podcast_fixture(request) -> Tuple[Podcast, List[Podpost]]: assert invoked > 0 -@httpretty.activate -def test_pagination(): - url_f = "https://fakefeed.com/page" - HTTPretty.register_uri(HTTPretty.GET, url_f, body=read_testdata('testdata/fakefeednohref.xml'), - adding_headers=xml_headers) - podcast, episodes = Podcast.create_from_url(url_f) - assert 3 == podcast.count_episodes() - assert 3 == len(episodes) @httpretty.activate diff --git a/test/test_podpost.py b/test/test_podpost.py index c6e6a89..3b8f89f 100644 --- a/test/test_podpost.py +++ b/test/test_podpost.py @@ -1,7 +1,7 @@ """ Podpost tests """ - +import logging import sys import httpretty @@ -14,6 +14,8 @@ sys.path.append("../python") from podcast.podcast import Podcast from podcast.podpost import Podpost, PodpostFactory +logger = logging.getLogger(__name__) + @httpretty.activate def test_podpost_save(): @@ -25,18 +27,20 @@ def test_podpost_save(): p, episodes = Podcast.create_from_url('https://freakshow.fm/feed/opus/') e: Podpost = p.get_latest_entry() - e.position = e.duration -59*1000 + assert e.duration == 10 * 60 * 1000 + 55 * 1000 + e.position = e.duration - 59 * 1000 id1 = e.id PodpostFactory().persist(e) n = PodpostFactory().get_podpost(e.id) id2 = n.id assert type(n) == Podpost assert id1 == id2 + assert n.duration == 10 * 60 * 1000 + 55 * 1000 assert n.get_data()["listened"] @httpretty.activate -def test_podpost_save(): +def test_podpost_save2(): """ Test podpost saving """ @@ -54,6 +58,7 @@ def test_podpost_save(): assert episode.get_data()['description'] == episode.plainpart assert episode.get_data()['detail'] == episode.htmlpart + def test_persist_bulk_empty(): PodpostFactory().persist_bulk([]) @@ -66,7 +71,6 @@ def test_persist_bulk_nochapters(): PodpostFactory().persist_bulk([post]) - def test_get_data_external_audio(): post = Podpost() post.guid = "" @@ -77,18 +81,16 @@ def test_get_data_external_audio(): post.get_data() - - def test_tracker_removal(): tests = [ - ("https://dts.podtrac.com/redirect.mp3/myfeed","https://myfeed"), - ("http://dts.podtrac.com/redirect.mp3/myfeed","http://myfeed"), - ("http://www.podtrac.com/pts/redirect.mp3/myfeed","http://myfeed"), - ("https://www.podtrac.com/pts/redirect.mp3/myfeed","https://myfeed"), - ("https://notracker.ru/feed/podtrac","https://notracker.ru/feed/podtrac"), + ("https://dts.podtrac.com/redirect.mp3/myfeed", "https://myfeed"), + ("http://dts.podtrac.com/redirect.mp3/myfeed", "http://myfeed"), + ("http://www.podtrac.com/pts/redirect.mp3/myfeed", "http://myfeed"), + ("https://www.podtrac.com/pts/redirect.mp3/myfeed", "https://myfeed"), + ("https://notracker.ru/feed/podtrac", "https://notracker.ru/feed/podtrac"), ] podpost = Podpost() for given, expected in tests: podpost.href = given - assert podpost.remove_trackers() == expected \ No newline at end of file + assert podpost.remove_trackers() == expected diff --git a/test/testdata/freakshow.rss b/test/testdata/freakshow.rss index 8b035df..158236d 100644 --- a/test/testdata/freakshow.rss +++ b/test/testdata/freakshow.rss @@ -64,7 +64,7 @@ - + 0:10:55 Metaebene Personal Media - Tim Pritlove Brot backen — Welt putzen — 36C3 245 -- GitLab From 8f118b432bea457ed9466a41a5f6d60afdb70bbd Mon Sep 17 00:00:00 2001 From: Thilo Kogge Date: Sun, 17 Jul 2022 17:11:28 +0200 Subject: [PATCH 4/5] fixed mpris --- qml/harbour-podqast.qml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/qml/harbour-podqast.qml b/qml/harbour-podqast.qml index 32ce031..106042c 100644 --- a/qml/harbour-podqast.qml +++ b/qml/harbour-podqast.qml @@ -476,7 +476,6 @@ ApplicationWindow { MprisPlayer { id: mprisPlayer - property string title: playerHandler.firsttitle serviceName: "podqast" @@ -490,19 +489,24 @@ ApplicationWindow { canPause: true canPlay: true canSeek: true - playbackStatus: playerHandler.isPlaying ? Mpris.Playing : Mpris.Paused - - onTitleChanged: { - updateMetadata() + playbackStatus: { + switch (mediaplayer.playbackState) { + case Audio.PlayingState: + return Mpris.Playing + case Audio.PausedState: + return Mpris.Paused + default: + return Mpris.Stopped + } } - - function updateMetadata() { - var metadata = mprisPlayer.metadata - metadata[Mpris.metadataToString( - Mpris.Title)] = playerHandler.firsttitle - metadata[Mpris.metadataToString( - Mpris.AlbumArtist)] = playerHandler.firstPodcastTitle - mprisPlayer.metadata = metadata + rate: playerHandler.playrate + + metaData { + url: mediaplayer.source + duration: playerHandler.duration + title: playerHandler.firsttitle + contributingArtist: playerHandler.firstPodcastTitle + artUrl: playerHandler.playicon } loopStatus: Mpris.None -- GitLab From 550abe67cdd0d2162acf11e5ef2bdbd0ff9203dc Mon Sep 17 00:00:00 2001 From: Thilo Kogge Date: Sun, 17 Jul 2022 17:29:12 +0200 Subject: [PATCH 5/5] fixed off durations if migrating from stored rss feeds --- python/podcast/data_migration.py | 2 +- test/test_migration_to_v1.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python/podcast/data_migration.py b/python/podcast/data_migration.py index a2c17b3..740eda6 100644 --- a/python/podcast/data_migration.py +++ b/python/podcast/data_migration.py @@ -123,7 +123,7 @@ def run_migrations(strict=True): if strict: raise set_versionnumber(3) - if current_version < 4: + if current_version < 4 and start_version > 1 : db.execute_sql("UPDATE podpost set duration = duration * 1000;") set_versionnumber(4) db.execute_sql('VACUUM "main"') diff --git a/test/test_migration_to_v1.py b/test/test_migration_to_v1.py index 3cf10a7..9a9f58e 100644 --- a/test/test_migration_to_v1.py +++ b/test/test_migration_to_v1.py @@ -42,6 +42,7 @@ def test_migration_v1(): assert ilen(ExternalFactory().get_external().get_podposts()) == 0 assert ilen(InboxFactory().get_inbox().get_podposts()) == 42 assert PodpostChapter.select().count() == 9293 + assert (130 * 60 + 54) * 1000 == QueueFactory().get_queue()._get_top().duration PodcastFactory().remove_podcast("http://minkorrekt.de/feed/opus/") assert ilen(PodcastListFactory().get_podcast_list().get_podcasts()) == 24 -- GitLab