sindex 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,3 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ %w{.git test/tmp/}.each {|exception| at.add_exception(exception)}
3
+ end
data/bin/sindex CHANGED
@@ -34,12 +34,16 @@ STANDARD_CONFIG = {
34
34
 
35
35
  config = STANDARD_CONFIG.merge_with_serialized(CONFIG_FILE)
36
36
 
37
- options = {}
37
+ options = {
38
+ :language => :de,
39
+ }
38
40
  OptionParser.new do |opts|
39
- opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [DIR]"
41
+ opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [OPTIONS] [DIR]"
40
42
 
41
43
  opts.separator("")
42
- opts.separator("Tool that manages an index with all your watched episodes")
44
+ opts.separator("Tool that manages an index with all your watched episodes.")
45
+ opts.separator("The default action without any arguments adds new episodes")
46
+ opts.separator("to the index.")
43
47
  opts.separator("")
44
48
  opts.separator(" Options:")
45
49
 
@@ -48,12 +52,42 @@ OptionParser.new do |opts|
48
52
  exit
49
53
  end
50
54
 
55
+ opts.on( "-i", "--indexfile STRING", String,
56
+ "Path to the index that holds the index") do |opt|
57
+
58
+ config[:index_file] = opt
59
+ end
60
+
61
+ opts.on( "-b", "--buildindex STRING", String,
62
+ "Build an index by reading the series/episodes from the supplied directory") do |opt|
63
+
64
+ raise ArgumentError, "supplied directory does not exist" unless
65
+ File.directory? opt
66
+ options[:build_index_from_dir] = opt
67
+ end
68
+
69
+ opts.on( "-l", "--language STRING", String,
70
+ "language in which the episodes in the directory are, choices: (de,en,fr)") do |opt|
71
+
72
+ raise ArgumentError, "Supplied Language not supported, choices:(de,en,fr)" unless
73
+ opt.match(/^(de|en|fr)$/)
74
+ options[:language] = opt.to_sym
75
+ end
76
+
77
+ opts.separator("")
51
78
  opts.separator(" Arguments:")
52
79
  opts.separator(" DIR The path that includes the episodes")
53
80
  opts.separator(" defaults to ~/Downloads")
54
81
  opts.separator("")
55
82
  end.parse!
56
83
 
84
+ # change episode directory if a different directory is supplied
85
+ if directory = ARGV.pop
86
+ raise ArgumentError, "supplied directory does not exist" unless
87
+ File.directory? directory
88
+ config[:episode_directory] = directory
89
+ end
90
+
57
91
 
58
92
  class Cmdline
59
93
  include HighLine::SystemExtensions
@@ -62,19 +96,30 @@ class Cmdline
62
96
  @config = config
63
97
  @options = options
64
98
 
65
- @series_index = Sindex::SeriesIndex.new(index_file: @config[:index_file])
66
99
  @processed_episodes = {}
100
+ end
101
+
102
+ def build_up_index
103
+ @series_index = Sindex::SeriesIndex.new
104
+ @series_index.build_up_index_from_directory(
105
+ @options[:build_index_from_dir], @options[:language])
67
106
 
107
+ @series_index.dump_index_to_file(@config[:index_file])
68
108
  end
69
109
 
70
- # mark episodes as watched
71
110
  def mark_as_watched
111
+ call_pre_processing_hook
112
+
113
+ @series_index = Sindex::SeriesIndex.new(index_file: @config[:index_file])
72
114
 
73
115
  @info_store = Serienrenamer::InformationStore.new(
74
116
  @config[:information_store_path], @config[:byte_count_for_md5])
75
117
 
76
118
  # process all episodes
77
119
  Dir.chdir(@config[:episode_directory])
120
+
121
+ added_episodes=false
122
+
78
123
  for filename in Dir.entries('.').sort do
79
124
 
80
125
  next if filename.match(/^\./)
@@ -109,8 +154,12 @@ class Cmdline
109
154
  @series_index.add_episode_to_index(series_name, filename, language)
110
155
  @processed_episodes[filename] = series_name
111
156
  puts "Added '#{filename}' to index"
157
+
158
+ added_episodes=true
112
159
  end
113
160
 
161
+ exit unless added_episodes
162
+
114
163
  if agree("\nShould I write the new index? ", true)
115
164
  @series_index.dump_index_to_file(@config[:index_file])
116
165
  puts "New Index version has been written\n"
@@ -123,6 +172,8 @@ class Cmdline
123
172
  system(cmd) or fail("Episode-Hook failed")
124
173
  end
125
174
  end
175
+
176
+ call_post_processing_hook
126
177
  else
127
178
  puts "the index was not changed"
128
179
  exit
@@ -134,6 +185,22 @@ class Cmdline
134
185
  #############################################################################
135
186
  private
136
187
 
188
+ def call_pre_processing_hook
189
+ # calling the pre-processing hook to allow a git pull or something else
190
+ # in a Script
191
+ if @config[:pre_processing_hook] and @config[:pre_processing_hook].match(/\w+/)
192
+ system(@config[:pre_processing_hook]) or fail("Pre-Processing-Hook failed")
193
+ end
194
+ end
195
+
196
+ def call_post_processing_hook
197
+ # calling the post-processing hook to allow a git commit/push or something
198
+ # else in a Script
199
+ if @config[:post_processing_hook] and @config[:post_processing_hook].match(/\w+/)
200
+ system(@config[:post_processing_hook]) or fail("Post-Processing-Hook failed")
201
+ end
202
+ end
203
+
137
204
  def determine_episode_language(seriesname, filename)
138
205
  series = @series_index.series_data[seriesname]
139
206
 
@@ -155,10 +222,8 @@ class Cmdline
155
222
  end
156
223
  return language
157
224
  end
158
-
159
225
  end
160
226
 
161
-
162
227
  def determine_series_name_for_episode(filename)
163
228
  sum = md5sum(filename)
164
229
  if not @info_store.episode_hash[sum].nil?
@@ -194,7 +259,6 @@ class Cmdline
194
259
  end
195
260
  end
196
261
 
197
-
198
262
  # Private: Generates a md5sum for the number of bytes for the supplied file
199
263
  #
200
264
  # Returns filename
@@ -209,21 +273,17 @@ class Cmdline
209
273
  end
210
274
  end
211
275
 
212
- # calling the pre-processing hook to allow a git pull or something else
213
- # in a Script
214
- if config[:pre_processing_hook] and config[:pre_processing_hook].match(/\w+/)
215
- system(config[:pre_processing_hook]) or fail("Pre-Processing-Hook failed")
216
- end
276
+ ##########################
277
+ # Do the actual processing
217
278
 
218
279
  cmd = Cmdline.new(config, options)
219
280
  begin
220
- cmd.mark_as_watched()
221
-
222
- # calling the post-processing hook to allow a git commit/push or something
223
- # else in a Script
224
- if config[:post_processing_hook] and config[:post_processing_hook].match(/\w+/)
225
- system(config[:post_processing_hook]) or fail("Post-Processing-Hook failed")
281
+ if options[:build_index_from_dir]
282
+ cmd.build_up_index
283
+ else
284
+ cmd.mark_as_watched
226
285
  end
286
+
227
287
  rescue Interrupt => e
228
288
  puts
229
289
  end
@@ -65,6 +65,37 @@ module Sindex
65
65
  false
66
66
  end
67
67
 
68
+ # Public: Builds up an index from a directory full of series
69
+ #
70
+ # :directory - path to the directory that holds the series
71
+ # :language - the language symbol which the episodes in the directory have
72
+ #
73
+ def build_up_index_from_directory(directory, language=:de)
74
+ raise ArgumentError, "you have not supplied an existing directory" unless
75
+ File.directory? directory
76
+
77
+ Dir.chdir(directory)
78
+
79
+ Dir['*'].sort.each do |directory|
80
+ next unless File.directory? directory
81
+
82
+ series = Series.new
83
+
84
+ Dir["#{directory}/**/*"].sort.each do |episode|
85
+ next unless File.file? episode
86
+ basename_episode = File.basename(episode)
87
+
88
+ next unless SeriesIndex.extract_episode_identifier(basename_episode)
89
+ next unless basename_episode.match(/\.(mkv|mov|avi|flv|mp4|mpg|wmv)$/)
90
+
91
+ series.add_episode(basename_episode, language)
92
+ end
93
+
94
+ @series_data[directory] = series
95
+ end
96
+
97
+ end
98
+
68
99
  # Public: Dumps the in-memory version of the index back to a xml file
69
100
  #
70
101
  # :filename - path to file in which the index should be dumped
@@ -1,3 +1,3 @@
1
1
  module Sindex
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/test/test_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'stringio'
2
2
  require 'turn/autorun'
3
3
  require File.dirname(__FILE__) + '/../lib/sindex'
4
+ require File.join(File.dirname(__FILE__), "test_testdata.rb")
4
5
 
5
6
  Turn.config.ansi = true
6
7
 
@@ -114,3 +114,48 @@ class TestIndex < Test::Unit::TestCase
114
114
  "Shameless.US.S01E09.German"), true
115
115
  end
116
116
  end
117
+
118
+ class TestIndexParsedFromDir < Test::Unit::TestCase
119
+ def setup
120
+ TestData.create
121
+ end
122
+
123
+ def teardown
124
+ TestData.clean
125
+ end
126
+
127
+ def test_that_an_error_is_raised_if_the_directory_does_not_exist
128
+ index = Sindex::SeriesIndex.new()
129
+ assert_raise ArgumentError do
130
+ index.build_up_index_from_directory('/this/should/not/exist')
131
+ end
132
+ end
133
+
134
+ def test_that_the_index_holds_the_right_number_of_series
135
+ index = Sindex::SeriesIndex.new()
136
+ index.build_up_index_from_directory(TestData::SERIES_STORAGE_DIR)
137
+ assert_equal index.empty?, false
138
+ assert_equal 7, index.series_data.length
139
+ assert_equal true, index.is_series_in_index?("The Big Bang Theory")
140
+ assert_equal true, index.is_series_in_index?("Criminal Minds")
141
+ end
142
+
143
+ def test_that_episodes_from_directory_are_in_index
144
+ index = Sindex::SeriesIndex.new()
145
+ index.build_up_index_from_directory(TestData::SERIES_STORAGE_DIR)
146
+
147
+ assert_equal true, index.episode_existing?("Criminal Minds", "S01E01")
148
+ assert_equal false, index.episode_existing?("Criminal Minds", "S01E04")
149
+
150
+ assert_equal true, index.episode_existing?("Chuck", "S01E01")
151
+ assert_equal false, index.episode_existing?("Chuck", "S01E31")
152
+ end
153
+
154
+ def test_that_episodes_are_in_index_in_the_supplied_language
155
+ index = Sindex::SeriesIndex.new()
156
+ index.build_up_index_from_directory(TestData::SERIES_STORAGE_DIR, :en)
157
+
158
+ assert_equal true, index.episode_existing?("Criminal Minds", "S01E01", :en)
159
+ assert_equal false, index.episode_existing?("Criminal Minds", "S01E04", :en)
160
+ end
161
+ end
@@ -0,0 +1,115 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+
3
+ class TestData
4
+
5
+ TESTFILE_DIRECTORY = File.join(File.dirname(__FILE__), 'tmp')
6
+ SERIES_STORAGE_DIR = File.join(TESTFILE_DIRECTORY, 'series')
7
+
8
+ EPISODES = {
9
+ :chuck => { :filename => "S04E11 - Pilot.avi",
10
+ :series => "Chuck",
11
+ :data => { :from => '1_1', :to => '4_10' }
12
+ },
13
+ :tbbt => { :filename => "S05E06 - Pilot.avi",
14
+ :series => "The Big Bang Theory",
15
+ :data => { :from => '1_1', :to => '5_9',
16
+ :exclude => ['5_5', '5_6', '5_7', '5_8', ] }
17
+ },
18
+ :crmi => { :filename => "S01E04 - Pilot.avi",
19
+ :series => "Criminal Minds",
20
+ :data => { :from => '1_1', :to => '1_3' }
21
+ },
22
+ :seap => { :filename => "S01E04 - Pilot.avi",
23
+ :series => "Sea Patrol",
24
+ :data => { :from => '1_1', :to => '1_3' }
25
+ },
26
+ :drhou => { :filename => "S05E01 - First Episode.avi",
27
+ :series => "Dr House",
28
+ :data => { :from => '1_1', :to => '4_20' }
29
+ },
30
+ :spook => { :filename => "S10E01 - First Episode.avi",
31
+ :series => "Spooks",
32
+ :data => { :from => '1_1', :to => '9_20' }
33
+ },
34
+ :numbe => { :filename => "S04E31 - High Episode.avi",
35
+ :series => "Numb3rs",
36
+ :data => { :from => '1_1', :to => '4_30' }
37
+ },
38
+ }
39
+
40
+ # create test data
41
+ def self.create
42
+ _create_directories
43
+ EPISODES.each do |key,value|
44
+ create_series(value[:series], value[:data])
45
+ end
46
+ end
47
+
48
+ # remove files
49
+ def self.clean
50
+ remove_series_dir
51
+ end
52
+
53
+ class << self
54
+
55
+ # this method creates a directory structure for a given
56
+ # series with the opportunity to exclude some episodes
57
+ def create_series(seriesname, options={})
58
+ default = { :from => '1_0', :to => '1_0',
59
+ :max => 30, :exclude => [] }
60
+ options = default.merge(options)
61
+
62
+ series_dir = File.join(SERIES_STORAGE_DIR, seriesname)
63
+ _create_dir(series_dir)
64
+
65
+ from = _split_entry(options[:from])
66
+ to = _split_entry(options[:to])
67
+
68
+ for season in from[0]..to[0]
69
+
70
+ season_dir = File.join(series_dir, "Staffel %02d" % season)
71
+ _create_dir(season_dir)
72
+
73
+ episodes = (season == to[0]) ? to[1] : options[:max]
74
+
75
+ for episode in 1..episodes.to_i
76
+
77
+ # check for excludes
78
+ definition = "%d_%d" % [ season, episode ]
79
+ next if options[:exclude].include? definition
80
+
81
+ # build and create file
82
+ file = "S%02dE%02d - Episode %02d.mkv" % [ season, episode,episode ]
83
+ episode_file = File.join(season_dir, file)
84
+ _create_file(episode_file)
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ # remove testfile directory
91
+ def remove_series_dir
92
+ if File.directory?(SERIES_STORAGE_DIR)
93
+ FileUtils.remove_dir(SERIES_STORAGE_DIR)
94
+ end
95
+ end
96
+
97
+ def _split_entry(definition)
98
+ definition.split(/_/)
99
+ end
100
+
101
+ def _create_directories
102
+ _create_dir TESTFILE_DIRECTORY
103
+ _create_dir SERIES_STORAGE_DIR
104
+ end
105
+
106
+ def _create_dir(dir)
107
+ FileUtils.mkdir(dir) unless File.directory?(dir)
108
+ end
109
+
110
+ def _create_file(file)
111
+ FileUtils.touch(file) unless File.file?(file)
112
+ end
113
+ end
114
+
115
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sindex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
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-11-02 00:00:00.000000000 Z
12
+ date: 2012-11-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -100,6 +100,7 @@ executables:
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
+ - .autotest
103
104
  - .gitignore
104
105
  - .travis.yml
105
106
  - Gemfile
@@ -117,6 +118,7 @@ files:
117
118
  - test/seriesindex_example.xml
118
119
  - test/test_helper.rb
119
120
  - test/test_series_index.rb
121
+ - test/test_testdata.rb
120
122
  homepage: https://github.com/pboehm/sindex
121
123
  licenses: []
122
124
  post_install_message:
@@ -131,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
133
  version: '0'
132
134
  segments:
133
135
  - 0
134
- hash: -599233288800797893
136
+ hash: -4573183238350985480
135
137
  required_rubygems_version: !ruby/object:Gem::Requirement
136
138
  none: false
137
139
  requirements:
@@ -140,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
142
  version: '0'
141
143
  segments:
142
144
  - 0
143
- hash: -599233288800797893
145
+ hash: -4573183238350985480
144
146
  requirements: []
145
147
  rubyforge_project:
146
148
  rubygems_version: 1.8.24
@@ -151,3 +153,4 @@ test_files:
151
153
  - test/seriesindex_example.xml
152
154
  - test/test_helper.rb
153
155
  - test/test_series_index.rb
156
+ - test/test_testdata.rb