slg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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