offmap

package module
v0.0.0-...-f702f57 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2022 License: GPL-3.0 Imports: 10 Imported by: 0

README

offmap

An email synchronizer

Installation

Installation requires go and scdoc.

$ git clone https://git.sr.ht/~rockorager/offmap
$ cd offmap
$ make
$ sudo make install

Users of Archlinux can install the latest development version using the AUR package offmap-git.

Usage

Recommended usage includes adding verbosity flags. While offmap is in development, it will be important to watch the log outputs. Each 'v' increases the verbosity one level.

# Sync your mail
$ offmap sync -vvvv

# View the pending changes since last sync
$ offmap diff -vvvv

During development, offmap will not delete directories. Individual emails will be deleted, however full directories will not.

Configuration

Offmap configuration is intended to be very simple. The configuration file should be kept at: $XDG_CONFIG_HOME/offmap/offmap.toml

[account-name]
maildir         = "/abs/path/to/maildir"
host            = "imap.yourhost.com:993"
username        = "you@yourhost.com"
password        = "your-password"

Advantages

Offmap aims to improve over existing IMAP <-> maildir synchronization tools in two ways:

  1. Simpler configuration
  2. Usage of IMAP Extensions

Specifically, offmap will attempt to use the following IMAP extensions:

  • UIDPLUS (required)
  • CONDSTORE (optional)
  • LIST-STATUS (optional)
  • QRESYNC (not yet implemented)
  • MULTIAPPEND (not yet implemented)
  • COMPRESS (not yet implemented)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Name           string
	Maildir        string `toml:"maildir"`
	Host           string `toml:"host"`
	Username       string `toml:"username"`
	Password       string `toml:"password"`
	PasswordCmd    string `toml:"password-cmd"`
	AuthMech       string `toml:"auth-mech"`
	MaxConnections int    `toml:"max-connections"`
}

func LoadConfig

func LoadConfig(accts []string) ([]*Config, error)

type Diff

type Diff struct {
	Mailboxes *MailboxDiff

	// Emails is a map of EmailDiffs to mailbox name. The key will always be
	// in reference to the local name, ("/" as a delimiter)
	Emails map[string]*EmailDiff

	FetchFunc func(string, []*Email) chan *FullEmail
}

Diff represents the changes to the store state since last sync

func NewDiff

func NewDiff() *Diff

NewDiff creates a new Diff object

func (*Diff) Fetch

func (d *Diff) Fetch(name string, emls []*Email) chan *FullEmail

type Email

type Email struct {
	// The UID of the email
	UID uint32 `json:"u"`
	// The Maildir Key of the email
	Key string `json:"k"`
	// The current flags on the email
	Flags []maildir.Flag `json:"f"`
	// The UIDValidity of the mailbox the email belongs to
	UIDValidity uint32 `json:"m"`
	//
	Mailbox *Mailbox `json:"-"`
	// Date is the best known time for the email creation
	Date time.Time `json:"-"`
	// contains filtered or unexported fields
}

Email is the internal representation of an email's state

func NewEmail

func NewEmail(mbox *Mailbox, uid uint32, key string, flags []maildir.Flag) *Email

NewEmail creates a new Email object

func (*Email) Filename

func (e *Email) Filename() string

func (*Email) Len

func (e *Email) Len() int

func (*Email) Read

func (e *Email) Read(p []byte) (int, error)

func (*Email) SetFilename

func (e *Email) SetFilename(path string)

func (*Email) SetSize

func (e *Email) SetSize(i int)

type EmailDiff

type EmailDiff struct {
	Created     []*Email
	Deleted     []*Email
	FlagAdded   map[maildir.Flag][]*Email
	FlagRemoved map[maildir.Flag][]*Email
}

func CompareEmails

func CompareEmails(saved map[string]*Email, cur map[string]*Email) *EmailDiff

CompareEmails compares state of emails for a mailbox pair and adds them to the appropriate changes category. The passed maps are a map of <key> or <uid>, both as strings.

func NewEmailDiff

func NewEmailDiff() *EmailDiff

type FullEmail

type FullEmail struct {
	*Email
	Body io.Reader
	Size int
}

func (*FullEmail) Len

func (fe *FullEmail) Len() int

func (*FullEmail) Read

func (fe *FullEmail) Read(p []byte) (int, error)

func (*FullEmail) SetSize

func (fe *FullEmail) SetSize(i int)

type Mailbox

type Mailbox struct {
	// The UIDValidity of the mailbox
	UIDValidity uint32 `json:"uidvalidity"`
	// LocalName is the relative path of the maildir
	LocalName string `json:"localName"`
	// RemoteName is the name of the mailbox on the remote IMAP. It could
	// have different delimiters than filepath ("/")
	RemoteName string `json:"remoteName"`

	// The emails in the mailbox
	Emails []*Email `json:"emails"`

	// UIDNext is the next UID in the mailbox. This is only used in certain
	// sync scenarios
	UIDNext uint32 `json:"uidNext,omitempty"`
	// HighestModSeq is the highest mod seq reported by the server for this
	// mailbox. It is only used in certain sync scenarios
	HighestModSeq uint64 `json:"modseq,omitempty"`

	// If the mailbox is already synched.
	Synched bool `json:"-"`
}

Mailbox is the internal representation of a mailbox state

func NewMailbox

func NewMailbox(id uint32, local string, remote string) *Mailbox

NewMailbox creates a new Mailbox object

func (*Mailbox) EmailByKey

func (m *Mailbox) EmailByKey(key string) (*Email, bool)

type MailboxDiff

type MailboxDiff struct {
	// Mailboxes created since last sync
	Created []*Mailbox
	// Mailboxes renamed since last sync. The key will always be in
	// reference to the local name, ("/" as a delimiter), and is the old
	// name of the mailbox.
	Renamed map[string]*Mailbox
	// Mailboxes deleted since the last sync. These mailboxes are deleted
	// last
	Deleted []*Mailbox
	// UIDValidityChange are mailboxes whose names haven't changed, but
	// UIDvalidity has. These mailboxes are deleted before making sync
	// changes
	UIDValidityChange []*Mailbox
}

func CompareMailboxes

func CompareMailboxes(oldSt map[string]*Mailbox, newSt map[string]*Mailbox) *MailboxDiff

CompareMailboxes compares states of two maps of mailboxes and returns the diff. The maps are strings of the LocalName to the mailbox object

func NewMailboxDiff

func NewMailboxDiff() *MailboxDiff

type State

type State struct {
	// Mailboxes is a map of local mailbox ID to remote mailbox ID
	Mailboxes []*Mailbox `json:"mailboxes"`
	// contains filtered or unexported fields
}

State is the application state. It manages the synchronization state

func NewState

func NewState(cfg *Config) (*State, error)

NewState creates a new application state and validates the config

func (*State) AddFlag

func (s *State) AddFlag(dir string, f maildir.Flag, ref *Email)

Adds a flag to the email in the given dir

func (*State) CreateEmail

func (s *State) CreateEmail(dir string, eml *Email)

CreateEmail creates an email in state for the LocalName passed in

func (*State) CreateMailbox

func (s *State) CreateMailbox(mbox *Mailbox)

func (*State) DeleteEmail

func (s *State) DeleteEmail(dir string, ref *Email)

func (*State) DeleteMailbox

func (s *State) DeleteMailbox(mbox *Mailbox)

func (*State) Load

func (s *State) Load() error

func (*State) MailboxByLocalName

func (s *State) MailboxByLocalName(name string) (*Mailbox, bool)

func (*State) RemoveFlag

func (s *State) RemoveFlag(dir string, flag maildir.Flag, ref *Email)

func (*State) RenameMailbox

func (s *State) RenameMailbox(orig string, dest *Mailbox)

func (*State) Save

func (s *State) Save() error

func (*State) UpdateMailboxState

func (s *State) UpdateMailboxState(name string, modseq uint64, uidnext uint32)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL