serienmover 0.1.2 → 0.1.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.
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: