Documentation
¶
Index ¶
- Constants
- Variables
- func DeNormalizeAccountName(name string) string
- func DeNormalizeMaildirName(name string) string
- func FindMailFilePath(basepath string, uid uint32) (string, error)
- func NewOracle() *oracle
- func NormalizeAccountName(name string) string
- func NormalizeMaildirName(name string) string
- type ErrMalformedName
- type ErrTidying
- type Flag
- type Library
- func (l *Library) ClassifyMessages(mbox string, messages []*imap.Message) (*imap.SeqSet, *imap.SeqSet, []uint32)
- func (l *Library) LocalSync(mbox string, messages chan *imap.Message, done chan error) error
- func (l *Library) Persist(mbox string, pipe MessagePipe) error
- func (l *Library) RegisterMbox(mbox, basePath string) error
- func (l *Library) Tidy(mbox string, messageIds []uint32) error
- type MailDir
- type MailFile
- type MailRepo
- func (m *MailRepo) Add(key uint32, value *MailFile)
- func (m *MailRepo) Del(key uint32)
- func (m *MailRepo) Get(key uint32) (*MailFile, bool)
- func (m *MailRepo) Has(key uint32) bool
- func (m *MailRepo) Len() int
- func (m *MailRepo) MarshalJSON() ([]byte, error)
- func (m *MailRepo) Range(f func(uint32, *MailFile))
- func (m *MailRepo) RangeWhile(f func(uint32, *MailFile) bool)
- func (m *MailRepo) UnmarshalJSON(b []byte) error
- func (m *MailRepo) Value(key uint32) *MailFile
- type MailboxInfo
- type MessagePipe
- type NewMailDirParams
Constants ¶
const ( FlagSeen Flag = "S" FlagAnswered = "R" FlagFlagged = "F" FlagDeleted = "T" FlagDraft = "D" FlagUnknown = "" )
Variables ¶
var ErrErrorsChNotOk = errors.New("errors channel closed")
var ErrEventsChNotOk = errors.New("events channel closed")
var ErrMalformedFlags = errors.New("malformed flags")
var ErrNilMessage = errors.New("nil message")
var ErrNoMoreMessages = errors.New("no more messages")
var ErrNotFound = errors.New("File not found")
var ErrPathIsNotDirectory = errors.New("the path is not a directory")
var ErrUnknownFlag = errors.New("flag not known")
Functions ¶
func DeNormalizeAccountName ¶
func DeNormalizeMaildirName ¶
func NormalizeAccountName ¶
func NormalizeMaildirName ¶
Types ¶
type ErrMalformedName ¶
type ErrMalformedName struct {
// contains filtered or unexported fields
}
func (*ErrMalformedName) Error ¶
func (e *ErrMalformedName) Error() string
type ErrTidying ¶
type ErrTidying struct {
// contains filtered or unexported fields
}
func (*ErrTidying) Error ¶
func (e *ErrTidying) Error() string
type Library ¶
type Library struct { // Mailboxes are the names of the IMAP folders, with hierarchy separator replaced // with `.` Mailboxes []string // Info holds the information related to each IMAP folder Info map[string]MailboxInfo // Dirs is the true MailDir struct associated with each IMAP folder Dirs map[string]*MailDir // contains filtered or unexported fields }
Library represents the point where all the files, associated to a given IMAP account, are stored locally. The directory structure is flat with respect to the mailbox hierarchy. For example, if a given account has the following IMAP folders:
``` INBOX INBOX/remember INBOX/archives/proj1 INBOX/archives/proj2 Sent Spam Trash ```
This will be matched with the following directory structure
``` . ├── INBOX │ ├── cur │ ├── new │ └── tmp ├── INBOX.remember │ ├── cur │ ├── new │ └── tmp ├── INBOX.archives.proj1 │ ├── cur │ ├── new │ └── tmp ├── INBOX.archives.proj2 │ ├── cur │ ├── new │ └── tmp ├── Sent │ ├── cur │ ├── new │ └── tmp ├── Spam │ ├── cur │ ├── new │ └── tmp └── Trash ├── cur ├── new └── tmp ```
func InitLibrary ¶
func InitLibrary(name, basePath string, logger logz.Logger, upsyncCallback common.UpsyncCallbackFn) (*Library, error)
func (*Library) ClassifyMessages ¶
func (l *Library) ClassifyMessages(mbox string, messages []*imap.Message) (*imap.SeqSet, *imap.SeqSet, []uint32)
ClassifyMessages uses the messages given in input to prepare three lists
- the first is the list of message uids that have to be updated
- the second is the list of message uids that have to be downloaded anew
- the third is the list of message uids that have to be deleted
func (*Library) Persist ¶
func (l *Library) Persist(mbox string, pipe MessagePipe) error
Persist stores the given messages as files in the mailbox. It follows this logic:
- if a message has no flags, it has never been seen and is placed in new/
- if a message has some flag set (in particular the \Seen flag) it is placed directly in cur/ and marked as not new, as it has yet been consumed by some other MUA
func (*Library) RegisterMbox ¶
RegisterMbox ensures that the given mailbox is present in the current library and has a corresponding (existing) maildir
type MailDir ¶
type MailDir struct { MailFiles *MailRepo NewMailFiles *MailRepo RenamePipeline *MailRepo PutPipeline *MailRepo RemovePipeline *MailRepo // contains filtered or unexported fields }
func NewMailDir ¶
func NewMailDir(params NewMailDirParams) (*MailDir, error)
NewMailDir returns a new MailDir instance. If the underlying directory structure does not exist, the function creates it.
func (*MailDir) GetLastMsgId ¶
func (*MailDir) LocalInit ¶
LocalInit has the task to read all the maildir cur/ and new/ files and create the *MailFile correspondent entries in the MailFiles and NewMailFiles slices.
func (*MailDir) LocalMailFiles ¶
type MailFile ¶
type MailFile struct {
// contains filtered or unexported fields
}
MailFile holds the information needed to format the name of the file containing a single email. The format is: `<%d_%d.%d.%s>,U=<%d>,FMD5=<%s>:2,<FLAGS>` (logical groups being enclosed by angle brackets) where:
- `<%d_%d.%d.%s>` is the concatenation of:
- system unix timestamp of arrival time of the message
- a progressive number to distinguish messages arrived at once
- pid of the current process
- hostname of the local machine
- `,U=<%d>` holds the UID of the message as decided by the server
- `,FMD5=<%s>:2` holds the md5sum of the name of the current mailbox
- `,<FLAGS>` carries the flags active on the message
func NewMailFile ¶
func (*MailFile) MarshalJSON ¶
func (*MailFile) SetMd5FromName ¶
type MailRepo ¶
type MailRepo struct {
// contains filtered or unexported fields
}
MailRepo is much similar to sync.Map, but is tailored for usage within papero, because of the types at the interface and because it is not optimized for the sync.Map use cases. It is fundamentally a map[uint32]*MailFile with a *sync.RWMutex to allow rw access from multiple goroutines.
func NewMailRepo ¶
func NewMailRepo() *MailRepo
NewMailRepo returns a new *MailRepo, ready to be used.
func (*MailRepo) Get ¶
Get safely returns a *MailFile, if any, and a boolean, as when accessing a map.
func (*MailRepo) MarshalJSON ¶
func (*MailRepo) RangeWhile ¶
RangeWhile allows to safely apply a function on each tuple (key, value), as long such function returns `true`.
func (*MailRepo) UnmarshalJSON ¶
type MailboxInfo ¶
MailboxInfo holds some metadata about each IMAP folder local instance
type MessagePipe ¶
type MessagePipe interface {
Next() (*imap.Message, error)
}
type NewMailDirParams ¶
type NewMailDirParams struct {
Name, BasePath string
Logger logz.Logger
Upsync chan upsyncMsg
Errs chan errorMsg
}