Class: TaskJuggler::SheetReceiver

Inherits:
SheetHandlerBase show all
Includes:
StdIoWrapper
Defined in:
lib/taskjuggler/SheetReceiver.rb

Instance Attribute Summary

Attributes inherited from SheetHandlerBase

#dryRun, #workingDir

Instance Method Summary collapse

Methods included from StdIoWrapper

#stdIoWrapper

Methods inherited from SheetHandlerBase

#addToScm, #cutOut, #htmlMailBody, #info, #log, #sendEmail, #sendRichTextEmail, #setWorkingDir, #warning

Constructor Details

#initialize(appName, type) ⇒ SheetReceiver

Returns a new instance of SheetReceiver.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/taskjuggler/SheetReceiver.rb', line 29

def initialize(appName, type)
  super(appName)

  @sheetType = type
  # The following settings must be set by the deriving class.
  # Sheet type specific option for tj3client
  @tj3clientOption = nil
  # Base directory to store received sheets
  @sheetDir = nil
  # Base directory where to find the resource file.
  @templateDir = nil
  # Directory to store the failed emails.
  @failedMailsDir = nil
  # Directory to store the failed sheets
  @failedSheetsDir = nil
  # File that holds the acceptable signatures.
  @signatureFile = nil
  # The log file
  @logFile = nil
  # The subject of the confirmation email
  @emailSubject = nil

  # Regular expressions to identify a sheet.
  @sheetHeader = nil
  # Regular expression to extract the sheet signature (date).
  @signatureFilter = nil
  # The email address of the submitter of the sheet.
  @submitter = nil
  # The resource ID of the submitter.
  @resourceId = nil
  # The stdout content from tj3client
  @report = nil
  # The stderr content from tj3client
  @warnings = nil

  # The extracted sheet text.
  @sheet = nil
  # Will indicate whether the sheet was attached or in mail body
  @sheetWasAttached = true
  # The end date of the reporting period.
  @date = nil
  # The id of the incomming message.
  @messageId = nil
end

Instance Method Details

#processEmailObject

Read the sheet from $stdin in email format. Extract the sheet from the attachments or body and check it. If ok, send back a summary, otherwise the error message. The actual check is done by a tj3 server process that is accessed via tj3client.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/taskjuggler/SheetReceiver.rb', line 79

def processEmail
  setWorkingDir

  createDirectories

  begin
    # Read the RFC 822 compliant mail from STDIN.
    rawMail = $stdin.read
    rawMail = rawMail.forceUTF8Encoding

    mail = Mail.new(rawMail)
  rescue
    # In certain cases, Mail will fail to create the Mail object. Since we
    # don't have the email sender yet, we have to try to extract it
    # ourself.
    fromLine = nil
    rawMail.each_line do |line|
      unless fromLine
        matches = line.match('^From: .*')
        if matches
          fromLine = matches[0]
          break
        end
      end
    end

    # Try to extract the mail sender the dirty way so we can at least send
    # a response to the submitter.
    @submitter = fromLine[6..-1] if fromLine && fromLine.is_a?(String)
    error("Incoming mail could not be processed: #{$!}")
  end

  # Who sent this email?
  @submitter = mail.from.respond_to?('[]') ? mail.from[0] : mail.from
  # Getting the message ID.
  @messageId = mail.message_id || 'unknown'
  @idDigest = Digest::MD5.hexdigest(@messageId)
  info("Processing #{@sheetType} mail from #{@submitter} " +
       "with ID #{@messageId} (#{@idDigest})")

  # Store the mail in the failedMailsDir in case something goes wrong.
  File.open("#{@failedMailsDir}/#{@idDigest}", 'w') do |f|
    f.write(mail)
  end

  # First we search the attachments and then the body.
  mail.attachments.each do |attachment|
    # We are looking for an attached file with a .tji extension.
    fileName = attachment.filename
    next unless fileName && fileName[-4..-1] == '.tji'

    # Further inspect the attachment. If we could process it, we are done.
    return true if processSheet(attachment.body.decoded)
  end
  # None of the attachements worked, so let's try the mail body.
  @sheetWasAttached = false
  return true if processSheet(mail.body.decoded)

  error(<<"EOT"
No #{@sheetType} sheet found in email. Please make sure the header syntax is
correct and contained in a single line that starts at the begining of the
line. If you had the #{@sheetType} sheet attached, the file name must have a
'.tji' extension to be found.
EOT
       )
end