kat 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/kat.rb +114 -0
  3. metadata +44 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac470759ccf5f883197aa00a7f6f35a5a2f145f9
4
+ data.tar.gz: 03af12f13bc393815acdc233db00a69f0357b351
5
+ SHA512:
6
+ metadata.gz: bd6dd7ec83d42f787841820cf6143edf8792f7ca2be069c71eaea96a1e7a70c445160e612138a6e630148df66f7c734346b682a4c003e5e765a007b79b8412d4
7
+ data.tar.gz: 18a7cf881b384e435b4a2e6e449cd8b1b1a442d8217484f1b098e68fd38f1b54cfebac20fe89c1ea5bb4ac6e4fed4ac7a6795540a04de6537bba47c2ec9fe6e0
@@ -0,0 +1,114 @@
1
+ # TODO: Implement field sort and sort order
2
+ # Lookup advanced search for language and platform values
3
+ # Comments
4
+ # Tests
5
+
6
+ require 'nokogiri'
7
+ require 'open-uri'
8
+
9
+ class Kat
10
+ VERSION = 0.1
11
+
12
+ KAT_URL = 'http://kickass.to'
13
+ SEARCH_URL = "#{KAT_URL}/usearch/"
14
+ ADVANCED_URL = "#{KAT_URL}/torrents/search/advanced/"
15
+
16
+ STRING_FIELDS = [ :category, :seeds, :user, :age, :files, :imdb, :season, :episode ]
17
+ SELECT_FIELDS = [ { :name => :language, :id => :lang_id }, { :name => :platform, :id => :platform_id } ]
18
+ SWITCH_FIELDS = [ :safe, :verified ]
19
+
20
+ attr_reader :results, :pages, :error
21
+
22
+ def initialize search_term = nil, opts = {}
23
+ @search_term = []
24
+ @options = opts.is_a?(Hash) ? opts : {}
25
+ self.query = search_term.dup
26
+ end
27
+
28
+ def self.search search_term
29
+ self.new(search_term).search
30
+ end
31
+
32
+ def query page = 0
33
+ @query.join(' ').gsub(/[^a-z0-9\-: _]/i, '') + (page > 0 ? "/#{page + 1}" : '') + (@query.empty? ? '' : '/')
34
+ end
35
+
36
+ def query= search_term
37
+ @search_term = case search_term
38
+ when nil then []
39
+ when String then [ search_term ]
40
+ when Array then search_term.flatten.select {|el| el.is_a? String }
41
+ else raise ArgumentError, "search_term must be a String or Array object. #{search_term.inspect} given."
42
+ end
43
+ build_query
44
+ end
45
+
46
+ def options
47
+ @options.dup
48
+ end
49
+
50
+ def options= opts
51
+ raise ArgumentError, "opts must be a Hash object. #{opts.inspect} given." unless opts.is_a? Hash
52
+ @options.merge! opts
53
+ build_query
54
+ end
55
+
56
+ def search page = 0
57
+ unless query.empty? or @results[page] or (@pages > 0 and page >= @pages)
58
+ begin
59
+ doc = Nokogiri::HTML(open("#{SEARCH_URL}#{URI::encode(query page)}"))
60
+ @results[page] = doc.css('td.torrentnameCell').map do |node|
61
+ { :title => node.css('a.normalgrey').text,
62
+ :magnet => node.css('a.imagnet').first.attributes['href'].value,
63
+ :download => node.css('a.idownload').last.attributes['href'].value,
64
+ :size => (node = node.next_element).text,
65
+ :files => (node = node.next_element).text.to_i,
66
+ :age => (node = node.next_element).text,
67
+ :seeds => (node = node.next_element).text.to_i,
68
+ :leeches => (node = node.next_element).text.to_i }
69
+ end
70
+ @pages = doc.css('div.pages > a').last.text.to_i if @pages == 0
71
+ @pages = 1 if @pages == 0
72
+ rescue => e
73
+ if e.name == :text
74
+ @pages = 1
75
+ else
76
+ @error = { :error => e, :query => query(page) }
77
+ end
78
+ end
79
+ end
80
+
81
+ @results[page]
82
+ end
83
+
84
+ def respond_to? method_sym, include_private = false
85
+ return true if not @results.empty? and (@results.last.first[method_sym] or @results.last.first[method_sym.to_s.chop.to_sym])
86
+ super
87
+ end
88
+
89
+ private
90
+
91
+ def build_query
92
+ @query = @search_term.dup
93
+ @pages = 0
94
+ @results = []
95
+
96
+ @query << "\"#{@options[:exact]}\"" if @options[:exact]
97
+ @query << @options[:or].join(' OR ') unless @options[:or].nil? or @options[:or].empty?
98
+ @query += @options[:without].map {|s| "-#{s}" } if @options[:without]
99
+
100
+ STRING_FIELDS.each {|f| @query << "#{f}:#{@options[f]}" if @options[f] }
101
+ SELECT_FIELDS.each {|f| @query << "#{f[:id]}:#{@options[f[:name]]}" if @options[f[:name]].to_i > 0 }
102
+ SWITCH_FIELDS.each {|f| @query << "#{f}:1" if @options[f] }
103
+ end
104
+
105
+ def method_missing method_sym, *arguments, &block
106
+ m = method_sym.to_s.chop.to_sym
107
+ if not @results.empty? and (@results.last.first[method_sym] or @results.last.first[m])
108
+ @results.compact.map {|rs| rs.map {|r| r[method_sym] || r[m] } }.flatten
109
+ else
110
+ super
111
+ end
112
+ end
113
+
114
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kat
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Fission Xuiptz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A command-line interface to Kickass Torrents
14
+ email: fissionxuiptz@softwaremojo.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/kat.rb
20
+ homepage: http://rubygems.org/gems/kat
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.0.3
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Kickass Torrents CLI
44
+ test_files: []