ud 0.2.5 → 0.3.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: 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