kvannotten / pcd Goto Github PK
View Code? Open in Web Editor NEWCLI podcast client (podcatcher) written in golang
License: GNU General Public License v3.0
CLI podcast client (podcatcher) written in golang
License: GNU General Public License v3.0
Is your feature request related to a problem? Please describe.
I'd like to have the ability to have the tool download the latest episode of all shows in a list of favorite episodes in the config whenever a sync
is run.
Describe the solution you'd like
A new property in the config YAML will need to be added. I recommend an array of IDs:
---
podcasts:
- id: 1
...
- id: 2
...
favorites:
- 1
- 2
Additional context
This will probably require some significant refactoring of the download.go
file. I'm happy to work on it if you're open to that.
Is your feature request related to a problem? Please describe.
I'd like to know what the latest episodes of all of the shows are. It might be beyond the scope of this project to manage play status and determine what you haven't heard yet, but you could do that yourself if there is a way to repeatedly list latest.
Describe the solution you'd like
A latest
method seems like the least disruptive way to do this. Maybe with id/name arguments in addition to an all
or -1
or something to show a list of the most recent episodes of all shows. Favorites as well? This could be achieved by writing the latest episode name into the show object: latest_episode_name
or something similar, presumably updated on sync.
Justification
If this is beyond the scope of the project this could be accomplished with a separate script, but it seems like a nice feature that would allow users to write more complex interactions. For example, pipe the results of this method into dmenu
for input, and then pipe the results of dmenu
back into pcd
to download the selection(s).
Don't know if it's intended behavior, but copying and pasting that template didn't work for me because of the spaces as pcd was unable to load the file (it didn't show any error, it just didn't synced), after removing the spaces pcd recognized the file and synced normally.
I've followed the instructions and created a pcd.yml file at the write path, but pcd won't load it. pcd doesn't sync any podcasts.
Describe the bug
You assume that the feed will have RFC1123 date format on pudDate node while parsing the feed.
I've seen feeds that come as RFC1123Z which will cause time.Parse to fail and skip the episodes all together.
To Reproduce
Try parsing a feed with:
<pubDate>Thu, 10 Nov 2016 19:41:48 GMT</pubDate>
Expected behavior
Error on parsing the episode and presumably the whole feed (assuming the feed is consistent on date format)
Additional context
Patch below provides a quick fix.
Some notes:
diff --git a/pcd.go b/pcd.go
index 73773b2..a5bb20d 100644
--- a/pcd.go
+++ b/pcd.go
@@ -11,7 +11,6 @@ import (
"os"
"path/filepath"
"strings"
- "time"
"github.com/kvannotten/pcd/rss"
"github.com/pkg/errors"
@@ -33,7 +32,7 @@ type Podcast struct {
type Episode struct {
Title string
- Date time.Time
+ Date string
URL string
Length int
}
@@ -158,7 +157,7 @@ func (p *Podcast) String() string {
title = fmt.Sprintf("%s...", episode.Title[0:(titleLength-4)])
}
formatStr := fmt.Sprintf("%%-4d %%-%ds %%20s\n", tl)
- sb.WriteString(fmt.Sprintf(formatStr, index+1, title, episode.Date.Format(rss.Layout)))
+ sb.WriteString(fmt.Sprintf(formatStr, index+1, title, episode.Date))
}
return sb.String()
@@ -217,14 +216,10 @@ func parseEpisodes(content io.Reader) ([]Episode, error) {
var episodes []Episode
for _, item := range feed.Channel.Items {
- t, err := time.Parse(rss.Layout, item.Date.Date)
- if err != nil {
- log.Printf("Could not parse episode: %#v", err)
- continue
- }
+
episode := Episode{
Title: item.Title.Title,
- Date: t,
+ Date: item.Date.Date,
URL: item.Enclosure.URL,
Length: item.Enclosure.Length,
}
diff --git a/rss/parser.go b/rss/parser.go
index 17774f2..565ccec 100644
--- a/rss/parser.go
+++ b/rss/parser.go
@@ -6,6 +6,7 @@ import (
"io"
"io/ioutil"
"log"
+ "sort"
"time"
)
@@ -84,20 +85,22 @@ func Parse(content io.Reader) (*PodcastFeed, error) {
return &feed, nil
}
-const Layout string = "Mon, _2 Jan 2006 15:04:05 -0700"
+func stringToDate(d string) time.Time {
+ var t time.Time
+ var err error
-func sortFeedByDate(feed *PodcastFeed) {
- if len(feed.Channel.Items) < 1 {
- return
+ t, err = time.Parse(time.RFC1123, d)
+ if err != nil {
+ t, _ = time.Parse(time.RFC1123Z, d)
}
+ return t
+}
- firstDate, _ := time.Parse(Layout, feed.Channel.Items[0].Date.Date)
- lastDate, _ := time.Parse(Layout, feed.Channel.Items[len(feed.Channel.Items)-1].Date.Date)
+func sortFeedByDate(feed *PodcastFeed) {
+ sort.Slice(feed.Channel.Items, func(i, j int) bool {
+ d1 := stringToDate(feed.Channel.Items[i].Date.Date)
+ d2 := stringToDate(feed.Channel.Items[j].Date.Date)
- if firstDate.After(lastDate) {
- // reverse the feed
- for i, j := 0, len(feed.Channel.Items)-1; i < j; i, j = i+1, j-1 {
- feed.Channel.Items[i], feed.Channel.Items[j] = feed.Channel.Items[j], feed.Channel.Items[i]
- }
- }
+ return d2.After(d1)
+ })
}
Is your feature request related to a problem? Please describe.
For usability reasons, I think it'll be nice if the user does not need to create a file themselves. Currently if a new user wants to use this, they'd have to copy and paste the dummy configuration file from the README.md.
Describe the solution you'd like
If a configuration file does not exist, create a dummy one.
Describe alternatives you've considered
N/A
Additional context
N/A
Is your feature request related to a problem? Please describe.
I'd like the ability to download a range of episodes to a podcast
Describe the solution you'd like
pcd d podcast-name 63-65
which would download 63, 64, and 65. It would also be nice to have a syntax for doing combinations of ranges and individual episodes. For example:
pcd d podcast-name 63-65,67,69-75
would download 63, 64, 65, 67, 69, 70, 71, 72, 73, 74, 75.
Describe alternatives you've considered
Manually writing a function to call pcd for 63-65. This seems cumbersome, however.
Additional context
One of the reasons I would prefer a command line podcast client is for the ability to do things in bulk
Describe the bug
Feed parser can't handle string values in the length
property
To Reproduce
Steps to reproduce the behavior:
length
pcd sync
pcd ls
Expected behavior
length
should be intelligently coerced into a usable format.
I'm happy to help out with this one, but I'd like to know if you're opinionated about an approach. My initial thought is some pre-processor function on the feed before it gets coerced into the struct
. It looks like this is possible using the UnmarshalXML method on the Unmarshaler type.
When downloading episodes, the naming schemes are different between podcasts (for example, one podcast I follow names every episode 'stream.mp4', creating file conflicts). Since pcd fetches the episode name from the feed, wouldn't it be more convenient for the file to be automatically named? Castget does this by allowing filename patterns in the config file (e.g. filename=%(date)-%(title)
).
Info:
pcd v 0.7
Describe the bug
Downloading any podcast will result in a file with a name that instead of ending with ".mp3" will end with ".mp3?dest-id=(some number here)" messing with the extension name ends with the audio file being unplayable by some music players.
here's a "ls -la" of one of my download folders:
-rw-r--r-- 1 peep peep 90943970 fev 27 18:31 'LPOTL353REDOFINAL.mp3?dest-id=754182'
-rw-r--r-- 1 peep peep 66852854 fev 27 18:23 'SideStoriesDOATTEND_Final.mp3dest-id=754182'
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A file with a clean ".mp3" extension
Desktop (please complete the following information):
Is your feature request related to a problem? Please describe.
I'm not sure if pcd does anything with the audio file's metadata, but a nice feature would be to update the file's metadata with the info from the RSS.
Describe the solution you'd like
If this process is already done for song name and album name (it seems to be), would also be nice to link the episode's number from the RSS with the track number in the file's metadata to help song players with ordering the episodes correctly.
On pcd ls X
, it would be useful if downloaded episodes would display a mark (such as โ) indicating them to be done.
On pcd sync
, it would be useful to display "X new episodes" next to each entry.
Describe the bug
The help message claims the config is stored under .config/pcd but it actually checks .config/pcd.yml.
To Reproduce
Add file to .config/pcd and sync (nothing happens for me at least). Then try renaming to pcd.yml, this works. Note that the help message says
Just add the necessary configuration under ~/.config/pcd and you can get started.
...
Flags:
--config string config file (default is $HOME/.config/pcd)
Expected behavior
Help message should say:
Just add the necessary configuration under ~/.config/pcd.yml and you can get started.
...
Flags:
--config string config file (default is $HOME/.config/pcd.yml)
Desktop (please complete the following information):
Is your feature request related to a problem? Please describe.
I like to run mpv
with a specific set of arguments when I play a podcast. marrie
let's you define a command to run on downloaded files in it's config files. Plus I'm a bad speller/forgetful, so it's nice if pcd
could handle path searing for me.
Describe the solution you'd like
Something like the following, which will run a podcast with an user specified video player command :
pcd p 1 1
I suppose the filename can be guessed from the RSS feed. If it's not present, just error and fail (maybe suggest to download it). If it is, play it.
Describe alternatives you've considered
Manual navigation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.