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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ex_ua.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :spec
6
+
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new
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
@@ -0,0 +1,5 @@
1
+ module ExUA
2
+ # Download item
3
+ class Item < Struct.new(:id, :title, :download_url, :additional_servers)
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module ExUa
2
+ VERSION = "0.0.1"
3
+ end
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
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+ describe ExUA::Category do
3
+ pending
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+ describe ExUA::Client do
3
+ pending
4
+ end
@@ -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