Beispiel #1
0
class Actor(Entity):
    name = Field(Unicode(60))
    movies = ManyToMany('Movie', inverse='actors', tablename='movie_casting')
    using_options(tablename='actors')
Beispiel #2
0
class B(Entity):
    using_options(resolve_root='tests.db1')

    cs = ManyToMany('.c.C')
    a1s = ManyToMany('a.A1')
Beispiel #3
0
class DataBoard(Entity):
    """Board mapper

     - ``title`` -- board title
     - ``is_template`` -- is this a real board or a template?
     - ``columns`` -- list of board columns
     - ``labels`` -- list of labels for cards
     - ``comments_allowed`` -- who can comment ? (0 nobody, 1 board members only , 2 all application users)
     - ``votes_allowed`` -- who can vote ? (0 nobody, 1 board members only , 2 all application users)
     - ``description`` -- board description
     - ``visibility`` -- board visibility [0 Private, 1 Public (anyone with the URL can view),
                                           2 Shared (anyone can view it from her home page)]
     - ``uri`` -- board URI (Universally Unique IDentifier)
     - ``last_users`` -- list of last users
     - ``pending`` -- invitations pending for new members (use token)
     - ``archive`` -- display archive column ? (0 false, 1 true)
     - ``archived`` -- is board archived ?
    """
    using_options(tablename='board')
    title = Field(Unicode(255))
    is_template = Field(Boolean, default=False)
    columns = OneToMany('DataColumn',
                        order_by="index",
                        cascade='delete',
                        lazy='subquery')
    # provisional
    labels = OneToMany('DataLabel', order_by='index')
    comments_allowed = Field(Integer, default=1)
    votes_allowed = Field(Integer, default=1)
    description = Field(UnicodeText, default=u'')
    visibility = Field(Integer, default=0)
    version = Field(Integer, default=0, server_default='0')
    # provisional
    board_members = OneToMany('DataMembership',
                              lazy='subquery',
                              order_by=('manager'))
    uri = Field(Unicode(255), index=True, unique=True)
    last_users = ManyToOne('DataUser', order_by=('fullname', 'email'))
    pending = OneToMany('DataToken', order_by='username')
    history = OneToMany('DataHistory')

    background_image = Field(Unicode(255))
    background_position = Field(Unicode(255))
    title_color = Field(Unicode(255))
    show_archive = Field(Integer, default=0)
    archived = Field(Boolean, default=False)

    # provisional
    weight_config = OneToOne('DataBoardWeightConfig')

    def __init__(self, *args, **kwargs):
        """Initialization.

        Create board and uri of the board
        """
        super(DataBoard, self).__init__(*args, **kwargs)
        self.uri = unicode(uuid.uuid4())

    @property
    def template_title(self):
        manager = self.get_first_manager()
        if not manager or self.visibility == 0:
            return self.title
        return u'{0} ({1})'.format(self.title, manager.fullname)

    def get_first_manager(self):
        if not self.board_members:
            return None
        potential_manager = self.board_members[-1]
        return potential_manager.user if potential_manager.manager else None

    def copy(self):
        new_data = DataBoard(title=self.title,
                             description=self.description,
                             background_position=self.background_position,
                             title_color=self.title_color,
                             comments_allowed=self.comments_allowed,
                             votes_allowed=self.votes_allowed)
        # TODO: move to board extension
        new_data.weight_config = DataBoardWeightConfig(
            weighting_cards=self.weighting_cards, weights=self.weights)
        session.add(new_data)
        session.flush()
        # TODO: move to board extension
        for label in self.labels:
            new_data.labels.append(label.copy())
        session.flush()
        return new_data

    def get_label_by_title(self, title):
        return (l for l in self.labels if l.title == title).next()

    def delete_history(self):
        for event in self.history:
            session.delete(event)
        session.flush()

    def increase_version(self):
        self.version += 1
        if self.version > 2147483600:
            self.version = 1

    @property
    def url(self):
        return "%s/%s" % (urllib.quote_plus(
            self.title.encode('ascii', 'ignore').replace('/', '_')), self.uri)

    @classmethod
    def get_by_id(cls, id):
        return cls.get(id)

    @classmethod
    def get_by_uri(cls, uri):
        return cls.get_by(uri=uri)

    def set_background_image(self, image):
        self.background_image = image or u''

    @classmethod
    def get_all_boards(cls, user):
        """Return all boards the user is member of."""
        query = session.query(cls).join(DataMembership)
        query = query.filter(cls.is_template == False,
                             DataMembership.user == user)
        return query.order_by(cls.title)

    @classmethod
    def get_shared_boards(cls):
        query = session.query(cls).filter(cls.visibility == BOARD_SHARED)
        return query.order_by(cls.title)

    @classmethod
    def get_templates_for(cls, user, public_value):
        q = cls.query
        q = q.filter(cls.archived == False)
        q = q.filter(cls.is_template == True)
        q = q.order_by(cls.title)

        q1 = q.filter(cls.visibility == public_value)

        q2 = q.join(DataMembership)
        q2 = q2.filter(DataMembership.user == user)
        q2 = q2.filter(cls.visibility != public_value)

        return q1, q2

    def create_column(self, index, title, nb_cards=None, archive=False):
        return DataColumn.create_column(self, index, title, nb_cards, archive)

    def delete_column(self, column):
        if column in self.columns:
            self.columns.remove(column)

    def create_label(self, title, color):
        label = DataLabel(title=title, color=color)
        self.labels.append(label)
        session.flush()
        return label

    ############# Membership management; those functions belong to a board extension

    def delete_members(self):
        DataMembership.delete_members(self)

    def has_member(self, user):
        """Return True if user is member of the board

        In:
         - ``user`` -- user to test (DataUser instance)
        Return:
         - True if user is member of the board
        """
        return DataMembership.has_member(self, user)

    def has_manager(self, user):
        """Return True if user is manager of the board

        In:
         - ``user`` -- user to test (DataUser instance)
        Return:
         - True if user is manager of the board
        """
        return DataMembership.has_member(self, user, manager=True)

    def remove_member(self, user):
        DataMembership.remove_member(board=self, user=user)

    def change_role(self, user, new_role):
        DataMembership.change_role(self, user, new_role == 'manager')

    def add_member(self, user, role='member'):
        """ Add new member to the board

        In:
         - ``new_member`` -- user to add (DataUser instance)
         - ``role`` -- role's member (manager or member)
        """
        DataMembership.add_member(self, user, role == 'manager')

    ############# Weight configuration, those functions belong to an extension

    @property
    def weights(self):
        return self.weight_config.weights

    @weights.setter
    def weights(self, value):
        self.weight_config.weights = value

    @property
    def weighting_cards(self):
        return self.weight_config.weighting_cards

    @weighting_cards.setter
    def weighting_cards(self, value):
        self.weight_config.weighting_cards = value

    def reset_card_weights(self):
        self.weight_config.reset_card_weights()

    def total_weight(self):
        return self.weight_config.total_weight()
Beispiel #4
0
class Industry(Entity):
    using_options(tablename='industry')

    id = Field(Integer, primary_key=True)
    name = Field(String(255), default='')
Beispiel #5
0
class User(Entity):
    """Reasonably basic User definition. Probably would want additional
    attributes.
    """
    using_options(tablename="user", auto_primarykey="user_id")

    user_name = Field(Unicode(16), required=True, unique=True)

    _password = Field(Unicode(40), colname="password", required=True)

    groups = ManyToMany(
        "Group",
        inverse="users",
        tablename="user_group",
        local_colname="group_id",
        remote_colname="user_id",
        )

    def _set_password(self, password):
        """encrypts password on the fly"""
        self._password = self.__encrypt_password(password)

    def _get_password(self):
        """returns password"""
        return self._password

    password = descriptor=property(_get_password, _set_password)

    def __encrypt_password(self, password):
        """Hash the given password with SHA1.
        
        Edit this method to implement your own algorithm.
        
        """
        hashed_password = password

        if isinstance(password, unicode):
            password_8bit = password.encode('UTF-8')

        else:
            password_8bit = password

        hashed_password = sha.new(password_8bit).hexdigest()

        # make sure the hased password is an UTF-8 object at the end of the
        # process because SQLAlchemy _wants_ a unicode object for Unicode columns
        if not isinstance(hashed_password, unicode):
            hashed_password = hashed_password.decode('UTF-8')

        return hashed_password

    def validate_password(self, password):
        """Check the password against existing credentials.
        this method _MUST_ return a boolean.

        @param password: the password that was provided by the user to
        try and authenticate. This is the clear text version that we will
        need to match against the (possibly) encrypted one in the database.
        @type password: unicode object
        """
        return self.password == self.__encrypt_password(password)
Beispiel #6
0
class Degree(Entity):
    using_options(tablename='degree')

    id = Field(Integer, primary_key=True)
    name = Field(String(255), default='')
Beispiel #7
0
class Univs(Entity):
    using_options(tablename='univs')
    id = Field(Integer, primary_key=True)
    name = Field(String(255), default='')
    provinces = ManyToOne('Provinces')
Beispiel #8
0
class Ticket(Entity):
    using_options(tablename=tname)
    using_table_options(mysql_engine='InnoDB', mysql_charset='utf8')

    # Athena username
    requestor = Field(Unicode(255), index=True)
    # Locker name
    locker = Field(Unicode(255), index=True)
    # Hostname involved
    hostname = Field(Unicode(255), index=True)
    # path
    path = Field(Unicode(255))
    # "open" or "moira" or "dns" or "resolved"
    state = Field(Unicode(32))
    rtid = Field(Integer)
    # Purpose
    purpose = Field(UnicodeText())

    events = OneToMany('Event', order_by='timestamp')

    @staticmethod
    def create(locker, hostname, path, requestor=None, purpose=""):
        if requestor is None:
            requestor = auth.current_user()
        t = Ticket(requestor=requestor,
                   hostname=hostname,
                   locker=locker,
                   path=path,
                   state="open",
                   purpose=purpose)
        session.flush()
        t.addEvent(type='request', state="open", target='us')
        return t

    def addEvent(self,
                 type,
                 state,
                 by=None,
                 target=None,
                 subject=None,
                 body=None):
        if by is None:
            by = auth.current_user()
        Event(ticket=self,
              type=type,
              target=target,
              subject=subject,
              body=body,
              by=by)
        if state != self.state:
            self.state = state
            pat = "%s's %s changed the ticket re: %s to %s"
        else:
            pat = "%s's %s left the ticket re: %s as %s"
        try:
            url = "%s%s" % (tg.request.host_url, tg.url('/queue'))
        except:
            # Default to something sane if we're not in the context of a request
            url = "https://pony.scripts.mit.edu:444/queue"

        log.zwrite(pat % (by, type, self.hostname, state),
                   instance=self.id,
                   zsig=url)

    @staticmethod
    def all():
        return Ticket.query.all()
Beispiel #9
0
class DataUser(Entity):
    """Label mapper
    """
    using_options(tablename='user')
    # VARCHAR(binary=True) here is a hack to make MySQL case sensitive
    # like the other DBMS.
    # No consequences on regular databases.
    username = Field(VARCHAR(255, binary=True),
                     unique=True,
                     primary_key=True,
                     nullable=False)
    source = Field(Unicode(255), nullable=False, primary_key=True)
    fullname = Field(Unicode(255), nullable=False)
    email = Field(Unicode(255), nullable=True)
    picture = Field(Unicode(255), nullable=True)
    language = Field(Unicode(255), default=u"en", nullable=True)
    email_to_confirm = Field(Unicode(255))
    _salt = Field(Unicode(255), colname='salt', nullable=False)
    _password = Field(Unicode(255), colname='password', nullable=True)
    registration_date = Field(DateTime, nullable=False)
    last_login = Field(DateTime, nullable=True)
    display_week_numbers = Field(Boolean, default=False)
    board_members = OneToMany('DataBoardMember')
    boards = AssociationProxy(
        'board_members',
        'board',
        creator=lambda board: DataBoardMember(board=board))
    board_managers = OneToMany('DataBoardManager')
    managed_boards = AssociationProxy(
        'board_managers',
        'board',
        creator=lambda board: DataBoardManager(board=board))
    last_board = OneToOne('DataBoard', inverse='last_users')
    cards = ManyToMany('DataCard', inverse='members', lazy='dynamic')
    my_cards = OneToMany('DataCard', inverse='author')
    history = OneToMany('DataHistory')
    votes = OneToMany('DataVote')

    def __init__(self,
                 username,
                 password,
                 fullname,
                 email,
                 source=u'application',
                 picture=None,
                 **kw):
        """Create a new user with an unconfirmed email"""
        super(DataUser,
              self).__init__(username=username,
                             fullname=fullname,
                             email=None,
                             email_to_confirm=email,
                             source=source,
                             picture=picture,
                             registration_date=datetime.datetime.utcnow(),
                             **kw)
        # Create password if source is local
        if source == "application":
            self.change_password(password)
        else:
            # External authentication
            self.change_password('passwd')
            self.email_to_confirm = None

    def update(self, fullname, email, picture=None):
        self.fullname = fullname
        if email:
            self.email = email
        self.picture = picture

    def check_password(self, clear_password):
        """Check the user password. Return True if the password is valid for this user"""
        encrypted_password = self._encrypt_password(self._salt, clear_password)
        return encrypted_password == self._password

    def change_password(self, clear_password):
        """Change the user password"""
        self._salt = self._create_random_salt()
        self._password = self._encrypt_password(self._salt, clear_password)

    def set_email_to_confirm(self, email_to_confirm):
        if email_to_confirm:
            self.email_to_confirm = email_to_confirm

    def is_validated(self):
        return self.email_to_confirm is None

    def confirm_email(self):
        """Called when a user confirms his email address"""
        # already confirmed
        if self.email_to_confirm is None:
            return

        self.email = self.email_to_confirm
        self.email_to_confirm = None

    def add_board(self, board, role="member"):
        """Add board to user's board lists

        In:
         - ``board`` -- DataBoard instance to add
         - ``role`` -- user is member or manager
        """
        boards = set(dbm.board for dbm in self.board_members)
        if board not in boards:
            self.board_members.append(DataBoardMember(board=board))
        if role == "manager" and board not in self.managed_boards:
            self.managed_boards.append(board)

    def get_picture(self):
        return self.picture

    @classmethod
    def get_confirmed_users(cls):
        return cls.query.filter(cls.email is not None)

    @staticmethod
    def _create_random_salt(length=32):
        allowed_chars = string.ascii_letters + string.digits
        return u''.join(random.choice(allowed_chars) for _ in range(length))

    @staticmethod
    def _encrypt_password(salt, password):
        secret = "NzlSszmvDNY2e2lVMwiKJwgWjNGFCP1a"
        secret_salt = hashlib.sha512(secret + salt).hexdigest()
        utf8_password = password.encode('utf-8')
        return unicode(hashlib.sha512(secret_salt + utf8_password).hexdigest())

    @classmethod
    def get_unconfirmed_users(cls, before_date=None):
        q = cls.query.filter(cls.email is None)
        if before_date:
            q = q.filter(cls.registration_date < before_date)
        return q

    @classmethod
    def get_by_username(cls, username):
        return cls.get_by(username=username)

    @classmethod
    def get_by_email(cls, email):
        return cls.get_by(email=email)

    @classmethod
    def search(cls, value):
        return cls.query.filter(
            cls.fullname.ilike('%' + value + '%')
            | cls.email.ilike('%' + value + '%'))

    def best_friends(self, exclude_list=(), size=None):
        from kansha.board.models import DataBoard

        cls = self.__class__
        bm2 = aliased(DataBoardMember)
        cnt = func.count(DataBoardMember.board_id)
        query = database.session.query(cls, cnt)
        query = query.join(
            (DataBoardMember,
             and_(DataBoardMember.user_source == cls.source,
                  DataBoardMember.user_username == cls.username)))
        query = query.join(
            (DataBoard, DataBoard.id == DataBoardMember.board_id))
        query = query.join((bm2, bm2.board_id == DataBoard.id))
        query = query.filter(bm2.member == self)
        if exclude_list:
            query = query.filter(~cls.email.in_(exclude_list))
        query = query.group_by(cls)
        query = query.order_by(cnt.desc(), cls.fullname)
        if size:
            query = query.limit(size)
        return [res[0] for res in query]
Beispiel #10
0
class RecipeAddition(Entity, DeepCopyMixin):

    USES = ('MASH', 'FIRST WORT', 'BOIL', 'POST-BOIL', 'FLAME OUT', 'PRIMARY',
            'SECONDARY', 'TERTIARY')

    using_options(inheritance='multi', polymorphic=True)

    amount = Field(Float)

    #
    # At the database level, only certain units are actually stored.
    # We do this for the sake of uniformity (to make calculations easier).
    #
    unit = Field(Enum(
        *['POUND', 'OUNCE', 'TEASPOON', 'TABLESPOON', 'GALLON', 'LITER'],
        native_enum=False),
                 nullable=True)

    use = Field(Enum(*USES, native_enum=False))
    duration = Field(Interval)

    recipe = ManyToOne('Recipe', inverse='additions')
    fermentable = ManyToOne('Fermentable', inverse='additions')
    hop = ManyToOne('Hop', inverse='additions')
    yeast = ManyToOne('Yeast', inverse='additions')
    extra = ManyToOne('Extra', inverse='extra')

    @property
    def printable_amount(self):
        if getattr(self.recipe, 'unit_system', None) == 'METRIC':
            return UnitConvert.to_str(*to_metric(self.amount, self.unit))

        return UnitConvert.to_str(self.amount, self.unit)

    @property
    def ingredient(self):
        for ingredient in ('fermentable', 'hop', 'yeast', 'extra'):
            match = getattr(self, ingredient, None)
            if match is not None:
                return match

    @property
    def pounds(self):
        if self.unit == 'POUND':
            return self.amount
        if self.unit == 'OUNCE':
            return self.amount / 16.0
        raise InvalidUnitException('Could not convert `%s` to pounds.' %
                                   self.unit)

    @property
    def minutes(self):
        if self.duration is None:
            return 0
        return self.duration.seconds / 60

    @property
    def sortable_minutes(self):
        if self.use == 'FIRST WORT':
            return maxint

        if self.use in ('POST BOIL', 'FLAME-OUT'):
            return -1

        return self.minutes

    @property
    def step(self):
        return ({
            'MASH': 'mash',
            'FIRST WORT': 'boil',
            'BOIL': 'boil',
            'POST-BOIL': 'boil',
            'FLAME OUT': 'boil',
            'PRIMARY': 'fermentation',
            'SECONDARY': 'fermentation',
            'TERTIARY': 'fermentation'
        })[self.use]

    @property
    def percentage(self):
        additions = getattr(self.recipe, self.step)
        return self.recipe._percent(additions).get(self, 0)

    def to_xml(self):
        from draughtcraft.lib.beerxml import export

        if self.hop:

            kw = {
                'name': self.hop.name,
                'alpha': self.hop.alpha_acid,
                'amount': to_kg(self.amount, self.unit),
                'time': self.minutes,
                'notes': self.hop.description,
                'form': self.form.capitalize(),
                'origin': self.hop.printed_origin
            }

            kw['use'] = {
                'MASH': 'Mash',
                'FIRST WORT': 'First Wort',
                'BOIL': 'Boil',
                'POST-BOIL': 'Aroma',
                'FLAME OUT': 'Aroma',
                'PRIMARY': 'Dry Hop',
                'SECONDARY': 'Dry Hop',
                'TERTIARY': 'Dry Hop'
            }.get(self.use)

            return export.Hop(**kw)

        if self.fermentable:
            kw = {
                'name': self.fermentable.name,
                'amount': to_kg(self.amount, self.unit),
                'yield': self.fermentable.percent_yield,
                'color': self.fermentable.lovibond,
                'add_after_boil': self.step == 'fermentation',
                'origin': self.fermentable.printed_origin,
                'notes': self.fermentable.description
            }

            kw['type'] = {
                'MALT': 'Grain',
                'GRAIN': 'Grain',
                'ADJUNCT': 'Adjunct',
                'EXTRACT': 'Extract',
                'SUGAR': 'Sugar'
            }.get(self.fermentable.type)

            if self.fermentable.type == 'EXTRACT' and \
                    'DME' in self.fermentable.name:
                kw['type'] = 'Dry Extract'

            return export.Fermentable(**kw)

        if self.yeast:
            kw = {
                'name': self.yeast.name,
                'form': self.yeast.form.capitalize(),
                'attenuation': self.yeast.attenuation * 100.00,
                'notes': self.yeast.description
            }

            # Map types as appropriately as possible to BeerXML <TYPE>'s.
            kw['type'] = {
                'ALE': 'Ale',
                'LAGER': 'Lager',
                'WILD': 'Ale',
                'MEAD': 'Wine',
                'CIDER': 'Wine',
                'WINE': 'Wine'
            }.get(self.yeast.type)

            if self.yeast.form == 'LIQUID':
                #
                # If the yeast is liquid, it's probably a activator/vial.  For
                # simplicity, we'll assume Wyeast's volume, 125ml.
                #
                kw['amount'] = 0.125
            else:
                #
                # If the yeast is dry, it's probably a small packet.  For
                # simplicity, we'll assume a standard weight of 11.5g.
                #
                kw['amount'] = 0.0115
                kw['amount_is_weight'] = True

            if self.use in ('SECONDARY', 'TERTIARY'):
                kw['add_to_secondary'] = True

            return export.Yeast(**kw)

        if self.extra:
            kw = {
                'name': self.extra.name,
                'type': string.capwords(self.extra.type),
                'time': self.minutes,
                'notes': self.extra.description
            }

            kw['use'] = {
                'MASH': 'Mash',
                'FIRST WORT': 'Boil',
                'BOIL': 'Boil',
                'POST-BOIL': 'Boil',
                'FLAME OUT': 'Boil',
                'PRIMARY': 'Primary',
                'SECONDARY': 'Secondary',
                'TERTIARY': 'Secondary'
            }.get(self.use)

            if self.unit is None:
                #
                # If there's no unit (meaning it's just one "unit"), assume
                # a weight of 15 grams.
                #
                kw['amount'] = 0.015
                kw['amount_is_weight'] = True
            elif self.extra.liquid:
                kw['amount'] = to_l(self.amount, self.unit)
            else:
                kw['amount'] = to_kg(self.amount, self.unit)
                kw['amount_is_weight'] = True

            return export.Misc(**kw)

    def __json__(self):
        return {
            'amount': 1 if self.yeast else self.amount,
            'unit': self.unit,
            'use': self.use,
            'minutes': self.minutes,
            'ingredient': self.ingredient
        }
Beispiel #11
0
class sys_users(Entity):
    uid = Field(Integer, primary_key=True)
    username = Field(String(50))
    realname = Field(String(32))
    shell = Field(String(20), default='/bin/bash')
    password = Field(String(40))
    homedir = Field(String(32), default='/home/data-exchange-home')
    lastchange = Field(String(50))
    min = Field(Integer)
    max = Field(Integer)
    warn = Field(Integer)
    inact = Field(Integer)
    _expire = Field(Integer, colname='expire', synonym='expire')
    confirmed = Field(Boolean, default=False)
    created = Field(DateTime, default=datetime.now)
    email = Field(String(100))
    status = Field(String(1), default='N')
    organisation = Field(String(100))
    group = ManyToOne('sys_groups', colname='gid')
    known_partners = ManyToOne('known_partners')
    groups = ManyToMany('sys_groups', tablename='sys_groupmembers')
    using_options(tablename='sys_users')
    using_table_options(mysql_engine='InnoDB')

    ADDITIONAL_HOURS = 48
    ADMIN_MAIL = '*****@*****.**'

    def validate_password(self, password):
        """
        Check the password against existing credentials.
        
        :param password: the password that was provided by the user to
            try and authenticate. This is the clear text version that we will
            need to match against the hashed one in the database.
        :type password: unicode object.
        :return: Whether the password is valid.
        :rtype: bool
        
        """
        salt = self.password[:2]

        hashed_pass = crypt.crypt(password, salt)
        return self.password == hashed_pass

    def _set_expire(self, expire):
        self._expire = time.mktime(expire.timetuple())

    def _get_expire(self):
        return datetime.fromtimestamp(self._expire)

    expire = property(_get_expire, _set_expire)

    def _set_password_plain(self, password):
        self._password_plain = password
        chars = string.letters + string.digits
        salt = random.choice(chars) + random.choice(chars)
        self.password = crypt.crypt(password, salt)

    def _get_password_plain(self):
        return self._password_plain

    password_plain = property(_get_password_plain, _set_password_plain)

    @classmethod
    def generatePassword(cls):
        return ''.join(random.sample(string.letters + string.digits, 12))

    @classmethod
    def getExpireDate(cls):
        return datetime.today() + timedelta(hours=cls.ADDITIONAL_HOURS)

    def _get_is_notify(self):
        if (self.status == 'A' and self.isExpired == True
                and self.confirmed == True) or (self.known_partners
                                                is not None):
            return True
        else:
            return False

    isNotify = property(_get_is_notify)

    def _get_expire_in(self):
        if not self.expire:
            return 'N/A'
        timediff = self.expire - datetime.today()
        return timediff

    expire_in = property(_get_expire_in)

    def _get_is_expired(self):
        if self.expire:
            if self.expire < datetime.today():
                return True
        return False

    isExpired = property(_get_is_expired)

    @before_insert
    def _auto_confirm(self):

        if self.known_partners:
            self.confirmed = True
            self.status = 'A'

    def notify(self):
        if self.isNotify == True:
            self.sendAccountMail()
        else:
            self.notify_admin()

    def notify_admin(self):
        from email.mime.text import MIMEText
        mailtext = """%(name)s of %(organisation)s has requested a temporary FTP-Account.

Please confirm the request here: %(link)s""" % dict(
            name=self.realname,
            organisation=self.organisation,
            link=
            'http://arabidopsis.gmi.oeaw.ac.at:5000/management/RequestFTPAccess/confirmlist'
        )
        msg = MIMEText(mailtext)
        me = '*****@*****.**'
        msg['Subject'] = 'New Temporary FTP-Account-Request'
        msg['From'] = me
        msg['To'] = self.ADMIN_MAIL
        #return True
        # Send the message via our own SMTP server, but don't include the
        # envelope header.
        s = smtplib.SMTP()
        s.connect()
        s.sendmail(me, [self.email], msg.as_string())
        s.quit()

    def sendAccountMail(self):

        from email.mime.text import MIMEText
        mailtext = """Dear Mr/Mrs %(name)s! 

You requested a Temporary sftp-Account for the Arabidopsis-Server.

You can connect to the Arabidopsis sftp-Server using following account information:
Login:       %(username)s
Password:  %(password)s
Server: %(server)s | %(direct_link)s

The account is active until %(expire)s

You can use FileZilla or any other sftp capable application to transfer data from and to the server. 

Regards
Norborg-Group""" % dict(
            name=self.realname,
            username=self.username,
            password=self.password_plain,
            server='arabidopsis.gmi.oeaw.ac.at:22',
            direct_link='sftp://%s:%[email protected]:22' %
            (self.username, self.password_plain),
            expire=self.expire)
        msg = MIMEText(mailtext)
        me = '*****@*****.**'
        msg['Subject'] = 'Arabidopsis Temporary sFTP-Account'
        msg['From'] = me
        msg['To'] = self.email
        #return True
        # Send the message via our own SMTP server, but don't include the
        # envelope header.
        s = smtplib.SMTP()
        s.connect()
        s.sendmail(me, [self.email], msg.as_string())
        s.quit()

    def confirm(self):
        if not self.known_partners:
            self.known_partners = known_partners.get_by(email=self.email)
        self.confirmed = True
        if not self.known_partners:
            self.known_partners = known_partners(email=self.email)
        self.expires = self.getExpireDate()
        self.status = 'A'
        self.password_plain = self.generatePassword()
        __session__.flush()
Beispiel #12
0
class Movie(Entity):
    using_options(tablename='movies')
    title = Field(Unicode(60), required=True)
    short_description = Field(Unicode(512))
    releasedate = Field(Date)
    #
    # All relation types are covered with their own editor
    #
    director = ManyToOne('Person')
    cast = OneToMany('Cast')
    visitor_reports = OneToMany('VisitorReport')
    tags = ManyToMany('Tag')
    genre = Field(Unicode(15))
    rating = Field(camelot.types.Rating())
# end short movie definition
    #
    # Camelot includes custom sqlalchemy types, like Image, which stores an
    # image on disk and keeps the reference to it in the database.
    #
    cover = Field(camelot.types.Image(upload_to='covers'))
    #
    # Or File, which stores a file in the upload_to directory and stores a
    # reference to it in the database
    #
    script = Field(camelot.types.File(upload_to='script'))
    description = Field(camelot.types.RichText)

    #
    # Using a ColumnProperty, an sql query can be assigned to a field
    #
    @ColumnProperty
    def total_visitors(self):
        return sql.select([sql.func.sum(VisitorReport.visitors)],
                               VisitorReport.movie_id==self.id)

    #
    # Normal python properties can be used as well, but then the
    # delegate needs be specified
    #
    @property
    def visitors_chart(self):
        #
        # Container classes are used to transport chunks of data between
        # the model thread and the gui thread, in this case a chart
        #
        from camelot.container.chartcontainer import BarContainer
        return BarContainer(range(len(self.visitor_reports)),
                            [vr.visitors for vr in self.visitor_reports])

    #
    # Each Entity subclass can have a subclass of EntityAdmin as
    # its inner class.  The EntityAdmin class defines how the Entity
    # class will be displayed in the GUI.  Its behavior can be steered
    # by specifying some class attributes
    #
    # To fully customize the way the entity is visualized, the EntityAdmin
    # subclass should overrule some of the EntityAdmin's methods
    #
    class Admin(EntityAdmin):
        # the list_display attribute specifies which entity attributes should
        # be visible in the table view
        list_display = ['cover', 'title', 'releasedate', 'rating',]
        lines_per_row = 5
        # define filters to be available in the table view
        list_filter = ['genre', ComboBoxFilter('director.full_name')]
        # if the search function needs to look in related object attributes,
        # those should be specified within list_search
        list_search = ['director.full_name']
        # the form_display attribute specifies which entity attributes should be
        # visible in the form view
        form_display = TabForm([
          ('Movie', Form([
            HBoxForm([WidgetOnlyForm('cover'), ['title', 'rating']]),
            'short_description',
            'releasedate',
            'director',
            'script',
            'genre',
            'description',], columns = 2)),
          ('Cast', WidgetOnlyForm('cast')),
          ('Visitors', WidgetOnlyForm('visitors_chart')),
          ('Tags', WidgetOnlyForm('tags'))
        ])

        # create a list of actions available for the user on the form view
        # those actions will be executed within the model thread
        #
        form_actions = [('Burn DVD', burn_to_disk)]
        #
        # additional attributes for a field can be specified in the
        # field_attributes dictionary
        #
        field_attributes = dict(cast=dict(create_inline=True),
                                genre=dict(choices=genre_choices, editable=lambda o:bool(o.title and len(o.title))),
                                releasedate=dict(background_color=lambda o:ColorScheme.orange_1 if o.releasedate and o.releasedate < datetime.date(1920,1,1) else None),
                                visitors_chart=dict(delegate=delegates.ChartDelegate),
                                rating=dict(tooltip='''<table>
                                                          <tr><td>1 star</td><td>Not that good</td></tr>
                                                          <tr><td>2 stars</td><td>Almost good</td></tr>
                                                          <tr><td>3 stars</td><td>Good</td></tr>
                                                          <tr><td>4 stars</td><td>Very good</td></tr>
                                                          <tr><td>5 stars</td><td>Awesome !</td></tr>
                                                       </table>'''),
                                smiley=dict(delegate=delegates.SmileyDelegate),
                                script=dict(remove_original=True))

    def __unicode__(self):
        return self.title or ''
Beispiel #13
0
class Permission(Entity):
    permission_id = Field(Integer, primary_key=True)
    permission_name = Field(Unicode(16), unique=True)
    description = Field(Unicode(255))
    groups = ManyToMany('Group', inverse='permissions')
    using_options(tablename='permission')
Beispiel #14
0
class VisitIdentity(Entity):
    visit_key = Field(String(40), primary_key=True)
    user = ManyToOne('User', colname='user_id', use_alter=True)
    using_options(tablename='visit_identity')
Beispiel #15
0
 class Director(Person):
     movies = e.OneToMany('Movie')
     e.using_options(inheritance='multi')
Beispiel #16
0
class Collection(Entity):
    name = Field(UnicodeText)

    using_options(tablename='collections')
    using_table_options(schema='inventory')
Beispiel #17
0
class DataColumn(Entity):
    """Column mapper
    """
    using_options(tablename='column')
    title = Field(Unicode(200))
    index = Field(Integer)
    nb_max_cards = Field(Integer)
    archive = Field(Boolean, default=False)
    cards = OneToMany('DataCard', order_by='index', cascade='delete')
    board = ManyToOne('DataBoard', colname='board_id')

    @classmethod
    def create_column(cls, board, index, title, nb_cards=None, archive=False):
        """Create new column

        In:
            - ``board`` -- DataBoard, father of the column
            - ``index`` -- position in the board
            - ``title`` -- title of the column
        Return:
            - created DataColumn instance
        """
        q = cls.query
        q = q.filter(cls.index >= index)
        q = q.filter(cls.board == board)
        q.update({'index': cls.index + 1})
        col = cls(title=title,
                  index=index,
                  board=board,
                  nb_max_cards=nb_cards,
                  archive=archive)
        session.add(col)
        session.flush()
        return col

    @classmethod
    def delete_column(cls, column):
        """Delete column

        Delete a given column, re-index other columns and delete all cards
        of the column

        In:
            - ``column`` -- DataColumn instance to delete
        """
        index = column.index
        board = column.board
        column.delete()
        session.flush()
        q = cls.query
        q = q.filter(cls.index >= index)
        q = q.filter(cls.board == board)
        q.update({'index': cls.index - 1})

    def reorder(self):
        for i, card in enumerate(self.cards):
            card.index = i

    def get_cards_count(self):
        q = DataCard.query.filter(DataCard.column_id == self.id)
        return q.count()
Beispiel #18
0
class DataChecklist(Entity):
    using_options(tablename='checklists')

    title = Field(Unicode(255))
    items = OneToMany('DataChecklistItem',
                      order_by='index',
                      inverse='checklist',
                      collection_class=ordering_list('index'))
    card = ManyToOne('DataCard')
    author = ManyToOne('DataUser')
    index = Field(Integer)

    @classmethod
    def get_by_card(cls, card):
        q = cls.query
        q = q.filter_by(card=card)
        q = q.order_by(cls.index)
        return q.all()

    def update(self, other):
        self.title = other.title
        self.index = other.index
        for item in other.items:
            self.items.append(
                DataChecklistItem(title=item.title,
                                  index=item.index,
                                  done=False))
        database.session.flush()

    def __unicode__(self):
        titles = [item.title for item in self.items if item.title]
        if self.title:
            titles.insert(0, self.title)
        return u'\n'.join(titles)

    def to_indexable(self):
        return unicode(self)

    def add_item_from_str(self, text):
        item = DataChecklistItem.new_from_str(text)
        return self.add_item(item)

    def add_item(self, item):
        self.items.append(item)
        return item

    def insert_item(self, index, item):
        self.items.insert(index, item)

    def remove_item(self, item):
        self.items.remove(item)

    def delete_item(self, item):
        self.remove_item(item)
        item.delete()

    def purge(self):
        for item in self.items:
            item.delete()

    @staticmethod
    def total_items(card):
        return DataChecklistItem.total_items(card)

    @staticmethod
    def total_items_done(card):
        return DataChecklistItem.total_items_done(card)
Beispiel #19
0
class Provinces(Entity):
    using_options(tablename='provinces')

    id = Field(Integer, primary_key=True)
    name = Field(String(255))
Beispiel #20
0
class DataHistory(Entity):
    using_options(tablename='history', order_by='-when')

    when = Field(DateTime)
    action = Field(Unicode(255))
    data = Field(JSONType)

    board = ManyToOne('DataBoard', ondelete='cascade')
    card = ManyToOne('DataCard', ondelete='cascade', required=True)
    user = ManyToOne('DataUser', ondelete='cascade', required=True)

    def to_string(self):
        data = self.data.copy()
        data['author'] = self.user.fullname or self.user.username
        return render_event(self.action, data)

    @classmethod
    def add_history(cls, board, card, user, action, data):
        data.update(action=action)
        when = datetime.utcnow()
        data = cls(when=when,
                   action=action,
                   board=board,
                   card=card,
                   user=user,
                   data=data)
        database.session.flush()

    @classmethod
    def get_events(cls, board, hours=None):
        '''board to None means "everything".'''
        since = datetime.utcnow() - timedelta(hours=hours)
        q = cls.query
        if board:
            q = q.filter_by(board=board)
        q = q.filter(cls.when >= since)
        q = q.order_by(cls.board_id, cls.action, cls.when)
        return q.all()

    @classmethod
    def get_history(cls, board, cardid=None, username=None):
        q = cls.query
        q = q.filter_by(board=board)
        if cardid:
            q = q.filter(cls.card.has(id=cardid))
        if username:
            q = q.filter(cls.user.has(username=username))
        return q

    @classmethod
    def get_last_activity(cls, board):
        q = database.session.query(cls.when)
        q = q.filter(cls.board == board)
        q = q.order_by(cls.when.desc())
        q = q.limit(1)
        return q.scalar()

    @classmethod
    def purge(cls, card):
        q = database.session.query(cls).filter(cls.card == card)
        for log in q:
            log.delete()
Beispiel #21
0
class CompanyPartner(Entity):
    using_options(tablename='company_partner')

    id = Field(Integer, primary_key=True)
    name = Field(String(255), default='')
Beispiel #22
0
class Artigo(Entity):
    using_options(tablename='artigo_lei')
    lei = ManyToOne('Lei')
    numero = Field(Unicode(32))
    paragrafos = OneToMany('Paragrafo')
    incisos = OneToMany('Inciso')
Beispiel #23
0
class Schools(Entity):
    using_options(tablename='schools')

    id = Field(Integer, primary_key=True)
    name = Field(String(255), default='')
Beispiel #24
0
class Paragrafo(Entity):
    using_options(tablename='paragrafo_artigo')
    artigo = ManyToOne('Artigo')
    numero = Field(Unicode(128))
Beispiel #25
0
 class CategoryEntity(elixir.Entity):
     elixir.using_options(tablename=str(categories))
     # save_on_init IS VERY IMPORTANT
     elixir.using_mapper_options(save_on_init=False)
Beispiel #26
0
class Inciso(Entity):
    using_options(tablename='inciso_artigo')
    artigo = ManyToOne('Artigo')
    numero = Field(Unicode(32))
    letras = OneToMany('Letra')
Beispiel #27
0
class DataBoard(Entity):
    """Board mapper

     - ``title`` -- board title
     - ``is_template`` -- is this a real board or a template?
     - ``columns`` -- list of board columns
     - ``labels`` -- list of labels for cards
     - ``comments_allowed`` -- who can comment ? (0 nobody, 1 board members only , 2 all application users)
     - ``votes_allowed`` -- who can vote ? (0 nobody, 1 board members only , 2 all application users)
     - ``description`` -- board description
     - ``visibility`` -- board visibility (0 Private, 1 Public)
     - ``members`` -- list of members (simple members and manager)
     - ``managers`` -- list of managers
     - ``uri`` -- board URI (Universally Unique IDentifier)
     - ``last_users`` -- list of last users
     - ``pending`` -- invitations pending for new members (use token)
     - ``archive`` -- display archive column ? (0 false, 1 true)
     - ``archived`` -- is board archived ?
    """
    using_options(tablename='board')
    title = Field(Unicode(255))
    is_template = Field(Boolean, default=False)
    columns = OneToMany('DataColumn', order_by="index",
                        cascade='delete')
    labels = OneToMany('DataLabel', order_by='index')
    comments_allowed = Field(Integer, default=1)
    votes_allowed = Field(Integer, default=1)
    description = Field(UnicodeText, default=u'')
    visibility = Field(Integer, default=0)
    version = Field(Integer, default=0, server_default='0')
    board_members = OneToMany('DataBoardMember', cascade='delete')
    board_managers = OneToMany('DataBoardManager', cascade='delete')
    members = AssociationProxy('board_members', 'member', creator=lambda member: DataBoardMember(member=member))
    managers = AssociationProxy('board_managers', 'member', creator=lambda member: DataBoardManager(member=member))
    uri = Field(Unicode(255), index=True, unique=True)
    last_users = ManyToOne('DataUser', order_by=('fullname', 'email'))
    pending = OneToMany('DataToken', order_by='username')
    history = OneToMany('DataHistory')

    background_image = Field(Unicode(255))
    background_position = Field(Unicode(255))
    title_color = Field(Unicode(255))
    show_archive = Field(Integer, default=0)
    archived = Field(Boolean, default=False)

    weighting_cards = Field(Integer, default=0)
    weights = Field(Unicode(255), default=u'')

    @property
    def template_title(self):
        if not self.managers or self.visibility == 0:
            return self.title
        return u'{0} ({1})'.format(self.title, self.managers[0].fullname)

    def copy(self):
        new_data = DataBoard(title=self.title,
                             description=self.description,
                             background_position=self.background_position,
                             title_color=self.title_color,
                             comments_allowed=self.comments_allowed,
                             votes_allowed=self.votes_allowed,
                             weighting_cards=self.weighting_cards,
                             weights=self.weights)
        session.flush()
        # TODO: move to board extension
        for label in self.labels:
            new_data.labels.append(label.copy())
        session.flush()
        return new_data

    def get_label_by_title(self, title):
        return (l for l in self.labels if l.title == title).next()

    def delete_members(self):
        for member in self.board_members:
            session.delete(member)
        session.flush()

    def delete_history(self):
        for event in self.history:
            session.delete(event)
        session.flush()

    def increase_version(self):
        self.version += 1
        if self.version > 2147483600:
            self.version = 1

    @property
    def url(self):
        return urllib.quote_plus(
            "%s/%s" % (self.title.encode('ascii', 'ignore'), self.uri),
            '/'
        )

    def __init__(self, *args, **kwargs):
        """Initialization.

        Create board and uri of the board
        """
        super(DataBoard, self).__init__(*args, **kwargs)
        self.uri = unicode(uuid.uuid4())

    @classmethod
    def get_by_id(cls, id):
        return cls.get(id)

    @classmethod
    def get_by_uri(cls, uri):
        return cls.get_by(uri=uri)

    def has_member(self, user):
        """Return True if user is member of the board

        In:
         - ``user`` -- user to test (User instance)
        Return:
         - True if user is member of the board
        """
        return user.data in self.members

    def remove_member(self, board_member):
        board_member.delete()

    def has_manager(self, user):
        """Return True if user is manager of the board

        In:
         - ``user`` -- user to test (User instance)
        Return:
         - True if user is manager of the board
        """
        return user.data in self.managers

    def remove_manager(self, board_member):
        obj = DataBoardManager.get_by(board=self, member=board_member.get_user_data())
        if obj is not None:
            obj.delete()
        self.remove_member(board_member)

    def change_role(self, board_member, new_role):
        obj = DataBoardManager.get_by(board=self, member=board_member.get_user_data())
        if new_role == 'manager':
            if obj is None:
                obj = DataBoardManager(board=self, member=board_member.get_user_data())
                session.add(obj)
        else:
            if obj is not None:
                obj.delete()

    def last_manager(self, member):
        """Return True if member is the last manager of the board"""
        return member.role == 'manager' and len(self.managers) == 1

    def add_member(self, new_member, role='member'):
        """ Add new member to the board

        In:
         - ``new_member`` -- user to add (DataUser instance)
         - ``role`` -- role's member (manager or member)
        """
        self.board_members.append(DataBoardMember(member=new_member.data))

        if role == 'manager':
            self.managers.append(new_member.data)

        session.flush()

    def get_pending_users(self):
        emails = [token.username for token in self.pending]
        return DataUser.query.filter(DataUser.email.in_(emails))

    def set_background_image(self, image):
        self.background_image = image or u''

    @classmethod
    def get_all_board_ids(cls):
        return session.query(cls.id).filter_by(is_template=False).order_by(cls.title)

    @classmethod
    def get_templates_for(cls, user_username, user_source, public_value):
        q = cls.query
        q = q.filter(cls.archived == False)
        q = q.filter(cls.is_template == True)
        q = q.order_by(cls.title)

        q1 = q.filter(cls.visibility == public_value)

        q2 = q.join(DataBoardManager)
        q2 = q2.filter(DataBoardManager.user_username == user_username)
        q2 = q2.filter(DataBoardManager.user_source == user_source)
        q2 = q2.filter(cls.visibility != public_value)

        return q1, q2

    def create_column(self, index, title, nb_cards=None, archive=False):
        return DataColumn.create_column(self, index, title, nb_cards, archive)

    def create_label(self, title, color):
        label = DataLabel(title=title, color=color)
        self.labels.append(label)
        session.flush()
        return label
Beispiel #28
0
class Letra(Entity):
    using_options(tablename='letra_inciso')
    inciso = ManyToOne('Inciso')
    letra = Field(Unicode(16))
class User(Entity):
    """Reasonably basic User definition. Probably would want additional
    attributes.
    """
    using_options(tablename="user", auto_primarykey="user_id")

    user_name = Field(Unicode(16), required=True, unique=True)

    _password = Field(Unicode(80), colname="password", required=True)

    groups = ManyToMany(
        "Group",
        inverse="users",
        tablename="user_group",
        local_colname="group_id",
        remote_colname="user_id",
        )

    def _set_password(self, password):
        """Hash password on the fly."""
        hashed_password = password

        if isinstance(password, unicode):
            password_8bit = password.encode('UTF-8')
        else:
            password_8bit = password
        
        salt = sha1()
        salt.update(os.urandom(60))
        hash = sha1()
        hash.update(password_8bit + salt.hexdigest())
        hashed_password = salt.hexdigest() + hash.hexdigest()

        # Make sure the hased password is an UTF-8 object at the end of the
        # process because SQLAlchemy _wants_ a unicode object for Unicode
        # fields
        if not isinstance(hashed_password, unicode):
            hashed_password = hashed_password.decode('UTF-8')

        self._password = hashed_password

    def _get_password(self):
        """Return the password hashed"""
        return self._password

    password = descriptor=property(_get_password, _set_password)

    def validate_password(self, password):
        """Check the password against existing credentials.

        :param password: the password that was provided by the user to
            try and authenticate. This is the clear text version that we will
            need to match against the hashed one in the database.
        :type password: unicode object.
        :return: Whether the password is valid.
        :rtype: bool
        
        """
        hashed_pass = sha1()
        hashed_pass.update(password + self.password[:40])
        return self.password[40:] == hashed_pass.hexdigest()
Beispiel #30
0
class Director(Entity):
    name = Field(Unicode(60))
    movies = OneToMany('Movie', inverse='director')
    using_options(tablename='directors')