subdl 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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: []