transcribeme 0.0.5.beta → 1.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +22 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -2
- data/Guardfile +35 -0
- data/README.md +36 -7
- data/Rakefile +4 -4
- data/lib/transcribeme.rb +4 -36
- data/lib/transcribeme/api/client.rb +184 -34
- data/lib/transcribeme/version.rb +2 -1
- data/spec/lib/api/client_spec.rb +133 -5
- data/spec/spec_helper.rb +1 -1
- data/spec/support/audio/yes-we-can-speech.mp3 +0 -0
- data/spec/support/cassettes/list_of_recordings.yml +212 -0
- data/spec/support/cassettes/new_session.yml +19 -26
- data/spec/support/cassettes/successful_sign_in.yml +245 -0
- data/spec/support/cassettes/successful_sign_in_after_initialize_call.yml +244 -0
- data/spec/support/cassettes/unsuccessful_sign_in.yml +167 -0
- data/spec/support/cassettes/upload_url.yml +208 -0
- data/transcribeme.gemspec +15 -13
- metadata +52 -27
- metadata.gz.sig +0 -0
- data/lib/transcribeme/api/check_transcription_ready.rb +0 -29
- data/lib/transcribeme/api/customer_login.rb +0 -33
- data/lib/transcribeme/api/finalize_session.rb +0 -30
- data/lib/transcribeme/api/recordings.rb +0 -32
- data/lib/transcribeme/api/session.rb +0 -37
- data/lib/transcribeme/api/submission.rb +0 -31
- data/lib/transcribeme/api/submission_with_promocode.rb +0 -32
- data/lib/transcribeme/api/upload_url.rb +0 -30
- data/lib/transcribeme/customer.rb +0 -5
- data/lib/transcribeme/recording.rb +0 -5
- data/lib/transcribeme/transcription.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 220bcd847b3e0b90afbbea5f779e59705c7952ea
|
4
|
+
data.tar.gz: c6e5d50a3297e6b5756bb5e8d0f0185a6d94b1dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3ef2f1b18f139220c0096da77af39089707c4544afdda70dd03e854bdd4e8a46302ca108e2435960333b2c5221a7e48c9989eacbe5c9d5942e17d93f8edbc23
|
7
|
+
data.tar.gz: 6526240aafff85c06311693037ad10f3b5a8a09d285652cb53886f53426ad2e444e1b97a6c83d223dacc0a441f29a2130112faa09e32bf0381cc5ad1dd8e1401
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
TrailingWhitespace:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
LineLength:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
StringLiterals:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
EmptyLines:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
AllCops:
|
14
|
+
Includes:
|
15
|
+
- Rakefile
|
16
|
+
- config.ru
|
17
|
+
Excludes:
|
18
|
+
- db/schema.rb
|
19
|
+
- db/migrate/**
|
20
|
+
- bin/**
|
21
|
+
- config/**
|
22
|
+
- script/**
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -3,7 +3,12 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in transcribeme-api.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
group :development, :tools do
|
6
|
+
group :development, :test do
|
8
7
|
gem 'pry'
|
8
|
+
gem 'rubocop'
|
9
|
+
gem 'guard-rspec'
|
10
|
+
gem 'guard-yard'
|
11
|
+
gem 'guard-rubocop'
|
12
|
+
gem 'terminal-notifier-guard'
|
13
|
+
gem 'coveralls', require: false
|
9
14
|
end
|
data/Guardfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
guard :rubocop do
|
27
|
+
watch(%r{.+\.rb$})
|
28
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
guard 'yard' do
|
32
|
+
watch(%r{app/.+\.rb})
|
33
|
+
watch(%r{lib/.+\.rb})
|
34
|
+
watch(%r{ext/.+\.c})
|
35
|
+
end
|
data/README.md
CHANGED
@@ -6,10 +6,19 @@
|
|
6
6
|
[![Code Climate](https://codeclimate.com/github/tuttinator/transcribeme.png)](https://codeclimate.com/github/tuttinator/transcribeme)
|
7
7
|
|
8
8
|
|
9
|
-
###
|
9
|
+
### Description
|
10
10
|
|
11
|
+
This gem is a Ruby wrapper for the TranscribeMe SOAP API, built on Savon, and includes some extra dangly bits for uploading to Windows Azure Blob storage.
|
11
12
|
|
12
|
-
|
13
|
+
The DSL may change before 1.0.0 stable is released.
|
14
|
+
|
15
|
+
Changes from prior 1.0.0 include bringing the Ruby method names in line with the actual SOAP action names.
|
16
|
+
|
17
|
+
This gem wants to make it easy for you. If you call the 'sign_in' method before initializing a session then we all know you meant to. We'll jump right in there and initialize it for you.
|
18
|
+
|
19
|
+
## Prerequisites
|
20
|
+
|
21
|
+
This gem relies on FFMPEG for determining the duration of audio (and video) files. The TranscribeMe SOAP API leaves it as the client's responsibility for determining the duration of files being uploaded.
|
13
22
|
|
14
23
|
## Installation
|
15
24
|
|
@@ -37,11 +46,31 @@ The documentation can be [browsed online](http://rubydoc.info/github/tuttinator/
|
|
37
46
|
|
38
47
|
## Roadmap
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
- [
|
43
|
-
- [ ]
|
44
|
-
- [ ]
|
49
|
+
Version 1.0.0 stable
|
50
|
+
|
51
|
+
- [ ] Write specs
|
52
|
+
- [ x ] Set up Travis-CI and document supported Ruby versions
|
53
|
+
- [ x ] Investigate Windows Azure Blob storage file upload
|
54
|
+
- [ x ] Include Excon for Windows Azure Blob storage
|
55
|
+
- [ x ] Base64 decrypt transcription results
|
56
|
+
- [ ] Document SOAP calls and error messages
|
57
|
+
- [ ] Complete YARD documentation
|
58
|
+
- [ ] Include option (default)
|
59
|
+
- [ ] Validations for GUIDs
|
60
|
+
- [ ] Exceptions for error handling (about 50%)
|
61
|
+
- [ ] Modelling Recording objects, particularly better describing recording status
|
62
|
+
|
63
|
+
Version 1.1.0
|
64
|
+
|
65
|
+
- [ ] Create a CLI interface
|
66
|
+
|
67
|
+
RubyMotion
|
68
|
+
|
69
|
+
- [ ] A RubyMotion fork (transcribeme-motion), wrapped in BubbleWrap's HTTP DSL (watch this space)
|
70
|
+
|
71
|
+
REST API Wrapper
|
72
|
+
|
73
|
+
- [ ] A Sinatra RESTful wrapper around the SOAP operations for your own personal REST API middleman, with JSON-ic magic at your fingertips. JSON was always my favourite Argonaut.
|
45
74
|
|
46
75
|
## Contributing
|
47
76
|
|
data/Rakefile
CHANGED
data/lib/transcribeme.rb
CHANGED
@@ -1,37 +1,5 @@
|
|
1
|
-
require 'transcribeme/version'
|
2
|
-
|
3
|
-
module TranscribeMe
|
4
|
-
module API
|
5
|
-
|
6
|
-
WSDL = "http://transcribeme-api.cloudapp.net/PortalAPI.svc?wsdl=wsdl0"
|
7
|
-
ENDPOINT = "http://transcribeme-api.cloudapp.net/PortalAPI.svc"
|
8
|
-
NAMESPACE = "http://TranscribeMe.API.Web"
|
9
|
-
NAMESPACE_IDENTIFIER = :tns # any identifier can be used
|
10
|
-
|
11
|
-
SOAP_ENVELOPE = ["soapenv:Envelope", { "xmlns:soapenv" => "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:#{NAMESPACE_IDENTIFIER}" => NAMESPACE }]
|
12
|
-
|
13
|
-
def self.construct_xml(soap_method, options = {})
|
14
|
-
Builder::XmlMarkup.new.tag!(*SOAP_ENVELOPE) do |xml|
|
15
|
-
xml.tag!("soapenv:Body") do |xml|
|
16
|
-
xml.tag!("#{NAMESPACE_IDENTIFIER}:#{soap_method}") do |xml|
|
17
|
-
options.each do |key, value|
|
18
|
-
xml.tag!("#{NAMESPACE_IDENTIFIER}:#{key}") { |xml| xml.text! value }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
1
|
require 'savon'
|
29
|
-
|
30
|
-
require '
|
31
|
-
require 'transcribeme/
|
32
|
-
require 'transcribeme/api/
|
33
|
-
require 'transcribeme/api/recordings'
|
34
|
-
require 'transcribeme/api/submission'
|
35
|
-
require 'transcribeme/api/submission_with_promocode'
|
36
|
-
require 'transcribeme/api/check_transcription_ready'
|
37
|
-
require 'transcribeme/api/upload_url'
|
2
|
+
require 'streamio-ffmpeg'
|
3
|
+
require 'excon'
|
4
|
+
require 'transcribeme/version'
|
5
|
+
require 'transcribeme/api/client'
|
@@ -1,16 +1,34 @@
|
|
1
|
+
# TranscribeMe
|
1
2
|
module TranscribeMe
|
3
|
+
# API module
|
2
4
|
module API
|
3
|
-
|
5
|
+
# API Client with methods for interacting with the SOAP API
|
4
6
|
class Client
|
5
7
|
|
6
|
-
|
7
|
-
attr_reader :
|
8
|
-
|
8
|
+
# Public: Returns the session id of the current session
|
9
|
+
attr_reader :session_id
|
10
|
+
# Public: Returns the expiry time of the current session
|
11
|
+
attr_reader :session_expiry_time
|
12
|
+
# Public: Returns the underlining Savon object
|
13
|
+
attr_reader :savon
|
14
|
+
|
15
|
+
WSDL = 'http://transcribeme-api.cloudapp.net/PortalAPI.svc?wsdl=wsdl0'
|
16
|
+
ENDPOINT = 'http://transcribeme-api.cloudapp.net/PortalAPI.svc'
|
17
|
+
NAMESPACE = 'http://TranscribeMe.API.Web'
|
18
|
+
|
19
|
+
# Public: Initializes the API Client class
|
20
|
+
#
|
9
21
|
def initialize
|
10
|
-
|
22
|
+
# Note: Deliberately disabling the verbose Savon logging
|
23
|
+
@savon = ::Savon.client(endpoint: ENDPOINT, namespace: NAMESPACE,
|
24
|
+
soap_version: 1, wsdl: WSDL, log: false)
|
11
25
|
end
|
12
26
|
|
13
|
-
|
27
|
+
# Public: Initializes a session on the API server and stores
|
28
|
+
# the expiry time and the session_id in instance variables
|
29
|
+
#
|
30
|
+
# Returns the session_id GUID
|
31
|
+
def initialize_session
|
14
32
|
response = @savon.call :initialize_session
|
15
33
|
# Without ActiveSupport
|
16
34
|
# 1.hour.from_now is 3600 seconds from Time.now
|
@@ -18,69 +36,201 @@ module TranscribeMe
|
|
18
36
|
@session_id = response.body[:initialize_session_response][:initialize_session_result]
|
19
37
|
end
|
20
38
|
|
21
|
-
|
39
|
+
# Public: Calls the 'SignIn' SOAP action
|
40
|
+
#
|
41
|
+
# username - a String which corresponds to a TranscribeMe Portal
|
42
|
+
# account username which can be any valid email address
|
43
|
+
# password - a String which is the portal account password
|
44
|
+
#
|
45
|
+
# Returns a GUID of the Customer ID
|
46
|
+
def sign_in(username, password)
|
22
47
|
|
23
|
-
|
48
|
+
# If #login_with is called before we have a session_id instance variable
|
49
|
+
# then call initialize_session
|
50
|
+
initialize_session unless session_valid?
|
24
51
|
|
52
|
+
# Use Savon to call the 'SignIn' SOAP action
|
25
53
|
response = @savon.call :sign_in,
|
26
|
-
message: {
|
27
|
-
|
28
|
-
|
54
|
+
message: { 'wsdl:sessionID' => @session_id,
|
55
|
+
'wsdl:username' => username,
|
56
|
+
'wsdl:password' => password }
|
29
57
|
|
30
|
-
|
58
|
+
error_message = response.body[:sign_in_response][:error_message]
|
59
|
+
|
60
|
+
raise error_message if error_message
|
31
61
|
|
62
|
+
# Assign the customer_login_id variable to the string in the SOAP response
|
63
|
+
@customer_login_id = response.body[:sign_in_response][:sign_in_result]
|
32
64
|
end
|
33
65
|
|
66
|
+
# Public: Calls the 'GetCustomerRecordings' SOAP Action
|
67
|
+
#
|
68
|
+
# requires the user to be logged in
|
69
|
+
#
|
70
|
+
# Returns an Array of Hashes of with the properties of recording objects
|
34
71
|
def get_recordings
|
35
|
-
# raise
|
72
|
+
# raise 'Login first!' unless @customer_login_id
|
36
73
|
|
37
74
|
response = @savon.call :get_customer_recordings,
|
38
|
-
message: {
|
75
|
+
message: { 'wsdl:sessionID' => session_id }
|
39
76
|
|
40
77
|
@recordings = response.body[:get_customer_recordings_response][:get_customer_recordings_result][:recording_info]
|
41
78
|
end
|
42
79
|
|
80
|
+
# Public: Calls the 'GetUploadUrl' SOAP Action
|
81
|
+
#
|
82
|
+
# Returns the upload url as a String
|
43
83
|
def get_upload_url
|
44
|
-
# raise
|
84
|
+
# raise 'Login first!' unless @customer_login_id
|
45
85
|
|
46
86
|
response = @savon.call :get_upload_url,
|
47
|
-
message: {
|
87
|
+
message: { 'wsdl:sessionID' => @session_id }
|
48
88
|
|
49
89
|
@upload_url = response.body[:get_upload_url_response][:get_upload_url_result]
|
90
|
+
end
|
50
91
|
|
92
|
+
# Public: uploads to Azure Blob Storage and commits the upload to
|
93
|
+
# the TranscribeMe SOAP API
|
94
|
+
#
|
95
|
+
# file_path - a String with the path to the actual file
|
96
|
+
# options - a Hash with these keys:
|
97
|
+
# :multiple_speakers - Boolean (default is true)
|
98
|
+
# :duration - Float
|
99
|
+
# :description - String
|
100
|
+
#
|
101
|
+
# Returns the response as a Hash
|
102
|
+
def upload(file_path, options = {})
|
103
|
+
|
104
|
+
# If not logged in, raise this exception
|
105
|
+
raise 'Login first!' unless @customer_login_id
|
106
|
+
|
107
|
+
# Extract options from the options hash
|
108
|
+
multiple_speakers = options[:multiple_speakers] || true
|
109
|
+
description = options[:description]
|
110
|
+
file_name = File.basename(file_path)
|
111
|
+
file_format = File.extname(file_path)
|
112
|
+
file_size = File.stat(file_path).size
|
113
|
+
# Use the duration if provided in the options hash
|
114
|
+
duration = options[:duration] || ::FFMPEG::Movie.new(file_path).duration
|
115
|
+
|
116
|
+
# Use the last upload url, or grab a new one
|
117
|
+
@upload_url ||= get_upload_url
|
118
|
+
|
119
|
+
# Create a connection to the upload url
|
120
|
+
connection = Excon.new(@upload_url)
|
121
|
+
# Upload to
|
122
|
+
connection.put(headers: { "x-ms-blob-type" => "BlockBlob",
|
123
|
+
"x-ms-date" => Time.now.to_s,
|
124
|
+
"Content-Length" => file_size}, body: File.read(file_path))
|
125
|
+
|
126
|
+
# Post to the
|
127
|
+
response = @savon.call :commit_upload, message: { "wsdl:sessionID" => @session_id,
|
128
|
+
"wsdl:url" => @upload_url,
|
129
|
+
"wsdl:name" => file_name,
|
130
|
+
"wsdl:description" => description,
|
131
|
+
"wsdl:duration" => duration,
|
132
|
+
"wsdl:source" => "Ruby API Client",
|
133
|
+
"wsdl:format" => file_format,
|
134
|
+
"wsdl:isMultipleSpeakers" => multiple_speakers }
|
135
|
+
|
136
|
+
# Set the upload url to nil so that we don't reuse it
|
137
|
+
@upload_url = nil
|
138
|
+
|
139
|
+
response
|
51
140
|
end
|
52
141
|
|
53
|
-
|
54
|
-
|
55
|
-
|
142
|
+
# Public: Calls the 'TranscribeRecording' SOAP Action
|
143
|
+
#
|
144
|
+
# recording_id - a String in GUID format
|
145
|
+
#
|
146
|
+
# Returns the SOAP response Hash
|
147
|
+
def transcribe_recording(recording_id)
|
148
|
+
# initialize_session unless @session.try :valid?
|
149
|
+
|
150
|
+
response = @savon.call :transcribe_recording,
|
151
|
+
message: { 'wsdl:sessionID' => @session_id,
|
152
|
+
'wsdl:recordingId' => recording_id }
|
153
|
+
|
154
|
+
response.body[:transcribe_recording_response][:transcribe_recording_result]
|
56
155
|
end
|
57
156
|
|
58
|
-
|
59
|
-
|
60
|
-
|
157
|
+
# Public: Calls the 'TranscribeRecordingWithPromoCode' SOAP Action
|
158
|
+
#
|
159
|
+
# recording_id - a String in GUID format
|
160
|
+
# promocode - a String
|
161
|
+
#
|
162
|
+
# Returns the SOAP response Hash
|
163
|
+
def transcribe_recording_using_promocode(recording_id, promocode)
|
164
|
+
# initialize_session unless @session.try :valid?
|
165
|
+
|
166
|
+
response = @savon.call :transcribe_recording_using_promocode,
|
167
|
+
message: { 'wsdl:sessionID' => @session_id,
|
168
|
+
'wsdl:recordingId' => recording_id,
|
169
|
+
'wsdl:promoCode' => promocode }
|
170
|
+
|
171
|
+
response.body[:transcribe_recording_using_promocode_response][:transcribe_recording_using_promocode_result]
|
61
172
|
end
|
62
173
|
|
63
|
-
|
64
|
-
|
65
|
-
|
174
|
+
# Public: Calls the 'GetRecordingInfo' SOAP Action
|
175
|
+
#
|
176
|
+
# recording_id - a String in GUID format
|
177
|
+
#
|
178
|
+
# Returns the SOAP response Hash
|
179
|
+
def get_recording_info(recording_id)
|
180
|
+
response = @savon.call :get_recording_info,
|
181
|
+
message: { 'wsdl:sessionID' => @session_id,
|
182
|
+
'wsdl:recordingID' => recording_id }
|
183
|
+
response.body[:get_recording_info_response][:get_recording_info_result]
|
66
184
|
end
|
67
185
|
|
68
|
-
|
69
|
-
|
70
|
-
|
186
|
+
# Public: Calls the 'GetTranscription' SOAP Action to allow for
|
187
|
+
# downloading of transcriptions
|
188
|
+
#
|
189
|
+
# recording_id - a String in GUID format
|
190
|
+
# format - a Symbol - either :text, :rtf, :pdf, :html
|
191
|
+
#
|
192
|
+
# Returns the file data in a String to write to a file (decoded from Base64.)
|
193
|
+
def get_transcription(recording_id, format = :text)
|
194
|
+
format_type = case format
|
195
|
+
when :text
|
196
|
+
"Text"
|
197
|
+
else
|
198
|
+
format.to_s.upcase
|
199
|
+
end
|
200
|
+
|
201
|
+
response = @savon.call :get_transcription, message: { 'wsdl:sessionID' => @session_id,
|
202
|
+
'wsdl:recId' => recording_id,
|
203
|
+
'wsdl:formattingType' => format_type }
|
204
|
+
|
205
|
+
error_message = response.body[:get_transcription_response][:error_message]
|
206
|
+
raise error_message if error_message
|
207
|
+
|
208
|
+
transcription = response.body[:get_transcription_response][:get_transcription_result]
|
209
|
+
|
210
|
+
raise "Transcription unable to be downloaded" if transcription.nil?
|
211
|
+
|
212
|
+
Base64.decode64(transcription)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Public: Calls the 'FinalizeSession' SOAP Action to close
|
216
|
+
# the session on the server
|
217
|
+
#
|
218
|
+
# Returns the SOAP response Hash
|
219
|
+
def finalize_session
|
220
|
+
@savon.call :finalize_session,
|
221
|
+
message: { 'wsdl:sessionID' => @session_id }
|
71
222
|
end
|
72
223
|
|
73
224
|
private
|
74
225
|
|
226
|
+
# Private: Checks if the session expiry time has passed
|
227
|
+
#
|
228
|
+
# Returns a Boolean
|
75
229
|
def session_valid?
|
76
|
-
if @session_expiry_time
|
77
|
-
@session_expiry_time > Time.now
|
78
|
-
end
|
230
|
+
@session_expiry_time > Time.now if @session_expiry_time
|
79
231
|
end
|
80
232
|
|
81
|
-
|
82
|
-
|
83
233
|
end
|
84
234
|
|
85
235
|
end
|
86
|
-
end
|
236
|
+
end
|