dlc 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/Rakefile +1 -2
  2. data/VERSION +1 -1
  3. data/dlc.gemspec +18 -16
  4. data/lib/dlc.rb +60 -47
  5. data/test/helper.rb +9 -0
  6. data/test/test_dlc.rb +0 -0
  7. metadata +15 -21
data/Rakefile CHANGED
@@ -10,8 +10,7 @@ begin
10
10
  gem.email = "jphastings@gmail.com"
11
11
  gem.homepage = "http://github.com/jphastings/ruby-DLC"
12
12
  gem.authors = ["JP Hastings-Spital"]
13
- gem.add_dependency "builder"
14
- gem.add_dependency "ruby-aes-normal"
13
+ gem.add_dependency "openssl"
15
14
  end
16
15
  Jeweler::GemcutterTasks.new
17
16
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.1.2
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dlc}
8
- s.version = "1.1.1"
8
+ s.version = "1.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["JP Hastings-Spital"]
12
- s.date = %q{2010-06-09}
12
+ s.date = %q{2010-12-21}
13
13
  s.description = %q{Allows the generation of DLC container files (of JDownloader fame) from ruby}
14
14
  s.email = %q{jphastings@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -17,31 +17,33 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = [
19
19
  "README.rdoc",
20
- "Rakefile",
21
- "VERSION",
22
- "dlc.gemspec",
23
- "lib/dlc.rb"
20
+ "Rakefile",
21
+ "VERSION",
22
+ "dlc.gemspec",
23
+ "lib/dlc.rb",
24
+ "test/helper.rb",
25
+ "test/test_dlc.rb"
24
26
  ]
25
27
  s.homepage = %q{http://github.com/jphastings/ruby-DLC}
26
- s.rdoc_options = ["--charset=UTF-8"]
27
28
  s.require_paths = ["lib"]
28
- s.rubygems_version = %q{1.3.6}
29
+ s.rubygems_version = %q{1.3.7}
29
30
  s.summary = %q{Allows the generation of DLC container files (of JDownloader fame) from ruby}
31
+ s.test_files = [
32
+ "test/helper.rb",
33
+ "test/test_dlc.rb"
34
+ ]
30
35
 
31
36
  if s.respond_to? :specification_version then
32
37
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
33
38
  s.specification_version = 3
34
39
 
35
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
36
- s.add_runtime_dependency(%q<builder>, [">= 0"])
37
- s.add_runtime_dependency(%q<ruby-aes-normal>, [">= 0"])
40
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
41
+ s.add_runtime_dependency(%q<openssl>, [">= 0"])
38
42
  else
39
- s.add_dependency(%q<builder>, [">= 0"])
40
- s.add_dependency(%q<ruby-aes-normal>, [">= 0"])
43
+ s.add_dependency(%q<openssl>, [">= 0"])
41
44
  end
42
45
  else
43
- s.add_dependency(%q<builder>, [">= 0"])
44
- s.add_dependency(%q<ruby-aes-normal>, [">= 0"])
46
+ s.add_dependency(%q<openssl>, [">= 0"])
45
47
  end
46
48
  end
47
49
 
data/lib/dlc.rb CHANGED
@@ -62,14 +62,12 @@ require 'time'
62
62
  require 'net/http'
63
63
  require 'digest/md5'
64
64
 
65
- require 'rubygems'
66
- require 'builder'
67
- require 'ruby-aes'
65
+ require 'openssl'
68
66
 
69
67
  # A hack to make the AES module accept string keys when they look like hex!
70
- def Aes.check_iv(iv)
71
- return iv
72
- end
68
+ #def Aes.check_iv(iv)
69
+ # return iv
70
+ #end
73
71
 
74
72
  # The DLC module, this is the container for the Settings and Package classes. It also contains some private helper functions
75
73
  module DLC
@@ -189,6 +187,13 @@ module DLC
189
187
  @category = "various"
190
188
  @comment = ""
191
189
  end
190
+
191
+ # Experimental reading of DLC files
192
+ def load(dlc)
193
+ dlc = open(dlc).read if !dlc.is_a? String
194
+
195
+
196
+ end
192
197
 
193
198
  # Adds a link to the package
194
199
  # Will take an array of links too
@@ -201,7 +206,12 @@ module DLC
201
206
  return @links
202
207
  end
203
208
  if url.is_a?(String) and url =~ /^http(s)?\:\/\//
204
- @links.push({:url=>url,:filename=>nil,:size=>0})
209
+ response = nil
210
+ uri = URI.parse(url)
211
+ Net::HTTP.start(uri.host, uri.port) {|http|
212
+ response = http.head(uri.path)
213
+ }
214
+ @links.push({:url=>url,:filename=>File.basename(uri.path),:size=>response['content-length'].to_i})
205
215
  return @links
206
216
  end
207
217
  raise RuntimeError, "Invalid URL: #{url}"
@@ -231,39 +241,28 @@ module DLC
231
241
  # the jdownloader service is queried for information.
232
242
  def dlc
233
243
  settings = DLC::Settings.new
234
- if settings.inspect.nil?
244
+ if settings.nil?
235
245
  raise NoGeneratorDetailsError, "You must enter a name, url and email for the generator. See the documentation."
236
246
  end
237
247
 
238
- xml = Builder::XmlMarkup.new(:indent=>0)
239
- xml.dlc do
240
- xml.header do
241
- xml.generator do
242
- xml.app(DLC.encode("Ruby DLC API (kedakai)"))
243
- xml.version(DLC.encode(DLC::Api[:version]))
244
- xml.url(DLC.encode(settings.url))
245
- end
246
- xml.tribute do
247
- xml.name(DLC.encode(settings.name))
248
- end
249
- xml.dlcxmlversion(DLC.encode('20_02_2008'))
250
- end
251
- xml.content do
252
- package = {:name => DLC.encode(@name)}
253
- package[:passwords] = DLC.encode(@passwords.collect{|pw| "\"#{pw}\""}.join(",")) if @passwords.length != 0
254
- package[:comment] = DLC.encode(@comment) if @comment != ""
255
- package[:category] = DLC.encode(@category) if @category != ""
256
- xml.package(package) do
257
- @links.each do |link|
258
- xml.file do
259
- xml.url(DLC.encode(link[:url]))
260
- xml.filename(DLC.encode(link[:filename]))
261
- xml.size(DLC.encode(link[:size]))
262
- end
263
- end
264
- end
265
- end
266
- end
248
+ xml = "<dlc>
249
+ <header>
250
+ <generator>
251
+ <app>#{DLC.encode('Ruby DLC API (kedakai)')}</app>
252
+ <version>#{DLC.encode(DLC::Api[:version])}</version>
253
+ <url>#{DLC.encode(settings.url)}</url>
254
+ </generator>
255
+ <tribute>
256
+ <name>#{DLC.encode(settings.name)}</name>
257
+ </tribute>
258
+ <dlcxmlversion>#{DLC.encode('20_02_2008')}</dlcxmlversion>
259
+ </header>
260
+ <content>
261
+ <package name=\"#{DLC.encode(@name)}\" comment=\"#{DLC.encode(@comment)}\" category=\"#{DLC.encode(@category)}\" passwords=\"#{DLC.encode(@passwords.collect{|pw| '\"#{pw}\"'}.join(','))}\">
262
+ #{@links.collect{|link| "<file><url>#{DLC.encode(link[:url])}</url><filename>#{DLC.encode(link[:filename])}</filename><size>#{DLC.encode(link[:size])}</size></file>"}.join}
263
+ </package>
264
+ </content>
265
+ </dlc>"
267
266
 
268
267
  # Lets get a key/encoded key pair
269
268
  begin
@@ -271,27 +270,41 @@ module DLC
271
270
  rescue NoKeyCachedError
272
271
  # Generate a key
273
272
  expires = 3600
274
- key = Digest::MD5.hexdigest(Time.now.to_i.to_s+"salty salty"+rand(100000).to_s)[0..15]
273
+ key = Digest::MD5.hexdigest(Time.now.to_i.to_s+"GrrrAARRGG!!"+rand(100000).to_s)[0..15]
275
274
  begin
276
- if Net::HTTP.post_form(URI.parse(DLC::Api[:service_urls][rand(DLC::Api[:service_urls].length)]),{
275
+ res = Net::HTTP.post_form(URI.parse(DLC::Api[:service_urls][rand(DLC::Api[:service_urls].length)]),{
277
276
  :data => key, # A random key
278
277
  :lid => DLC.encode([settings.url,settings.email,expires].join("_")), # Details about the generator of the DLC
279
278
  :version => DLC::Api[:version],
280
279
  :client => "rubydlc"
281
- }).body =~ /^<rc>(.+)<\/rc><rcp>(.+)<\/rcp>$/
280
+ })
281
+
282
+ if res.body =~ /<rc>(.+)<\/rc><rcp>(.+)<\/rcp>$/
283
+ key = $2
282
284
  encoded_key = $1
283
- # What is the second part?!
284
285
  settings.set_keycache(key, encoded_key, expires)
285
286
  else
286
- raise ServerNotRespondingError
287
+ raise ServerNotRespondingError, "The DLC service is sending a malformed response. I can't make your DLC at the moment."
287
288
  end
288
289
  rescue
289
290
  raise ServerNotRespondingError, "The DLC service is not responding in the expected way. Try again later."
290
291
  end
291
292
  end
292
-
293
- b64 = DLC.encode(xml.target!)
294
- DLC.encode(Aes.encrypt_buffer(128,"CBC",key,key,b64.ljust((b64.length/16).ceil*16,"\000")))+encoded_key
293
+
294
+ b64 = DLC.encode(xml)
295
+
296
+ cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
297
+ cipher.encrypt
298
+ cipher.iv = key
299
+ cipher.key = key
300
+
301
+ crypt = cipher.update(
302
+ b64.ljust((b64.length/16).ceil*16,"\000") # pad to a multiple of 16 bytes, with 0s
303
+ )
304
+
305
+ crypt << cipher.final
306
+
307
+ DLC.encode(crypt)+encoded_key
295
308
  end
296
309
 
297
310
  # Gives some useful information when people use the library from irb
@@ -305,9 +318,9 @@ module DLC
305
318
  # For when a DLC is requested without settings set
306
319
  class NoGeneratorDetailsError < StandardError; end
307
320
  # For when the keycache is accessed and no valid key is available
308
- class NoKeyCachedError < StandardError; end
321
+ class NoKeyCachedError < RuntimeError; end
309
322
  # For when the service is not responding in the expected manner
310
- class ServerNotRespondingError < StandardError; end
323
+ class ServerNotRespondingError < RuntimeError; end
311
324
 
312
325
  private
313
326
  def self.encode(string)
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+ require 'shoulda'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'dlc'
7
+
8
+ class Test::Unit::TestCase
9
+ end
Binary file
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 1
8
- - 1
9
- version: 1.1.1
8
+ - 2
9
+ version: 1.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - JP Hastings-Spital
@@ -14,13 +14,14 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-09 00:00:00 +01:00
17
+ date: 2010-12-21 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: builder
21
+ name: openssl
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
@@ -29,18 +30,6 @@ dependencies:
29
30
  version: "0"
30
31
  type: :runtime
31
32
  version_requirements: *id001
32
- - !ruby/object:Gem::Dependency
33
- name: ruby-aes-normal
34
- prerelease: false
35
- requirement: &id002 !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- segments:
40
- - 0
41
- version: "0"
42
- type: :runtime
43
- version_requirements: *id002
44
33
  description: Allows the generation of DLC container files (of JDownloader fame) from ruby
45
34
  email: jphastings@gmail.com
46
35
  executables: []
@@ -55,16 +44,19 @@ files:
55
44
  - VERSION
56
45
  - dlc.gemspec
57
46
  - lib/dlc.rb
47
+ - test/helper.rb
48
+ - test/test_dlc.rb
58
49
  has_rdoc: true
59
50
  homepage: http://github.com/jphastings/ruby-DLC
60
51
  licenses: []
61
52
 
62
53
  post_install_message:
63
- rdoc_options:
64
- - --charset=UTF-8
54
+ rdoc_options: []
55
+
65
56
  require_paths:
66
57
  - lib
67
58
  required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
68
60
  requirements:
69
61
  - - ">="
70
62
  - !ruby/object:Gem::Version
@@ -72,6 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
64
  - 0
73
65
  version: "0"
74
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
75
68
  requirements:
76
69
  - - ">="
77
70
  - !ruby/object:Gem::Version
@@ -81,9 +74,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
74
  requirements: []
82
75
 
83
76
  rubyforge_project:
84
- rubygems_version: 1.3.6
77
+ rubygems_version: 1.3.7
85
78
  signing_key:
86
79
  specification_version: 3
87
80
  summary: Allows the generation of DLC container files (of JDownloader fame) from ruby
88
- test_files: []
89
-
81
+ test_files:
82
+ - test/helper.rb
83
+ - test/test_dlc.rb