royw-dvdprofiler2xbmc 0.0.2 → 0.0.3
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.
- data/README.rdoc +67 -10
- data/lib/dvdprofiler2xbmc/app.rb +52 -53
- data/lib/dvdprofiler2xbmc/app_config.rb +5 -4
- data/lib/dvdprofiler2xbmc/cli.rb +23 -19
- data/lib/dvdprofiler2xbmc/imdb_extensions.rb +21 -21
- data/lib/dvdprofiler2xbmc/media.rb +17 -5
- data/lib/dvdprofiler2xbmc/media_files.rb +7 -6
- data/lib/dvdprofiler2xbmc/nfo.rb +19 -15
- data/lib/dvdprofiler2xbmc.rb +1 -1
- metadata +2 -2
data/README.rdoc
CHANGED
|
@@ -51,19 +51,72 @@ Problems:
|
|
|
51
51
|
* IMDB ID scraping doesn't handle boxed sets or multiple movies per media
|
|
52
52
|
file. I don't see how to work around this exept to eliminate from media
|
|
53
53
|
library.
|
|
54
|
-
* Needs a better method to setup AppConfig defaults.
|
|
54
|
+
* Needs a better method to setup AppConfig defaults. Current thinking
|
|
55
|
+
is to prompt for required parameters on first run.
|
|
55
56
|
* Needs to support selectable/multiple regex based naming conventions
|
|
56
57
|
* Needs to support directory containers
|
|
57
58
|
* Does not support stacking
|
|
59
|
+
* .dvdprofiler2xbmcrc uses base 10 integers for permissions. Should be
|
|
60
|
+
either base 8 or symbolic.
|
|
58
61
|
|
|
59
62
|
== SYNOPSIS:
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
system. Then run:
|
|
64
|
+
First check the version by running:
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
$ bin/dvdprofiler2xbmc -v
|
|
67
|
+
INFO dvdprofiler2xbmc: Dvdprofiler2xbmc 0.0.2
|
|
68
|
+
INFO dvdprofiler2xbmc: saving: /home/royw/.dvdprofiler2xbmcrc
|
|
69
|
+
|
|
70
|
+
Notice that this generated a config file for you
|
|
71
|
+
(/home/royw/.dvdprofiler2xbmcrc) in your home directory.
|
|
72
|
+
|
|
73
|
+
Now edit the config file. Be sure to change the following fields to match
|
|
74
|
+
your system:
|
|
75
|
+
|
|
76
|
+
collection_filespec: /home/royw/DVD Profiler/Shared/Collection.xml
|
|
77
|
+
images_dir: /home/royw/DVD Profiler/Shared/Images
|
|
78
|
+
directories:
|
|
79
|
+
- /media/dad-kubuntu/public/data/videos_iso
|
|
80
|
+
- /media/dcerouter/public/data/videos_iso
|
|
81
|
+
- /media/royw-gentoo/public/data/videos_iso
|
|
82
|
+
- /media/royw-gentoo/public/data/movies
|
|
83
|
+
genre_maps: !map:Mash
|
|
84
|
+
Anime: Animation
|
|
85
|
+
Science-Fiction: Science Fiction
|
|
86
|
+
SciFi: Science Fiction
|
|
87
|
+
Musical: Musicals
|
|
88
|
+
|
|
89
|
+
The "collection_filespec" points to the collection.xml file exported by
|
|
90
|
+
DVD Profiler.
|
|
91
|
+
|
|
92
|
+
The "images_dir" points to the directory containing the images (cover scans)
|
|
93
|
+
from DVD Profiler.
|
|
94
|
+
|
|
95
|
+
The "directories" are the top level directories of where your media is
|
|
96
|
+
stored. Note, may be mount points or symbolic links.
|
|
97
|
+
|
|
98
|
+
The "genre_maps" is a list of genres to rename. In the above example,
|
|
99
|
+
"Anime" will be renamed "Animation", "Science-Fiction" will be renamed
|
|
100
|
+
"Science Fiction", etc.
|
|
101
|
+
|
|
102
|
+
You may want to adjust these also:
|
|
103
|
+
|
|
104
|
+
file_permissions: 436
|
|
105
|
+
dir_permissions: 511
|
|
106
|
+
|
|
107
|
+
Note the permissions are the base 10 integer of the octal permission mask.
|
|
108
|
+
For example, 436 (base 10) is 664 (base 8) and 511 (base 10) is 777 (base 8).
|
|
109
|
+
|
|
110
|
+
Save the .dvdprofiler2xbmcrc file.
|
|
111
|
+
|
|
112
|
+
You may want to get the command line help by running:
|
|
113
|
+
|
|
114
|
+
dvdprofiler2xbmc --help
|
|
115
|
+
|
|
116
|
+
To process your media, simply run:
|
|
117
|
+
|
|
118
|
+
dvdprofiler2xbmc
|
|
65
119
|
|
|
66
|
-
For help, run bin/dvdprofiler2xbmc --help
|
|
67
120
|
|
|
68
121
|
== REQUIREMENTS:
|
|
69
122
|
|
|
@@ -72,11 +125,15 @@ For help, run bin/dvdprofiler2xbmc --help
|
|
|
72
125
|
|
|
73
126
|
== INSTALL:
|
|
74
127
|
|
|
75
|
-
sudo gem install
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
sudo gem
|
|
128
|
+
sudo gem install royw-dvdprofiler2xbmc
|
|
129
|
+
|
|
130
|
+
== UNINSTALL:
|
|
131
|
+
|
|
132
|
+
sudo gem uninstall royw-dvdprofiler2xbmc
|
|
133
|
+
|
|
134
|
+
optionally
|
|
135
|
+
|
|
136
|
+
rm ~/.dvdprofiler2xbmcrc
|
|
80
137
|
|
|
81
138
|
== LICENSE:
|
|
82
139
|
|
data/lib/dvdprofiler2xbmc/app.rb
CHANGED
|
@@ -25,10 +25,10 @@ class DvdProfiler2Xbmc
|
|
|
25
25
|
@media_files = nil
|
|
26
26
|
@collection = nil
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
def execute
|
|
30
30
|
@media_files = MediaFiles.new(AppConfig[:directories])
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
collection_filepath = File.expand_path(AppConfig[:collection_filespec])
|
|
33
33
|
@collection = Collection.new(collection_filepath)
|
|
34
34
|
|
|
@@ -43,15 +43,15 @@ class DvdProfiler2Xbmc
|
|
|
43
43
|
# set file and directory permissions
|
|
44
44
|
AppConfig[:directories].each do |dir|
|
|
45
45
|
Dir.glob(File.join(dir, '**/*')).each do |f|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
begin
|
|
47
|
+
if File.directory?(f)
|
|
48
|
+
File.chmod(AppConfig[:dir_permissions], f) unless AppConfig[:dir_permissions].nil?
|
|
49
|
+
else
|
|
50
|
+
File.chmod(AppConfig[:file_permissions], f) unless AppConfig[:file_permissions].nil?
|
|
51
|
+
end
|
|
52
|
+
rescue Exception => e
|
|
53
|
+
AppConfig[:logger].error {e.to_s}
|
|
54
|
+
end
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
end
|
|
@@ -63,29 +63,29 @@ class DvdProfiler2Xbmc
|
|
|
63
63
|
buf = []
|
|
64
64
|
unless DvdProfiler2Xbmc.interrupted?
|
|
65
65
|
unless @media_files.nil?
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
duplicates = duplicates_report
|
|
67
|
+
unless duplicates.empty?
|
|
68
|
+
buf << "Duplicates:\n"
|
|
69
|
+
buf += duplicates
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
missing_isbns = missing_isbn_report
|
|
73
|
+
unless missing_isbns.empty?
|
|
74
|
+
buf += missing_isbns
|
|
75
|
+
end
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
buf
|
|
79
79
|
end
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
protected
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
# find ISBN for each title and assign to the media
|
|
84
84
|
def find_isbns(title, medias)
|
|
85
85
|
title_pattern = Collection.title_pattern(title)
|
|
86
86
|
unless @collection.title_isbn_hash[title_pattern].nil?
|
|
87
87
|
medias.each do |media|
|
|
88
|
-
|
|
88
|
+
media.isbn = @collection.title_isbn_hash[title_pattern]
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|
|
@@ -94,17 +94,17 @@ class DvdProfiler2Xbmc
|
|
|
94
94
|
def copy_thumbnails(title, medias)
|
|
95
95
|
medias.each do |media|
|
|
96
96
|
unless media.isbn.nil?
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
media.isbn.each do |isbn|
|
|
98
|
+
src_image_filespec = File.join(AppConfig[:images_dir], "#{isbn}f.jpg")
|
|
99
|
+
if File.exist?(src_image_filespec)
|
|
100
|
+
dest_image_filespec = media.path_to(:thumbnail_extension)
|
|
101
|
+
begin
|
|
102
|
+
File.copy(src_image_filespec, dest_image_filespec)
|
|
103
|
+
rescue Exception => e
|
|
104
|
+
AppConfig[:logger].error {e.to_s}
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
end
|
|
@@ -113,13 +113,13 @@ class DvdProfiler2Xbmc
|
|
|
113
113
|
def create_nfos(title, medias)
|
|
114
114
|
medias.each do |media|
|
|
115
115
|
unless media.isbn.nil?
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
media.isbn.each do |isbn|
|
|
117
|
+
dvd_hash = @collection.isbn_dvd_hash[isbn]
|
|
118
|
+
unless dvd_hash.nil?
|
|
119
|
+
nfo = NFO.new(media, dvd_hash)
|
|
120
|
+
nfo.save
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
end
|
|
@@ -130,26 +130,26 @@ class DvdProfiler2Xbmc
|
|
|
130
130
|
duplicates = @media_files.duplicate_titles
|
|
131
131
|
unless duplicates.empty?
|
|
132
132
|
duplicates.each do |title, medias|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
if medias.length > 1
|
|
134
|
+
buf << title
|
|
135
|
+
medias.each {|media| buf << " #{media.media_path}"}
|
|
136
|
+
end
|
|
137
137
|
end
|
|
138
138
|
end
|
|
139
139
|
buf
|
|
140
140
|
end
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
# unable to find ISBN for these titles report
|
|
143
143
|
def missing_isbn_report
|
|
144
144
|
buf = []
|
|
145
145
|
@media_files.titles.each do |title, medias|
|
|
146
146
|
if medias.nil?
|
|
147
|
-
|
|
147
|
+
buf << "No media for #{title}"
|
|
148
148
|
else
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
if medias[0].isbn.nil?
|
|
150
|
+
buf << "ISBN not found for #{title}"
|
|
151
|
+
medias.each {|media| buf << " #{media.media_path}"}
|
|
152
|
+
end
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
buf
|
|
@@ -157,4 +157,3 @@ class DvdProfiler2Xbmc
|
|
|
157
157
|
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
-
|
|
@@ -22,13 +22,13 @@ module AppConfig
|
|
|
22
22
|
|
|
23
23
|
def self.save
|
|
24
24
|
begin
|
|
25
|
-
File.delete(@yaml_filespec) if File.exist?(yaml_filespec)
|
|
26
|
-
AppConfig[:logger].info { "saving: #{yaml_filespec}" }
|
|
27
|
-
File.open(yaml_filespec, "w") do |f|
|
|
25
|
+
File.delete(@yaml_filespec) if File.exist?(@yaml_filespec)
|
|
26
|
+
AppConfig[:logger].info { "saving: #{@yaml_filespec}" }
|
|
27
|
+
File.open(@yaml_filespec, "w") do |f|
|
|
28
28
|
YAML.dump(@config, f)
|
|
29
29
|
end
|
|
30
30
|
rescue Exception => e
|
|
31
|
-
AppConfig[:logger].error { "Error saving config file \"#{@yaml_filespec} - " + e.to_s }
|
|
31
|
+
AppConfig[:logger].error { "Error saving config file \"#{@yaml_filespec} - " + e.to_s + "\n" + e.backtrace.join("\n")}
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -79,6 +79,7 @@ module AppConfig
|
|
|
79
79
|
@config.thumbnail_extension = 'tbn'
|
|
80
80
|
@config.nfo_extension = 'nfo'
|
|
81
81
|
@config.nfo_backup_extension = 'nfo~'
|
|
82
|
+
@config.no_imdb_extension = 'no_imdb_lookup'
|
|
82
83
|
|
|
83
84
|
# map some genre names
|
|
84
85
|
@config.genre_maps = {
|
data/lib/dvdprofiler2xbmc/cli.rb
CHANGED
|
@@ -49,20 +49,21 @@ module Dvdprofiler2xbmc
|
|
|
49
49
|
options = setupParser()
|
|
50
50
|
od = options.parse(arguments)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
# load config values
|
|
53
|
+
AppConfig.default
|
|
54
|
+
|
|
55
|
+
# the first reinitialize_logger adds the command line logging options to the default config
|
|
56
|
+
# then we load the config files
|
|
57
|
+
# then we run reinitialize_logger again to modify the logger for any logging options from the config files
|
|
58
|
+
|
|
59
|
+
reinitialize_logger(logger, od["--quiet"], od["--debug"])
|
|
60
|
+
AppConfig.load
|
|
61
|
+
# AppConfig[:pretend] = od["--pretend"]
|
|
62
|
+
AppConfig[:imdb_query] = !od["--no_imdb_query"]
|
|
63
|
+
AppConfig.save
|
|
64
|
+
reinitialize_logger(logger, od["--quiet"], od["--debug"])
|
|
65
65
|
|
|
66
|
+
unless od["--help"] || od["--version"]
|
|
66
67
|
# create and execute class instance here
|
|
67
68
|
app = DvdProfiler2Xbmc.new
|
|
68
69
|
app.execute
|
|
@@ -81,12 +82,15 @@ module Dvdprofiler2xbmc
|
|
|
81
82
|
# Returns:: OptionParser instances
|
|
82
83
|
def self.setupParser()
|
|
83
84
|
options = OptionParser.new()
|
|
84
|
-
options << Option.new(:flag, :names => %w(--help),
|
|
85
|
+
options << Option.new(:flag, :names => %w(--help -h),
|
|
85
86
|
:opt_found => lambda {Log4r::Logger['dvdprofiler2xbmc'].info{options.to_s}},
|
|
86
87
|
:opt_description => "This usage information")
|
|
87
|
-
options << Option.new(:flag, :names => %w(--
|
|
88
|
+
options << Option.new(:flag, :names => %w(--version -v),
|
|
89
|
+
:opt_found => lambda {Log4r::Logger['dvdprofiler2xbmc'].info{"Dvdprofiler2xbmc #{Dvdprofiler2xbmc::VERSION}"}},
|
|
90
|
+
:opt_description => "This version of dvdprofiler2xbmc")
|
|
91
|
+
# options << Option.new(:flag, :names => %w(--pretend -p))
|
|
88
92
|
options << Option.new(:flag, :names => %w(--no_imdb_query -n))
|
|
89
|
-
options << Option.new(:flag, :names => %w(--
|
|
93
|
+
options << Option.new(:flag, :names => %w(--quiet -q))
|
|
90
94
|
options << Option.new(:flag, :names => %w(--debug -d))
|
|
91
95
|
options
|
|
92
96
|
end
|
|
@@ -94,7 +98,7 @@ module Dvdprofiler2xbmc
|
|
|
94
98
|
# Reinitialize the logger using the loaded config.
|
|
95
99
|
# logger:: logger for any user messages
|
|
96
100
|
# config:: is the application's config hash.
|
|
97
|
-
def self.reinitialize_logger(logger,
|
|
101
|
+
def self.reinitialize_logger(logger, quiet, debug)
|
|
98
102
|
# switch the logger to the one specified in the config files
|
|
99
103
|
unless AppConfig[:logfile].nil?
|
|
100
104
|
logfile_outputter = Log4r::RollingFileOutputter.new(:logfile, :filename => AppConfig[:logfile], :maxsize => 1000000 )
|
|
@@ -106,8 +110,8 @@ module Dvdprofiler2xbmc
|
|
|
106
110
|
logfile_outputter.level = level_map[AppConfig[:logfile_level]] || Log4r::INFO
|
|
107
111
|
end
|
|
108
112
|
end
|
|
109
|
-
Log4r::Outputter[:console].level = Log4r::
|
|
110
|
-
Log4r::Outputter[:console].level = Log4r::
|
|
113
|
+
Log4r::Outputter[:console].level = Log4r::INFO
|
|
114
|
+
Log4r::Outputter[:console].level = Log4r::WARN if quiet
|
|
111
115
|
Log4r::Outputter[:console].level = Log4r::DEBUG if debug
|
|
112
116
|
# logger.trace = true
|
|
113
117
|
AppConfig[:logger] = logger
|
|
@@ -2,7 +2,7 @@ class ImdbMovie
|
|
|
2
2
|
def raw_title
|
|
3
3
|
document.at("h1").innerText
|
|
4
4
|
end
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
def video_game?
|
|
7
7
|
raw_title =~ /\(VG\)/
|
|
8
8
|
end
|
|
@@ -10,7 +10,7 @@ class ImdbMovie
|
|
|
10
10
|
def release_year
|
|
11
11
|
document.search("//h5[text()^='Release Date']/..").innerHTML[/\d{4}/]
|
|
12
12
|
end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
# return an Array of Strings containing AKA titles
|
|
15
15
|
def also_known_as
|
|
16
16
|
el = document.search("//h5[text()^='Also Known As:']/..").at('h5')
|
|
@@ -30,33 +30,33 @@ end
|
|
|
30
30
|
class ImdbSearch
|
|
31
31
|
# Find the IMDB ID for the current search title
|
|
32
32
|
# The find can be helped a lot by including a years option that contains
|
|
33
|
-
# an Array of integers that are the production year (plus/minus a year)
|
|
33
|
+
# an Array of integers that are the production year (plus/minus a year)
|
|
34
34
|
# and the release year.
|
|
35
35
|
def find_id(options={})
|
|
36
36
|
id = nil
|
|
37
37
|
found_movies = self.movies
|
|
38
38
|
unless found_movies.nil?
|
|
39
39
|
desired_movies = found_movies.select do |m|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
aka = m.also_known_as
|
|
41
|
+
result = imdb_compare_titles(m.title, aka, @query) && !m.video_game? && !m.release_year.blank?
|
|
42
|
+
if result
|
|
43
|
+
AppConfig[:logger].debug { m.title }
|
|
44
|
+
AppConfig[:logger].debug { "m.release_year => #{m.release_year}" }
|
|
45
|
+
unless options[:years].blank?
|
|
46
|
+
result = options[:years].include?(m.release_year.to_i)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
result
|
|
50
50
|
end
|
|
51
51
|
ids = desired_movies.collect{|m| m.id}.uniq.compact
|
|
52
52
|
if ids.length == 1
|
|
53
|
-
|
|
53
|
+
id = "tt#{ids[0]}"
|
|
54
54
|
else
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
AppConfig[:logger].debug { options[:media_path] } unless options[:media_path].nil?
|
|
56
|
+
AppConfig[:logger].debug { options[:years].pretty_inspect }
|
|
57
|
+
desired_movies.collect{|m| [m.raw_title, m.id, m.title, m.url, m.release_year.blank? ? 'no release date' : m.release_year]}.uniq.compact.each do |m|
|
|
58
|
+
AppConfig[:logger].debug { m.pretty_inspect }
|
|
59
|
+
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
id
|
|
@@ -80,13 +80,13 @@ class ImdbSearch
|
|
|
80
80
|
end
|
|
81
81
|
result
|
|
82
82
|
end
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
# a fuzzy compare that is case insensitive and replaces '&' with 'and'
|
|
85
85
|
# (because that is what IMDB occasionally does)
|
|
86
86
|
def fuzzy_compare_titles(title1, title2)
|
|
87
87
|
t1 = title1.downcase
|
|
88
88
|
t2 = title2.downcase
|
|
89
|
-
(t1 == t2) ||
|
|
89
|
+
(t1 == t2) ||
|
|
90
90
|
(t1.gsub(/&/, 'and') == t2.gsub(/&/, 'and')) ||
|
|
91
91
|
(t1.gsub(/[-:]/, ' ') == t2.gsub(/[-:]/, ' ')) ||
|
|
92
92
|
(t1.gsub('more at imdbpro ?', '') == t2)
|
|
@@ -3,20 +3,23 @@
|
|
|
3
3
|
class Media
|
|
4
4
|
attr_reader :media_path, :nfo_files, :image_files, :year, :media_subdirs
|
|
5
5
|
attr_accessor :isbn
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
DISC_NUMBER_REGEX = /\.(cd|part|disk|disc)\d+/i
|
|
8
|
+
|
|
7
9
|
def initialize(directory, media_file)
|
|
8
10
|
@media_subdirs = File.dirname(media_file)
|
|
9
11
|
@media_path = File.expand_path(File.join(directory, media_file))
|
|
10
12
|
Dir.chdir(File.dirname(@media_path))
|
|
11
13
|
@nfo_files = Dir.glob("*.{#{AppConfig[:nfo_extensions].join(',')}}")
|
|
12
14
|
@image_files = Dir.glob("*.{#{AppConfig[:media_extensions].join(',')}}")
|
|
13
|
-
@year = $1 if File.basename(@media_path
|
|
15
|
+
@year = $1 if File.basename(@media_path) =~ /\s\-\s(\d{4})/
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
# return the media's title extracted from the filename and cleaned up
|
|
17
19
|
def title
|
|
18
20
|
if @title.nil?
|
|
19
|
-
|
|
21
|
+
# ditch extensions including disc number (ex, a.part2.b => a, a.cd1.b => a)
|
|
22
|
+
@title = File.basename(@media_path, ".*").gsub(DISC_NUMBER_REGEX, '')
|
|
20
23
|
@title.gsub!(/\s\-\s\d{4}/, '') # remove year
|
|
21
24
|
@title.gsub!(/\s\-\s0/, '') # remove "- 0", i.e., bad year
|
|
22
25
|
@title.gsub!(/\(\d{4}\)/, '') # remove (year)
|
|
@@ -26,14 +29,23 @@ class Media
|
|
|
26
29
|
end
|
|
27
30
|
@title
|
|
28
31
|
end
|
|
29
|
-
|
|
32
|
+
|
|
33
|
+
def path_to(type)
|
|
34
|
+
# ditch all extensions (ex, a.b => a, a.cd1.b => a)
|
|
35
|
+
new_path = File.basename(@media_path, ".*").gsub(DISC_NUMBER_REGEX, '')
|
|
36
|
+
unless (type == :base) || AppConfig[type].nil?
|
|
37
|
+
new_path += '.' + AppConfig[type]
|
|
38
|
+
end
|
|
39
|
+
File.join(File.dirname(@media_path), new_path)
|
|
40
|
+
end
|
|
41
|
+
|
|
30
42
|
# return the media's title but with the (year) appended
|
|
31
43
|
def title_with_year
|
|
32
44
|
name = title
|
|
33
45
|
name = "#{name} (#{@year})" unless @year.nil?
|
|
34
46
|
name
|
|
35
47
|
end
|
|
36
|
-
|
|
48
|
+
|
|
37
49
|
def to_s
|
|
38
50
|
buf = []
|
|
39
51
|
buf << @media_path
|
|
@@ -9,8 +9,8 @@ class MediaFiles
|
|
|
9
9
|
@medias = []
|
|
10
10
|
directories.each do |dir|
|
|
11
11
|
Dir.chdir(dir)
|
|
12
|
-
@medias += Dir.glob("**/*.{#{AppConfig[:media_extensions].join(',')}}").collect do |filename|
|
|
13
|
-
|
|
12
|
+
@medias += Dir.glob("**/*.{#{AppConfig[:media_extensions].join(',')}}").collect do |filename|
|
|
13
|
+
Media.new(dir, filename)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
@titles = {}
|
|
@@ -20,16 +20,17 @@ class MediaFiles
|
|
|
20
20
|
@titles[title] << media
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
25
|
# find duplicate titles and return them in a hash
|
|
26
26
|
# where the key is the title and the value is an
|
|
27
27
|
# array of Media objects
|
|
28
28
|
def duplicate_titles
|
|
29
29
|
duplicates = {}
|
|
30
30
|
@titles.each do |title, medias|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
base_medias = medias.collect{|media| media.path_to(:base) }.uniq
|
|
32
|
+
if base_medias.length > 1
|
|
33
|
+
duplicates[title] = medias
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
duplicates
|
data/lib/dvdprofiler2xbmc/nfo.rb
CHANGED
|
@@ -6,12 +6,12 @@ class NFO
|
|
|
6
6
|
@dvd_hash = dvd_hash
|
|
7
7
|
load
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
# save as a .nfo file, creating a backup if the .nfo already exists
|
|
11
11
|
def save
|
|
12
12
|
begin
|
|
13
|
-
nfo_filespec = @media.
|
|
14
|
-
nfo_backup_filespec = @media.
|
|
13
|
+
nfo_filespec = @media.path_to(:nfo_extension)
|
|
14
|
+
nfo_backup_filespec = @media.path_to(:nfo_backup_extension)
|
|
15
15
|
File.delete(nfo_backup_filespec) if File.exist?(nfo_backup_filespec)
|
|
16
16
|
File.rename(nfo_filespec, nfo_backup_filespec) if File.exist?(nfo_filespec)
|
|
17
17
|
File.open(nfo_filespec, "w") do |file|
|
|
@@ -21,21 +21,25 @@ class NFO
|
|
|
21
21
|
AppConfig[:logger].error { "Error saving nfo file - " + e.to_s }
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
def load
|
|
26
26
|
begin
|
|
27
|
-
nfo_filespec = @media.
|
|
27
|
+
nfo_filespec = @media.path_to(:nfo_extension)
|
|
28
28
|
@movie = XmlSimple.xml_in(nfo_filespec) if File.exist? nfo_filespec
|
|
29
29
|
rescue Exception => e
|
|
30
30
|
AppConfig[:logger].error { "Error loading \"#{nfo_filespec}\" - " + e.to_s }
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# return a nfo xml String from the given dvd_hash (from Collection)
|
|
35
35
|
def to_nfo(dvd_hash)
|
|
36
36
|
@movie ||= {}
|
|
37
37
|
imdb_id = @movie['id']
|
|
38
|
-
|
|
38
|
+
if AppConfig[:imdb_query] && imdb_id.blank?
|
|
39
|
+
unless File.exist?(@media.path_to(:no_imdb_extension))
|
|
40
|
+
imdb_id = imdb_lookup(dvd_hash)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
39
43
|
@movie['title'] = dvd_hash[:title]
|
|
40
44
|
@movie['mpaa'] = dvd_hash[:rating]
|
|
41
45
|
@movie['year'] = dvd_hash[:productionyear]
|
|
@@ -46,16 +50,16 @@ class NFO
|
|
|
46
50
|
@movie['actor'] = dvd_hash[:actors]
|
|
47
51
|
@movie['id'] = imdb_id unless imdb_id.nil?
|
|
48
52
|
@movie['isbn'] = dvd_hash[:isbn]
|
|
49
|
-
|
|
53
|
+
|
|
50
54
|
begin
|
|
51
55
|
XmlSimple.xml_out(@movie, 'NoAttr' => true, 'RootName' => 'movie')
|
|
52
56
|
rescue Exception => e
|
|
53
57
|
AppConfig[:logger].error { "Error creating nfo file - " + e.to_s }
|
|
54
58
|
end
|
|
55
59
|
end
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
protected
|
|
58
|
-
|
|
62
|
+
|
|
59
63
|
def map_genres(genres)
|
|
60
64
|
new_genres = []
|
|
61
65
|
genres.each do |genre|
|
|
@@ -71,11 +75,11 @@ class NFO
|
|
|
71
75
|
unless dvd_hash[:title].blank?
|
|
72
76
|
years = released_years(dvd_hash)
|
|
73
77
|
begin
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
imdb_search = ImdbSearch.new(dvd_hash[:title])
|
|
79
|
+
id = imdb_search.find_id(:years => years, :media_path => @media.media_path)
|
|
76
80
|
rescue Exception => e
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
AppConfig[:logger].error { "Error searching IMDB - " + e.to_s }
|
|
82
|
+
AppConfig[:logger].error { e.backtrace.join("\n") }
|
|
79
83
|
end
|
|
80
84
|
end
|
|
81
85
|
AppConfig[:logger].info { "IMDB id => #{id}" } unless id.nil?
|
|
@@ -98,6 +102,6 @@ class NFO
|
|
|
98
102
|
end
|
|
99
103
|
years.flatten.uniq.compact.sort
|
|
100
104
|
end
|
|
101
|
-
|
|
105
|
+
|
|
102
106
|
end
|
|
103
107
|
|
data/lib/dvdprofiler2xbmc.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: royw-dvdprofiler2xbmc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roy Wright
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-03-
|
|
12
|
+
date: 2009-03-20 00:00:00 -07:00
|
|
13
13
|
default_executable: dvdprofiler2xbmc
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|