sindex 0.0.2 → 0.1.0
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/bin/sindex +230 -0
- data/lib/sindex/version.rb +1 -1
- data/sindex.gemspec +3 -0
- metadata +55 -5
data/bin/sindex
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- ruby -*-
|
3
|
+
# encoding: UTF-8
|
4
|
+
|
5
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
+
|
7
|
+
require 'sindex'
|
8
|
+
require 'serienrenamer'
|
9
|
+
require 'serienmover'
|
10
|
+
require 'fileutils'
|
11
|
+
require 'hashconfig'
|
12
|
+
require 'optparse'
|
13
|
+
require 'digest/md5'
|
14
|
+
require 'highline/import'
|
15
|
+
require "highline/system_extensions"
|
16
|
+
|
17
|
+
# create program configuration dirs/files
|
18
|
+
CONFIG_DIR = File.join( File.expand_path("~"), ".sindex" )
|
19
|
+
CONFIG_FILE = File.join( CONFIG_DIR, "config.yml" )
|
20
|
+
FileUtils.mkdir(CONFIG_DIR) unless File.directory?(CONFIG_DIR)
|
21
|
+
|
22
|
+
###
|
23
|
+
# configuration
|
24
|
+
STANDARD_CONFIG = {
|
25
|
+
:index_file => File.join(CONFIG_DIR, "seriesindex.xml"),
|
26
|
+
:pre_processing_hook => "",
|
27
|
+
:post_processing_hook => "",
|
28
|
+
:episode_hook => "",
|
29
|
+
:episode_directory => File.join(File.expand_path("~"), "Downloads"),
|
30
|
+
:information_store_path =>
|
31
|
+
File.join(File.expand_path("~"), ".serienrenamer/information_storage.yml"),
|
32
|
+
:byte_count_for_md5 => 2048,
|
33
|
+
}
|
34
|
+
|
35
|
+
config = STANDARD_CONFIG.merge_with_serialized(CONFIG_FILE)
|
36
|
+
|
37
|
+
options = {}
|
38
|
+
OptionParser.new do |opts|
|
39
|
+
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [DIR]"
|
40
|
+
|
41
|
+
opts.separator("")
|
42
|
+
opts.separator("Tool that manages an index with all your watched episodes")
|
43
|
+
opts.separator("")
|
44
|
+
opts.separator(" Options:")
|
45
|
+
|
46
|
+
opts.on( "-v", "--version", "Outputs the version number.") do |opt|
|
47
|
+
puts Sindex::VERSION
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.separator(" Arguments:")
|
52
|
+
opts.separator(" DIR The path that includes the episodes")
|
53
|
+
opts.separator(" defaults to ~/Downloads")
|
54
|
+
opts.separator("")
|
55
|
+
end.parse!
|
56
|
+
|
57
|
+
|
58
|
+
class Cmdline
|
59
|
+
include HighLine::SystemExtensions
|
60
|
+
|
61
|
+
def initialize(config, options)
|
62
|
+
@config = config
|
63
|
+
@options = options
|
64
|
+
|
65
|
+
@series_index = Sindex::SeriesIndex.new(index_file: @config[:index_file])
|
66
|
+
@processed_episodes = {}
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# mark episodes as watched
|
71
|
+
def mark_as_watched
|
72
|
+
|
73
|
+
@info_store = Serienrenamer::InformationStore.new(
|
74
|
+
@config[:information_store_path], @config[:byte_count_for_md5])
|
75
|
+
|
76
|
+
# process all episodes
|
77
|
+
Dir.chdir(@config[:episode_directory])
|
78
|
+
for filename in Dir.entries('.').sort do
|
79
|
+
|
80
|
+
next if filename.match(/^\./)
|
81
|
+
next unless Serienrenamer::Episode.determine_video_file(filename)
|
82
|
+
|
83
|
+
# process only files that have the right format
|
84
|
+
next unless filename.match(/^S\d+E\d+.-.\w+.*\.\w+$/)
|
85
|
+
|
86
|
+
puts "\n>>> #{filename}"
|
87
|
+
|
88
|
+
series_name = determine_series_name_for_episode(filename)
|
89
|
+
puts "<< selected series name: #{series_name}"
|
90
|
+
|
91
|
+
if not series_name
|
92
|
+
puts "No suitable series found/selected"
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
96
|
+
if not @series_index.is_series_in_index?(series_name)
|
97
|
+
puts "Series is not in index"
|
98
|
+
next
|
99
|
+
end
|
100
|
+
|
101
|
+
language = determine_episode_language(series_name, filename)
|
102
|
+
puts "<< language: #{language}"
|
103
|
+
|
104
|
+
if @series_index.episode_existing?(series_name, filename, language)
|
105
|
+
puts "This episode is already existing in this series"
|
106
|
+
next
|
107
|
+
end
|
108
|
+
|
109
|
+
@series_index.add_episode_to_index(series_name, filename, language)
|
110
|
+
@processed_episodes[filename] = series_name
|
111
|
+
puts "Added '#{filename}' to index"
|
112
|
+
end
|
113
|
+
|
114
|
+
if agree("\nShould I write the new index? ", true)
|
115
|
+
@series_index.dump_index_to_file(@config[:index_file])
|
116
|
+
puts "New Index version has been written\n"
|
117
|
+
|
118
|
+
# Post process all the episodes with a different hook
|
119
|
+
if @config[:episode_hook] and @config[:episode_hook].match(/\w+/)
|
120
|
+
@processed_episodes.each do |filename,series|
|
121
|
+
puts "Calling Epiode Hook for '#{filename}'"
|
122
|
+
cmd = '%s "%s" "%s"' % [ @config[:episode_hook], filename, series ]
|
123
|
+
system(cmd) or fail("Episode-Hook failed")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
else
|
127
|
+
puts "the index was not changed"
|
128
|
+
exit
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
#############################################################################
|
133
|
+
#############################################################################
|
134
|
+
#############################################################################
|
135
|
+
private
|
136
|
+
|
137
|
+
def determine_episode_language(seriesname, filename)
|
138
|
+
series = @series_index.series_data[seriesname]
|
139
|
+
|
140
|
+
case series.episodes.size
|
141
|
+
when 0
|
142
|
+
return :de
|
143
|
+
when 1
|
144
|
+
return series.episodes.keys.first
|
145
|
+
else
|
146
|
+
language = nil
|
147
|
+
|
148
|
+
puts "The series has watched in multiple languages:"
|
149
|
+
choose do |menu|
|
150
|
+
menu.prompt = "Choose the right language: "
|
151
|
+
|
152
|
+
series.episodes.keys.each do |lang|
|
153
|
+
menu.choice lang.to_s do lambda { language = lang }.call end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
return language
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def determine_series_name_for_episode(filename)
|
163
|
+
sum = md5sum(filename)
|
164
|
+
if not @info_store.episode_hash[sum].nil?
|
165
|
+
series_pattern = @info_store.episode_hash[sum]
|
166
|
+
puts "<< from infostore: #{series_pattern}"
|
167
|
+
|
168
|
+
matching_series = @series_index.series_data.keys.select do |seriesname|
|
169
|
+
Serienmover::SeriesStore.does_match_series?(seriesname, series_pattern)
|
170
|
+
end
|
171
|
+
|
172
|
+
series = nil
|
173
|
+
|
174
|
+
case matching_series.size
|
175
|
+
when 0
|
176
|
+
puts "There are not further information about this episode"
|
177
|
+
series = ask("The name of the series: ") { |q| q.validate = /\w+/ }
|
178
|
+
when 1
|
179
|
+
series = matching_series[0]
|
180
|
+
else
|
181
|
+
|
182
|
+
puts "Available series names:"
|
183
|
+
choose do |menu|
|
184
|
+
menu.prompt = "Choose the right series: "
|
185
|
+
|
186
|
+
matching_series.each do |s|
|
187
|
+
menu.choice s do lambda { series = s }.call end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
return series
|
192
|
+
else
|
193
|
+
return ask("The name of the series: ") { |q| q.validate = /\w+/ }
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
# Private: Generates a md5sum for the number of bytes for the supplied file
|
199
|
+
#
|
200
|
+
# Returns filename
|
201
|
+
def md5sum(filename)
|
202
|
+
if File.file?(filename)
|
203
|
+
d = Digest::MD5.new
|
204
|
+
|
205
|
+
file = File.new(filename)
|
206
|
+
return d.hexdigest(open(file, 'rb').read(@config[:byte_count_for_md5]))
|
207
|
+
end
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
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
|
217
|
+
|
218
|
+
cmd = Cmdline.new(config, options)
|
219
|
+
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")
|
226
|
+
end
|
227
|
+
rescue Interrupt => e
|
228
|
+
puts
|
229
|
+
end
|
230
|
+
|
data/lib/sindex/version.rb
CHANGED
data/sindex.gemspec
CHANGED
@@ -19,4 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_runtime_dependency(%q<nokogiri>, [">= 1.5"])
|
21
21
|
gem.add_runtime_dependency(%q<hashconfig>, [">= 0.0.1"])
|
22
|
+
gem.add_runtime_dependency(%q<serienrenamer>, [">= 0.0.1"])
|
23
|
+
gem.add_runtime_dependency(%q<serienmover>, [">= 0.0.1"])
|
24
|
+
gem.add_runtime_dependency(%q<highline>, ["= 1.6.13"])
|
22
25
|
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.0
|
4
|
+
version: 0.1.0
|
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-10-
|
12
|
+
date: 2012-10-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -43,11 +43,60 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 0.0.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: serienrenamer
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.0.1
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: serienmover
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.0.1
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.0.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: highline
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - '='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.6.13
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - '='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.6.13
|
46
94
|
description: Tool and library that manages the episodes you have seen in different
|
47
95
|
tv series
|
48
96
|
email:
|
49
97
|
- philipp-boehm@live.de
|
50
|
-
executables:
|
98
|
+
executables:
|
99
|
+
- sindex
|
51
100
|
extensions: []
|
52
101
|
extra_rdoc_files: []
|
53
102
|
files:
|
@@ -57,6 +106,7 @@ files:
|
|
57
106
|
- LICENSE.txt
|
58
107
|
- README.md
|
59
108
|
- Rakefile
|
109
|
+
- bin/sindex
|
60
110
|
- lib/sindex.rb
|
61
111
|
- lib/sindex/errors.rb
|
62
112
|
- lib/sindex/series.rb
|
@@ -81,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
131
|
version: '0'
|
82
132
|
segments:
|
83
133
|
- 0
|
84
|
-
hash:
|
134
|
+
hash: 811642567388058588
|
85
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
136
|
none: false
|
87
137
|
requirements:
|
@@ -90,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
140
|
version: '0'
|
91
141
|
segments:
|
92
142
|
- 0
|
93
|
-
hash:
|
143
|
+
hash: 811642567388058588
|
94
144
|
requirements: []
|
95
145
|
rubyforge_project:
|
96
146
|
rubygems_version: 1.8.24
|