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.
Files changed (89) hide show
  1. data/Gemfile +2 -0
  2. data/README.md +64 -0
  3. data/agpl-3.0.txt +661 -0
  4. data/lib/ixtlan-remote.rb +23 -0
  5. data/lib/ixtlan/passwords.rb +52 -0
  6. data/lib/ixtlan/passwords.rb~ +47 -0
  7. data/lib/ixtlan/railtie.rb~ +17 -0
  8. data/lib/ixtlan/remote.rb +23 -0
  9. data/lib/ixtlan/remote/access_controller.rb +62 -0
  10. data/lib/ixtlan/remote/access_controller.rb~ +25 -0
  11. data/lib/ixtlan/remote/constant_time_compare.rb +39 -0
  12. data/lib/ixtlan/remote/constant_time_compare.rb~ +19 -0
  13. data/lib/ixtlan/remote/heartbeat.rb~ +80 -0
  14. data/lib/ixtlan/remote/model_conversion.rb~ +245 -0
  15. data/lib/ixtlan/remote/model_helpers.rb +73 -0
  16. data/lib/ixtlan/remote/model_helpers.rb~ +53 -0
  17. data/lib/ixtlan/remote/permission.rb +40 -0
  18. data/lib/ixtlan/remote/permission.rb~ +19 -0
  19. data/lib/ixtlan/remote/railtie.rb +30 -0
  20. data/lib/ixtlan/remote/railtie.rb~ +9 -0
  21. data/lib/ixtlan/remote/remote_access_controller.rb~ +25 -0
  22. data/lib/ixtlan/remote/remote_permisson.rb~ +9 -0
  23. data/lib/ixtlan/remote/resource.rb +145 -0
  24. data/lib/ixtlan/remote/resource.rb-~ +165 -0
  25. data/lib/ixtlan/remote/resource.rb~ +152 -0
  26. data/lib/ixtlan/remote/rest.rb +108 -0
  27. data/lib/ixtlan/remote/rest.rb~ +83 -0
  28. data/lib/ixtlan/remote/rest_resource.rb~ +140 -0
  29. data/lib/ixtlan/remote/rest_resource_config.rb~ +63 -0
  30. data/lib/ixtlan/remote/rest_resource_factory.rb~ +259 -0
  31. data/lib/ixtlan/remote/rest_resource_old.rb-~ +259 -0
  32. data/lib/ixtlan/remote/server.rb +119 -0
  33. data/lib/ixtlan/remote/server.rb~ +82 -0
  34. data/lib/ixtlan/remote/summary.rb +46 -0
  35. data/lib/ixtlan/remote/summary.rb~ +23 -0
  36. data/lib/ixtlan/remote/sync.rb +104 -0
  37. data/lib/ixtlan/remote/sync.rb~ +78 -0
  38. data/lib/ixtlan/remote/sync_summary.rb~ +23 -0
  39. data/lib/ixtlan/remote/tranlation_key.rb~ +7 -0
  40. data/lib/ixtlan/remote/translation.rake~ +194 -0
  41. data/lib/ixtlan/remote/translation_models.rb~ +11 -0
  42. data/lib/ixtlan/remote/updater.rb~ +71 -0
  43. data/lib/ixtlan/user_management/application_model.rb +30 -0
  44. data/lib/ixtlan/user_management/application_model.rb~ +21 -0
  45. data/lib/ixtlan/user_management/application_resource.rb +48 -0
  46. data/lib/ixtlan/user_management/application_resource.rb~ +21 -0
  47. data/lib/ixtlan/user_management/authentcator.rb~ +31 -0
  48. data/lib/ixtlan/user_management/authentication_model.rb +31 -0
  49. data/lib/ixtlan/user_management/authentication_model.rb~ +21 -0
  50. data/lib/ixtlan/user_management/authenticator.rb +55 -0
  51. data/lib/ixtlan/user_management/authenticator.rb~ +20 -0
  52. data/lib/ixtlan/user_management/domain_resource.rb +48 -0
  53. data/lib/ixtlan/user_management/domain_resource.rb~ +21 -0
  54. data/lib/ixtlan/user_management/dummy_authentication.rb +50 -0
  55. data/lib/ixtlan/user_management/dummy_authentication.rb~ +49 -0
  56. data/lib/ixtlan/user_management/group.rb~ +39 -0
  57. data/lib/ixtlan/user_management/group_model.rb +31 -0
  58. data/lib/ixtlan/user_management/group_model.rb~ +21 -0
  59. data/lib/ixtlan/user_management/models.rb~ +39 -0
  60. data/lib/ixtlan/user_management/session-serializer.rb~ +18 -0
  61. data/lib/ixtlan/user_management/session_cuba.rb +47 -0
  62. data/lib/ixtlan/user_management/session_cuba.rb~ +44 -0
  63. data/lib/ixtlan/user_management/session_manager.rb +38 -0
  64. data/lib/ixtlan/user_management/session_model.rb +36 -0
  65. data/lib/ixtlan/user_management/session_model.rb~ +10 -0
  66. data/lib/ixtlan/user_management/session_plugin.rb +32 -0
  67. data/lib/ixtlan/user_management/session_serializer.rb +21 -0
  68. data/lib/ixtlan/user_management/session_serializer.rb~ +21 -0
  69. data/lib/ixtlan/user_management/user.rb~ +16 -0
  70. data/lib/ixtlan/user_management/user_model.rb +36 -0
  71. data/lib/ixtlan/user_management/user_model.rb~ +33 -0
  72. data/lib/ixtlan/user_management/user_resource.rb +55 -0
  73. data/lib/ixtlan/user_management/user_resource.rb~ +24 -0
  74. data/lib/ixtlan/user_management/user_serializer.rb +15 -0
  75. data/lib/ixtlan/user_management/user_serializer.rb~ +23 -0
  76. data/spec/access_controller_spec.rb +65 -0
  77. data/spec/access_controller_spec.rb~ +65 -0
  78. data/spec/model_helpers_spec.rb +40 -0
  79. data/spec/model_helpers_spec.rb~ +36 -0
  80. data/spec/remote_access_controller_spec.rb~ +36 -0
  81. data/spec/resource_spec.rb +181 -0
  82. data/spec/resource_spec.rb~ +173 -0
  83. data/spec/rest_resource_spec.rb~ +173 -0
  84. data/spec/rest_spec.rb +94 -0
  85. data/spec/rest_spec.rb~ +99 -0
  86. data/spec/rest_with_attribute_name_like_model_name_spec.rb +82 -0
  87. data/spec/sync_spec.rb +83 -0
  88. data/spec/sync_spec.rb~ +81 -0
  89. 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