Class: ICFS::Email::Core
- Inherits:
-
Object
- Object
- ICFS::Email::Core
- Defined in:
- lib/icfs/email/core.rb
Overview
Core email processing engine.
Constant Summary collapse
- ValFile =
A file to attach
{ method: :hash, required: { content: Validate::IsString, # content of the file name: Items::FieldFilename, # name of the file }.freeze }.freeze
- ValReceive =
Results of processing a valid message
{ method: :hash, required: { orig: Validate::IsString, # the raw message caseid: Items::FieldCaseid, # case to write user: Items::FieldUsergrp, # user as author files: { # files to attach method: :array, check: ValFile }.freeze, }.freeze, optional: { entry: Validate::IsIntPos, # the entry number time: Validate::IsIntPos, # the time of the entry title: Items::FieldTitle, # title of the entry content: Items::FieldContent, # content of the entry tags: { # tags to apply method: :array, check: Items::FieldTag }.freeze, perms: { # perms to apply method: :array, check: Items::FieldPermAny, }.freeze, stats: { # stats to apply method: :array, min: 1, check: { method: :hash, required: { "name" => Items::FieldStat, "value" => Validate::IsFloat, "credit" => { method: :array, min: 1, max: 32, check: Items::FieldUsergrp }.freeze }.freeze }.freeze }.freeze, save_raw: Validate::IsBoolean, # save the raw email as a File save_msg: Validate::IsBoolean, # save the processed message w/o attach }.freeze, others: true, }.freeze
- DefaultTitle =
Default title
'Email gateway default title'
- DefaultContent =
Default content
'Entry generated via email gateway with no content.'
- DefaultOrig =
Filename for original content
'email_received.eml'
- DefaultEmail =
Filename for processed content without attachments
'email.eml'
- CopyFields =
Basic header fields to copy
[ "to", "cc", "message-id", "in-reply-to", "references", "subject", "comments", "keywords", "date", "from", "sender", "reply-to", ].freeze
- ContentFields =
Content related fields
[ "content-transfer-encoding", "content-description", "content-disposition", "content-type", "content-id", "content-location", ].freeze
- FieldsSet =
Set of header fields to copy set
Set.new(CopyFields).merge(ContentFields).freeze
Instance Method Summary collapse
-
#initialize(api, log, st = nil) ⇒ Core
constructor
New instance.
-
#receive(msg) ⇒ Array
Process a received email using the middleware stack.
-
#stack_set(st) ⇒ Object
Set the middleware stack.
Constructor Details
#initialize(api, log, st = nil) ⇒ Core
New instance
119 120 121 122 123 |
# File 'lib/icfs/email/core.rb', line 119 def initialize(api, log, st=nil) @api = api @log = log self.stack_set(st) if st end |
Instance Method Details
#receive(msg) ⇒ Array
Process a received email using the middleware stack
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/icfs/email/core.rb', line 146 def receive(msg) @log.debug('Email: Processing %s' % msg.) # setup the environment env = { orig: msg.raw_source.dup, # the original text email msg: msg, # the email message being worked on files: [], # files to attach to the entry api: @api, # the ICFS API } # process all middleware @stack.each do |mid| resp, err = mid.receive(env) case resp when :continue next when :stop break when :failure return [:failure, err] else raise ScriptError end end # check that all required fields were completed err = Validate.check(env, ValReceive) if err @log.info('Email: Invalid: %s' % err.inspect) return [:invalid, err] end # API set to active user @api.user = env[:user] # if an entry was specified if env[:entry] && env[:entry] != 0 ent = @api.entry_read(env[:caseid], env[:entry]) ent.delete('icfs') ent.delete('log') ent.delete('user') ent.delete('tags') if ent['tags'][0] == ICFS::TagNone else ent = {} ent['caseid'] = env[:caseid] end # build entry ent['time'] = env[:time] if env[:time] ent['title'] = env[:title] if env[:title] ent['title'] ||= DefaultTitle ent['content'] = env[:content] if env[:content] ent['content'] ||= DefaultContent if env[:tags] ent['tags'] ||= [] ent['tags'] = (ent['tags'] + env[:tags]).uniq end ent['perms'] = env[:perms].uniq if env[:perms] ent['stats'] = env[:stats] if env[:stats] # files files = env[:files].map do |fd| tmp = @api.tempfile tmp.write(fd[:content]) { 'name' => fd[:name], 'temp' => tmp } end if env[:save_original] tmp = @api.tempfile tmp.write(env[:orig]) files << { 'name' => DefaultOrig, 'temp' => tmp } end if env[:save_email] tmp = @api.tempfile env[:msg].header.fields.delete_if do |fi| !FieldsSet.include?(fi.name.downcase) end tmp.write(env[:msg].encoded) files << { 'name' => DefaultEmail, 'temp' => tmp } end unless files.empty? ent['files'] ||= [] ent['files'] = ent['files'] + files end # try to record it @api.record(ent, nil, nil, nil) @log.info('Email: Success: %s %d-%d' % [ent['caseid'], ent['entry'], ent['log']]) return [:success, ent] rescue ICFS::Error::Conflict => ex @log.warn('Email: Conflict: %s' % ex.) return [:conflict, ex.] rescue ICFS::Error::NotFound => ex @log.warn('Email: Not Found: %s' % ex.) return [:notfound, ex.] rescue ICFS::Error::Perms => ex @log.warn('Email: Permissions: %s' % ex.) return [:perms, ex.] rescue ICFS::Error::Value => ex @log.warn('Email: Value: %s' % ex.) return [:value, ex.] end |
#stack_set(st) ⇒ Object
Set the middleware stack
Each middleware object must respond to #receive and return one of:
* :continue - process more middleware
* :success - stops further middleare, and records the entry
* :failure - stops further middlware and does not record
134 135 136 |
# File 'lib/icfs/email/core.rb', line 134 def stack_set(st) @stack = st end |