kat 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.
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: []