rsence 2.0.0.6.pre → 2.0.0.7.pre
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/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
|
|