serienmover 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +12 -11
  2. data/bin/serienmover +148 -131
  3. data/lib/serienmover/version.rb +1 -1
  4. metadata +3 -2
data/README.md CHANGED
@@ -56,14 +56,15 @@ like, hold all copied files in a separate directory. This file has to be
56
56
  executable and there are two parameters supplied:
57
57
  1) the episodefile 2) the seriesname
58
58
 
59
- ### auto_process_list
60
- Should use `serienmover` a file to decide if a file is moved or copied.
61
- The path to the file is set by `auto_process_list_file`, which defaults to
62
- `~/.serienmover/autoprocess.yml`. This file is updated by `serienmover` with
63
- new series. You can select `c` (copy), `m` (move) or `n` (nothing) for every
64
- series. An example for this file follows:
65
-
66
- Scrubs: c
67
- Goofy und Max: n
68
- New Girl: m
69
-
59
+ ### auto_process_enable
60
+ Should `serienmover` decide automatically which action (copy/move) should be
61
+ applied on the episodes.
62
+
63
+ ### auto_default_action
64
+ This is the default action, that `serienmover` will apply, when the previous
65
+ setting is true.
66
+
67
+ ### auto_exceptions
68
+ A list of series that will have the opposite default action. When
69
+ `auto_default_action` is `:copy` than the default action is `:move`, and vice
70
+ versa.
data/bin/serienmover CHANGED
@@ -27,14 +27,15 @@ STANDARD_CONFIG = {
27
27
  :store_path => '',
28
28
  :byte_count_for_md5 => 2048,
29
29
  :post_copy_hook => '',
30
- :auto_process_list => false,
31
- :auto_process_list_file => File.join(CONFIG_DIR, "autoprocess.yml")
30
+ :auto_process_enable => false,
31
+ :auto_default_action => :copy, # or :move
32
+ :auto_exceptions => [ # Series that should have the other action
33
+ 'SERIES_DOESN_NOT_EXISTS',
34
+ ],
32
35
  }
33
36
 
34
37
  config = STANDARD_CONFIG.merge_with_serialized(CONFIG_FILE)
35
38
 
36
- ###
37
- # option definition and handling
38
39
  options = {}
39
40
  OptionParser.new do |opts|
40
41
  opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [DIR]"
@@ -46,7 +47,7 @@ OptionParser.new do |opts|
46
47
  opts.separator(" Options:")
47
48
 
48
49
  opts.on( "-s", "--seriesdir=DIR", String,
49
- "Directory that contains series data (multiple allowed)") do |dirs|
50
+ "Directory that contains series data (multiple allowed)") do |dirs|
50
51
  dirs = [ dirs ] if dirs.is_a? String
51
52
 
52
53
  dirs.each do |d|
@@ -54,98 +55,106 @@ OptionParser.new do |opts|
54
55
  config[:series_directories] << d
55
56
  end
56
57
  end
57
- end
58
+ end
58
59
 
59
60
  opts.on( "-i", "--ignore-seriesinfo",
60
- "do not use the information from the infostore") do |opt|
61
+ "do not use the information from the infostore") do |opt|
61
62
  config[:read_episode_info] = false
62
- end
63
+ end
63
64
 
64
- opts.on( "-n", "--[no]-autoprocess",
65
- "use a file to select between copying and moving") do |opt|
66
- config[:auto_process_list] = opt
67
- end
65
+ opts.on( "-n", "--no-autoprocess",
66
+ "disables auto processing") do |opt|
67
+ config[:auto_process_enable] = false
68
+ end
68
69
 
69
70
  opts.on( "-v", "--version",
70
- "Outputs the version number.") do |opt|
71
+ "Outputs the version number.") do |opt|
71
72
  puts Serienmover::VERSION
72
73
  exit
73
- end
74
+ end
74
75
 
75
76
  opts.separator("")
76
77
  opts.separator(" Arguments:")
77
78
  opts.separator(" DIR The path that includes the episodes")
78
79
  opts.separator(" defaults to ~/Downloads")
79
80
  opts.separator("")
80
-
81
81
  end.parse!
82
82
 
83
- ###
84
- # change into DIR
85
- episode_directory = ARGV.pop || config[:default_directory]
86
83
 
87
- fail "'#{episode_directory}' does not exist or is not a directory" unless
88
- Dir.exists?(episode_directory)
84
+ class Serienmover::Cmdline
89
85
 
90
- Dir.chdir(episode_directory)
86
+ def initialize(config, options)
87
+ @config = config
88
+ @options = options
91
89
 
92
- ###
93
- # instantiate the series_store
94
- store = Serienmover::SeriesStore.new(config[:series_directories])
90
+ @series_store = Serienmover::SeriesStore.new(@config[:series_directories])
91
+ @info_store = Serienrenamer::InformationStore.new(
92
+ @config[:store_path], @config[:byte_count_for_md5])
95
93
 
96
- ###
97
- # build up and load autoprocess list
98
- autoprocess_list = {}
94
+ @processable_files = []
95
+ end
99
96
 
100
- if config[:auto_process_list] && config[:auto_process_list] == true
101
- exisiting_series = Hash[store.series_list.map{ |s| [s, "n"] }]
102
- autoprocess_list =
103
- exisiting_series.merge_with_serialized(config[:auto_process_list_file])
104
- end
97
+ def process
98
+ chdir
105
99
 
106
- ###
107
- # instantiate information store
108
- info_store = Serienrenamer::InformationStore.new(
109
- config[:store_path], config[:byte_count_for_md5])
100
+ Dir.new('.').to_a.sort.each do |file|
101
+ determine_target_and_action file
102
+ end
110
103
 
111
- ###
112
- # iterate through all episode files
113
- episode_actions = []
104
+ exit if @processable_files.empty?
114
105
 
115
- Dir.new('.').to_a.sort.each do |file|
106
+ exit unless should_start_with_processing?
116
107
 
117
- next if file.match(/^\./)
118
- next unless File.file? file
119
- next unless Serienrenamer::Episode.determine_video_file(file)
108
+ puts "\nEpisodes will be processed now"
120
109
 
121
- p file
110
+ @processable_files.each do |episode|
111
+ apply_action_on_episode episode
112
+ end
113
+ end
122
114
 
123
- episode = Serienrenamer::Episode.new(file)
124
115
 
125
- # get seriesname from the informationstore which is used by
126
- # serienrenamer to store the seriesname when it renames files
127
- md5 = episode.md5sum(config[:byte_count_for_md5])
128
- series = info_store.episode_hash[md5]
116
+ def chdir
117
+ episode_directory = ARGV.pop || @config[:default_directory]
129
118
 
130
- options = {}
131
- if config[:read_episode_info] && series && series.match(/\w+/)
132
- options[:series] = series
119
+ fail "'#{episode_directory}' does not exist or is not a directory" unless
120
+ Dir.exists?(episode_directory)
121
+ Dir.chdir(episode_directory)
133
122
  end
134
123
 
135
- targets = store.find_suitable_target(episode, options)
136
- selected_target = nil
137
124
 
138
- ###
139
- # process the targets
140
- case targets.size
141
- when 0
142
- puts "No suitable target found\n"
143
- next
144
- when 1
145
- selected_target = targets[0]
146
- else
125
+ def determine_target_and_action(file)
126
+ return if file.match(/^\./)
127
+ return unless File.file? file
128
+ return unless Serienrenamer::Episode.determine_video_file(file)
129
+
130
+ puts "\n\n"
131
+ p file
132
+
133
+ episode = Serienrenamer::Episode.new(file)
134
+
135
+ # get seriesname from the informationstore which is used by
136
+ # serienrenamer to store the seriesname when it renames files
137
+ md5 = episode.md5sum(@config[:byte_count_for_md5])
138
+ series = @info_store.episode_hash[md5]
139
+
140
+ options = {}
141
+ if @config[:read_episode_info] && series && series.match(/\w+/)
142
+ options[:series] = series
143
+ end
144
+
145
+ targets = @series_store.find_suitable_target(episode, options)
146
+ selected_target = nil
147
+
148
+ ###
149
+ # process the targets
150
+ case targets.size
151
+ when 0
152
+ puts "No suitable target found\n"
153
+ return
154
+ when 1
155
+ selected_target = targets[0]
156
+ else
147
157
 
148
- begin
149
158
  puts "Available targets:"
150
159
  choose do |menu|
151
160
  menu.prompt = "Choose the right target: "
@@ -154,90 +163,98 @@ Dir.new('.').to_a.sort.each do |file|
154
163
  menu.choice t.series do lambda { selected_target = t }.call end
155
164
  end
156
165
  end
157
- rescue Interrupt
158
- puts ""
159
166
  end
160
167
 
161
- end
168
+ if selected_target
169
+ puts ">> '%s'" % selected_target
170
+ episode.target = selected_target
171
+
172
+ # get the choice from the autoprocess
173
+ copy = nil
174
+ if @config[:auto_process_enable]
162
175
 
163
- if selected_target
164
- puts ">> '%s'" % selected_target
165
- episode.target = selected_target
176
+ if @config[:auto_default_action] == :copy and not
177
+ @config[:auto_exceptions].include? episode.target.series
178
+ copy = true
179
+ else
180
+ copy = false
181
+ end
182
+ end
166
183
 
167
- # get the choice from the autoprocess
168
- choice = autoprocess_list[episode.target.series]
169
- copy = nil
170
- copy = true if choice && choice.match(/[ck]/i)
171
- copy = false if choice && choice.match(/[vm]/i)
184
+ ###
185
+ # ask for the action (copy/move)
186
+ print "What should be done ( [c]opy (*) , [m]ove ): "
187
+ char = nil
172
188
 
173
- ###
174
- # ask for the action (copy/move)
175
- print "What should be done ( [c]opy (*) , [m]ove ): "
176
- char = nil
189
+ if copy.nil?
190
+ char = get_character
191
+ print char.chr unless char.chr.match(/\r/)
177
192
 
178
- if copy.nil?
179
- char = get_character
180
- print char.chr unless char.chr.match(/\r/)
193
+ unless char.chr.match(/[kcmv\r]/i)
194
+ puts "\nwill be skipped ...\n\n"
195
+ return
196
+ end
197
+ end
181
198
 
182
- unless char.chr.match(/[kcmv\r]/i)
183
- puts "\nwill be skipped ...\n\n"
184
- next
199
+ if copy == true || char && char.chr.match(/[kc\r]/i)
200
+ episode.set_action(copy: true)
201
+ print " ... copy"
202
+ else
203
+ episode.set_action(move: true)
204
+ print " ... move"
185
205
  end
186
- end
187
206
 
188
- if copy == true || char && char.chr.match(/[kc\r]/i)
189
- episode.set_action(copy: true)
190
- print " ... copy"
191
- else
192
- episode.set_action(move: true)
193
- print " ... move"
207
+ ###
208
+ # save the episode and set the target as used
209
+ @series_store.set_target_to_used(episode, selected_target)
210
+
211
+ @processable_files << episode
194
212
  end
213
+ end
195
214
 
196
- ###
197
- # save the episode and set the target as used
198
- store.set_target_to_used(episode, selected_target)
199
215
 
200
- episode_actions << episode
216
+ def apply_action_on_episode(episode)
217
+ puts "%s '%s' to '%s'" % [episode.action.capitalize, episode, episode.target]
218
+
219
+ episode.process_action
220
+
221
+ # the supplied Script is called with two parameters
222
+ # 1. the path to the episodefile
223
+ # 2. the seriesname
224
+ #
225
+ if @config[:post_copy_hook] &&
226
+ File.file?(@config[:post_copy_hook]) &&
227
+ File.executable?(@config[:post_copy_hook]) &&
228
+ episode.action.match(/copy/i)
229
+
230
+ puts "Calling Post-Copy-Hook for this episode"
231
+ cmd = '%s "%s" "%s"' %
232
+ [ @config[:post_copy_hook], episode.episodepath, episode.target ]
233
+
234
+ system(cmd) or fail "Post-Copy-Hook ends not succesfully"
235
+ end
201
236
  end
202
237
 
203
- puts "\n\n"
204
- end
205
238
 
206
- exit if episode_actions.empty?
239
+ def should_start_with_processing?
207
240
 
208
- ####
209
- # Process the actions on the episodes
210
- print "Start processing the episodes ? [yJ]"
211
- char = get_character
212
- print char.chr
241
+ print "\n\nStart processing the episodes ? [yJ]"
242
+ char = get_character
243
+ print char.chr
213
244
 
214
- unless char.chr.match(/[jy\r]/i)
215
- puts "\nwill exit ...\n\n"
216
- exit
217
- end
245
+ unless char.chr.match(/[jy\r]/i)
246
+ puts "\nwill exit ...\n\n"
247
+ return false
248
+ end
218
249
 
219
- puts "\nEpisodes will be processed now"
220
- episode_actions.each do |episode|
221
- puts "%s '%s' to '%s'" % [episode.action.capitalize, episode, episode.target]
222
-
223
- episode.process_action
224
-
225
- ###
226
- # run the Script that is supplied in config[:post_copy_hook]
227
- # this lets you process episodes that are copied
228
- #
229
- # the supplied Script is called with two parameters
230
- # 1. the path to the episodefile
231
- # 2. the seriesname
232
- if config[:post_copy_hook] &&
233
- File.file?(config[:post_copy_hook]) &&
234
- File.executable?(config[:post_copy_hook]) &&
235
- episode.action.match(/copy/i)
236
-
237
- puts "Calling Post-Copy-Hook for this episode"
238
- cmd = '%s "%s" "%s"' %
239
- [ config[:post_copy_hook], episode.episodepath, episode.target ]
240
-
241
- system(cmd) or fail "Post-Copy-Hook ends not succesfully"
250
+ true
242
251
  end
243
252
  end
253
+
254
+ cmd = Serienmover::Cmdline.new(config, options)
255
+ begin
256
+ cmd.process
257
+ rescue Interrupt => e
258
+ puts
259
+ end
260
+
@@ -1,3 +1,3 @@
1
1
  module Serienmover
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serienmover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-31 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: serienrenamer
@@ -82,3 +82,4 @@ test_files:
82
82
  - spec/series_store_spec.rb
83
83
  - spec/spec_helper.rb
84
84
  - spec/spec_testdata.rb
85
+ has_rdoc: