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