wonko_the_sane 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc57f86a647b80182858a1980048fe31dde2dbc6
4
- data.tar.gz: 7ddb8818395ea2e823cf61ac94aa26d362453f79
3
+ metadata.gz: 40c75f8cc35f2cedea382f8b22f0373f9199ab60
4
+ data.tar.gz: 419906fc73b134f8ddc6d994d2bab5ec8d277840
5
5
  SHA512:
6
- metadata.gz: 48502a7dfd108e92d4cae999c99fa87ab236334ef771aec8f9cb6c942dc25a4ae9fc43ee0d81c79fed334415256d95e8cf2d47884767be965b23d25c96dfd678
7
- data.tar.gz: 7addb60be6a1876d40cc473367916d4a406937cc9d492baa43b01a2c6d73e81ec9222329a245a0f6d110eb724e74d3efc920fe5babfc0c2a86284ebea90a1000
6
+ metadata.gz: bcba25e623bf105bc2aa37d9572e3a542ffc58c4eaa30f50d8dc576aa6af10a9472175736e4460687d24564e977070de45935b037001b39be6b7f2ea972f3a25
7
+ data.tar.gz: 52fd86ab7abd1262bf6b2096ef67e89a83641157b8fb9106787a2d71d4916d17bf85f1d0cecf369b64e0c8b6baa126c51302a84f281549851f32179744553e0c
data/bin/wonko_the_sane CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  require 'wonko_the_sane'
2
3
  require 'optparse'
3
4
 
@@ -21,7 +22,7 @@ Logging.logger['General'].info 'Welcome to WonkoTheSane!'.yellow
21
22
 
22
23
  WonkoTheSane.configure do |config|
23
24
  config.data_path = File.dirname(__FILE__) + '/../data'
24
- config.register_lists_from 'data/sources.json'
25
+ config.register_lists_from_sources
25
26
  config.register_list VanillaVersionList
26
27
  config.register_list VanillaLegacyVersionList
27
28
  config.register_list LiteLoaderVersionList
@@ -82,6 +83,15 @@ OptionParser.new do |opts|
82
83
  opts.on '--update-nem', 'Updates sources.json with data from NEM' do
83
84
  update_nem
84
85
  end
86
+ opts.on '--set-config=VAL', 'Sets a configuration value' do |val|
87
+ parts = val.match /([^:=]*)([:=](.*))?/
88
+ if parts.length == 4 && !parts[3].nil?
89
+ Settings[parts[1]] = parts[3]
90
+ else
91
+ Settings.delete parts[1]
92
+ end
93
+ Settings.save! WonkoTheSane.settings_file
94
+ end
85
95
  opts.on '-h', '--help', 'Prints this help' do
86
96
  puts opts
87
97
  exit
@@ -89,3 +99,4 @@ OptionParser.new do |opts|
89
99
  end.parse!
90
100
 
91
101
  TaskStack.pop_all
102
+ WonkoTheSane.wonkoweb_uploader.upload_changes!
data/data/minecraft.json CHANGED
@@ -1,4 +1,4 @@
1
- {
1
+ {
2
2
  "versions": [
3
3
  {
4
4
  "id": "1.5.2",
@@ -4,9 +4,19 @@ require 'yajl/json_gem'
4
4
  require 'fileutils'
5
5
  require 'zip'
6
6
  require 'set'
7
+ require 'uri'
8
+ require 'net/http'
9
+ require 'digest'
10
+ require 'date'
11
+ require 'time'
12
+ require 'oga'
13
+ require 'configliere'
14
+ require 'httparty'
15
+ require 'active_support/core_ext/hash/indifferent_access'
7
16
 
8
17
  require 'wonko_the_sane/version'
9
18
  require 'wonko_the_sane/tools/update_nem'
19
+ require 'wonko_the_sane/util/benchmark'
10
20
  require 'wonko_the_sane/util/configuration'
11
21
  require 'wonko_the_sane/util/extraction_cache'
12
22
  require 'wonko_the_sane/util/deep_storage_cache'
@@ -30,6 +40,7 @@ require 'wonko_the_sane/versionlists/liteloader_version_list'
30
40
  require 'wonko_the_sane/versionlists/vanilla_legacy_version_list'
31
41
  require 'wonko_the_sane/versionlists/vanilla_version_list'
32
42
 
43
+ require 'wonko_the_sane/wonkoweb_uploader'
33
44
  require 'wonko_the_sane/reader_writer'
34
45
  require 'wonko_the_sane/registry'
35
46
  require 'wonko_the_sane/rules'
@@ -39,16 +50,25 @@ require 'wonko_the_sane/version_parser'
39
50
  require 'wonko_the_sane/wonko_version'
40
51
 
41
52
  module WonkoTheSane
53
+ def self.wonkoweb_uploader
54
+ @uploader ||= WonkoWebUploader.new
55
+ end
56
+
42
57
  def self.lists
43
58
  configuration.lists
44
59
  end
45
60
 
61
+ def self.settings_file
62
+ File.dirname(__FILE__) + '/../wonko_the_sane.yml'
63
+ end
64
+
46
65
  def self.data(file)
47
66
  configuration.data_path + '/' + file
48
67
  end
49
68
 
50
69
  def self.data_json(file)
51
- JSON.parse File.open(data(file), 'r'), symbolize_keys: true
70
+ res = JSON.parse File.read data file
71
+ res.is_a?(Hash) ? HashWithIndifferentAccess.new(res) : res
52
72
  end
53
73
 
54
74
  def self.set_data_json(file, obj)
@@ -64,3 +84,24 @@ module WonkoTheSane
64
84
  end
65
85
  private_class_method :configuration
66
86
  end
87
+
88
+ Settings.use :config_block, :encrypted, :prompt, :define
89
+ Settings({
90
+ aws: {
91
+ client_id: nil,
92
+ client_secret: nil
93
+ },
94
+ wonkoweb: {
95
+ host: nil,
96
+ email: nil,
97
+ token: nil
98
+ }
99
+ })
100
+ Settings.define 'aws.client_id', encrypted: true
101
+ Settings.define 'aws.client_secret', encrypted: true
102
+ Settings.define 'wonkoweb.host'
103
+ Settings.define 'wonkoweb.name'
104
+ Settings.define 'wonkoweb.token', encrypted: true
105
+ Settings.read WonkoTheSane.settings_file
106
+ Settings[:encrypt_pass] = ENV['ENCRYPT_PASS'] || (print 'Password: '; pwd = STDIN.noecho(&:gets).chomp; puts; pwd)
107
+ Settings.resolve!
@@ -114,16 +114,16 @@ class MojangInput
114
114
  file.client.downloads = object[:libraries].map do |obj|
115
115
  MojangInput.sanetize_mojang_library obj
116
116
  end.flatten 1
117
- mainLib = VersionLibrary.new
118
- mainLib.name = "net.minecraft:minecraft:#{file.version}"
119
- mainLib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/' + file.version + '.jar'
120
- file.client.downloads << mainLib
117
+ main_lib = VersionLibrary.new
118
+ main_lib.name = "net.minecraft:minecraft:#{file.version}"
119
+ main_lib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/' + file.version + '.jar'
120
+ file.client.downloads << main_lib
121
121
  file.client.launchMethod = 'minecraft'
122
122
 
123
- serverLib = VersionLibrary.new
124
- serverLib.name = "net.minecraft:minecraft_server:#{file.version}"
125
- serverLib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/minecraft_server.' + file.version + '.jar'
126
- file.server.downloads << serverLib
123
+ server_lib = VersionLibrary.new
124
+ server_lib.name = "net.minecraft:minecraft_server:#{file.version}"
125
+ server_lib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/minecraft_server.' + file.version + '.jar'
126
+ file.server.downloads << server_lib
127
127
  file.server.jarModTarget = "net.minecraft:minecraft_server:#{file.version}"
128
128
  file.server.launchMethod = 'java.jar'
129
129
 
@@ -2,7 +2,7 @@ require 'hashie'
2
2
 
3
3
  module Reader
4
4
  def read_version_index(data)
5
- json = Hashie::Mash.new JSON.parse(data, symbolize_names: true)
5
+ json = Hashie::Mash.new data
6
6
 
7
7
  index = VersionIndex.new json.uid
8
8
  index.name = json.name
@@ -21,11 +21,11 @@ module Reader
21
21
 
22
22
  def read_download(data, key)
23
23
  if data[key.to_sym]
24
- return data[key.to_sym].map do |dl|
24
+ data[key.to_sym].map do |dl|
25
25
  Download.from_json key, dl
26
26
  end
27
27
  else
28
- return []
28
+ []
29
29
  end
30
30
  end
31
31
 
@@ -49,7 +49,7 @@ module Reader
49
49
  end
50
50
 
51
51
  def read_version(data)
52
- json = Hashie::Mash.new JSON.parse(data)
52
+ json = Hashie::Mash.new data
53
53
 
54
54
  file = WonkoVersion.new
55
55
  file.is_complete = true
@@ -73,11 +73,11 @@ module Reader
73
73
  end
74
74
  end if json[:data]
75
75
 
76
- return file
76
+ file
77
77
  end
78
78
 
79
79
  def read_index(data)
80
- JSON.parse data, symbolize_names: true
80
+ data.with_indifferent_access
81
81
  end
82
82
  end
83
83
 
@@ -96,7 +96,7 @@ module Writer
96
96
  json[:versions] << obj
97
97
  end
98
98
 
99
- return JSON.pretty_generate json
99
+ json
100
100
  end
101
101
 
102
102
  def write_resource(side, resource, out)
@@ -134,25 +134,26 @@ module Writer
134
134
  formatVersion: 0,
135
135
  uid: version.uid,
136
136
  version: version.version,
137
- time: version.time
137
+ time: version.time.to_s,
138
+ type: version.type,
139
+ data: [],
140
+ requires: []
138
141
  }
139
- json[:type] = version.type if version.type and version.type != ''
140
142
  json[:requires] = version.requires.map do |req|
141
143
  obj = { uid: req.uid }
142
144
  obj[:version] = req.version if req.version
143
145
  obj
144
146
  end if version.requires and not version.requires.empty?
145
147
 
146
- json[:data] = []
147
148
  write_resource(:client, version.client, json[:data]) if version.is_complete
148
149
  write_resource(:server, version.server, json[:data]) if version.is_complete
149
150
  write_resource(:common, version.common, json[:data]) if version.is_complete
150
151
 
151
- JSON.pretty_generate json
152
+ json
152
153
  end
153
154
 
154
155
  def write_index(index)
155
- JSON.pretty_generate index
156
+ index
156
157
  end
157
158
  end
158
159
 
@@ -1,20 +1,17 @@
1
1
  class Registry
2
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
3
+ return VersionIndex.new uid unless File.exists? VersionIndex.local_filename uid
4
+ $rw.read_version_index JSON.parse File.read(VersionIndex.local_filename uid)
5
+ end
6
+
7
+ def store_version_index(index)
8
+ File.write index.local_filename, JSON.pretty_generate($rw.write_version_index index)
9
+ WonkoTheSane.wonkoweb_uploader.file_changed index.uid
8
10
  end
9
11
 
10
12
  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
13
+ return { index: [] } unless File.exists? 'files/index.json'
14
+ $rw.read_index JSON.parse File.read 'files/index.json'
18
15
  end
19
16
 
20
17
  def store(version)
@@ -23,34 +20,30 @@ class Registry
23
20
  else
24
21
  BaseSanitizer.sanitize(version, DownloadsFixer).each do |version|
25
22
  Dir.mkdir 'files/' + version.uid unless Dir.exist? 'files/' + version.uid
26
- File.write version.local_filename, $rw.write_version(version)
23
+ File.write version.local_filename, JSON.pretty_generate($rw.write_version version)
24
+ WonkoTheSane.wonkoweb_uploader.version_changed version.uid, version.version
27
25
 
28
26
  vindex = version_index version.uid
29
27
  vindex.add_version version
30
- File.write VersionIndex.local_filename(vindex.uid), $rw.write_version_index(vindex)
28
+ store_version_index vindex
31
29
 
32
30
  ind = index
31
+ next if ind[:index].find { |i| version.uid == i[:uid] } # early exit if the uid already exists in the index
33
32
  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)
33
+ ind[:index] << { uid: version.uid }
34
+ File.write 'files/index.json', JSON.pretty_generate($rw.write_index ind)
43
35
  end
44
36
  end
45
37
  rescue Exception => e
46
38
  Logging.logger[version.uid].error 'Unable to store: ' + version.version
47
39
  raise e
48
40
  end
41
+
49
42
  def retrieve(id, version)
50
43
  if File.exist? WonkoVersion.local_filename(id, version)
51
- return $rw.read_version File.read(WonkoVersion.local_filename id, version)
44
+ $rw.read_version JSON.parse File.read(WonkoVersion.local_filename id, version)
52
45
  else
53
- return nil
46
+ nil
54
47
  end
55
48
  end
56
49
 
@@ -0,0 +1,17 @@
1
+ module Util
2
+ def self.deep_map_keys(val, &block)
3
+ Util.deep_map_hash val do |k, v|
4
+ [yield(k), v]
5
+ end
6
+ end
7
+
8
+ def self.deep_map(val, &block)
9
+ if val.is_a? Array
10
+ val.map { |item| deep_map_hash item, &block }
11
+ elsif val.is_a? Hash
12
+ Hash[val.map { |k, v| yield k, deep_map_hash(v, &block) }]
13
+ else
14
+ yield nil, val
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ require 'benchmark'
2
+
3
+ module WonkoTheSane
4
+ module Util
5
+ class Benchmark
6
+ def initialize
7
+ @timers = {}
8
+ @calls = {}
9
+ end
10
+
11
+ def benchmark(id, &block)
12
+ @timers[id.to_s] ||= ::Benchmark::Tms.new(0, 0, 0, 0, 0, id.to_s)
13
+ @calls[id.to_s] ||= 0
14
+ @calls[id.to_s] += 1
15
+ ret = nil
16
+ @timers[id.to_s].add! { ret = yield }
17
+ ret
18
+ end
19
+
20
+ def print_times(reset = false)
21
+ @timers.each do |id, timer|
22
+ puts "#{timer.label}: #{timer.real.round 2}s total, #{(timer.real / @calls[id]).round 2}s/call"
23
+ end
24
+ @timers = {} if reset
25
+ @calls = {} if reset
26
+ end
27
+ end
28
+ end
29
+ end
@@ -18,7 +18,7 @@ module WonkoTheSane
18
18
  end
19
19
  end
20
20
 
21
- def register_lists_from(file)
21
+ def register_lists_from_sources
22
22
  sources = WonkoTheSane.data_json 'sources.json'
23
23
  sources[:forgefiles].each do |uid, urlId|
24
24
  register_list ForgeFilesModsList.new(uid.to_s, urlId)
@@ -4,13 +4,14 @@ require 'wonko_the_sane/util/http_cache'
4
4
  module WonkoTheSane
5
5
  module Util
6
6
  class DeepStorageCache
7
- def initialize(manifest_file)
8
- lines = File.read('.aws-credentials').split "\n"
9
- @resource = Aws::S3::Resource.new region: 'eu-west-1', credentials: Aws::Credentials.new(lines[0], lines[1])
7
+ def initialize
8
+ @resource = Aws::S3::Resource.new region: 'eu-west-1',
9
+ credentials: Aws::Credentials.new(Settings[:aws][:client_id],
10
+ Settings[:aws][:client_secret])
10
11
  @bucket = @resource.bucket 'wonkoweb-02jandal-xyz'
11
12
 
12
13
  @manifest = @bucket.object 'manifest.json'
13
- @entries = @manifest.exists? ? JSON.parse(@manifest.get.body, symbolize_keys: true) : {}
14
+ @entries = @manifest.exists? ? JSON.parse(@manifest.get.body.read, symbolize_keys: true) : {}
14
15
  end
15
16
 
16
17
  def get_info(url, options = {})
@@ -19,7 +20,7 @@ module WonkoTheSane
19
20
  ctxt = options[:ctxt] || 'DeepStorageCache'
20
21
 
21
22
  file = HTTPCache.file url, check_stale: false, ctxt: options[:ctxt]
22
- info = info_for_file file, url
23
+ info = self.class.info_for_file file, url
23
24
 
24
25
  @entries[url] = info
25
26
  @manifest.put body: JSON.pretty_generate(@entries)
@@ -31,8 +32,18 @@ module WonkoTheSane
31
32
  # http://anthonylewis.com/2011/02/09/to-hex-and-back-with-ruby/
32
33
  md5 = [info[:md5].scan(/../).map { |x| x.hex.chr }.join].pack 'm0'
33
34
 
35
+ content_type = case url
36
+ when /\.zip$/, /\.jar$/
37
+ 'application/zip'
38
+ else
39
+ ''
40
+ end
41
+
34
42
  Logging.logger[ctxt].debug "Uploading backup of #{url} to S3..."
35
- object.put body: file, content_md5: md5, metadata: Hash[info.map { |k,v| [k.to_s, v.to_s]}]
43
+ object.put body: file,
44
+ content_md5: md5,
45
+ content_type: content_type,
46
+ metadata: Hash[info.map { |k,v| [k.to_s, v.to_s]}]
36
47
  Logging.logger[ctxt].debug 'Backup successfully uploaded to S3'
37
48
  end
38
49
  end
@@ -41,8 +52,8 @@ module WonkoTheSane
41
52
  end
42
53
 
43
54
  def self.get_info(url, options = {})
44
- if File.exists? '.aws-credentials'
45
- @@instance ||= DeepStorageCache.new 'cache/deep_storage.json'
55
+ if Settings[:aws][:client_id]
56
+ @@instance ||= DeepStorageCache.new
46
57
  @@instance.get_info url, options
47
58
  else
48
59
  info_for_file HTTPCache.file(url, check_stale: false, ctxt: options[:ctxt]), url
@@ -51,7 +62,7 @@ module WonkoTheSane
51
62
 
52
63
  private
53
64
 
54
- def info_for_file(file, url)
65
+ def self.info_for_file(file, url)
55
66
  {
56
67
  url: url,
57
68
  file: url.gsub(/[&:$@=+,?\\^`><\{\}\[\]#%'"~|]/, '_'),
@@ -16,7 +16,7 @@ class HTTPCache
16
16
 
17
17
  def file(ctxt, url, key, check_stale = true)
18
18
  fetch ctxt, url, key, check_stale
19
- File.new @basedir + '/' + key, 'r'
19
+ File.open @basedir + '/' + key, 'r'
20
20
  end
21
21
 
22
22
  private
@@ -1,3 +1,3 @@
1
1
  module WonkoTheSane
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
@@ -14,19 +14,25 @@ class VersionIndex
14
14
  @versions << version
15
15
  end
16
16
  end
17
+
17
18
  def remove_version(version)
18
19
  @versions.select! do |ver|
19
20
  version.version != ver.version
20
21
  end
21
22
  end
23
+
22
24
  def self.get_full_version(version)
23
25
  if File.exist? version.local_filename
24
- Reader.read_version File.read(version.local_filename)
26
+ Reader.read_version JSON.parse File.read(version.local_filename)
25
27
  else
26
28
  nil
27
29
  end
28
30
  end
29
31
 
32
+ def local_filename
33
+ VersionIndex.local_filename @uid
34
+ end
35
+
30
36
  def self.local_filename(uid)
31
37
  'files/' + uid + '.json'
32
38
  end
@@ -18,38 +18,36 @@ class BaseVersionList
18
18
 
19
19
  def refresh
20
20
  @lastError = nil
21
- begin
22
- versions = get_versions
21
+ versions = get_versions
23
22
 
24
- # check if some versions aren't in @processed (likely new ones) and fetch and process them
25
- versions.each do |version|
26
- begin
27
- next if not version
28
- id = version.is_a?(Array) ? version.first : version
29
- unless @processed.include? id
30
- files = get_version version
31
- next if files.nil? or (files.is_a? Array and files.empty?)
23
+ # check if some versions aren't in @processed (likely new ones) and fetch and process them
24
+ versions.each do |version|
25
+ begin
26
+ next if not version
27
+ id = version.is_a?(Array) ? version.first : version
28
+ unless @processed.include? id
29
+ files = get_version version
30
+ next if files.nil? or (files.is_a? Array and files.empty?)
32
31
 
33
- files.flatten.each do |file|
34
- file.is_complete = true
35
- Registry.instance.store file
36
- end if files and files.is_a? Array
37
- files.is_complete = true if files and files.is_a? WonkoVersion
38
- Registry.instance.store files if files and files.is_a? WonkoVersion
32
+ files.flatten.each do |file|
33
+ file.is_complete = true
34
+ Registry.instance.store file
35
+ end if files and files.is_a? Array
36
+ files.is_complete = true if files and files.is_a? WonkoVersion
37
+ Registry.instance.store files if files and files.is_a? WonkoVersion
39
38
 
40
- @processed << id
41
- write_cache_file
42
- end
43
- rescue => e
44
- logger.error e.message
45
- logger.warn e.backtrace.first
46
- binding.pry if $stdout.isatty && ENV['DEBUG_ON_ERROR']
47
- @lastError = e.message
39
+ @processed << id
40
+ write_cache_file
48
41
  end
49
42
  end
50
-
51
- FileUtils.touch cache_file
52
43
  end
44
+
45
+ FileUtils.touch cache_file
46
+ rescue => e
47
+ logger.error e.message
48
+ logger.warn e.backtrace.first
49
+ binding.pry if $stdout.isatty && ENV['DEBUG_ON_ERROR']
50
+ @lastError = e.message
53
51
  end
54
52
 
55
53
  def logger
@@ -93,11 +91,11 @@ class BaseVersionList
93
91
  end
94
92
 
95
93
  def get_json(url)
96
- JSON.parse HTTPCache.file(url, ctxt: @artifact, check_stale: true), symbolize_names: true
94
+ Yajl::Parser.parse HTTPCache.file(url, ctxt: @artifact, check_stale: true), symbolize_keys: true
97
95
  end
98
96
 
99
97
  def get_json_cached(url)
100
- JSON.parse HTTPCache.file(url, ctxt: @artifact, check_stale: false), symbolize_names: true
98
+ Yajl::Parser.parse HTTPCache.file(url, ctxt: @artifact, check_stale: false), symbolize_keys: true
101
99
  end
102
100
  end
103
101
  Dir.mkdir 'cache' unless Dir.exist? 'cache'
@@ -1,7 +1,3 @@
1
- require_relative 'base_version_list'
2
- require 'date'
3
- require 'time'
4
-
5
1
  class CurseVersionList < BaseVersionList
6
2
  def initialize(uid, curseId, fileRegex)
7
3
  super(uid)
@@ -95,7 +95,7 @@ class VersionLibrary < Download
95
95
  @mavenBaseUrl = json[:mavenBaseUrl]
96
96
 
97
97
  # if the absolute url is equal to the expected maven url we clear the absolute url
98
- if @url == url
98
+ if @mavenBaseUrl && @url == url
99
99
  @url = nil
100
100
  end
101
101
  end
@@ -134,7 +134,7 @@ class WonkoVersion
134
134
  attr_accessor :type
135
135
  attr_accessor :is_complete
136
136
 
137
- attr_accessor :requires # list of Referenced
137
+ attr_accessor :requires # [Referenced]
138
138
 
139
139
  class Resources
140
140
  attr_accessor :traits
@@ -0,0 +1,162 @@
1
+ module WonkoTheSane
2
+ class WonkoWeb
3
+ include HTTParty
4
+
5
+ class UploadError < ResponseError
6
+ attr_reader :errors
7
+
8
+ def initialize(errors)
9
+ @errors = errors
10
+ end
11
+ end
12
+
13
+ def initialize(benchmark)
14
+ self.class.base_uri Settings[:wonkoweb][:host]
15
+ self.class.headers 'X-Uploader-Name' => Settings[:wonkoweb][:name],
16
+ 'X-Uploader-Token' => Settings[:wonkoweb][:token],
17
+ 'X-WUR-Enabled' => 'true',
18
+ 'Content-Type' => 'application/json'
19
+
20
+ @benchmark = benchmark
21
+ end
22
+
23
+ def index
24
+ self.class.get(path 'index').with_indifferent_access
25
+ end
26
+
27
+ def file(uid)
28
+ self.class.get(path uid).with_indifferent_access
29
+ end
30
+
31
+ def version(uid, version)
32
+ self.class.get(path uid, version).with_indifferent_access
33
+ end
34
+
35
+ def upload_file(data)
36
+ return if data.nil?
37
+ uid = data[:uid]
38
+ theirs = @benchmark.benchmark('upload_file.theirs') { file uid rescue nil }
39
+
40
+ data.delete :versions # only stubs here
41
+ data[:name] ||= data[:uid]
42
+
43
+ upload_hash path, path(uid), data, theirs, false
44
+ end
45
+
46
+ def upload_version(data)
47
+ return if data.nil?
48
+ uid = data[:uid]
49
+ version = data[:version]
50
+ theirs = @benchmark.benchmark('upload_version.theirs') { version uid, version rescue nil }
51
+ upload_hash path(uid), path(uid, version), data, theirs, true
52
+ end
53
+
54
+ private
55
+
56
+ def upload_hash(create_path, update_path, ours, theirs, allow_overwrite)
57
+ caller = ours[:version] ? 'upload_version' : 'upload_file'
58
+ res = if theirs.nil? || (theirs[:errors] && theirs[:errors].size > 0)
59
+ # upload entire file
60
+ @benchmark.benchmark(caller + '.create') { self.class.post create_path, body: JSON.generate(ours) }
61
+ else
62
+ # upload changes
63
+
64
+ body = JSON.parse JSON.generate ours # round-trip to "normalize" things
65
+ # keep_if modifies in-place (why isn't it named keep_if! ????????)
66
+ body.keep_if { |k, v| !(theirs[k.to_sym] == v) }
67
+ body.keep_if { |k, v| theirs[k.to_sym].nil? || theirs[k.to_sym].to_s.empty? } unless allow_overwrite
68
+ @benchmark.benchmark(caller + '.update') { self.class.patch update_path, body: JSON.generate(body) } unless body.empty?
69
+ end
70
+
71
+ if !res.nil? && (res.code >= 300 || JSON.parse(res.body).key?('errors'))
72
+ binding.pry
73
+ fail UploadError.new res.body[:errors]
74
+ end
75
+ end
76
+
77
+ def path(*args)
78
+ return '/api/v1.json' if args.nil? || args.empty?
79
+ '/api/v1/' + args.map(&:to_s).join('/') + '.json'
80
+ end
81
+ end
82
+
83
+ class WonkoWebUploader
84
+ def initialize
85
+ data = JSON.parse File.read 'uploader_queue.json' if File.exists? 'uploader_queue.json'
86
+ data ||= {}
87
+ data = data.with_indifferent_access
88
+ @changed_files = data[:files] || []
89
+ @changed_versions = data[:versions] || {}
90
+
91
+ @benchmark = WonkoTheSane::Util::Benchmark.new
92
+ @client = WonkoWeb.new @benchmark
93
+ end
94
+
95
+ def file_changed(uid)
96
+ @changed_files << uid
97
+ save_changes!
98
+ end
99
+
100
+ def version_changed(uid, version)
101
+ @changed_versions[uid] ||= []
102
+ @changed_versions[uid] << version
103
+ save_changes!
104
+ end
105
+
106
+ def upload_changes!
107
+ @changed_files.uniq!
108
+ return if Settings[:wonkoweb][:host].nil?
109
+
110
+ existing_uids = @benchmark.benchmark('initial index') { @client.index }[:index].map { |obj| obj[:uid] }
111
+ logger.info "Uploading #{@changed_files.size} changed files to WonkoWeb at #{Settings[:wonkoweb][:host]}..."
112
+ @changed_files.dup.each do |uid|
113
+ begin
114
+ @client.upload_file $rw.write_version_index Registry.instance.version_index uid
115
+ existing_uids << uid
116
+ @changed_files.delete uid
117
+ rescue => e
118
+ logger.error "Unable to upload file for #{uid} to WonkoWeb: #{e.message}"
119
+ logger.warn e.backtrace.first
120
+ binding.pry if $stdout.isatty && ENV['DEBUG_ON_ERROR']
121
+ end
122
+ end
123
+ logger.info 'Done.'
124
+ @benchmark.print_times true
125
+
126
+ num_versions = @changed_versions.collect { |k, v| v.size }.inject :+
127
+ logger.info "Uploading #{num_versions} changed versions to WonkoWeb at #{Settings[:wonkoweb][:host]}..."
128
+ @changed_versions.dup.each do |uid, versions|
129
+ versions.dup.each do |version|
130
+ begin
131
+ @client.upload_file $rw.write_version_index Registry.instance.version_index uid unless existing_uids.include? uid
132
+ @client.upload_version $rw.write_version Registry.instance.retrieve uid, version
133
+ versions.delete version
134
+ rescue => e
135
+ logger.error "Unable to upload version #{version} of #{uid} to WonkoWeb: #{e.message}"
136
+ logger.warn e.backtrace.first
137
+ binding.pry if $stdout.isatty && ENV['DEBUG_ON_ERROR']
138
+ end
139
+ @changed_versions.delete uid if versions.empty?
140
+ end
141
+ end
142
+ logger.info 'Done.'
143
+ @benchmark.print_times true
144
+
145
+ save_changes!
146
+ end
147
+
148
+ private
149
+
150
+ def logger
151
+ Logging.logger[self]
152
+ end
153
+
154
+ def save_changes!
155
+ data = {
156
+ files: @changed_files,
157
+ versions: @changed_versions
158
+ }
159
+ File.write 'uploader_queue.json', JSON.pretty_generate(data)
160
+ end
161
+ end
162
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wonko_the_sane
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - 02JanDal
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-05-17 00:00:00.000000000 Z
13
+ date: 2015-05-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -250,6 +250,48 @@ dependencies:
250
250
  - - ">="
251
251
  - !ruby/object:Gem::Version
252
252
  version: '0'
253
+ - !ruby/object:Gem::Dependency
254
+ name: configliere
255
+ requirement: !ruby/object:Gem::Requirement
256
+ requirements:
257
+ - - ">="
258
+ - !ruby/object:Gem::Version
259
+ version: '0'
260
+ type: :runtime
261
+ prerelease: false
262
+ version_requirements: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - ">="
265
+ - !ruby/object:Gem::Version
266
+ version: '0'
267
+ - !ruby/object:Gem::Dependency
268
+ name: httparty
269
+ requirement: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ type: :runtime
275
+ prerelease: false
276
+ version_requirements: !ruby/object:Gem::Requirement
277
+ requirements:
278
+ - - ">="
279
+ - !ruby/object:Gem::Version
280
+ version: '0'
281
+ - !ruby/object:Gem::Dependency
282
+ name: activesupport
283
+ requirement: !ruby/object:Gem::Requirement
284
+ requirements:
285
+ - - ">="
286
+ - !ruby/object:Gem::Version
287
+ version: '0'
288
+ type: :runtime
289
+ prerelease: false
290
+ version_requirements: !ruby/object:Gem::Requirement
291
+ requirements:
292
+ - - ">="
293
+ - !ruby/object:Gem::Version
294
+ version: '0'
253
295
  description:
254
296
  email:
255
297
  - jan@dalheimer.de
@@ -276,6 +318,8 @@ files:
276
318
  - lib/wonko_the_sane/rules.rb
277
319
  - lib/wonko_the_sane/timestamps.rb
278
320
  - lib/wonko_the_sane/tools/update_nem.rb
321
+ - lib/wonko_the_sane/util.rb
322
+ - lib/wonko_the_sane/util/benchmark.rb
279
323
  - lib/wonko_the_sane/util/configuration.rb
280
324
  - lib/wonko_the_sane/util/deep_storage_cache.rb
281
325
  - lib/wonko_the_sane/util/extraction_cache.rb
@@ -295,6 +339,7 @@ files:
295
339
  - lib/wonko_the_sane/versionlists/vanilla_legacy_version_list.rb
296
340
  - lib/wonko_the_sane/versionlists/vanilla_version_list.rb
297
341
  - lib/wonko_the_sane/wonko_version.rb
342
+ - lib/wonko_the_sane/wonkoweb_uploader.rb
298
343
  homepage: https://github.com/MultiMC/WonkoTheSane
299
344
  licenses:
300
345
  - MIT
@@ -321,4 +366,3 @@ specification_version: 4
321
366
  summary: Pre-processing and format-unification of various resources mainly related
322
367
  to Minecraft
323
368
  test_files: []
324
- has_rdoc: