zypper-onlinesearch 1.0.0 → 1.1.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
- data/.rubocop.yml +81 -0
- data/Gemfile +12 -2
- data/Gemfile.lock +36 -5
- data/LICENSE +674 -0
- data/README.md +8 -104
- data/Rakefile +7 -1
- data/lib/zypper/onlinesearch/cache.rb +20 -23
- data/lib/zypper/onlinesearch/cli.rb +63 -61
- data/lib/zypper/onlinesearch/data.rb +116 -106
- data/lib/zypper/onlinesearch/release.rb +13 -12
- data/lib/zypper/onlinesearch/request.rb +62 -54
- data/lib/zypper/onlinesearch/utils.rb +64 -26
- data/lib/zypper/onlinesearch/version.rb +3 -1
- data/lib/zypper/onlinesearch/view.rb +188 -155
- data/lib/zypper/onlinesearch.rb +69 -90
- data/zypper-onlinesearch.gemspec +20 -23
- metadata +12 -56
- data/.gitignore +0 -11
- data/.travis.yml +0 -5
- data/bin/console +0 -14
- data/bin/setup +0 -8
@@ -1,9 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
require "uri"
|
3
5
|
|
4
6
|
module Zypper
|
5
7
|
module Onlinesearch
|
6
|
-
|
8
|
+
#
|
9
|
+
# Handles the list of requests.
|
10
|
+
#
|
7
11
|
class RequestList
|
8
12
|
attr_reader :engines, :refresh, :timeout, :query
|
9
13
|
|
@@ -12,35 +16,36 @@ module Zypper
|
|
12
16
|
@refresh = args[:refresh]
|
13
17
|
@timeout = args[:timeout]
|
14
18
|
@query = args[:query]
|
19
|
+
m = Request.const_get(args[:operation].to_s.capitalize)
|
15
20
|
|
16
21
|
if args[:engine] == :all
|
17
|
-
m = Request.const_get(args[:operation].to_s.capitalize)
|
18
22
|
m.constants.each do |k|
|
19
23
|
@engines[k.to_s.downcase] = m.const_get(k).new(args[:query], args[:refresh], args[:timeout])
|
20
24
|
end
|
21
25
|
else
|
22
|
-
m = Request.const_get(args[:operation].to_s.capitalize)
|
23
26
|
klass = args[:engine].to_s.capitalize.to_sym
|
24
27
|
raise InvalidEngine, args[:engine] unless m.constants.include? klass
|
28
|
+
|
25
29
|
@engines[args[:engine].to_s.downcase] = m.const_get(klass).new(args[:query], args[:refresh], args[:timeout])
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
29
|
-
def self.
|
33
|
+
def self.class?(operation, engine)
|
30
34
|
Request.const_get(operation.to_s.capitalize).constants.include?(engine.to_s.capitalize.to_sym)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
34
|
-
|
38
|
+
#
|
39
|
+
# The single page request.
|
40
|
+
#
|
35
41
|
class PageRequest
|
36
|
-
|
37
42
|
attr_reader :page
|
38
43
|
|
39
|
-
USER_AGENT =
|
44
|
+
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"
|
40
45
|
|
41
46
|
def initialize(query, refresh, timeout = 60, cookies = [])
|
42
47
|
@query = query.strip
|
43
|
-
@cache = Cache.new(*
|
48
|
+
@cache = Cache.new(*self.class.to_s.split("::")[-2..].map(&:downcase))
|
44
49
|
@refresh = refresh
|
45
50
|
@cookies = cookies
|
46
51
|
@timeout = timeout
|
@@ -55,7 +60,7 @@ module Zypper
|
|
55
60
|
end
|
56
61
|
|
57
62
|
def redirected_to
|
58
|
-
ping[
|
63
|
+
ping["location"]
|
59
64
|
end
|
60
65
|
|
61
66
|
def not_found?
|
@@ -79,7 +84,7 @@ module Zypper
|
|
79
84
|
end
|
80
85
|
|
81
86
|
def to_data
|
82
|
-
klass = self.class.to_s.split(
|
87
|
+
klass = self.class.to_s.split("::")[-2..]
|
83
88
|
Data.const_get(klass[0].to_sym).const_get(klass[1].to_sym).new(@page.body).data
|
84
89
|
end
|
85
90
|
|
@@ -90,31 +95,32 @@ module Zypper
|
|
90
95
|
private
|
91
96
|
|
92
97
|
def get_request(request_uri = nil, limit = 10)
|
93
|
-
if request_uri
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
+
request_uri = if request_uri
|
99
|
+
request_uri =~ %r{://} ? URI(request_uri).request_uri : request_uri
|
100
|
+
else
|
101
|
+
uri.request_uri
|
102
|
+
end
|
98
103
|
|
99
104
|
request = Net::HTTP::Get.new(request_uri)
|
100
|
-
request[
|
101
|
-
request[
|
105
|
+
request["User-Agent"] = USER_AGENT
|
106
|
+
request["Cookie"] = @cookies.join(";") unless @cookies.empty?
|
102
107
|
|
103
108
|
http = Net::HTTP.new(uri.host, uri.port)
|
104
|
-
http.use_ssl = (uri.scheme ==
|
109
|
+
http.use_ssl = (uri.scheme == "https")
|
105
110
|
http.open_timeout = @timeout
|
106
111
|
|
107
112
|
res = http.request(request)
|
108
113
|
|
109
114
|
if res.is_a? Net::HTTPRedirection
|
110
|
-
raise TooManyRedirections, uri.to_s if limit
|
111
|
-
|
115
|
+
raise TooManyRedirections, uri.to_s if limit.negative?
|
116
|
+
|
117
|
+
res = get_request(res["location"], limit - 1)
|
112
118
|
end
|
113
119
|
|
114
120
|
res
|
115
121
|
end
|
116
122
|
|
117
|
-
def ping(force
|
123
|
+
def ping(force: false)
|
118
124
|
begin
|
119
125
|
@page = @cache.get(@query) unless @refresh
|
120
126
|
if @page.nil? || force
|
@@ -124,23 +130,23 @@ module Zypper
|
|
124
130
|
rescue SocketError
|
125
131
|
raise NoConnection
|
126
132
|
rescue Net::OpenTimeout
|
127
|
-
@page = Net::HTTPRequestTimeOut.new(
|
133
|
+
@page = Net::HTTPRequestTimeOut.new("1.1", "", "")
|
128
134
|
end
|
129
135
|
@page
|
130
136
|
end
|
131
137
|
end
|
132
138
|
|
133
|
-
|
134
139
|
module Request
|
135
|
-
|
136
140
|
module Search
|
137
|
-
|
141
|
+
#
|
142
|
+
# Handles the search on openSUSE.
|
143
|
+
#
|
138
144
|
class Opensuse < PageRequest
|
139
|
-
|
140
|
-
URL = 'https://software.opensuse.org/search'
|
145
|
+
URL = "https://software.opensuse.org/search"
|
141
146
|
|
142
147
|
def initialize(query, cache, timeout, cookies = [])
|
143
|
-
super query, cache, timeout,
|
148
|
+
super query, cache, timeout,
|
149
|
+
cookies << "baseproject=ALL;search_devel=true;search_debug=false;search_lang=false"
|
144
150
|
end
|
145
151
|
|
146
152
|
def uri
|
@@ -150,29 +156,30 @@ module Zypper
|
|
150
156
|
end
|
151
157
|
end
|
152
158
|
|
153
|
-
|
159
|
+
#
|
160
|
+
# Handles the search on Packman.
|
161
|
+
#
|
154
162
|
class Packman < PageRequest
|
155
|
-
|
156
|
-
URL = 'http://packman.links2linux.org/search'
|
163
|
+
URL = "http://packman.links2linux.org/search"
|
157
164
|
|
158
165
|
def uri
|
159
166
|
u = URI(URL)
|
160
|
-
u.query = URI.encode_www_form({q: @query, scope:
|
167
|
+
u.query = URI.encode_www_form({ q: @query, scope: "name" })
|
161
168
|
u
|
162
169
|
end
|
163
170
|
end
|
164
|
-
|
165
171
|
end
|
166
172
|
|
167
|
-
|
168
173
|
module Page
|
169
|
-
|
174
|
+
#
|
175
|
+
# Handle the page on openSUSE.
|
176
|
+
#
|
170
177
|
class Opensuse < PageRequest
|
171
|
-
|
172
|
-
URL = 'https://software.opensuse.org/package/'
|
178
|
+
URL = "https://software.opensuse.org/package/"
|
173
179
|
|
174
180
|
def initialize(query, cache, timeout, cookies = [])
|
175
|
-
super query, cache, timeout,
|
181
|
+
super query, cache, timeout,
|
182
|
+
cookies << "baseproject=ALL;search_devel=true;search_debug=false;search_lang=false"
|
176
183
|
end
|
177
184
|
|
178
185
|
def uri
|
@@ -180,24 +187,24 @@ module Zypper
|
|
180
187
|
end
|
181
188
|
end
|
182
189
|
|
183
|
-
|
190
|
+
#
|
191
|
+
# Handle the page on Packman.
|
192
|
+
#
|
184
193
|
class Packman < PageRequest
|
185
|
-
|
186
|
-
URL = 'http://packman.links2linux.org/package/'
|
194
|
+
URL = "http://packman.links2linux.org/package/"
|
187
195
|
|
188
196
|
def uri
|
189
197
|
URI(URL + URI.encode(@query))
|
190
198
|
end
|
191
|
-
|
192
199
|
end
|
193
200
|
end
|
194
201
|
|
195
|
-
|
196
202
|
module Links
|
197
|
-
|
203
|
+
#
|
204
|
+
# Handles the links on openSUSE
|
205
|
+
#
|
198
206
|
class Opensuse < PageRequest
|
199
|
-
|
200
|
-
URL = 'https://software.opensuse.org/download/package'
|
207
|
+
URL = "https://software.opensuse.org/download/package"
|
201
208
|
|
202
209
|
def initialize(query, refresh, timeout = 60, cookies = [])
|
203
210
|
query = URI(query).query
|
@@ -205,25 +212,26 @@ module Zypper
|
|
205
212
|
end
|
206
213
|
|
207
214
|
def uri
|
208
|
-
URI(@query =~
|
215
|
+
URI(@query =~ %r{://} ? @query : "#{URL}?#{@query}")
|
209
216
|
end
|
210
217
|
end
|
211
218
|
|
219
|
+
#
|
220
|
+
# Handles the links on Packman.
|
221
|
+
#
|
212
222
|
class Packman < PageRequest
|
213
|
-
|
214
|
-
URL = 'http://packman.links2linux.org/package/'
|
223
|
+
URL = "http://packman.links2linux.org/package/"
|
215
224
|
|
216
225
|
def initialize(query, refresh, timeout = 60, cookies = [])
|
217
|
-
query = query.split(
|
226
|
+
query = query.split("/")[-2..].join("/") if query =~ %r{://}
|
218
227
|
super query, refresh, timeout, cookies
|
219
228
|
end
|
220
229
|
|
221
230
|
def uri
|
222
|
-
URI(@query =~
|
231
|
+
URI(@query =~ %r{://} ? @query : "#{URL}#{URI.encode(@query)}")
|
223
232
|
end
|
224
233
|
end
|
225
234
|
end
|
226
|
-
|
227
235
|
end
|
228
236
|
end
|
229
237
|
end
|
@@ -1,6 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zypper
|
4
|
+
#
|
5
|
+
# Collection of util classes.
|
6
|
+
#
|
2
7
|
module Onlinesearch
|
3
|
-
|
8
|
+
#
|
9
|
+
# String class patch.
|
10
|
+
#
|
4
11
|
class ::String
|
5
12
|
def black; "\033[30m#{self}\033[0m" end
|
6
13
|
def red; "\033[31m#{self}\033[0m" end
|
@@ -26,48 +33,63 @@ module Zypper
|
|
26
33
|
def none; self end
|
27
34
|
end
|
28
35
|
|
36
|
+
#
|
37
|
+
# Float class patch.
|
38
|
+
#
|
29
39
|
class ::Float
|
30
40
|
def to_human
|
31
41
|
conv = {
|
32
|
-
1024=>
|
33
|
-
1024*1024=>
|
34
|
-
1024*1024*1024=>
|
35
|
-
1024*1024*1024*1024=>
|
36
|
-
1024*1024*1024*1024*1024=>
|
37
|
-
1024*1024*1024*1024*1024*1024=>
|
38
|
-
1024*1024*1024*1024*1024*1024*1024=>
|
42
|
+
1024 => "B",
|
43
|
+
1024 * 1024 => "KB",
|
44
|
+
1024 * 1024 * 1024 => "MB",
|
45
|
+
1024 * 1024 * 1024 * 1024 => "GB",
|
46
|
+
1024 * 1024 * 1024 * 1024 * 1024 => "TB",
|
47
|
+
1024 * 1024 * 1024 * 1024 * 1024 * 1024 => "PB",
|
48
|
+
1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 => "EB"
|
39
49
|
}
|
40
|
-
conv.keys.sort.each
|
50
|
+
conv.keys.sort.each do |mult|
|
41
51
|
next if self >= mult
|
42
|
-
|
43
|
-
|
44
|
-
|
52
|
+
|
53
|
+
suffix = conv[mult]
|
54
|
+
return format("%<fnum>.2f %<suffix>s", fnum: self / (mult / 1024), suffix: suffix)
|
55
|
+
end
|
45
56
|
end
|
46
57
|
end
|
47
58
|
|
59
|
+
#
|
60
|
+
# Array class patch.
|
61
|
+
#
|
48
62
|
class ::Array
|
49
63
|
def max_column(field)
|
50
|
-
|
64
|
+
max_by { |x| x[field].to_s.length }[field].to_s.length
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
68
|
+
#
|
69
|
+
# Default error code.
|
70
|
+
#
|
54
71
|
class ::StandardError
|
55
72
|
def error_code
|
56
73
|
1
|
57
74
|
end
|
58
75
|
end
|
59
76
|
|
77
|
+
#
|
78
|
+
# Color the error message.
|
79
|
+
#
|
60
80
|
class Messages
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
puts ' [E] '.bold.red + e
|
81
|
+
def self.error(err)
|
82
|
+
if err.instance_of? String
|
83
|
+
puts " #{"[E]".bold.red} #{err}"
|
65
84
|
else
|
66
|
-
|
85
|
+
warn "Error! ".bold.red + err.message
|
67
86
|
end
|
68
87
|
end
|
69
88
|
end
|
70
89
|
|
90
|
+
#
|
91
|
+
# Too short query string.
|
92
|
+
#
|
71
93
|
class QueryStringTooShort < StandardError
|
72
94
|
def initialize(query)
|
73
95
|
super "The query string '#{query}' is too short, be sure to use more than 3 characters."
|
@@ -78,12 +100,18 @@ module Zypper
|
|
78
100
|
end
|
79
101
|
end
|
80
102
|
|
103
|
+
#
|
104
|
+
# Too many redirections.
|
105
|
+
#
|
81
106
|
class TooManyRedirections < StandardError
|
82
107
|
def initialize(url)
|
83
108
|
super "#{url} generates too many redirections!"
|
84
109
|
end
|
85
110
|
end
|
86
111
|
|
112
|
+
#
|
113
|
+
# Invalid engine request.
|
114
|
+
#
|
87
115
|
class InvalidEngine < StandardError
|
88
116
|
def initialize(engine)
|
89
117
|
super "#{engine} is not a valid engine!"
|
@@ -94,21 +122,30 @@ module Zypper
|
|
94
122
|
end
|
95
123
|
end
|
96
124
|
|
125
|
+
#
|
126
|
+
# No item number provided.
|
127
|
+
#
|
97
128
|
class MissingItemNumber < StandardError
|
98
129
|
def initialize
|
99
|
-
super
|
130
|
+
super "No item number has been provided!"
|
100
131
|
end
|
101
132
|
end
|
102
133
|
|
134
|
+
#
|
135
|
+
# Empty cache folder.
|
136
|
+
#
|
103
137
|
class EmptyCache < StandardError
|
104
138
|
def initialize
|
105
|
-
super
|
139
|
+
super "The cache folder is already empty!"
|
106
140
|
end
|
107
141
|
end
|
108
142
|
|
143
|
+
#
|
144
|
+
# No internet connection.
|
145
|
+
#
|
109
146
|
class NoConnection < StandardError
|
110
147
|
def initialize
|
111
|
-
super
|
148
|
+
super "Internet connection has some trouble"
|
112
149
|
end
|
113
150
|
|
114
151
|
def error_code
|
@@ -116,15 +153,16 @@ module Zypper
|
|
116
153
|
end
|
117
154
|
end
|
118
155
|
|
156
|
+
#
|
157
|
+
# Ctrl + C message error.
|
158
|
+
#
|
119
159
|
class Interruption < StandardError
|
120
160
|
def initialize
|
121
|
-
super
|
161
|
+
super "Ok ok... Exiting!"
|
122
162
|
end
|
123
163
|
end
|
124
164
|
|
125
|
-
Signal.trap(
|
126
|
-
|
127
|
-
Signal.trap('TERM') { raise Interruption }
|
128
|
-
|
165
|
+
Signal.trap("INT") { raise Interruption }
|
166
|
+
Signal.trap("TERM") { raise Interruption }
|
129
167
|
end
|
130
168
|
end
|