ixtlan-remote 0.1.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.
- data/Gemfile +2 -0
- data/README.md +64 -0
- data/agpl-3.0.txt +661 -0
- data/lib/ixtlan-remote.rb +23 -0
- data/lib/ixtlan/passwords.rb +52 -0
- data/lib/ixtlan/passwords.rb~ +47 -0
- data/lib/ixtlan/railtie.rb~ +17 -0
- data/lib/ixtlan/remote.rb +23 -0
- data/lib/ixtlan/remote/access_controller.rb +62 -0
- data/lib/ixtlan/remote/access_controller.rb~ +25 -0
- data/lib/ixtlan/remote/constant_time_compare.rb +39 -0
- data/lib/ixtlan/remote/constant_time_compare.rb~ +19 -0
- data/lib/ixtlan/remote/heartbeat.rb~ +80 -0
- data/lib/ixtlan/remote/model_conversion.rb~ +245 -0
- data/lib/ixtlan/remote/model_helpers.rb +73 -0
- data/lib/ixtlan/remote/model_helpers.rb~ +53 -0
- data/lib/ixtlan/remote/permission.rb +40 -0
- data/lib/ixtlan/remote/permission.rb~ +19 -0
- data/lib/ixtlan/remote/railtie.rb +30 -0
- data/lib/ixtlan/remote/railtie.rb~ +9 -0
- data/lib/ixtlan/remote/remote_access_controller.rb~ +25 -0
- data/lib/ixtlan/remote/remote_permisson.rb~ +9 -0
- data/lib/ixtlan/remote/resource.rb +145 -0
- data/lib/ixtlan/remote/resource.rb-~ +165 -0
- data/lib/ixtlan/remote/resource.rb~ +152 -0
- data/lib/ixtlan/remote/rest.rb +108 -0
- data/lib/ixtlan/remote/rest.rb~ +83 -0
- data/lib/ixtlan/remote/rest_resource.rb~ +140 -0
- data/lib/ixtlan/remote/rest_resource_config.rb~ +63 -0
- data/lib/ixtlan/remote/rest_resource_factory.rb~ +259 -0
- data/lib/ixtlan/remote/rest_resource_old.rb-~ +259 -0
- data/lib/ixtlan/remote/server.rb +119 -0
- data/lib/ixtlan/remote/server.rb~ +82 -0
- data/lib/ixtlan/remote/summary.rb +46 -0
- data/lib/ixtlan/remote/summary.rb~ +23 -0
- data/lib/ixtlan/remote/sync.rb +104 -0
- data/lib/ixtlan/remote/sync.rb~ +78 -0
- data/lib/ixtlan/remote/sync_summary.rb~ +23 -0
- data/lib/ixtlan/remote/tranlation_key.rb~ +7 -0
- data/lib/ixtlan/remote/translation.rake~ +194 -0
- data/lib/ixtlan/remote/translation_models.rb~ +11 -0
- data/lib/ixtlan/remote/updater.rb~ +71 -0
- data/lib/ixtlan/user_management/application_model.rb +30 -0
- data/lib/ixtlan/user_management/application_model.rb~ +21 -0
- data/lib/ixtlan/user_management/application_resource.rb +48 -0
- data/lib/ixtlan/user_management/application_resource.rb~ +21 -0
- data/lib/ixtlan/user_management/authentcator.rb~ +31 -0
- data/lib/ixtlan/user_management/authentication_model.rb +31 -0
- data/lib/ixtlan/user_management/authentication_model.rb~ +21 -0
- data/lib/ixtlan/user_management/authenticator.rb +55 -0
- data/lib/ixtlan/user_management/authenticator.rb~ +20 -0
- data/lib/ixtlan/user_management/domain_resource.rb +48 -0
- data/lib/ixtlan/user_management/domain_resource.rb~ +21 -0
- data/lib/ixtlan/user_management/dummy_authentication.rb +50 -0
- data/lib/ixtlan/user_management/dummy_authentication.rb~ +49 -0
- data/lib/ixtlan/user_management/group.rb~ +39 -0
- data/lib/ixtlan/user_management/group_model.rb +31 -0
- data/lib/ixtlan/user_management/group_model.rb~ +21 -0
- data/lib/ixtlan/user_management/models.rb~ +39 -0
- data/lib/ixtlan/user_management/session-serializer.rb~ +18 -0
- data/lib/ixtlan/user_management/session_cuba.rb +47 -0
- data/lib/ixtlan/user_management/session_cuba.rb~ +44 -0
- data/lib/ixtlan/user_management/session_manager.rb +38 -0
- data/lib/ixtlan/user_management/session_model.rb +36 -0
- data/lib/ixtlan/user_management/session_model.rb~ +10 -0
- data/lib/ixtlan/user_management/session_plugin.rb +32 -0
- data/lib/ixtlan/user_management/session_serializer.rb +21 -0
- data/lib/ixtlan/user_management/session_serializer.rb~ +21 -0
- data/lib/ixtlan/user_management/user.rb~ +16 -0
- data/lib/ixtlan/user_management/user_model.rb +36 -0
- data/lib/ixtlan/user_management/user_model.rb~ +33 -0
- data/lib/ixtlan/user_management/user_resource.rb +55 -0
- data/lib/ixtlan/user_management/user_resource.rb~ +24 -0
- data/lib/ixtlan/user_management/user_serializer.rb +15 -0
- data/lib/ixtlan/user_management/user_serializer.rb~ +23 -0
- data/spec/access_controller_spec.rb +65 -0
- data/spec/access_controller_spec.rb~ +65 -0
- data/spec/model_helpers_spec.rb +40 -0
- data/spec/model_helpers_spec.rb~ +36 -0
- data/spec/remote_access_controller_spec.rb~ +36 -0
- data/spec/resource_spec.rb +181 -0
- data/spec/resource_spec.rb~ +173 -0
- data/spec/rest_resource_spec.rb~ +173 -0
- data/spec/rest_spec.rb +94 -0
- data/spec/rest_spec.rb~ +99 -0
- data/spec/rest_with_attribute_name_like_model_name_spec.rb +82 -0
- data/spec/sync_spec.rb +83 -0
- data/spec/sync_spec.rb~ +81 -0
- metadata +313 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ixtlan-remote - helper sync data between miniapps or communicate wth realtime
|
|
3
|
+
# rest-services
|
|
4
|
+
# Copyright (C) 2012 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# This file is part of ixtlan-remote.
|
|
7
|
+
#
|
|
8
|
+
# ixtlan-remote is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# ixtlan-remote is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Affero General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
# along with ixtlan-remote. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
require 'rest-client'
|
|
22
|
+
require 'ixtlan/remote/resource'
|
|
23
|
+
module RestClient
|
|
24
|
+
class Resource
|
|
25
|
+
# allow payload on delete - breaks code using original method !!!!
|
|
26
|
+
def delete(payload = nil, additional_headers={}, &block)
|
|
27
|
+
headers = (options[:headers] || {}).merge(additional_headers)
|
|
28
|
+
opts = options.merge( :method => :delete,
|
|
29
|
+
:url => url,
|
|
30
|
+
:headers => headers )
|
|
31
|
+
if payload
|
|
32
|
+
opts[:payload] = payload
|
|
33
|
+
end
|
|
34
|
+
Request.execute( opts, &(block || @block))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
module Ixtlan
|
|
40
|
+
module Remote
|
|
41
|
+
class Server
|
|
42
|
+
|
|
43
|
+
attr_accessor :url
|
|
44
|
+
|
|
45
|
+
def initialize( factory )
|
|
46
|
+
@factory = factory
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def options
|
|
50
|
+
@options ||= {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def map
|
|
54
|
+
@map ||= {}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def models
|
|
58
|
+
map.keys
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class Meta
|
|
62
|
+
|
|
63
|
+
attr_reader :path, :new_method
|
|
64
|
+
|
|
65
|
+
def initialize( new_method, path = nil )
|
|
66
|
+
@new_method = new_method
|
|
67
|
+
@path = path.to_s if path
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
NEW_METHOD = Proc.new do | model, attributes |
|
|
72
|
+
cond = {}
|
|
73
|
+
model.key.each { |k| cond[ k.name ] = attributes[ k.name.to_s ] }
|
|
74
|
+
m = model.first_or_new( cond )
|
|
75
|
+
m.attributes = attributes
|
|
76
|
+
m
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def new_method_dm( clazz )
|
|
80
|
+
if clazz.respond_to?( :key ) && clazz.key.kind_of?( DataMapper::PropertySet )
|
|
81
|
+
Proc.new { |a| NEW_METHOD.call( clazz, a ) }
|
|
82
|
+
else
|
|
83
|
+
clazz.method( :new )
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def new_method(clazz)
|
|
88
|
+
if defined? DataMapper
|
|
89
|
+
new_method_dm(clazz)
|
|
90
|
+
else
|
|
91
|
+
warn "TODO need better implementation for ActiveRecord in #{__FILE__} #{__LINE__}"
|
|
92
|
+
|
|
93
|
+
clazz.method( :new )
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def add_model( clazz, path = nil )
|
|
98
|
+
@factory[ clazz ] = self
|
|
99
|
+
m = map[ clazz ] = Meta.new( new_method( clazz ),
|
|
100
|
+
(path || clazz.to_s.underscore.pluralize ) )
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def keys( clazz )
|
|
104
|
+
# TODO
|
|
105
|
+
if clazz.respond_to?( :key )
|
|
106
|
+
clazz.key.first
|
|
107
|
+
else
|
|
108
|
+
clazz.id
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def new_rest_resource( clazz )
|
|
113
|
+
client = RestClient::Resource.new( @url, options )
|
|
114
|
+
meta = map[ clazz ]
|
|
115
|
+
Resource.new( client[ meta.path ], clazz, meta.new_method )
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'rest-client'
|
|
2
|
+
module Ixtlan
|
|
3
|
+
module Remote
|
|
4
|
+
class Server
|
|
5
|
+
|
|
6
|
+
attr_accessor :url
|
|
7
|
+
|
|
8
|
+
def initialize( factory )
|
|
9
|
+
@factory = factory
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def options
|
|
13
|
+
@options ||= {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def map
|
|
17
|
+
@map ||= {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Meta
|
|
21
|
+
|
|
22
|
+
attr_reader :path
|
|
23
|
+
|
|
24
|
+
def initialize( path, new_method )
|
|
25
|
+
@new = new_method
|
|
26
|
+
@path = path.to_s if path
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def singular
|
|
30
|
+
@path.singularize if @path
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def new( attributes )
|
|
34
|
+
@new.call( attributes )
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if defined? DataMapper
|
|
39
|
+
|
|
40
|
+
NEW_METHOD = Proc.new do | model, attributes |
|
|
41
|
+
cond = {}
|
|
42
|
+
model.key.each { |k| cond[ k.name ] = attributes[ k.name.to_s ] }
|
|
43
|
+
m = model.first_or_new( cond )
|
|
44
|
+
m.attributes = attributes
|
|
45
|
+
m
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def new_method( clazz )
|
|
49
|
+
#if clazz.include? ::DataMapper::Resource
|
|
50
|
+
if clazz.respond_to?( :key ) && clazz.key.kind_of?( DataMapper::PropertySet )
|
|
51
|
+
Proc.new { |a| NEW_METHOD.call( clazz, a ) }
|
|
52
|
+
else
|
|
53
|
+
clazz.method( :new )
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
raise "need implementation"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def add_model( clazz, &block )
|
|
62
|
+
@factory[ clazz ] = self
|
|
63
|
+
m = map[ clazz ] = Meta.new( path = clazz.to_s.underscore.pluralize,
|
|
64
|
+
new_method( clazz ) )
|
|
65
|
+
block.call m if block
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def keys( clazz )
|
|
69
|
+
if clazz.respond_to?( :key )
|
|
70
|
+
clazz.key
|
|
71
|
+
else
|
|
72
|
+
# TODO
|
|
73
|
+
clazz.id
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def new_rest_resource
|
|
78
|
+
Resource.new( RestClient::Resource.new( @url, options ), map )
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ixtlan-remote - helper sync data between miniapps or communicate wth realtime
|
|
3
|
+
# rest-services
|
|
4
|
+
# Copyright (C) 2012 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# This file is part of ixtlan-remote.
|
|
7
|
+
#
|
|
8
|
+
# ixtlan-remote is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# ixtlan-remote is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Affero General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
# along with ixtlan-remote. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
module Ixtlan
|
|
22
|
+
module Remote
|
|
23
|
+
class Summary
|
|
24
|
+
|
|
25
|
+
attr_reader :failures, :count
|
|
26
|
+
|
|
27
|
+
def initialize(clazz)
|
|
28
|
+
@count = 0
|
|
29
|
+
@failures = []
|
|
30
|
+
@clazz = clazz
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def inc_count
|
|
34
|
+
@count += 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def inc_failures(errors)
|
|
38
|
+
@failures << errors.inspect
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_log
|
|
42
|
+
"update #{@clazz} - total: #{@count + @failures.size} success: #{@count} failures: #{@failures.size == 0 ? 0 : @failures.join("\n\t\t")}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Ixtlan::Remote::Sync
|
|
2
|
+
|
|
3
|
+
class Summary
|
|
4
|
+
|
|
5
|
+
def initialize(clazz)
|
|
6
|
+
@count = 0
|
|
7
|
+
@failures = 0
|
|
8
|
+
@clazz = clazz
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inc_count
|
|
12
|
+
@count += 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def inc_failures
|
|
16
|
+
@falures += 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_log
|
|
20
|
+
"update #{@clazz} - total: #{@count + @failures} success: #{@count} failures: #{@failures}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ixtlan-remote - helper sync data between miniapps or communicate wth realtime
|
|
3
|
+
# rest-services
|
|
4
|
+
# Copyright (C) 2012 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# This file is part of ixtlan-remote.
|
|
7
|
+
#
|
|
8
|
+
# ixtlan-remote is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# ixtlan-remote is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Affero General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
# along with ixtlan-remote. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
require 'ixtlan/remote/summary'
|
|
22
|
+
require 'active_support/all'
|
|
23
|
+
|
|
24
|
+
module Ixtlan
|
|
25
|
+
module Remote
|
|
26
|
+
class Sync
|
|
27
|
+
|
|
28
|
+
SECONDS_IN_DAY = 60 * 60 * 24
|
|
29
|
+
NANOSECONDS_IN_DAY = SECONDS_IN_DAY * 1000 * 1000 * 1000
|
|
30
|
+
def initialize(restserver)
|
|
31
|
+
@restserver = restserver
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def clazzes
|
|
35
|
+
@clazzes ||= {}
|
|
36
|
+
end
|
|
37
|
+
private :clazzes
|
|
38
|
+
|
|
39
|
+
def register(clazz, &block)
|
|
40
|
+
clazzes[clazz] = block unless clazzes.key?(clazz)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# max method ORM dependent
|
|
44
|
+
if defined? ActiveRecord
|
|
45
|
+
def max(clazz)
|
|
46
|
+
(clazz.maximum(:updated_at) || DateTime.new(0)).to_datetime
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
def max(clazz)
|
|
50
|
+
clazz.max(:updated_at)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
private :max
|
|
54
|
+
|
|
55
|
+
# UTC timestamp of last updated record
|
|
56
|
+
def last_update( clazz )
|
|
57
|
+
last_date = ( max( clazz ) || DateTime.new( 0 ) )
|
|
58
|
+
last_date.strftime( '%Y-%m-%d %H:%M:%S.' ) + ( "%06d" % ( last_date.sec_fraction / NANOSECONDS_IN_DAY / 1000 ) ) + "+0:00"
|
|
59
|
+
end
|
|
60
|
+
private :last_update
|
|
61
|
+
|
|
62
|
+
def self.do_it( clazz = nil )
|
|
63
|
+
if clazz
|
|
64
|
+
new.do_it( clazz )
|
|
65
|
+
else
|
|
66
|
+
new.do_it
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# load the last changed records
|
|
71
|
+
def do_it(set = clazzes.keys)
|
|
72
|
+
@last_result = []
|
|
73
|
+
set = [set] unless set.is_a? Array
|
|
74
|
+
# use only regstered classes !!
|
|
75
|
+
set = set - (set - clazzes.keys)
|
|
76
|
+
set.to_a.each do |clazz|
|
|
77
|
+
summary = Summary.new(clazz)
|
|
78
|
+
@last_result << summary
|
|
79
|
+
@restserver.retrieve(clazz,
|
|
80
|
+
:last_changes,
|
|
81
|
+
:updated_at => last_update(clazz)).each do |item|
|
|
82
|
+
if item.save
|
|
83
|
+
summary.inc_count
|
|
84
|
+
else
|
|
85
|
+
summary.inc_failures(item.errors)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
b = clazzes[clazz]
|
|
89
|
+
b.call summary if b
|
|
90
|
+
end
|
|
91
|
+
to_log
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def to_log
|
|
95
|
+
if @last_result
|
|
96
|
+
@last_result.collect { |r| r.to_log }.join("\n\t")
|
|
97
|
+
else
|
|
98
|
+
"no results yet"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
alias :to_s :to_log
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'ixtlan/remote/summary'
|
|
2
|
+
require 'active_support/all'
|
|
3
|
+
|
|
4
|
+
class Ixtlan::Remote::Sync
|
|
5
|
+
|
|
6
|
+
SECONDS_IN_DAY = 60 * 60 * 24
|
|
7
|
+
NANOSECONDS_IN_DAY = SECONDS_IN_DAY * 1000 * 1000 * 1000
|
|
8
|
+
def initialize(restserver)
|
|
9
|
+
@restserver = restserver
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def clazzes
|
|
13
|
+
@clazzes ||= {}
|
|
14
|
+
end
|
|
15
|
+
private :clazzes
|
|
16
|
+
|
|
17
|
+
def register(clazz, &block)
|
|
18
|
+
clazzes[clazz] = block unless clazzes.key?(clazz)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# max method ORM dependent
|
|
22
|
+
if defined? ActiveRecord
|
|
23
|
+
def max(clazz)
|
|
24
|
+
clazz.maximum(:updated_at)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
def max(clazz)
|
|
28
|
+
clazz.max(:updated_at)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
private :max
|
|
32
|
+
|
|
33
|
+
# UTC timestamp of last updated record
|
|
34
|
+
def last_update(clazz)
|
|
35
|
+
last_date = ( max(clazz) || DateTime.new( 0 ) ) + 1# + SECONDS_IN_DAY
|
|
36
|
+
last_date.strftime('%Y-%m-%d %H:%M:%S.') + ("%06d" % (last_date.sec_fraction / NANOSECONDS_IN_DAY / 1000)) + "+0:00"
|
|
37
|
+
end
|
|
38
|
+
private :last_update
|
|
39
|
+
|
|
40
|
+
def self.do_it(clazz = nil)
|
|
41
|
+
if clazz
|
|
42
|
+
new.do_it(clazz)
|
|
43
|
+
else
|
|
44
|
+
new.do_it
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# load the last changed records
|
|
49
|
+
def do_it(set = clazzes.keys)
|
|
50
|
+
@last_result = []
|
|
51
|
+
set = [set] unless set.is_a? Array
|
|
52
|
+
set.to_a.each do |clazz|
|
|
53
|
+
summary = Summary.new(clazz)
|
|
54
|
+
@last_result << summary
|
|
55
|
+
@restserver.retrieve(clazz,
|
|
56
|
+
:last_changes,
|
|
57
|
+
:updated_at => last_update(clazz)).each do |item|
|
|
58
|
+
if item.save
|
|
59
|
+
summary.inc_count
|
|
60
|
+
else
|
|
61
|
+
summary.inc_failures
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
b = clazzes[clazz]
|
|
65
|
+
b.call summary if b
|
|
66
|
+
end
|
|
67
|
+
to_log
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def to_log
|
|
71
|
+
if @last_result
|
|
72
|
+
@last_result.collect { |r| r.to_log }.join("\n\t")
|
|
73
|
+
else
|
|
74
|
+
"no results yet"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
alias :to_s :to_log
|
|
78
|
+
end
|