Merge branch 'develop' of git.znuny.com:zammad/zammad into develop

This commit is contained in:
Martin Edenhofer 2018-06-12 15:03:31 +02:00
commit 4b8e615640
219 changed files with 1629 additions and 2261 deletions

View file

@ -251,10 +251,7 @@ returns
def self.day_and_comment_by_event(event, start_time) def self.day_and_comment_by_event(event, start_time)
day = "#{start_time.year}-#{format('%02d', start_time.month)}-#{format('%02d', start_time.day)}" day = "#{start_time.year}-#{format('%02d', start_time.month)}-#{format('%02d', start_time.day)}"
comment = event.summary || event.description comment = event.summary || event.description
comment = Encode.conv( 'utf8', comment.to_s.force_encoding('utf-8') ) comment = comment.to_utf8(fallback: :read_as_sanitized_binary)
if !comment.valid_encoding?
comment = comment.encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
end
# ignore daylight saving time entries # ignore daylight saving time entries
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i) return if comment.match?(/(daylight saving|sommerzeit|summertime)/i)

View file

@ -10,11 +10,11 @@ process emails from STDIN
e. g. e. g.
cat test/fixtures/mail1.box | rails r 'Channel::Driver::MailStdin.new' cat test/data/mail/mail001.box | rails r 'Channel::Driver::MailStdin.new'
e. g. if you want to trust on mail headers e. g. if you want to trust on mail headers
cat test/fixtures/mail1.box | rails r 'Channel::Driver::MailStdin.new(trusted: true)' cat test/data/mail/mail001.box | rails r 'Channel::Driver::MailStdin.new(trusted: true)'
=end =end

View file

@ -3,6 +3,9 @@
# encoding: utf-8 # encoding: utf-8
class Channel::EmailParser class Channel::EmailParser
EMAIL_REGEX = /.+@.+/
RECIPIENT_FIELDS = %w[to cc delivered-to x-original-to envelope-to].freeze
SENDER_FIELDS = %w[from reply-to return-path].freeze
=begin =begin
@ -67,418 +70,16 @@ class Channel::EmailParser
=end =end
def parse(msg) def parse(msg)
data = {} mail = Mail.new(msg.utf8_encode)
# Rectify invalid encodings message_attributes = [
encoding = CharDet.detect(msg)['encoding'] { mail_instance: mail },
msg.force_encoding(encoding) if !msg.valid_encoding? message_header_hash(mail),
message_body_hash(mail),
self.class.sender_attributes(mail),
]
mail = Mail.new(msg) message_attributes.reduce({}.with_indifferent_access, &:merge)
# set all headers
mail.header.fields.each do |field|
# full line, encode, ready for storage
begin
value = Encode.conv('utf8', field.to_s)
if value.blank?
value = field.raw_value
end
data[field.name.to_s.downcase.to_sym] = value
rescue => e
data[field.name.to_s.downcase.to_sym] = field.raw_value
end
# if we need to access the lines by objects later again
data["raw-#{field.name.downcase}".to_sym] = field
end
# verify content, ignore recipients with non email address
['to', 'cc', 'delivered-to', 'x-original-to', 'envelope-to'].each do |field|
next if data[field.to_sym].blank?
next if data[field.to_sym].match?(/@/)
data[field.to_sym] = ''
end
# get sender with @ / email address
from = nil
['from', 'reply-to', 'return-path'].each do |item|
next if data[item.to_sym].blank?
next if data[item.to_sym] !~ /@/
from = data[item.to_sym]
break if from
end
# in case of no sender with email address - get sender
if !from
['from', 'reply-to', 'return-path'].each do |item|
next if data[item.to_sym].blank?
from = data[item.to_sym]
break if from
end
end
# set x-any-recipient
data['x-any-recipient'.to_sym] = ''
['to', 'cc', 'delivered-to', 'x-original-to', 'envelope-to'].each do |item|
next if data[item.to_sym].blank?
if data['x-any-recipient'.to_sym] != ''
data['x-any-recipient'.to_sym] += ', '
end
data['x-any-recipient'.to_sym] += mail[item.to_sym].to_s
end
# set extra headers
data = data.merge(Channel::EmailParser.sender_properties(from))
# do extra encoding (see issue#1045)
if data[:subject].present?
data[:subject].sub!(/^=\?us-ascii\?Q\?(.+)\?=$/, '\1')
end
# compat headers
data[:message_id] = data['message-id'.to_sym]
# body
# plain_part = mail.multipart? ? (mail.text_part ? mail.text_part.body.decoded : nil) : mail.body.decoded
# html_part = message.html_part ? message.html_part.body.decoded : nil
data[:attachments] = []
# multi part email
if mail.multipart?
# html attachment/body may exists and will be converted to strict html
if mail.html_part&.body
data[:body] = mail.html_part.body.to_s
data[:body] = Encode.conv(mail.html_part.charset.to_s, data[:body])
data[:body] = data[:body].html2html_strict.to_s.force_encoding('utf-8')
if !data[:body].force_encoding('UTF-8').valid_encoding?
data[:body] = data[:body].encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
end
data[:content_type] = 'text/html'
end
# text attachment/body exists
if data[:body].blank? && mail.text_part
data[:body] = mail.text_part.body.decoded
data[:body] = Encode.conv(mail.text_part.charset, data[:body])
data[:body] = data[:body].to_s.force_encoding('utf-8')
if !data[:body].valid_encoding?
data[:body] = data[:body].encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
end
data[:content_type] = 'text/plain'
end
# any other attachments
if data[:body].blank?
data[:body] = 'no visible content'
data[:content_type] = 'text/plain'
end
# add html attachment/body as real attachment
if mail.html_part
filename = 'message.html'
headers_store = {
'content-alternative' => true,
'original-format' => true,
}
if mail.mime_type
headers_store['Mime-Type'] = mail.html_part.mime_type
end
if mail.charset
headers_store['Charset'] = mail.html_part.charset
end
attachment = {
data: mail.html_part.body.to_s,
filename: mail.html_part.filename || filename,
preferences: headers_store
}
data[:attachments].push attachment
end
# get attachments
mail.parts&.each do |part|
# protect process to work fine with spam emails, see test/fixtures/mail15.box
begin
attachs = _get_attachment(part, data[:attachments], mail)
data[:attachments].concat(attachs)
rescue
attachs = _get_attachment(part, data[:attachments], mail)
data[:attachments].concat(attachs)
end
end
# not multipart email
# html part only, convert to text and add it as attachment
elsif mail.mime_type && mail.mime_type.to_s.casecmp('text/html').zero?
filename = 'message.html'
data[:body] = mail.body.decoded
data[:body] = Encode.conv(mail.charset, data[:body])
data[:body] = data[:body].html2html_strict.to_s.force_encoding('utf-8')
if !data[:body].valid_encoding?
data[:body] = data[:body].encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
end
data[:content_type] = 'text/html'
# add body as attachment
headers_store = {
'content-alternative' => true,
'original-format' => true,
}
if mail.mime_type
headers_store['Mime-Type'] = mail.mime_type
end
if mail.charset
headers_store['Charset'] = mail.charset
end
attachment = {
data: mail.body.decoded,
filename: mail.filename || filename,
preferences: headers_store
}
data[:attachments].push attachment
# text part only
elsif !mail.mime_type || mail.mime_type.to_s == '' || mail.mime_type.to_s.casecmp('text/plain').zero?
data[:body] = mail.body.decoded
data[:body] = Encode.conv(mail.charset, data[:body])
if !data[:body].force_encoding('UTF-8').valid_encoding?
data[:body] = data[:body].encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
end
data[:content_type] = 'text/plain'
else
filename = '-no name-'
data[:body] = 'no visible content'
data[:content_type] = 'text/plain'
# add body as attachment
headers_store = {
'content-alternative' => true,
}
if mail.mime_type
headers_store['Mime-Type'] = mail.mime_type
end
if mail.charset
headers_store['Charset'] = mail.charset
end
attachment = {
data: mail.body.decoded,
filename: mail.filename || filename,
preferences: headers_store
}
data[:attachments].push attachment
end
# strip not wanted chars
data[:body].gsub!(/\n\r/, "\n")
data[:body].gsub!(/\r\n/, "\n")
data[:body].tr!("\r", "\n")
# get mail date
begin
if mail.date
data[:date] = Time.zone.parse(mail.date.to_s)
end
rescue
data[:date] = nil
end
# remember original mail instance
data[:mail_instance] = mail
data
end
def _get_attachment(file, attachments, mail)
# check if sub parts are available
if file.parts.present?
list = []
file.parts.each do |p|
attachment = _get_attachment(p, attachments, mail)
list.concat(attachment)
end
return list
end
# ignore text/plain attachments - already shown in view
return [] if mail.text_part&.body.to_s == file.body.to_s
# ignore text/html - html part, already shown in view
return [] if mail.html_part&.body.to_s == file.body.to_s
# get file preferences
headers_store = {}
file.header.fields.each do |field|
# full line, encode, ready for storage
begin
value = Encode.conv('utf8', field.to_s)
if value.blank?
value = field.raw_value
end
headers_store[field.name.to_s] = value
rescue => e
headers_store[field.name.to_s] = field.raw_value
end
end
# cleanup content id, <> will be added automatically later
if headers_store['Content-ID']
headers_store['Content-ID'].gsub!(/^</, '')
headers_store['Content-ID'].gsub!(/>$/, '')
end
# get filename from content-disposition
filename = nil
# workaround for: NoMethodError: undefined method `filename' for #<Mail::UnstructuredField:0x007ff109e80678>
begin
filename = file.header[:content_disposition].filename
rescue
begin
if file.header[:content_disposition].to_s =~ /filename="(.+?)"/i
filename = $1
elsif file.header[:content_disposition].to_s =~ /filename='(.+?)'/i
filename = $1
elsif file.header[:content_disposition].to_s =~ /filename=(.+?);/i
filename = $1
end
rescue
Rails.logger.debug { 'Unable to get filename' }
end
end
# as fallback, use raw values
if filename.blank?
if headers_store['Content-Disposition'].to_s =~ /filename="(.+?)"/i
filename = $1
elsif headers_store['Content-Disposition'].to_s =~ /filename='(.+?)'/i
filename = $1
elsif headers_store['Content-Disposition'].to_s =~ /filename=(.+?);/i
filename = $1
end
end
# for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5)
filename ||= file.header[:content_location].to_s
# generate file name based on content-id
if filename.blank? && headers_store['Content-ID'].present?
if headers_store['Content-ID'] =~ /(.+?)@.+?/i
filename = $1
end
end
# generate file name based on content type
if filename.blank? && headers_store['Content-Type'].present?
if headers_store['Content-Type'].match?(%r{^message/rfc822}i)
begin
parser = Channel::EmailParser.new
mail_local = parser.parse(file.body.to_s)
filename = if mail_local[:subject].present?
"#{mail_local[:subject]}.eml"
elsif headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.eml".to_s.force_encoding('utf-8')
else
'Mail.eml'
end
rescue
filename = 'Mail.eml'
end
end
# e. g. Content-Type: video/quicktime; name="Video.MOV";
if filename.blank?
['name="(.+?)"(;|$)', "name='(.+?)'(;|$)", 'name=(.+?)(;|$)'].each do |regexp|
if headers_store['Content-Type'] =~ /#{regexp}/i
filename = $1
break
end
end
end
# e. g. Content-Type: video/quicktime
if filename.blank?
map = {
'message/delivery-status': ['txt', 'delivery-status'],
'text/plain': %w[txt document],
'text/html': %w[html document],
'video/quicktime': %w[mov video],
'image/jpeg': %w[jpg image],
'image/jpg': %w[jpg image],
'image/png': %w[png image],
'image/gif': %w[gif image],
}
map.each do |type, ext|
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
filename = if headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
else
"#{ext[1]}.#{ext[0]}"
end
break
end
end
end
if filename.blank?
filename = 'file'
end
attachment_count = 0
local_filename = ''
local_extention = ''
if filename =~ /^(.*?)\.(.+?)$/
local_filename = $1
local_extention = $2
end
(1..1000).each do |count|
filename_exists = false
attachments.each do |attachment|
if attachment[:filename] == filename
filename_exists = true
end
end
break if filename_exists == false
filename = if local_extention.present?
"#{local_filename}#{count}.#{local_extention}"
else
"#{local_filename}#{count}"
end
end
# get mime type
if file.header[:content_type]&.string
headers_store['Mime-Type'] = file.header[:content_type].string
end
# get charset
if file.header&.charset
headers_store['Charset'] = file.header.charset
end
# remove not needed header
headers_store.delete('Content-Transfer-Encoding')
headers_store.delete('Content-Disposition')
# workaround for mail gem
# https://github.com/zammad/zammad/issues/928
filename = Mail::Encodings.value_decode(filename)
attach = {
data: file.body.to_s,
filename: filename,
preferences: headers_store,
}
[attach]
end end
=begin =begin
@ -669,7 +270,7 @@ returns
mail[:attachments]&.each do |attachment| mail[:attachments]&.each do |attachment|
filename = attachment[:filename].force_encoding('utf-8') filename = attachment[:filename].force_encoding('utf-8')
if !filename.force_encoding('UTF-8').valid_encoding? if !filename.force_encoding('UTF-8').valid_encoding?
filename = filename.encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?') filename = filename.utf8_encode(fallback: :read_as_sanitized_binary)
end end
Store.add( Store.add(
object: 'Ticket::Article', object: 'Ticket::Article',
@ -728,45 +329,51 @@ returns
true true
end end
def self.sender_properties(from) def self.sender_attributes(from)
data = {} if from.is_a?(Mail::Message)
return data if from.blank? from = SENDER_FIELDS.map { |f| from.header[f] }.compact
begin .map(&:to_utf8).reject(&:blank?)
list = Mail::AddressList.new(from) .partition { |address| address.match?(EMAIL_REGEX) }
list.addresses.each do |address| .flatten.first
data[:from_email] = address.address
data[:from_local] = address.local
data[:from_domain] = address.domain
data[:from_display_name] = address.display_name ||
(address.comments && address.comments[0])
break if data[:from_email].present? && data[:from_email] =~ /@/
end
rescue => e
if from =~ /<>/ && from =~ /<.+?>/
data = sender_properties(from.gsub(/<>/, ''))
end
end end
if data.blank? || data[:from_email].blank? data = {}.with_indifferent_access
from.strip! return data if from.blank?
if from =~ /^(.+?)<(.+?)@(.+?)>$/
data[:from_email] = "#{$2}@#{$3}" from = from.gsub('<>', '').strip
data[:from_local] = $2 mail_address = begin
data[:from_domain] = $3 Mail::AddressList.new(from).addresses
.select { |a| a.address.present? }
.partition { |a| a.address.match?(EMAIL_REGEX) }
.flatten.first
rescue Mail::Field::ParseError => e
STDOUT.puts e
end
if mail_address&.address.present?
data[:from_email] = mail_address.address
data[:from_local] = mail_address.local
data[:from_domain] = mail_address.domain
data[:from_display_name] = mail_address.display_name || mail_address.comments&.first
elsif from =~ /^(.+?)<((.+?)@(.+?))>$/
data[:from_email] = $2
data[:from_local] = $3
data[:from_domain] = $4
data[:from_display_name] = $1 data[:from_display_name] = $1
else else
data[:from_email] = from data[:from_email] = from
data[:from_local] = from data[:from_local] = from
data[:from_domain] = from data[:from_domain] = from
end data[:from_display_name] = from
end end
# do extra decoding because we needed to use field.value # do extra decoding because we needed to use field.value
data[:from_display_name] = Mail::Field.new('X-From', Encode.conv('utf8', data[:from_display_name])).to_s data[:from_display_name] =
data[:from_display_name].delete!('"') Mail::Field.new('X-From', data[:from_display_name].to_utf8)
data[:from_display_name].strip! .to_s
data[:from_display_name].gsub!(/^'/, '') .delete('"')
data[:from_display_name].gsub!(/'$/, '') .strip
.gsub(/(^'|'$)/, '')
data data
end end
@ -855,6 +462,270 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
files files
end end
private
def message_header_hash(mail)
imported_fields = mail.header.fields.map do |f|
value = begin
f.to_utf8
rescue NameError # handle bug #1238 in Mail 2.7.1.rc1
'' # swap out for commented line below once upgrade is available
end
[f.name.downcase, value]
end.to_h
# imported_fields = mail.header.fields.map { |f| [f.name.downcase, f.to_utf8] }.to_h
raw_fields = mail.header.fields.map { |f| ["raw-#{f.name.downcase}", f] }.to_h
custom_fields = {}.tap do |h|
validated_recipients = imported_fields.slice(*RECIPIENT_FIELDS)
.transform_values { |v| v.match?(EMAIL_REGEX) ? v : '' }
h.merge!(validated_recipients)
h['date'] = Time.zone.parse(mail.date.to_s) || imported_fields['date']
h['message_id'] = imported_fields['message-id']
h['subject'] = imported_fields['subject']&.sub(/^=\?us-ascii\?Q\?(.+)\?=$/, '\1')
h['x-any-recipient'] = validated_recipients.values.select(&:present?).join(', ')
end
[imported_fields, raw_fields, custom_fields].reduce({}.with_indifferent_access, &:merge)
end
def message_body_hash(mail)
message = [mail.html_part, mail.text_part, mail].find { |m| m&.body.present? }
if message.mime_type.nil? || message.mime_type.match?(%r{^text/(plain|html)$})
content_type = message.mime_type || 'text/plain'
body = body_text(message, strict_html: content_type.eql?('text/html'))
end
content_type = 'text/plain' if body.blank?
{
attachments: collect_attachments(mail),
content_type: content_type || 'text/plain',
body: body.presence || 'no visible content'
}.with_indifferent_access
end
def body_text(message, **options)
body_text = begin
message.body.to_s
rescue Mail::UnknownEncodingType # see test/data/mail/mail043.box / issue #348
message.body.raw_source
end
body_text = body_text.utf8_encode(from: message.charset, fallback: :read_as_sanitized_binary)
body_text = Mail::Utilities.to_lf(body_text)
return body_text.html2html_strict if options[:strict_html]
body_text
end
def collect_attachments(mail)
attachments = []
# Add non-plaintext body as an attachment
if mail.html_part&.body.present? ||
(!mail.multipart? && mail.mime_type.present? && mail.mime_type != 'text/plain')
message = mail.html_part || mail
filename = message.filename.presence ||
(message.mime_type.eql?('text/html') ? 'message.html' : '-no name-')
headers_store = {
'content-alternative' => true,
'original-format' => message.mime_type.eql?('text/html'),
'Mime-Type' => message.mime_type,
'Charset' => message.charset,
}.reject { |_, v| v.blank? }
attachments.push({ data: body_text(message),
filename: filename,
preferences: headers_store })
end
mail.parts.each do |part|
begin
new_attachments = get_attachments(part, attachments, mail).flatten.compact
attachments.push(*new_attachments)
rescue => e # Protect process to work with spam emails (see test/fixtures/mail15.box)
raise e if (fail_count ||= 0).positive?
(fail_count += 1) && retry
end
end
attachments
end
def get_attachments(file, attachments, mail)
return file.parts.map { |p| get_attachments(p, attachments, mail) } if file.parts.any?
return [] if [mail.text_part, mail.html_part].include?(file)
# get file preferences
headers_store = {}
file.header.fields.each do |field|
# full line, encode, ready for storage
begin
value = field.to_utf8
if value.blank?
value = field.raw_value
end
headers_store[field.name.to_s] = value
rescue => e
headers_store[field.name.to_s] = field.raw_value
end
end
# cleanup content id, <> will be added automatically later
if headers_store['Content-ID']
headers_store['Content-ID'].gsub!(/^</, '')
headers_store['Content-ID'].gsub!(/>$/, '')
end
# get filename from content-disposition
# workaround for: NoMethodError: undefined method `filename' for #<Mail::UnstructuredField:0x007ff109e80678>
filename = file.header[:content_disposition].try(:filename)
begin
if file.header[:content_disposition].to_s =~ /filename="(.+?)"/i
filename = $1
elsif file.header[:content_disposition].to_s =~ /filename='(.+?)'/i
filename = $1
elsif file.header[:content_disposition].to_s =~ /filename=(.+?);/i
filename = $1
end
rescue
Rails.logger.debug { 'Unable to get filename' }
end
# as fallback, use raw values
if filename.blank?
if headers_store['Content-Disposition'].to_s =~ /filename="(.+?)"/i
filename = $1
elsif headers_store['Content-Disposition'].to_s =~ /filename='(.+?)'/i
filename = $1
elsif headers_store['Content-Disposition'].to_s =~ /filename=(.+?);/i
filename = $1
end
end
# for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5)
filename ||= file.header[:content_location].to_s
# generate file name based on content-id
if filename.blank? && headers_store['Content-ID'].present?
if headers_store['Content-ID'] =~ /(.+?)@.+?/i
filename = $1
end
end
# generate file name based on content type
if filename.blank? && headers_store['Content-Type'].present?
if headers_store['Content-Type'].match?(%r{^message/rfc822}i)
begin
parser = Channel::EmailParser.new
mail_local = parser.parse(file.body.to_s)
filename = if mail_local[:subject].present?
"#{mail_local[:subject]}.eml"
elsif headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.eml".to_s.force_encoding('utf-8')
else
'Mail.eml'
end
rescue
filename = 'Mail.eml'
end
end
# e. g. Content-Type: video/quicktime; name="Video.MOV";
if filename.blank?
['name="(.+?)"(;|$)', "name='(.+?)'(;|$)", 'name=(.+?)(;|$)'].each do |regexp|
if headers_store['Content-Type'] =~ /#{regexp}/i
filename = $1
break
end
end
end
# e. g. Content-Type: video/quicktime
if filename.blank?
map = {
'message/delivery-status': ['txt', 'delivery-status'],
'text/plain': %w[txt document],
'text/html': %w[html document],
'video/quicktime': %w[mov video],
'image/jpeg': %w[jpg image],
'image/jpg': %w[jpg image],
'image/png': %w[png image],
'image/gif': %w[gif image],
}
map.each do |type, ext|
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
filename = if headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
else
"#{ext[1]}.#{ext[0]}"
end
break
end
end
end
if filename.blank?
filename = 'file'
end
local_filename = ''
local_extention = ''
if filename =~ /^(.*?)\.(.+?)$/
local_filename = $1
local_extention = $2
end
1.upto(1000) do |i|
filename_exists = false
attachments.each do |attachment|
if attachment[:filename] == filename
filename_exists = true
end
end
break if filename_exists == false
filename = if local_extention.present?
"#{local_filename}#{i}.#{local_extention}"
else
"#{local_filename}#{i}"
end
end
# get mime type
if file.header[:content_type]&.string
headers_store['Mime-Type'] = file.header[:content_type].string
end
# get charset
if file.header&.charset
headers_store['Charset'] = file.header.charset
end
# remove not needed header
headers_store.delete('Content-Transfer-Encoding')
headers_store.delete('Content-Disposition')
# workaround for mail gem
# https://github.com/zammad/zammad/issues/928
filename = Mail::Encodings.value_decode(filename)
attach = {
data: file.body.to_s,
filename: filename,
preferences: headers_store,
}
[attach]
end
end end
module Mail module Mail
@ -862,7 +733,7 @@ module Mail
# workaround to get content of no parseable headers - in most cases with non 7 bit ascii signs # workaround to get content of no parseable headers - in most cases with non 7 bit ascii signs
class Field class Field
def raw_value def raw_value
value = Encode.conv('utf8', @raw_value) value = @raw_value.try(:utf8_encode)
return value if value.blank? return value if value.blank?
value.sub(/^.+?:(\s|)/, '') value.sub(/^.+?:(\s|)/, '')
end end
@ -903,19 +774,4 @@ module Mail
end.join('') end.join('')
end end
end end
# issue#348 - IMAP mail fetching stops because of broken spam email (e. g. broken Content-Transfer-Encoding value see test/fixtures/mail43.box)
# https://github.com/zammad/zammad/issues/348
class Body
def decoded
if !Encodings.defined?(encoding)
#raise UnknownEncodingType, "Don't know how to decode #{encoding}, please call #encoded and decode it yourself."
Rails.logger.info "UnknownEncodingType: Don't know how to decode #{encoding}!"
raw_source
else
Encodings.get_encoding(encoding).decode(raw_source)
end
end
end
end end

View file

@ -19,7 +19,7 @@ module Channel::Filter::ReplyToBasedSender
mail['origin_from_display_name'.to_sym] = mail[:from_display_name] mail['origin_from_display_name'.to_sym] = mail[:from_display_name]
# get properties of reply-to header # get properties of reply-to header
result = Channel::EmailParser.sender_properties(reply_to) result = Channel::EmailParser.sender_attributes(reply_to)
if setting == 'as_sender_of_email' if setting == 'as_sender_of_email'

View file

@ -61,7 +61,7 @@ end
if connection.execute("SHOW tables LIKE 'settings';").any? && if connection.execute("SHOW tables LIKE 'settings';").any? &&
Setting.get('postmaster_max_size').present? && Setting.get('postmaster_max_size').present? &&
Setting.get('postmaster_max_size') > max_allowed_packet_mb Setting.get('postmaster_max_size').to_i > max_allowed_packet_mb
printf "\e[33m" # ANSI yellow printf "\e[33m" # ANSI yellow
puts <<~MSG puts <<~MSG
Warning: Database config value 'max_allowed_packet' less than Zammad setting 'Maximum Email Size' Warning: Database config value 'max_allowed_packet' less than Zammad setting 'Maximum Email Size'

5
lib/core_ext/object.rb Normal file
View file

@ -0,0 +1,5 @@
class Object
def to_utf8(**options)
to_s.utf8_encode(**options)
end
end

View file

@ -1,3 +1,5 @@
require 'rchardet'
class String class String
alias old_strip strip alias old_strip strip
alias old_strip! strip! alias old_strip! strip!
@ -8,7 +10,7 @@ class String
sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '') sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '')
# if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default # if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default
rescue rescue Encoding::CompatibilityError
old_strip! old_strip!
end end
self self
@ -20,7 +22,7 @@ class String
new_string.sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '') new_string.sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '')
# if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default # if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default
rescue rescue Encoding::CompatibilityError
new_string = old_strip new_string = old_strip
end end
new_string new_string
@ -109,7 +111,7 @@ class String
string = "#{self}" # rubocop:disable Style/UnneededInterpolation string = "#{self}" # rubocop:disable Style/UnneededInterpolation
# in case of invalid encoding, strip invalid chars # in case of invalid encoding, strip invalid chars
# see also test/fixtures/mail21.box # see also test/data/mail/mail021.box
# note: string.encode!('UTF-8', 'UTF-8', :invalid => :replace, :replace => '?') was not detecting invalid chars # note: string.encode!('UTF-8', 'UTF-8', :invalid => :replace, :replace => '?') was not detecting invalid chars
if !string.valid_encoding? if !string.valid_encoding?
string = string.chars.select(&:valid_encoding?).join string = string.chars.select(&:valid_encoding?).join
@ -451,4 +453,59 @@ class String
string string
end end
# Returns a copied string whose encoding is UTF-8.
# If both the provided and current encodings are invalid,
# an auto-detected encoding is tried.
#
# Supports some fallback strategies if a valid encoding cannot be found.
#
# Options:
#
# * from: An encoding to try first.
# Takes precedence over the current and auto-detected encodings.
#
# * fallback: The strategy to follow if no valid encoding can be found.
# * `:output_to_binary` returns an ASCII-8BIT-encoded string.
# * `:read_as_sanitized_binary` returns a UTF-8-encoded string with all
# invalid byte sequences replaced with "?" characters.
def utf8_encode(**options)
dup.utf8_encode!(options)
end
def utf8_encode!(**options)
return self if (encoding == Encoding::UTF_8) && valid_encoding?
input_encoding = viable_encodings(try_first: options[:from]).first
return encode!('utf-8', input_encoding) if input_encoding.present?
case options[:fallback]
when :output_to_binary
force_encoding('ascii-8bit')
when :read_as_sanitized_binary
encode!('utf-8', 'ascii-8bit', invalid: :replace, undef: :replace, replace: '?')
else
raise EncodingError, 'could not find a valid input encoding'
end
end
private
def viable_encodings(try_first: nil)
return dup.viable_encodings(try_first: try_first) if frozen?
provided = Encoding.find(try_first) if try_first.present?
original = encoding
detected = CharDet.detect(self)['encoding']
[provided, original, detected]
.compact
.reject { |e| Encoding.find(e) == Encoding::ASCII_8BIT }
.select { |e| force_encoding(e).valid_encoding? }
.tap { force_encoding(original) } # clean up changes from previous line
# if `try_first` is not a valid encoding, try_first again without it
rescue ArgumentError
try_first.present? ? viable_encodings : raise
end
end end

View file

@ -1,37 +0,0 @@
module Encode
def self.conv (charset, string)
# return if string is false
return string if !string
# if no charset is given, use LATIN1 as default
if !charset || charset == 'US-ASCII' || charset == 'ASCII-8BIT'
charset = 'ISO-8859-15'
end
# validate already existing utf8 strings
if charset.casecmp('utf8').zero? || charset.casecmp('utf-8').zero?
begin
# return if encoding is valid
utf8 = string.dup.force_encoding('UTF-8')
return utf8 if utf8.valid_encoding?
# try to encode from Windows-1252 to utf8
string.encode!('UTF-8', 'Windows-1252')
rescue EncodingError => e
Rails.logger.error "Bad encoding: #{string.inspect}"
string = string.encode!('UTF-8', invalid: :replace, undef: :replace, replace: '?')
end
return string
end
# convert string
begin
string.encode!('UTF-8', charset)
rescue => e
Rails.logger.error 'ERROR: ' + e.inspect
string
end
#Iconv.conv( 'UTF8', charset, string)
end
end

View file

@ -119,9 +119,9 @@ module Enrichment
def fetch def fetch
if !Rails.env.production? if !Rails.env.production?
filename = Rails.root.join('test', 'fixtures', 'clearbit', "#{@local_user.email}.json") filename = Rails.root.join('test', 'data', 'clearbit', "#{@local_user.email}.json")
if File.exist?(filename) if File.exist?(filename)
data = IO.binread(filename) data = File.binread(filename)
return JSON.parse(data) if data return JSON.parse(data) if data
end end
end end

View file

@ -373,40 +373,35 @@ cleanup html string:
string.gsub('&amp;', '&').gsub('&lt;', '<').gsub('&gt;', '>').gsub('&quot;', '"').gsub('&nbsp;', ' ') string.gsub('&amp;', '&').gsub('&lt;', '<').gsub('&gt;', '>').gsub('&quot;', '"').gsub('&nbsp;', ' ')
end end
def self.cleanup_target(string, keep_spaces: false) def self.cleanup_target(string, **options)
string = CGI.unescape(string).encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?') cleaned_string = CGI.unescape(string).utf8_encode(fallback: :read_as_sanitized_binary)
blank_regex = if keep_spaces cleaned_string = cleaned_string.gsub(/[[:space:]]/, '') if !options[:keep_spaces]
/\t|\n|\r/ cleaned_string = cleaned_string.strip
else .delete("\t\n\r\u0000")
/[[:space:]]|\t|\n|\r/ .gsub(%r{/\*.*?\*/}, '')
end .gsub(/<!--.*?-->/, '')
cleaned_string = string.strip.gsub(blank_regex, '').gsub(%r{/\*.*?\*/}, '').gsub(/<!--.*?-->/, '').gsub(/\[.+?\]/, '').delete("\u0000") .gsub(/\[.+?\]/, '')
sanitize_attachment_disposition(cleaned_string) sanitize_attachment_disposition(cleaned_string)
end end
def self.sanitize_attachment_disposition(url) def self.sanitize_attachment_disposition(url)
uri = URI(url) uri = URI(url)
return url if uri.host != Setting.get('fqdn')
if uri.host == Setting.get('fqdn') && uri.query.present?
params = CGI.parse(uri.query || '') params = CGI.parse(uri.query || '')
if params.key?('disposition') .tap { |p| p.merge!('disposition' => 'attachment') if p.include?('disposition') }
params['disposition'] = 'attachment' uri.query = URI.encode_www_form(params)
end
uri.query = if params.blank?
nil
else
URI.encode_www_form(params)
end end
uri.to_s uri.to_s
rescue URI::InvalidURIError rescue URI::Error
url url
end end
def self.url_same?(url_new, url_old) def self.url_same?(url_new, url_old)
url_new = CGI.unescape(url_new.to_s).encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?').downcase.gsub(%r{/$}, '').gsub(/[[:space:]]|\t|\n|\r/, '').strip url_new = CGI.unescape(url_new.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.gsub(%r{/$}, '').gsub(/[[:space:]]|\t|\n|\r/, '').strip
url_old = CGI.unescape(url_old.to_s).encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?').downcase.gsub(%r{/$}, '').gsub(/[[:space:]]|\t|\n|\r/, '').strip url_old = CGI.unescape(url_old.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.gsub(%r{/$}, '').gsub(/[[:space:]]|\t|\n|\r/, '').strip
url_new = html_decode(url_new).sub('/?', '?') url_new = html_decode(url_new).sub('/?', '?')
url_old = html_decode(url_old).sub('/?', '?') url_old = html_decode(url_old).sub('/?', '?')
return true if url_new == url_old return true if url_new == url_old
@ -485,6 +480,7 @@ satinize style of img tags
end end
private_class_method :cleanup_target private_class_method :cleanup_target
private_class_method :sanitize_attachment_disposition
private_class_method :add_link private_class_method :add_link
private_class_method :url_same? private_class_method :url_same?
private_class_method :html_decode private_class_method :html_decode

View file

@ -22,8 +22,8 @@ module Import
def utf8_encode(data) def utf8_encode(data)
data.each do |key, value| data.each do |key, value|
next if !value next if !value
next if value.class != String next if !value.respond_to?(:utf8_encode)
data[key] = Encode.conv('utf8', value) data[key] = value.utf8_encode
end end
end end

View file

@ -58,7 +58,7 @@ module Import
next if value.nil? next if value.nil?
example = value.to_s.force_encoding('UTF-8').encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?') example = value.to_utf8(fallback: :read_as_sanitized_binary)
example.gsub!(/^(.{20,}?).*$/m, '\1...') example.gsub!(/^(.{20,}?).*$/m, '\1...')
@examples[attribute] = "#{attribute} (e. g. #{example})" @examples[attribute] = "#{attribute} (e. g. #{example})"

View file

@ -94,9 +94,9 @@ module Import
end end
def handle_response(response) def handle_response(response)
encoded_body = Encode.conv('utf8', response.body.to_s) encoded_body = response.body.to_utf8
# remove null bytes otherwise PostgreSQL will fail # remove null bytes otherwise PostgreSQL will fail
encoded_body.gsub!('\u0000', '') encoded_body.delete('\u0000')
JSON.parse(encoded_body) JSON.parse(encoded_body)
end end

View file

@ -144,7 +144,7 @@ class Ldap
next if value.blank? next if value.blank?
next if value[0].blank? next if value[0].blank?
example_value = value[0].force_encoding('UTF-8').encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?') example_value = value[0].force_encoding('UTF-8').utf8_encode(fallback: :read_as_sanitized_binary)
attributes[attribute] = "#{attribute} (e. g. #{example_value})" attributes[attribute] = "#{attribute} (e. g. #{example_value})"
end end

View file

@ -0,0 +1,58 @@
require 'rails_helper'
RSpec.describe String do
describe '#utf8_encode' do
context 'for valid, UTF-8-encoded strings' do
let(:subject) { 'hello' }
it 'returns an identical copy' do
expect(subject.utf8_encode).to eq(subject)
expect(subject.utf8_encode.encoding).to be(subject.encoding)
expect(subject.utf8_encode).not_to be(subject)
end
end
context 'for strings in other encodings' do
let(:subject) { original_string.encode(input_encoding) }
context 'with no from: option' do
let(:original_string) { 'Tschüss!' }
let(:input_encoding) { Encoding::ISO_8859_2 }
it 'detects the input encoding' do
expect(subject.utf8_encode).to eq(original_string)
end
end
context 'with a valid from: option' do
let(:original_string) { 'Tschüss!' }
let(:input_encoding) { Encoding::ISO_8859_2 }
it 'uses the specified input encoding' do
expect(subject.utf8_encode(from: 'iso-8859-2')).to eq(original_string)
end
it 'uses any valid input encoding, even if not correct' do
expect(subject.utf8_encode(from: 'gb18030')).to eq('Tsch黶s!')
end
end
context 'with an invalid from: option' do
let(:original_string) { '―陈志' }
let(:input_encoding) { Encoding::GB18030 }
it 'does not try it' do
expect { subject.encode('utf-8', 'gb2312') }
.to raise_error(Encoding::InvalidByteSequenceError)
expect { subject.utf8_encode(from: 'gb2312') }
.not_to raise_error(Encoding::InvalidByteSequenceError)
end
it 'uses the detected input encoding instead' do
expect(subject.utf8_encode(from: 'gb2312')).to eq(original_string)
end
end
end
end
end

View file

@ -45,7 +45,8 @@ class AgentTicketAttachmentTest < TestCase
# add attachment, attachment check should quiet # add attachment, attachment check should quiet
file_upload( file_upload(
css: '.content.active .attachmentPlaceholder-inputHolder input', css: '.content.active .attachmentPlaceholder-inputHolder input',
files: ['test/fixtures/upload2.jpg', 'test/fixtures/upload1.txt'], files: [Rails.root.join('test', 'data', 'upload', 'upload1.txt'),
Rails.root.join('test', 'data', 'upload', 'upload2.jpg')],
) )
# submit form # submit form
@ -91,7 +92,7 @@ class AgentTicketAttachmentTest < TestCase
# add attachment, attachment check should quiet # add attachment, attachment check should quiet
file_upload( file_upload(
css: '.content.active .attachmentPlaceholder-inputHolder input', css: '.content.active .attachmentPlaceholder-inputHolder input',
files: ['test/fixtures/upload1.txt'], files: [Rails.root.join('test', 'data', 'upload', 'upload1.txt')],
) )
# submit form # submit form
@ -132,7 +133,8 @@ class AgentTicketAttachmentTest < TestCase
# add attachment without body # add attachment without body
file_upload( file_upload(
css: '.content.active .attachmentPlaceholder-inputHolder input', css: '.content.active .attachmentPlaceholder-inputHolder input',
files: ['test/fixtures/upload2.jpg', 'test/fixtures/upload1.txt'], files: [Rails.root.join('test', 'data', 'upload', 'upload1.txt'),
Rails.root.join('test', 'data', 'upload', 'upload2.jpg')],
) )
# submit form # submit form

View file

@ -1226,7 +1226,7 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
file_upload( file_upload(
browser: browser1, browser: browser1,
css: '.content.active .attachmentPlaceholder-inputHolder input' css: '.content.active .attachmentPlaceholder-inputHolder input'
files: ['path/in/home/some_file.ext'], # 'test/fixtures/test1.pdf' files: ['path/in/home/some_file.ext'], # 'test/data/pdf/test1.pdf'
) )
=end =end

View file

@ -531,7 +531,8 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
# invalid file # invalid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple_col_not_existing.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'organization_simple_col_not_existing.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/organizations/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/organizations/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -545,7 +546,8 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest
assert_equal("Line 2: unknown attribute 'name2' for Organization.", result['errors'][1]) assert_equal("Line 2: unknown attribute 'name2' for Organization.", result['errors'][1])
# valid file try # valid file try
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'organization_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/organizations/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/organizations/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -559,7 +561,8 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest
assert_nil(Organization.find_by(name: 'organization-member-import2')) assert_nil(Organization.find_by(name: 'organization-member-import2'))
# valid file # valid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'organization_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/organizations/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/organizations/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)

View file

@ -101,7 +101,8 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
# invalid file # invalid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple_col_not_existing.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'text_module_simple_col_not_existing.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/text_modules/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/text_modules/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -115,7 +116,8 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest
assert_equal("Line 2: unknown attribute 'keywords2' for TextModule.", result['errors'][1]) assert_equal("Line 2: unknown attribute 'keywords2' for TextModule.", result['errors'][1])
# valid file try # valid file try
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'text_module_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/text_modules/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/text_modules/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -129,7 +131,8 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest
assert_nil(TextModule.find_by(name: 'some name2')) assert_nil(TextModule.find_by(name: 'some name2'))
# valid file # valid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'text_module_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/text_modules/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/text_modules/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)

View file

@ -144,7 +144,8 @@ class TicketArticleAttachmentsControllerTest < ActionDispatch::IntegrationTest
test '01.02 test attachments for split' do test '01.02 test attachments for split' do
headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' } headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
email_raw_string = IO.binread('test/fixtures/mail24.box') email_file_path = Rails.root.join('test', 'data', 'mail', 'mail024.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string) ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
@ -161,7 +162,8 @@ class TicketArticleAttachmentsControllerTest < ActionDispatch::IntegrationTest
test '01.03 test attachments for forward' do test '01.03 test attachments for forward' do
headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' } headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
email_raw_string = IO.binread('test/fixtures/mail8.box') email_file_path = Rails.root.join('test', 'data', 'mail', 'mail008.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string) ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
@ -177,7 +179,8 @@ class TicketArticleAttachmentsControllerTest < ActionDispatch::IntegrationTest
assert_equal(result['attachments'].class, Array) assert_equal(result['attachments'].class, Array)
assert(result['attachments'].blank?) assert(result['attachments'].blank?)
email_raw_string = IO.binread('test/fixtures/mail24.box') email_file_path = Rails.root.join('test', 'data', 'mail', 'mail024.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string) ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
post "/api/v1/ticket_attachment_upload_clone_by_article/#{article_p.id}", params: { form_id: '1234-2' }.to_json, headers: headers.merge('Authorization' => credentials) post "/api/v1/ticket_attachment_upload_clone_by_article/#{article_p.id}", params: { form_id: '1234-2' }.to_json, headers: headers.merge('Authorization' => credentials)

View file

@ -978,7 +978,8 @@ class UserControllerTest < ActionDispatch::IntegrationTest
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
# invalid file # invalid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple_col_not_existing.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'user_simple_col_not_existing.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/users/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/users/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -992,7 +993,8 @@ class UserControllerTest < ActionDispatch::IntegrationTest
assert_equal("Line 2: unknown attribute 'firstname2' for User.", result['errors'][1]) assert_equal("Line 2: unknown attribute 'firstname2' for User.", result['errors'][1])
# valid file try # valid file try
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'user_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/users/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/users/import?try=true', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
@ -1006,7 +1008,8 @@ class UserControllerTest < ActionDispatch::IntegrationTest
assert_nil(User.find_by(login: 'user-simple-import2')) assert_nil(User.find_by(login: 'user-simple-import2'))
# valid file # valid file
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple.csv'), 'text/csv') csv_file_path = Rails.root.join('test', 'data', 'csv', 'user_simple.csv')
csv_file = ::Rack::Test::UploadedFile.new(csv_file_path, 'text/csv')
post '/api/v1/users/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials } post '/api/v1/users/import', params: { file: csv_file, col_sep: ';' }, headers: { 'Authorization' => credentials }
assert_response(200) assert_response(200)
result = JSON.parse(@response.body) result = JSON.parse(@response.body)

View file

Can't render this file because it has a wrong number of fields in line 2.

View file

Can't render this file because it has a wrong number of fields in line 2.

View file

@ -0,0 +1,13 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: John.Smith@example.com
from_email: John.Smith@example.com
from_display_name: ''
subject: 'CI Daten für PublicView '
content_type: text/html
body: |-
<div>
<div>Hallo Martin,</div><p>&nbsp;</p><div>wie besprochen hier noch die Daten für die Intranetseite:</div><p>&nbsp;</p><div>Schriftart/-größe: Verdana 11 Pt wenn von Browser nicht unterstützt oder nicht vorhanden wird Arial 11 Pt genommen</div><div>Schriftfarbe: Schwarz</div><div>Farbe für die Balken in der Grafik: D7DDE9 (Blau)</div><p>&nbsp;</p><div>Wenn noch was fehlt oder du was brauchst sag mir Bescheid.</div><p>&nbsp;</p><div>Mit freundlichem Gruß<br><br>John Smith<br>Service und Support<br><br>Example Service AG &amp; Co. </div><div>Management OHG<br>Someware-Str. 4<br>xxxxx Someware<br><br>
</div><div>Tel.: +49 001 7601 462<br>Fax: +49 001 7601 472 </div><div>john.smith@example.com</div><div>
<a href="http://www.example.com" rel="nofollow noreferrer noopener" target="_blank">www.example.com</a>
</div><div>
<br>OHG mit Sitz in Someware<br>AG: Someware - HRA 4158<br>Geschäftsführung: Tilman Test, Klaus Jürgen Test, </div><div>Bernhard Test, Ulrich Test<br>USt-IdNr. DE 1010101010<br><br>Persönlich haftende geschäftsführende Gesellschafterin: </div><div>Marie Test Example Stiftung, Someware<br>Vorstand: Rolf Test<br><br>Persönlich haftende Gesellschafterin: </div><div>Example Service AG, Someware<br>AG: Someware - HRB xxx<br>Vorstand: Marie Test </div><p>&nbsp;</p></div>

View file

@ -0,0 +1,13 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Martin Edenhofer <martin@example.com>
from_email: martin@example.com
from_display_name: Martin Edenhofer
subject: aaäöüßad asd
content_type: text/plain
body: |
äöüß ad asd
-Martin
--
Old programmers never die. They just branch to a new address.

View file

@ -0,0 +1,26 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"Günther John | Example GmbH" <k.guenther@example.com>'
from_email: k.guenther@example.com
from_display_name: Günther John | Example GmbH
subject: Ticket Templates
content_type: text/html
body: |-
<div>
<p>Hallo Martin,</p><p>&nbsp;</p><p>ich möchte mich gern für den Beta-Test für die Ticket Templates unter XXXX 2.4 anmelden.</p><p>&nbsp;</p><div> <p>&nbsp;</p><p>Mit freundlichen Grüßen</p><p>John Günther</p><p>&nbsp;</p><p><a href="http://www.GeoFachDatenServer.de" rel="nofollow noreferrer noopener" target="_blank" title="http://www.GeoFachDatenServer.de">example.com</a> profitieren Sie vom umfangreichen Daten-Netzwerk </p><p>&nbsp;</p><p>_ __ ___ ____________________________ ___ __ _</p><p>&nbsp;</p><p>Example GmbH</p><p>Some What</p><p>&nbsp;</p><p>Sitz: Someware-Straße 9, XXXXX Someware</p><p>&nbsp;</p><p>M: +49 (0) XXX XX XX 70</p><p>T: +49 (0) XXX XX XX 22</p><p>F: +49 (0) XXX XX XX 11</p><p>W: <a href="http://www.example.de" rel="nofollow noreferrer noopener" target="_blank">http://www.example.de</a></p><p>&nbsp;</p><p>Geschäftsführer: John Smith</p><p>HRB XXXXXX AG Someware</p><p>St.-Nr.: 112/107/05858</p><p>&nbsp;</p><p>ISO 9001:2008 Zertifiziert -Qualitätsstandard mit Zukunft</p><p>_ __ ___ ____________________________ ___ __ _</p><p>&nbsp;</p><p>Diese Information ist ausschließlich für den Adressaten bestimmt und kann vertrauliche oder gesetzlich geschützte Informationen enthalten. Wenn Sie nicht der bestimmungsgemäße Adressat sind, unterrichten Sie bitte den Absender und vernichten Sie diese Mail. Anderen als dem bestimmungsgemäßen Adressaten ist es untersagt, diese E-Mail zu lesen, zu speichern, weiterzuleiten oder ihren Inhalt auf welche Weise auch immer zu verwenden.</p></div><p>&nbsp;</p><div>
<span class="js-signatureMarker"></span><p><b>Von:</b> Fritz Bauer [mailto:me@example.com] <br><b>Gesendet:</b> Donnerstag, 3. Mai 2012 11:51<br><b>An:</b> John Smith<br><b>Cc:</b> Smith, John Marian; johnel.fratczak@example.com; ole.brei@example.com; Günther John | Example GmbH; bkopon@example.com; john.heisterhagen@team.example.com; sven.rocked@example.com; michael.house@example.com; tgutzeit@example.com<br><b>Betreff:</b> Re: OTRS::XXX Erweiterung - Anhänge an CI's</p></div><p>&nbsp;</p><p>Hallo,</p><div> <p>&nbsp;</p></div><div>
<p>ich versuche an den Punkten anzuknüpfen.</p></div><div> <p>&nbsp;</p></div><div>
<p><b>a) LDAP Muster Konfigdatei</b></p></div><div> <p>&nbsp;</p></div><div>
<p><a href="https://wiki.lab.example.com/doku.php?id=xxxx:start&amp;#ldap" rel="nofollow noreferrer noopener" target="_blank">https://wiki.lab.example.com/doku.php?id=xxxx:start&amp;#ldap</a></p></div><div> <p>&nbsp;</p></div><div>
<p>PS: Es gibt noch eine Reihe weiterer Möglichkeiten, vor allem im Bezug auf Agenten-Rechte/LDAP Gruppen Synchronisation. Wenn Ihr hier weitere Informationen benötigt, einfach im Wiki die Aufgabenbeschreibung rein machen und ich kann eine Beispiel-Config dazu legen.</p></div><div>
<p>&nbsp;</p></div><div> <p>&nbsp;</p></div><div>
<p><b>b) Ticket Templates</b></p></div><div>
<p>Wir haben das Paket vom alten Maintainer übernommen, es läuft nun auf XXXX 2.4, XXXX 3.0 und XXXX 3.1. Wir haben das Paket um weitere Funktionen ergänzt und würden es gerne hier in diesen Kreis zum Beta-Test bereit stellen.</p></div><div> <p>&nbsp;</p></div><div>
<p>Vorgehen:</p></div><div>
<p>Wer Interesse hat, bitte eine Email an mich und ich versende Zugänge zu den Beta-Test-Systemen. Nach ca. 2 Wochen werden wir die Erweiterungen in der Version 1.0 veröffentlichen.</p></div><div> <p>&nbsp;</p></div><div> <p>&nbsp;</p></div><div>
<p><b>c) XXXX Entwickler Schulung</b></p></div><div>
<p>Weil es immer wieder Thema war, falls jemand Interesse hat, das XXXX bietet nun auch OTRS Entwickler Schulungen an (<a href="http://www.example.com/kurs/xxxx_entwickler/" rel="nofollow noreferrer noopener" target="_blank">http://www.example.com/kurs/xxxx_entwickler/</a>).</p></div><div> <p>&nbsp;</p></div><div> <p>&nbsp;</p></div><div>
<p><b>d) Genelle Fragen?</b></p></div><div>
<p>Haben sich beim ein oder anderen generell noch Fragen aufgetan?</p></div><div> <p>&nbsp;</p></div><div> <p>&nbsp;</p></div><div>
<p>Viele Grüße!</p></div><div> <p>&nbsp;</p></div><div>
<div>
<p>-Fritz</p></div><p>On May 2, 2012, at 14:25 , John Smith wrote:<br><br></p><p>Moin Moin,<br><br>die Antwort ist zwar etwas spät, aber nach der Schulung war ich krank und danach<br>hatte ich viel zu tun auf der Arbeit, sodass ich keine Zeit für XXXX hatte.<br>Ich denke das ist allgemein das Problem, wenn sowas nebenbei gemacht werden muss.<br><br>Wie auch immer, danke für die mail mit dem ITSM Zusatz auch wenn das zur Zeit bei der Example nicht relevant ist.<br><br>Ich habe im XXXX Wiki den Punkt um die Vorlagen angefügt.<br>Ticket Template von John Bäcker<br>Bei uns habe ich das Ticket Template von John Bäcker in der Version 0.1.96 unter XXXX 3.0.10 implementiert. <br><br>Fritz wollte sich auch um das andere Ticket Template Modul kümmern und uns zur Verfügung stellen, welches unter XXXX 3.0 nicht lauffähig sein sollte.<br><br>Im Wiki kann ich die LDAP Muster Konfigdatei nicht finden.<br>Hat die jemand von euch zufälligerweise ?<br><br>Danke und Gruß<br>John Smith<br><br>Am 4. April 2012 08:24 schrieb Smith, John Marian &lt;john.smith@example.com&gt;:<br>Hallo zusammen,<br><br>ich hoffe Ihr seid noch gut nach Hause gekommen am Mittwoch. Der XXX Kurs Donnerstag und Freitag war noch ganz gut, wobei ich mir den letzten halben Tag eigentlich hätte schenken können.<br><br>Soweit ich weiß arbeitet Ihr nicht mit XXX? Falls doch habe ich hier eine tolle (eigentlich) kostenpflichtige Erweiterung für Euch.<br><br>Es handelt sich um eine programmiertes Paket von der XXXX AG. Die Weitergabe ist legal.<br><br>Mit dem Paket kann man Anhänge an CIs (Configuration Items) verknüpfen. Das ist sehr praktisch wenn man zum Beispiel Rechnungen an Server, Computern und und und anhängen möchte.<br><br>Der Dank geht an Frank Linden, der uns das Paket kostenlos zur Verfügung gestellt hat.<br><br>Viele Grüße aus Someware<br><br>John<br><br>_________________________<br>SysAdmin<br>John Marian Smith<br>IT-Management<br><br>Example GmbH &amp; Co. KG<br>Der Provider für<br>Mehrwertdienste &amp; YYY<br><br>Someware 23<br>XXXXX Someware<br><br>Tel. (01802) XX XX XX - 42<br>Fax (01802) XX XX XX - 99<br>nur 6 Cent je Anruf aus dem dt. Festnetz,<br>max. 42 Cent pro Min. aus dem Mobilfunknetz<br><br>E-Mail john.smith@Example.de<br>Web <a href="http://www.Example.de" rel="nofollow noreferrer noopener" target="_blank">www.Example.de</a><br>Amtsgericht Hannover HRA xxxxxxxx<br>Komplementärin: Example Verwaltungs- GmbH<br>Vertreten durch: Somebody, Somebody<br>Amtsgericht Someware HRB XXX XXX<br><br>_________________________ <br>Highlights der Example Contact Center-Suite:<br>Virtual XXX&amp;Power-XXX, Self-Services&amp;XXX-Portale,<br>XXX-/Web-Kundenbefragungen, CRM, PEP, YYY</p></div></div>

View file

@ -0,0 +1,27 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"Günther Katja | Example GmbH" <k.guenther@example.com>'
from_email: k.guenther@example.com
from_display_name: Günther Katja | Example GmbH
subject: 'AW: Ticket Templates [Ticket#11168]'
content_type: text/plain
body: |+
Hallo Katja,
super! Ich freu mich!
Wir würden gerne die Präsentation/Einführung in die Ticket Templates per Screensharing oder zumindest per Telefon machen.
Mögliche Termine:
o Do, 10.05.2012 15:00-16:00
o Fr, 11.05.2012 13:00-14:00
o Di, 15.05.2012 17:00-18:00
Über Feedback würde ich mich freuen!
PS: Zur besseren Übersicht habe ich ein Ticket erstellt. :) Im Footer sind unsere geschäftlichen Kontaktdaten (falls diese irgendwann einmal benötigt werden sollten), mehr dazu in ein paar Tagen.
Liebe Grüße!
-Martin

View file

@ -0,0 +1,6 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: marc.smith@example.com (Marc Smith)
from_email: marc.smith@example.com
from_display_name: Marc Smith
subject: 'Re: XXXX Betatest Ticket Templates [Ticket#11162]'
content_type: text/plain

View file

@ -0,0 +1,10 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"Hans BÄKOSchönland" <me@bogen.net>'
from_email: me@bogen.net
from_display_name: Hans BÄKOSchönland
subject: 'utf8: 使って / ISO-8859-1: Priorität" / cp-1251: Сергей Углицких'
content_type: text/html
body: '<p>this is a test</p><br><hr> <a href="http://localhost/8HMZENUS/2737??PS="
rel="nofollow noreferrer noopener" target="_blank" title="http://localhost/8HMZENUS/2737??PS=">Compare
Cable, DSL or Satellite plans: As low as $2.95. </a> <br> <br> Test1: <br> Test2:&amp;
<br> Test3:∋ <br> Test4:&amp; <br> Test5:='

View file

@ -0,0 +1,22 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Eike.Ehringer@example.com
from_email: Eike.Ehringer@example.com
from_display_name: ''
subject: AW:Installation [Ticket#11392]
content_type: text/html
body: "Hallo.<br>Jetzt muss ich dir noch kurzfristig absagen für morgen.<br>Lass uns
evtl morgen Tel.<br><br>Mfg eike <br><br><div>\n<div>Martin Edenhofer via Znuny
Team --- Installation [Ticket#11392] ---</div><div>\n<br><table border=\"0\" cellspacing=\"0\"
cellpadding=\"0\">\n<tr>\n<td>Von:</td>\n<td>\"Martin Edenhofer via Znuny Team\"
&lt;support@example.com&gt;</td>\n</tr>\n<tr>\n<td>An</td>\n<td>eike.xx@xx-corpxx.com</td>\n</tr>\n<tr>\n<td>Datum:</td>\n<td>Mi.,
13.06.2012 14:30</td>\n</tr>\n<tr>\n<td>Betreff</td>\n<td>Installation [Ticket#11392]</td>\n</tr>\n</table>\n<hr>\n<br><pre>Hi
Eike,\n\nanbei wie gestern telefonisch besprochen Informationen zur Vorbereitung.\n\na)
Installation von <a href=\"http://ftp.gwdg.de/pub/misc/zammad/RPMS/fedora/4/zammad-3.0.13-01.noarch.rpm\"
rel=\"nofollow noreferrer noopener\" target=\"_blank\">http://ftp.gwdg.de/pub/misc/zammad/RPMS/fedora/4/zammad-3.0.13-01.noarch.rpm</a>
(dieses RPM ist RHEL kompatible) und dessen Abhängigkeiten.\n\nb) Installation von
\"mysqld\" und \"perl-DBD-MySQL\".\n\nDas wäre es zur Vorbereitung!\n\nBei Fragen
nur zu!\n\n -Martin\n\n--\nMartin Edenhofer\n\nZnuny GmbH // Marienstraße 11 //
10117 Berlin // Germany\n\nP: +49 (0) 30 60 98 54 18-0\nF: +49 (0) 30 60 98 54 18-8\nW:
<a href=\"http://example.com\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">http://example.com</a>
\n\nLocation: Berlin - HRB 139852 B Amtsgericht Berlin-Charlottenburg\nManaging
Director: Martin Edenhofer\n\n</pre>\n</div></div>"

View file

@ -0,0 +1,72 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Franz.Schaefer@example.com
from_email: Franz.Schaefer@example.com
from_display_name: ''
subject: 'could not rename: ZZZAAuto'
content_type: text/html
body: |-
<img src="cid:_1_08FC9B5808FC7D5C004AD64FC1257A28">
<br>
<br>Gravierend?<br> <table>
<tr>
<td>Mit freundlichen Grüßen</td>
</tr>
</table>
<br>
<table>
<tr>
<td>
<b>Franz Schäfer</b>
</td>
</tr>
<tr>
<td>Manager Information Systems</td>
</tr>
</table>
<br>
<table>
<tr>
<td> Telefon </td>
<td> +49 000 000 8565 </td>
</tr>
<tr>
<td colspan="2">christian.schaefer@example.com</td>
</tr>
</table>
<br>
<table>
<tr>
<td>
<b>Example Stoff GmbH</b>
</td>
</tr>
<tr>
<td> Fakultaet </td>
</tr>
<tr>
<td> Düsseldorfer Landstraße 395 </td>
</tr>
<tr>
<td> D-00000 Hof </td>
</tr>
<tr>
<td><a href="http://www.example.com" rel="nofollow noreferrer noopener" target="_blank"><u>www.example.com</u></a></td>
</tr>
</table>
<br>
<table>
<tr>
<td>
<hr>
</td>
</tr>
<tr>
<td> Geschäftsführung/Management Board: Jan Bauer (Vorsitzender/Chairman), Oliver Bauer, Heiko Bauer, Boudewijn Bauer </td>
</tr>
<tr>
<td> Sitz der Gesellschaft / Registered Office: Hof </td>
</tr>
<tr>
<td>Registergericht / Commercial Register of the Local Court: HRB 0000 AG Hof</td>
</tr>
</table>

View file

@ -0,0 +1,10 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Martin Edenhofer <martin@example.de>
from_email: martin@example.de
from_display_name: Martin Edenhofer
subject: 'AW: OTRS / Anfrage OTRS Einführung/Präsentation [Ticket#11545]'
content_type: text/html
body: |-
Enjoy!<div>
<br><div>-Martin<br><span class="js-signatureMarker"></span><br>--<br>Old programmers never die. They just branch to a new address.<br>
</div><br><div><img src="cid:485376C9-2486-4351-B932-E2010998F579@home" style="width:640px;height:425px;"></div></div>

View file

@ -0,0 +1,9 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Smith Sepp <smith@example.com>
from_email: smith@example.com
from_display_name: Smith Sepp
subject: Gruß aus Oberalteich
content_type: text/html
body: |-
<div>
<p>Herzliche Grüße aus Oberalteich sendet Herrn Smith</p><p>&nbsp;</p><p>Sepp Smith - Dipl.Ing. agr. (FH)</p><p>Geschäftsführer der example Straubing-Bogen</p><p>Klosterhof 1 | 94327 Bogen-Oberalteich</p><p>Tel: 09422-505601 | Fax: 09422-505620</p><p>Internet: <a href="http://example-straubing-bogen.de/" rel="nofollow noreferrer noopener" target="_blank">http://example-straubing-bogen.de</a></p><p>Facebook: <a href="http://facebook.de/examplesrbog" rel="nofollow noreferrer noopener" target="_blank">http://facebook.de/examplesrbog</a></p><p><b><img border="0" src="cid:image001.jpg@01CDB132.D8A510F0" alt="Beschreibung: Beschreibung: efqmLogo" style="width:60px;height:19px;"></b><b> - European Foundation für Quality Management</b></p><p>&nbsp;</p></div>

View file

@ -0,0 +1,40 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
reply-to: serviceteam@cylex.de
from: CYLEX Newsletter <carina.merkant@cylex.de>
from_email: carina.merkant@cylex.de
from_display_name: CYLEX Newsletter
subject: Eine schöne Adventszeit für ZNUNY GMBH - ENTERPRISE SERVICES FÜR OTRS
to: enjoy_us@znuny.com
content_type: text/html
body: |-
<table border="0" cellpadding="0" style=" font-size: 14px;">
<tbody>
<tr>
<td>
<p>
<a href="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-2/http://web2.cylex.de/advent2012?b2b" rel="nofollow noreferrer noopener" target="_blank" title="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-2/http://web2.cylex.de/advent2012?b2b"></a></p><p>Lieber CYLEX Eintragsinhaber,</p><p>das Jahr neigt sich dem Ende und die besinnliche Zeit beginnt laut Kalender mit dem<br> 1. Advent. Und wie immer wird es in der vorweihnachtlichen Zeit meist beruflich und privat<br> so richtig schön hektisch.</p><p>Um Ihre Weihnachtsstimmung in Schwung zu bringen kommen wir nun mit unserem Adventskalender ins Spiel. Denn 24 Tage werden Sie unsere netten Geschichten, Rezepte und Gewinnspiele sowie ausgesuchte Geschenktipps und Einkaufsgutscheine online begleiten. Damit lässt sich Ihre Freude auf das Fest garantiert mit jedem Tag steigern.</p><table style=" font-size: 14px;">
<tbody>
<tr>
<td align="left" valign="middle"> Einen gemütlichen Start in die Adventszeit wünscht Ihnen</td>
<td align="right" valign="middle">
<a href="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-1/http://web2.cylex.de/advent2012?b2b" rel="nofollow noreferrer noopener" target="_blank" title="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-1/http://web2.cylex.de/advent2012?b2b"></a>
</td>
</tr>
</tbody>
</table>
<p>Ihr CYLEX Team<br>
<br>
<strong>P.S.</strong> Damit Sie keinen Tag versäumen, empfehlen wir Ihnen den <a href="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-3/http://web2.cylex.de/advent2012?b2b" rel="nofollow noreferrer noopener" target="_blank" title="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-3/http://web2.cylex.de/advent2012?b2b">Link des Adventkalenders</a> in<br> Ihrer Lesezeichen-Symbolleiste zu ergänzen.</p><p>&nbsp;</p></td>
</tr>
</tbody>
</table> <table cellspacing="0" cellpadding="0" style="color:#6578a0; font-size:10px;">
<tbody>
<tr>
<td align="left" style="text-align:left;"> Impressum <br> S.C. CYLEX INTERNATIONAL S.N.C.<br> Sat. Palota 119/A RO 417516 Palota Romania <br> Tel.: +49 208/62957-0 | <br> Geschäftsführer: Francisc Osvald<br> Handelsregister: J05/1591/2009<br> USt.IdNr.: RO26332771 <br>
<br> serviceteam@cylex.de<br>
<a href="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-98/http://web2.cylex.de/Homepage/Home.asp" rel="nofollow noreferrer noopener" target="_blank" title="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-98/http://web2.cylex.de/Homepage/Home.asp">Homepage</a><br>
<a href="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-99/http://newsletters.cylex.de/unsubscribe.aspx?uid=4134001&amp;d=www.cylex.de&amp;e=enjoy@znuny.com&amp;sc=3009&amp;l=d" rel="nofollow noreferrer noopener" target="_blank" title="http://newsletters.cylex.de/ref/www.cylex.de/sid-105/uid-4134001/lid-99/http://newsletters.cylex.de/unsubscribe.aspx?uid=4134001&amp;d=www.cylex.de&amp;e=enjoy@znuny.com&amp;sc=3009&amp;l=d">Newsletter abbestellen</a>
</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,16 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Alex.Smith@example.com
from_email: Alex.Smith@example.com
from_display_name: ''
subject: 'AW: Agenda [Ticket#11995]'
to: example@znuny.com
content_type: text/html
body: |-
<div>
<p>Hallo Herr Edenhofer,</p><p>&nbsp;</p><p>möglicherweise haben wir für unsere morgige Veranstaltung ein Problem mit unserer Develop-Umgebung.<br> Der Kollege Smith wollte uns noch die Möglichkeit geben, direkt auf die Datenbank zugreifen zu können, hierzu hat er Freitag noch einige Einstellungen vorgenommen und uns die Zugangsdaten mitgeteilt. Eine der Änderungen hatte aber offenbar zur Folge, dass ein Starten der Develop-Anwendung nicht mehr möglich ist (s. Fehlermeldung)<br>
<img src="cid:image002.png@01CDD14F.29D467A0" style="width:577px;height:345px;"></p><p>&nbsp;</p><p>Herr Smith ist im Urlaub, er wurde von seinen Datenbank-Kollegen kontaktiert aber offenbar lässt sich nicht mehr 100%ig rekonstruieren, was am Freitag noch verändert wurde.<br> Meinen Sie, dass Sie uns bei der Behebung der o. a. Störung morgen helfen können? Die Datenbank-Kollegen werden uns nach besten Möglichkeiten unterstützen, Zugriff erhalten wir auch.</p><p>&nbsp;</p><p>Mit freundlichen Grüßen</p><p>&nbsp;</p><p>Alex Smith<br>
<br> Abteilung IT-Strategie, Steuerung &amp; Support<br> im Bereich Informationstechnologie<br>
<br> Example Example GmbH<br> (Deutsche Example)<br> Longstreet 5<br> 11111 Frankfurt am Main<br>
<br> Telefon: (069) 11 1111 11 30</p><p>Telefon ServiceDesk: (069) 11 1111 12 22<br> Telefax: (069) 11 1111 14 85<br> Internet: <a href="http://www.example.com/" title="http://www.example.com/" rel="nofollow noreferrer noopener" target="_blank">www.example.com</a></p><p>&nbsp;</p><span class="js-signatureMarker"></span><p>-----Ursprüngliche Nachricht-----<br> Von: Martin Edenhofer via Znuny Sales [mailto:example@znuny.com] <br> Gesendet: Freitag, 30. November 2012 13:50<br> An: Smith, Alex<br> Betreff: Agenda [Ticket#11995]</p><p>&nbsp;</p><p>Sehr geehrte Frau Smith,</p><p>&nbsp;</p><p>ich habe (wie telefonisch avisiert) versucht eine Agenda für nächste Woche zusammen zu stellen.</p><p>&nbsp;</p><p>Leider ist es mir dies Inhaltlich nur unzureichend gelungen (es gibt zu wenig konkrete Anforderungen im Vorfeld :) ).</p><p>&nbsp;</p><p>Dadurch würde ich gerne am Dienstag als erste Amtshandlung (mit Herrn Molitor im Boot) die Anforderungen und Ziele der zwei Tage, Mittelfristig und Langfristig definieren. Aufgrund dessen können wir die Agenda der zwei Tage fixieren. Inhaltlich können wir (ich) alles abdecken, von daher gibt es hier keine Probleme. ;)</p><p>&nbsp;</p><p>Ist dies für Sie so in Ordnung?</p><p>&nbsp;</p><p>Für Fragen stehe ich gerne zur Verfügung!</p><p>&nbsp;</p><p>Ich freue mich auf Dienstag,</p><p>&nbsp;</p><p>Martin Edenhofer</p><p>&nbsp;</p><p>--</p><p>Enterprise Services for OTRS</p><p>&nbsp;</p><p>Znuny GmbH // Marienstraße 11 // 10117 Berlin // Germany</p><p>&nbsp;</p><p>P: +49 (0) 30 60 98 54 18-0</p><p>F: +49 (0) 30 60 98 54 18-8</p><p>W: <a href="http://znuny.com" rel="nofollow noreferrer noopener" target="_blank">http://znuny.com</a>
</p><p>&nbsp;</p><p>Location: Berlin - HRB 139852 B Amtsgericht Berlin-Charlottenburg Managing Director: Martin Edenhofer</p></div><div>
<p>-------------------------------------------------------------------------------------------------</p><p>Rechtsform: GmbH</p><p>Geschaeftsfuehrer: Dr. Carl Heinz Smith, Dr. Carsten Smith</p><p>Sitz der Gesellschaft und Registergericht: Frankfurt/Main, HRB 11111</p><p>Alleiniger Gesellschafter: Bundesrepublik Deutschland,</p><p>vertreten durch das XXX der Finanzen.</p></div>

View file

@ -0,0 +1,8 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: thomas.smith@example.com
from_email: thomas.smith@example.com
from_display_name: ''
subject: 'Antwort: Probleme ADB / Anlegen von Tickets [Ticket#111079]'
to: q1@znuny.com
content_type: text/html
body: "<p>JA</p>"

View file

@ -0,0 +1,14 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"Müller, Bernd" <Bernd.Mueller@example.com>'
from_email: Bernd.Mueller@example.com
from_display_name: Müller, Bernd
subject: 'AW: OTRS [Ticket#118192]'
to: "'Martin Edenhofer via Znuny Sales' <sales@znuny.com>"
content_type: text/plain
body: |
äöüß ad asd
-Martin
--
Old programmers never die. They just branch to a new address.

View file

@ -0,0 +1,7 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"Sara.Gang" <ynbe.ctrhk@gmail.com>'
from_email: ynbe.ctrhk@gmail.com
from_display_name: Sara.Gang
subject: 绩效管理,究竟谁错了
to: info42@znuny.com
content_type: text/plain

View file

@ -0,0 +1,5 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from_email: vipyimin@126.com
from_display_name: ''
subject: "【 直通美国排名第49大学 成功后付费 】"
to: '"enterprisemobility.apacservice" <enterprisemobility.apacservice@motorola.com>'

View file

@ -0,0 +1,8 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"都琹" <ghgbwum@185.com.cn>'
from_email: ghgbwum@185.com.cn
from_display_name: 都琹
subject: "【专业为您注册香港及海外公司(好处多多)】                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               人物
\ 互联网事百度新闻独家出品传媒换一批捷克戴维斯杯决赛前任命临时领队 前领队因病住院最新:盖世汽车讯 11月6日通用汽车宣布今年10月份在华销量...减持三特索道
孟凯将全力发展湘鄂情江青摄影作品科技日报讯 (记者过国忠 通讯员陈飞燕)江苏省无线电科学研究所有限公司院士工作站日前正式建...[详细]"
to: info@znuny.com

View file

@ -0,0 +1,6 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: postmaster@example.com
from_email: postmaster@example.com
from_display_name: ''
subject: "Benachrichtung \tzum \t=?unicode-1-1-utf-7?Q?+ANw-bermittlungsstatus \t(Fehlgeschlagen)?="
to: sales@znuny.org

View file

@ -0,0 +1,6 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: '"我" <>'
from_email: vipyiming@126.com
from_display_name: ''
subject: "《欧美简讯》"
to: 377861373 <377861373@qq.com>

View file

@ -0,0 +1,85 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Health and Care-Mall <drugs-cheapest8@sicor.com>
from_email: drugs-cheapest8@sicor.com
from_display_name: Health and Care-Mall
subject: The Highest Grade Drugs And EXTRA LOW Price .
to: info2@znuny.com
body: |-
________________________________________________________________________Yeah but even when they. Beth liî ed her neck as well <br>
<div>
<table border="0" cellspacing="5" style="color:#e3edea; background-color:#eee0ec; font-size:1px;">
<tr>
<td colspan="2">óû5a<span style="color:#dd7f6f;">H</span>w5³½<span style="color:#dd7f6f;">I</span>ΨµÁx<span style="color:#dd7f6f;">G</span>⌊o8K<span style="color:#dd7f6f;">H</span>Cmς9<span style="color:#dd7f6f;">-</span>Ö½23<span style="color:#dd7f6f;">Q</span>gñV6<span style="color:#dd7f6f;">U</span>AD¿ù<span style="color:#dd7f6f;">A</span>X←t¨<span style="color:#dd7f6f;">L</span>f7⊕®<span style="color:#dd7f6f;">I</span>r²r½<span style="color:#dd7f6f;">T</span>LA5p<span style="color:#dd7f6f;">Y</span>JhjV<span style="color:#dd7f6f;"> </span>gPnã<span style="color:#dd7f6f;">M</span>36V®<span style="color:#dd7f6f;">E</span>89RU<span style="color:#dd7f6f;">D</span>ΤÅ©È<span style="color:#dd7f6f;">I</span>9æsà<span style="color:#dd7f6f;">C</span>ΘYEϒ<span style="color:#dd7f6f;">A</span>fgb<span style="color:#dd7f6f;">T</span>¡1∫r<span style="color:#dd7f6f;">I</span>oiš¦<span style="color:#dd7f6f;">O</span>5oUI<span style="color:#dd7f6f;">N</span>±Isæ<span style="color:#dd7f6f;">S</span>عPp<span style="color:#dd7f6f;"> </span>Ÿÿq1<span style="color:#dd7f6f;">F</span>Χ⇑eG<span style="color:#dd7f6f;">O</span>z⌈F³<span style="color:#dd7f6f;">R</span>98y§<span style="color:#dd7f6f;"> </span>74”l<span style="color:#dd7f6f;">T</span>r8r§<span style="color:#dd7f6f;">H</span>ÐæuØ<span style="color:#dd7f6f;">E</span>ÛPËq<span style="color:#dd7f6f;"> </span>Vmkf<span style="color:#dd7f6f;">B</span>∫SKN<span style="color:#dd7f6f;">E</span>lst4<span style="color:#dd7f6f;">S</span>∃Á8ü<span style="color:#dd7f6f;">T</span>ðG°í<span style="color:#dd7f6f;"> </span>lY9å<span style="color:#dd7f6f;">P</span>u×8&gt;<span style="color:#dd7f6f;">R</span>Ò¬⊕Μ<span style="color:#dd7f6f;">I</span>ÙzÙC<span style="color:#dd7f6f;">C</span>4³ÌQ<span style="color:#dd7f6f;">E</span>ΡºSè<span style="color:#dd7f6f;">!</span>XgŒs.</td>
</tr>
<tr>
<td align="center" colspan="2">çγ⇓B<span style="color:#2a0984;"><a href="http://pxmzcgy.storeprescription.ru?zz=fkxffti" rel="nofollow noreferrer noopener" target="_blank" title="http://pxmzcgy.storeprescription.ru?zz=fkxffti"><b><span style="color:#fbe6bf;">cwsp</span>C L I C K H E R E<span style="color:#fdedb6;">ëe3¸</span> !</b></a></span>Calm dylan for school today.<br>Closing the nursery with you down. Here and made the mess. Maybe the oï from under his mother. Song of course beth touched his pants.<br>When someone who gave up from here. Feel of god knows what.</td>
</tr>
<tr>
<td colspan="2">TBϖ∃<span style="color:#2a0984;">M</span>5T5Ε<span style="color:#2a0984;">E</span>f2û<span style="color:#2a0984;">N</span>¶ÁvΖ<span style="color:#2a0984;">'</span>®⇓∝5<span style="color:#2a0984;">S</span>ÐçË5<span style="color:#2a0984;"> </span>Χ0jΔ<span style="color:#2a0984;">H</span>bAgþ<span style="color:#2a0984;">E</span>—2i6<span style="color:#2a0984;">A</span>2lD⇑<span style="color:#2a0984;">L</span>GjÓn<span style="color:#2a0984;">T</span>Oy»¦<span style="color:#2a0984;">H</span>ëτ9<span style="color:#2a0984;">:</span>Their mother and tugged it seemed like</td>
</tr>
<tr>
<td>d3Rs<span style="color:#2a0984;">V</span>¶HÓΘ<span style="color:#2a0984;">i</span>¯B∂g<span style="color:#2a0984;">a</span>x1bî<span style="color:#2a0984;">g</span>dHä3<span style="color:#2a0984;">r</span>ýJÿ1<span style="color:#2a0984;">a</span>IKDz<span style="color:#2a0984;"> </span>n1jf<span style="color:#2a0984;">a</span>Tk³V<span style="color:#2a0984;">s</span>395ß<span style="color:#2a0984;"> </span>C˜lB<span style="color:#2a0984;">l</span>mxG<span style="color:#2a0984;">o</span>0√úX<span style="color:#2a0984;">w</span>T8Ya<span style="color:#2a0984;"> </span>õ8ks<span style="color:#2a0984;">a</span>∫f·ℵ<span style="color:#2a0984;">s</span>”6ÑQ<span style="color:#2a0984;"> </span>ÍAd7<span style="color:#2a0984;">$</span>p32d<span style="color:#2a0984;">1</span>e∏æe<span style="color:#2a0984;">.</span>0”×6<span style="color:#2a0984;">1</span>aîΚ6<span style="color:#2a0984;">3</span>αSMû</td>
<td>Nf5É<span style="color:#2a0984;">C</span>dL1<span style="color:#2a0984;">i</span>↔xca<span style="color:#2a0984;">a</span>5êR3<span style="color:#2a0984;">l</span>6Lc3<span style="color:#2a0984;">i</span>ãz16<span style="color:#2a0984;">s</span>ó9èU<span style="color:#2a0984;"> </span>zDE²<span style="color:#2a0984;">a</span>EȨg<span style="color:#2a0984;">s</span>25ËÞ<span style="color:#2a0984;"> </span>hE§c<span style="color:#2a0984;">l</span>⊃¢¢Â<span style="color:#2a0984;">o</span>ÒµB<span style="color:#2a0984;">w</span>²zF©<span style="color:#2a0984;"> </span>qÏkõ<span style="color:#2a0984;">a</span>XUiu<span style="color:#2a0984;">s</span>1r0⊆<span style="color:#2a0984;"> </span>d•∈ø<span style="color:#2a0984;">$</span>¢Z2F<span style="color:#2a0984;">1</span>2­8l<span style="color:#2a0984;">.</span>07d5<span style="color:#2a0984;">6</span>PÚl2<span style="color:#2a0984;">5</span>JAO6</td>
</tr>
<tr>
<td>45lo<span style="color:#2a0984;">V</span>óiv1<span style="color:#2a0984;">i</span>2ãΥ⌊<span style="color:#2a0984;">a</span>ð⊃d2<span style="color:#2a0984;">g</span>ÃΥ3™<span style="color:#2a0984;">r</span>ÎÍu¸<span style="color:#2a0984;">a</span>WjO8<span style="color:#2a0984;"> </span>n40<span style="color:#2a0984;">S</span>oyè2<span style="color:#2a0984;">u</span>¡∅Î3<span style="color:#2a0984;">p</span>¢JΜN<span style="color:#2a0984;">e</span>Ìé×j<span style="color:#2a0984;">r</span>áÒrΚ<span style="color:#2a0984;"> </span>1ÌÓ9<span style="color:#2a0984;">A</span>úrAk<span style="color:#2a0984;">c</span>8nuE<span style="color:#2a0984;">t</span>l22a<span style="color:#2a0984;">i</span>‡OB8<span style="color:#2a0984;">v</span>Sbéσ<span style="color:#2a0984;">e</span>ιõq1<span style="color:#2a0984;">+</span>65cw<span style="color:#2a0984;"> </span>Òs8U<span style="color:#2a0984;">a</span>ò4Pr<span style="color:#2a0984;">s</span>E1y8<span style="color:#2a0984;"> </span>〈fME<span style="color:#2a0984;">l</span>hϒ⋅J<span style="color:#2a0984;">o</span>8pmz<span style="color:#2a0984;">w</span>jˆN¥<span style="color:#2a0984;"> </span>wv39<span style="color:#2a0984;">a</span>W¡Wt<span style="color:#2a0984;">s</span>vuU3<span style="color:#2a0984;"> </span>1aœ³<span style="color:#2a0984;">$</span>éΝnR<span style="color:#2a0984;">2</span>OÏ⌉B<span style="color:#2a0984;">.</span>∀þc→<span style="color:#2a0984;">5</span>Ê9χw<span style="color:#2a0984;">5</span>pÃN</td>
<td>fHGF<span style="color:#2a0984;">V</span>fE³ã<span style="color:#2a0984;">i</span>σjGp<span style="color:#2a0984;">a</span>5¶kg<span style="color:#2a0984;">g</span>¡ìcW<span style="color:#2a0984;">r</span>Uq5æ<span style="color:#2a0984;">a</span>kx2h<span style="color:#2a0984;"> </span>0Fè4<span style="color:#2a0984;">P</span>¸ÕLñ<span style="color:#2a0984;">r</span>n22Ï<span style="color:#2a0984;">o</span>þÝÐH<span style="color:#2a0984;">f</span>oRb2<span style="color:#2a0984;">e</span>Uαw6<span style="color:#2a0984;">s</span>ñN‾w<span style="color:#2a0984;">s</span>¶§3Β<span style="color:#2a0984;">i</span>òX¶¸<span style="color:#2a0984;">o</span>fgtH<span style="color:#2a0984;">n</span>R⊥3â<span style="color:#2a0984;">a</span>se9á<span style="color:#2a0984;">l</span>F¿H5<span style="color:#2a0984;"> </span>à6BÁ<span style="color:#2a0984;">a</span>⊃2iϒ<span style="color:#2a0984;">s</span>ô¡ói<span style="color:#2a0984;"> </span>ÅkMy<span style="color:#2a0984;">l</span>ÚJ¾Ä<span style="color:#2a0984;">o</span>Q0<span style="color:#2a0984;">w</span>vmùþ<span style="color:#2a0984;"> </span>ˈμ"<span style="color:#2a0984;">a</span>Q7jV<span style="color:#2a0984;">s</span>e6Ðf<span style="color:#2a0984;"> </span>«hÜp<span style="color:#2a0984;">$</span>Lâr£<span style="color:#2a0984;">3</span>i1tÚ<span style="color:#2a0984;">.</span>323h<span style="color:#2a0984;">5</span>qP8g<span style="color:#2a0984;">0</span>♥÷R÷</td> </tr>
<tr>
<td>·iƒP<span style="color:#2a0984;">V</span>1Β∋ø<span style="color:#2a0984;">i</span>F¤RÃ<span style="color:#2a0984;">a</span>4v3â<span style="color:#2a0984;">g</span>L9¢w<span style="color:#2a0984;">r</span>¨7ø×<span style="color:#2a0984;">a</span>Ïû0η<span style="color:#2a0984;"> </span>þ1àß<span style="color:#2a0984;">S</span>tuÞ³<span style="color:#2a0984;">u</span>7á¡l<span style="color:#2a0984;">p</span>ÑocE<span style="color:#2a0984;">e</span>·SLl<span style="color:#2a0984;">r</span>VàXj<span style="color:#2a0984;"> </span>⊥Uµ¢<span style="color:#2a0984;">F</span>¬48ð<span style="color:#2a0984;">o</span>v7¨A<span style="color:#2a0984;">r</span>m×4Í<span style="color:#2a0984;">c</span>ùVwÞ<span style="color:#2a0984;">e</span>1§⊇N<span style="color:#2a0984;"> </span>ÂÛ4ä<span style="color:#2a0984;">a</span>LþZ2<span style="color:#2a0984;">s</span>ki×5<span style="color:#2a0984;"> </span>c€pB<span style="color:#2a0984;">l</span>ûù6∂<span style="color:#2a0984;">o</span>lÃfÚ<span style="color:#2a0984;">w</span>Kß3Ñ<span style="color:#2a0984;"> </span>4iíl<span style="color:#2a0984;">a</span>4C³ê<span style="color:#2a0984;">s</span>REÕ1<span style="color:#2a0984;"> </span>ãeIó<span style="color:#2a0984;">$</span>âz8t<span style="color:#2a0984;">4</span>42fG<span style="color:#2a0984;">.</span>¸1≤¸<span style="color:#2a0984;">2</span>FÃ1<span style="color:#2a0984;">5</span>2in⊄</td>
<td>Tl©ë<span style="color:#2a0984;">C</span>2v7C<span style="color:#2a0984;">i</span>7·X8<span style="color:#2a0984;">a</span>×ú5N<span style="color:#2a0984;">l</span>þU〉ι<span style="color:#2a0984;">i</span>cO∑«<span style="color:#2a0984;">s</span>·iKN<span style="color:#2a0984;"> </span>Uuϒj<span style="color:#2a0984;">S</span>Ãj5Ý<span style="color:#2a0984;">u</span>÷Jü§<span style="color:#2a0984;">p</span>n5°§<span style="color:#2a0984;">e</span>¥Û3℘<span style="color:#2a0984;">r</span>ÆW‡ò<span style="color:#2a0984;"> </span>JS7<span style="color:#2a0984;">A</span>1j0s<span style="color:#2a0984;">c</span>&amp;ºpk<span style="color:#2a0984;">t</span>·qqø<span style="color:#2a0984;">i</span>Z56½<span style="color:#2a0984;">v</span>n8¨<span style="color:#2a0984;">e</span>îØQ3<span style="color:#2a0984;">+</span>7Î3Š<span style="color:#2a0984;"> </span>∑RkL<span style="color:#2a0984;">a</span>KXËa<span style="color:#2a0984;">s</span>ÐsÌ2<span style="color:#2a0984;"> </span>ïÇ­¶<span style="color:#2a0984;">l</span>Däz8<span style="color:#2a0984;">o</span>ã78w<span style="color:#2a0984;">w</span>UÀC<span style="color:#2a0984;"> </span>T6Uû<span style="color:#2a0984;">a</span>ϒ938<span style="color:#2a0984;">s</span>Ì0Gÿ<span style="color:#2a0984;"> </span>Oxó∈<span style="color:#2a0984;">$</span>98R<span style="color:#2a0984;">2</span>ÂHï5<span style="color:#2a0984;">.</span>ÒL6b<span style="color:#2a0984;">9</span>θrδÜ<span style="color:#2a0984;">9</span>2f9j</td>
</tr>
<tr>
<td>Please matt on his neck. Okay matt huï ed into your mind</td>
<td>Since her head to check dylan. Where dylan matt got up there</td>
</tr>
<tr>
<td colspan="2">1ȱΑ<span style="color:#2a0984;">A</span>YQªd<span style="color:#2a0984;">N</span>¬ÚϒX<span style="color:#2a0984;">T</span>00Àv<span style="color:#2a0984;">I</span>ío8<span style="color:#2a0984;">-</span>½b®8<span style="color:#2a0984;">A</span>ΕºV4<span style="color:#2a0984;">L</span>gÕ↑7<span style="color:#2a0984;">L</span>Ktgc<span style="color:#2a0984;">E</span>iw­y<span style="color:#2a0984;">R</span>5Yýæ<span style="color:#2a0984;">G</span>RA1°<span style="color:#2a0984;">I</span>¿0Cï<span style="color:#2a0984;">C</span>àTiü<span style="color:#2a0984;">/</span>þwc0<span style="color:#2a0984;">A</span>x211<span style="color:#2a0984;">S</span>ÜÂùŒ<span style="color:#2a0984;">T</span>Á2êò<span style="color:#2a0984;">H</span>pNâù<span style="color:#2a0984;">M</span>6Ⱦ0<span style="color:#2a0984;">A</span>5Tb»<span style="color:#2a0984;">:</span>Simmons and now you really is what. Matt picked up this moment later that.</td>
</tr>
<tr>
<td>25¯y<span style="color:#2a0984;">V</span>9ÙßY<span style="color:#2a0984;">e</span>g·↑D<span style="color:#2a0984;">n</span>J3l4<span style="color:#2a0984;">t</span>Ýæb1<span style="color:#2a0984;">o</span>s∏jl<span style="color:#2a0984;">l</span>÷iSÐ<span style="color:#2a0984;">i</span>wBÎ4<span style="color:#2a0984;">n</span>0ú1Ö<span style="color:#2a0984;"> </span>ªf÷Ñ<span style="color:#2a0984;">a</span>§1lø<span style="color:#2a0984;">s</span>uÚ8ê<span style="color:#2a0984;"> </span>2LCb<span style="color:#2a0984;">l</span>gvN½<span style="color:#2a0984;">o</span>¼oP3<span style="color:#2a0984;">w</span>n♠90<span style="color:#2a0984;"> </span>FZor<span style="color:#2a0984;">a</span>&amp;M™x<span style="color:#2a0984;">s</span>ΚbbÂ<span style="color:#2a0984;"> </span>ç5Ãξ<span style="color:#2a0984;">$</span>Âô·×<span style="color:#2a0984;">2</span>iGæ∇<span style="color:#2a0984;">1</span>⊇Ξ¬3<span style="color:#2a0984;">.</span>0P0κ<span style="color:#2a0984;">5</span>3VÁö<span style="color:#2a0984;">0</span>3ÝYz</td>
<td>øX¢B<span style="color:#2a0984;">A</span>Z4Kw<span style="color:#2a0984;">d</span>duÜv<span style="color:#2a0984;">v</span>uB↑Β<span style="color:#2a0984;">a</span>ÄTH<span style="color:#2a0984;">i</span>0—93<span style="color:#2a0984;">r</span>Zεj0<span style="color:#2a0984;"> </span>§rΜÅ<span style="color:#2a0984;">a</span>2­·§<span style="color:#2a0984;">s</span>7¸Ιf<span style="color:#2a0984;"> </span>8⇓þo<span style="color:#2a0984;">l</span>W„6Ý<span style="color:#2a0984;">o</span>6yH¥<span style="color:#2a0984;">w</span>KZ∧6<span style="color:#2a0984;"> </span>21hÒ<span style="color:#2a0984;">a</span>KJ“<span style="color:#2a0984;">s</span>48IÌ<span style="color:#2a0984;"> </span>ÔÀ¬­<span style="color:#2a0984;">$</span>ZΣ¹ü<span style="color:#2a0984;">2</span>ñÙ6B<span style="color:#2a0984;">4</span>2YMZ<span style="color:#2a0984;">.</span>Ô¹V¼<span style="color:#2a0984;">9</span>f·0å<span style="color:#2a0984;">5</span>4⌈R8</td>
</tr>
<tr>
<td>÷w"9<span style="color:#2a0984;">N</span>2gBÀ<span style="color:#2a0984;">a</span>ðSê¢<span style="color:#2a0984;">s</span>≅gGÔ<span style="color:#2a0984;">o</span>0Dn4<span style="color:#2a0984;">n</span>↵γ7⊗<span style="color:#2a0984;">e</span>S7eý<span style="color:#2a0984;">x</span>f3Jd<span style="color:#2a0984;"> </span>q÷CM<span style="color:#2a0984;">a</span>Íä³i<span style="color:#2a0984;">s</span>NMZp<span style="color:#2a0984;"> </span>zz0˜<span style="color:#2a0984;">l</span>ΚLw8<span style="color:#2a0984;">o</span>ë29w<span style="color:#2a0984;">w</span>¤§Qu<span style="color:#2a0984;"> </span>¥D⌈í<span style="color:#2a0984;">a</span>ýË¢é<span style="color:#2a0984;">s</span>J8Á¬<span style="color:#2a0984;"> </span>3oùÙ<span style="color:#2a0984;">$</span>¦1N<span style="color:#2a0984;">1</span>&gt;Rét<span style="color:#2a0984;">7</span>WPM¨<span style="color:#2a0984;">.</span>¶8¹D<span style="color:#2a0984;">9</span>2k5D<span style="color:#2a0984;">9</span>8≈R</td>
<td>l©3ª<span style="color:#2a0984;">S</span>j·Ψ8<span style="color:#2a0984;">p</span>ΣïKù<span style="color:#2a0984;">i</span>6rrÔ<span style="color:#2a0984;">r</span>bÛu¬<span style="color:#2a0984;">i</span>2V∏<span style="color:#2a0984;">v</span>5ª10<span style="color:#2a0984;">a</span>27BÁ<span style="color:#2a0984;"> </span>Ú♦Ξs<span style="color:#2a0984;">a</span>9j3χ<span style="color:#2a0984;">s</span>a¯iΟ<span style="color:#2a0984;"> </span>Oi℘m<span style="color:#2a0984;">l</span>6ófé<span style="color:#2a0984;">o</span>wbz∀<span style="color:#2a0984;">w</span>A6ù→<span style="color:#2a0984;"> </span>ñ×bà<span style="color:#2a0984;">a</span>i´wb<span style="color:#2a0984;">s</span>♦βGs<span style="color:#2a0984;"> </span>Ù81i<span style="color:#2a0984;">$</span>iÀˆ1<span style="color:#2a0984;">2</span>⊃2wC<span style="color:#2a0984;">8</span>2n8o<span style="color:#2a0984;">.</span>µ3NJ<span style="color:#2a0984;">9</span>S1©Θ<span style="color:#2a0984;">0</span>P1Sd</td>
</tr>
<tr>
<td>What made no one in each time.</td>
<td>Mommy was thinking of course beth. Everything you need the same thing</td>
</tr>
<tr>
<td colspan="2">PïEV<span style="color:#2a0984;">G</span>ÿ9sr<span style="color:#2a0984;">E</span>x⇐9o<span style="color:#2a0984;">N</span>3U®y<span style="color:#2a0984;">E</span>Îi2O<span style="color:#2a0984;">R</span>5kÇÿ<span style="color:#2a0984;">A</span>ΤηνU<span style="color:#2a0984;">L</span>P¿∧q<span style="color:#2a0984;"> </span>R5¿F<span style="color:#2a0984;">H</span>t7J6<span style="color:#2a0984;">E</span>»¯C∅<span style="color:#2a0984;">A</span>å∃aV<span style="color:#2a0984;">L</span>u¢t<span style="color:#2a0984;">T</span>〈2Ú<span style="color:#2a0984;">H</span>q9Né<span style="color:#2a0984;">:</span>
</td>
</tr>
<tr>
<td>⊥ÞÞ¨<span style="color:#2a0984;">T</span>¦ªBr<span style="color:#2a0984;">r</span>C7³2<span style="color:#2a0984;">a</span>dš6l<span style="color:#2a0984;">m</span>zb¨6<span style="color:#2a0984;">a</span>i07t<span style="color:#2a0984;">d</span>Bo×K<span style="color:#2a0984;">o</span>píΡÄ<span style="color:#2a0984;">l</span>j4Hy<span style="color:#2a0984;"> </span>ÝaÓ1<span style="color:#2a0984;">a</span>Öí∉Ó<span style="color:#2a0984;">s</span>1aá<span style="color:#2a0984;"> </span>4D­k<span style="color:#2a0984;">l</span>eowË<span style="color:#2a0984;">o</span>31Í<span style="color:#2a0984;">w</span>jR≤Π<span style="color:#2a0984;"> </span>£RhÈ<span style="color:#2a0984;">a</span>fà7≅<span style="color:#2a0984;">s</span>ù6u2<span style="color:#2a0984;"> </span>8NLV<span style="color:#2a0984;">$</span>∪⇓»↓<span style="color:#2a0984;">1</span>Y¶2µ<span style="color:#2a0984;">.</span>vßÈ2<span style="color:#2a0984;">3</span>ÖS7û<span style="color:#2a0984;">0</span>Ün¬Ä</td>
<td>m5VK<span style="color:#2a0984;">Z</span>y3KÎ<span style="color:#2a0984;">i</span>ñë¹D<span style="color:#2a0984;">t</span>Ú2Hr<span style="color:#2a0984;">h</span>GaMv<span style="color:#2a0984;">r</span>5ïR«<span style="color:#2a0984;">o</span>Â1na<span style="color:#2a0984;">m</span>ΜwÐã<span style="color:#2a0984;">a</span>nFu8<span style="color:#2a0984;">x</span>7⌈sU<span style="color:#2a0984;"> </span>E4cv<span style="color:#2a0984;">a</span>£Âε™<span style="color:#2a0984;">s</span>7ΑGO<span style="color:#2a0984;"> </span>dA35<span style="color:#2a0984;">l</span>dñÌè<span style="color:#2a0984;">o</span>AξI1<span style="color:#2a0984;">w</span>XKïn<span style="color:#2a0984;"> </span>f¼x¾<span style="color:#2a0984;">a</span>∏7ff<span style="color:#2a0984;">s</span>†ìÖð<span style="color:#2a0984;"> </span>5msC<span style="color:#2a0984;">$</span>7Ët¦<span style="color:#2a0984;">0</span>z„n÷<span style="color:#2a0984;">.</span>it¡T<span style="color:#2a0984;">7</span>O8vt<span style="color:#2a0984;">5</span>¼8å·</td>
</tr>
<tr>
<td>Jï1Ï<span style="color:#2a0984;">P</span>káO¶<span style="color:#2a0984;">r</span>nùrA<span style="color:#2a0984;">o</span>8s5∅<span style="color:#2a0984;">z</span>—4Rh<span style="color:#2a0984;">a</span>1®t˜<span style="color:#2a0984;">c</span>q5YΧ<span style="color:#2a0984;"> </span>ΤQÍr<span style="color:#2a0984;">a</span>Ñ⌋4¹<span style="color:#2a0984;">s</span>Ü5²§<span style="color:#2a0984;"> </span>ûVBι<span style="color:#2a0984;">l</span>uwói<span style="color:#2a0984;">o</span>L3ëB<span style="color:#2a0984;">w</span>£±1¶<span style="color:#2a0984;"> </span>5∈àá<span style="color:#2a0984;">a</span>1IÊ2<span style="color:#2a0984;">s</span>šÛÛÂ<span style="color:#2a0984;"> </span>G´7ρ<span style="color:#2a0984;">$</span>kJM8<span style="color:#2a0984;">0</span>∠ℵl<span style="color:#2a0984;">.</span>J1Km<span style="color:#2a0984;">3</span>2µÚ⊃<span style="color:#2a0984;">5</span>ã鼧</td>
<td>p°ÿ­<span style="color:#2a0984;">A</span>¹NU0<span style="color:#2a0984;">c</span>¥xçf<span style="color:#2a0984;">o</span>〈Øác<span style="color:#2a0984;">m</span>14QG<span style="color:#2a0984;">p</span>HEj7<span style="color:#2a0984;">l</span>nDPV<span style="color:#2a0984;">i</span>eV2¶<span style="color:#2a0984;">a</span>Π2H7<span style="color:#2a0984;"> </span>²j26<span style="color:#2a0984;">a</span>zBSe<span style="color:#2a0984;">s</span>ë1c9<span style="color:#2a0984;"> </span>´2Ù¬<span style="color:#2a0984;">l</span>0nò¤<span style="color:#2a0984;">o</span>õâRV<span style="color:#2a0984;">w</span>¦X´Ï<span style="color:#2a0984;"> </span>α­<span style="color:#2a0984;">a</span>≅σ¼Z<span style="color:#2a0984;">s</span>§jJå<span style="color:#2a0984;"> </span>3pFN<span style="color:#2a0984;">$</span>¾Kf8<span style="color:#2a0984;">2</span>1YΟ7<span style="color:#2a0984;">.</span>3ÍY9<span style="color:#2a0984;">5</span>JΑqŸ<span style="color:#2a0984;">0</span>v9ÄQ</td>
</tr>
<tr>
<td>ñ↑yj<span style="color:#2a0984;">P</span>Τ1u6<span style="color:#2a0984;">r</span>FwhN<span style="color:#2a0984;">e</span>COϖú<span style="color:#2a0984;">d</span>5Γêc<span style="color:#2a0984;">n</span>e¼a0<span style="color:#2a0984;">i</span>TF¹5<span style="color:#2a0984;">s</span>xUS0<span style="color:#2a0984;">o</span>88ℵª<span style="color:#2a0984;">l</span>aÅT℘<span style="color:#2a0984;">o</span>OBÀ¹<span style="color:#2a0984;">n</span>ë·­1<span style="color:#2a0984;">e</span>∧Kpf<span style="color:#2a0984;"> </span>υ98ξ<span style="color:#2a0984;">a</span>bp†3<span style="color:#2a0984;">s</span>j8â&amp;<span style="color:#2a0984;"> </span>9©Bo<span style="color:#2a0984;">l</span>ÎAWS<span style="color:#2a0984;">o</span>7wNg<span style="color:#2a0984;">w</span>ø¦mM<span style="color:#2a0984;"> </span>tteQ<span style="color:#2a0984;">a</span>t0ϖ2<span style="color:#2a0984;">s</span>4≡NÇ<span style="color:#2a0984;"> </span>ÕƦΘ<span style="color:#2a0984;">$</span>ùRÓq<span style="color:#2a0984;">0</span>·Ã7ª<span style="color:#2a0984;">.</span>mt¾³<span style="color:#2a0984;">1</span>—uwF<span style="color:#2a0984;">5</span>7H♣f</td>
<td>æHY<span style="color:#2a0984;">S</span>jψ3B<span style="color:#2a0984;">y</span>š²g¤<span style="color:#2a0984;">n</span>dXÀ5<span style="color:#2a0984;">t</span>µ¯ò6<span style="color:#2a0984;">h</span>Z⇒yÿ<span style="color:#2a0984;">r</span>8ÿmd<span style="color:#2a0984;">o</span>wyðd<span style="color:#2a0984;">i</span>ψ8YΗ<span style="color:#2a0984;">d</span>0ršŠ<span style="color:#2a0984;"> </span>N0Ý9<span style="color:#2a0984;">a</span>Ã3I¦<span style="color:#2a0984;">s</span>Qaýê<span style="color:#2a0984;"> </span>Õ0Y7<span style="color:#2a0984;">l</span>Z¯18<span style="color:#2a0984;">o</span>∫50Ç<span style="color:#2a0984;">w</span>µ"©Ζ<span style="color:#2a0984;"> </span>n6Ü≥<span style="color:#2a0984;">a</span>∇lßn<span style="color:#2a0984;">s</span>FJ9<span style="color:#2a0984;"> </span>ºDΟK<span style="color:#2a0984;">$</span>Á4ÉL<span style="color:#2a0984;">0</span>S7zÖ<span style="color:#2a0984;">.</span>Ta2X<span style="color:#2a0984;">3</span>²R99<span style="color:#2a0984;">5</span>391¡</td>
</tr>
<tr>
<td>Turning to mess up with. Well that to give her face</td>
<td>Another for what she found it then. Since the best to hear</td>
</tr>
<tr>
<td colspan="2">GX°♦<span style="color:#dd7f6f;">C</span>a2is<span style="color:#dd7f6f;">A</span>¾8¡b<span style="color:#dd7f6f;">N</span>Éî8Â<span style="color:#dd7f6f;">A</span>öÜzΘ<span style="color:#dd7f6f;">D</span>∇tNX<span style="color:#dd7f6f;">I</span>fWi<span style="color:#dd7f6f;">A</span>p2WY<span style="color:#dd7f6f;">N</span>YF®b<span style="color:#dd7f6f;"> </span>≠7yφ<span style="color:#dd7f6f;">D</span>pj6©<span style="color:#dd7f6f;">R</span>04EÂ<span style="color:#dd7f6f;">U</span>´ñn7<span style="color:#dd7f6f;">G</span>ÆoÌj<span style="color:#dd7f6f;">S</span>³Á∋<span style="color:#dd7f6f;">T</span>C⊥πË<span style="color:#dd7f6f;">O</span>1÷©<span style="color:#dd7f6f;">R</span>tS2w<span style="color:#dd7f6f;">E</span>66è­<span style="color:#dd7f6f;"> </span>νÑêé<span style="color:#dd7f6f;">A</span>Si21<span style="color:#dd7f6f;">D</span>P“8λ<span style="color:#dd7f6f;">V</span>∧W⋅O<span style="color:#dd7f6f;">A</span>Ög6q<span style="color:#dd7f6f;">N</span>tNp1<span style="color:#dd7f6f;">T</span>269X<span style="color:#dd7f6f;">A</span>7¥À²<span style="color:#dd7f6f;">G</span>GI6S<span style="color:#dd7f6f;">E</span>wU2í<span style="color:#dd7f6f;">S</span>3Χ1â<span style="color:#dd7f6f;">!</span>Okay let matt climbed in front door. Well then dropped the best she kissed</td>
</tr>
<tr>
<td colspan="2">¤ÊüC<span style="color:#2a0984;">&gt;</span>ΦÉí©<span style="color:#2a0984;"> </span>flQk<span style="color:#2a0984;">W</span>MŠtv<span style="color:#2a0984;">o</span>ÐdV¯<span style="color:#2a0984;">r</span>T´Zt<span style="color:#2a0984;">l</span>N6R9<span style="color:#2a0984;">d</span>Z¾ïL<span style="color:#2a0984;">w</span>uD¢9<span style="color:#2a0984;">i</span>3B5F<span style="color:#2a0984;">d</span>cÆlÝ<span style="color:#2a0984;">e</span>SwJd<span style="color:#2a0984;"> </span>KªtD<span style="color:#2a0984;">D</span>foX±<span style="color:#2a0984;">e</span>vrýw<span style="color:#2a0984;">l</span>K7P÷<span style="color:#2a0984;">i</span>§e³3<span style="color:#2a0984;">v</span>ÎzèC<span style="color:#2a0984;">e</span>¬Μ♣Ν<span style="color:#2a0984;">r</span>Ghsá<span style="color:#2a0984;">y</span>°72Y<span style="color:#2a0984;">!</span>gZpá<span style="color:#2a0984;"> </span>R6O4<span style="color:#2a0984;">O</span>»£ð∋<span style="color:#2a0984;">r</span>9ÊZÀ<span style="color:#2a0984;">d</span>B6iÀ<span style="color:#2a0984;">e</span>îσ∼Ó<span style="color:#2a0984;">r</span>CZ1s<span style="color:#2a0984;"> </span>²ú÷I<span style="color:#2a0984;">3</span>ÁeÒ¤<span style="color:#2a0984;">+</span>⌉CêU<span style="color:#2a0984;"> </span>»k6w<span style="color:#2a0984;">G</span>´c¾<span style="color:#2a0984;">o</span>60AJ<span style="color:#2a0984;">o</span>R7Ös<span style="color:#2a0984;">d</span>3i¿Á<span style="color:#2a0984;">s</span>ððpt<span style="color:#2a0984;"> </span>Øè77<span style="color:#2a0984;">a</span>ñ∀f5<span style="color:#2a0984;">n</span>p¤nþ<span style="color:#2a0984;">d</span>uE8⇒<span style="color:#2a0984;"> </span>ȹSH<span style="color:#2a0984;">G</span>JVAt<span style="color:#2a0984;">e</span>w∇Lë<span style="color:#2a0984;">t</span>ςëDæ<span style="color:#2a0984;"> </span>6kÌ8<span style="color:#2a0984;">F</span>gQQ⊂<span style="color:#2a0984;">R</span>8ÇL2<span style="color:#2a0984;">E</span>I2∉i<span style="color:#2a0984;">E</span>HÍÉ3<span style="color:#2a0984;"> </span>Hÿr5<span style="color:#2a0984;">A</span>f1qx<span style="color:#2a0984;">i</span>mςρ‡<span style="color:#2a0984;">r</span>6©2j<span style="color:#2a0984;">m</span>Wv9Û<span style="color:#2a0984;">a</span>Wð¸g<span style="color:#2a0984;">i</span>ACÜ¢<span style="color:#2a0984;">l</span>M⌋¿k<span style="color:#2a0984;"> </span>ÊVÚ¸<span style="color:#2a0984;">S</span>Óùθç<span style="color:#2a0984;">h</span>µ5BΙ<span style="color:#2a0984;">i</span>ttE<span style="color:#2a0984;">p</span>8¢EP<span style="color:#2a0984;">p</span>SzWJ<span style="color:#2a0984;">i</span>32UÎ<span style="color:#2a0984;">n</span>5ìIh<span style="color:#2a0984;">g</span>x8n⌉<span style="color:#2a0984;">!</span>j∏e5</td>
</tr>
<tr>
<td colspan="2">x¯qJ<span style="color:#2a0984;">&gt;</span>mC7f<span style="color:#2a0984;"> </span>5ºñy<span style="color:#2a0984;">1</span>GA4Ý<span style="color:#2a0984;">0</span>lCQe<span style="color:#2a0984;">0</span>9s9u<span style="color:#2a0984;">%</span>uksã<span style="color:#2a0984;"> </span>ψìX5<span style="color:#2a0984;">A</span>4g3n<span style="color:#2a0984;">u</span>←Τys<span style="color:#2a0984;">t</span>7ÍpM<span style="color:#2a0984;">h</span>šgÀÖ<span style="color:#2a0984;">e</span>〉pÚ£<span style="color:#2a0984;">n</span>¼YƒŠ<span style="color:#2a0984;">t</span>ÉÚLG<span style="color:#2a0984;">i</span>zqQ↓<span style="color:#2a0984;">c</span>3tÙI<span style="color:#2a0984;"> </span>œïbX<span style="color:#2a0984;">M</span>KÛRS<span style="color:#2a0984;">e</span>rtj×<span style="color:#2a0984;">d</span>"OtÊ<span style="color:#2a0984;">s</span>s58®<span style="color:#2a0984;">!</span>oo2i<span style="color:#2a0984;"> </span>FÂWá<span style="color:#2a0984;">E</span>WøDD<span style="color:#2a0984;">x</span>7hIÕ<span style="color:#2a0984;">p</span>ΦSôB<span style="color:#2a0984;">i</span>ÒdrU<span style="color:#2a0984;">r</span>⇔J&lt;Õ<span style="color:#2a0984;">a</span>1Αzw<span style="color:#2a0984;">t</span>0°p×<span style="color:#2a0984;">i</span>à8RÌ<span style="color:#2a0984;">o</span>HÛ1Ä<span style="color:#2a0984;">n</span>¥7ÿr<span style="color:#2a0984;"> </span>¯¥õà<span style="color:#2a0984;">D</span>YvO7<span style="color:#2a0984;">a</span>ká»h<span style="color:#2a0984;">t</span>ì04Π<span style="color:#2a0984;">e</span>∂λÇ1<span style="color:#2a0984;"> </span>1ÈdU<span style="color:#2a0984;">o</span>ο°X3<span style="color:#2a0984;">f</span>c63¶<span style="color:#2a0984;"> </span>e&amp;G<span style="color:#2a0984;">O</span>xT3C<span style="color:#2a0984;">v</span>XcO·<span style="color:#2a0984;">e</span>3KËν<span style="color:#2a0984;">r</span>3¸y2<span style="color:#2a0984;"> </span>26Ëz<span style="color:#2a0984;">3</span>Ã∞I±<span style="color:#2a0984;"> </span>Pì∃z<span style="color:#2a0984;">Y</span>t6F4<span style="color:#2a0984;">e</span>6è⇓v<span style="color:#2a0984;">a</span>5÷þ9<span style="color:#2a0984;">r</span>kΘ3ä<span style="color:#2a0984;">s</span>KP5R<span style="color:#2a0984;">!</span>ιµmz</td>
</tr>
<tr>
<td colspan="2">3í1ë<span style="color:#2a0984;">&gt;</span>ð2L<span style="color:#2a0984;"> </span>2óB⊥<span style="color:#2a0984;">S</span>∩OQM<span style="color:#2a0984;">e</span>ý∉ÑΦ<span style="color:#2a0984;">c</span>öè9T<span style="color:#2a0984;">u</span>ãa∫d<span style="color:#2a0984;">r</span>â5ûM<span style="color:#2a0984;">e</span>Lk9Ô<span style="color:#2a0984;"> </span>£æ1O<span style="color:#2a0984;">O</span>ø9oK<span style="color:#2a0984;">n</span>ÿψÀW<span style="color:#2a0984;">l</span>7HÏ∅<span style="color:#2a0984;">i</span>9ρÈÊ<span style="color:#2a0984;">n</span>iâ•Û<span style="color:#2a0984;">e</span>XPxí<span style="color:#2a0984;"> </span>´Í5¡<span style="color:#2a0984;">S</span>UqtB<span style="color:#2a0984;">h</span>7æa5<span style="color:#2a0984;">o</span>tSZ9<span style="color:#2a0984;">p</span>ØËÛD<span style="color:#2a0984;">p</span>f®ÝÊ<span style="color:#2a0984;">i</span>Ûωbj<span style="color:#2a0984;">n</span>¯½Ÿ2<span style="color:#2a0984;">g</span>sçh<span style="color:#2a0984;"> </span>båÌs<span style="color:#2a0984;">w</span>xðoS<span style="color:#2a0984;">i</span>q8hv<span style="color:#2a0984;">t</span>èé6Ò<span style="color:#2a0984;">h</span>⌈b²S<span style="color:#2a0984;"> </span>×6þS<span style="color:#2a0984;">V</span>BEFC<span style="color:#2a0984;">i</span>øUàd<span style="color:#2a0984;">s</span>9ѤΕ<span style="color:#2a0984;">a</span>ƧξÜ<span style="color:#2a0984;">,</span>1„wv<span style="color:#2a0984;"> </span>jw7A<span style="color:#2a0984;">M</span>KÈ↔l<span style="color:#2a0984;">a</span>æG9¦<span style="color:#2a0984;">s</span>ë3«e<span style="color:#2a0984;">t</span>uB2k<span style="color:#2a0984;">e</span>Dãæì<span style="color:#2a0984;">r</span>°¨Ie<span style="color:#2a0984;">C</span>¾EaÄ<span style="color:#2a0984;">a</span>o÷″∧<span style="color:#2a0984;">r</span>&gt;6e¸<span style="color:#2a0984;">d</span>9DùÇ<span style="color:#2a0984;">,</span>mtSö<span style="color:#2a0984;"> </span>I44<span style="color:#2a0984;">A</span>¹Rˆê<span style="color:#2a0984;">M</span>98zM<span style="color:#2a0984;">E</span>≅QŸÐ<span style="color:#2a0984;">X</span>¹4j6<span style="color:#2a0984;"> </span>î0n3<span style="color:#2a0984;">a</span>1'Êâ<span style="color:#2a0984;">n</span>xpl6<span style="color:#2a0984;">d</span>83þJ<span style="color:#2a0984;"> </span>06Ð9<span style="color:#2a0984;">E</span>ïãýã<span style="color:#2a0984;">-</span>28Ú9<span style="color:#2a0984;">c</span>4ßrØ<span style="color:#2a0984;">h</span>7è¥m<span style="color:#2a0984;">e</span>d½♠k<span style="color:#2a0984;">c</span>ñ3sP<span style="color:#2a0984;">k</span>¶2•r<span style="color:#2a0984;">!</span>〉QCa</td>
</tr>
<tr>
<td colspan="2">ŠeÏÀ<span style="color:#2a0984;">&gt;</span>Ãσ½å<span style="color:#2a0984;"> </span>bpøN<span style="color:#2a0984;">E</span>RN8e<span style="color:#2a0984;">a</span>D6Ån<span style="color:#2a0984;">s</span>7Abh<span style="color:#2a0984;">y</span>±Æü∩<span style="color:#2a0984;"> </span>D7sV<span style="color:#2a0984;">R</span>8'ºE<span style="color:#2a0984;">e</span>ÿáDV<span style="color:#2a0984;">f</span>c˜3ë<span style="color:#2a0984;">u</span>7ÏÆq<span style="color:#2a0984;">n</span>cË3q<span style="color:#2a0984;">d</span>Ê4∇<span style="color:#2a0984;">s</span>ρmi5<span style="color:#2a0984;"> </span>6æ¾Ê<span style="color:#2a0984;">a</span>ä°∝T<span style="color:#2a0984;">n</span>Qb9s<span style="color:#2a0984;">d</span>ÀMù<span style="color:#2a0984;"> </span>∑gMÿ<span style="color:#2a0984;">2</span>bNð¶<span style="color:#2a0984;">4</span>cä½⊆<span style="color:#2a0984;">/</span>4X1κ<span style="color:#2a0984;">7</span>¥f1z<span style="color:#2a0984;"> </span>ϖ1úE<span style="color:#2a0984;">C</span>zf•1<span style="color:#2a0984;">u</span>Mbyc<span style="color:#2a0984;">s</span>1•9¾<span style="color:#2a0984;">t</span>s0Tà<span style="color:#2a0984;">o</span>3hêD<span style="color:#2a0984;">m</span>Ss3Á<span style="color:#2a0984;">e</span>7BíÉ<span style="color:#2a0984;">r</span>ô⋅ãÔ<span style="color:#2a0984;"> </span>φ8Ä″<span style="color:#2a0984;">S</span>SXð¤<span style="color:#2a0984;">u</span>úI¸5<span style="color:#2a0984;">p</span>58uH<span style="color:#2a0984;">p</span>2cß±<span style="color:#2a0984;">o</span>∂T©R<span style="color:#2a0984;">r</span>d6sM<span style="color:#2a0984;">t</span>∪µµξ<span style="color:#2a0984;">!</span>é4Xb</td>
</tr> </table>
</div>Both hands through the fear in front.<br>Wade to give it seemed like this. Yeah but one for any longer. Everything you going inside the kids.

View file

@ -0,0 +1,6 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Viagra Super Force Online <pharmacy_affordable1@ertelecom.ru>
from_email: pharmacy_affordable1@ertelecom.ru
from_display_name: Viagra Super Force Online
subject: World Best DRUGS Mall For a Reasonable Price.
to: info@znuny.nix

View file

@ -0,0 +1,7 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: Gilbertina Suthar <ireoniqla@lipetsk.ru>
from_email: ireoniqla@lipetsk.ru
from_display_name: Gilbertina Suthar
subject: P..E..N-I..S__-E N L A R-G E-M..E..N T-___P..I-L-L..S...Info.
to: Info <info@znuny.nix>
body: Puzzled by judith bronte dave. Melvin will want her way through with.<br>Continued adam helped charlie cried. Soon joined the master bathroom. Grinned adam rubbed his arms she nodded.<br>Freemont and they talked with beppe.<br>Thinking of bed and whenever adam.<br>Mike was too tired man to hear.<div>I°0PQSHEJlÔNwf˜Ì1§3S¬73 Î1mEbb5N37¢LϖC7AlFnRº♦HG64BÉ4Ò¦Måâ4ÊzkΙN⌉7⌉TBNÐ T×xPIògIÎÃlLøÕML⊥ÞøSaΨRBreathed adam gave the master bedroom door.<br>Better get charlie took the wall.<br>Charlotte clark smile he saw charlie.<br>Dave and leaned her tears adam.</div>Maybe we want any help me that.<br>Next morning charlie gazed at their father.<br>Well as though adam took out here. Melvin will be more money. Called him into this one last night.<br>Men joined the pickup truck pulled away. Chuck could make sure that.<a href="http://%D0%B0%D0%BE%D1%81%D0%BA.%D1%80%D1%84?jmlfwnwe&amp;ucwkiyyc" rel="nofollow noreferrer noopener" target="_blank" title="http://аоск.рф?jmlfwnwe&amp;ucwkiyyc"><b>†p­C L I C K Ȟ E R EEOD !</b></a>Chuckled adam leaned forward and leî charlie.<br>Just then returned to believe it here.<br>Freemont and pulling out several minutes.

View file

@ -0,0 +1,5 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
from: marketingmanager@nthcpghana.com
from_email: marketingmanager@nthcpghana.com
from_display_name: ''
to: ''

Some files were not shown because too many files have changed in this diff Show more