slg 0.0.1
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/bin/slg +39 -0
- data/lib/slg.rb +107 -0
- data/tests/query_tests.rb +44 -0
- data/tests/tests.rb +53 -0
- metadata +200 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 138f7e46a189d5f94aec8149144f460938dff2f74e3f86650ac323874be91c3e
|
4
|
+
data.tar.gz: 7b5b412986a25443036a2f8dabef508d2b59242884542f443837a9389c512bda
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b9c3b92bad04d21f66128e0cfdd1cc6001f8a70eb3323c86b2e42dafa95756d7af2ff5e4a109c9ccc70e6876d6d50bd8ca9fd19ad176098bce6152520e35e071
|
7
|
+
data.tar.gz: 8e04ce6ff7b6086edcfc408587a8f451861c2a0055859da63c92f8c53d177946413f52dd2727e2a5ab2ccbdf7525096f4429f32c51544ebf44d0816a5b61fde2
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/bin/slg
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
|
4
|
+
# clean interrupt
|
5
|
+
trap("INT") { abort }
|
6
|
+
|
7
|
+
require "optimist"
|
8
|
+
require "slg"
|
9
|
+
|
10
|
+
opts = Optimist.options do
|
11
|
+
version "slg #{Slg.version}"
|
12
|
+
banner <<-EOS
|
13
|
+
Slg is a command-line tool to scrape definitions from Slengo.it.
|
14
|
+
|
15
|
+
Usage:
|
16
|
+
slg [options] <word(s)>
|
17
|
+
where [options] are:
|
18
|
+
EOS
|
19
|
+
|
20
|
+
opt :count, "Limit the number of definitions", :type => :int, :default => 1, :short => "-n"
|
21
|
+
opt :color, "Use colorized output", :default => true
|
22
|
+
opt :browser, "Open the results in a browser window", :short => "-b"
|
23
|
+
end
|
24
|
+
|
25
|
+
Optimist.die :count, "must be non-negative" if opts[:count] < 0
|
26
|
+
|
27
|
+
if ARGV.empty?
|
28
|
+
puts "Error: No word provided. Use -h or --help to see the help."
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
term = ARGV.join " "
|
33
|
+
|
34
|
+
if opts[:browser]
|
35
|
+
Slg.open_url(term)
|
36
|
+
else
|
37
|
+
q = Slg.query(ARGV.join(" "), opts)
|
38
|
+
puts Slg.format_results(q, opts[:color])
|
39
|
+
end
|
data/lib/slg.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "open-uri"
|
5
|
+
require "nokogiri"
|
6
|
+
|
7
|
+
require "ud/formatting"
|
8
|
+
|
9
|
+
# Most of this code is copy/pasted from UD.
|
10
|
+
# TODO generalize the code in UD and reuse it here.
|
11
|
+
|
12
|
+
# This module provide some methods to scrape definitions from Slengo.it.
|
13
|
+
module Slg
|
14
|
+
class << self
|
15
|
+
# @return [String] the current gem's version
|
16
|
+
def version
|
17
|
+
"0.0.1"
|
18
|
+
end
|
19
|
+
|
20
|
+
WWW_ROOT = "https://slengo.it"
|
21
|
+
|
22
|
+
# Get the search URL to query for a given term.
|
23
|
+
# @param term [String] the term to search for. It must be a string, spaces
|
24
|
+
# are allowed.
|
25
|
+
# @return [String]
|
26
|
+
def search_url(term)
|
27
|
+
param = URI.encode_www_form_component(term).gsub(/\+/, "%20")
|
28
|
+
"#{WWW_ROOT}/define/#{param}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Open the search URL in the user's browser
|
32
|
+
# @param term [String] the term to search for. It must be a string, spaces
|
33
|
+
# are allowed.
|
34
|
+
# @return [Nil]
|
35
|
+
def open_url(term)
|
36
|
+
system open_cmd, search_url(term)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Query the website and return a list of definitions for the provided term.
|
40
|
+
# This list may be empty if there's no result.
|
41
|
+
# @param term [String] the term to search for
|
42
|
+
# @param opts [Hash] options. This is used by the command-line tool.
|
43
|
+
# +:count+ is the maximum number of results to return
|
44
|
+
# @return [Array<Hash>]
|
45
|
+
def query(term, opts = {})
|
46
|
+
url = search_url(term)
|
47
|
+
text = OpenURI.open_uri url
|
48
|
+
|
49
|
+
opts = { :count => 1 }.merge(opts || {})
|
50
|
+
|
51
|
+
return [] if opts[:count] <= 0
|
52
|
+
|
53
|
+
doc = Nokogiri::HTML.parse text
|
54
|
+
|
55
|
+
doc.css("article.definition-card").map do |elt|
|
56
|
+
examples = elt.css(".word-examples li").map(&:text).map(&:strip)
|
57
|
+
example = examples.join "\n\n"
|
58
|
+
|
59
|
+
votes = elt.css(".votes-container .v-progress-linear")
|
60
|
+
# Slengo.it uses percentages instead of number of votes
|
61
|
+
upvotes = votes.attr("aria-valuenow").to_s.to_i
|
62
|
+
downvotes = 100 - upvotes
|
63
|
+
|
64
|
+
header_p = elt.css("header p").first
|
65
|
+
|
66
|
+
definition = elt.css("div.word-definition").text
|
67
|
+
# Remove 'see also'
|
68
|
+
definition.gsub! /\bCfr\..+/m, ""
|
69
|
+
definition.strip!
|
70
|
+
|
71
|
+
{
|
72
|
+
# There's no :id nor :author
|
73
|
+
# For some reason the selector 'h1.word-title' work in JS in the
|
74
|
+
# browser but not with Nokogiri.
|
75
|
+
:word => header_p.text.strip,
|
76
|
+
:permalink => url,
|
77
|
+
:definition => definition,
|
78
|
+
:example => example,
|
79
|
+
:upvotes => upvotes,
|
80
|
+
:downvotes => downvotes,
|
81
|
+
# TODO add region as well
|
82
|
+
}
|
83
|
+
|
84
|
+
end.take opts[:count]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Format results for output
|
88
|
+
# @param results [Array] this must be an array of results, as returned by
|
89
|
+
# +UD.query+.
|
90
|
+
# @param color [Boolean] colored output
|
91
|
+
# @return [String]
|
92
|
+
def format_results(results, color = true)
|
93
|
+
UD::Formatting.text(results, color)
|
94
|
+
end
|
95
|
+
|
96
|
+
def open_cmd
|
97
|
+
case RbConfig::CONFIG["host_os"]
|
98
|
+
when /darwin/
|
99
|
+
"open"
|
100
|
+
when /bsd|linux/
|
101
|
+
"xdg-open"
|
102
|
+
when /cygwin|mingw|mswin/
|
103
|
+
"start"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/fake_responses'
|
5
|
+
|
6
|
+
class Slg_Query_test < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@foo, @bar = [
|
9
|
+
{
|
10
|
+
:definition=>"Foo foo.",
|
11
|
+
:downvotes=>0,
|
12
|
+
:example=> "foo ex 1\n\nfoo ex 2",
|
13
|
+
:permalink=>"https://slengo.it/define/culo",
|
14
|
+
:upvotes=>100,
|
15
|
+
:word=>"foo",
|
16
|
+
},
|
17
|
+
{
|
18
|
+
:definition=>"Bar bar.",
|
19
|
+
:downvotes=>10,
|
20
|
+
:example=>"bar ex",
|
21
|
+
:permalink=>"https://slengo.it/define/culo",
|
22
|
+
:upvotes=>90,
|
23
|
+
:word=>"foo",
|
24
|
+
}
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_search_url
|
29
|
+
assert_equal("https://slengo.it/define/foo", Slg.search_url('foo'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_query_no_results
|
33
|
+
assert_equal([], Slg.query('foooo'))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_query_two_results
|
37
|
+
assert_equal([@foo, @bar], Slg.query('culo', :count => 2))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_query_count
|
41
|
+
assert_equal([@foo], Slg.query('culo', :count => 1))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
data/tests/tests.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
|
4
|
+
ci = ENV["CI"] || ENV["CONTINUOUS_INTEGRATION"]
|
5
|
+
|
6
|
+
if ci
|
7
|
+
require 'coveralls'
|
8
|
+
Coveralls.wear!
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'test/unit'
|
12
|
+
require 'simplecov'
|
13
|
+
|
14
|
+
test_dir = File.expand_path( File.dirname(__FILE__) )
|
15
|
+
|
16
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter if ci
|
17
|
+
SimpleCov.start { add_filter '/tests/' }
|
18
|
+
|
19
|
+
require 'slg'
|
20
|
+
|
21
|
+
for t in Dir.glob( File.join( test_dir, '*_tests.rb' ) )
|
22
|
+
require t
|
23
|
+
end
|
24
|
+
|
25
|
+
class SlgTests < Test::Unit::TestCase
|
26
|
+
|
27
|
+
def test_slg_version
|
28
|
+
assert(Slg.version =~ /^\d+\.\d+\.\d+/)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_slg_open_cmd
|
32
|
+
os = RbConfig::CONFIG["host_os"]
|
33
|
+
|
34
|
+
RbConfig::CONFIG["host_os"] = "darwin"
|
35
|
+
assert_equal "open", Slg.send(:open_cmd)
|
36
|
+
|
37
|
+
RbConfig::CONFIG["host_os"] = "linux"
|
38
|
+
assert_equal "xdg-open", Slg.send(:open_cmd)
|
39
|
+
|
40
|
+
RbConfig::CONFIG["host_os"] = "bsd"
|
41
|
+
assert_equal "xdg-open", Slg.send(:open_cmd)
|
42
|
+
|
43
|
+
RbConfig::CONFIG["host_os"] = "cygwin"
|
44
|
+
assert_equal "start", Slg.send(:open_cmd)
|
45
|
+
|
46
|
+
ensure
|
47
|
+
RbConfig::CONFIG["host_os"] = os
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
exit Test::Unit::AutoRunner.run
|
metadata
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Baptiste Fontaine
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIID/DCCAmSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAkMSIwIAYDVQQDDBliL0RD
|
14
|
+
PXB0aXN0ZWZvbnRhaW5lL0RDPWZyMB4XDTIwMDMwNDE5MDMyMVoXDTIxMDMwNDE5
|
15
|
+
MDMyMVowJDEiMCAGA1UEAwwZYi9EQz1wdGlzdGVmb250YWluZS9EQz1mcjCCAaIw
|
16
|
+
DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKdjTwN/gnJ3WHxKeusaRN1o902Q
|
17
|
+
BmIRgdtbhpsHtgUruKNujutEBpmhG1fka8+mujhqh885blckeC8hXgqpHGK1MsJU
|
18
|
+
tgsNB2F2Nvof/uGBzi+OZ76HPLmfvJFb/KUiwrh08jTbFftMBCmuekbxBajt2N2F
|
19
|
+
shF6DFEqO2hl/itVt5UeIZhpIZvO7qSZ9FtLRXs0q2O27h4QfAv6XobNDwH5TBs5
|
20
|
+
z+EYufgTtupf26xW0v6z2NDG6z36Eap7QAwoivuPCuXO+IPgxhubtGvFYSo7ygP4
|
21
|
+
RbYsaGucRneCCzezTD+i1LnhGt9TCbQjdvidgM+i616JC/HRXglM0apgBZSjayoI
|
22
|
+
XHoajIajnU+570cu01Wsa+SF9m4stKao0hLnCUMeYybmA/Ilk58nJ2xZJWMULu76
|
23
|
+
7Ttzead1Ah25ZdWefKG5FIGkpezEp4z/YihGEJt+hxS7Aa2xYiIlnYFwUno530/8
|
24
|
+
So5Ibqdd3pMKJDUQJvGIBhsQIXF4Iogk4txoPwIDAQABozkwNzAJBgNVHRMEAjAA
|
25
|
+
MAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUsV1eKnEFtVRwyz6/nTuharH3G+UwDQYJ
|
26
|
+
KoZIhvcNAQELBQADggGBAJz7tbRe/iyMthV7fdqnhFv0SZo1UVWZSaIjB39W4lUi
|
27
|
+
7X1Smag2Fe7IqARUPLn2e49ObyupAmTi0zHoSG/+HsBUqNPPoVW1Y67dtrMM49o7
|
28
|
+
qSN66EogB4nvGdvqJ9eOlioiAX7vczWmQjfSONuk0ihOfaTChD7LwoPptTUu/Q6+
|
29
|
+
aT8zz7TH+sxxx+D09Q9+Ywf1RVnUe+i1PTo8kadnHIQdeBPudKrw5GWcIoLz1V16
|
30
|
+
A+j/SNEUqY1ui8TBX6axkd8vh6C1YcVAFCcdrxTMFTeB1irvL8jns6SulRHM08UC
|
31
|
+
9NR+YthP16QuQzb5R2wIGX6WT11cnIpo0LzTnY/QSZGgwJkuLalBLzUssMiVnoSX
|
32
|
+
rVdmQBLrs38YcJouqHpf0wCGygf5430Bq4nCu0xUaH5umPcwJE9qaF1ZfgSCfZEz
|
33
|
+
Qe5fflfwGHtlmT6SWZoQD48xF/ILJ+cLTpF79ardGYnWT6N7VUAI5lKp7OjZYd+q
|
34
|
+
wwYlmlBW0Femxy5WoxzECQ==
|
35
|
+
-----END CERTIFICATE-----
|
36
|
+
date: 2020-03-23 00:00:00.000000000 Z
|
37
|
+
dependencies:
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: optimist
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '3.0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - "~>"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.0'
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: colored
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - "~>"
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.2'
|
59
|
+
type: :runtime
|
60
|
+
prerelease: false
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - "~>"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.2'
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: ud
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - "~>"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0.3'
|
73
|
+
type: :runtime
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0.3'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: nokogiri
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '1.10'
|
87
|
+
type: :runtime
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.10'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: simplecov
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0.18'
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0.18'
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
name: rake
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '12.3'
|
115
|
+
type: :development
|
116
|
+
prerelease: false
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '12.3'
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
name: test-unit
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '3.3'
|
129
|
+
type: :development
|
130
|
+
prerelease: false
|
131
|
+
version_requirements: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '3.3'
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: webmock
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '3.8'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '3.8'
|
150
|
+
- !ruby/object:Gem::Dependency
|
151
|
+
name: coveralls
|
152
|
+
requirement: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - "~>"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0.8'
|
157
|
+
type: :development
|
158
|
+
prerelease: false
|
159
|
+
version_requirements: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0.8'
|
164
|
+
description: Get words' definitions from Slengo on the command-line.
|
165
|
+
email: b@ptistefontaine.fr
|
166
|
+
executables:
|
167
|
+
- slg
|
168
|
+
extensions: []
|
169
|
+
extra_rdoc_files: []
|
170
|
+
files:
|
171
|
+
- bin/slg
|
172
|
+
- lib/slg.rb
|
173
|
+
- tests/query_tests.rb
|
174
|
+
- tests/tests.rb
|
175
|
+
homepage: https://github.com/bfontaine/slg
|
176
|
+
licenses:
|
177
|
+
- MIT
|
178
|
+
metadata: {}
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
require_paths:
|
182
|
+
- lib
|
183
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - ">="
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
193
|
+
requirements: []
|
194
|
+
rubygems_version: 3.1.2
|
195
|
+
signing_key:
|
196
|
+
specification_version: 4
|
197
|
+
summary: Slengo.it unofficial scrapper
|
198
|
+
test_files:
|
199
|
+
- tests/tests.rb
|
200
|
+
- tests/query_tests.rb
|
metadata.gz.sig
ADDED
Binary file
|