rsence 2.0.0.6.pre → 2.0.0.7.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/INSTALL.rdoc +39 -25
- data/VERSION +1 -1
- data/conf/default_conf.yaml +0 -3
- data/lib/conf/default.rb +59 -60
- data/lib/daemon/daemon.rb +269 -280
- data/lib/http/broker.rb +47 -14
- data/lib/http/rackup.rb +4 -0
- data/lib/http/request.rb +47 -49
- data/lib/http/response.rb +47 -45
- data/lib/plugins/gui_plugin.rb +22 -21
- data/lib/plugins/guiparser.rb +95 -94
- data/lib/plugins/plugin.rb +300 -295
- data/lib/plugins/plugin_plugins.rb +64 -40
- data/lib/plugins/plugin_sqlite_db.rb +63 -63
- data/lib/plugins/plugin_util.rb +95 -104
- data/lib/plugins/pluginmanager.rb +373 -414
- data/lib/plugins/plugins.rb +11 -4
- data/lib/plugins/servlet.rb +10 -9
- data/lib/session/msg.rb +249 -248
- data/lib/session/sessionmanager.rb +364 -373
- data/lib/session/sessionstorage.rb +265 -272
- data/lib/transporter/transporter.rb +164 -169
- data/lib/util/gzstring.rb +2 -0
- data/lib/values/hvalue.rb +224 -224
- data/lib/values/valuemanager.rb +98 -98
- data/plugins/index_html/index_html.rb +1 -32
- metadata +4 -4
@@ -11,235 +11,230 @@
|
|
11
11
|
|
12
12
|
module RSence
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
class Transporter
|
14
|
+
# Transporter handles incoming requests targeted at RSence
|
15
|
+
# and distributes calls and data accordingly.
|
16
|
+
class Transporter
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
# ValueManager syncronizes value objects
|
19
|
+
require 'values/valuemanager'
|
22
20
|
|
23
|
-
|
24
|
-
|
21
|
+
# SessionManager creates, validates, stores and expires sessions
|
22
|
+
require 'session/sessionmanager'
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
# PluginManager handles all the plugins
|
25
|
+
require 'plugins/pluginmanager'
|
28
26
|
|
29
|
-
|
27
|
+
attr_accessor :valuemanager, :sessions, :plugins
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
def initialize
|
30
|
+
@config = ::RSence.config[:transporter_conf]
|
31
|
+
@accept_req = false
|
32
|
+
@valuemanager = ValueManager.new
|
33
|
+
@sessions = SessionManager.new( self )
|
34
|
+
@plugins = PluginManager.new( ::RSence.config[:plugin_paths], self, RSence.args[:autoupdate] )
|
35
|
+
if RSence.launch_pid != Process.pid
|
36
|
+
Process.kill( 'TERM', RSence.launch_pid )
|
37
|
+
end
|
39
38
|
end
|
40
|
-
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def online?
|
41
|
+
@accept_req
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
def online=(state)
|
45
|
+
if RSence.args[:verbose]
|
46
|
+
if state
|
47
|
+
puts "RSence is online now."
|
48
|
+
else
|
49
|
+
puts "RSence is offline now."
|
50
|
+
end
|
52
51
|
end
|
52
|
+
@accept_req = state
|
53
53
|
end
|
54
|
-
@accept_req = state
|
55
|
-
end
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
def shutdown
|
56
|
+
online=false
|
57
|
+
@plugins.shutdown
|
58
|
+
@sessions.shutdown
|
59
|
+
end
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
def servlet( request_type, request, response )
|
62
|
+
broker_urls = ::RSence.config[:broker_urls]
|
63
|
+
uri = request.fullpath
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
65
|
+
if request_type == :post
|
66
|
+
## /x handles xhr without cookies
|
67
|
+
if uri == broker_urls[:x] and @sessions.accept_requests
|
68
|
+
xhr( request, response, { :cookies => true, :servlet => false } )
|
69
|
+
return true
|
70
|
+
## /hello handles the first xhr (with cookies, for session key)
|
71
|
+
elsif uri == broker_urls[:hello] and @sessions.accept_requests
|
72
|
+
xhr( request, response, { :cookies => true, :servlet => false } )
|
73
|
+
return true
|
74
|
+
else
|
75
|
+
session = {}
|
76
|
+
return @plugins.match_servlet( request_type, request, response, session )
|
77
|
+
end
|
76
78
|
else
|
77
79
|
session = {}
|
78
80
|
return @plugins.match_servlet( request_type, request, response, session )
|
79
81
|
end
|
80
|
-
else
|
81
|
-
session = {}
|
82
|
-
return @plugins.match_servlet( request_type, request, response, session )
|
83
82
|
end
|
84
|
-
end
|
85
83
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
84
|
+
# wrapper for the session manager stop client functionality
|
85
|
+
def xhr_error_handler(msg,err_name,err_extra_descr='')
|
86
|
+
@sessions.stop_client_with_message( msg,
|
87
|
+
@config[:messages][err_name][:title],
|
88
|
+
@config[:messages][err_name][:descr]+err_extra_descr,
|
89
|
+
@config[:messages][err_name][:uri]
|
90
|
+
)
|
91
|
+
end
|
94
92
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
93
|
+
# wrapper for tracebacks in xhr
|
94
|
+
def xhr_traceback_handler(e,err_descr='Transporter::UnspecifiedError')
|
95
|
+
puts "=="*40 if RSence.args[:debug]
|
96
|
+
puts err_descr
|
97
|
+
if RSence.args[:debug]
|
98
|
+
puts "--"*40
|
99
|
+
puts e.message
|
100
|
+
puts " #{e.backtrace.join("\n ")}"
|
101
|
+
puts "=="*40
|
102
|
+
end
|
104
103
|
end
|
105
|
-
end
|
106
104
|
|
107
|
-
|
108
|
-
|
105
|
+
## handles incoming XMLHttpRequests from the browser
|
106
|
+
def xhr(request, response, options = { :cookies => false, :servlet => false } )
|
109
107
|
|
110
|
-
|
108
|
+
session_conf = ::RSence.config[:session_conf]
|
111
109
|
|
112
|
-
|
110
|
+
options[:cookies] = false unless options.has_key?(:cookies)
|
113
111
|
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
if session_conf[:session_cookies] and session_conf[:trust_cookies]
|
113
|
+
options[:cookies] = true
|
114
|
+
end
|
117
115
|
|
118
|
-
|
119
|
-
|
116
|
+
# Creates the msg object, also checks or creates a new session; verifies session keys and such
|
117
|
+
msg = @sessions.init_msg( request, response, options )
|
120
118
|
|
121
|
-
|
119
|
+
response_success = true
|
122
120
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
121
|
+
# If the client encounters an error, display error message
|
122
|
+
if request.query.has_key?('err_msg')
|
123
|
+
response_success = false
|
124
|
+
client_error_msg = request.query['err_msg'].inspect
|
125
|
+
puts "\nCLIENT ERROR:\n#{client_error_msg}\n" if RSence.args[:debug]
|
126
|
+
xhr_error_handler(msg,:client_error,client_error_msg)
|
127
|
+
end
|
130
128
|
|
131
|
-
|
132
|
-
|
129
|
+
# If the session is valid, continue:
|
130
|
+
if msg.ses_valid and response_success
|
133
131
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
132
|
+
# If cookies are true, it means the url base needs to
|
133
|
+
# be changed from /hello to /x to prevent further cookie juggling.
|
134
|
+
if options[:cookies] and not options[:servlet]
|
135
|
+
msg.reply("COMM.Transporter.url=#{::RSence.config[:broker_urls][:x].to_json};")
|
136
|
+
end
|
139
137
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
138
|
+
# Appends a 'new session.' message for new sessions in RSence.args[:verbose]:
|
139
|
+
puts "new session." if msg.new_session and RSence.args[:verbose]
|
140
|
+
puts "restored session." if msg.restored_session and RSence.args[:verbose]
|
141
|
+
puts "clone source." if msg.cloned_targets and RSence.args[:verbose]
|
142
|
+
puts "clone target." if msg.cloned_source and RSence.args[:verbose]
|
145
143
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
144
|
+
## Pass the client XML to the value manager
|
145
|
+
if request.query.has_key?( 'values' )
|
146
|
+
syncdata_str = request.query[ 'values' ]
|
147
|
+
begin
|
148
|
+
@valuemanager.xhr( msg, syncdata_str )
|
149
|
+
rescue => e
|
150
|
+
response_success = false
|
151
|
+
xhr_error_handler( msg, :valuemanager_xhr_error, e.message )
|
152
|
+
xhr_traceback_handler( e, "Transporter::ValueManagerXHRError: @valuemanager.xhr failed." )
|
153
|
+
end
|
155
154
|
end
|
156
|
-
end
|
157
155
|
|
158
|
-
|
159
|
-
|
156
|
+
## Calls the restore_ses of plugins, when a session is restored (page reload with previously active session)
|
157
|
+
if msg.restored_session
|
158
|
+
|
159
|
+
msg.session[:deps] = []
|
160
160
|
|
161
|
-
|
161
|
+
if msg.cloned_source
|
162
|
+
begin
|
163
|
+
@plugins.delegate( :cloned_target, msg, msg.cloned_source )
|
164
|
+
rescue => e
|
165
|
+
response_success = false
|
166
|
+
xhr_error_handler( msg, :plugin_delegate_cloned_target_error, e.message )
|
167
|
+
xhr_traceback_handler( e, "Transporter::PluginDelegateClonedTargetError: @plugins.delegate 'cloned_target' failed." )
|
168
|
+
end
|
169
|
+
end
|
162
170
|
|
163
|
-
if msg.cloned_source
|
164
171
|
begin
|
165
|
-
@plugins.delegate( :
|
172
|
+
@plugins.delegate( :restore_ses, msg )
|
166
173
|
rescue => e
|
167
174
|
response_success = false
|
168
|
-
xhr_error_handler( msg, :
|
169
|
-
xhr_traceback_handler( e, "Transporter::
|
175
|
+
xhr_error_handler( msg, :plugin_delegate_restore_ses_error, e.message )
|
176
|
+
xhr_traceback_handler( e, "Transporter::PluginDelegateRestoreSesError: @plugins.delegate 'restore_ses' failed." )
|
170
177
|
end
|
171
|
-
end
|
172
178
|
|
179
|
+
elsif msg.new_session
|
180
|
+
begin
|
181
|
+
@plugins.delegate( :init_ses, msg )
|
182
|
+
rescue => e
|
183
|
+
response_success = false
|
184
|
+
xhr_error_handler( msg, :plugin_delegate_init_ses_error, e.message )
|
185
|
+
xhr_traceback_handler( e, "Transporter::PluginDelegateInitSesError: @plugins.delegate 'init_ses' failed." )
|
186
|
+
end
|
187
|
+
elsif msg.cloned_targets
|
188
|
+
begin
|
189
|
+
@plugins.delegate( :cloned_source, msg, msg.cloned_targets )
|
190
|
+
rescue => e
|
191
|
+
response_success = false
|
192
|
+
xhr_error_handler( msg, :plugin_delegate_cloned_source_error, e.message )
|
193
|
+
xhr_traceback_handler( e, "Transporter::PluginDelegateClonedSourceError: @plugins.delegate 'cloned_source' failed." )
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
## Calls validators for changed values
|
173
198
|
begin
|
174
|
-
@
|
199
|
+
@valuemanager.validate( msg )
|
175
200
|
rescue => e
|
176
201
|
response_success = false
|
177
|
-
xhr_error_handler( msg, :
|
178
|
-
xhr_traceback_handler( e, "Transporter::
|
202
|
+
xhr_error_handler( msg, :valuemanager_validate_error, e.message )
|
203
|
+
xhr_traceback_handler( e, "Transporter::ValueManagerValidateError: @valuemanager.validate failed." )
|
179
204
|
end
|
180
|
-
|
181
|
-
|
205
|
+
|
206
|
+
### Allows every plugin to respond to the idle call
|
182
207
|
begin
|
183
|
-
@plugins.delegate( :
|
208
|
+
@plugins.delegate( :idle, msg )
|
184
209
|
rescue => e
|
185
210
|
response_success = false
|
186
|
-
xhr_error_handler( msg, :
|
187
|
-
xhr_traceback_handler( e, "Transporter::
|
211
|
+
xhr_error_handler( msg, :plugin_idle_error, e.message )
|
212
|
+
xhr_traceback_handler( e, "Transporter::PluginIdleError: @plugins.idle failed." )
|
188
213
|
end
|
189
|
-
|
214
|
+
|
215
|
+
### Processes outgoing values to client
|
190
216
|
begin
|
191
|
-
@
|
217
|
+
@valuemanager.sync_client( msg )
|
192
218
|
rescue => e
|
193
219
|
response_success = false
|
194
|
-
xhr_error_handler( msg, :
|
195
|
-
xhr_traceback_handler( e, "Transporter::
|
220
|
+
xhr_error_handler( msg, :valuemanager_sync_client_error, e.message )
|
221
|
+
xhr_traceback_handler( e, "Transporter::ValueManagerSyncClientError: @valuemanager.sync_client failed." )
|
196
222
|
end
|
197
|
-
end
|
198
223
|
|
199
|
-
|
200
|
-
begin
|
201
|
-
@valuemanager.validate( msg )
|
202
|
-
rescue => e
|
203
|
-
response_success = false
|
204
|
-
xhr_error_handler( msg, :valuemanager_validate_error, e.message )
|
205
|
-
xhr_traceback_handler( e, "Transporter::ValueManagerValidateError: @valuemanager.validate failed." )
|
206
|
-
end
|
224
|
+
else
|
207
225
|
|
208
|
-
|
209
|
-
begin
|
210
|
-
@plugins.delegate( :idle, msg )
|
211
|
-
rescue => e
|
226
|
+
# session is not valid, the error was set in SessionManager
|
212
227
|
response_success = false
|
213
|
-
xhr_error_handler( msg, :plugin_idle_error, e.message )
|
214
|
-
xhr_traceback_handler( e, "Transporter::PluginIdleError: @plugins.idle failed." )
|
215
|
-
end
|
216
228
|
|
217
|
-
### Processes outgoing values to client
|
218
|
-
begin
|
219
|
-
@valuemanager.sync_client( msg )
|
220
|
-
rescue => e
|
221
|
-
response_success = false
|
222
|
-
xhr_error_handler( msg, :valuemanager_sync_client_error, e.message )
|
223
|
-
xhr_traceback_handler( e, "Transporter::ValueManagerSyncClientError: @valuemanager.sync_client failed." )
|
224
229
|
end
|
225
|
-
|
226
|
-
else
|
227
|
-
|
228
|
-
# session is not valid, the error was set in SessionManager
|
229
|
-
response_success = false
|
230
|
-
|
231
|
-
end
|
232
|
-
|
233
|
-
msg.response_success = response_success
|
234
230
|
|
235
|
-
|
236
|
-
msg.response_done()
|
237
|
-
end
|
231
|
+
msg.response_success = response_success
|
238
232
|
|
239
|
-
|
233
|
+
unless options[:servlet]
|
234
|
+
msg.response_done()
|
235
|
+
end
|
240
236
|
|
237
|
+
return msg
|
238
|
+
end
|
241
239
|
end
|
242
|
-
|
243
|
-
end
|
244
|
-
|
245
240
|
end
|
data/lib/util/gzstring.rb
CHANGED
data/lib/values/hvalue.rb
CHANGED
@@ -10,317 +10,317 @@
|
|
10
10
|
module RSence
|
11
11
|
|
12
12
|
|
13
|
-
## HValue is the server-side representation of the client's HValue object.
|
14
|
-
## It's the 'messenger' to syncronize server-client data and is smart enough
|
15
|
-
## to validate and process itself as well as tell the client-side
|
16
|
-
## representation of itself.
|
17
|
-
class HValue
|
13
|
+
## HValue is the server-side representation of the client's HValue object.
|
14
|
+
## It's the 'messenger' to syncronize server-client data and is smart enough
|
15
|
+
## to validate and process itself as well as tell the client-side
|
16
|
+
## representation of itself.
|
17
|
+
class HValue
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
attr_reader :valid, :sync, :val_id, :data, :members
|
20
|
+
attr_writer :valid, :val_id
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
# Method for binding the value to the session data.
|
23
|
+
def add( msg )
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
# get the value storage from the session data
|
26
|
+
session_values = msg.session[:values][:by_id]
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
## Store the object here
|
29
|
+
session_values[ @val_id ] = self
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
## Sends the client-side description
|
32
|
+
restore( msg )
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
## Set the valid flag, so we know that the value is initially in sync
|
35
|
+
@valid = true
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
## (Re-)Send the client-size representation
|
39
|
+
def restore( msg )
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
## Tags itself as a new value from the client's point of view
|
42
|
+
@is_new_to_client = true
|
43
43
|
|
44
|
-
|
44
|
+
add_to_sync( msg )
|
45
45
|
|
46
|
-
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
# +HValue+ constructor. Binds HValue automatically to the +Message+ instance
|
49
|
+
# given as parameter. Data given as second parameter.
|
50
|
+
def initialize( msg, data, meta = { :name => nil } )
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
## Get an unique integer id for the value
|
53
|
+
if RSence.args[:debug] and meta[:name] and not msg.valuemanager.id_exists?( msg, meta[:name] )
|
54
|
+
@val_id = meta[:name]
|
55
|
+
else
|
56
|
+
@val_id = msg.valuemanager.randgen.gen
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
## set the data of the hvalue
|
60
|
+
set( msg, data, true )
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
## the @sync flag is raised, when the client data is older than the server data
|
63
|
+
@sync = false
|
64
64
|
|
65
|
-
|
66
|
-
|
65
|
+
## the @is_valid flas is lowered, when the client data is newer than the server data
|
66
|
+
@is_valid = true
|
67
67
|
|
68
|
-
|
69
|
-
|
68
|
+
## Bind the value to the value manager and report it to the client
|
69
|
+
add( msg )
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
## storage for validator bindings
|
72
|
+
@members = {}
|
73
73
|
|
74
|
-
|
74
|
+
end
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
76
|
+
# Binds the value to the plugin method (both as
|
77
|
+
# strings; plugin as the name registered in PluginManager)
|
78
|
+
#
|
79
|
+
# It uses strings instead of '...method(...)' because
|
80
|
+
# it won't work with marshal. Strings are easier and work
|
81
|
+
# as well.
|
82
|
+
def bind( plugin_name, method_name )
|
83
|
+
@members[plugin_name] = [] unless @members.has_key?( plugin_name )
|
84
|
+
@members[plugin_name].push( method_name ) unless @members[plugin_name].include?( method_name )
|
85
|
+
return true
|
86
|
+
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
# Releases the binding of the value, both params as
|
89
|
+
# in bind, but optional (false = 'wildcard')
|
90
|
+
def release( plugin_name=false, method_name=false )
|
91
|
+
return release_all if not plugin_name and not method_name
|
92
|
+
return false unless @members.has_key?( plugin_name )
|
93
|
+
if not method_name
|
94
|
+
@members.delete( plugin_name )
|
95
|
+
else
|
96
|
+
@members[plugin_name].slice!(@members[plugin_name].index( method_name )) if @members[plugin_name].include?(method_name)
|
97
|
+
end
|
98
|
+
return true
|
97
99
|
end
|
98
|
-
return true
|
99
|
-
end
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
## Releases all members.
|
102
|
+
def release_all
|
103
|
+
@members = {}
|
104
|
+
return true
|
105
|
+
end
|
106
106
|
|
107
|
-
|
108
|
-
|
107
|
+
# The unbind method can be used as an alias to release (as in the client).
|
108
|
+
alias unbind release
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
# Tell all bound instances that the value is changed.
|
111
|
+
def tell( msg )
|
112
|
+
invalid_count = 0
|
113
|
+
@members.each_key do |plugin_name|
|
114
|
+
@members[plugin_name].each do |method_name|
|
115
|
+
invalid_count += 1 unless msg.plugins.run_plugin( plugin_name, method_name, msg, self )
|
116
|
+
end
|
117
|
+
end
|
118
|
+
if invalid_count == 0
|
119
|
+
@is_valid = true
|
120
|
+
msg.session[:values][:check].delete( @val_id )
|
116
121
|
end
|
117
122
|
end
|
118
|
-
if invalid_count == 0
|
119
|
-
@is_valid = true
|
120
|
-
msg.session[:values][:check].delete( @val_id )
|
121
|
-
end
|
122
|
-
end
|
123
123
|
|
124
|
-
|
125
|
-
|
124
|
+
# Handle client updates.
|
125
|
+
def from_client( msg, data )
|
126
126
|
|
127
|
-
|
128
|
-
|
127
|
+
# only process changes, if different from the one already stored.
|
128
|
+
if @data != data
|
129
129
|
|
130
|
-
|
131
|
-
|
130
|
+
## set takes care of the setting..
|
131
|
+
@data = data
|
132
132
|
|
133
|
-
|
134
|
-
|
133
|
+
## change the valid state, because the value was set by the client!
|
134
|
+
@is_valid = false
|
135
135
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
136
|
+
## add the id to the values to be checked
|
137
|
+
check_ids = msg.session[:values][:check]
|
138
|
+
unless check_ids.include?( @val_id )
|
139
|
+
check_ids.push( @val_id )
|
140
|
+
end
|
140
141
|
end
|
141
|
-
end
|
142
142
|
|
143
|
-
|
143
|
+
end
|
144
144
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
145
|
+
def add_to_sync( msg )
|
146
|
+
## add the id to the values to be syncronized (to client)
|
147
|
+
sync_ids = msg.session[:values][:sync]
|
148
|
+
unless sync_ids.include?( @val_id )
|
149
|
+
sync_ids.push( @val_id )
|
150
|
+
end
|
150
151
|
end
|
151
|
-
end
|
152
152
|
|
153
|
-
|
154
|
-
|
153
|
+
# Sets the data.
|
154
|
+
def set( msg, data, dont_tell_client=false )
|
155
155
|
|
156
|
-
|
156
|
+
@data = data
|
157
157
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
158
|
+
# won't tell the client about the change, usually not needed
|
159
|
+
unless dont_tell_client
|
160
|
+
## update the flags
|
161
|
+
@sync = false
|
162
|
+
@is_valid = true
|
163
163
|
|
164
|
-
|
164
|
+
add_to_sync( msg )
|
165
|
+
end
|
165
166
|
end
|
166
|
-
end
|
167
167
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
168
|
+
# Tell the client that the value changed.
|
169
|
+
def to_client( msg )
|
170
|
+
if @is_new_to_client
|
171
|
+
## Initialize a new client value
|
172
|
+
init_str = "COMM.Values.create(#{@val_id.to_json},#{@data.to_json});"
|
173
|
+
msg.reply_value( init_str )
|
174
|
+
@is_new_to_client = false
|
175
|
+
else
|
176
|
+
## Sets the client value
|
177
|
+
msg.reply_value "HVM.s(#{@val_id.to_json},#{@data.to_json});"
|
178
|
+
end
|
178
179
|
end
|
179
|
-
end
|
180
180
|
|
181
|
-
|
182
|
-
|
181
|
+
# Clean up self.
|
182
|
+
def die( msg=false )
|
183
183
|
|
184
|
-
|
184
|
+
release_all
|
185
185
|
|
186
|
-
|
187
|
-
|
186
|
+
# get the value storage from the session data
|
187
|
+
session_values = msg.session[:values][:by_id]
|
188
188
|
|
189
|
-
|
190
|
-
|
189
|
+
## Store the object here
|
190
|
+
session_values.delete( @val_id )
|
191
191
|
|
192
|
-
|
193
|
-
|
192
|
+
if msg and not @is_new_to_client
|
193
|
+
msg.reply_value("HVM.del(#{@val_id.to_json});")
|
194
|
+
end
|
194
195
|
end
|
195
|
-
end
|
196
196
|
|
197
|
-
end
|
197
|
+
end
|
198
198
|
|
199
|
-
class UploadValue < HValue
|
199
|
+
class UploadValue < HValue
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
201
|
+
@state_responders = {
|
202
|
+
:ready => [], # id == 0
|
203
|
+
:started => [], # id == 1
|
204
|
+
:process => [], # id == 2 ; also uses bind
|
205
|
+
3 => [], # id == 3
|
206
|
+
4 => [], # id == 4
|
207
|
+
:error => [] # id < 0
|
208
|
+
}
|
209
209
|
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
@upload_state = 0
|
211
|
+
@upload_key = ''
|
212
|
+
@uploads = []
|
213
213
|
|
214
|
-
|
215
|
-
|
214
|
+
# the data should contain both state and key in the value
|
215
|
+
def from_client( msg, data )
|
216
216
|
|
217
|
-
|
218
|
-
|
217
|
+
## change the valid state, because the value was set by the client!
|
218
|
+
@is_valid = data.include?(':::')
|
219
219
|
|
220
|
-
|
221
|
-
|
220
|
+
# the state and key are separated by the ':::' delimitter string
|
221
|
+
if @is_valid
|
222
222
|
|
223
|
-
|
224
|
-
|
223
|
+
# split state and key using the delimitter
|
224
|
+
(upload_state, upload_key) = data.split(':::')
|
225
225
|
|
226
|
-
|
227
|
-
|
226
|
+
# the state is a number
|
227
|
+
upload_state = upload_state.to_i
|
228
228
|
|
229
|
-
|
230
|
-
|
229
|
+
@upload_state = upload_state
|
230
|
+
@upload_key = upload_key
|
231
231
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
232
|
+
# negative states are errors
|
233
|
+
if upload_state < 0
|
234
|
+
# "upload error: #{upload_state}"
|
235
|
+
# (parse the error)
|
236
|
+
unless @state_respders[:error].empty?
|
237
|
+
@state_responders[:error].each do |plugin_name,method_name|
|
238
|
+
msg.run( plugin_name,method_name,msg,self,upload_state )
|
239
|
+
end
|
239
240
|
end
|
240
|
-
end
|
241
241
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
242
|
+
# the default state, 0 means the ui is ready to send an
|
243
|
+
# upload and ticketserve is ready to receive it
|
244
|
+
elsif upload_state == 0
|
245
|
+
# "upload state: ready to upload."
|
246
|
+
# (do nothing)
|
247
247
|
|
248
|
-
|
249
|
-
|
250
|
-
|
248
|
+
unless @state_respders[:ready].empty?
|
249
|
+
@state_responders[:ready].each do |plugin_name,method_name|
|
250
|
+
msg.run( plugin_name,method_name,msg,self,upload_state )
|
251
|
+
end
|
251
252
|
end
|
252
|
-
end
|
253
253
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
254
|
+
# this state means the upload's transfer is started and progressing
|
255
|
+
elsif upload_state == 1
|
256
|
+
# "upload state: upload started."
|
257
|
+
# (show progress bar)
|
258
258
|
|
259
|
-
|
260
|
-
|
261
|
-
|
259
|
+
unless @state_respders[:started].empty?
|
260
|
+
@state_responders[:started].each do |plugin_name,method_name|
|
261
|
+
msg.run( plugin_name,method_name,msg,self,upload_state )
|
262
|
+
end
|
262
263
|
end
|
263
|
-
end
|
264
264
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
265
|
+
# this state means the upload's transfer is complete,
|
266
|
+
# but the uploaded data hasn't been handled yet.
|
267
|
+
elsif upload_state == 2
|
268
|
+
# "upload state: waiting to process."
|
269
269
|
|
270
|
-
|
271
|
-
|
272
|
-
|
270
|
+
uploads = msg.plugins[:ticketservices].get_uploads(upload_key,true)
|
271
|
+
if uploads.size == 1
|
272
|
+
uploaded_data = uploads[0]
|
273
273
|
|
274
|
-
|
275
|
-
|
274
|
+
# only process changes, if different from the one already stored.
|
275
|
+
if uploaded_data != @data
|
276
276
|
|
277
|
-
|
277
|
+
@data = uploaded_data
|
278
278
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
279
|
+
## add the id to the values to be checked
|
280
|
+
check_ids = msg.session[:values][:check]
|
281
|
+
unless check_ids.include?( @val_id )
|
282
|
+
check_ids.push( @val_id )
|
283
|
+
end
|
284
284
|
|
285
|
+
end
|
286
|
+
msg.plugins[:ticketservices].del_uploads(upload_key,msg.ses_id)
|
287
|
+
else
|
288
|
+
# "upload, amount of uploads: #{uploads.size}"
|
285
289
|
end
|
286
|
-
msg.plugins[:ticketservices].del_uploads(upload_key,msg.ses_id)
|
287
|
-
else
|
288
|
-
# "upload, amount of uploads: #{uploads.size}"
|
289
|
-
end
|
290
290
|
|
291
|
-
|
292
|
-
|
291
|
+
#
|
292
|
+
hvalue.set(msg,"3:::#{upload_key}")
|
293
293
|
|
294
|
-
|
294
|
+
msg.console( "upload state: set to ack" )
|
295
295
|
|
296
|
-
|
297
|
-
|
298
|
-
|
296
|
+
elsif upload_state == 3
|
297
|
+
# "upload state: waiting for user ack."
|
298
|
+
# (do nothing)
|
299
299
|
|
300
|
-
|
300
|
+
msg.console( "upload state: waiting user ack" )
|
301
301
|
|
302
302
|
|
303
|
-
|
304
|
-
|
305
|
-
|
303
|
+
elsif upload_state == 4
|
304
|
+
# "upload state: user wants to upload again."
|
305
|
+
# (set a new upload key, )
|
306
306
|
|
307
|
-
|
307
|
+
msg.console( "upload state: ack, getting new key" )
|
308
308
|
|
309
309
|
|
310
|
-
|
310
|
+
setup_upload( msg, hvalue )
|
311
311
|
|
312
312
|
|
313
|
-
|
314
|
-
|
313
|
+
else
|
314
|
+
# "upload unknown state: #{upload_state.inspect}"
|
315
|
+
end
|
315
316
|
end
|
317
|
+
return true
|
318
|
+
end
|
319
|
+
def setup_upload(msg,hvalue,size_bytes=500*1024,accept_mime=/image\/(.*?)/,allow_multi=false)
|
320
|
+
upload_key = msg.plugins[:ticketservices].upload_key(msg,hvalue.val_id,size_bytes,accept_mime,allow_multi)
|
321
|
+
hvalue.set( msg, upload_key )
|
316
322
|
end
|
317
|
-
return true
|
318
|
-
end
|
319
|
-
def setup_upload(msg,hvalue,size_bytes=500*1024,accept_mime=/image\/(.*?)/,allow_multi=false)
|
320
|
-
upload_key = msg.plugins[:ticketservices].upload_key(msg,hvalue.val_id,size_bytes,accept_mime,allow_multi)
|
321
|
-
hvalue.set( msg, upload_key )
|
322
323
|
end
|
323
|
-
end
|
324
324
|
|
325
325
|
end
|
326
326
|
|