ud 0.1.3 → 0.2.0

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.
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