wonko_the_sane 0.1.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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/bin/wonko_the_sane +91 -0
  3. data/data/minecraft.json +668 -0
  4. data/data/mods.json +2475 -0
  5. data/data/sources.json +427 -0
  6. data/data/timestamps.json +13 -0
  7. data/lib/wonko_the_sane.rb +66 -0
  8. data/lib/wonko_the_sane/input/base_input.rb +55 -0
  9. data/lib/wonko_the_sane/input/forge_installer_profile_input.rb +134 -0
  10. data/lib/wonko_the_sane/input/forgefiles_mods_input.rb +30 -0
  11. data/lib/wonko_the_sane/input/jenkins_input.rb +46 -0
  12. data/lib/wonko_the_sane/input/mojang_input.rb +214 -0
  13. data/lib/wonko_the_sane/reader_writer.rb +163 -0
  14. data/lib/wonko_the_sane/registry.rb +61 -0
  15. data/lib/wonko_the_sane/rules.rb +69 -0
  16. data/lib/wonko_the_sane/timestamps.rb +30 -0
  17. data/lib/wonko_the_sane/tools/update_nem.rb +85 -0
  18. data/lib/wonko_the_sane/util/configuration.rb +35 -0
  19. data/lib/wonko_the_sane/util/deep_storage_cache.rb +65 -0
  20. data/lib/wonko_the_sane/util/extraction_cache.rb +30 -0
  21. data/lib/wonko_the_sane/util/file_hash_cache.rb +42 -0
  22. data/lib/wonko_the_sane/util/http_cache.rb +143 -0
  23. data/lib/wonko_the_sane/util/maven_identifier.rb +39 -0
  24. data/lib/wonko_the_sane/util/task_stack.rb +21 -0
  25. data/lib/wonko_the_sane/version.rb +3 -0
  26. data/lib/wonko_the_sane/version_index.rb +33 -0
  27. data/lib/wonko_the_sane/version_parser.rb +115 -0
  28. data/lib/wonko_the_sane/versionlists/base_version_list.rb +103 -0
  29. data/lib/wonko_the_sane/versionlists/curse_version_list.rb +52 -0
  30. data/lib/wonko_the_sane/versionlists/forge_version_list.rb +142 -0
  31. data/lib/wonko_the_sane/versionlists/forgefiles_mods_list.rb +24 -0
  32. data/lib/wonko_the_sane/versionlists/jenkins_version_list.rb +29 -0
  33. data/lib/wonko_the_sane/versionlists/liteloader_version_list.rb +66 -0
  34. data/lib/wonko_the_sane/versionlists/vanilla_legacy_version_list.rb +39 -0
  35. data/lib/wonko_the_sane/versionlists/vanilla_version_list.rb +35 -0
  36. data/lib/wonko_the_sane/wonko_version.rb +184 -0
  37. metadata +324 -0
@@ -0,0 +1,163 @@
1
+ require 'hashie'
2
+
3
+ module Reader
4
+ def read_version_index(data)
5
+ json = Hashie::Mash.new JSON.parse(data, symbolize_names: true)
6
+
7
+ index = VersionIndex.new json.uid
8
+ index.name = json.name
9
+ json.versions.each do |ver|
10
+ v = WonkoVersion.new
11
+ v.is_complete = false
12
+ v.uid = json.uid
13
+ v.version = ver[:version]
14
+ v.type = ver[:type]
15
+ v.time = ver[:time]
16
+ index.versions << v
17
+ end
18
+
19
+ return index
20
+ end
21
+
22
+ def read_download(data, key)
23
+ if data[key.to_sym]
24
+ return data[key.to_sym].map do |dl|
25
+ Download.from_json key, dl
26
+ end
27
+ else
28
+ return []
29
+ end
30
+ end
31
+
32
+ def read_resource(data, res)
33
+ return if not data or not data.is_a? Object
34
+ res.traits = data[:'general.traits'] if data[:'general.traits']
35
+ res.folders = data[:'general.folders'] if data[:'general.folders']
36
+ res.launchMethod = data[:'general.launcher'] if data[:'general.launcher']
37
+ res.downloads = []
38
+ res.downloads << read_download(data, 'general.downloads')
39
+ res.downloads << read_download(data, 'java.libraries')
40
+ res.downloads << read_download(data, 'java.natives')
41
+ res.downloads.flatten!
42
+
43
+ res.mainClass = data[:'java.mainClass']
44
+ res.appletClass = data[:'mc.appletClass']
45
+ res.assets = data[:'mc.assets']
46
+ res.minecraftArguments = data[:'mc.arguments']
47
+ res.tweakers = data[:'mc.tweakers']
48
+ res.jarModTarget = data[:'mc.jarModTarget'] if data[:'mc.jarModTarget']
49
+ end
50
+
51
+ def read_version(data)
52
+ json = Hashie::Mash.new JSON.parse(data)
53
+
54
+ file = WonkoVersion.new
55
+ file.is_complete = true
56
+
57
+ file.uid = json.uid
58
+ file.version = json.version
59
+ file.time = json.time
60
+ file.type = json.type
61
+ file.requires = json.requires.map do |req|
62
+ Referenced.new(req[:uid], req[:version])
63
+ end if json.requires
64
+
65
+ json[:data].each do |data|
66
+ rules = data[:rules] ? data[:rules] : [ImplicitRule.new(:allow)]
67
+ if Rule.allowed_on_side rules, :client
68
+ read_resource data, file.client
69
+ elsif Rule.allowed_on_side rules, :server
70
+ read_resource data, file.server
71
+ else
72
+ read_resource data, file.common
73
+ end
74
+ end if json[:data]
75
+
76
+ return file
77
+ end
78
+
79
+ def read_index(data)
80
+ JSON.parse data, symbolize_names: true
81
+ end
82
+ end
83
+
84
+ module Writer
85
+ def write_version_index(index)
86
+ json = {
87
+ formatVersion: 0,
88
+ uid: index.uid,
89
+ name: index.name,
90
+ versions: []
91
+ }
92
+ index.versions.each do |ver|
93
+ obj = { version: ver.version }
94
+ obj[:type] = ver.type
95
+ obj[:time] = ver.time
96
+ json[:versions] << obj
97
+ end
98
+
99
+ return JSON.pretty_generate json
100
+ end
101
+
102
+ def write_resource(side, resource, out)
103
+ data = {}
104
+
105
+ data[:'general.traits'] = resource.traits if resource.traits and not resource.traits.empty?
106
+ data[:'general.launcher'] = resource.launchMethod if resource.launchMethod
107
+ data[:'general.folders'] = resource.folders if resource.folders and not resource.folders.empty?
108
+ resource.downloads.each do |dl|
109
+ data[dl.type] = [] if not data[dl.type]
110
+ data[dl.type] << dl.to_json
111
+ end
112
+ data[:'java.mainClass'] = resource.mainClass if resource.mainClass and resource.mainClass != ''
113
+ data[:'mc.jarModTarget'] = resource.jarModTarget if resource.jarModTarget
114
+
115
+ data[:'mc.tweakers'] = resource.tweakers if resource.tweakers and not resource.tweakers.empty?
116
+ data[:'mc.appletClass'] = resource.appletClass if resource.appletClass and resource.appletClass != ''
117
+ data[:'mc.assets'] = resource.assets if resource.assets and resource.assets != ''
118
+ data[:'mc.arguments'] = resource.minecraftArguments if resource.minecraftArguments and resource.minecraftArguments != ''
119
+
120
+ if not data.empty?
121
+ if side == :client or side == :server
122
+ data[:rules] = [
123
+ ImplicitRule.new(:disallow).to_json,
124
+ SidedRule.new(:allow, side).to_json
125
+ ]
126
+ end
127
+ out << data
128
+ end
129
+ end
130
+
131
+ def write_version(version)
132
+ # metadata
133
+ json = {
134
+ formatVersion: 0,
135
+ uid: version.uid,
136
+ version: version.version,
137
+ time: version.time
138
+ }
139
+ json[:type] = version.type if version.type and version.type != ''
140
+ json[:requires] = version.requires.map do |req|
141
+ obj = { uid: req.uid }
142
+ obj[:version] = req.version if req.version
143
+ obj
144
+ end if version.requires and not version.requires.empty?
145
+
146
+ json[:data] = []
147
+ write_resource(:client, version.client, json[:data]) if version.is_complete
148
+ write_resource(:server, version.server, json[:data]) if version.is_complete
149
+ write_resource(:common, version.common, json[:data]) if version.is_complete
150
+
151
+ JSON.pretty_generate json
152
+ end
153
+
154
+ def write_index(index)
155
+ JSON.pretty_generate index
156
+ end
157
+ end
158
+
159
+ class RW
160
+ include Writer
161
+ include Reader
162
+ end
163
+ $rw = RW.new
@@ -0,0 +1,61 @@
1
+ class Registry
2
+ def version_index(uid)
3
+ if File.exist? VersionIndex.local_filename(uid)
4
+ $rw.read_version_index File.read(VersionIndex.local_filename uid)
5
+ else
6
+ VersionIndex.new uid
7
+ end
8
+ end
9
+
10
+ def index
11
+ if File.exists? 'files/index.json'
12
+ $rw.read_index File.read('files/index.json')
13
+ else
14
+ {
15
+ index: []
16
+ }
17
+ end
18
+ end
19
+
20
+ def store(version)
21
+ if version.is_a? Array
22
+ version.each do |f| store(f) end
23
+ else
24
+ BaseSanitizer.sanitize(version, DownloadsFixer).each do |version|
25
+ Dir.mkdir 'files/' + version.uid unless Dir.exist? 'files/' + version.uid
26
+ File.write version.local_filename, $rw.write_version(version)
27
+
28
+ vindex = version_index version.uid
29
+ vindex.add_version version
30
+ File.write VersionIndex.local_filename(vindex.uid), $rw.write_version_index(vindex)
31
+
32
+ ind = index
33
+ ind[:formatVersion] = 0
34
+ ind[:index].each do |i|
35
+ if version.uid == i[:uid]
36
+ return
37
+ end
38
+ end
39
+ ind[:index] << {
40
+ uid: version.uid
41
+ }
42
+ File.write 'files/index.json', $rw.write_index(ind)
43
+ end
44
+ end
45
+ rescue Exception => e
46
+ Logging.logger[version.uid].error 'Unable to store: ' + version.version
47
+ raise e
48
+ end
49
+ def retrieve(id, version)
50
+ if File.exist? WonkoVersion.local_filename(id, version)
51
+ return $rw.read_version File.read(WonkoVersion.local_filename id, version)
52
+ else
53
+ return nil
54
+ end
55
+ end
56
+
57
+ def self.instance
58
+ Dir.mkdir 'files' unless Dir.exist? 'files'
59
+ @@instance ||= Registry.new
60
+ end
61
+ end
@@ -0,0 +1,69 @@
1
+ class Rule
2
+ attr_accessor :action
3
+
4
+ def initialize(action)
5
+ @action = action
6
+ end
7
+
8
+ def to_json
9
+ { action: @action }
10
+ end
11
+
12
+ def self.allowed_on_side(rules, side)
13
+ allowed = :allow
14
+ rules.each do |rule|
15
+ if rule.is_a? ImplicitRule
16
+ allowed = rule.action
17
+ elsif rule.is_a? SidedRule
18
+ allowed = rule.action if rule.side = side
19
+ end
20
+ end
21
+ return allowed
22
+ end
23
+
24
+ def self.from_json(obj)
25
+ if obj.key? :os
26
+ return OsRule.new obj[:action].to_sym, obj[:os][:name], obj[:os][:version], obj[:os][:arch]
27
+ elsif obj.key? :side
28
+ return SidedRule.new obj[:action].to_sym, obj[:side]
29
+ else
30
+ return ImplicitRule.new obj[:action].to_sym
31
+ end
32
+ end
33
+ end
34
+ class ImplicitRule < Rule
35
+ end
36
+ class OsRule < Rule
37
+ attr_accessor :os
38
+ attr_accessor :os_version
39
+ attr_accessor :os_arch
40
+
41
+ def initialize(action, os, os_version = nil, os_arch = nil)
42
+ super(action)
43
+ @os = os
44
+ @os_version = os_version
45
+ @os_arch = os_arch
46
+ end
47
+
48
+ def to_json
49
+ obj = super
50
+ obj[:os] = { name: @os }
51
+ obj[:os][:version] = @os_version if @os_version
52
+ obj[:os][:arch] = @os_arch if @os_arch
53
+ return obj
54
+ end
55
+ end
56
+ class SidedRule < Rule
57
+ attr_accessor :side
58
+
59
+ def initialize(action, side)
60
+ super(action)
61
+ @side = side
62
+ end
63
+
64
+ def to_json
65
+ obj = super
66
+ obj[:side] = @side
67
+ return obj
68
+ end
69
+ end
@@ -0,0 +1,30 @@
1
+ class Timestamps
2
+ def initialize
3
+ @json = WonkoTheSane.data_json 'timestamps.json'
4
+ end
5
+
6
+ def get(uid, version, default = nil)
7
+ if @json[uid.to_sym] and @json[uid.to_sym][version.to_sym.to_sym]
8
+ return @json[uid.to_sym][version.to_sym]
9
+ elsif default.nil?
10
+ raise 'No timestamp available for ' + uid + ': ' + version
11
+ elsif default.is_a? String
12
+ if default.to_i.to_s == default
13
+ return default.to_i
14
+ else
15
+ return DateTime.parse(default).to_time.to_i
16
+ end
17
+ elsif default.is_a? Fixnum
18
+ return default
19
+ elsif default.is_a? Float
20
+ return default.to_i
21
+ else
22
+ raise 'InvalidTimeFormat'
23
+ end
24
+ end
25
+
26
+ def self.get(uid, version, default = nil)
27
+ @@me ||= Timestamps.new
28
+ @@me.get uid, version, default
29
+ end
30
+ end
@@ -0,0 +1,85 @@
1
+ def get_curse_id(name)
2
+ data = HTTPCache.get('http://minecraft.curseforge.com/mc-mods/' + name).gsub /[\n\r]/, ''
3
+ match = data.match /<li class="view-on?-cur?se"> *<a href="http:\/\/curse.com\/project\/(\d*)">/
4
+ return match[1]
5
+ end
6
+
7
+ def update_nem
8
+ forgefilesCleaned = {
9
+ IronChests: :IronChests2
10
+ }
11
+
12
+ sources = WonkoTheSane.data_json 'sources.json'
13
+ sources[:forgefiles] = {} if not sources[:forgefiles]
14
+ sources[:jenkins] = [] if not sources[:jenkins]
15
+ sources[:curse] = [] if not sources[:curse]
16
+
17
+ nemList = JSON.parse HTTPCache.get('https://raw.githubusercontent.com/SinZ163/NotEnoughMods/master/NEMP/mods.json'), symbolize_names: true
18
+ nemList.each do |key, value|
19
+ name = (value[:name] ? value[:name] : key).to_sym
20
+ case value[:function]
21
+ when 'CheckMCForge2'
22
+ if forgefilesCleaned[name]
23
+ name = forgefilesCleaned[name]
24
+ end
25
+ if not sources[:forgefiles].find do |artifact, urlId| urlId == name.to_s end and not [:MinecraftForge, :FML, :Cauldron].include? name
26
+ print "Please enter an uid for the #{"forgefiles".cyan} artifact #{name.to_s.green}: "
27
+ uid = gets.chomp
28
+ if not uid.empty?
29
+ sources[:forgefiles][uid.to_sym] = name.to_s
30
+ end
31
+ end
32
+ when 'CheckAE'
33
+ # TODO
34
+ when 'CheckAE2'
35
+ # TODO
36
+ when 'CheckAtomicStryker'
37
+ # TODO
38
+ when 'CheckBigReactors'
39
+ # TODO
40
+ when 'CheckBuildCraft'
41
+ # TODO
42
+ when 'CheckChickenBones'
43
+ # TODO
44
+ when 'CheckCurse'
45
+ curseId = value[:curse][:id] ? value[:curse][:id] : get_curse_id(value[:curse][:name] ? value[:curse][:name] : name.to_s.downcase)
46
+ if not sources[:curse].find do |obj| obj[:id] == curseId end
47
+ print "Please enter an uid for the #{"curse".cyan} artifact #{name.to_s.green} (id: #{curseId.yellow}): "
48
+ uid = gets.chomp
49
+ if not uid.empty?
50
+ sources[:curse] << {
51
+ uid: uid,
52
+ id: curseId,
53
+ fileregex: value[:curse][:regex]
54
+ }
55
+ end
56
+ end
57
+ when 'CheckDropBox'
58
+ # TODO
59
+ when 'CheckGitHubRelease'
60
+ # TODO
61
+ when 'CheckHTML'
62
+ # TODO
63
+ when 'CheckJenkins'
64
+ parts = value[:jenkins][:url].match(/^(.*)\/job\/([^\/]*)\//)
65
+ if not sources[:jenkins].find do |obj| obj[:url] == parts[1] and obj[:artifact] == parts[2] end
66
+ print "Please enter an uid for the #{"jenkins".cyan} artifact #{name.to_s.green} from #{parts[1].yellow} (#{parts[2].red}): "
67
+ uid = gets.chomp
68
+ if not uid.empty?
69
+ sources[:jenkins] << {
70
+ uid: uid,
71
+ url: parts[1],
72
+ artifact: parts[2]
73
+ }
74
+ end
75
+ end
76
+ when 'CheckLunatrius'
77
+ # TODO
78
+ when 'CheckSpacechase'
79
+ # TODO
80
+ end
81
+
82
+ # keep the writing in the loop so we don't lose progress in case of crashes or similar
83
+ WonkoTheSane.set_data_json 'sources.json', sources
84
+ end
85
+ end
@@ -0,0 +1,35 @@
1
+ module WonkoTheSane
2
+ module Util
3
+ class Configuration
4
+ attr_reader :lists
5
+ attr_accessor :data_path
6
+
7
+ def register_list(list)
8
+ @lists ||= []
9
+ case list
10
+ when String
11
+ register_list list.to_sym
12
+ when Symbol
13
+ register_list list.constantize
14
+ when Class
15
+ register_list list.new
16
+ else
17
+ @lists << list
18
+ end
19
+ end
20
+
21
+ def register_lists_from(file)
22
+ sources = WonkoTheSane.data_json 'sources.json'
23
+ sources[:forgefiles].each do |uid, urlId|
24
+ register_list ForgeFilesModsList.new(uid.to_s, urlId)
25
+ end if sources[:forgefiles]
26
+ sources[:jenkins].each do |obj|
27
+ register_list JenkinsVersionList.new(obj[:uid], obj[:url], obj[:artifact], obj[:fileRegex])
28
+ end if sources[:jenkins]
29
+ sources[:curse].each do |obj|
30
+ register_list CurseVersionList.new(obj[:uid], obj[:id], obj[:fileregex])
31
+ end if sources[:curse]
32
+ end
33
+ end
34
+ end
35
+ end