ex_ua 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +8 -0
- data/ex_ua.gemspec +24 -0
- data/lib/ex_ua/category.rb +108 -0
- data/lib/ex_ua/item.rb +5 -0
- data/lib/ex_ua/version.rb +3 -0
- data/lib/ex_ua.rb +39 -0
- data/spec/category_spec.rb +4 -0
- data/spec/client_spec.rb +4 -0
- data/spec/spec_helper.rb +1 -0
- metadata +81 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/ex_ua.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ex_ua/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ex_ua"
|
7
|
+
s.version = ExUa::VERSION
|
8
|
+
s.authors = ["Andriy Dmytrenko"]
|
9
|
+
s.email = ["refresh.xss@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{An http://ex.ua/ API}
|
12
|
+
s.description = %q{Ruby API for ex.ua}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ex_ua"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "mechanize"
|
24
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module ExUA
|
2
|
+
# Represents a category
|
3
|
+
class Category
|
4
|
+
attr_reader :id,:parent
|
5
|
+
|
6
|
+
# @params[ExUA::Client] ex_ua client
|
7
|
+
# @params[Fixnum] id Category id
|
8
|
+
# @params[Hash] options
|
9
|
+
def initialize(ex_ua, id, options={})
|
10
|
+
@ex_ua,@id = ex_ua, id
|
11
|
+
@url = options[:url] || url_from_id(id)
|
12
|
+
@name = options.delete(:name)
|
13
|
+
@parent = options.delete(:parent)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"id:#{id} name:'#{name}' page: #{page}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
"#<#{self.class}: #{to_s}>"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Canonical url
|
25
|
+
def canonical_url
|
26
|
+
@canonical_url ||= page_content.root.xpath("//link[@rel='canonical']/@href").first.value
|
27
|
+
end
|
28
|
+
|
29
|
+
# Category name
|
30
|
+
def name
|
31
|
+
@name ||= page_content.root.xpath("//meta[@name='title']/@content").first.value
|
32
|
+
end
|
33
|
+
|
34
|
+
# List of subcategories
|
35
|
+
def categories
|
36
|
+
page_content.search('table.include_0 a b').map do |link|
|
37
|
+
if match = link.parent.attributes["href"].value.match(%r{/view/(?<id>\d+)\?r=(?<r>\d+)})
|
38
|
+
Category.new(@ex_ua,match[:id], parent: self, name: link.text)
|
39
|
+
end
|
40
|
+
end.compact
|
41
|
+
end
|
42
|
+
|
43
|
+
# Is there a next category?
|
44
|
+
def next?
|
45
|
+
!!next_url
|
46
|
+
end
|
47
|
+
|
48
|
+
# Is there a previous category?
|
49
|
+
def prev?
|
50
|
+
!!prev_url
|
51
|
+
end
|
52
|
+
|
53
|
+
# Next category
|
54
|
+
def next
|
55
|
+
Category.new(@ex_ua, self.id, url: next_url)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Previous category
|
59
|
+
def prev
|
60
|
+
Category.new(@ex_ua, self.id, url: prev_url)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Current page number
|
64
|
+
def page
|
65
|
+
CGI.parse(URI.parse(@url).query||"")["p"].first || 0
|
66
|
+
end
|
67
|
+
|
68
|
+
# Download items
|
69
|
+
def items
|
70
|
+
table_rows = page_content.search('table.list tr')
|
71
|
+
table_rows.map do |tr|
|
72
|
+
tr.search("a[title!='']")
|
73
|
+
end.reject(&:empty?).map do |links|
|
74
|
+
Item.new.tap do |item|
|
75
|
+
links.each { |link|
|
76
|
+
case link.attributes["href"].value
|
77
|
+
when %r{^/get/}
|
78
|
+
item.download_url = link.attributes["href"].value
|
79
|
+
item.title = link.attributes["title"].value
|
80
|
+
item.id = item.download_url.match(%r{^/get/(\d+)})[1].to_i
|
81
|
+
when %r{^/load}
|
82
|
+
item.additional_servers||=[]
|
83
|
+
item.additional_servers << link.attributes["title"].value
|
84
|
+
end
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
|
92
|
+
def page_content
|
93
|
+
@page_content||=@ex_ua.agent.get("#{ExUA::BASE_URL}#{@url}")
|
94
|
+
end
|
95
|
+
|
96
|
+
def url_from_id(id)
|
97
|
+
"/view/#{id}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def next_url
|
101
|
+
@next_url||=page_content.root.xpath("//link[@rel='next']/@href").first.tap{|a| a.value if a}
|
102
|
+
end
|
103
|
+
|
104
|
+
def prev_url
|
105
|
+
@prev_url||=page_content.root.xpath("//link[@rel='prev']/@href").first.tap{|a| a.value if a}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/ex_ua/item.rb
ADDED
data/lib/ex_ua.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module ExUA
|
2
|
+
BASE_URL='http://ex.ua'
|
3
|
+
end
|
4
|
+
require "ex_ua/version"
|
5
|
+
require "ex_ua/item"
|
6
|
+
require "ex_ua/category"
|
7
|
+
require 'mechanize'
|
8
|
+
|
9
|
+
module ExUA
|
10
|
+
# Client for ExUA
|
11
|
+
# @example Usage
|
12
|
+
# client = ExUA::Client.new
|
13
|
+
# categories = client.base_categories('ru')
|
14
|
+
#
|
15
|
+
class Client
|
16
|
+
attr_reader :agent
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@agent = Mechanize.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<#{self.class}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
# List of available languages
|
27
|
+
def available_languages
|
28
|
+
@available_langauges||=@agent.get(BASE_URL).search('select[name=lang] option').inject({}){|acc,el| acc[el.attributes["value"].value]=el.text;acc}
|
29
|
+
end
|
30
|
+
|
31
|
+
# List of base categories for a given language
|
32
|
+
# @param[String] lang Language
|
33
|
+
# @example
|
34
|
+
# client.base_categories('ru')
|
35
|
+
def base_categories(lang)
|
36
|
+
%w[video audio images texts games software].map{|cat| Category.new(self, nil, url: "/#{lang}/#{cat}")}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/client_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ex_ua'
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ex_ua
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andriy Dmytrenko
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &2151875460 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2151875460
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mechanize
|
27
|
+
requirement: &2151874060 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2151874060
|
36
|
+
description: Ruby API for ex.ua
|
37
|
+
email:
|
38
|
+
- refresh.xss@gmail.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- Gemfile
|
45
|
+
- Rakefile
|
46
|
+
- ex_ua.gemspec
|
47
|
+
- lib/ex_ua.rb
|
48
|
+
- lib/ex_ua/category.rb
|
49
|
+
- lib/ex_ua/item.rb
|
50
|
+
- lib/ex_ua/version.rb
|
51
|
+
- spec/category_spec.rb
|
52
|
+
- spec/client_spec.rb
|
53
|
+
- spec/spec_helper.rb
|
54
|
+
homepage: ''
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project: ex_ua
|
74
|
+
rubygems_version: 1.8.10
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: An http://ex.ua/ API
|
78
|
+
test_files:
|
79
|
+
- spec/category_spec.rb
|
80
|
+
- spec/client_spec.rb
|
81
|
+
- spec/spec_helper.rb
|