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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/bin/ud +13 -19
- data/lib/ud.rb +46 -24
- data/lib/ud/formatting.rb +55 -59
- data/tests/query_tests.rb +7 -6
- data/tests/tests.rb +27 -3
- metadata +21 -21
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be08bba53ec9677e2382c7221afbdbe86daeeb2b
|
4
|
+
data.tar.gz: 2127476c4b657755e04cd5393a4bc58c852a6840
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab2a0d140114d914a7a066219ad5e3fd2a93c8f20bb8be031900a779db2d4a5ba244f330b1d85e14a95134e7cc2213c1a8973e34f4a21f28d4dacb4234199452
|
7
|
+
data.tar.gz: f421052deba0e6a06f163450d1d5871c85cc68a33dabdc4234ea855dbbb006571114d336621251e2b378a9329127ebfc6cd4eba636650b7146cca418a6a16b10
|
checksums.yaml.gz.sig
CHANGED
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(
|
5
|
+
trap("INT") { abort }
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
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 :
|
21
|
-
opt :
|
22
|
-
opt :color,
|
23
|
-
opt :browser,
|
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 :
|
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
|
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(
|
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
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "uri"
|
4
|
+
require "json"
|
5
|
+
require "open-uri"
|
6
6
|
|
7
|
-
require File.dirname(__FILE__) +
|
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
|
-
|
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
|
21
|
+
# @param opts [Hash] options.
|
23
22
|
# @return [String]
|
24
|
-
def search_url(term
|
25
|
-
param = URI.encode_www_form(
|
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,
|
62
|
+
def query(term, opts = {})
|
63
|
+
parse_response(open(search_url(term)).read, opts)
|
64
|
+
end
|
51
65
|
|
52
|
-
|
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(
|
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
|
70
|
-
|
71
|
-
|
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
|
|
data/lib/ud/formatting.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
67
|
+
EOD
|
68
|
+
end.join "\n"
|
69
|
+
end
|
74
70
|
end
|
75
71
|
end
|
76
72
|
end
|
data/tests/query_tests.rb
CHANGED
@@ -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
|
|
data/tests/tests.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# -*- coding: UTF-8 -*-
|
3
3
|
|
4
|
-
|
5
|
-
|
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.
|
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
|
-
|
15
|
+
Fw0xNTEyMjMwMTExMTZaFw0xNjEyMjIwMTExMTZaMD0xEDAOBgNVBAMMB2JhdGlm
|
16
16
|
b24xFTATBgoJkiaJk/IsZAEZFgV5YWhvbzESMBAGCgmSJomT8ixkARkWAmZyMIIB
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
+
|
29
|
-
|
30
|
-
|
31
|
-
|
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:
|
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.
|
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.
|
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.
|
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
|