camelot.camelot.types

Package camelot :: Package camelot :: Package types |
[hide private]
[frames] | no frames]

# Source Code for Package camelot.camelot.types

      1  import os
      2

      3  import logging
      4  logger = logging.getLogger('camelot.types')
      5  logger.setLevel(logging.DEBUG)
      6

      7  from sqlalchemy import types
      8

      9

     10 -class VirtualAddress(types.TypeDecorator):
     11    """Sqlalchemy type to store virtual addresses : eg, phone number, e-mail

     12    address, ...

     13

     14    This column type accepts and returns tuples of strings, the first string is

     15    the virtual_address_type, and the second the address itself:

     16

     17    eg: ('mail','project-camelot@conceptive.be') is stored as

     18    mail://project-camelot@conceptive.be

     19    """
     20

     21    impl = types.Unicode
     22    virtual_address_types = ['phone', 'fax', 'mobile', 'email', 'im', 'pager',]
     23

     24 -  def bind_processor(self, dialect):
     25

     26      impl_processor = self.impl.bind_processor(dialect)
     27      if not impl_processor:
     28        impl_processor = lambda x:x
     29

     30      def processor(value):
     31        if value is not None:
     32          value = '://'.join(value)
     33        return impl_processor(value)
     34

     35      return processor
     36

     37 -  def result_processor(self, dialect):
     38

     39      impl_processor = self.impl.result_processor(dialect)
     40      if not impl_processor:
     41        impl_processor = lambda x:x
     42

     43      def processor(value):
     44

     45        if value:
     46          return value.split('://')
     47        return ('phone','')
     48

     49      return processor
     50

     51

     52 -class Code(types.TypeDecorator):
     53    """Sqlalchemy column type to store codes

     54

     55    This column type accepts and returns a list of strings and stores them as a

     56    string joined with points.

     57

     58    eg: ['08', 'AB'] is stored as 08.AB

     59

     60    @param parts: a list of input masks specifying the mask for each part, eg ['99', 'AA'], for

     61    valid input masks, see the docs of qlineedit

     62    """
     63

     64    impl = types.Unicode
     65

     66 -  def __init__(self, parts, **kwargs):
     67      import string
     68      translator = string.maketrans('', '')
     69      self.parts = parts
     70      max_length = sum(len(part.translate(translator, '<>!')) for part in parts) + len(parts)
     71      types.TypeDecorator.__init__(self, length=max_length, **kwargs)
     72

     73 -  def bind_processor(self, dialect):
     74

     75      impl_processor = self.impl.bind_processor(dialect)
     76      if not impl_processor:
     77        impl_processor = lambda x:x
     78

     79      def processor(value):
     80        if value is not None:
     81          value = '.'.join(value)
     82        return impl_processor(value)
     83

     84      return processor
     85

     86 -  def result_processor(self, dialect):
     87

     88      impl_processor = self.impl.result_processor(dialect)
     89      if not impl_processor:
     90        impl_processor = lambda x:x
     91

     92      def processor(value):
     93

     94        if value:
     95          return value.split('.')
     96        return ['' for p in self.parts]
     97

     98      return processor
     99

    100

    101 -class IPAddress(Code):
    102 -  def __init__(self, **kwargs):
    103      super(IPAddress, self).__init__(parts=['900','900','900','900'])
    104

    105 -class RichText(types.TypeDecorator):
    106    """Sqlalchemy column type to store rich text

    107

    108    by default, fields of this type will be displayed within a rich

    109    text editor"""
    110

    111    impl = types.UnicodeText
    112

    113  # Try to import PIL in various ways

    114  try:
    115    from PIL import Image as PILImage
    116  except:
    117    import Image as PILImage
    118

    119

    120 -class StoredImage(object):
    121    """Class linking a PIL image and the location and filename where the image is stored"""
    122

    123 -  def __init__(self, image, location=None, filename=None):
    124      self.image = image
    125      self.location = location
    126      self.filename = filename
    127

    128    @property
    129 -  def full_path(self):
    130      import os
    131      return os.path.join(self.location, self.filename)
    132

    133

    134 -class Image(types.TypeDecorator):
    135    """Sqlalchemy column type to store images

    136

    137    This column type accepts and returns a StoredImage, and stores them in the directory

    138    specified by settings.MEDIA_ROOT.  The name of the file is stored as a string in

    139    the database.

    140    """
    141

    142    impl = types.Unicode
    143

    144 -  def __init__(self, max_length=100, upload_to='', prefix='image-', format='png', **kwargs):
    145      import settings
    146      self.upload_to = os.path.join(settings.CAMELOT_MEDIA_ROOT, upload_to)
    147      self.prefix = prefix
    148      self.format = format
    149      self.max_length = max_length
    150      if not os.path.exists(self.upload_to):
    151        os.makedirs(self.upload_to)
    152      types.TypeDecorator.__init__(self, length=max_length, **kwargs)
    153

    154 -  def bind_processor(self, dialect):
    155

    156      impl_processor = self.impl.bind_processor(dialect)
    157      if not impl_processor:
    158        impl_processor = lambda x:x
    159

    160      def processor(value):
    161        if value is not None:
    162          import tempfile
    163          (handle, name) = tempfile.mkstemp(suffix='.%s'%self.format, prefix=self.prefix, dir=os.path.join(self.upload_to))
    164          value.image.save(os.fdopen(handle, 'wb'), 'png')
    165          value = os.path.basename(name)
    166        return impl_processor(value)
    167

    168      return processor
    169

    170 -  def result_processor(self, dialect):
    171

    172      impl_processor = self.impl.result_processor(dialect)
    173      if not impl_processor:
    174        impl_processor = lambda x:x
    175

    176      def processor(value):
    177

    178        if value:
    179          value = os.path.join(self.upload_to, impl_processor(value))
    180          if os.path.exists(value):
    181            return StoredImage(PILImage.open( value ), self.upload_to, value)
    182          else:
    183            logger.warn('Image at %s does not exist'%value)
    184

    185      return processor
    186