subdl 0.0.6 → 0.0.7

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. checksums.yaml +7 -0
  2. data/bin/subdl +6 -7
  3. data/lib/subdl.rb +90 -33
  4. metadata +16 -28
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b353f0e19e883d57a353f5ea315cc4d6ef1a71e6
4
+ data.tar.gz: b81266cb82694395f3b86f77bbee9a69f8723271
5
+ SHA512:
6
+ metadata.gz: f67572d0e484e3055ee9d61f389a9a16274bcffd9c3beee96389364e5a9cd43688523fb49c2c27fee8829b16d480e58b833b96b2dd90632f1aac89c9a09522db
7
+ data.tar.gz: cc0219092a9b21f22235e51edd83867b64f255eb66db0b5f35d03d26cebc72f535e41e494a3e0ced9dfa99f7ddc8c0b84922ec590266d746ba9bfd53d5a82777
data/bin/subdl CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
-
3
2
  require 'subdl'
4
3
 
5
- itasa = Itasa.new
6
- Credentials.new.read_to itasa
7
- crawler = Crawler.new itasa
4
+ subdl = Subdl.new mechanize_agent,
5
+ ItasaLoginForm.new,
6
+ $stdout,
7
+ FileSystem.new,
8
+ FileReader.new
8
9
 
9
- until ARGV.empty? do
10
- crawler.download_sub_for ARGV.shift
11
- end
10
+ subdl.main ARGV
@@ -2,16 +2,37 @@ require 'mechanize'
2
2
  require 'cgi'
3
3
  require 'json'
4
4
  require 'zipruby'
5
+ require 'nokogiri'
6
+
7
+ class Subdl
8
+ def initialize agent, itasa_login, stdout, file_system,
9
+ file_reader
10
+ itasa = Itasa.new(agent, itasa_login)
11
+ credentials = Credentials.new file_reader
12
+ @crawler = Crawler.new itasa, credentials, file_system, stdout
13
+ end
14
+ def main argv
15
+ until argv.empty? do
16
+ @crawler.download_sub_for argv.shift
17
+ end
18
+ end
19
+ end
5
20
 
6
21
  class Crawler
7
22
 
8
- def initialize itasa
23
+ def initialize itasa, credentials, file_system, stdout
9
24
  @itasa = itasa
25
+ @credentials = credentials
26
+ @file_system = file_system
27
+ @stdout = stdout
10
28
  end
11
29
 
12
30
  def download_sub_for path
13
- movie_file = MovieFile.new(path)
14
- @itasa.each_id movie_file.search_term do |id, showname|
31
+ movie_file = MovieFile.new path, @stdout
32
+ ids = @itasa.search_subtitles(movie_file.search_term)
33
+
34
+ ids.each do |id|
35
+ @itasa.login *@credentials.read
15
36
  @itasa.download_zip id do |zip_contents|
16
37
  unpack_subtitle_to zip_contents, movie_file
17
38
  end
@@ -21,7 +42,7 @@ class Crawler
21
42
  def unpack_subtitle_to zip_contents, movie_file
22
43
  Zip::Archive.open_buffer(zip_contents) do |archive|
23
44
  archive.each do |entry|
24
- movie_file.add_subtitle entry.read
45
+ movie_file.save_subtitle entry.read, @file_system
25
46
  end
26
47
  end
27
48
  end
@@ -30,8 +51,8 @@ end
30
51
 
31
52
  class MovieFile
32
53
  attr_reader :episode, :season, :show
33
- attr_writer :fs
34
- def initialize filename
54
+
55
+ def initialize filename, stdout=nil
35
56
  @filename = filename
36
57
  text = File.basename filename
37
58
  text = remove_year_from text
@@ -41,7 +62,7 @@ class MovieFile
41
62
  @season = remove_leading_zeros m[2]
42
63
  @episode = remove_leading_zeros m[3]
43
64
  end
44
- @fs = FileSystem
65
+ @stdout = stdout
45
66
  end
46
67
 
47
68
  def remove_year_from text
@@ -56,10 +77,11 @@ class MovieFile
56
77
  "%s %dx%02d" % [show, season, episode]
57
78
  end
58
79
 
59
- def add_subtitle contents
80
+ def save_subtitle contents, fs
60
81
  srt_filename = @filename.gsub /.mp4$/, ''
61
82
  srt_filename += ".itasa#{next_distinguisher}.srt"
62
- @fs.save_file srt_filename, contents
83
+ @stdout.puts "Downloaded as #{srt_filename}"
84
+ fs.save_file srt_filename, contents
63
85
  end
64
86
 
65
87
  def next_distinguisher
@@ -74,58 +96,81 @@ class MovieFile
74
96
  end
75
97
 
76
98
  class FileSystem
77
- def self.save_file filename, contents
99
+ def save_file filename, contents
78
100
  File.open filename, 'w' do |f|
79
101
  f.write contents
80
102
  end
81
103
  end
82
104
  end
83
105
 
84
- class Itasa
85
- def initialize
86
- @agent = Mechanize.new do |a|
87
- a.user_agent_alias = 'Mac FireFox'
88
- end
106
+ def mechanize_agent
107
+ Mechanize.new do |a|
108
+ a.user_agent_alias = 'Mac FireFox'
89
109
  end
110
+ end
90
111
 
91
- def login username, password
92
- home_page = @agent.get "http://#{host}"
112
+ class ItasaLoginForm
113
+
114
+ def login username, password, page_where_to_login, agent
115
+ return if logged_in?
116
+ home_page = agent.get page_where_to_login
93
117
  login_form = home_page.form 'login'
94
118
  login_form.username = username
95
119
  login_form.passwd = password
96
- @page = @agent.submit(login_form)
120
+ @page = agent.submit(login_form)
97
121
  end
98
122
 
123
+ private
124
+
99
125
  def logged_in?
100
126
  return false unless @page
101
127
  link_that_exists_only_once_logged = @page.search(
102
128
  "//a[@href='forum/index.php?action=unreadreplies']")
103
- link_that_exists_only_once_logged.first
129
+ return link_that_exists_only_once_logged.first != nil
130
+ end
131
+
132
+
133
+ end
134
+
135
+ class Itasa
136
+ def initialize agent, login_form
137
+ @agent = agent
138
+ @login_form = login_form || ItasaLoginForm.new
139
+ end
140
+
141
+ def login username, password
142
+ @login_form.login username, password, "http://#{host}", @agent
104
143
  end
105
144
 
106
- def each_id text
145
+ def autocomplete_data_for text
107
146
  response = @agent.get search_url(text)
108
- JSON.parse(response.body).each do |episode|
109
- yield episode['id'], episode['value']
110
- end
111
- nil
147
+ response.body
148
+ end
149
+
150
+ def search_subtitles text
151
+ json = autocomplete_data_for text
152
+ return extract_ids_from_autocomplete_data json
153
+ end
154
+
155
+ def extract_ids_from_autocomplete_data json
156
+ JSON.parse(json).map { |episode| episode['id'] }
112
157
  end
113
158
 
114
159
  def download_zip id
115
160
  page = @agent.get subtitle_page_url(id)
116
- zipped_subtitle = @agent.get subtitle_zip_url(page)
161
+ zipped_subtitle = @agent.get subtitle_zip_url(page.body)
117
162
  yield zipped_subtitle.body
118
163
  end
119
164
 
120
165
  def subtitle_zip_url page
121
- link = page.search("//a[img[contains(@src,'download2.gif')]]").first
122
- return link[:href]
166
+ doc = Nokogiri::HTML(page)
167
+ return doc.at_xpath("//a[img[contains(@src,'download2.gif')]]")[:href]
123
168
  end
124
169
 
125
170
  def search_url text
126
171
  url = URI.parse "http://#{host}/modules/mod_itasalivesearch/search.php"
127
172
  url.query = "term=#{CGI.escape text}"
128
- return url
173
+ return url.to_s
129
174
  end
130
175
 
131
176
  def subtitle_page_url id
@@ -139,10 +184,22 @@ class Itasa
139
184
  end
140
185
 
141
186
  class Credentials
142
- def read_to itasa
143
- contents = File.read(File.expand_path('~/.itasa-credentials')).lines
144
- username = contents.next.chomp
145
- password = contents.next.chomp
146
- itasa.login username, password
187
+ def initialize file_reader
188
+ @file_reader = file_reader
189
+ end
190
+ def parse file_contents
191
+ lines = file_contents.lines.to_a
192
+ username = lines[0].chomp
193
+ password = lines[1].chomp
194
+ [username, password]
195
+ end
196
+ def read
197
+ parse @file_reader.read_expand('~/.itasa-credentials')
198
+ end
199
+ end
200
+
201
+ class FileReader
202
+ def read_expand expandable_path
203
+ File.read(File.expand_path(expandable_path))
147
204
  end
148
205
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subdl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
5
- prerelease:
4
+ version: 0.0.7
6
5
  platform: ruby
7
6
  authors:
8
7
  - Andrea Francia
@@ -14,81 +13,71 @@ dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: mechanize
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: zipruby
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: json
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rspec
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  description: A simple hello world gem
@@ -102,26 +91,25 @@ files:
102
91
  - bin/subdl
103
92
  homepage: https://github.com/andreafrancia/subdl
104
93
  licenses: []
94
+ metadata: {}
105
95
  post_install_message:
106
96
  rdoc_options: []
107
97
  require_paths:
108
98
  - lib
109
99
  required_ruby_version: !ruby/object:Gem::Requirement
110
- none: false
111
100
  requirements:
112
- - - ! '>='
101
+ - - '>='
113
102
  - !ruby/object:Gem::Version
114
103
  version: '0'
115
104
  required_rubygems_version: !ruby/object:Gem::Requirement
116
- none: false
117
105
  requirements:
118
- - - ! '>='
106
+ - - '>='
119
107
  - !ruby/object:Gem::Version
120
108
  version: '0'
121
109
  requirements: []
122
110
  rubyforge_project:
123
- rubygems_version: 1.8.25
111
+ rubygems_version: 2.0.3
124
112
  signing_key:
125
- specification_version: 3
113
+ specification_version: 4
126
114
  summary: Download subtitles for your favorite show.
127
115
  test_files: []