Changeset in

Show
Ignore:
Timestamp:
05/02/09 13:38:19 (3 years ago)
Author:
Gartersnake Server <gartersnake@…>
Children:
4bceacf6b979775083c8623c2906a66e95eefe48
Parents:
935fbfb3a362aa24429eff491679842cfb8feb81
git-committer:
Gartersnake Server <gartersnake@gartersnake.precisionconversions.com> / 2009-05-02T13:38:19Z-0700
Message:

Restructured file layout, converted to 'resourcetotrac'

Location:
resourcetotrac
Files:
3 added
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • resourcetotrac/resourcetotrac/api.py

    r935fbfb ref235ae  
    1717# Local imports 
    1818 
    19 __all__ = ['IEmailStore'] 
    20  
    21 class StoreConnectError(StandardError): pass 
     19__all__ = [ 
     20    'IDataSource', 
     21    'IResourceSubmitter', 
     22    'IResourceParser', 
     23    'ITypeParser', 
     24    'BaseParsedMessage', 
     25] 
    2226 
    2327 
     
    6266        """ Submits the resource to Trac """  
    6367 
     68class IResourceParser(Interface): 
     69    """ Parse a message 
     70 
     71    This interface should be subclassed to the specific data source. 
     72    """ 
     73 
     74    def match_resource_type(self, resource_type): 
     75        """ Return whether or not to parse the given resource type """ 
     76 
     77    def parse_message(self, resource_type, message): 
     78        """ Parses the message and returns a child instance of 
     79        BaseParsedMesssage 
     80        """ 
     81 
     82class ITypeParser(Interface): 
     83    """ Extracts the resource type from the message 
     84     
     85    This interface should be subclassed to the specific data source. 
     86    """ 
     87 
     88    def get_resource_type(self, msg): 
     89        """ Returns the resource type or None if it can't identify it """ 
     90     
     91 
     92 
    6493class BaseParsedMessage(object): 
    6594    """ Base class for parsed messages. 
  • resourcetotrac/resourcetotrac/email/imap.py

    r935fbfb ref235ae  
    2020 
    2121# Local imports 
    22 from emailtoticket.api import IEmailStore, StoreConnectError 
     22from resourcetotrac.api import IDataSource 
     23from resourcetotrac.email.api import StoreConnectError, IEmailResourceParser 
     24from resourcetotrac.email.api import IEmailTypeParser 
    2325 
    24 __all__ = ['IMAPStore'] 
     26__all__ = ['IMAPSource'] 
    2527 
    2628RESPONSE = 0 
     
    3032OK = 'OK' 
    3133 
    32 class IMAPStore(Component): 
     34class IMAPSource(Component): 
    3335 
    34     implements(IEmailStore) 
     36    implements(IDataSource) 
    3537 
    36     host = Option('email2ticket', 'imap.host', default='localhost', 
     38    resource_parsers = ExtensionPoint(IEmailResourceParser) 
     39    type_parsers = ExtensionPoint(IEmailTypeParser) 
     40 
     41    host = Option('resource2trac', 'imap.host', default='localhost', 
    3742                   doc="Hostname or IP of IMAP server. [default:localhost]") 
    38     port = IntOption('email2ticket', 'imap.port', default='143', 
     43    port = IntOption('resource2trac', 'imap.port', default='143', 
    3944                   doc="Port to use when connecting to IMAP server. " 
    4045                       "[default:143 or 993 if imap.ssl = True]") 
    41     ssl = BoolOption('email2ticket', 'imap.ssl', default=False, 
     46    ssl = BoolOption('resource2trac', 'imap.ssl', default=False, 
    4247                      doc="Use SSL") 
    43     user = Option('email2ticket', 'imap.user', 
     48    user = Option('resource2trac', 'imap.user', 
    4449                   doc="Username to use when logging into IMAP") 
    45     passwd = Option('email2ticket', 'imap.passwd', 
     50    passwd = Option('resource2trac', 'imap.passwd', 
    4651                    doc="IMAP password") 
    47     def __repr__(self): 
    48         return 'IMAPStore' 
    4952 
    50     def __str__(self): 
    51         return 'IMAPStore' 
     53    # IDataSource Methods 
     54    def get_message(self): 
     55        """ Generator that returns a tuple of (id, email) 
    5256 
     57        The id parameter is an identifier that can be used to locate the email 
     58        in the email store. 
     59 
     60        The email parameter must be an email.message.Message object 
     61        """ 
     62        if not self.connected: 
     63            self.log.debug('Connection timeout.  Retrying connection...') 
     64            self._connect() 
     65 
     66        response = self.cnx.select() 
     67        if response[RESPONSE] != OK: 
     68            self.log.debug('Unable to select messages from server') 
     69        for x in int(response[DATA]): 
     70            msg = self._parse_message( msg = email.message_from_string(self.cnx.fetch(x, r'(UID RFC822)')[DATA][CONTAINER][MSG]) 
     71            yield (x, parsed_msg) 
     72         
     73 
     74    def archive_message(self, id, info={}): 
     75        """ Archive the email with the specified id 
     76 
     77        The id is the id retrieved from the call to get_email(). 
     78        """ 
     79         
     80        archive = 'INBOX._archive.%d' % ticket 
     81        response = self.cnx.list(archive) 
     82        if response[RESPONSE] == OK and response[DATA][0] == 'None': 
     83            response = self.cnx.create(archive) 
     84        if response[RESPONSE] == OK: 
     85            response = self.cnx.select() 
     86            if response[RESPONSE] == OK: 
     87                self.cnx.copy(id, archive) 
     88        pass 
     89         
     90 
     91    def delete_message(self, id): 
     92        """ Delete the email from the email store """ 
     93        self.cnx.store(id, '+flags', r'(\Deleted)') 
     94 
     95 
     96    def cleanup(self): 
     97        self.cnx.expunge() 
     98 
     99    # Private Methods 
    53100    def _connect(self): 
    54101        """ Logs into the IMAP server. """ 
     
    85132    connected = property(_test_imap_cnx) 
    86133 
     134    def _parse_email(self, msg); 
     135        """ Parses the message returning an instance of the appropriate  
     136        BaseParsedMessage subclass 
     137        """ 
     138        for p in self.type_parsers: 
     139            resource_type = p.get_resource_type(msg) 
     140            if resource_type: 
     141                break 
     142            continue 
     143        for p in self.resource_parsers: 
     144            if p.match_resource_type(resource_type): 
     145                return p.parse_message(resource_type, msg) 
     146            continue 
     147        return None 
    87148 
    88     def get_email(self): 
    89         """ Generator that returns a tuple of (id, email) 
     149    def __repr__(self): 
     150        return 'IMAPSource' 
    90151 
    91         The id parameter is an identifier that can be used to locate the email 
    92         in the email store. 
     152    def __str__(self): 
     153        return 'IMAPSource' 
    93154 
    94         The email parameter must be an email.message.Message object 
    95         """ 
    96         if not self.connected: 
    97             self.log.debug('Connection timeout.  Retrying connection...') 
    98             self._connect() 
    99  
    100         response = self.cnx.select() 
    101         if response[RESPONSE] != OK: 
    102             self.log.debug('Unable to select messages from server') 
    103         for x in int(response[DATA]): 
    104             yield (x, email.message_from_string(self.cnx.fetch(x, r'(UID RFC822)')[DATA][CONTAINER][MSG])) 
    105          
    106  
    107     def archive_email(self, id, info={}): 
    108         """ Archive the email with the specified id 
    109  
    110         The id is the id retrieved from the call to get_email(). 
    111         """ 
    112         ticket = info.get('ticket', 0) 
    113         archive = 'INBOX._archive.%d' % ticket 
    114         response = self.cnx.list(archive) 
    115         if response[RESPONSE] == OK and response[DATA][0] == 'None': 
    116             response = self.cnx.create(archive) 
    117  
    118         if response[RESPONSE] == OK: 
    119             self.cnx.copy(id, archive) 
    120         pass 
    121          
    122  
    123     def delete_email(self, id): 
    124         """ Delete the email from the email store """ 
    125         self.cnx.store(id, '+flags', r'(\Deleted)') 
    126  
    127  
    128     def cleanup(self): 
    129         self.cnx.expunge() 
  • resourcetotrac/resourcetotrac/script.py

    r935fbfb ref235ae  
    1919import daemonize 
    2020from trac.env import Environment 
    21 from trac.core import Component 
     21from trac.core import Component, ExtensionPoint 
    2222from trac.config import OrderedExtensionsOption 
    2323 
    2424# Local imports 
    25 from emailtoticket.api import IEmailStore 
    26 from emailtoticket.util import EmailParser 
     25from resourcetotrac.api import IDataSource, IResourceSubmitter 
    2726 
    2827 
     
    3029 
    3130 
    32 __all__ = ['EmailToTicketConfig'] 
     31__all__ = ['ResourceSubmission'] 
    3332 
    3433 
    35 class EmailTicketSubmission(Component): 
     34class ResourceSubmission(Component): 
    3635 
    3736    implemnts(IResourceSubmitter) 
    3837 
    39     email_stores = OrderedExtensionsOption('email2ticket', 'stores',  
    40                                            IEmailStore, include_missing=False, 
    41                                            doc="List of enabled email stores") 
     38    data_sources = OrderedExtensionsOption('resource2trac', 'sources',  
     39                                           IDataSource, include_missing=False, 
     40                                           doc="List of enabled data sources") 
    4241 
    43     archive = BoolOption('email2ticket', 'archive', True, 
    44                          doc="Whether or not to archive the processed emails") 
     42    resource_submitters = ExtensionPoint(IResourceSubmitter) 
    4543 
    46     def submit_ticket(self, email): 
    47         """ Rape the email and submit/update a ticket """ 
    48  
    49         parser = EmailParser(self.env) 
    50         subject = parser.get_subject(email)email['Subject'].strip() 
    51         author_email = parseaddr(email['From'])[1] 
    52         update = subject[:3].lower() == 're:' 
    53         if update: 
    54             subject = subject[3:].strip() 
    55          
     44    archive = BoolOption('resource2trac', 'archive', True, 
     45                         doc="Whether or not to archive the processed messages") 
    5646 
    5747 
    58     def process_tickets(self): 
    59         self.parser 
    60         for store in self.email_stores: 
    61             for id, email in store.get_email(): 
     48    def process_resources(self): 
     49        for src in self.data_sources: 
     50            for id, msg in src.get_message(): 
    6251                try: 
    63                     info = self.submit_ticket(email) 
     52                    resource_type = msg.get_type() 
     53                    for submitter in self.resource_submitters(): 
     54                        if submitter.match_resource_type(resource_type): 
     55                            break 
     56                        continue 
     57                    submitter.submit_resource(resource_type, msg) 
    6458                    if self.archive: 
    65                         store.archive_email(id) 
    66                     store.delete_email(id) 
     59                        src.archive_message(id) 
     60                    src.delete_message(id) 
    6761                except: 
    68                     self.log.debug('Unable to submit the ticket') 
    69             store.cleanup() 
     62                    self.log.debug('Unable to submit the resource') 
     63            src.cleanup() 
    7064            continue 
    71              
    72  
    7365 
    7466 
     
    10395def main(argv): 
    10496    opts = doArgs(argv) 
    105     emailticket = EmailTicketSubmission(opts.env)  
     97    emailticket = ResourceSubmission(opts.env)  
    10698    emailticket.process_tickets() 
    10799    return 0 
  • resourcetotrac/setup.py

    r935fbfb ref235ae  
    2727        resourcetotrac.api = resourcetotrac.api 
    2828        resourcetotrac.config = resourcetotrac.config 
    29         resourcetotrac.imap = resourcetotrac.imap 
     29        resourcetotrac.email.imap = resourcetotrac.email.imap 
    3030    """ 
    3131# Currently no package data in use 
Note: See TracChangeset for help on using the changeset viewer.