ud 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2134c365e3c168e488e70bd92781de30d419787b
4
- data.tar.gz: 41f9521a67fcbd7a13af576b72ad0487b912634e
3
+ metadata.gz: 6c17aeb74c72f8713fd49862c33fa292f256174d
4
+ data.tar.gz: f1964b4cf50361f5b2765aee3e136cc96d806c61
5
5
  SHA512:
6
- metadata.gz: 046591e9726d26e77674979759936e8337a0048b4102db0493edec4431d47796f61171d6ff4f767c237568245bcd5c8052c87c5208918a9503c43a4ce6f5361a
7
- data.tar.gz: 323c6c600173bf87c696dd26a1ae4e66649223728ff760c69544b2c98891a534cefea349f4f2ba3d84b8878970e5137d85c0aefbbf3426db81e662beb58fcdf0
6
+ metadata.gz: cf6a6865b51c9ae2aebd9a063d365b3457aad7aa7a946c706eceb46b299ffcf4a36e981c1d85ee0352693d4c92de840314be300dda31cc9b87742aca105929f4
7
+ data.tar.gz: e69cc02df921261f58893efb090f8debae155845d4a144f658ad79f1ce15090a9c4903d037bb728cf5a5b9fcd0f16e447b566ecf35566301c71cf364dd79ea92
data/bin/ud CHANGED
@@ -14,7 +14,7 @@ Usage:
14
14
  where [options] are:
15
15
  EOS
16
16
 
17
- opt :ratio, 'Filter by upvotes/downvotes ratio', :type => :float, :default => 0.0
17
+ opt :ratio, 'Filter by upvotes/downvotes ratio', :type => :float, :default => 0.0, :short => '-r'
18
18
  opt :count, 'Limit the number of definitions', :type => :int, :default => 1, :short => '-n'
19
19
  opt :color, 'Use colorized output', :default => true
20
20
  opt :up, 'Shortcut for \'-r 2\''
data/lib/ud.rb CHANGED
@@ -4,112 +4,67 @@
4
4
  require 'uri'
5
5
  require 'json'
6
6
  require 'open-uri'
7
- require 'nokogiri'
8
7
 
9
8
  require File.dirname(__FILE__) + '/ud/formatting'
10
9
 
11
10
  # This module provide some methods to scrape definitions from the Urban
12
11
  # Dictionary website.
13
12
  module UD
13
+ class << self
14
14
 
15
- # The current version of the module
16
- def UD.version
17
- '0.1.3'
18
- end
19
-
20
- # Get the search URL to query for a given term.
21
- # [term] the term to search for. It must be a string, spaces are allowed
22
- def UD.search_url(term='')
23
- param = URI.encode_www_form('term' => term)
24
- "http://www.urbandictionary.com/define.php?#{param}"
25
- end
26
-
27
- # Get the thumbs (up/down) for a list of definitions' ids.
28
- # This is an helper for internal usage.
29
- def UD.thumbs(ids)
30
-
31
- param = URI.encode_www_form('ids' => ids.join(','))
32
- json = open "http://api.urbandictionary.com/v0/uncacheable?#{param}"
33
-
34
- response = JSON.parse(json.read)
35
- thumbs = {}
36
-
37
- response['thumbs'].each do |t|
38
-
39
- thumbs[t['defid']] = {
40
- :up => t['thumbs_up'],
41
- :down => t['thumbs_down']
42
- }
43
-
15
+ def version
16
+ '0.2.0'
44
17
  end
45
18
 
46
- thumbs
47
- end
48
-
49
- # Get the text of an element. This is an helper for internal usage.
50
- def UD.text(el)
51
- el.text.strip.gsub(/\r/, "\n")
52
- rescue
53
- ''
54
- end
55
-
56
- # Query the website and return a list of definitions for the provided term.
57
- # This list may be empty if there's no result. It only scraps the first
58
- # page of results.
59
- # [term] the term to search for
60
- # [opts] options. This is used by the command-line tool. +:count+ is the
61
- # maximum number of results to return, +:ratio+ is the minimum
62
- # upvotes/downvotes ratio. Other options may be added in the future.
63
- def UD.query(term, *opts)
64
-
65
- opts = {:count => 1, :ratio => 0.0}.merge(opts[0] || {})
66
-
67
- return [] if opts[:count] <= 0
68
-
69
- url = search_url(term)
70
- doc = Nokogiri::HTML(open(url))
71
-
72
- return [] unless doc.css('#not_defined_yet').empty?
73
-
74
- words = doc.css('#entries .box')
75
- ids = words.take(opts[:count]).map do |w|
76
- w.css('.thumb.up').first.attr('data-defid')
19
+ # Get the search URL to query for a given term.
20
+ # [term] the term to search for. It must be a string, spaces are allowed
21
+ def search_url(term='')
22
+ param = URI.encode_www_form('term' => term)
23
+ "http://api.urbandictionary.com/v0/define?#{param}"
77
24
  end
78
25
 
79
- thumbs = thumbs(ids)
80
-
81
- if opts[:ratio] > 0
82
- ids.delete_if do |id|
83
- t = thumbs[id.to_i] || {:up => 1, :down => 1}
84
- (t[:up] / t[:down].to_f) < opts[:ratio]
85
- end
26
+ # Get the text of an element. This is an helper for internal usage.
27
+ def text(el)
28
+ el.text.strip.gsub(/\r/, "\n")
29
+ rescue
30
+ ''
86
31
  end
87
32
 
88
- ids.map do |id|
89
-
90
- box = doc.css(".add_to_list[data-defid=\"#{id}\"]").first.parent
91
-
92
- word = text box.css(".word > a").first
93
- t = thumbs[id.to_i] || {}
94
-
95
- {
96
- :id => id,
97
- :word => word,
98
- :definition => text(box.css('.definition')),
99
- :example => text(box.css('.example')),
100
- :upvotes => t[:up],
101
- :downvotes => t[:down]
102
-
103
- }
104
-
33
+ # Query the website and return a list of definitions for the provided term.
34
+ # This list may be empty if there's no result.
35
+ # [term] the term to search for
36
+ # [opts] options. This is used by the command-line tool. +:count+ is the
37
+ # maximum number of results to return, +:ratio+ is the minimum
38
+ # upvotes/downvotes ratio. Other options may be added in the future.
39
+ def query(term, *opts)
40
+
41
+ opts = {:count => 1, :ratio => 0.0}.merge(opts[0] || {})
42
+
43
+ return [] if opts[:count] <= 0
44
+
45
+ resp = JSON.parse(open(search_url term).read, :symbolize_names => true)
46
+
47
+ resp[:list].map do |res|
48
+ {
49
+ :id => res[:defid],
50
+ :word => res[:word],
51
+ :author => res[:author],
52
+ :permalink => res[:permalink],
53
+ :definition => res[:definition].strip,
54
+ :example => res[:example].strip,
55
+ :upvotes => res[:thumbs_up],
56
+ :downvotes => res[:thumbs_down]
57
+ }
58
+ end.keep_if do |d|
59
+ d[:upvotes]/[d[:downvotes], 0.1].max.to_f >= opts[:ratio]
60
+ end.take opts[:count]
105
61
  end
106
62
 
107
- end
63
+ # Format results for output
64
+ # [results] this must be an array of results, as returned by +UD.query+.
65
+ def format_results(results, color=true)
66
+ UD::Formatting.text(results, color)
67
+ end
108
68
 
109
- # Format results for output
110
- # [results] this must be an array of results, as returned by +UD.query+.
111
- def UD.format_results(results, color=true)
112
- UD::Formatting.text(results, color)
113
69
  end
114
-
115
70
  end
data/lib/ud/formatting.rb CHANGED
@@ -3,10 +3,11 @@
3
3
 
4
4
  module UD
5
5
  module Formatting
6
+ class << self
6
7
 
7
8
  # Fit a text in a given width (number of chars). It returns
8
9
  # a list of lines of text.
9
- def self.fit(txt, width=79)
10
+ def fit(txt, width=79)
10
11
  return [] if width < 1
11
12
 
12
13
  # from http://stackoverflow.com/a/7567210/735926
@@ -18,7 +19,7 @@ module UD
18
19
  # the beginning of each element.
19
20
  # [txt] The text to tab, may be a string or a list of strings
20
21
  # [width] The width (number of spaces) of a tab
21
- def self.tab(txt, width=4)
22
+ def tab(txt, width=4)
22
23
  width = 0 if width < 0
23
24
 
24
25
  tab = ' ' * width
@@ -30,7 +31,7 @@ module UD
30
31
 
31
32
  # Format results for text output (e.g. in the terminal)
32
33
  # [results] this must be an array of results, as returned by +UD.query+.
33
- def self.text(results, color=true)
34
+ def text(results, color=true)
34
35
  require 'colored' if color
35
36
 
36
37
  results.map do |r|
@@ -61,5 +62,6 @@ module UD
61
62
  end.join("\n")
62
63
  end
63
64
 
65
+ end
64
66
  end
65
67
  end
data/tests/query_tests.rb CHANGED
@@ -5,106 +5,92 @@ require File.dirname(__FILE__) + '/fake_responses'
5
5
 
6
6
  class UD_Formatting_test < Test::Unit::TestCase
7
7
 
8
- ROOT_URL = 'http://www.urbandictionary.com'
8
+ ROOT_URL = 'http://api.urbandictionary.com/v0/define'
9
+
10
+ def setup
11
+ @foo, @bar = [
12
+ {
13
+ :id => 1,
14
+ :author => 'a1',
15
+ :permalink => 'http://example.com/1',
16
+ :word => 'foo',
17
+ :definition => 'A',
18
+ :example => 'AA',
19
+ :upvotes => 42,
20
+ :downvotes => 17
21
+
22
+ },
23
+ {
24
+ :id => 2,
25
+ :author => 'a2',
26
+ :permalink => 'http://example.com/2',
27
+ :word => 'bar',
28
+ :definition => 'B',
29
+ :example => 'BB',
30
+ :upvotes => 17,
31
+ :downvotes => 42
32
+ }
33
+ ]
34
+ end
9
35
 
10
36
  # == UD#search_url == #
11
37
 
12
38
  def test_search_url_empty_term
13
39
  assert_equal(
14
- "#{ROOT_URL}/define.php?term=",
40
+ "#{ROOT_URL}?term=",
15
41
  UD.search_url())
16
42
  assert_equal(
17
- "#{ROOT_URL}/define.php?term=",
43
+ "#{ROOT_URL}?term=",
18
44
  UD.search_url(''))
19
45
  end
20
46
 
21
47
  def test_search_url_spaces_in_term
22
48
  assert_equal(
23
- "#{ROOT_URL}/define.php?term=a+b",
49
+ "#{ROOT_URL}?term=a+b",
24
50
  UD.search_url('a b'))
25
51
  end
26
52
 
27
53
  def test_search_url_encode_special_chars
28
54
  assert_equal(
29
- "#{ROOT_URL}/define.php?term=%3D",
55
+ "#{ROOT_URL}?term=%3D",
30
56
  UD.search_url('='))
31
57
  end
32
58
 
33
59
  def test_search_url
34
60
  assert_equal(
35
- "#{ROOT_URL}/define.php?term=foo",
61
+ "#{ROOT_URL}?term=foo",
36
62
  UD.search_url('foo'))
37
63
  end
38
64
 
39
- # == UD#thumbs == #
40
-
41
- def test_thumbs_no_ids
42
- assert_equal({}, UD.thumbs([]))
43
- end
44
-
45
- def test_thumbs_one_id
46
- assert_equal({42 =>{:up => 2, :down => 1}}, UD.thumbs([42]))
47
- end
48
-
49
65
  # == UD#query == #
50
66
 
51
67
  def test_query_no_results
52
- assert_equal([], UD.query('nothing'))
68
+ assert_equal([], UD.query('fooo'))
53
69
  end
54
70
 
55
71
  def test_query_two_results
56
72
 
57
73
  expected = [
58
- {
59
- :id => '1',
60
- :word => 'foo',
61
- :definition => 'A',
62
- :example => 'AA',
63
- :upvotes => 1,
64
- :downvotes => 1
65
-
66
- },
67
- {
68
- :id => '2',
69
- :word => 'bar',
70
- :definition => 'B',
71
- :example => 'BB',
72
- :upvotes => 2,
73
- :downvotes => 1
74
- }
74
+ @foo, @bar
75
75
  ]
76
76
 
77
- assert_equal(expected, UD.query('two', :count => 2))
77
+ assert_equal(expected, UD.query('two_results', :count => 2))
78
78
  end
79
79
 
80
80
  def test_query_count
81
81
  expected = [
82
- {
83
- :id => '1',
84
- :word => 'foo',
85
- :definition => 'A',
86
- :example => 'AA',
87
- :upvotes => 1,
88
- :downvotes => 1
89
- }
82
+ @foo
90
83
  ]
91
84
 
92
- assert_equal(expected, UD.query('two', :count => 1))
85
+ assert_equal(expected, UD.query('two_results', :count => 1))
93
86
  end
94
87
 
95
88
  def test_query_ratio
96
89
  expected = [
97
- {
98
- :id => '2',
99
- :word => 'bar',
100
- :definition => 'B',
101
- :example => 'BB',
102
- :upvotes => 2,
103
- :downvotes => 1
104
- }
90
+ @foo
105
91
  ]
106
92
 
107
- assert_equal(expected, UD.query('two', :count => 10, :ratio => 1.5))
93
+ assert_equal(expected, UD.query('two_results', :count => 10, :ratio => 1.5))
108
94
  end
109
95
 
110
96
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Baptiste Fontaine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-12 00:00:00.000000000 Z
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: nokogiri
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 1.5.9
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 1.5.9
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: json
29
15
  requirement: !ruby/object:Gem::Requirement