royw-dvdprofiler2xbmc 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -14,7 +14,8 @@ $hoe = Hoe.new('dvdprofiler2xbmc', Dvdprofiler2xbmc::VERSION) do |p|
14
14
  ['royw-imdb','>= 0.0.16'],
15
15
  ['log4r','>= 1.0.5'],
16
16
  ['commandline','>= 0.7.10'],
17
- ['mash','>= 0.0.3']
17
+ ['mash','>= 0.0.3'],
18
+ ['highline', '>= 1.5.0']
18
19
  ]
19
20
  p.extra_dev_deps = [
20
21
  ['newgem', ">= #{::Newgem::VERSION}"]
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{dvdprofiler2xbmc}
5
- s.version = "0.0.6"
5
+ s.version = "0.0.8"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Roy Wright"]
9
- s.date = %q{2009-04-08}
9
+ s.date = %q{2009-04-14}
10
10
  s.default_executable = %q{dvdprofiler2xbmc}
11
- s.description = %q{This script will attempt to match up media files from a set of directories to the collection.xml file exported from DVD Profiler. For matches, the script will then create a {moviename}.nfo from the data in collections.xml and also copy the front cover image to {moviename}.tbn. Both files will be placed in the same directory as the source media file. Also the specific profile information for each movie will be saved into {moviename}.dvdprofiler.xml. The script will then search IMDB for a title or also known as (AKA) match. If necessary, the script will refine the search by using the media year (year in media filename), then dvdprofiler production year, then dvdprofiler release year, then try again with each year plus or minus a year. The IMDB profile found will be saved as {moviename}.imdb.xml. Next the script will use the IMDB ID to query themovieDb.com. This is primarily to retrieve any fanart but will also add any missing parameters to the .nfo file (very unlikely). The TMDB profile found will be saved as {moviename}.tmdb.xml. So in summary the files generated are: {moviename}.tmdb.xml - profile from themovieDb.com {moviename}.imdb.xml - profile from imdb.com {moviename}.dvdprofiler.xml - profile from collection.xml {moviename}-fanart.jpg - first fanart image from themovieDb.com {moviename}.tbn - image from DVD Profiler {moviename}.nfo - generated info profile for xbmc To force regeneration, simply delete these files then run the script again. Then on XBMC, set the source content to none to remove the meta data from the library, then set the source content back to Movies to import the media. This time, the data in the .nfo files will be used instead of scraping.}
11
+ s.description = %q{This script will attempt to match up media files from a set of directories to the collection.xml file exported from DVD Profiler. For matches, the script will then create a {moviename}.nfo from the data in collections.xml and also copy the front cover image to {moviename}.tbn. Both files will be placed in the same directory as the source media file. Also the specific profile information for each movie will be saved into {moviename}.dvdprofiler.xml. The script will then search IMDB for a title or also known as (AKA) match. If necessary, the script will refine the search by using the media year (year in media filename), then dvdprofiler production year, then dvdprofiler release year, then try again with each year plus or minus a year. The IMDB profile found will be saved as {moviename}.imdb.xml. Next the script will use the IMDB ID to query themovieDb.com. This is primarily to retrieve any fanart but will also add any missing parameters to the .nfo file (very unlikely). The TMDB profile found will be saved as {moviename}.tmdb.xml. So in summary the files generated are: {moviename}.tmdb.xml - profile from themovieDb.com {moviename}.imdb.xml - profile from imdb.com {moviename}.dvdprofiler.xml - profile from collection.xml {moviename}-fanart.jpg - first fanart image from themovieDb.com {moviename}.tbn - image from DVD Profiler {moviename}.nfo - generated info profile for xbmc To force regeneration, simply delete these files then run the script again. Then on XBMC, set the source content to none to remove the meta data from the library, then set the source content back to Movies to import the media. This time, the data in the .nfo files will be used instead of scraping. Note, XBMC pre-9.04 r19177 does not successfully scan all media. The work-around is after the scan is complete to restart XBMC so it will scan again (if you have autoscan enabled).}
12
12
  s.email = ["roy@wright.org"]
13
13
  s.executables = ["dvdprofiler2xbmc"]
14
14
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc"]
15
- s.files = [".gitignore", "History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "Rakefile", "bin/dvdprofiler2xbmc", "dvdprofiler2xbmc.gemspec", "lib/dvdprofiler2xbmc.rb", "lib/dvdprofiler2xbmc/app_config.rb", "lib/dvdprofiler2xbmc/controllers/app.rb", "lib/dvdprofiler2xbmc/controllers/fanart_controller.rb", "lib/dvdprofiler2xbmc/controllers/nfo_controller.rb", "lib/dvdprofiler2xbmc/controllers/thumbnail_controller.rb", "lib/dvdprofiler2xbmc/extensions.rb", "lib/dvdprofiler2xbmc/models/collection.rb", "lib/dvdprofiler2xbmc/models/dvdprofiler_profile.rb", "lib/dvdprofiler2xbmc/models/imdb_profile.rb", "lib/dvdprofiler2xbmc/models/media.rb", "lib/dvdprofiler2xbmc/models/media_files.rb", "lib/dvdprofiler2xbmc/models/tmdb_movie.rb", "lib/dvdprofiler2xbmc/models/tmdb_profile.rb", "lib/dvdprofiler2xbmc/models/xbmc_info.rb", "lib/dvdprofiler2xbmc/open_cache_extension.rb", "lib/dvdprofiler2xbmc/views/cli.rb", "spec/cache_extensions.rb", "spec/dvdprofiler2xbmc_spec.rb", "spec/dvdprofiler_profile_spec.rb", "spec/imdb_profile_spec.rb", "spec/nfo_controller_spec.rb", "spec/samples/Collection.xml", "spec/samples/Collection.yaml", "spec/samples/Die Hard - 1988.nfo", "spec/samples/The Egg and I.dummy", "spec/spec.opts", "spec/spec_helper.rb", "spec/tmdb_movie_spec.rb", "spec/tmdb_profile_spec.rb", "spec/xbmc_info_spec.rb", "tasks/rspec.rake", "test/test_dvdprofiler2xbmc.rb", "test/test_dvdprofiler2xbmc_cli.rb", "test/test_helper.rb"]
15
+ s.files = [".gitignore", "History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "Rakefile", "bin/dvdprofiler2xbmc", "dvdprofiler2xbmc.gemspec", "lib/dvdprofiler2xbmc.rb", "lib/dvdprofiler2xbmc/app_config.rb", "lib/dvdprofiler2xbmc/controllers/app.rb", "lib/dvdprofiler2xbmc/controllers/fanart_controller.rb", "lib/dvdprofiler2xbmc/controllers/nfo_controller.rb", "lib/dvdprofiler2xbmc/controllers/thumbnail_controller.rb", "lib/dvdprofiler2xbmc/extensions.rb", "lib/dvdprofiler2xbmc/models/collection.rb", "lib/dvdprofiler2xbmc/models/dvdprofiler_profile.rb", "lib/dvdprofiler2xbmc/models/imdb_profile.rb", "lib/dvdprofiler2xbmc/models/media.rb", "lib/dvdprofiler2xbmc/models/media_files.rb", "lib/dvdprofiler2xbmc/models/tmdb_movie.rb", "lib/dvdprofiler2xbmc/models/tmdb_profile.rb", "lib/dvdprofiler2xbmc/models/xbmc_info.rb", "lib/dvdprofiler2xbmc/open_cache_extension.rb", "lib/dvdprofiler2xbmc/views/cli.rb", "lib/dvdprofiler2xbmc/views/config_editor.rb", "spec/app_spec.rb", "spec/cache_extensions.rb", "spec/config_editor_spec.rb", "spec/dvdprofiler2xbmc_spec.rb", "spec/dvdprofiler_profile_spec.rb", "spec/fanart_controller_spec.rb", "spec/imdb_profile_spec.rb", "spec/media_spec.rb", "spec/nfo_controller_spec.rb", "spec/samples/Collection.xml", "spec/samples/Die Hard - 1988.nfo", "spec/samples/Ma and Pa Kettle.cd1.dummy", "spec/samples/The Egg and I.dummy", "spec/spec.opts", "spec/spec_helper.rb", "spec/tmdb_movie_spec.rb", "spec/tmdb_profile_spec.rb", "spec/xbmc_info_spec.rb", "tasks/rspec.rake", "test/test_dvdprofiler2xbmc.rb", "test/test_helper.rb", "test/test_dvdprofiler2xbmc_cli.rb"]
16
16
  s.has_rdoc = true
17
17
  s.homepage = %q{http://www.github.com/royw/dvdprofiler2xbmc}
18
18
  s.post_install_message = %q{PostInstall.txt}
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_runtime_dependency(%q<log4r>, [">= 1.0.5"])
35
35
  s.add_runtime_dependency(%q<commandline>, [">= 0.7.10"])
36
36
  s.add_runtime_dependency(%q<mash>, [">= 0.0.3"])
37
+ s.add_runtime_dependency(%q<highline>, [">= 1.5.0"])
37
38
  s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
38
39
  s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
39
40
  else
@@ -43,6 +44,7 @@ Gem::Specification.new do |s|
43
44
  s.add_dependency(%q<log4r>, [">= 1.0.5"])
44
45
  s.add_dependency(%q<commandline>, [">= 0.7.10"])
45
46
  s.add_dependency(%q<mash>, [">= 0.0.3"])
47
+ s.add_dependency(%q<highline>, [">= 1.5.0"])
46
48
  s.add_dependency(%q<newgem>, [">= 1.3.0"])
47
49
  s.add_dependency(%q<hoe>, [">= 1.8.0"])
48
50
  end
@@ -53,6 +55,7 @@ Gem::Specification.new do |s|
53
55
  s.add_dependency(%q<log4r>, [">= 1.0.5"])
54
56
  s.add_dependency(%q<commandline>, [">= 0.7.10"])
55
57
  s.add_dependency(%q<mash>, [">= 0.0.3"])
58
+ s.add_dependency(%q<highline>, [">= 1.5.0"])
56
59
  s.add_dependency(%q<newgem>, [">= 1.3.0"])
57
60
  s.add_dependency(%q<hoe>, [">= 1.8.0"])
58
61
  end
@@ -27,5 +27,5 @@ require 'dvdprofiler2xbmc/models/xbmc_info'
27
27
 
28
28
 
29
29
  module Dvdprofiler2xbmc
30
- VERSION = '0.0.6'
30
+ VERSION = '0.0.8'
31
31
  end
@@ -9,17 +9,86 @@
9
9
  # a Hash and does cause a limitation where the key must be either
10
10
  # a symbol or a string.
11
11
  module AppConfig
12
- @config = Mash.new
12
+
13
+ # @config, @help, @initial, @data_type, @validate, and @validate_item
14
+ # are mashes that share the same keys. For example @help.foo would be
15
+ # the help text for @config.foo
16
+
17
+ # the current config values
18
+ @config = Mash.new
19
+
20
+ # help about the config item
21
+ @help = Mash.new
22
+
23
+ # initial (default) config values
24
+ @initial = Mash.new
25
+
26
+ # data type constants used in the editor
27
+ @data_type = Mash.new
28
+
29
+ # validate the config item
30
+ @validate = Mash.new
31
+
32
+ # validate an entry for a config item, note usually need to allow
33
+ # empty string for either array entry termination or to accept
34
+ # a default value
35
+ @validate_item = Mash.new
36
+
37
+ # the @navigation array contains hashes where each hash is a "page"
38
+ # that contains an array of @config keys. This provides a natural
39
+ # organization for UIs.
40
+ @navigation = []
41
+
42
+ class << self
43
+ attr_reader :help, :initial, :navigation, :config, :data_type, :validate, :validate_item
44
+ end
45
+
13
46
  @yaml_filespec = File.join(ENV['HOME'], '.dvdprofiler2xbmcrc')
14
47
 
48
+ # shortcut accessor for @config items
15
49
  def self.[](k)
16
50
  @config[k]
17
51
  end
18
52
 
53
+ # shortcut accessor for @config items
19
54
  def self.[]=(k,v)
20
55
  @config[k] = v
21
56
  end
22
57
 
58
+ # does the config file exist?
59
+ def self.exist?
60
+ File.exist?(@yaml_filespec)
61
+ end
62
+
63
+ # load the config file, overwriting current values
64
+ def self.load
65
+ begin
66
+ if File.exist?(@yaml_filespec)
67
+ cfg = YAML.load_file(@yaml_filespec)
68
+ cfg.delete('logger')
69
+ if cfg.version != @config.version
70
+ AppConfig[:logger].info {"config file (#{@yaml_filespec}) version mismatch"}
71
+ AppConfig[:logger].info {"file version => #{cfg.version}"}
72
+ AppConfig[:logger].info {"config version => #{@config.version}"}
73
+ # remove from @config any keys that are not in cfg
74
+ file_keys = cfg.keys.sort
75
+ current_keys = @config.keys.sort
76
+ intersection_keys = file_keys & current_keys
77
+ obsolete_keys = file_keys - intersection_keys
78
+ obsolete_keys.each do |key|
79
+ AppConfig[:logger].info { "removing obsolete key #{key}"}
80
+ cfg.delete(key)
81
+ end
82
+ cfg.delete('version')
83
+ end
84
+ @config.merge! cfg
85
+ end
86
+ rescue Exception => e
87
+ AppConfig[:logger].error { "Error loading config file \"#{@yaml_filespec} - " + e.to_s + "\n" + e.backtrace.join("\n") }
88
+ end
89
+ end
90
+
91
+ # save the config file
23
92
  def self.save
24
93
  begin
25
94
  unless @config.blank?
@@ -36,80 +105,341 @@ module AppConfig
36
105
  end
37
106
  end
38
107
 
39
- def self.load
40
- begin
41
- if File.exist?(@yaml_filespec)
42
- cfg = YAML.load_file(@yaml_filespec)
43
- cfg.delete('logger')
44
- @config.merge! cfg
108
+ # generate a string for displaying the current config
109
+ def self.to_s
110
+ buf = []
111
+ @navigation.each do |page|
112
+ page.each do |heading, keys|
113
+ buf << heading
114
+ buf << ''
115
+ keys.each do |key|
116
+ buf << key
117
+ buf << @help[key].split("\n").collect{|line| " " + line}.join("\n") unless @help[key].blank?
118
+ buf << "Initial:"
119
+ buf << @initial[key].pretty_inspect.collect{|line| " " + line.rstrip}
120
+ buf << "Current:"
121
+ buf << @config[key].pretty_inspect.collect{|line| " " + line.rstrip}
122
+ buf << ''
123
+ end
124
+ buf << ''
45
125
  end
46
- rescue Exception => e
47
- AppConfig[:logger].error { "Error loading config file \"#{@yaml_filespec} - " + e.to_s }
48
126
  end
127
+ buf.join("\n")
49
128
  end
50
129
 
130
+ # is the current config valid?
131
+ def self.valid?
132
+ valid = true
133
+ @validate.each do |field, value|
134
+ unless @validate[field].call(@config[field])
135
+ valid = false
136
+ end
137
+ end
138
+ valid
139
+ end
140
+
141
+ # set the config to the default values
51
142
  def self.default
52
143
  # Note, all paths and extensions are case sensitive
53
144
 
54
- # Array of paths to scan for media
55
- # Note, directories underneath these will be added as genres to
56
- # each .nfo file. For example:
57
- # /media/royw-gentoo/public/data/movies/Action/Bond/Goldeneye.m4v
58
- # will add 'Action' and 'Bond' genres to Goldeneye.nfo
59
- # Also note, that duplicate genres will be collapsed into single
60
- # genres in the .nfo file.
145
+ # this is the version of the rc file and is used to trigger
146
+ # removal of no longer existing keys
147
+ @config.version = '0.1.0'
148
+
149
+ @config.color_enabled = true
150
+
151
+ @navigation = [
152
+ {'Application Options' => %w(color_enabled)},
153
+ {'Setup Paths' => %w(directories subdirs_as_genres collection_filespec images_dir)},
154
+ {'Setup Permissions'=> %w(file_permissions dir_permissions)},
155
+ {'Setup Genre Mapping' => %w(genre_maps)},
156
+ {'File Naming' => %w(media_extensions image_extensions naming)},
157
+ {'Parsing' => %w(part_regex media_parsers)}
158
+ ]
159
+
160
+ @help.directories = [
161
+ 'Array of paths to scan for media. Replace with your paths.'
162
+ ].join("\n")
163
+ @initial.directories = []
164
+ # My directories are:
61
165
  @config.directories = [
62
- '/media/dad-kubuntu/public/data/videos_iso',
63
- '/media/dcerouter/public/data/videos_iso',
64
- '/media/royw-gentoo/public/data/videos_iso',
65
- '/media/royw-gentoo/public/data/movies'
166
+ # '/media/dad-kubuntu/public/data/videos_iso',
167
+ # '/media/dcerouter/public/data/videos_iso',
168
+ # '/media/royw-gentoo/public/data/videos_iso',
169
+ # '/media/royw-gentoo/public/data/movies'
66
170
  ]
171
+ @data_type.directories = :ARRAY_OF_PATHSPECS
172
+ @validate.directories = lambda do |directories|
173
+ valid = false
174
+ unless directories.empty?
175
+ valid = true
176
+ directories.each do |dir|
177
+ unless File.exist?(dir) && File.directory?(dir)
178
+ valid = false
179
+ end
180
+ end
181
+ end
182
+ valid
183
+ end
184
+ @validate_item.directories = lambda do |dir|
185
+ dir.empty? || (File.exist?(dir) && File.directory?(dir))
186
+ end
187
+
188
+ @help.subdirs_as_genres = [
189
+ 'Directories underneath these will be added as genres to each .nfo file.',
190
+ 'For example:',
191
+ ' /media/movies/Action/Bond/Goldeneye.m4v',
192
+ 'will add "Action" and "Bond" genres to Goldeneye.nfo',
193
+ 'Also note, that duplicate genres will be collapsed into single genres in the .nfo file.'
194
+ ].join("\n")
195
+ @initial.subdirs_as_genres = true
196
+ @config.subdirs_as_genres = @initial.subdirs_as_genres
197
+ @data_type.subdirs_as_genres = :BOOLEAN
67
198
 
68
199
  # Typical locations are:
69
200
  # @config.collection_filespec = File.join(ENV['HOME'], 'DVD Profiler/Databases/Exports/Collection.xml')
70
201
  # @config.images_dir = File.join(ENV['HOME'], 'DVD Profiler/Databases/Default/Images')
71
202
  #
72
- # My locations are:
73
- @config.collection_filespec = '/home/royw/DVD Profiler/Shared/Collection.xml'
74
- @config.images_dir = '/home/royw/DVD Profiler/Shared/Images'
203
+ @help.collection_filespec = [
204
+ 'The location of DVD Profiler\'s exported Collection.xml'
205
+ ].join("\n")
206
+ @initial.collection_filespec = '~/DVD Profiler/Databases/Exports/Collection.xml'
207
+ # My location is:
208
+ @config.collection_filespec = @initial.collection_filespec
209
+ # @config.collection_filespec = '/home/royw/DVD Profiler/Shared/Collection.xml'
210
+ @data_type.collection_filespec = :FILESPEC
211
+ @validate.collection_filespec = lambda do |filespec|
212
+ File.exist?(filespec) && File.file?(filespec)
213
+ end
214
+ @validate_item.collection_filespec = lambda do |filespec|
215
+ filespec.empty? || (File.exist?(filespec) && File.file?(filespec))
216
+ end
217
+
218
+ @help.images_dir = [
219
+ 'The location of DVD Profiler\'s cover scan images.'
220
+ ].join("\n")
221
+ @initial.images_dir = '~/DVD Profiler/Databases/Exports/Images'
222
+ # My location is:
223
+ @config.images_dir = @initial.images_dir
224
+ # @config.images_dir = '/home/royw/DVD Profiler/Shared/Images'
225
+ @data_type.images_dir = :PATHSPEC
226
+ @validate.images_dir = lambda do |directory|
227
+ File.exist?(directory) && File.directory?(directory)
228
+ end
229
+ @validate_item.images_dir = lambda do |directory|
230
+ directory.empty? || (File.exist?(directory) && File.directory?(directory))
231
+ end
75
232
 
76
233
  # You will probably need to edit the MEDIA_EXTENSIONS to specify
77
234
  # the containers used in your library
78
- @config.media_extensions = [ 'iso', 'm4v' ]
235
+ @help.media_extensions = [
236
+ 'The supported file extensions for movie media.',
237
+ 'You probably will not need to edit this list.'
238
+ ].join("\n")
239
+ @initial.media_extensions = %w(iso m4v mp4 mpeg wmv asf flv mkv mov aac nut ogg ogm ram rm rv ra rmvb 3gp vivo pva nuv nsv nsa fli flc)
240
+ @config.media_extensions = @initial.media_extensions
241
+ @data_type.media_extensions = :ARRAY_OF_STRINGS
242
+ @validate.media_extensions = lambda do |extensions|
243
+ !extensions.collect{|ext| ext.blank? ? nil : ext}.compact.empty?
244
+ end
245
+ @validate_item.media_extensions = lambda do |extension|
246
+ true
247
+ end
79
248
 
80
249
  # You probably will not need to change these
81
250
  # Source file extensions.
82
- @config.image_extensions = [ 'jpg', 'jpeg', 'png', 'gif' ]
83
- @config.nfo_extensions = [ 'nfo' ]
84
- # Destination file extensions
85
- @config.thumbnail_extension = 'tbn'
86
- @config.nfo_extension = 'nfo'
87
- @config.no_imdb_extension = 'no_imdb_lookup'
88
- @config.no_tmdb_extension = 'no_tmdb_lookup'
89
- @config.no_isbn_extension = 'no_isbn'
90
- @config.dvdprofiler_xml_extension = 'dvdprofiler.xml'
91
- @config.dvdprofiler_yaml_extension = 'dvdprofiler.yaml'
92
- @config.imdb_xml_extension = 'imdb.xml'
93
- @config.imdb_yaml_extension = 'imdb.yaml'
94
- @config.tmdb_xml_extension = 'tmdb.xml'
95
- @config.tmdb_yaml_extension = 'tmdb.yaml'
96
- @config.fanart_extension = '-fanart'
97
- @config.new_extension = '.new'
98
- @config.backup_extension = '~'
251
+ @help.image_extensions = [
252
+ 'The file extensions for image files such as cover art, fan art, and thumbnails.',
253
+ 'You probably will not need to edit this list.'
254
+ ].join("\n")
255
+ @initial.image_extensions = %w(jpg jpeg png gif bmp tbn)
256
+ @config.image_extensions = @initial.image_extensions
257
+ @data_type.image_extensions = :ARRAY_OF_STRINGS
258
+ @validate.image_extensions = lambda do |extensions|
259
+ !extensions.collect{|ext| ext.blank? ? nil : ext}.compact.empty?
260
+ end
261
+ @validate_item.media_extensions = lambda do |extension|
262
+ true
263
+ end
99
264
 
100
265
  # map some genre names
101
- @config.genre_maps = {
102
- 'SciFi' => 'Science Fiction',
103
- 'Science-Fiction' => 'Science Fiction',
104
- 'Anime' => 'Animation',
105
- 'Musical' => 'Musicals',
106
- 'Music' => 'Musicals'
266
+ @help.genre_maps = [
267
+ 'Change the name of genres.',
268
+ 'For example, "SciFi" can be mapped to "Science Fiction"'
269
+ ].join("\n")
270
+ @initial.genre_maps = {
271
+ 'SciFi' => 'Science Fiction',
272
+ 'Science-Fiction' => 'Science Fiction',
273
+ 'Anime' => 'Animation',
274
+ 'Musical' => 'Musicals',
275
+ 'Music' => 'Musicals',
276
+ 'War Film' => 'War'
107
277
  }
278
+ @config.genre_maps = @initial.genre_maps
279
+ @data_type.genre_maps = :HASH_STRING_KEYS_STRING_VALUES
280
+
281
+ @help.file_permissions = [
282
+ 'Set the file permissions of all files in the scanned directories to this value.',
283
+ 'This is useful to maintain consistancy of file permissions'
284
+ ].join("\n")
285
+ @initial.file_permissions = 0664.to_s(8)
286
+ @config.file_permissions = @initial.file_permissions
287
+ @data_type.file_permissions = :PERMISSIONS
288
+ @validate.file_permissions = lambda do |permissions|
289
+ (permissions.to_i(8) >= 0) && (permissions.to_i(8) <= 07777)
290
+ end
291
+ @validate_item.file_permissions = lambda do |permissions|
292
+ permissions.empty? || ((permissions.to_i(8) >= 0) && (permissions.to_i(8) <= 07777))
293
+ end
294
+
295
+ @help.dir_permissions = [
296
+ 'Set the directory permissions of all sub-directories in the scanned directories to this value.',
297
+ 'This is useful to maintain consistancy of directory permissions'
298
+ ].join("\n")
299
+ @initial.dir_permissions = 0777.to_s(8)
300
+ @config.dir_permissions = @initial.dir_permissions
301
+ @data_type.dir_permissions = :PERMISSIONS
302
+ @validate.dir_permissions = lambda do |permissions|
303
+ permissions.empty? || ((permissions.to_i(8) >= 0) && (permissions.to_i(8) <= 07777))
304
+ end
305
+
306
+ # This maps the file type to extension.
307
+ # The one unusual case in the list is for :fanart where
308
+ # the actually media extension will be appended to this
309
+ # extension (see FanartController)
310
+ @help.extensions = [
311
+ 'Internally used to map types to file extensions.',
312
+ 'You may change the values if you need different file extensions.',
313
+ 'Do not change the keys unless you really know what you are doing!'
314
+ ].join("\n")
315
+ @initial.extensions = {
316
+ :fanart => '-fanart',
317
+ :thumbnail => 'tbn',
318
+ :nfo => 'nfo',
319
+ :dvdprofiler_xml => 'dvdprofiler.xml',
320
+ :imdb_xml => 'imdb.xml',
321
+ :tmdb_xml => 'tmdb.xml',
322
+ :new => 'new',
323
+ :backup => '~',
324
+ :no_isbn => 'no_isbn',
325
+ :no_imdb_lookup => 'no_imdb_lookup',
326
+ :no_tmdb_lookup => 'no_tmdb_lookup',
327
+ }
328
+ @config.extensions = @initial.extensions
329
+ # @data_type.extensions = :HASH_FIXED_SYMBOL_KEYS_STRING_VALUES
330
+
331
+ # substitutions:
332
+ # %t => movie title
333
+ # %e => extension from @config.extensions
334
+ # %p => part
335
+ @help.naming = [
336
+ 'Defines the various formatting of generated file names.',
337
+ 'Do not change the naming keys (ex: :fanart, :thumbnail,...).',
338
+ 'The :part key/value defines the format for a multi-part media while :no_part defines the format for single part media.',
339
+ 'The substutions are:',
340
+ ' %t => movie title',
341
+ ' %e => appropriate file extension',
342
+ ' %p => the part substring from the media file (ex: \'cd1\', \'disc3\')',
343
+ ' %r => video resolution',
344
+ ' %y => year'
345
+ ].join("\n")
346
+ @initial.naming = {
347
+ :fanart => {:part => '%t%e', :no_part => '%t%e'},
348
+ :thumbnail => {:part => '%t.%e', :no_part => '%t.%e'},
349
+ :nfo => {:part => '%t.%e', :no_part => '%t.%e'},
350
+ :dvdprofiler_xml => {:part => '%t.%e', :no_part => '%t.%e'},
351
+ :imdb_xml => {:part => '%t.%e', :no_part => '%t.%e'},
352
+ :tmdb_xml => {:part => '%t.%e', :no_part => '%t.%e'}
353
+ }
354
+ @config.naming = @initial.naming
355
+
356
+ # recognized multi-part tokens where N is an integer:
357
+ # *.cdN.*
358
+ # *.ptN.*
359
+ # *.diskN.*
360
+ # *.discN.*
361
+ @help.part_regex = [
362
+ 'The regular expression for parsing the part sub-string from the media file.',
363
+ 'For example to find "cd2" in "movie.cd2.avi"'
364
+ ].join("\n")
365
+ @initial.part_regex = /\.(cd|pt|disk|disc)\d+/i
366
+ @config.part_regex = @initial.part_regex
367
+
368
+ # media filename parsers.
369
+ # The :tokens array refers to the matches in the regex, ex:
370
+ # {:regex => /^\s*(.*\S)\s*\.([^.]+)\s*$/, :tokens => [:title, :extension]}
371
+ # :title will be assigned the first match (.*\S) and
372
+ # :extension will be assigned the second match ([^.]+)
373
+ # See (Media.parse)
374
+ @help.media_parsers = [
375
+ 'Media filename parsers.',
376
+ 'The :tokens array refers to the matches in the regex, ex:',
377
+ ' {:regex => /^\s*(.*\S)\s*\.([^.]+)\s*$/, :tokens => [:title, :extension]}',
378
+ ':title will be assigned the first match (.*\S) and',
379
+ ':extension will be assigned the second match ([^.]+).',
380
+ 'Valid tokens are: :title, :year, :resolution, :part, :extension'
381
+ ].join("\n")
382
+ @initial.media_parsers = [
383
+ # "movie title - yyyy[res].partN.ext"
384
+ {:regex => /^\s*(.*\S)\s*\-\s*(\d{4})\s*\[(\S*)\]\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
385
+ :tokens => [:title, :year, :resolution, :part, :extension]
386
+ },
387
+ # "movie title (yyyy)[res].partN.ext"
388
+ {:regex => /^\s*(.*\S)\s*\(\s*(\d{4})\s*\)\s*\[(\S*)\]\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
389
+ :tokens => [:title, :year, :resolution, :part, :extension]
390
+ },
391
+ # "movie title[res].partN.ext"
392
+ {:regex => /^\s*(.*\S)\s*\[(\S*)\]\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
393
+ :tokens => [:title, :resolution, :part, :extension]
394
+ },
395
+ # "movie title - yyyy[res].ext"
396
+ {:regex => /^\s*(.*\S)\s*\-\s*(\d{4})\s*\[(\S*)\]\s*\.([^.]+)\s*$/,
397
+ :tokens => [:title, :year, :resolution, :extension]
398
+ },
399
+ # "movie title (yyyy)[res].ext"
400
+ {:regex => /^\s*(.*\S)\s*\(\s*(\d{4})\s*\)\s*\[(\S*)\]\s*\.([^.]+)\s*$/,
401
+ :tokens => [:title, :year, :resolution, :extension]
402
+ },
403
+ # "movie title[res].ext"
404
+ {:regex => /^\s*(.*\S)\s*\[(\S*)\]\s*\.([^.]+)\s*$/,
405
+ :tokens => [:title, :resolution, :extension]
406
+ },
407
+ # "movie title - yyyy.partN.ext"
408
+ {:regex => /^\s*(.*\S)\s*\-\s*(\d{4})\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
409
+ :tokens => [:title, :year, :part, :extension]
410
+ },
411
+ # "movie title (yyyy).partN.ext"
412
+ {:regex => /^\s*(.*\S)\s*\(\s*(\d{4})\s*\)\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
413
+ :tokens => [:title, :year, :part, :extension]
414
+ },
415
+ # "movie title.partN.ext"
416
+ {:regex => /^\s*(.*\S)\s*\.(cd\d+|pt\d+|disk\d+|disc\d+)\.([^.]+)\s*$/,
417
+ :tokens => [:title, :part, :extension]
418
+ },
419
+ # "movie title - yyyy.ext"
420
+ {:regex => /^\s*(.*\S)\s*\-\s*(\d{4})\s*\.([^.]+)\s*$/,
421
+ :tokens => [:title, :year, :extension]
422
+ },
423
+ # "movie title (yyyy).ext"
424
+ {:regex => /^\s*(.*\S)\s*\(\s*(\d{4})\s*\)\s*\.([^.]+)\s*$/,
425
+ :tokens => [:title, :year, :extension]
426
+ },
427
+ # "movie title.ext"
428
+ {:regex => /^\s*(.*\S)\s*\.([^.]+)\s*$/,
429
+ :tokens => [:title, :extension]
430
+ }
431
+ ]
432
+ @config.media_parsers = @initial.media_parsers
433
+
434
+ @help.do_update = [
435
+ 'Perform update.'
436
+ ].join("\n")
437
+ @initial.do_update = true
438
+ @config.do_update = @initial.do_update
439
+ end
108
440
 
109
- @config.file_permissions = 0664
110
- @config.dir_permissions = 0777
111
- @config.imdb_query = true
112
- @config.tmdb_query = true
113
- @config.do_update = true
441
+ private
442
+ def initialize
443
+ AppConfig[:logger].error {"Should never be instantiated"}
114
444
  end
115
445
  end