git-fit 0.6.1 → 0.7.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.
- checksums.yaml +4 -4
- data/lib/git-fit.rb +10 -3
- data/lib/git_fit/cli/sync.rb +23 -34
- data/lib/git_fit/config.rb +9 -2
- data/lib/git_fit/config_template.rb +12 -0
- data/lib/git_fit/sync/base.rb +64 -1
- data/lib/git_fit/sync/garmin.rb +16 -0
- data/lib/git_fit/sync/garmin_base.rb +648 -0
- data/lib/git_fit/sync/garmin_base_di.rb +186 -0
- data/lib/git_fit/sync/garmin_cn.rb +29 -0
- data/lib/git_fit/sync/igpsport.rb +225 -0
- data/lib/git_fit/sync/keep.rb +499 -0
- data/lib/git_fit/sync/lorem.rb +1 -0
- data/lib/git_fit/sync/runner.rb +322 -0
- data/lib/git_fit/sync/strava.rb +187 -0
- data/lib/git_fit/sync/xingzhe.rb +262 -0
- data/lib/git_fit/sync/xoss.rb +369 -0
- data/lib/git_fit/version.rb +1 -1
- metadata +66 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 726e06c730a1309c59072df3f52e3261f5bf0e9d3b931e7a7016a8756c3190fa
|
|
4
|
+
data.tar.gz: 314a50f4b64054fe984e022421e464f22ae0a5469c9e7d369c5ef775ccdc0f14
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e36dcd8e78e57bbec0a451f1ce8d98fe4a3ab83dbbce334c0b528f08b5a2cc3d050a3b5da1092dbbc808d3afb6fb48b4d8052030f7d3301ac557027c97072d4
|
|
7
|
+
data.tar.gz: '00767969c5771dac29763dad5a65f4d1fd0c348ea127cfa36165dc46497000eb0db93ccff83aa13f5fc2c051d35ea618163ba1046e0abbb4c7cac315aac9f386'
|
data/lib/git-fit.rb
CHANGED
|
@@ -56,11 +56,18 @@ require_relative "git_fit/timezone/resolver"
|
|
|
56
56
|
require_relative "git_fit/privacy/polyline_filter"
|
|
57
57
|
require_relative "git_fit/import"
|
|
58
58
|
require_relative "git_fit/sync/base"
|
|
59
|
-
require_relative "git_fit/sync/strava"
|
|
60
59
|
require_relative "git_fit/util"
|
|
61
|
-
require_relative "git_fit/sync/base"
|
|
62
|
-
require_relative "git_fit/sync/strava"
|
|
63
60
|
require_relative "git_fit/sync/lorem"
|
|
61
|
+
require_relative "git_fit/sync/garmin_base"
|
|
62
|
+
require_relative "git_fit/sync/garmin_base_di"
|
|
63
|
+
require_relative "git_fit/sync/garmin"
|
|
64
|
+
require_relative "git_fit/sync/garmin_cn"
|
|
65
|
+
require_relative "git_fit/sync/strava"
|
|
66
|
+
require_relative "git_fit/sync/keep"
|
|
67
|
+
require_relative "git_fit/sync/igpsport"
|
|
68
|
+
require_relative "git_fit/sync/xoss"
|
|
69
|
+
require_relative "git_fit/sync/xingzhe"
|
|
70
|
+
require_relative "git_fit/sync/runner"
|
|
64
71
|
require_relative "git_fit/cli/sync"
|
|
65
72
|
require_relative "git_fit/db/rebuild"
|
|
66
73
|
require_relative "git_fit/db/connection"
|
data/lib/git_fit/cli/sync.rb
CHANGED
|
@@ -4,46 +4,35 @@ module GitFit
|
|
|
4
4
|
def sync
|
|
5
5
|
db = connect_db
|
|
6
6
|
source = options[:source]
|
|
7
|
-
unless source
|
|
8
|
-
say_status :error, "Use --source to specify a source (e.g. lorem)", :red
|
|
9
|
-
return
|
|
10
|
-
end
|
|
11
|
-
|
|
12
7
|
filter = options[:activity]&.flat_map { |v| v.split(",") }&.map(&:strip)&.map(&:downcase)
|
|
13
8
|
privacy = GitFit::Privacy::PolylineFilter.new(config: git_fit_config.privacy_config)
|
|
14
|
-
adapter = build_sync_adapter(source, db, filter, privacy: privacy)
|
|
15
|
-
unless adapter
|
|
16
|
-
say_status :error, "Unknown source: #{source}", :red
|
|
17
|
-
return
|
|
18
|
-
end
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if count > 0
|
|
23
|
-
say_status :done, "#{source}: #{count} activities synced", :green
|
|
10
|
+
sources = if source
|
|
11
|
+
[source]
|
|
24
12
|
else
|
|
25
|
-
|
|
13
|
+
configured = (git_fit_config["sync"] || {}).keys
|
|
14
|
+
builtin = GitFit::Sync::Base.adapters
|
|
15
|
+
.map { |c| c.config_key }
|
|
16
|
+
if ENV["GIT_FIT_ENVIRONMENT"] == "testing"
|
|
17
|
+
builtin += GitFit::Sync::Base.test_adapters
|
|
18
|
+
.map { |c| c.config_key }
|
|
19
|
+
end
|
|
20
|
+
(builtin + configured).uniq
|
|
26
21
|
end
|
|
27
|
-
rescue => e
|
|
28
|
-
say_status :error, "#{source}: #{e.message}", :red
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
23
|
+
runner = GitFit::Sync::Runner.new(
|
|
24
|
+
sources: sources,
|
|
25
|
+
db: db,
|
|
26
|
+
config: git_fit_config,
|
|
27
|
+
activity_filter: filter,
|
|
28
|
+
privacy: privacy,
|
|
29
|
+
num_workers: git_fit_config.dig("sync", "workers") || 3,
|
|
30
|
+
time_budget: git_fit_config.dig("sync", "time_budget"),
|
|
31
|
+
total_timeout: git_fit_config.dig("sync", "total_timeout")
|
|
32
|
+
)
|
|
33
|
+
runner.run
|
|
34
|
+
rescue => e
|
|
35
|
+
say_status :error, e.message, :red
|
|
47
36
|
end
|
|
48
37
|
end
|
|
49
38
|
end
|
data/lib/git_fit/config.rb
CHANGED
|
@@ -5,7 +5,11 @@ module GitFit
|
|
|
5
5
|
class Config
|
|
6
6
|
DEFAULTS = {
|
|
7
7
|
"database" => { "path" => "db/fit.sqlite3" },
|
|
8
|
-
"sync" => {
|
|
8
|
+
"sync" => {
|
|
9
|
+
"workers" => 3,
|
|
10
|
+
"time_budget" => nil,
|
|
11
|
+
"total_timeout" => nil
|
|
12
|
+
},
|
|
9
13
|
"export" => {
|
|
10
14
|
"json" => { "path" => "site/activities.json" },
|
|
11
15
|
"svg" => { "dir" => "site/svg" },
|
|
@@ -60,7 +64,10 @@ module GitFit
|
|
|
60
64
|
private
|
|
61
65
|
|
|
62
66
|
def load_env
|
|
63
|
-
@data["database"]["path"] = ENV["GIT_FIT_DATABASE_PATH"] if ENV["GIT_FIT_DATABASE_PATH"]
|
|
67
|
+
@data["database"]["path"] = ENV["GIT_FIT_DATABASE_PATH"] if ENV["GIT_FIT_DATABASE_PATH"] && !ENV["GIT_FIT_DATABASE_PATH"].empty?
|
|
68
|
+
@data["sync"]["workers"] = ENV["GIT_FIT_SYNC_WORKERS"].to_i if ENV["GIT_FIT_SYNC_WORKERS"] && !ENV["GIT_FIT_SYNC_WORKERS"].empty?
|
|
69
|
+
@data["sync"]["time_budget"] = ENV["GIT_FIT_SYNC_TIME_BUDGET"].to_f if ENV["GIT_FIT_SYNC_TIME_BUDGET"] && !ENV["GIT_FIT_SYNC_TIME_BUDGET"].empty?
|
|
70
|
+
@data["sync"]["total_timeout"] = ENV["GIT_FIT_SYNC_TOTAL_TIMEOUT"].to_f if ENV["GIT_FIT_SYNC_TOTAL_TIMEOUT"] && !ENV["GIT_FIT_SYNC_TOTAL_TIMEOUT"].empty?
|
|
64
71
|
|
|
65
72
|
GitFit.registered_configs.each do |reg|
|
|
66
73
|
reg[:keys].each do |key|
|
|
@@ -7,6 +7,10 @@ module GitFit
|
|
|
7
7
|
path: db/fit.sqlite3
|
|
8
8
|
|
|
9
9
|
sync:
|
|
10
|
+
# workers: 3 # env: GIT_FIT_SYNC_WORKERS
|
|
11
|
+
# time_budget: 300 # env: GIT_FIT_SYNC_TIME_BUDGET (seconds)
|
|
12
|
+
# total_timeout: 600 # env: GIT_FIT_SYNC_TOTAL_TIMEOUT (seconds)
|
|
13
|
+
|
|
10
14
|
# strava: # env: GIT_FIT_STRAVA_CLIENT_ID
|
|
11
15
|
# client_id: "" # env: GIT_FIT_STRAVA_CLIENT_SECRET
|
|
12
16
|
# refresh_token: "" # env: GIT_FIT_STRAVA_REFRESH_TOKEN
|
|
@@ -26,6 +30,14 @@ module GitFit
|
|
|
26
30
|
# lorem: # env: GIT_FIT_LOREM_COUNT
|
|
27
31
|
# count: 5
|
|
28
32
|
|
|
33
|
+
# xoss: # env: GIT_FIT_XOSS_PHONE
|
|
34
|
+
# phone: "" # env: GIT_FIT_XOSS_PASSWORD
|
|
35
|
+
# password: ""
|
|
36
|
+
|
|
37
|
+
# xingzhe: # env: GIT_FIT_XINGZHE_EMAIL
|
|
38
|
+
# email: "" # env: GIT_FIT_XINGZHE_PASSWORD
|
|
39
|
+
# password: ""
|
|
40
|
+
|
|
29
41
|
export:
|
|
30
42
|
json:
|
|
31
43
|
path: site/activities.json
|
data/lib/git_fit/sync/base.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "fileutils"
|
|
2
|
+
require "json"
|
|
2
3
|
require "time"
|
|
3
4
|
|
|
4
5
|
module GitFit
|
|
@@ -81,6 +82,32 @@ module GitFit
|
|
|
81
82
|
)
|
|
82
83
|
end
|
|
83
84
|
|
|
85
|
+
class << self
|
|
86
|
+
def adapters
|
|
87
|
+
@adapters ||= []
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_adapters
|
|
91
|
+
@test_adapters ||= []
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def register_adapter
|
|
95
|
+
Base.adapters << self unless Base.adapters.include?(self)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def register_test_adapter
|
|
99
|
+
Base.test_adapters << self unless Base.test_adapters.include?(self)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def config_key(source = nil)
|
|
103
|
+
if source
|
|
104
|
+
@config_key = source
|
|
105
|
+
else
|
|
106
|
+
@config_key ||= name.split("::").last.downcase
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
84
111
|
protected
|
|
85
112
|
|
|
86
113
|
def raw_dir
|
|
@@ -144,7 +171,11 @@ module GitFit
|
|
|
144
171
|
end
|
|
145
172
|
|
|
146
173
|
def raw_file_exists?(platform_id)
|
|
147
|
-
|
|
174
|
+
return false unless respond_to?(:raw_path, true)
|
|
175
|
+
path = raw_path(platform_id)
|
|
176
|
+
File.exist?(path)
|
|
177
|
+
rescue NotImplementedError
|
|
178
|
+
false
|
|
148
179
|
end
|
|
149
180
|
|
|
150
181
|
def show_progress?(count, total)
|
|
@@ -158,6 +189,38 @@ module GitFit
|
|
|
158
189
|
return 1 unless total && total > 0
|
|
159
190
|
[1, (1.5 * (total ** 0.4)).to_i].max
|
|
160
191
|
end
|
|
192
|
+
|
|
193
|
+
def raw_path(platform_id)
|
|
194
|
+
raise NotImplementedError, "#{self.class} must implement #raw_path"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def write_source_archive(data, platform_id, ext = "json")
|
|
198
|
+
dir = raw_dir
|
|
199
|
+
FileUtils.mkdir_p(dir)
|
|
200
|
+
tmp = File.join(dir, ".#{platform_id}.#{ext}.tmp")
|
|
201
|
+
dest = File.join(dir, "#{platform_id}.#{ext}")
|
|
202
|
+
case data
|
|
203
|
+
when String then File.write(tmp, data)
|
|
204
|
+
when Hash, Array then File.write(tmp, JSON.generate(data))
|
|
205
|
+
end
|
|
206
|
+
File.rename(tmp, dest)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def write_standardized_json(attrs, platform_id)
|
|
210
|
+
dir = std_dir
|
|
211
|
+
FileUtils.mkdir_p(dir)
|
|
212
|
+
tmp = File.join(dir, ".#{platform_id}.json.tmp")
|
|
213
|
+
dest = File.join(dir, "#{platform_id}.json")
|
|
214
|
+
File.write(tmp, JSON.generate(attrs.transform_keys(&:to_s)))
|
|
215
|
+
File.rename(tmp, dest)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def existing_run_ids
|
|
219
|
+
prefix = "#{self.class.config_key}_"
|
|
220
|
+
@db[:activities].where(Sequel.like(:run_id, "#{prefix}%"))
|
|
221
|
+
.select_map(:run_id)
|
|
222
|
+
.map { |rid| rid.sub(/\A#{Regexp.escape(prefix)}/, "") }
|
|
223
|
+
end
|
|
161
224
|
end
|
|
162
225
|
end
|
|
163
226
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative "garmin_base_di"
|
|
2
|
+
|
|
3
|
+
module GitFit
|
|
4
|
+
module Sync
|
|
5
|
+
class Garmin < GarminBaseDI
|
|
6
|
+
register_adapter
|
|
7
|
+
register_config :email, :password, :secret, :auth_seed
|
|
8
|
+
config_key "garmin"
|
|
9
|
+
|
|
10
|
+
def initialize(config:, db:, activity_filter: nil, privacy: nil, time_budget: nil)
|
|
11
|
+
super
|
|
12
|
+
@domain = "garmin.com"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|