ud 0.2.5 → 0.3.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: ef94c79592b39fe5f56775e9d08eab3ea601db08
4
- data.tar.gz: 3202e4b6ce4fe9bb52b2ef984c137f714d3091d4
3
+ metadata.gz: be08bba53ec9677e2382c7221afbdbe86daeeb2b
4
+ data.tar.gz: 2127476c4b657755e04cd5393a4bc58c852a6840
5
5
  SHA512:
6
- metadata.gz: dd4694a3b5970d1073129ffa8078c5727e4246161bcbd2bde9c4b02b4a4fe09248d5d9ae8a5cf6fe31bca65f3b8f82676076bbeaea1d604e928a0f8011be62b0
7
- data.tar.gz: bbeede97c81c1496c534fbf8c48771f0e2145ef11506d4cb8b0ff7a0dc9c76ef2d1b6c05fa08de5846ebe435666d4edca59e02fa69cb7cd6412173c576e50938
6
+ metadata.gz: ab2a0d140114d914a7a066219ad5e3fd2a93c8f20bb8be031900a779db2d4a5ba244f330b1d85e14a95134e7cc2213c1a8973e34f4a21f28d4dacb4234199452
7
+ data.tar.gz: f421052deba0e6a06f163450d1d5871c85cc68a33dabdc4234ea855dbbb006571114d336621251e2b378a9329127ebfc6cd4eba636650b7146cca418a6a16b10
Binary file
data.tar.gz.sig CHANGED
Binary file
data/bin/ud CHANGED
@@ -2,10 +2,10 @@
2
2
  # -*- coding: UTF-8 -*-
3
3
 
4
4
  # clean interrupt
5
- trap('INT') { abort }
5
+ trap("INT") { abort }
6
6
 
7
- require 'trollop'
8
- require 'ud'
7
+ require "trollop"
8
+ require "ud"
9
9
 
10
10
  opts = Trollop.options do
11
11
  version "ud #{UD.version}"
@@ -17,30 +17,24 @@ Usage:
17
17
  where [options] are:
18
18
  EOS
19
19
 
20
- opt :ratio, 'Filter by upvotes/downvotes ratio', :type => :float, :default => 0.0, :short => '-r'
21
- opt :count, 'Limit the number of definitions', :type => :int, :default => 1, :short => '-n'
22
- opt :color, 'Use colorized output', :default => true
23
- opt :browser, 'Open the results in a browser window', :short => '-b'
24
- opt :up, 'Shortcut for \'-r 2\''
25
-
20
+ opt :count, "Limit the number of definitions", :type => :int, :default => 1, :short => "-n"
21
+ opt :random, "Print a random definition instead of searching", :short => "m"
22
+ opt :color, "Use colorized output", :default => true
23
+ opt :browser, "Open the results in a browser window", :short => "-b"
26
24
  end
27
25
 
28
- Trollop.die :ratio, 'must be non-negative' if opts[:ratio] < 0
29
- Trollop.die :count, 'must be non-negative' if opts[:count] < 0
30
-
31
- opts[:ratio] = 2 if opts[:up]
26
+ Trollop.die :count, "must be non-negative" if opts[:count] < 0
32
27
 
33
- if ARGV.empty?
34
- puts 'Error: No word provided. Use -h or --help to see the help.'
28
+ if !opts[:random] && ARGV.empty?
29
+ puts "Error: No word provided. Use -h or --help to see the help."
35
30
  exit 1
36
31
  end
37
32
 
38
- term = ARGV.join(' ')
33
+ term = ARGV.join " "
39
34
 
40
35
  if opts[:browser]
41
- UD.open_url(term)
36
+ opts[:random] ? UD.open_random : UD.open_url(term)
42
37
  else
43
- q = UD.query(ARGV.join(' '), opts)
38
+ q = opts[:random] ? UD.random(opts) : UD.query(ARGV.join(" "), opts)
44
39
  puts UD.format_results(q, opts[:color])
45
40
  end
46
-
data/lib/ud.rb CHANGED
@@ -1,61 +1,83 @@
1
1
  # -*- coding: UTF-8 -*-
2
2
 
3
- require 'uri'
4
- require 'json'
5
- require 'open-uri'
3
+ require "uri"
4
+ require "json"
5
+ require "open-uri"
6
6
 
7
- require File.dirname(__FILE__) + '/ud/formatting'
7
+ require File.dirname(__FILE__) + "/ud/formatting"
8
8
 
9
9
  # This module provide some methods to scrape definitions from the Urban
10
10
  # Dictionary website.
11
11
  module UD
12
12
  class << self
13
-
14
13
  # @return [String] the current gem's version
15
14
  def version
16
- '0.2.5'
15
+ "0.3.0"
17
16
  end
18
17
 
19
18
  # Get the search URL to query for a given term.
20
19
  # @param term [String] the term to search for. It must be a string, spaces
21
20
  # are allowed.
22
- # @param api [Boolean] truthy if the API URL should be used.
21
+ # @param opts [Hash] options.
23
22
  # @return [String]
24
- def search_url(term='', api=true)
25
- param = URI.encode_www_form('term' => term)
23
+ def search_url(term, opts = {})
24
+ param = URI.encode_www_form("term" => term)
26
25
 
27
- if api
26
+ if opts[:api] != false
28
27
  "http://api.urbandictionary.com/v0/define?#{param}"
29
28
  else
30
29
  "http://www.urbandictionary.com/define.php?#{param}"
31
30
  end
32
31
  end
33
32
 
33
+ # @param opts [Hash] options.
34
+ def random_url(opts = {})
35
+ if opts[:api] != false
36
+ "http://api.urbandictionary.com/v0/random"
37
+ else
38
+ "http://www.urbandictionary.com/random.php"
39
+ end
40
+ end
41
+
34
42
  # Open the search URL in the user's browser
35
43
  # @param term [String] the term to search for. It must be a string, spaces
36
44
  # are allowed.
37
45
  # @return [Nil]
38
- def open_url(term='')
39
- system open_cmd, search_url(term, false)
46
+ def open_url(term)
47
+ system open_cmd, search_url(term, :api => false)
48
+ end
49
+
50
+ # Open a random definition URL in the user's browser
51
+ # @return [Nil]
52
+ def open_random
53
+ system open_cmd, random_url(:api => false)
40
54
  end
41
55
 
42
56
  # Query the website and return a list of definitions for the provided term.
43
57
  # This list may be empty if there's no result.
44
58
  # @param term [String] the term to search for
45
59
  # @param opts [Hash] options. This is used by the command-line tool.
46
- # +:count+ is the maximum number of results to return,
47
- # +:ratio+ is the minimum upvotes/downvotes ratio. Other
48
- # options may be added in the future.
60
+ # +:count+ is the maximum number of results to return
49
61
  # @return [Array<Hash>]
50
- def query(term, *opts)
62
+ def query(term, opts = {})
63
+ parse_response(open(search_url(term)).read, opts)
64
+ end
51
65
 
52
- opts = {:count => 1, :ratio => 0.0}.merge(opts[0] || {})
66
+ def random(opts = {})
67
+ parse_response(open(random_url).read, opts)
68
+ end
69
+
70
+ # @param opts [Hash] options. This is used by the command-line tool.
71
+ # +:count+ is the maximum number of results to return
72
+ # @return [Array<Hash>]
73
+ def parse_response(text, opts = {})
74
+ opts = { :count => 1 }.merge(opts || {})
53
75
 
54
76
  return [] if opts[:count] <= 0
55
77
 
56
- resp = JSON.parse(open(search_url term).read, :symbolize_names => true)
78
+ resp = JSON.parse(text, :symbolize_names => true)
57
79
 
58
- resp[:list].map do |res|
80
+ results = resp[:list].map do |res|
59
81
  {
60
82
  :id => res[:defid],
61
83
  :word => res[:word],
@@ -64,11 +86,11 @@ module UD
64
86
  :definition => res[:definition].strip,
65
87
  :example => res[:example].strip,
66
88
  :upvotes => res[:thumbs_up],
67
- :downvotes => res[:thumbs_down]
89
+ :downvotes => res[:thumbs_down],
68
90
  }
69
- end.keep_if do |d|
70
- d[:upvotes]/[d[:downvotes], 0.1].max.to_f >= opts[:ratio]
71
- end.take opts[:count]
91
+ end
92
+
93
+ results.take opts[:count]
72
94
  end
73
95
 
74
96
  # Format results for output
@@ -76,7 +98,7 @@ module UD
76
98
  # +UD.query+.
77
99
  # @param color [Boolean] colored output
78
100
  # @return [String]
79
- def format_results(results, color=true)
101
+ def format_results(results, color = true)
80
102
  UD::Formatting.text(results, color)
81
103
  end
82
104
 
@@ -1,63 +1,61 @@
1
1
  # -*- coding: UTF-8 -*-
2
2
 
3
3
  module UD
4
-
5
4
  # Formatting tools for {UD.query}'s output
6
5
  module Formatting
7
6
  class << self
8
-
9
- # Fit a text in a given width (number of chars).
10
- # @param txt [String]
11
- # @param width [Integer] maximum width
12
- # @return [Array] list of lines of text
13
- def fit(txt, width=79)
14
- return [] if width < 1
15
-
16
- # from http://stackoverflow.com/a/7567210/735926
17
- r = /(.{1,#{width}})(?:\s|$)/m
18
- txt.split("\n").map { |l| l.scan(r) }.flatten
19
- end
20
-
21
- # Add a tab at the beginning of a text. If it's a list, add a tab at
22
- # the beginning of each element.
23
- # @param txt [String] The text to tab, may be a string or a list of strings
24
- # @param width [Integer] tab width
25
- # @return [String]
26
- def tab(txt, width=4)
27
- width = 0 if width < 0
28
-
29
- tab = ' ' * width
30
-
31
- return tab + txt if txt.is_a?(String)
32
-
33
- txt.map { |l| tab + l }
34
- end
35
-
36
- # Format results for text output (e.g. in the terminal)
37
- # @param results [Array<Hash>] this must be an array of results, as
38
- # returned by {UD.query}.
39
- # @param color [Boolean] colored output
40
- # @return [String]
41
- def text(results, color=true)
42
- require 'colored' if color
43
-
44
- results.map do |r|
45
-
46
- word = r[:word]
47
- upvotes = r[:upvotes]
48
- downvotes = r[:downvotes]
49
-
50
- if (color)
51
- word = word.bold
52
- upvotes = upvotes.to_s.green
53
- downvotes = downvotes.to_s.red
54
- end
55
-
56
- votes = "#{upvotes}/#{downvotes}"
57
- definition = tab(fit(r[:definition], 75)).join("\n")
58
- example = tab(fit(r[:example], 75)).join("\n")
59
-
60
- <<-EOD
7
+ # Fit a text in a given width (number of chars).
8
+ # @param txt [String]
9
+ # @param width [Integer] maximum width
10
+ # @return [Array] list of lines of text
11
+ def fit(txt, width = 79)
12
+ return [] if width < 1
13
+
14
+ # from http://stackoverflow.com/a/7567210/735926
15
+ r = /(.{1,#{width}})(?:\s|$)/m
16
+ txt.split("\n").map { |l| l.scan(r) }.flatten
17
+ end
18
+
19
+ # Add a tab at the beginning of a text. If it's a list, add a tab at
20
+ # the beginning of each element.
21
+ # @param txt [String] The text to tab, may be a string or a list of
22
+ # strings
23
+ # @param width [Integer] tab width
24
+ # @return [String]
25
+ def tab(txt, width = 4)
26
+ return txt if width <= 0
27
+
28
+ tab = " " * width
29
+
30
+ return tab + txt if txt.is_a? String
31
+
32
+ txt.map { |l| tab + l }
33
+ end
34
+
35
+ # Format results for text output (e.g. in the terminal)
36
+ # @param results [Array<Hash>] this must be an array of results, as
37
+ # returned by {UD.query}.
38
+ # @param color [Boolean] colored output
39
+ # @return [String]
40
+ def text(results, color = true)
41
+ require "colored" if color
42
+
43
+ results.map do |r|
44
+ word = r[:word]
45
+ upvotes = r[:upvotes]
46
+ downvotes = r[:downvotes]
47
+
48
+ if color
49
+ word = word.bold
50
+ upvotes = upvotes.to_s.green
51
+ downvotes = downvotes.to_s.red
52
+ end
53
+
54
+ votes = "#{upvotes}/#{downvotes}"
55
+ definition = tab(fit(r[:definition], 75)).join "\n"
56
+ example = tab(fit(r[:example], 75)).join "\n"
57
+
58
+ <<-EOD
61
59
  * #{word} (#{votes}):
62
60
 
63
61
  #{definition}
@@ -66,11 +64,9 @@ module UD
66
64
  #{example}
67
65
 
68
66
 
69
- EOD
70
-
71
- end.join("\n")
72
- end
73
-
67
+ EOD
68
+ end.join "\n"
69
+ end
74
70
  end
75
71
  end
76
72
  end
@@ -37,12 +37,11 @@ class UD_Query_test < Test::Unit::TestCase
37
37
  # == UD#search_url == #
38
38
 
39
39
  def test_search_url_empty_term
40
- assert_equal("#{API_URL}?term=", UD.search_url())
41
40
  assert_equal("#{API_URL}?term=", UD.search_url(''))
42
41
  end
43
42
 
44
43
  def test_search_url_empty_term_nonapi
45
- assert_equal("#{ROOT_URL}?term=", UD.search_url('', false))
44
+ assert_equal("#{ROOT_URL}?term=", UD.search_url('', :api => false))
46
45
  end
47
46
 
48
47
  def test_search_url_spaces_in_term
@@ -57,6 +56,12 @@ class UD_Query_test < Test::Unit::TestCase
57
56
  assert_equal("#{API_URL}?term=foo", UD.search_url('foo'))
58
57
  end
59
58
 
59
+ # == UD#random_url == #
60
+
61
+ def test_random_url
62
+ assert_equal("http://api.urbandictionary.com/v0/random", UD.random_url)
63
+ end
64
+
60
65
  # == UD#query == #
61
66
 
62
67
  def test_query_no_results
@@ -70,9 +75,5 @@ class UD_Query_test < Test::Unit::TestCase
70
75
  def test_query_count
71
76
  assert_equal([@foo], UD.query('two_results', :count => 1))
72
77
  end
73
-
74
- def test_query_ratio
75
- assert_equal([@foo], UD.query('two_results', :count => 10, :ratio => 1.5))
76
- end
77
78
  end
78
79
 
@@ -1,15 +1,19 @@
1
1
  #! /usr/bin/env ruby
2
2
  # -*- coding: UTF-8 -*-
3
3
 
4
- require 'coveralls'
5
- Coveralls.wear!
4
+ ci = ENV["CI"] || ENV["CONTINUOUS_INTEGRATION"]
5
+
6
+ if ci
7
+ require 'coveralls'
8
+ Coveralls.wear!
9
+ end
6
10
 
7
11
  require 'test/unit'
8
12
  require 'simplecov'
9
13
 
10
14
  test_dir = File.expand_path( File.dirname(__FILE__) )
11
15
 
12
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
16
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter if ci
13
17
  SimpleCov.start { add_filter '/tests/' }
14
18
 
15
19
  require 'ud'
@@ -26,6 +30,26 @@ class UDTests < Test::Unit::TestCase
26
30
  assert(UD.version =~ /^\d+\.\d+\.\d+/)
27
31
  end
28
32
 
33
+ # == UD#open_cmd (private) == #
34
+
35
+ def test_ud_open_cmd
36
+ os = RbConfig::CONFIG["host_os"]
37
+
38
+ RbConfig::CONFIG["host_os"] = "darwin"
39
+ assert_equal "open", UD.send(:open_cmd)
40
+
41
+ RbConfig::CONFIG["host_os"] = "linux"
42
+ assert_equal "xdg-open", UD.send(:open_cmd)
43
+
44
+ RbConfig::CONFIG["host_os"] = "bsd"
45
+ assert_equal "xdg-open", UD.send(:open_cmd)
46
+
47
+ RbConfig::CONFIG["host_os"] = "cygwin"
48
+ assert_equal "start", UD.send(:open_cmd)
49
+
50
+ RbConfig::CONFIG["host_os"] = os
51
+ end
52
+
29
53
  end
30
54
 
31
55
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Baptiste Fontaine
@@ -12,25 +12,25 @@ cert_chain:
12
12
  -----BEGIN CERTIFICATE-----
13
13
  MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MRAwDgYDVQQDDAdiYXRp
14
14
  Zm9uMRUwEwYKCZImiZPyLGQBGRYFeWFob28xEjAQBgoJkiaJk/IsZAEZFgJmcjAe
15
- Fw0xNDA4MjQxMTM5NTJaFw0xNTA4MjQxMTM5NTJaMD0xEDAOBgNVBAMMB2JhdGlm
15
+ Fw0xNTEyMjMwMTExMTZaFw0xNjEyMjIwMTExMTZaMD0xEDAOBgNVBAMMB2JhdGlm
16
16
  b24xFTATBgoJkiaJk/IsZAEZFgV5YWhvbzESMBAGCgmSJomT8ixkARkWAmZyMIIB
17
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn3uOgWl+FwXIjDdCay28i6cK
18
- FxHWhHoS/mH9pkXzSGVctEKP2fulie6MkIvrLCP5M6TpByeaBjcJjZPadrou1FIc
19
- Yc/O14jYjaKTqfMxpzgNfGzDdBgBo0QZ9rcHjORetdIZdUSDaZjPtI1aGS6eBMsh
20
- W2X6GxL4UQ1kH0Lyg7iPYAH5RHnD3+G+S28iOPFfRLFzm4fwJp1k7URiiSyOHTDp
21
- B0ZehKKrW/ibCaRMYp2VoCamcim4de1VA6CTOaYSShueqThE18n1HM6aprihziyM
22
- 04yIpo80/unO6JxlsUFdBjsb5d7oJSqPJ6/OfcFnyXa/VRm+Ed9d6PTwZvL7YwID
23
- AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUWyH3xMx1
24
- 8I5NLncgNEC0ZlDRKegwGwYDVR0RBBQwEoEQYmF0aWZvbkB5YWhvby5mcjAbBgNV
25
- HRIEFDASgRBiYXRpZm9uQHlhaG9vLmZyMA0GCSqGSIb3DQEBBQUAA4IBAQAaTVya
26
- CGgojxBwUoadCCIsFheGsXvSFhikkXYNXy0VxEYr8BaTfGwzYh9c9T5N+Y5Mu5MW
27
- WegqwIwRhIu6Rg7huqJ7TK50pVDF0yrZcsxvWjOfd3clblBHjKGQx5Mbu7LVNGKE
28
- +QNdTAwYVTAA8wXHpxk200cHb9xz4e9ANpb4lonGuPz8jKmb/A7Z1M5QD6zStG8l
29
- sTlVAhA/LZiC9gL9LtW8Iq7o7xRFhxNPKWHu6JVThH9i16eli+JignOJbGna7C40
30
- QnOQb8zHyNL+gq2m/mnZGrSehx+6AujokjOfHbmivYMfDATOQQx0eIBI18IhacZm
31
- 42WxhhIV2bwDtd77
17
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0en8u9i10EQtkp3SUnXnXo0W
18
+ UISZyvp2kS22c2/FXYg566dtfkp3pwBOZi3gvRYAKpmXAwbynOANdm2bfzQiG+Br
19
+ 0966dfY0SIbFuhaueJ8JUm5o/nxxCiKxuvCFs5899SJxyzmD3NNVzjTdrSU6UTgx
20
+ Q7K/r2MRYxBmPBbi8wdxyP1Ko36o9BJdLNrUiAVec1VXOlqA9Iw8CyrlG3V1snNl
21
+ efNVzZ+sMCkR73IyxRRwRgPws2jo2/8LfKcL+J3mz4ekBs4PoyOCWCnPlpBjAwkx
22
+ OzzDCjpxYbn/SYNHC8MxVdgap7jEX75ogkfpGOrAEdiPASnc2nFKqbJNxX7hCQID
23
+ AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU2BKQg2pq
24
+ izVT9CkLdQo+nHNlvpQwGwYDVR0RBBQwEoEQYmF0aWZvbkB5YWhvby5mcjAbBgNV
25
+ HRIEFDASgRBiYXRpZm9uQHlhaG9vLmZyMA0GCSqGSIb3DQEBBQUAA4IBAQBkPKEW
26
+ urPeZb+IHuqWMqpzL/42fU4QuVUYDswLq+V0tXwnHo+okAq00Xh0yr0OaDBvm0mW
27
+ al9ZGC0RzaSQa+9mPd0t39oaWdtY7TOxQX3OC3vxdZ794gqyQgNxOmajFl22NY01
28
+ vxMAeZOu+IC5s2pQyUG0Gsq2sRbquW1mj8OC8KI3WWcECqGFOIOdXYTsqVqhwcN1
29
+ OpgZkC/pnOJanbP2ex2OHjlwFlpQ2PPAhoIG3mU1HEYXBZuP7+DUgNNgpopX83A5
30
+ 0df+9hsqme8UngbwGqM1XgU4dUlXNaoHejAm/d9IrRPvqE2oFsS9ytHShth2bC43
31
+ LPBfw/xSG5R4RjMC
32
32
  -----END CERTIFICATE-----
33
- date: 2015-05-17 00:00:00.000000000 Z
33
+ date: 2016-11-27 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: json
@@ -52,14 +52,14 @@ dependencies:
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '2.0'
55
+ version: '2.1'
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '2.0'
62
+ version: '2.1'
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: colored
65
65
  requirement: !ruby/object:Gem::Requirement
@@ -177,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
177
  version: '0'
178
178
  requirements: []
179
179
  rubyforge_project:
180
- rubygems_version: 2.4.6
180
+ rubygems_version: 2.5.2
181
181
  signing_key:
182
182
  specification_version: 4
183
183
  summary: Urban Dictionary unofficial scrapper
metadata.gz.sig CHANGED
Binary file