Package gluon :: Module dal :: Class IMAPAdapter
[hide private]
[frames] | no frames]

Class IMAPAdapter

source code

    object --+            
ConnectionPool --+        
       BaseAdapter --+    
          NoSQLAdapter --+

Nested Classes [hide private]

Inherited from BaseAdapter: __metaclass__

Instance Methods [hide private]
__init__(self, db, uri, pool_size=0, folder=None, db_codec='UTF-8', credential_decoder=<function IDENTITY at 0x334cd70>, driver_args={}, adapter_args={}, do_connect=True, after_connection=None)
x.__init__(...) initializes x; see help(type(x)) for signature
source code
reconnect(self, f=None, cursor=True)
IMAP4 Pool connection method
source code
get_last_message(self, tablename) source code
get_uid_bounds(self, tablename) source code
convert_date(self, date, add=None, imf=False) source code
encode_text(self, text, charset, errors='replace')
convert text for mail to unicode
source code
get_charset(self, message) source code
Query the mail database for mailbox names
source code
get_query_mailbox(self, query) source code
is_flag(self, flag) source code
define_tables(self, mailbox_names=None)
Auto create common IMAP fileds
source code
create_table(self, *args, **kwargs) source code
select(self, query, fields, attributes)
Search and Fetch records and return web2py rows
source code
insert(self, table, fields) source code
update(self, tablename, query, fields) source code
count(self, query, distinct=None) source code
delete(self, tablename, query) source code
BELONGS(self, first, second) source code
CONTAINS(self, first, second, case_sensitive=False) source code
GT(self, first, second) source code
GE(self, first, second) source code
LT(self, first, second) source code
LE(self, first, second) source code
NE(self, first, second=None) source code
EQ(self, first, second) source code
AND(self, first, second) source code
OR(self, first, second) source code
NOT(self, first) source code

Inherited from NoSQLAdapter: ADD, AGGREGATE, AS, DIV, ENDSWITH, EXTRACT, ILIKE, LEFT_JOIN, LENGTH, LOWER, MUL, ON, PRIMARY_KEY, RANDOM, STARTSWITH, SUB, SUBSTRING, UPPER, alias, close_connection, commit, commit_prepared, concat_add, constraint_name, create_sequence_and_triggers, distributed_transaction_begin, drop, execute, id_query, lastrowid, log_execute, migrate_table, prepare, represent, represent_exceptions, rollback, rollback_prepared, rowslice

Inherited from NoSQLAdapter (private): _count, _delete, _insert, _select, _update

Inherited from BaseAdapter: ALLOW_NULL, CASE, CAST, COALESCE, COALESCE_ZERO, COMMA, CONCAT, COUNT, EPOCH, INVERT, JOIN, LIKE, MOD, NOT_NULL, RAW, REGEXP, REPLACE, adapt, build_parsemap, bulk_insert, common_filter, connector, expand, expand_all, file_close, file_delete, file_exists, file_open, find_driver, get_table, isOperationalError, isProgrammingError, is_numerical_type, log, parse, parse_blob, parse_boolean, parse_date, parse_datetime, parse_decimal, parse_double, parse_id, parse_integer, parse_json, parse_list_integers, parse_list_references, parse_list_strings, parse_reference, parse_time, parse_value, save_dbt, select_limitby, sequence_name, smart_adapt, sqlsafe_field, sqlsafe_table, table_alias, tables, trigger_name, truncate, varquote

Inherited from ConnectionPool: after_connection, after_connection_hook, close, find_or_make_work_folder

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Static Methods [hide private]
header_represent(f, r) source code

Inherited from NoSQLAdapter: to_unicode

Inherited from ConnectionPool: close_all_instances, set_folder

Class Variables [hide private]
  drivers = ('imaplib')
IMAP server adapter
  types = {'bigint': <type 'long'>, 'blob': <type 'str'>, 'boole...
  dbengine = 'imap'
  REGEX_URI = re.compile(r'^(?P<user>[^:]+)(:(?P<password>[^@]*)...

Inherited from NoSQLAdapter: QUOTE_TEMPLATE, can_select_for_update

Inherited from BaseAdapter: FALSE, TRUE, T_SEP, commit_on_alter_table, connection, dbpath, driver, driver_name, folder, native_json, support_distributed_transaction, uploads_in_blob

Inherited from ConnectionPool: POOLS, check_active_connection

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, db, uri, pool_size=0, folder=None, db_codec='UTF-8', credential_decoder=<function IDENTITY at 0x334cd70>, driver_args={}, adapter_args={}, do_connect=True, after_connection=None)

source code 

x.__init__(...) initializes x; see help(type(x)) for signature

Overrides: object.__init__
(inherited documentation)

reconnect(self, f=None, cursor=True)

source code 

IMAP4 Pool connection method

imap connection lacks of self cursor command. A custom command should be provided as a replacement for connection pooling to prevent uncaught remote session closing

Overrides: ConnectionPool.reconnect

define_tables(self, mailbox_names=None)

source code 

Auto create common IMAP fileds

This function creates fields definitions "statically" meaning that custom fields as in other adapters should not be supported and definitions handled on a service/mode basis (local syntax for Gmail(r), Ymail(r)

Returns a dictionary with tablename, server native mailbox name pairs.

create_table(self, *args, **kwargs)

source code 
Overrides: BaseAdapter.create_table

select(self, query, fields, attributes)

source code 

Search and Fetch records and return web2py rows


insert(self, table, fields)

source code 
Overrides: BaseAdapter.insert

update(self, tablename, query, fields)

source code 
Overrides: BaseAdapter.update

count(self, query, distinct=None)

source code 
Overrides: BaseAdapter.count

delete(self, tablename, query)

source code 
Overrides: BaseAdapter.delete

BELONGS(self, first, second)

source code 
Overrides: BaseAdapter.BELONGS

CONTAINS(self, first, second, case_sensitive=False)

source code 
Overrides: BaseAdapter.CONTAINS

GT(self, first, second)

source code 
Overrides: BaseAdapter.GT

GE(self, first, second)

source code 
Overrides: BaseAdapter.GE

LT(self, first, second)

source code 
Overrides: BaseAdapter.LT

LE(self, first, second)

source code 
Overrides: BaseAdapter.LE

NE(self, first, second=None)

source code 
Overrides: BaseAdapter.NE

EQ(self, first, second)

source code 
Overrides: BaseAdapter.EQ

AND(self, first, second)

source code 
Overrides: BaseAdapter.AND

OR(self, first, second)

source code 
Overrides: BaseAdapter.OR

NOT(self, first)

source code 
Overrides: BaseAdapter.NOT

Class Variable Details [hide private]


IMAP server adapter

  This class is intended as an interface with
email IMAP servers to perform simple queries in the
web2py DAL query syntax, so email read, search and
other related IMAP mail services (as those implemented
by brands like Google(r), and Yahoo!(r)
can be managed from web2py applications.

The code uses examples by Yuji Tomita on this post:
and is based in docs for Python imaplib, python email
and email IETF's (i.e. RFC2060 and RFC3501)

This adapter was tested with a small set of operations with Gmail(r). Other
services requests could raise command syntax and response data issues.

It creates its table and field names "statically",
meaning that the developer should leave the table and field
definitions to the DAL instance by calling the adapter's
.define_tables() method. The tables are defined with the
IMAP server mailbox list information.

.define_tables() returns a dictionary mapping dal tablenames
to the server mailbox names with the following structure:

{<tablename>: str <server mailbox name>}

Here is a list of supported fields:

Field       Type            Description
uid         string
answered    boolean        Flag
created     date
content     list:string    A list of dict text or html parts
to          string
cc          string
bcc         string
size        integer        the amount of octets of the message*
deleted     boolean        Flag
draft       boolean        Flag
flagged     boolean        Flag
sender      string
recent      boolean        Flag
seen        boolean        Flag
subject     string
mime        string         The mime header declaration
email       string         The complete RFC822 message**
attachments <type list>    Each non text part as dict
encoding    string         The main detected encoding

*At the application side it is measured as the length of the RFC822
message string

WARNING: As row id's are mapped to email sequence numbers,
make sure your imap client web2py app does not delete messages
during select or update actions, to prevent
updating or deleting different messages.
Sequence numbers change whenever the mailbox is updated.
To avoid this sequence numbers issues, it is recommended the use
of uid fields in query references (although the update and delete
in separate actions rule still applies).

# This is the code recommended to start imap support
# at the app's model:

imapdb = DAL("imap://user:password@server:port", pool_size=1) # port 993 for ssl

Here is an (incomplete) list of possible imap commands:

# Count today's unseen messages
# smaller than 6000 octets from the
# inbox mailbox

q = imapdb.INBOX.seen == False
q &= imapdb.INBOX.created ==
q &= imapdb.INBOX.size < 6000
unread = imapdb(q).count()

# Fetch last query messages
rows = imapdb(q).select()

# it is also possible to filter query select results with limitby and
# sequences of mailbox fields<fields sequence>, limitby=(<int>, <int>))

# Mark last query messages as seen
messages = [row.uid for row in rows]
seen = imapdb(imapdb.INBOX.uid.belongs(messages)).update(seen=True)

# Delete messages in the imap database that have mails from mr. Gumby

deleted = 0
for mailbox in imapdb.tables
    deleted += imapdb(imapdb[mailbox].sender.contains("gumby")).delete()

# It is possible also to mark messages for deletion instead of ereasing them
# directly with set.update(deleted=True)

# This object give access
# to the adapter auto mailbox
# mapped names (which native
# mailbox has what table name)

imapdb.mailboxes <dict> # tablename, server native name pairs

# To retrieve a table native mailbox name use:

### New features v2.4.1:

# Declare mailboxes statically with tablename, name pairs
# This avoids the extra server names retrieval

imapdb.define_tables({"inbox": "INBOX"})

# Selects without content/attachments/email columns will only
# fetch header and flags

imapdb(q).select(imapdb.INBOX.sender, imapdb.INBOX.subject)



{'bigint': <type 'long'>,
 'blob': <type 'str'>,
 'boolean': <type 'bool'>,
 'date': <type ''>,
 'datetime': <type 'datetime.datetime'>,
 'id': <type 'long'>,
 'integer': <type 'int'>,
 'list:string': <type 'str'>,