summaryrefslogtreecommitdiffstats
path: root/kittystore/sa/kittysamodel.py
blob: 20dd4c561a4be73c324e363b5946a7c27d0a4316 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# -*- coding: utf-8 -*-

"""
KittySAModel - an object mapper to a SQL database representation of
                emails for mailman 3.

Copyright (C) 2012 Pierre-Yves Chibon
Author: Pierre-Yves Chibon <pingou@pingoured.fr>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
See http://www.gnu.org/copyleft/gpl.html  for the full text of the
license.
"""

from sqlalchemy import (
    Table,
    Column,
    Integer,
    DateTime,
    LargeBinary,
    String,
    Text,
)
from sqlalchemy.orm import mapper


def get_table(table, metadata, create=False):
    """ For a given string, create the table with the corresponding name,
    and following the defined structure and returns the Table object of
    the said table.

    :arg table, the name of the table in the database.
    :arg metadata, MetaData object containing the information relative
    to the connection to the database.
    :kwarg create, a boolean stipulating whether the table should be
    created if it does not already exist in the database.
    """
    # TODO:
    # - add an insertion timestamp to be able to calculate the "legacy id
    #   number" which was used to identify the email in pipermail, and
    #   eventually setup a proper redirection.
    # - use the msg_hash_id and the list_id as a primary key
    # - add a content-type (html or text) (and an encoding field maybe? or store everything as UTF-8?)
    table = Table( table, metadata,
        Column('id', Integer, primary_key=True),
        Column('sender', String(100), nullable=False),
        Column('email', String(75), nullable=False),
        Column('subject', Text, nullable=False, index=True),
        Column('content', Text, nullable=False),
        Column('date', DateTime, index=True),
        Column('message_id', String(150), index=True, unique=True,
            nullable=False),
        Column('stable_url_id', String(250), index=True, unique=True,
            nullable=False),
        Column('thread_id', String(150), nullable=False, index=True),
        Column('references', Text),
        Column('full', LargeBinary),
        useexisting=True)
    if create:
        metadata.create_all()
    return table


def get_class_object(table, entity_name, metadata, create=False, **kw):
    """ For a given table name, returns the object mapping the said
    table.

    :arg table, the name of the table in the database.
    :arg metadata, MetaData object containing the information relative
    to the connection to the database.
    :kwarg create, a boolean stipulating whether the table should be
    created if it does not already exist in the database.
    """
    newcls = type(entity_name, (Email, ), {})
    mapper(newcls, get_table(table, metadata, create), **kw)
    return newcls


class Email(object):
    """ Email table.

    Define the fields of the table and their types.
    """

    def __init__(self, sender, email, subject, content, date, message_id,
        stable_url_id, thread_id, references, full):
        """ Constructor instanciating the defaults values. """
        self.sender = sender
        self.email = email
        self.subject = subject
        self.content = content
        self.date = date
        self.message_id = message_id
        self.stable_url_id = stable_url_id
        self.thread_id = thread_id
        self.references = references
        self.full = full

    def __repr__(self):
        """ Representation of the Email object when printed. """
        return "<Email('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')>" \
                % (self.sender, self.email, self.date, self.subject,
                   self.message_id, self.stable_url_id, self.thread_id,
                   self.references)

    def save(self, session):
        """ Save the object into the database. """
        session.add(self)