Class: Imap::Backup::Serializer

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/imap/backup/serializer.rb,
lib/imap/backup/serializer/appender.rb,
lib/imap/backup/serializer/directory.rb,
lib/imap/backup/serializer/folder_maker.rb,
lib/imap/backup/serializer/integrity_checker.rb

Overview

Handles serialization for a folder

Defined Under Namespace

Classes: Appender, DelayedMetadataSerializer, Directory, FolderIntegrityError, FolderMaker, Imap, IntegrityChecker, Mbox, Message, MessageEnumerator, PermissionChecker, Transaction, UnusedNameFinder, Version2Migrator

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, folder) ⇒ Serializer

Returns a new instance of Serializer.

Parameters:

  • path (String)

    an account’s backup path

  • folder (String)

    a folder name



40
41
42
43
44
# File 'lib/imap/backup/serializer.rb', line 40

def initialize(path, folder)
  @path = path
  @folder = folder
  @validated = nil
end

Instance Attribute Details

#folderString (readonly)

Returns a folder name.

Returns:

  • (String)

    a folder name



34
35
36
# File 'lib/imap/backup/serializer.rb', line 34

def folder
  @folder
end

#pathString (readonly)

Returns an account’s backup path.

Returns:

  • (String)

    an account’s backup path



36
37
38
# File 'lib/imap/backup/serializer.rb', line 36

def path
  @path
end

Class Method Details

.folder_path_for(path:, folder:) ⇒ String

Returns the full path to a serialized folder (without file extensions).

Parameters:

  • path (String)

    an account’s backup path

  • folder (String)

    a folder name

Returns:

  • (String)

    the full path to a serialized folder (without file extensions)



23
24
25
26
# File 'lib/imap/backup/serializer.rb', line 23

def self.folder_path_for(path:, folder:)
  relative = File.join(path, folder)
  File.expand_path(relative)
end

Instance Method Details

#append(uid, message, flags) ⇒ void

This method returns an undefined value.

Appends a message to the serialized data

Parameters:

  • uid (Integer)

    the message’s UID

  • message (Integer)

    the message text

  • flags (Array[Symbol])

    the message’s flags



133
134
135
136
137
138
# File 'lib/imap/backup/serializer.rb', line 133

def append(uid, message, flags)
  validate!

  appender = Serializer::Appender.new(folder: sanitized, imap: imap, mbox: mbox)
  appender.append(uid: uid, message: message, flags: flags)
end

#apply_uid_validity(value) ⇒ String?

Sets the folder’s UID validity. If the existing value is nil, it sets the new value and ensures that both the metadata file and the mailbox are saved. If the supplied value is the same as the existing value, it does nothing. If the supplied valued is different to the existing value, it renames the existing folder to a new name, and creates a new folder with the supplied value.

Parameters:

  • value (Integer)

    The new UID validity value

Returns:

  • (String, nil)

    The name of the new folder



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/imap/backup/serializer.rb', line 102

def apply_uid_validity(value)
  validate!

  case
  when uid_validity.nil?
    internal_force_uid_validity(value)
    nil
  when uid_validity == value
    # NOOP
    nil
  else
    apply_new_uid_validity(value)
  end
end

#check_integrity!void

This method returns an undefined value.

Checks that the folder’s data is stored correctly



77
78
79
# File 'lib/imap/backup/serializer.rb', line 77

def check_integrity!
  IntegrityChecker.new(imap: imap, mbox: mbox).run
end

#deletevoid

This method returns an undefined value.

Deletes the serialized data



83
84
85
86
87
# File 'lib/imap/backup/serializer.rb', line 83

def delete
  imap.delete
  mbox.delete
  reload
end

#each_message(required_uids = nil, &block) ⇒ Enumerator, void

Enumerates over a series of messages. When called without a block, returns an Enumerator

Parameters:

  • required_uids (Array<Integer>) (defaults to: nil)

    the UIDs of the message to enumerate over

Returns:

  • (Enumerator, void)


156
157
158
159
160
161
162
163
164
165
# File 'lib/imap/backup/serializer.rb', line 156

def each_message(required_uids = nil, &block)
  return enum_for(:each_message, required_uids) if !block

  required_uids ||= uids

  validate!

  enumerator = Serializer::MessageEnumerator.new(imap: imap)
  enumerator.run(uids: required_uids, &block)
end

#filter(&block) ⇒ void

This method returns an undefined value.

Calls the supplied block on each message in the folder and discards those for which the block returns a false result

Parameters:

  • block (block)

    the block to call



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/imap/backup/serializer.rb', line 171

def filter(&block)
  temp_name = Serializer::UnusedNameFinder.new(serializer: self).run
  temp_folder_path = self.class.folder_path_for(path: path, folder: temp_name)
  new_mbox = Serializer::Mbox.new(temp_folder_path)
  new_imap = Serializer::Imap.new(temp_folder_path)
  new_imap.uid_validity = imap.uid_validity
  appender = Serializer::Appender.new(folder: temp_name, imap: new_imap, mbox: new_mbox)
  enumerator = Serializer::MessageEnumerator.new(imap: imap)
  enumerator.run(uids: uids) do |message|
    keep = block.call(message)
    appender.append(uid: message.uid, message: message.body, flags: message.flags) if keep
  end
  imap.delete
  new_imap.rename imap.folder_path
  mbox.delete
  new_mbox.rename mbox.folder_path
  reload
end

#folder_pathString

Returns the path to the serialized folder (without file extensions).

Returns:

  • (String)

    the path to the serialized folder (without file extensions)



191
192
193
# File 'lib/imap/backup/serializer.rb', line 191

def folder_path
  self.class.folder_path_for(path: path, folder: sanitized)
end

#force_uid_validity(value) ⇒ void

This method returns an undefined value.

Overwrites the UID validity of the folder and ensures that both the metadata file and the mailbox are saved.

Parameters:

  • value (Integer)

    the new UID validity



122
123
124
125
126
# File 'lib/imap/backup/serializer.rb', line 122

def force_uid_validity(value)
  validate!

  internal_force_uid_validity(value)
end

#reloadvoid

This method returns an undefined value.

Forces a reload of the serialized files



202
203
204
205
# File 'lib/imap/backup/serializer.rb', line 202

def reload
  @imap = nil
  @mbox = nil
end

#sanitizedString

Returns The folder’s name adapted for using as a file name.

Returns:

  • (String)

    The folder’s name adapted for using as a file name



196
197
198
# File 'lib/imap/backup/serializer.rb', line 196

def sanitized
  @sanitized ||= Naming.to_local_path(folder)
end

#transaction(&block) ⇒ void

This method returns an undefined value.

Calls the supplied block. This method is present so that this class implements the same interface as DelayedMetadataSerializer

Parameters:

  • block (block)

    the block that is wrapped by the transaction



52
53
54
# File 'lib/imap/backup/serializer.rb', line 52

def transaction(&block)
  block.call
end

#update(uid, flags: nil) ⇒ void

This method returns an undefined value.

Updates a messages flags

Parameters:

  • uid (Integer)

    the message’s UID

  • flags (Array<Symbol>) (defaults to: nil)

    the flags to set on the message



144
145
146
147
148
149
150
# File 'lib/imap/backup/serializer.rb', line 144

def update(uid, flags: nil)
  message = imap.get(uid)
  return if !message

  message.flags = flags if flags
  imap.save
end

#validate!Boolean

Checks that the metadata files are valid, migrates the metadata file from older versions, if necessary, or deletes any existing files if the pair are not valid.

Returns:

  • (Boolean)

    indicates whether there are existing, valid files



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/imap/backup/serializer.rb', line 60

def validate!
  return true if @validated

  optionally_migrate2to3

  if imap.valid? && mbox.valid?
    @validated = true
    return true
  end

  delete

  false
end