Giter Club home page Giter Club logo

pcd's People

Contributors

athiakos avatar dependabot[bot] avatar dstpierre avatar kvannotten avatar larryzju avatar shadizade avatar sneagan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pcd's Issues

Download New Episodes for Favorite Shows

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.

List Most Recent Episodes of All

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).

pcd isnt' loading config file

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.

feed pubDate RFC format

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:

  • Episode Date is now of type string, not an issue as it was printed with the original rss.Layout anyway
  • Not so great error handling if none of the specs are available
  • Somewhat more robust sorting of feed dates in case the order is completely mixed instead of reversed
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)
+	})
 }

Create a default configuration file when program is first used

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

Download a range of episodes for a podcast

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

Non-Int `length` Failure

Describe the bug
Feed parser can't handle string values in the length property

To Reproduce
Steps to reproduce the behavior:

  1. Add a feed that has string values for length
  2. pcd sync
  3. 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.

Standardize download filenames

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

File names are messed up even after the download ends

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:

  1. download any episode of any podcast using pcd
  2. use any file manager or terminal to check the downloaded file
  3. See error in the filename

Expected behavior
A file with a clean ".mp3" extension

Desktop (please complete the following information):

  • OS: Manjaro Linux x86_64
  • Version: v0.6.0-1 (built from AUR)

Tweaking in the audio file's metadata.

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.

Enhancements: done marking and verbose sync

  1. On pcd ls X, it would be useful if downloaded episodes would display a mark (such as โœ“) indicating them to be done.

  2. On pcd sync, it would be useful to display "X new episodes" next to each entry.

Help message is misleading

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):

  • OS: Arch Linux

Open downloads in player

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.