server/hookhelper.py
changeset 0 b97547f5f1fa
child 1132 96752791c2b6
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """helper functions for application hooks
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 """
       
     7 __docformat__ = "restructuredtext en"
       
     8 
       
     9 from smtplib import SMTP
       
    10 from threading import Lock
       
    11 
       
    12 from cubicweb import RepositoryError
       
    13 from cubicweb.server.pool import Operation, SingleLastOperation
       
    14 
       
    15 
       
    16 def entity_name(session, eid):
       
    17     """return the "name" attribute of the entity with the given eid"""
       
    18     return entity_attr(session, eid, 'name')
       
    19 
       
    20 def entity_attr(session, eid, attr):
       
    21     """return an arbitrary attribute of the entity with the given eid"""
       
    22     rset = session.execute('Any N WHERE X eid %%(x)s, X %s N' % attr,
       
    23                            {'x': eid}, 'x')
       
    24     return rset[0][0]
       
    25 
       
    26 def rproperty(session, rtype, eidfrom, eidto, rprop):
       
    27     rschema = session.repo.schema[rtype]
       
    28     subjtype = session.describe(eidfrom)[0]
       
    29     objtype = session.describe(eidto)[0]
       
    30     return rschema.rproperty(subjtype, objtype, rprop)
       
    31 
       
    32 def check_internal_entity(session, eid, internal_names):
       
    33     """check that the entity's name is not in the internal_names list.
       
    34     raise a RepositoryError if so, else return the entity's name
       
    35     """
       
    36     name = entity_name(session, eid)
       
    37     if name in internal_names:
       
    38         raise RepositoryError('%s entity can\'t be deleted' % name)
       
    39     return name
       
    40 
       
    41 def get_user_sessions(repo, ueid):
       
    42     for session in repo._sessions.values():
       
    43         if ueid == session.user.eid:
       
    44             yield session
       
    45         
       
    46 
       
    47 # mail related ################################################################
       
    48 
       
    49 SMTP_LOCK = Lock()
       
    50 
       
    51 class SendMailOp(SingleLastOperation):
       
    52     def __init__(self, session, msg=None, recipients=None, **kwargs):
       
    53         # may not specify msg yet, as
       
    54         # `cubicweb.sobjects.supervision.SupervisionMailOp`
       
    55         if msg is not None:
       
    56             assert recipients
       
    57             self.to_send = [(msg, recipients)]
       
    58         else:
       
    59             assert recipients is None
       
    60             self.to_send = []
       
    61         super(SendMailOp, self).__init__(session, **kwargs) 
       
    62        
       
    63     def register(self, session):
       
    64         previous = super(SendMailOp, self).register(session)
       
    65         if previous:
       
    66             self.to_send = previous.to_send + self.to_send
       
    67         
       
    68     def commit_event(self):
       
    69         self.repo.threaded_task(self.sendmails)
       
    70 
       
    71     def sendmails(self):        
       
    72         server, port = self.config['smtp-host'], self.config['smtp-port']
       
    73         SMTP_LOCK.acquire()
       
    74         try:
       
    75             try:
       
    76                 smtp = SMTP(server, port)
       
    77             except Exception, ex:
       
    78                 self.exception("can't connect to smtp server %s:%s (%s)",
       
    79                                server, port, ex)
       
    80                 return
       
    81             heloaddr = '%s <%s>' % (self.config['sender-name'],
       
    82                                     self.config['sender-addr'])
       
    83             for msg, recipients in self.to_send:
       
    84                 try:
       
    85                     smtp.sendmail(heloaddr, recipients, msg.as_string())
       
    86                 except Exception, ex:
       
    87                     self.exception("error sending mail to %s (%s)",
       
    88                                    recipients, ex)
       
    89             smtp.close()
       
    90         finally:
       
    91             SMTP_LOCK.release()
       
    92             
       
    93 
       
    94 # state related ###############################################################
       
    95 
       
    96 def previous_state(session, eid):
       
    97     """return the state of the entity with the given eid,
       
    98     usually since it's changing in the current transaction. Due to internal
       
    99     relation hooks, the relation may has been deleted at this point, so
       
   100     we have handle that
       
   101     """
       
   102     for eidfrom, rtype, eidto in reversed(session.query_data('pendingrelations', ())):
       
   103         if rtype == 'in_state' and eidfrom == eid:
       
   104             rset = session.execute('Any S,N WHERE S eid %(x)s, S name N',
       
   105                                    {'x': eidto}, 'x')
       
   106             return rset.get_entity(0, 0)
       
   107     rset = session.execute('Any S,N WHERE X eid %(x)s, X in_state S, S name N',
       
   108                            {'x': eid}, 'x')
       
   109     if rset:
       
   110         return rset.get_entity(0, 0)