apple-tv-converter 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,7 +28,7 @@ module AppleTvConverter
28
28
  end
29
29
 
30
30
  def search_subtitles(media, &block)
31
- language_options = languages.map(&:to_s).join(',') if languages.any?
31
+ language_options = languages.map(&:to_sym).join(',') if languages.any?
32
32
  options = []
33
33
 
34
34
  # Query by movie hash
@@ -142,7 +142,7 @@ module AppleTvConverter
142
142
  # Filter by number of discs (1)
143
143
  media_subtitles = media_subtitles.select { |s| s['SubSumCD'] == '1' }
144
144
  # Filter by language
145
- media_subtitles = media_subtitles.select { |s| languages.empty? || languages.include?(s['SubLanguageID']) }
145
+ media_subtitles = media_subtitles.select { |s| languages.empty? || languages.include?(s['SubLanguageID'].to_sym) }
146
146
  # Filter by movie name (unless it's an episode, as the movie name can be the episode's title)
147
147
  media_subtitles = media_subtitles.select { |s| s['MatchedBy'] == 'moviehash' || normalize(s['MovieName']) == normalize(media.show) } unless media.is_tv_show_episode?
148
148
 
@@ -155,7 +155,7 @@ module AppleTvConverter
155
155
  # media_subtitles = exact_match if exact_match.any?
156
156
 
157
157
  # Group the subtitles by language code
158
- media_subtitles = media_subtitles.group_by { |a| a['SubLanguageID'] }
158
+ media_subtitles = media_subtitles.group_by { |a| a['SubLanguageID'].to_sym }
159
159
 
160
160
  all_subtitles = Hash[*media_subtitles.flatten(1)]
161
161
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apple-tv-converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.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: 2014-07-21 00:00:00.000000000 Z
12
+ date: 2014-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -175,6 +175,28 @@ dependencies:
175
175
  - - ! '>='
176
176
  - !ruby/object:Gem::Version
177
177
  version: 2.7.0
178
+ - !ruby/object:Gem::Dependency
179
+ name: rest-client
180
+ requirement: !ruby/object:Gem::Requirement
181
+ none: false
182
+ requirements:
183
+ - - ~>
184
+ - !ruby/object:Gem::Version
185
+ version: 1.7.2
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: 1.7.2
189
+ type: :runtime
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ~>
195
+ - !ruby/object:Gem::Version
196
+ version: 1.7.2
197
+ - - ! '>='
198
+ - !ruby/object:Gem::Version
199
+ version: 1.7.2
178
200
  description: Converts movies to a format playable on Apple TV. Supporting multiple
179
201
  subtitles.
180
202
  email:
@@ -192,9 +214,12 @@ files:
192
214
  - lib/apple_tv_converter/media_converter_adapter.rb
193
215
  - lib/apple_tv_converter/media_converter_mac_adapter.rb
194
216
  - lib/apple_tv_converter/media_converter_windows_adapter.rb
217
+ - lib/apple_tv_converter/metadata/imdb.rb
218
+ - lib/apple_tv_converter/metadata/info.rb
219
+ - lib/apple_tv_converter/metadata/movie_db.rb
220
+ - lib/apple_tv_converter/metadata/tv_db.rb
195
221
  - lib/apple_tv_converter/movie_hasher.rb
196
222
  - lib/apple_tv_converter/subtitles_fetcher/opensubtitles.rb
197
- - lib/apple_tv_converter/tv_db_fetcher.rb
198
223
  - lib/apple_tv_converter/version.rb
199
224
  - lib/apple_tv_converter.rb
200
225
  - gems/streamio-ffmpeg/CHANGELOG
@@ -1,264 +0,0 @@
1
- module AppleTvConverter
2
- class TvDbFetcher
3
- require 'httparty'
4
- require 'yaml'
5
- require 'net/http'
6
- require 'zip/zip'
7
- require 'xml'
8
-
9
- include HTTParty
10
-
11
- base_uri 'thetvdb.com/api'
12
-
13
- def self.search(media, interactive = true, language = 'en')
14
- get_updates_from_server
15
-
16
- if media.tvdb_id
17
- show_id = media.tvdb_id
18
- else
19
- data = load_config_file('show_ids') || {}
20
-
21
- # http://thetvdb.com/api/GetSeries.php?seriesname=
22
- unless data.has_key?(media.show)
23
- show_ids = get_and_parse_data_from_server('show_ids', '/GetSeries.php', { :query => { :seriesname => media.show } }, ['Data', 'Series']) do |loaded_data|
24
- loaded_data = [loaded_data].flatten
25
-
26
- data[media.show] = if loaded_data.length > 1 && interactive
27
- choice = 0
28
- puts "\n *"
29
-
30
- while true
31
- puts %Q[ | Several shows found, choose the intended one:]
32
-
33
- loaded_data.each_with_index do |item, index|
34
- puts " | #{(index + 1).to_s.rjust(loaded_data.length.to_s.length)} - #{item['SeriesName']} (id: #{item['seriesid']})"
35
- puts " | #{' '.rjust(loaded_data.length.to_s.length)} AKA: #{item['AliasNames']}" if item['AliasNames']
36
- end
37
-
38
- printf " |\n *- What's your choice (1..#{loaded_data.length})? "
39
- choice = STDIN.gets.chomp.to_i
40
-
41
- break if choice.between?(1, loaded_data.length)
42
-
43
- puts " | Invalid choice!"
44
- puts " |"
45
- end
46
-
47
- loaded_data[choice - 1]['seriesid']
48
- else
49
- loaded_data.first['seriesid']
50
- end
51
-
52
- # Return the new list sorted by show name
53
- Hash[data.sort]
54
- end
55
- end
56
-
57
- show_id = data[media.show]
58
- end
59
-
60
- if show_id.to_i > 0
61
- # <mirrorpath_zip>/api/<apikey>/series/<seriesid>/all/<language>.zip
62
- show_data = get_data(show_id, "/#{api_key}/series/#{show_id}/all/#{language}.zip", { :zip => true }) do |data|
63
- show_data = xml_document_to_hash(XML::Document.string(data[language.to_s].gsub(/>\s*</im, '><')))
64
- banners = xml_document_to_hash(XML::Document.string(data['banners'].gsub(/>\s*</im, '><'))) rescue { 'Banner' => [] }
65
- actors = xml_document_to_hash(XML::Document.string(data['actors'].gsub(/>\s*</im, '><'))) rescue { 'Actor' => [] }
66
-
67
- {
68
- :series => show_data['Series'],
69
- :episodes => [show_data['Episode']].flatten,
70
- :banners => [banners['Banner']].flatten,
71
- :actors => [actors['Actor']].flatten
72
- }
73
-
74
- end
75
-
76
- return {
77
- :episode => show_data[:episodes].detect do |ep|
78
- # For season 1, check the absolute number first (for cartoons, etc.), and then check the usual season/episode combo
79
- (media.season.to_i == 1 && ep['absolute_number'].to_i == media.number.to_i) || (ep['SeasonNumber'].to_i == media.season.to_i && ep['EpisodeNumber'].to_i == media.number.to_i)
80
- end,
81
- :show => show_data
82
- }
83
- end
84
-
85
- return false
86
- end
87
-
88
- def self.get_poster(media)
89
- local_file = File.join(AppleTvConverter.data_path, 'cache', 'tvdb', "#{media.tvdb_id}.jpg")
90
-
91
- unless File.exists?(local_file)
92
- artwork_filename = media.tvdb_movie[:show][:series]['poster'] || ''
93
- artwork_filename = media.tvdb_movie_data('filename') || '' if artwork_filename.blank?
94
- artwork_filename = "http://thetvdb.com/banners/#{artwork_filename}" if !artwork_filename.blank?
95
-
96
- AppleTvConverter.copy artwork_filename, local_file unless artwork_filename.blank?
97
- end
98
-
99
- local_file
100
- end
101
-
102
- private
103
-
104
- def self.api_key ; return '67FBF9F0670DBDF2' ; end
105
- def self.local_cache_base_path
106
- return File.expand_path(File.join(AppleTvConverter.data_path, 'cache', 'tvdb'))
107
- end
108
- def self.server_update_timestamp
109
- @server_update_timestamp ||= load_config_file('update')
110
-
111
- unless @server_update_timestamp
112
- # http://thetvdb.com/api//Updates.php?type=none
113
- @server_update_timestamp = get_data_from_server('/Updates.php', { :query => { :type => 'none' }})["Items"]["Time"] rescue nil
114
- @server_update_timestamp = @server_update_timestamp.to_i unless @server_update_timestamp.nil?
115
- save_config_file 'update', @server_update_timestamp
116
- end
117
-
118
- @server_update_timestamp
119
- end
120
-
121
- def self.load_config_file(filename)
122
- full_filename = File.join(local_cache_base_path, filename =~ /\.yml$/ ? filename : "#{filename}.yml")
123
- File.exists?(full_filename) ? YAML.load_file(full_filename) : nil
124
- end
125
-
126
- def self.save_config_file(filename, data)
127
- full_filename = File.join(local_cache_base_path, filename =~ /\.yml$/ ? filename : "#{filename}.yml")
128
- File.open(full_filename, 'w') { |f| f.write data.to_yaml }
129
- end
130
-
131
- def self.delete_config_file(filename)
132
- full_filename = File.join(local_cache_base_path, filename =~ /\.yml$/ ? filename : "#{filename}.yml")
133
- File.delete(full_filename) if File.exists?(full_filename)
134
- end
135
-
136
-
137
- def self.get_data_from_server(url, options = {})
138
- AppleTvConverter.logger.debug " -> Getting from server: #{url}"
139
- cache = options.delete(:cache) || true
140
- zip = options.delete(:zip) || false
141
- response = self.get(url, options).parsed_response
142
-
143
- if zip
144
- filename = File.join(local_cache_base_path, 'zip_file.zip')
145
-
146
- begin
147
- File.open(filename, 'wb') { |f| f.write response }
148
- response = {}
149
-
150
- Zip::ZipFile.open(filename) do |zipfile|
151
- zipfile.each do |entry|
152
- unless entry.name.downcase["__macosx"]
153
- zip_data = zipfile.read(entry)
154
- response[entry.name.to_s.gsub(/\.xml$/i, '')] = zip_data
155
- end
156
- end
157
- end
158
- rescue => e
159
- ap [e, e.backtrace]
160
-
161
- ensure
162
- FileUtils.rm_f filename if File.exists?(filename)
163
- end
164
- end
165
-
166
- return response
167
- end
168
-
169
- def self.get_data(filename, url, url_options, response_indexes = [])
170
- AppleTvConverter.logger.debug "-> Getting data: #{filename}"
171
- data = load_config_file(filename)
172
-
173
- unless data
174
- data = get_data_from_server(url, url_options)
175
-
176
- if data
177
- begin
178
- response_indexes.each { |idx| data = data[idx] }
179
-
180
- data = yield(data) if block_given?
181
-
182
- save_config_file filename, data
183
- rescue
184
- data = nil
185
- end
186
- end
187
- else
188
- # ap ['found on cache', filename, data]
189
- end
190
-
191
- return data
192
- end
193
-
194
- def self.get_and_parse_data_from_server(filename, url, url_options, response_indexes = [])
195
- cache = url_options.delete(:cache) || true
196
- data = get_data_from_server(url, url_options)
197
-
198
- if data
199
- begin
200
- response_indexes.each { |idx| data = data[idx] }
201
-
202
- data = yield(data) if block_given?
203
-
204
- save_config_file filename, data if cache
205
- rescue
206
- data = nil
207
- end
208
- end
209
- end
210
-
211
- def self.get_updates_from_server(options = {})
212
- get_and_parse_data_from_server('updates', '/Updates.php', { :query => { :type => 'all', :time => load_config_file('update')}, :cache => false }, ['Items']) do |data|
213
- if data
214
- # Delete each show's cached data
215
- data['Series'].each do |show_id|
216
- delete_config_file show_id
217
- delete_config_file "#{show_id}.jpg"
218
- end
219
-
220
- # Save the new timestamp
221
- save_config_file 'update', data['Time']
222
- @server_update_timestamp = data['Time']
223
- end
224
- end
225
- end
226
-
227
- def self.xml_document_to_hash(document)
228
- def self.xml_node_to_hash(xml)
229
- return nil if xml.children.empty?
230
- return xml.children.first.to_s if xml.children.count == 1 && xml.children.first.text?
231
-
232
- # Append a sequential number to the name to prevent replacing items that should be in an array
233
- child_number = 0
234
- Hash[*(xml.children.map { |child| child_number += 1 ; ["#{child.name}::#{child_number}", xml_node_to_hash(child)] }.compact.flatten(1))]
235
- end
236
-
237
- intermediate_hash = xml_node_to_hash(document.root)
238
-
239
- return Hash[*(intermediate_hash.group_by do |obj|
240
- obj.first.gsub(/::\d+$/, '')
241
- end.map do |key, value|
242
- # Remove the 'key' entries
243
- value = value.flatten(1).delete_if { |v| v.to_s =~ /#{key}::\d+/ }
244
-
245
- # Remove the sequential number from the keys
246
- value.map! do |element|
247
- Hash[*(element.map do |ikey, ivalue|
248
- [ikey.gsub(/::\d+$/, ''), ivalue]
249
- end.flatten(1))]
250
- end
251
-
252
- # If there's only one entry, remove the array
253
- value = value.first if value.count == 1
254
-
255
- [key, value]
256
- end.flatten(1))]
257
- end
258
-
259
- FileUtils.mkdir_p local_cache_base_path
260
-
261
- # Load the server timestamp on startup
262
- server_update_timestamp
263
- end
264
- end