flox 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -0
  3. data/bin/flox +94 -14
  4. data/lib/flox/version.rb +1 -1
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b43c6043976e6f113bd8f1882c82ca6f106385b7279dbff99ea87e7eec3059ef
4
- data.tar.gz: 9166d78906c48085337b996fbf73f554a7aee8912d20d5e18e5b247ad13f463d
3
+ metadata.gz: f366e3d238defdbc4a7d2c94613eaed5a0877eaaad1aba8afa56392ff75caf25
4
+ data.tar.gz: ef61dd08c7dc87f040557fcef8d3b00e603311516b6c6cd58f461763c692629a
5
5
  SHA512:
6
- metadata.gz: 3edae31aac538f8ff71ac335cbc75b2393a2620c1c98aa63736634c62a5e815aff98be75f6b6df20898ab7356a119aab80e02b0b4c16708fb8bf985f4bb112e8
7
- data.tar.gz: 0a34f6e3de1631f64ba71a3f2c9100ffe9c51bce75611378f1f8fa66f6a51658e93c40325e04542fb4502d63964b7db5e824b87fc1ac07360b783d66b6c4ade6
6
+ metadata.gz: 24da9b6e59adf749c515f71bfec553bcbf42975a159e8fab4fbedb95ee82950941325d6376dc6f6ae0d5a07252684413df428bd667668a67c1cbc0777f5ee166
7
+ data.tar.gz: cbaa7a929062f4d35c05e99215a0cb783c674aef3b94b8d133a87e9edef527987be27b7a9ae11138261f2c350c567f3f78d0f1fcc5021cd1542868e7dab6ffa9
data/README.md CHANGED
@@ -33,6 +33,12 @@ As an example, here's how to download all the log files of a certain day that ha
33
33
 
34
34
  Note that you need to authorize with a "Hero" key. A hero is a special Flox player that has super-user rights; create it in the Flox online interface.
35
35
 
36
+ You can use that same key to export all the entities of a specific type. Like this:
37
+
38
+ flox export_entities --game_id="id" --game_key="key" --hero_key="key" --type="Player"
39
+
40
+ This will download JSON files with all player data into a subfolder of the working directory. Beware: you will need to add an index for the "updatedAt" property to this entity type first (which is done in the online interface, as well). This makes it possible that repeating the same export will only download new and changed files.
41
+
36
42
  ## How to use the Flox SDK
37
43
 
38
44
  The Ruby client is designed to be used not in games, but in scripts that help you operate your games. You can use it e.g. to automatically download your leaderboards or certain entities for backup. It's also easy to utilize Flox via 'irb', allowing quick introspection into your server data.
data/bin/flox CHANGED
@@ -4,18 +4,16 @@
4
4
  ## Copyright: Copyright 2014 Gamua
5
5
  ## License: Simplified BSD
6
6
 
7
- require 'flox'
8
- require 'fileutils'
9
- require 'slop'
10
-
11
- # Helper class that does the heavy lifting.
12
- class Worker
7
+ require "flox"
8
+ require "fileutils"
9
+ require "slop"
13
10
 
11
+ class LogExporter
14
12
  attr_reader :flox
15
13
 
16
- def initialize(args={})
14
+ def initialize(args = {})
17
15
  base_url = args[:url] || Flox::DEFAULT_URL
18
- game_id = args[:game_id]
16
+ game_id = args[:game_id]
19
17
  game_key = args[:game_key]
20
18
  hero_key = args[:hero_key]
21
19
 
@@ -25,7 +23,7 @@ class Worker
25
23
  puts "done."
26
24
  end
27
25
 
28
- def load_logs(args={})
26
+ def run(args = {})
29
27
  query = args[:query]
30
28
  limit = args[:limit]
31
29
  destination = args[:destination] || Dir.pwd
@@ -52,7 +50,82 @@ class Worker
52
50
  puts("Saved #{local_path}")
53
51
  end
54
52
  end
53
+ end
54
+
55
+ class EntityExporter
56
+ def run(args = {})
57
+ base_url = args[:url] || Flox::DEFAULT_URL
58
+ game_id = args[:game_id]
59
+ game_key = args[:game_key]
60
+ hero_key = args[:hero_key]
61
+ entity_type = args[:type]
62
+
63
+ puts("Exporting entities of type '#{entity_type}'. Beware, this will take a while!")
64
+ puts(" -> Precondition: the entity MUST have an index on the property 'updatedAt'!")
65
+ puts(" -> If you stop and restart, the exporter will continue where it left off.")
66
+ puts(" -> Running the exporter again will download only the changed / new entities.")
67
+ print("Progress: ")
68
+
69
+ batch_size = 10
70
+ num_threads = 4
71
+ out_folder = "export/#{entity_type}"
72
+ FileUtils.mkdir_p out_folder
73
+
74
+ status_file = "#{out_folder}/_export_status.json"
75
+ start_index = File.exist?(status_file) ?
76
+ JSON.parse(IO.read(status_file))["index"].to_i : 0
77
+
78
+ thread_state = [start_index] * num_threads
79
+ signal_queue = Queue.new
80
+
81
+ threads = (0...num_threads).map do |thread_index|
82
+ Thread.new do
83
+ flox = Flox.new(game_id, game_key, base_url)
84
+ flox.login_with_key(hero_key)
85
+
86
+ query = Flox::Query.new(entity_type)
87
+ query.order_by = "updatedAt ASC"
88
+ query.limit = batch_size
89
+ query.offset = start_index + thread_index * batch_size
90
+ sleep thread_index
91
+
92
+ loop do
93
+ begin
94
+ signal_queue << { :thread_index => thread_index,
95
+ :result_index => query.offset }
96
+ results = flox.find_entities(query)
97
+ break if results.count == 0
98
+ results.each do |player|
99
+ IO.write("#{out_folder}/#{player.id}.json", player.to_json)
100
+ end
101
+ rescue StandardError => e
102
+ print "\nError: #{e.message}"
103
+ if e.message.include? "index is missing"
104
+ abort("\n")
105
+ else
106
+ puts " - retrying."
107
+ end
108
+ else
109
+ query.offset += batch_size * num_threads
110
+ print "."
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ signal_thread = Thread.new do
117
+ while thread_signal = signal_queue.pop
118
+ thread_state[thread_signal[:thread_index]] = thread_signal[:result_index]
119
+ smallest_index = thread_state.min
120
+ IO.write(status_file, { :index => smallest_index }.to_json)
121
+ end
122
+ end
55
123
 
124
+ threads.each { |thr| thr.join }
125
+ signal_queue.close
126
+
127
+ puts "\nExport completed!"
128
+ end
56
129
  end
57
130
 
58
131
  #
@@ -67,11 +140,9 @@ def shared_options
67
140
  end
68
141
 
69
142
  begin
70
-
71
143
  ARGV << "-h" if ARGV.empty?
72
144
  Slop.parse(ARGV, :help => true) do
73
-
74
- on :v, "version", 'Print the current version of the Flox Gem.' do
145
+ on :v, "version", "Print the current version of the Flox Gem." do
75
146
  puts "Gamua Flox v#{Flox::VERSION}"
76
147
  end
77
148
 
@@ -84,12 +155,21 @@ begin
84
155
  on :l, "limit=", "Maximum number of logs to download", as: Integer
85
156
 
86
157
  run do |opts, args|
87
- Worker.new(opts).load_logs(opts)
158
+ LogExporter.new(opts).run(opts)
88
159
  end
89
160
  end
90
161
 
91
- end
162
+ command "export_entities" do
163
+ description "Fetch all entitites of a specific type from the server."
92
164
 
165
+ shared_options
166
+ on :d, "type=", "The entity type", :required => true
167
+
168
+ run do |opts, args|
169
+ EntityExporter.new.run(opts)
170
+ end
171
+ end
172
+ end
93
173
  rescue Slop::Error, Flox::Error => error
94
174
  puts error
95
175
  end
@@ -9,6 +9,6 @@
9
9
  class Flox
10
10
 
11
11
  # The current version of the Flox SDK.
12
- VERSION = '0.3.0'
12
+ VERSION = '0.4.0'
13
13
 
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sperl