gnomikologikon-fortune 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +19 -19
- data/gnomikologikon-fortune.gemspec +2 -2
- data/lib/gnomika.rb +0 -0
- data/lib/gnomikologikon/ui.rb +45 -29
- data/lib/gnomikologikon/version.rb +1 -1
- data/lib/gnomikologikon/web_processing.rb +27 -20
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dab21852657c1964bbcc1dedfa7f332bc75fdfa3724050eed63f3c39931bb415
|
4
|
+
data.tar.gz: c4456a60d52755901461ec4e1415da71969dbdd35404520dfbf263d50ca08501
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38873acd2a993c18de756e44e40a542d7a9c96fd6fcbf342976ec00c40a15eb5a4eed7f841b84be78a8d06d2da9b54370992b5606f6ffed2e987f2be75246c8e
|
7
|
+
data.tar.gz: 2653fcd2086ea4d99bb931c4d2ceb3648b8bdda26db0d4c528893b8f61b5c32f7fad0a84325ec25221d2b922fb386d1f5e5d896c489e12a2ab75d56f9c62c8f0
|
data/Gemfile.lock
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gnomikologikon-fortune (1.0.
|
4
|
+
gnomikologikon-fortune (1.0.3.pre.dev)
|
5
5
|
httparty
|
6
|
-
nokogiri (~> 1.
|
6
|
+
nokogiri (~> 1.12.5)
|
7
7
|
ruby-progressbar
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
ast (2.4.
|
13
|
-
httparty (0.
|
12
|
+
ast (2.4.2)
|
13
|
+
httparty (0.20.0)
|
14
14
|
mime-types (~> 3.0)
|
15
15
|
multi_xml (>= 0.5.2)
|
16
16
|
mime-types (3.3.1)
|
17
17
|
mime-types-data (~> 3.2015)
|
18
|
-
mime-types-data (3.
|
19
|
-
minitest (5.14.
|
18
|
+
mime-types-data (3.2021.0901)
|
19
|
+
minitest (5.14.4)
|
20
20
|
multi_xml (0.6.0)
|
21
|
-
nokogiri (1.
|
21
|
+
nokogiri (1.12.5-x86_64-linux)
|
22
22
|
racc (~> 1.4)
|
23
|
-
parallel (1.
|
24
|
-
parser (3.0.
|
23
|
+
parallel (1.21.0)
|
24
|
+
parser (3.0.2.0)
|
25
25
|
ast (~> 2.4.1)
|
26
26
|
racc (1.5.2)
|
27
27
|
rainbow (3.0.0)
|
28
|
-
rake (13.0.
|
29
|
-
rdoc (6.3.
|
30
|
-
regexp_parser (2.
|
31
|
-
rexml (3.2.
|
32
|
-
rubocop (1.
|
28
|
+
rake (13.0.6)
|
29
|
+
rdoc (6.3.2)
|
30
|
+
regexp_parser (2.1.1)
|
31
|
+
rexml (3.2.5)
|
32
|
+
rubocop (1.22.0)
|
33
33
|
parallel (~> 1.10)
|
34
34
|
parser (>= 3.0.0.0)
|
35
35
|
rainbow (>= 2.2.2, < 4.0)
|
36
36
|
regexp_parser (>= 1.8, < 3.0)
|
37
37
|
rexml
|
38
|
-
rubocop-ast (>= 1.
|
38
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
39
39
|
ruby-progressbar (~> 1.7)
|
40
40
|
unicode-display_width (>= 1.4.0, < 3.0)
|
41
|
-
rubocop-ast (1.
|
42
|
-
parser (>=
|
41
|
+
rubocop-ast (1.12.0)
|
42
|
+
parser (>= 3.0.1.1)
|
43
43
|
ruby-progressbar (1.11.0)
|
44
|
-
unicode-display_width (2.
|
44
|
+
unicode-display_width (2.1.0)
|
45
45
|
|
46
46
|
PLATFORMS
|
47
47
|
x86_64-linux
|
@@ -54,4 +54,4 @@ DEPENDENCIES
|
|
54
54
|
rubocop (~> 1.7)
|
55
55
|
|
56
56
|
BUNDLED WITH
|
57
|
-
2.2.
|
57
|
+
2.2.27
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.description = "This is a ruby application that downloads quotes from https://gnomikologikon.gr and
|
14
14
|
automatically converts them to files that can be used with the fortune command."
|
15
15
|
spec.homepage = "https://github.com/teogramm/gnomikologikon-fortune"
|
16
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
17
17
|
|
18
18
|
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
19
19
|
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = `git ls-files -- exe/*`.split("\n").map { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
-
spec.add_dependency "nokogiri", "~>1.
|
30
|
+
spec.add_dependency "nokogiri", "~>1.12.5"
|
31
31
|
spec.add_dependency "httparty"
|
32
32
|
spec.add_dependency "ruby-progressbar"
|
33
33
|
|
data/lib/gnomika.rb
CHANGED
File without changes
|
data/lib/gnomikologikon/ui.rb
CHANGED
@@ -71,41 +71,57 @@ module Gnomika
|
|
71
71
|
private
|
72
72
|
|
73
73
|
##
|
74
|
-
# Converts given selection into an array of
|
74
|
+
# Converts given selection into an array of integers.
|
75
75
|
# Throws an ArgumentError if the selection is invalid. An error message is included in the exception.
|
76
76
|
# This function must be used with a single selection (e.g 3 or 3-5), not with a list of many selections (e.g 1,2,3...)
|
77
|
-
# @param
|
78
|
-
# @param max_available_index
|
79
|
-
# @return Array
|
80
|
-
def self.selection_to_array(
|
77
|
+
# @param selection_string String of the selection
|
78
|
+
# @param max_available_index Maximum allowed value
|
79
|
+
# @return Array with the selected items
|
80
|
+
def self.selection_to_array(selection_string, max_available_index)
|
81
|
+
selection = []
|
81
82
|
# Check if selection is a range
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# to max_available index
|
90
|
-
if range_start > range_end || range_end > max_available_index || range_start < 1
|
91
|
-
raise ArgumentError
|
92
|
-
end
|
93
|
-
return (range_start..range_end).to_a
|
94
|
-
rescue ArgumentError
|
95
|
-
raise ArgumentError.new "Invalid range! (#{selection.strip})"
|
96
|
-
end
|
97
|
-
else
|
98
|
-
# Assume selection is an integer
|
99
|
-
begin
|
100
|
-
number = Integer(selection)
|
83
|
+
begin
|
84
|
+
if selection_string.include?("-")
|
85
|
+
# Try to process it as a range
|
86
|
+
selection = process_range(selection_string,max_available_index)
|
87
|
+
else
|
88
|
+
# Assume selection is an integer
|
89
|
+
number = Integer(selection_string)
|
101
90
|
# Check limits
|
102
91
|
if number < 1 || number > max_available_index
|
103
|
-
raise ArgumentError
|
92
|
+
raise ArgumentError.new "Invalid selection! (#{selection_string.strip})"
|
104
93
|
end
|
105
|
-
|
106
|
-
rescue
|
107
|
-
raise ArgumentError.new "Invalid selection! (#{selection.strip})"
|
94
|
+
selection = [number]
|
108
95
|
end
|
96
|
+
rescue ArgumentError => e
|
97
|
+
raise e
|
98
|
+
end
|
99
|
+
selection
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Tries to convert given string to a range of integers. Input string must be of the form a-b
|
104
|
+
# @param upper_limit Maximum allowed value
|
105
|
+
# @return Array of integers in the range
|
106
|
+
# @raise ArgumentError if given selection string is not a valid range
|
107
|
+
def self.process_range(selection_string, upper_limit)
|
108
|
+
range_start, range_end = selection_string.split("-")
|
109
|
+
range_start = Integer(range_start)
|
110
|
+
range_end = Integer(range_end)
|
111
|
+
# Check if range is correct. Start must be smaller or equal than end and end must be smaller or equal
|
112
|
+
# to upper_limit
|
113
|
+
unless is_valid_range?(range_start,range_end,upper_limit)
|
114
|
+
raise ArgumentError.new "Invalid range! (#{selection_string.strip})"
|
109
115
|
end
|
116
|
+
(range_start..range_end).to_a
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Checks if a range with the given parameters is valid. A range is valid if:
|
121
|
+
# 1. start <= end
|
122
|
+
# 2. end <= upper_limit
|
123
|
+
# 3. start > 0
|
124
|
+
def self.is_valid_range?(range_start,range_end,upper_limit)
|
125
|
+
not (range_start > range_end || range_end > upper_limit || range_start < 1)
|
110
126
|
end
|
111
|
-
end
|
127
|
+
end
|
@@ -18,9 +18,7 @@ module Gnomika
|
|
18
18
|
doc = Nokogiri::HTML.parse(response.body)
|
19
19
|
# Each "big" category is stored in a table with class "authrst"
|
20
20
|
category_tables = doc.xpath("//table[@class='authrst']")
|
21
|
-
|
22
21
|
categories = []
|
23
|
-
|
24
22
|
category_tables.each do |table|
|
25
23
|
# Get category name. Category names are stored in td elements with class "authrsh"
|
26
24
|
category_name = table.xpath("tr/td[@class='authrsh']").text
|
@@ -69,24 +67,7 @@ module Gnomika
|
|
69
67
|
quotes_tables = doc.xpath("//table[@class='quotes']//td[@class='quote']")
|
70
68
|
quotes = []
|
71
69
|
quotes_tables.each do |quote|
|
72
|
-
|
73
|
-
content = quote.at_xpath("./text()").text
|
74
|
-
# Check if there is an explanation
|
75
|
-
explanation = quote.xpath("./table[@class='expth']//td")
|
76
|
-
unless explanation.empty?
|
77
|
-
# If an explanation exists, there are two td elements
|
78
|
-
# Remove pavla
|
79
|
-
explanation = explanation.reject{|element| element["class"] == "pavla"}
|
80
|
-
# Keep the explanation td element
|
81
|
-
explanation = explanation[0]
|
82
|
-
content << "\n(#{explanation.text})"
|
83
|
-
end
|
84
|
-
# Check if there is a comment
|
85
|
-
comment = quote.xpath("./p[contains(@class, 'comnt')]")
|
86
|
-
unless comment.nil?
|
87
|
-
# Do not add comment if it does not contain text
|
88
|
-
content << "\n#{comment.text}" unless comment.text.empty?
|
89
|
-
end
|
70
|
+
content = get_quote_contents(quote)
|
90
71
|
# HTML p elements with class auth0-auth4 contain quote author and additional information (e.g. book)
|
91
72
|
# Get the text of all auth p elements and combine them in a string
|
92
73
|
author = quote.xpath(".//p[contains(@class, 'auth')]")
|
@@ -95,4 +76,30 @@ module Gnomika
|
|
95
76
|
end
|
96
77
|
quotes
|
97
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
##
|
83
|
+
# Gets and formats the contents of a quote from the given HTML code.
|
84
|
+
# @param html_quote Nokogiri HTML Node. The node should be a td element with class "quote"
|
85
|
+
def self.get_quote_contents(html_quote)
|
86
|
+
# Get quote contents
|
87
|
+
content = html_quote.at_xpath("./text()").text
|
88
|
+
# Check if there is an explanation
|
89
|
+
# If there is one explanation will be an empty array
|
90
|
+
explanation = html_quote.xpath("./table[@class='expth']//td")
|
91
|
+
unless explanation.empty?
|
92
|
+
# If an explanation exists, there are two td elements
|
93
|
+
# Remove pavla
|
94
|
+
explanation = explanation.reject{|element| element["class"] == "pavla"}
|
95
|
+
# Keep the explanation td element
|
96
|
+
explanation = explanation[0]
|
97
|
+
content << "\n(#{explanation.text})"
|
98
|
+
end
|
99
|
+
# Check if there is a comment
|
100
|
+
comment = html_quote.xpath("./p[contains(@class, 'comnt')]")
|
101
|
+
# Do not add comment if it does not contain text
|
102
|
+
content << "\n#{comment.text}" unless comment&.text.empty?
|
103
|
+
content
|
104
|
+
end
|
98
105
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gnomikologikon-fortune
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theodoros Grammenos
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.12.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.12.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: httparty
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,14 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
152
|
requirements:
|
153
153
|
- - ">="
|
154
154
|
- !ruby/object:Gem::Version
|
155
|
-
version: 2.
|
155
|
+
version: 2.5.0
|
156
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
158
|
- - ">="
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '0'
|
161
161
|
requirements: []
|
162
|
-
rubygems_version: 3.1.
|
162
|
+
rubygems_version: 3.1.6
|
163
163
|
signing_key:
|
164
164
|
specification_version: 4
|
165
165
|
summary: A tool to generate cookies for the fortune command from https://gnomikologikon.gr
|