factorio-mod 0.2.2 → 0.3.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/.gitlab-ci.yml +2 -2
- data/.yardopts +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +3 -3
- data/lib/factorio/mod.rb +1 -0
- data/lib/factorio/mod/cache.rb +25 -20
- data/lib/factorio/mod/download.rb +20 -0
- data/lib/factorio/mod/exception.rb +3 -3
- data/lib/factorio/mod/mod.rb +50 -40
- data/lib/factorio/mod/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adcb31d23a6438f33528e0690b06f8134759979b6d4fc7fbce2f9fb25f3cbc13
|
4
|
+
data.tar.gz: 07df7cc9b6882fe8248f123b9f88896041099c6cc2d55964473a8d5aebf71b44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8039d46e1b26cc7241af59ad447ed76b10e9975e72875da517d1d24342dbebf9c866af9a9aaa287393892b1cc62b3a9b6b97531be2620934d97f7ac611482632
|
7
|
+
data.tar.gz: a3860020ad29e8e513c02b30a1e77ce6829ffab221f35a7d142c0ded64bc15001fa252ee4ac9c8a7a0326d1992447ba2c2f67fb703661bf65542e3fea5b4640d
|
data/.gitlab-ci.yml
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -21,13 +21,13 @@ Or install it yourself as:
|
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
24
|
-
See `spec` directory
|
24
|
+
See `spec` directory or https://www.rubydoc.info/gems/factorio-mod
|
25
25
|
|
26
26
|
## Development
|
27
27
|
|
28
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
28
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
29
29
|
|
30
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version by `rake bump`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
30
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version by `bundle exec rake bump`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
31
31
|
|
32
32
|
## Contributing
|
33
33
|
|
data/lib/factorio/mod.rb
CHANGED
data/lib/factorio/mod/cache.rb
CHANGED
@@ -1,43 +1,48 @@
|
|
1
1
|
module Factorio
|
2
|
-
#
|
2
|
+
# Cache mod info
|
3
3
|
class Cache
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :cache
|
5
5
|
|
6
|
+
# @param uri [String] Mod URI like `https://mods.factorio.com/mod/LTN-easier`
|
6
7
|
def initialize(uri, cookie = '')
|
7
8
|
@uri = uri
|
8
9
|
@cookie = cookie
|
9
|
-
@
|
10
|
-
@gotten.default = false
|
10
|
+
@cache = {}
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
# Get the `Information` page.
|
14
|
+
# @return [Nokogiri::HTML]
|
15
|
+
def information
|
16
|
+
get :information, @uri
|
15
17
|
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
# Get the `Downloads` page.
|
20
|
+
# @return [Nokogiri::HTML]
|
21
|
+
def downloads
|
22
|
+
get :downloads, "#{@uri}/downloads"
|
19
23
|
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
# Get any page that already downloads.
|
26
|
+
# Get _better_(default information) mod page if none of the pages exist.
|
27
|
+
# @param better [Symbol] get which page if none of the pages exist.
|
28
|
+
# @return [Nokogiri::HTML]
|
29
|
+
def any(better = :information)
|
30
|
+
if @cache.key? :information
|
31
|
+
information
|
32
|
+
elsif @cache.key? :downloads
|
33
|
+
downloads
|
26
34
|
else
|
27
|
-
send
|
35
|
+
send better
|
28
36
|
end
|
29
37
|
end
|
30
38
|
|
31
39
|
private
|
32
40
|
|
41
|
+
# Get from cache or download page
|
33
42
|
def get(symbol, uri)
|
34
43
|
symbol = symbol.to_sym
|
35
|
-
return
|
36
|
-
|
37
|
-
URI.open(uri, 'Cookie' => @cookie)
|
38
|
-
)
|
39
|
-
@gotten[symbol] = true
|
40
|
-
instance_variable_get "@#{symbol}"
|
44
|
+
return @cache[symbol] if @cache.key? symbol
|
45
|
+
@cache[symbol] = Nokogiri::HTML(URI.open(uri, 'Cookie' => @cookie))
|
41
46
|
rescue OpenURI::HTTPError => e
|
42
47
|
raise NoMODError.new @name, e.io
|
43
48
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Factorio
|
2
|
+
class Mod
|
3
|
+
# store the entry of the _download_
|
4
|
+
Download = Struct.new(:version, :game_version, :uri, :date, :times) do
|
5
|
+
# `Download` page table header to attribute symbol
|
6
|
+
TABLE_HEADER_TO_SYM = {
|
7
|
+
'Version' => :version,
|
8
|
+
'Game Version' => :game_version,
|
9
|
+
'Download' => :uri,
|
10
|
+
'Release Date' => :date,
|
11
|
+
'Downloads' => :times
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# set value by String name
|
15
|
+
def set(name, value)
|
16
|
+
self[TABLE_HEADER_TO_SYM[name]] = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Factorio
|
2
|
-
# The Exception
|
2
|
+
# The Exception that can't find MOD
|
3
3
|
class NoMODError < StandardError
|
4
4
|
attr_reader :io
|
5
5
|
def initialize(msg, io)
|
@@ -8,14 +8,14 @@ module Factorio
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
# The Exception
|
11
|
+
# The Exception that not logged in
|
12
12
|
class NotLoginError < StandardError
|
13
13
|
def initialize(msg = 'Not logged in')
|
14
14
|
super
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
# The Exception
|
18
|
+
# The Exception that can't find download
|
19
19
|
class NoDownloadError < StandardError
|
20
20
|
def initialize(msg)
|
21
21
|
super
|
data/lib/factorio/mod/mod.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
module Factorio
|
2
|
-
#
|
2
|
+
# Info interface
|
3
|
+
#
|
4
|
+
# example:
|
5
|
+
#
|
6
|
+
# ```
|
7
|
+
# mod = Factorio::Mod.new 'LTN-easier'
|
8
|
+
# puts "The author of #{mod.title} is #{mod.author}"
|
9
|
+
# puts "The #{mod.title} is under #{mod.license}"
|
10
|
+
# puts "It latest version can download at #{mod.latest_download[:uri]}"
|
11
|
+
# puts "It latest version for factorio 0.16 can download at " \
|
12
|
+
# "#{mod.latest_download('0.16')[:uri]}"
|
13
|
+
# ```
|
3
14
|
class Mod
|
15
|
+
# factorio Mod portal website URI
|
4
16
|
MOD_URI = 'https://mods.factorio.com'.freeze
|
5
17
|
|
6
|
-
TABLE_HEAD_TO_GOOD_NAME = {
|
7
|
-
'Version' => :version,
|
8
|
-
'Game Version' => :game_version,
|
9
|
-
'Release Date' => :date,
|
10
|
-
'Downloads' => :download_times
|
11
|
-
}.freeze
|
12
|
-
private_constant :TABLE_HEAD_TO_GOOD_NAME
|
13
|
-
|
14
|
-
# Get the mod name
|
15
18
|
attr_reader :name
|
16
19
|
alias id name
|
17
20
|
alias string_id name
|
18
21
|
|
19
|
-
# @param name [String] name of
|
22
|
+
# @param name [String] name of the Mod
|
20
23
|
# @param cookie [String] logged in cookie
|
21
24
|
def initialize(name, cookie = '')
|
22
25
|
@name = name
|
@@ -25,14 +28,15 @@ module Factorio
|
|
25
28
|
|
26
29
|
private
|
27
30
|
|
31
|
+
# Get the meta table from Information page.
|
28
32
|
def data_table(key = '')
|
29
|
-
table = @mod.
|
33
|
+
table = @mod.information.xpath("//div[@class='mod-page-data-table']")
|
30
34
|
return table if key == ''
|
31
35
|
xpath = "//td[../td[@class='data-name'][.='#{key}:']]"
|
32
36
|
table.xpath xpath
|
33
37
|
end
|
34
38
|
|
35
|
-
# @return [String, String] csrf_token and cookie
|
39
|
+
# @return [String, String] `csrf_token` and cookie
|
36
40
|
def self.csrf_and_cookie
|
37
41
|
resp = open 'https://mods.factorio.com/login'
|
38
42
|
cookie = resp.meta['set-cookie'].split('; ')[0]
|
@@ -44,25 +48,31 @@ module Factorio
|
|
44
48
|
public
|
45
49
|
|
46
50
|
# rubocop:disable MethodLength
|
47
|
-
|
48
|
-
|
51
|
+
|
52
|
+
# Map each value with table header.
|
53
|
+
# @param table_header [Array] table header in order
|
54
|
+
# @param line [Nokogiri::HTML] `<tr>`
|
55
|
+
# @return [Hash] table with the table header as key
|
56
|
+
def self.bind_td_to_th(table_header, line)
|
57
|
+
line.css('td').each_with_index.each_with_object(Download.new) \
|
49
58
|
do |(item, index), obj|
|
50
|
-
key =
|
59
|
+
key = table_header[index]
|
51
60
|
if key == 'Download'
|
52
61
|
href = item.xpath('a/@href').to_s
|
53
62
|
raise NotLoginError if href =~ %r{^/login}
|
54
|
-
obj
|
63
|
+
obj.uri = MOD_URI + href
|
55
64
|
else
|
56
|
-
obj
|
65
|
+
obj.set(key, item.text)
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|
69
|
+
|
60
70
|
# rubocop:enable MethodLength
|
61
71
|
|
62
|
-
# Get logged in cookie
|
72
|
+
# Get the logged in cookie.
|
63
73
|
# @param username [String]
|
64
74
|
# @param password [String]
|
65
|
-
# @return [String] cookie
|
75
|
+
# @return [String] The logged in cookie
|
66
76
|
def self.login_cookie(username, password)
|
67
77
|
csrf_token, cookie = csrf_and_cookie
|
68
78
|
data = URI.encode_www_form(
|
@@ -74,74 +84,74 @@ module Factorio
|
|
74
84
|
resp.response['set-cookie'].split('; ')[0]
|
75
85
|
end
|
76
86
|
|
77
|
-
# Get the title (
|
78
|
-
# @return [String]
|
87
|
+
# Get the title (also known as _display name_) of the Mod
|
88
|
+
# @return [String] title
|
79
89
|
def title
|
80
90
|
@mod.any.css('.mod-card-title *').text
|
81
91
|
end
|
82
92
|
alias display_name title
|
83
93
|
|
84
|
-
# Get the summary of
|
85
|
-
# @return [String]
|
94
|
+
# Get the summary of the Mod
|
95
|
+
# @return [String] summary
|
86
96
|
def summary
|
87
97
|
@mod.any.css('.mod-card-summary').text
|
88
98
|
end
|
89
99
|
|
90
|
-
# Get
|
91
|
-
# @return [String]
|
100
|
+
# Get the GitHub URI.
|
101
|
+
# @return [String] GitHub URI
|
92
102
|
def github
|
93
103
|
uri = data_table('Source').xpath('a/@href').to_s
|
94
104
|
return if uri.empty?
|
95
105
|
uri
|
96
106
|
end
|
97
107
|
|
98
|
-
# Get git repo
|
99
|
-
# @return [String] git
|
108
|
+
# Get the git repo URI that can be cloned.
|
109
|
+
# @return [String] git URI
|
100
110
|
def git
|
101
111
|
return if github.nil?
|
102
112
|
github + '.git'
|
103
113
|
end
|
104
114
|
|
105
|
-
# Get license
|
115
|
+
# Get the license that the Mod use.
|
106
116
|
# @return [String] license name
|
107
117
|
def license
|
108
118
|
data_table('License').xpath('a').text
|
109
119
|
end
|
110
120
|
|
111
|
-
# Get license
|
112
|
-
# @return [String] license
|
121
|
+
# Get the license URI.
|
122
|
+
# @return [String] license URI
|
113
123
|
def license_uri
|
114
124
|
data_table('License').xpath('a/@href').to_s
|
115
125
|
end
|
116
126
|
|
117
|
-
# Get author
|
127
|
+
# Get the author of the Mod.
|
118
128
|
# @return [String] author
|
119
129
|
def author
|
120
130
|
data_table('Owner').xpath('a').text
|
121
131
|
end
|
122
132
|
|
123
|
-
# Get
|
124
|
-
# @return [Integer]
|
133
|
+
# Get the totle number of downloads of Mod.
|
134
|
+
# @return [Integer] number of downloads
|
125
135
|
def download_times
|
126
136
|
xpath = "//span[@class='mod-card-info-tag'][@title='Downloads']/div"
|
127
137
|
@mod.any.xpath(xpath).text.to_i
|
128
138
|
end
|
129
139
|
|
130
|
-
#
|
140
|
+
# Get the latest _download_ of the Mod.
|
131
141
|
# @param version [String] factorio version
|
132
|
-
# @return [
|
142
|
+
# @return [Download]
|
133
143
|
def latest_download(version = '')
|
134
144
|
return download_list.last if version == ''
|
135
145
|
download_list.each do |download|
|
136
|
-
return download if download
|
146
|
+
return download if download.game_version == version.to_s
|
137
147
|
end
|
138
148
|
raise NoDownloadError, "Can't found #{name} for factorio #{version}"
|
139
149
|
end
|
140
150
|
|
141
|
-
# Get all version
|
142
|
-
# @return [Array<
|
151
|
+
# Get the _download_ for all of version.
|
152
|
+
# @return [Array<Download>]
|
143
153
|
def download_list
|
144
|
-
table = @mod.
|
154
|
+
table = @mod.downloads.css 'table.mod-page-downloads-table'
|
145
155
|
head = table.css('thead tr th').map(&:text)
|
146
156
|
table.css('tbody tr').map do |line|
|
147
157
|
Mod.bind_td_to_th head, line
|
data/lib/factorio/mod/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: factorio-mod
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 71e6fd52
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- ".gitignore"
|
120
120
|
- ".gitlab-ci.yml"
|
121
121
|
- ".rspec"
|
122
|
+
- ".yardopts"
|
122
123
|
- Gemfile
|
123
124
|
- Gemfile.lock
|
124
125
|
- LICENSE
|
@@ -129,6 +130,7 @@ files:
|
|
129
130
|
- factorio-mod.gemspec
|
130
131
|
- lib/factorio/mod.rb
|
131
132
|
- lib/factorio/mod/cache.rb
|
133
|
+
- lib/factorio/mod/download.rb
|
132
134
|
- lib/factorio/mod/exception.rb
|
133
135
|
- lib/factorio/mod/mod.rb
|
134
136
|
- lib/factorio/mod/version.rb
|