epodder 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/arguments.rb +46 -46
- data/lib/configuration/configurator.rb +70 -70
- data/lib/database/episode.rb +27 -27
- data/lib/database/podcast.rb +7 -7
- data/lib/eclass.rb +4 -4
- data/lib/epodder.rb +18 -18
- data/lib/verb/add.rb +28 -28
- data/lib/verb/catchup.rb +11 -11
- data/lib/verb/clean.rb +38 -39
- data/lib/verb/download.rb +28 -30
- data/lib/verb/fetch.rb +8 -8
- data/lib/verb/list.rb +10 -10
- data/lib/verb/remove.rb +17 -17
- data/lib/verb/update.rb +55 -55
- data/lib/verb/verb.rb +30 -30
- metadata +59 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94d4f519a9c0b22eded9199580b110f7ef13a660
|
4
|
+
data.tar.gz: e03b1b144d3b3e2a955d6155c5ba0143228c03dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 158d4961b2e61a76f6a55bc3e21ed77c0db38c7a3b5a729d0946dfb17202df49095feb46298fe0212aa63c18786912fc0a901f5d20e319c7d306d6c5e222f021
|
7
|
+
data.tar.gz: 07dcb752b375fc2d72a1448804b070df1788aa29586564cb57d95d89e59062bc8b891545b4921b3acb0c52e7f8965376ede7189edc120c6565dcdec9ba8ba8ef
|
data/lib/arguments.rb
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
2
|
+
class Arguments
|
3
|
+
attr_accessor :args
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
def initialize
|
6
|
+
@args = Hash.new
|
7
|
+
@args[:arguments] = []
|
8
|
+
verb = Struct.new(:name,:desc,:block)
|
9
|
+
@verbs = [
|
10
|
+
verb.new('add','Add a new podcast.', Proc.new {|args| @args[:action] = :add; @args[:arguments] = args}),
|
11
|
+
verb.new('catchup','Mark older episodes as downloaded.', Proc.new {|args| @args[:action] = :catchup; @args[:arguments] = args}),
|
12
|
+
verb.new('remove','Remove a feed by supplying an id.', Proc.new {|args| @args[:action] = :remove; @args[:arguments] = args}),
|
13
|
+
verb.new('lscasts','List podcasts.', Proc.new {|args| @args[:action] = :list_podcast; @args[:arguments] = args}),
|
14
|
+
verb.new('lseps','List episodes of a podcast by id.', Proc.new {|args| @args[:action] = :list_episodes; @args[:arguments] = args}),
|
15
|
+
verb.new('fetch','Update then download podcasts', Proc.new {|args| @args[:action] = :fetch; @args[:arguments] = args}),
|
16
|
+
verb.new('download','Download podcasts specified by a list of id or all podcasts', Proc.new {|args| @args[:action] = :download; @args[:arguments] = args}),
|
17
|
+
verb.new('update','Update podcasts specified by a list of id or all podcasts', Proc.new {|args| @args[:action] = :update; @args[:arguments] = args}),
|
18
|
+
verb.new("clean", "Remove old content from the database", Proc.new {|args| @args[:action] = :clean; @args[:arguments] = args})
|
19
|
+
]
|
20
|
+
get_args
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
def get_args
|
24
|
+
@args[:path] = "~/.epodder"
|
25
|
+
cmd = CmdParse::CommandParser.new( true, true )
|
26
|
+
cmd.program_name = "ePodder"
|
27
|
+
cmd.program_version = [0, 0, 7]
|
28
|
+
cmd.options = CmdParse::OptionParserWrapper.new do |opt|
|
29
|
+
opt.separator "Global options:"
|
30
|
+
opt.on("-v", "--verbose", "Be verbose when outputting info") {|t| @args[:verbose] = true }
|
31
|
+
opt.on("-c", "--conf-dir [PATH]", "Set the configuration directory") {|path| @args[:path] = path}
|
32
|
+
opt.on("-l", "--log-path [PATH]", "Set logging to the specified file") {|path| @args[:log_file] = path}
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
cmd.add_command( CmdParse::HelpCommand.new )
|
36
|
+
cmd.add_command( CmdParse::VersionCommand.new)
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
@verbs.each do |verb|
|
39
|
+
command = CmdParse::Command.new(verb.name, false, false)
|
40
|
+
command.short_desc = verb.desc
|
41
|
+
command.set_execution_block(&verb.block)
|
42
|
+
cmd.add_command(command)
|
43
|
+
end
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
cmd.parse
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
def method_missing(name, value=nil, *args)
|
49
|
+
if @args.has_key? name
|
50
|
+
@args[name]
|
51
|
+
end
|
52
|
+
end
|
53
53
|
|
54
|
-
|
54
|
+
end
|
55
55
|
end
|
@@ -1,86 +1,86 @@
|
|
1
1
|
#TODO clean up nil!!
|
2
2
|
module Epodder
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
class Configurator < Eclass
|
4
|
+
@@default_path = "~/.epodder/"
|
5
|
+
@@db_path = "epodder.db"
|
6
|
+
@@yaml_path = "epodder.yaml"
|
7
|
+
@@default = {
|
8
|
+
:path_to_db => "epodder.db",
|
9
|
+
:path_to_download => "~/podcasts"
|
10
|
+
}
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
def initialize args
|
13
|
+
@args = args
|
14
|
+
load_working_dir! @args.path
|
15
|
+
load_config!
|
16
|
+
start_logging
|
17
|
+
load_download_dir!
|
18
|
+
load_database!
|
19
|
+
end
|
20
20
|
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
def load_config!
|
23
|
+
#Check to see if we have a config file or if we need to create it
|
24
|
+
if !File.exists? @@yaml_path
|
25
|
+
begin
|
26
|
+
File.open(@@yaml_path, "w") do |io|
|
27
|
+
YAML.dump(@@default, io)
|
28
|
+
end
|
29
|
+
rescue SystemCallError, NameError => error
|
30
|
+
puts "Could not load #{@@yaml_path}: #{error}"
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@conf = YAML.load_file(@@yaml_path)
|
32
35
|
end
|
33
|
-
end
|
34
|
-
@conf = YAML.load_file(@@yaml_path)
|
35
|
-
end
|
36
36
|
|
37
|
-
|
37
|
+
private
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
def load_download_dir!
|
40
|
+
Dir.mkdir File.expand_path(@conf[:path_to_download]) unless Dir.exists?(File.expand_path(@conf[:path_to_download]))
|
41
|
+
File.symlink(File.expand_path(@conf[:path_to_download]), "download") unless File.exists? "download"
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
def load_database!
|
45
|
+
#Datamapper magic goes here
|
46
|
+
DataMapper.setup(:default, "sqlite://#{Dir.pwd}/#{@conf[:path_to_db]}")
|
47
|
+
DataMapper.finalize
|
48
|
+
DataMapper.auto_upgrade!
|
49
|
+
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
def load_working_dir! path
|
52
|
+
@path = File.expand_path(path || @@default_path)
|
53
|
+
Dir.mkdir @path unless Dir.exists? @path
|
54
|
+
Dir.chdir @path unless file_error
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
def file_error
|
58
|
+
if !File.directory?(@path) || !File.readable?(@path) || !File.writable?(@path)
|
59
|
+
puts "#{@path} is not a directory or is not writable"
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
false
|
63
|
+
end
|
64
64
|
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
66
|
+
def start_logging
|
67
|
+
logger = Yell.new :name => 'log' do |l|
|
68
|
+
if @args.log_file.nil?
|
69
|
+
if @args.verbose
|
70
|
+
l.adapter :stdout, "epodder.log", :level => Yell.level(:info)
|
71
|
+
else
|
72
|
+
l.adapter :stdout, "epodder.log", :level => Yell.level(:error)
|
73
|
+
end
|
74
|
+
else
|
75
|
+
if @args.verbose
|
76
|
+
l.adapter :datefile, "epodder.log", :level => Yell.level(:info)
|
77
|
+
else
|
78
|
+
l.adapter :datefile, "epodder.log", :level => Yell.level(:error)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
logger.info "Loaded Logger"
|
80
83
|
end
|
81
|
-
end
|
82
|
-
logger.info "Loaded Logger"
|
83
|
-
end
|
84
84
|
|
85
|
-
|
85
|
+
end
|
86
86
|
end
|
data/lib/database/episode.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
require 'data_mapper'
|
2
2
|
module Epodder
|
3
|
-
|
4
|
-
|
3
|
+
class Episode < Eclass
|
4
|
+
include DataMapper::Resource
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
property :id, Serial
|
7
|
+
property :title, String, :length=> 500
|
8
|
+
property :url, URI
|
9
|
+
property :downloaded, Boolean
|
10
|
+
property :pub_date, DateTime
|
11
11
|
|
12
|
-
|
12
|
+
belongs_to :podcast
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
def self.lookup episode
|
15
|
+
if episode.enclosure
|
16
|
+
@episode = Episode.first_or_create(
|
17
|
+
:title => episode.title,
|
18
|
+
:url => episode.enclosure.url,
|
19
|
+
:pub_date => episode.pubdate,
|
20
|
+
:downloaded => false
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
def mark_as_downloaded
|
26
|
+
self.downloaded = true
|
27
|
+
success = self.save
|
28
|
+
if !success
|
29
|
+
self.errors.each do |e|
|
30
|
+
puts e
|
31
|
+
end
|
32
|
+
end
|
31
33
|
end
|
32
|
-
end
|
33
|
-
end
|
34
34
|
|
35
|
-
|
35
|
+
end
|
36
36
|
end
|
data/lib/database/podcast.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
class Podcast < Eclass
|
3
|
+
include DataMapper::Resource
|
4
|
+
property :id, Serial
|
5
|
+
property :title, String, :length=> 500
|
6
|
+
property :uri, URI
|
7
|
+
has n, :episodes, :constraint => :destroy
|
8
8
|
|
9
|
-
|
9
|
+
end
|
10
10
|
end
|
data/lib/eclass.rb
CHANGED
data/lib/epodder.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
2
|
+
require_all File.dirname(File.dirname(__FILE__)) << '/lib'
|
3
3
|
|
4
|
-
|
4
|
+
@@verbose = false
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def verbose?
|
7
|
+
@@verbose
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def verbose= state
|
11
|
+
@@verbose = state
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def self.do_verb verb, args
|
15
|
+
c = Epodder.const_get(verb.to_s.capitalize)
|
16
|
+
verb_object = c.send :new
|
17
|
+
verb_object.send verb, args
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
def self.run
|
21
|
+
args = Arguments.new
|
22
|
+
Configurator.new(args)
|
23
|
+
do_verb args.action, args.arguments
|
24
|
+
end
|
25
25
|
|
26
26
|
end
|
data/lib/verb/add.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class Add < Verb
|
3
|
+
def initialize
|
4
|
+
@mechanize = Mechanize.new
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def add args
|
8
|
+
args.each do |url|
|
9
|
+
lookup_podcast url
|
10
|
+
end
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def lookup_podcast url
|
14
|
+
@mechanize.get(url) do |feed|
|
15
|
+
save_podcast feed, url
|
16
|
+
end
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
def save_podcast feed, url
|
20
|
+
cast = FeedMe.parse feed.body
|
21
|
+
cast.emulate_atom!
|
22
|
+
podcast = Podcast.first_or_create(
|
23
|
+
:title => cast.title,
|
24
|
+
:uri => url
|
25
|
+
)
|
26
|
+
podcast.save
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
podcast.errors.each do |error|
|
29
|
+
@log.error error
|
30
|
+
end
|
31
|
+
puts "#{podcast.id} - #{podcast.title}"
|
32
|
+
end
|
33
33
|
|
34
|
-
|
34
|
+
end
|
35
35
|
end
|
data/lib/verb/catchup.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
class Catchup < Verb
|
3
|
+
def catchup args
|
4
|
+
if args.empty?
|
5
|
+
podcasts = Podcast.all
|
6
|
+
else
|
7
|
+
podcasts = args.map {|id| Podcast.get(id.to_i)}
|
8
|
+
end
|
9
|
+
podcasts.each do |podcast|
|
10
|
+
Episode.all(:downloaded => false, :podcast => podcast).update(:downloaded => true)
|
11
|
+
end
|
12
|
+
end
|
12
13
|
end
|
13
|
-
end
|
14
14
|
|
15
15
|
end
|
data/lib/verb/clean.rb
CHANGED
@@ -1,47 +1,46 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class Clean < Verb
|
3
|
+
def initialize
|
4
|
+
@mechanize = @mechanize = Mechanize.new
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
7
|
+
def clean args
|
8
|
+
if args.empty?
|
9
|
+
podcasts = Podcast.all
|
10
|
+
else
|
11
|
+
podcasts = args.map{|podcast| Podcast.get(podcast.to_i)}
|
12
|
+
end
|
13
|
+
podcasts.each do |podcast|
|
14
|
+
known_episodes = Episode.all(:downloaded => true, :podcast => podcast)
|
15
|
+
feed_episodes = open_podcast podcast, DateTime.now
|
16
|
+
known_episodes = known_episodes.map{|episode| episode.url.to_s}
|
17
|
+
feed_episodes = feed_episodes.map{|episode|@episode = episode; episode.enclosure.url}
|
18
|
+
episodes = (known_episodes - feed_episodes)
|
19
|
+
episodes_length = episodes.length
|
20
|
+
episodes.map{|episode| Episode.all(:url => episode)}.each do |episode|
|
21
|
+
if !episode.destroy
|
22
|
+
episode.errors.each {|error| puts error}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
puts "#{podcast.title} -- cleaned #{episodes_length} episodes"
|
26
|
+
end
|
25
27
|
end
|
26
|
-
puts "#{podcast.title} -- cleaned #{episodes_length} episodes"
|
27
|
-
end
|
28
|
-
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def open_podcast podcast, max_pub
|
30
|
+
begin
|
31
|
+
@mechanize.get(podcast.uri) do |feed|
|
32
|
+
return parse_feed feed, max_pub
|
33
|
+
end
|
34
|
+
rescue Exception => e
|
35
|
+
puts e
|
36
|
+
end
|
34
37
|
end
|
35
|
-
rescue Exception => e
|
36
|
-
puts e
|
37
|
-
end
|
38
|
-
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
def parse_feed feed, max_pub
|
40
|
+
podcast = FeedMe.parse feed.body
|
41
|
+
podcast.emulate_atom!
|
42
|
+
temp = podcast.items.select {|item| !item.enclosure.nil?}
|
43
|
+
temp.select {|item| !item.enclosure.empty?}
|
44
|
+
end
|
45
45
|
end
|
46
|
-
end
|
47
46
|
end
|
data/lib/verb/download.rb
CHANGED
@@ -1,38 +1,36 @@
|
|
1
|
-
require '
|
2
|
-
#require 'mechanize/progressbar'
|
3
|
-
#require 'progress'
|
1
|
+
require 'downspout'
|
4
2
|
module Epodder
|
5
|
-
|
3
|
+
class Download < Verb
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
def initialize
|
6
|
+
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
def download args
|
9
|
+
each_argument(args) do |podcast|
|
10
|
+
look_for_episodes podcast
|
11
|
+
end
|
12
|
+
end
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
def look_for_episodes podcast
|
15
|
+
episodes = Episode.all(:downloaded => false, :podcast => podcast)
|
16
|
+
episodes.select{|ep| !ep.nil?}.each do |episode|
|
17
|
+
puts episode.podcast.title
|
18
|
+
title = (episode.podcast.title).strip
|
19
|
+
Dir.mkdir "download/#{title}" unless Dir.exists? "download/#{title}"
|
20
|
+
puts "Downloading #{title} - #{episode.title || episode.id}"
|
21
|
+
download_episode episode
|
22
|
+
end
|
25
23
|
end
|
26
|
-
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
def download_episode episode
|
26
|
+
begin
|
27
|
+
Downspout::Config.max_redirects = 100
|
28
|
+
Downspout.download_url_to_path(episode.url, "download/#{episode.podcast.title.strip}/#{episode.url.to_s.match('((?!\/).)*$')}")
|
29
|
+
episode.mark_as_downloaded
|
30
|
+
rescue StandardError => e
|
31
|
+
puts e
|
32
|
+
end
|
33
|
+
end
|
36
34
|
|
37
|
-
|
35
|
+
end
|
38
36
|
end
|
data/lib/verb/fetch.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class Fetch < Verb
|
3
|
+
def initialize
|
4
|
+
#Nothing to do in initalize
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def fetch args
|
8
|
+
Update.new.update args
|
9
|
+
Download.new.download args
|
10
|
+
end
|
10
11
|
end
|
11
|
-
end
|
12
12
|
end
|
data/lib/verb/list.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class List_podcast < Verb
|
3
|
+
def initialize
|
4
|
+
#Nothing to do in initalize
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def list_podcast *args
|
8
|
+
Podcast.all.each do |pod|
|
9
|
+
puts "#{pod.id} : \"#{pod.title}\""
|
10
|
+
end
|
11
|
+
end
|
12
12
|
|
13
|
-
|
13
|
+
end
|
14
14
|
end
|
data/lib/verb/remove.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
require 'highline/import'
|
2
2
|
module Epodder
|
3
|
-
|
4
|
-
|
3
|
+
class Remove < Verb
|
4
|
+
def initialize
|
5
5
|
|
6
|
-
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
def remove args
|
9
|
+
each_argument(args) do |podcast|
|
10
|
+
input = ask("Remove #{podcast.id} : #{podcast.title}? Type \"YES\" to remove")
|
11
|
+
if input == "YES"
|
12
|
+
podcast.destroy
|
13
|
+
end
|
14
|
+
end
|
15
|
+
args.map{|id| Podcast.get(id)}.each do |podcast|
|
16
|
+
input = ask("Remove #{podcast.id} : #{podcast.title}? Type \"YES\" to remove")
|
17
|
+
if input == "YES"
|
18
|
+
podcast.destroy
|
19
|
+
end
|
20
|
+
end
|
19
21
|
end
|
20
|
-
end
|
21
|
-
end
|
22
22
|
|
23
|
-
|
23
|
+
end
|
24
24
|
end
|
data/lib/verb/update.rb
CHANGED
@@ -3,70 +3,70 @@ require 'feedme'
|
|
3
3
|
require 'mechanize'
|
4
4
|
#require 'progress'
|
5
5
|
module Epodder
|
6
|
-
|
6
|
+
class Update < Verb
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@mechanize = Mechanize.new
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def update args
|
14
|
+
each_argument(args) do |podcast|
|
15
|
+
check_for_new_episodes podcast
|
16
|
+
end
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def check_for_new_episodes podcast
|
20
|
+
max_pub = get_max_pubdate podcast
|
21
|
+
open_podcast podcast, max_pub
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def get_max_pubdate podcast
|
25
|
+
Episode.max(:pub_date, :conditions => { :podcast => podcast }) || Time.at(0).to_date
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
def open_podcast podcast, max_pub
|
29
|
+
begin
|
30
|
+
@mechanize.get(podcast.uri) do |feed|
|
31
|
+
@log.info "Maximum pubdate for #{podcast.title} - #{podcast.id} is #{max_pub}"
|
32
|
+
parse_feed feed, podcast, max_pub
|
33
|
+
end
|
34
|
+
rescue StandardError => e
|
35
|
+
puts "#{podcast.title} - #{e}"
|
36
|
+
end
|
33
37
|
end
|
34
|
-
rescue StandardError => e
|
35
|
-
puts "#{podcast.title} - #{e}"
|
36
|
-
end
|
37
|
-
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def is_valid? item, max_pub
|
49
|
-
item.enclosure && item.pubdate.to_date > max_pub.to_date
|
50
|
-
end
|
39
|
+
def parse_feed feed, database_podcast, max_pub
|
40
|
+
podcast = FeedMe.parse feed.body
|
41
|
+
podcast.emulate_atom!
|
42
|
+
pending_episodes = podcast.items.select {|item| is_valid? item, max_pub}
|
43
|
+
pending_episodes.each {|pending_episode| add_eligible_episode database_podcast, pending_episode }
|
44
|
+
length = pending_episodes.length
|
45
|
+
puts "#{database_podcast.title} has #{length} new episodes" if length > 0
|
46
|
+
end
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
48
|
+
def is_valid? item, max_pub
|
49
|
+
item.enclosure && item.pubdate.to_date > max_pub.to_date
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_eligible_episode podcast, item
|
53
|
+
begin
|
54
|
+
ep = Episode.first_or_create(
|
55
|
+
:title => item.title,
|
56
|
+
:url => item.enclosure.url,
|
57
|
+
:pub_date => item.pubdate.to_date,
|
58
|
+
:downloaded => false,
|
59
|
+
:podcast => podcast
|
60
|
+
)
|
61
|
+
ep.errors.each do |error|
|
62
|
+
@log.error error
|
63
|
+
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
rescue Exception => e
|
66
|
+
@log.error e
|
67
|
+
raise e
|
68
|
+
end
|
68
69
|
end
|
69
|
-
end
|
70
70
|
|
71
|
-
|
71
|
+
end
|
72
72
|
end
|
data/lib/verb/verb.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
module Epodder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class Verb < Eclass
|
3
|
+
def verb_struct
|
4
|
+
super
|
5
|
+
Struct.new(:name,:description,:block)
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
def add_command (cmd, args)
|
9
|
+
command = CmdParse::Command.new(@verb.name,false,false)
|
10
|
+
command.short_desc = @verb.description
|
11
|
+
command.set_execution_block(&@verb.block)
|
12
|
+
cmd.add_command(command)
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
def lookup_args args
|
16
|
+
if args.empty?
|
17
|
+
podcasts = Podcast.all
|
18
|
+
else
|
19
|
+
podcasts = args.map {|id| Podcast.get(id.to_i)}
|
20
|
+
end
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
def each_argument args, &block
|
24
|
+
podcasts = nil
|
25
|
+
if args.empty?
|
26
|
+
podcasts = Podcast.all
|
27
|
+
else
|
28
|
+
podcasts = args.map {|id| Podcast.get(id.to_i)}
|
29
|
+
end
|
30
|
+
podcasts.each do |podcast|
|
31
|
+
yield podcast
|
32
|
+
end
|
33
|
+
end
|
34
34
|
|
35
35
|
|
36
|
-
|
36
|
+
end
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epodder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Bergstrom
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -136,6 +136,62 @@ dependencies:
|
|
136
136
|
- - '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: curb
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: downspout
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: home_run
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '>='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: feedzirra
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - '>='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - '>='
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
139
195
|
- !ruby/object:Gem::Dependency
|
140
196
|
name: bundler
|
141
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -276,7 +332,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
332
|
version: '0'
|
277
333
|
requirements: []
|
278
334
|
rubyforge_project:
|
279
|
-
rubygems_version: 2.0.
|
335
|
+
rubygems_version: 2.0.4
|
280
336
|
signing_key:
|
281
337
|
specification_version: 4
|
282
338
|
summary: Ruby re-do of hpodder
|