Esempio n. 1
0
class Node(Storm):
    """A PubSub node."""
    __storm_table__ = u'nodes'

    node = Unicode(primary=True, allow_none=False)
    config = ReferenceSet(node, 'NodeConfig.node')
    items = ReferenceSet(node, 'Item.node')
    subscriptions = ReferenceSet(node, 'Subscription.node')
    affiliations = ReferenceSet(node, 'Affiliation.node')

    def __init__(self, node):
        super(Node, self).__init__()
        self.node = unicode(node)
Esempio n. 2
0
class Account(SQLBase):
    """An Account."""

    implements(IAccount)

    date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)

    displayname = StringCol(dbName='displayname', notNull=True)

    creation_rationale = EnumCol(dbName='creation_rationale',
                                 schema=AccountCreationRationale,
                                 notNull=True)
    status = AccountStatusEnumCol(enum=AccountStatus,
                                  default=AccountStatus.NOACCOUNT,
                                  notNull=True)
    date_status_set = UtcDateTimeCol(notNull=True, default=UTC_NOW)
    status_comment = StringCol(dbName='status_comment', default=None)

    openid_identifiers = ReferenceSet("Account.id",
                                      OpenIdIdentifier.account_id)

    def __repr__(self):
        displayname = self.displayname.encode('ASCII', 'backslashreplace')
        return "<%s '%s' (%s)>" % (self.__class__.__name__, displayname,
                                   self.status)

    def reactivate(self, comment):
        """See `IAccountSpecialRestricted`."""
        self.status = AccountStatus.ACTIVE
        self.status_comment = comment
Esempio n. 3
0
class Namespace(Storm):
    """A namespace is a container for L{Tag}s and other namespaces.

    @param creator: The L{User} that owns the namespace.
    @param path: The full C{unicode} path for the namespace.
    @param name: The C{unicode} name of the namespace (should be the same as
        the last segment of C{path}).
    @param parent: Optionally, the C{Namespace} instance that represents the
        parent of this namespace.
    """

    __storm_table__ = 'namespaces'

    id = Int('id', primary=True, allow_none=False, default=AutoReload)
    objectID = UUID('object_id', allow_none=False)
    parentID = Int('parent_id')
    creatorID = Int('creator_id', allow_none=False)
    path = Unicode('path', allow_none=False)
    name = Unicode('name', allow_none=False)
    creationTime = DateTime('creation_time', default=AutoReload)

    creator = Reference(creatorID, 'User.id')
    parent = Reference(parentID, id)
    children = ReferenceSet(id, parentID)
    permission = Reference(id, 'NamespacePermission.namespaceID')

    def __init__(self, creator, path, name, parentID=None):
        self.objectID = uuid4()
        self.creator = creator
        self.path = path
        self.name = name
        self.parentID = parentID
Esempio n. 4
0
class RoleEntity(Storm):
    __storm_table__ = 'ROLES'
    __storm_primary__ = 'id'

    id = Unicode(name='id')
    name = Unicode(name='name')

    permissions = ReferenceSet(id, 'Role2PermissionEntity.role_id',
                               'Role2PermissionEntity.permission_id',
                               PermissionEntity.id)
Esempio n. 5
0
class Category(Storm):
    """
    A thread category
    """

    __storm_table__ = "category"

    id = Int(primary=True)
    name = Unicode()
    threads = ReferenceSet(id, Thread.category_id)

    def __init__(self, name):
        self.name = unicode(name)
Esempio n. 6
0
class UserEntity(Storm):
    __storm_table__ = 'USERS'
    __storm_primary__ = 'id'

    id = Unicode(name='id')
    fullname = Unicode(name='fullname')
    password = Unicode(name='password')
    is_active = Int(name='is_active')
    is_superuser = Int(name='is_superuser')
    creation_date = DateTime(name='creation_date')

    roles = ReferenceSet(id, 'User2RoleEntity.user_id',
                         'User2RoleEntity.role_id', RoleEntity.id)
Esempio n. 7
0
class Account(SQLBase):
    """An Account."""

    date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)

    displayname = StringCol(dbName='displayname', notNull=True)

    creation_rationale = EnumCol(dbName='creation_rationale',
                                 schema=AccountCreationRationale,
                                 notNull=True)
    status = AccountStatusEnumCol(enum=AccountStatus,
                                  default=AccountStatus.NOACCOUNT,
                                  notNull=True)
    date_status_set = UtcDateTimeCol(notNull=True, default=UTC_NOW)
    status_history = StringCol(dbName='status_comment', default=None)

    openid_identifiers = ReferenceSet("Account.id",
                                      OpenIdIdentifier.account_id)

    def __repr__(self):
        displayname = self.displayname.encode('ASCII', 'backslashreplace')
        return "<%s '%s' (%s)>" % (self.__class__.__name__, displayname,
                                   self.status)

    def addStatusComment(self, user, comment):
        """See `IAccountModerateRestricted`."""
        prefix = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
        if user is not None:
            prefix += ' %s' % user.name
        old_lines = (self.status_history.splitlines()
                     if self.status_history else [])
        self.status_history = '\n'.join(old_lines +
                                        ['%s: %s' % (prefix, comment), ''])

    def setStatus(self, status, user, comment):
        """See `IAccountModerateRestricted`."""
        comment = comment or ''
        self.addStatusComment(
            user, '%s -> %s: %s' % (self.status.title, status.title, comment))
        # date_status_set is maintained by a DB trigger.
        self.status = status

    def reactivate(self, comment):
        """See `IAccountSpecialRestricted`."""
        self.setStatus(AccountStatus.ACTIVE, None, comment)
Esempio n. 8
0
File: board.py Progetto: JANE-XU/wld
class Thread(Storm):
    """
    I represent a discussion on a Board.

    @ivar created: Timestamp of my entry in the database
    @ivar name: The topic that will be discussed
    @ivar board_id: ID of the Board to which I belong
    @ivar user_id: ID of the User that created me 

    @ReferenceSet messages: A storm ReferenceSet object with all of my Messages
    @Reference user: The User that created me.
    """
    __storm_table__ = 'boards_threads'
    id = Int(primary=True)
    created = DateTime(default=datetime.datetime.now())
    name = Unicode(validator=unicoder)
    board_id = Int()
    user_id = Int()

    board = Reference(board_id, "Board.id")
    messages = ReferenceSet(id, "Message.thread_id")
    user = Reference(user_id, "User.id")

    def getJSON(self, extra=False):
        """
        Return a json object of my attributes and other useful stuff

        @param extra: Whether info from other classes will be included in the json
        """
        return_json = {
            'id': self.id,
            'created': self.created,
            'name': self.name,
        }

        if extra:
            user = store.find(User, User.id == self.user_id).one()
            messages = self.messages
            extra_data = {
                'username': user.username,
            }
            return_json.update(extra_data)

        return return_json
Esempio n. 9
0
class Email(Storm):
    """
    An archived email, from a mailing-list. It is identified by both the list
    name and the message id.
    """

    implements(IMessage)
    __storm_table__ = "email"
    __storm_primary__ = "list_name", "message_id"

    list_name = Unicode()
    message_id = Unicode()
    sender_name = Unicode()
    sender_email = Unicode()
    user_id = Unicode()
    subject = Unicode()
    content = Unicode()
    date = DateTime()
    timezone = Int()
    in_reply_to = Unicode()
    message_id_hash = Unicode()
    thread_id = Unicode()
    archived_date = DateTime(default_factory=datetime.datetime.now)
    thread_depth = Int(default=0)
    thread_order = Int(default=0)
    # path is required by IMessage, but it makes no sense here
    path = None
    # References
    attachments = ReferenceSet(
        (list_name, message_id),
        ("Attachment.list_name", "Attachment.message_id"),
        order_by="Attachment.counter")
    thread = Reference((list_name, thread_id),
                       ("Thread.list_name", "Thread.thread_id"))
    full_email = Reference((list_name, message_id),
                           ("EmailFull.list_name", "EmailFull.message_id"))
    full = Proxy(full_email, "EmailFull.full")
    mlist = Reference(list_name, "List.name")

    def __init__(self, list_name, message_id):
        self.list_name = unicode(list_name)
        self.message_id = unicode(message_id)
        self.message_id_hash = unicode(get_message_id_hash(self.message_id))
Esempio n. 10
0
File: user.py Progetto: JANE-XU/wld
class User(Storm):
    """
    I am a website user.  I can browse the site, view boards, and potentially modify other User objects.

    @ivar username: A unique name to identify me
    @ivar email: The email address tied to me
    @ivar first_name: My first name
    @ivar last_name: My surname

    @ReferenceSet board_perms: A storm ReferenceSet of all my Board permissions
    """
    __storm_table__ = 'users'
    id = Int(primary=True)
    username = Unicode(validator=unicoder)
    email = Unicode(validator=unicoder)
    first_name = Unicode(validator=unicoder)
    last_name = Unicode(validator=unicoder)

    board_perms = ReferenceSet(id, _LinkUserBoardPerms.user_id,
                               _LinkUserBoardPerms.perm_id, BoardPerms.id)
Esempio n. 11
0
class Location(Storm):
    __storm_table__ = "location"
    name = Unicode(primary=True)
    systems = ReferenceSet(name, "IcepapSystem.location_name")
    log = logging.getLogger('{}.Location'.format(__name__))

    @loggingInfo
    def __init__(self, name):
        self.name = name
        self.initialize()

    @loggingInfo
    def initialize(self):
        self._inmemory_systems = {}

    @loggingInfo
    def __storm_loaded__(self):
        self.initialize()

    @loggingInfo
    def loadSystemsfromDB(self):
        for system in self.systems:
            self._inmemory_systems[system.name] = system

    @loggingInfo
    def addSystem(self, system):
        self.systems.add(system)
        self._inmemory_systems[system.name] = system

    @loggingInfo
    def deleteSystem(self, name):
        system = self.systems.find(IcepapSystem.name == name).one()
        for driver in system.getDrivers():
            system.removeDriver(driver.addr)
        StormManager().deleteIcepapSystem(system)
        try:
            del self._inmemory_systems[name]
            self._inmemory_drivers = {}
        except Exception:
            pass
Esempio n. 12
0
class IcepapDriverCfg(Storm):
    __storm_table__ = "icepapdrivercfg"
    id = Int(primary=True)
    icepapsystem_name = Unicode()
    driver_addr = Int()
    name = Unicode()
    description = Unicode()
    signature = Unicode()
    date = DateTime()
    """ references """
    icepap_driver = Reference((icepapsystem_name, driver_addr),
                              ("IcepapDriver.icepapsystem_name",
                               "IcepapDriver.addr"))
    parameters = ReferenceSet(id, "CfgParameter.cfg_id")

    log = logging.getLogger('{}.IcepapDriverCfg'.format(__name__))

    @loggingInfo
    def __init__(self, name, description=None):
        if description is None:
            description = str("")
        self.description = str(description)
        self.name = str(name)
        self.date = datetime.datetime.now()
        self.initialize()

    @loggingInfo
    def __storm_loaded__(self):
        self.initialize()
        for cfgpar in self.parameters:
            self._inmemory_parameters[cfgpar.name] = cfgpar

    @loggingInfo
    def initialize(self):
        self._inmemory_parameters = {}

    @loggingInfo
    def setDriver(self, driver):
        self.icepap_driver = driver

    @loggingInfo
    def resetDriver(self):
        self.icepap_driver = None
        self.icepapsystem_name = None
        self.driver_addr = None

    @loggingInfo
    def setSignature(self, signature):
        self.signature = str(signature)

    @loggingInfo
    def getSignature(self):
        return str(self.signature)

    @loggingInfo
    def setParameter(self, name, value):
        name = str(name)
        value = str(value)
        cfgpar = None
        try:
            cfgpar = self.parameters.find(CfgParameter.name == name).one()
        except Exception:
            pass
        if cfgpar is None:
            cfgpar = CfgParameter(self, name, value)
            self.parameters.add(cfgpar)
        else:
            cfgpar.value = value
        self._inmemory_parameters[str(name)] = cfgpar

    @loggingInfo
    def getParameter(self, name, in_memory=False):
        if in_memory:
            if str(name) in self._inmemory_parameters:
                return self._inmemory_parameters[str(name)].value
            else:
                return None
        else:
            cfgpar = self.parameters.find(CfgParameter.name == name).one()
            if cfgpar is not None:
                return cfgpar.value
            else:
                return None

    @loggingInfo
    def toList(self):
        l = []
        for cfgpar in self._inmemory_parameters.values():
            l.append((cfgpar.name, cfgpar.value))
        return l

    @loggingInfo
    def __str__(self):
        text = "Configuration"
        for par in self.parameters:
            text = text + "\n" + par.name + ":\t" + par.value
        return text

    @loggingInfo
    def __ne__(self, other):
        return not self.__eq__(other)

    @loggingInfo
    def __eq__(self, other):
        self_list = self.toList()

        for name, value in self_list:
            other_value = other.getParameter(name, True)
            if other_value is not None:
                if value != other_value:
                    return False
            else:
                return False

        return True
class SourcePackageRecipe(Storm):
    """See `ISourcePackageRecipe` and `ISourcePackageRecipeSource`."""

    __storm_table__ = 'SourcePackageRecipe'

    def __str__(self):
        return '%s/%s' % (self.owner.name, self.name)

    implements(ISourcePackageRecipe)

    classProvides(ISourcePackageRecipeSource)

    delegates(ISourcePackageRecipeData, context='_recipe_data')

    id = Int(primary=True)

    daily_build_archive_id = Int(name='daily_build_archive', allow_none=True)
    daily_build_archive = Reference(daily_build_archive_id, 'Archive.id')

    date_created = UtcDateTimeCol(notNull=True)
    date_last_modified = UtcDateTimeCol(notNull=True)

    owner_id = Int(name='owner', allow_none=True)
    owner = Reference(owner_id, 'Person.id')

    registrant_id = Int(name='registrant', allow_none=True)
    registrant = Reference(registrant_id, 'Person.id')

    distroseries = ReferenceSet(
        id, _SourcePackageRecipeDistroSeries.sourcepackagerecipe_id,
        _SourcePackageRecipeDistroSeries.distroseries_id, DistroSeries.id)

    build_daily = Bool()

    is_stale = Bool()

    @property
    def _sourcepackagename_text(self):
        return self.sourcepackagename.name

    name = Unicode(allow_none=True)
    description = Unicode(allow_none=True)

    @cachedproperty
    def _recipe_data(self):
        return Store.of(self).find(
            SourcePackageRecipeData,
            SourcePackageRecipeData.sourcepackage_recipe == self).one()

    @property
    def builder_recipe(self):
        """Accesses of the recipe go to the SourcePackageRecipeData."""
        return self._recipe_data.getRecipe()

    @property
    def base_branch(self):
        return self._recipe_data.base_branch

    @staticmethod
    def preLoadDataForSourcePackageRecipes(sourcepackagerecipes):
        # Load the referencing SourcePackageRecipeData.
        spr_datas = load_referencing(SourcePackageRecipeData,
                                     sourcepackagerecipes,
                                     ['sourcepackage_recipe_id'])
        # Load the related branches.
        load_related(Branch, spr_datas, ['base_branch_id'])
        # Store the SourcePackageRecipeData in the sourcepackagerecipes
        # objects.
        for spr_data in spr_datas:
            cache = get_property_cache(spr_data.sourcepackage_recipe)
            cache._recipe_data = spr_data
        SourcePackageRecipeData.preLoadReferencedBranches(spr_datas)

    def setRecipeText(self, recipe_text):
        parsed = SourcePackageRecipeData.getParsedRecipe(recipe_text)
        self._recipe_data.setRecipe(parsed)

    @property
    def recipe_text(self):
        return self.builder_recipe.get_recipe_text()

    def updateSeries(self, distroseries):
        if distroseries != self.distroseries:
            self.distroseries.clear()
            for distroseries_item in distroseries:
                self.distroseries.add(distroseries_item)

    @staticmethod
    def new(registrant,
            owner,
            name,
            recipe,
            description,
            distroseries=None,
            daily_build_archive=None,
            build_daily=False,
            date_created=DEFAULT):
        """See `ISourcePackageRecipeSource.new`."""
        store = IMasterStore(SourcePackageRecipe)
        sprecipe = SourcePackageRecipe()
        builder_recipe = SourcePackageRecipeData.getParsedRecipe(recipe)
        SourcePackageRecipeData(builder_recipe, sprecipe)
        sprecipe.registrant = registrant
        sprecipe.owner = owner
        sprecipe.name = name
        if distroseries is not None:
            for distroseries_item in distroseries:
                sprecipe.distroseries.add(distroseries_item)
        sprecipe.description = description
        sprecipe.daily_build_archive = daily_build_archive
        sprecipe.build_daily = build_daily
        sprecipe.date_created = date_created
        sprecipe.date_last_modified = date_created
        store.add(sprecipe)
        return sprecipe

    @staticmethod
    def findStaleDailyBuilds():
        one_day_ago = datetime.now(utc) - timedelta(hours=23, minutes=50)
        joins = (
            SourcePackageRecipe,
            LeftJoin(
                SourcePackageRecipeBuild,
                And(
                    SourcePackageRecipeBuild.recipe_id ==
                    SourcePackageRecipe.id, SourcePackageRecipeBuild.archive_id
                    == SourcePackageRecipe.daily_build_archive_id,
                    SourcePackageRecipeBuild.date_created > one_day_ago)),
        )
        return IStore(SourcePackageRecipe).using(*joins).find(
            SourcePackageRecipe,
            SourcePackageRecipe.is_stale == True,
            SourcePackageRecipe.build_daily == True,
            SourcePackageRecipeBuild.date_created == None,
        ).config(distinct=True)

    @staticmethod
    def exists(owner, name):
        """See `ISourcePackageRecipeSource.new`."""
        store = IMasterStore(SourcePackageRecipe)
        recipe = store.find(SourcePackageRecipe,
                            SourcePackageRecipe.owner == owner,
                            SourcePackageRecipe.name == name).one()
        if recipe:
            return True
        else:
            return False

    def destroySelf(self):
        store = Store.of(self)
        self.distroseries.clear()
        self._recipe_data.instructions.find().remove()
        builds = store.find(SourcePackageRecipeBuild,
                            SourcePackageRecipeBuild.recipe == self)
        builds.set(recipe_id=None)
        store.remove(self._recipe_data)
        store.remove(self)

    def isOverQuota(self, requester, distroseries):
        """See `ISourcePackageRecipe`."""
        return SourcePackageRecipeBuild.getRecentBuilds(
            requester, self, distroseries).count() >= 5

    def containsUnbuildableSeries(self, archive):
        buildable_distros = set(BuildableDistroSeries.findSeries(
            archive.owner))
        return len(set(self.distroseries).difference(buildable_distros)) >= 1

    def requestBuild(self,
                     archive,
                     requester,
                     distroseries,
                     pocket=PackagePublishingPocket.RELEASE,
                     manual=False):
        """See `ISourcePackageRecipe`."""
        if not archive.is_ppa:
            raise NonPPABuildRequest

        buildable_distros = BuildableDistroSeries.findSeries(archive.owner)
        if distroseries not in buildable_distros:
            raise BuildNotAllowedForDistro(self, distroseries)

        reject_reason = archive.checkUpload(requester, distroseries, None,
                                            archive.default_component, pocket)
        if reject_reason is not None:
            raise reject_reason
        if self.isOverQuota(requester, distroseries):
            raise TooManyBuilds(self, distroseries)
        pending = IStore(self).find(
            SourcePackageRecipeBuild,
            SourcePackageRecipeBuild.recipe_id == self.id,
            SourcePackageRecipeBuild.distroseries_id == distroseries.id,
            SourcePackageRecipeBuild.archive_id == archive.id,
            SourcePackageRecipeBuild.status == BuildStatus.NEEDSBUILD)
        if pending.any() is not None:
            raise BuildAlreadyPending(self, distroseries)

        build = getUtility(ISourcePackageRecipeBuildSource).new(
            distroseries, self, requester, archive)
        build.queueBuild()
        queue_record = build.buildqueue_record
        if manual:
            queue_record.manualScore(queue_record.lastscore + 100)
        return build

    def performDailyBuild(self):
        """See `ISourcePackageRecipe`."""
        builds = []
        self.is_stale = False
        buildable_distros = set(
            BuildableDistroSeries.findSeries(self.daily_build_archive.owner))
        build_for = set(self.distroseries).intersection(buildable_distros)
        for distroseries in build_for:
            try:
                build = self.requestBuild(self.daily_build_archive, self.owner,
                                          distroseries,
                                          PackagePublishingPocket.RELEASE)
                builds.append(build)
            except BuildAlreadyPending:
                continue
        return builds

    @property
    def builds(self):
        """See `ISourcePackageRecipe`."""
        order_by = (Desc(
            Greatest(SourcePackageRecipeBuild.date_started,
                     SourcePackageRecipeBuild.date_finished)),
                    Desc(SourcePackageRecipeBuild.date_created),
                    Desc(SourcePackageRecipeBuild.id))
        return self._getBuilds(None, order_by)

    @property
    def completed_builds(self):
        """See `ISourcePackageRecipe`."""
        filter_term = (SourcePackageRecipeBuild.status !=
                       BuildStatus.NEEDSBUILD)
        order_by = (Desc(
            Greatest(SourcePackageRecipeBuild.date_started,
                     SourcePackageRecipeBuild.date_finished)),
                    Desc(SourcePackageRecipeBuild.id))
        return self._getBuilds(filter_term, order_by)

    @property
    def pending_builds(self):
        """See `ISourcePackageRecipe`."""
        filter_term = (
            SourcePackageRecipeBuild.status == BuildStatus.NEEDSBUILD)
        # We want to order by date_created but this is the same as ordering
        # by id (since id increases monotonically) and is less expensive.
        order_by = Desc(SourcePackageRecipeBuild.id)
        return self._getBuilds(filter_term, order_by)

    def _getBuilds(self, filter_term, order_by):
        """The actual query to get the builds."""
        query_args = [
            SourcePackageRecipeBuild.recipe == self,
            SourcePackageRecipeBuild.archive_id == Archive.id,
            Archive._enabled == True,
        ]
        if filter_term is not None:
            query_args.append(filter_term)
        result = Store.of(self).find(SourcePackageRecipeBuild, *query_args)
        result.order_by(order_by)
        return result

    def getPendingBuildInfo(self):
        """See `ISourcePackageRecipe`."""
        builds = self.pending_builds
        result = []
        for build in builds:
            result.append({
                "distroseries":
                build.distroseries.displayname,
                "archive":
                '%s/%s' % (build.archive.owner.name, build.archive.name)
            })
        return result

    @property
    def last_build(self):
        """See `ISourcePackageRecipeBuild`."""
        return self._getBuilds(
            True, Desc(SourcePackageRecipeBuild.date_finished)).first()

    def getMedianBuildDuration(self):
        """Return the median duration of builds of this recipe."""
        store = IStore(self)
        result = store.find(SourcePackageRecipeBuild,
                            SourcePackageRecipeBuild.recipe == self.id,
                            SourcePackageRecipeBuild.date_finished != None)
        durations = [
            build.date_finished - build.date_started for build in result
        ]
        if len(durations) == 0:
            return None
        durations.sort(reverse=True)
        return durations[len(durations) / 2]
Esempio n. 14
0

class FieldAnswerGroupFieldAnswer(BaseModel):
    """
    Class used to implement references between FieldAnswerGroup and FieldAnswer
    """
    __storm_table__ = 'fieldanswergroup_fieldanswer'
    __storm_primary__ = 'fieldanswergroup_id', 'fieldanswer_id'

    fieldanswergroup_id = Unicode()
    fieldanswer_id = Unicode()


Field.template = Reference(Field.template_id, Field.id)

Field.options = ReferenceSet(Field.id, FieldOption.field_id)

Field.children = ReferenceSet(Field.id, FieldField.parent_id,
                              FieldField.child_id, Field.id)

Field.attrs = ReferenceSet(Field.id, FieldAttr.field_id)

Field.activated_by = ReferenceSet(Field.id, OptionActivateField.field_id,
                                  OptionActivateField.field_option_id,
                                  FieldOption.id)

FieldOption.field = Reference(FieldOption.field_id, Field.id)

FieldOption.activated_fields = ReferenceSet(
    FieldOption.id, OptionActivateField.field_option_id,
    OptionActivateField.field_id, Field.id)
Esempio n. 15
0
class IcepapDriver(Storm):
    __storm_table__ = "icepapdriver"
    __storm_primary__ = ("icepapsystem_name", "addr")
    icepapsystem_name = Unicode()
    addr = Int()
    name = Unicode()
    mode = Unicode()
    """ references """
    icepap_system = Reference(icepapsystem_name, "IcepapSystem.name")
    historic_cfgs = ReferenceSet(
        (icepapsystem_name, addr),
        ("IcepapDriverCfg.icepapsystem_name", "IcepapDriverCfg.driver_addr"))

    log = logging.getLogger('{}.IcepapDriver'.format(__name__))

    @loggingInfo
    def __init__(self, icepap_name, addr):
        self.icepapsystem_name = str(icepap_name)
        self.addr = addr
        self.current_cfg = None
        self.initialize()

    @loggingInfo
    def __storm_loaded__(self):
        self.current_cfg = self.historic_cfgs.order_by("date").last()
        self.initialize()

    @loggingInfo
    def initialize(self):
        self.drivernr = self.addr % 10
        self.cratenr = self.addr // 10
        self._undo_list = []
        self.startup_cfg = self.current_cfg
        self.conflict = Conflict.NO_CONFLICT

    @loggingInfo
    def addConfiguration(self, cfg, current=True):
        if current:
            if self.current_cfg is not None:
                self._undo_list.append(self.current_cfg)
            else:
                self.startup_cfg = cfg
            self.current_cfg = cfg
            cfg.setDriver(self)
        self.historic_cfgs.add(cfg)

    @loggingInfo
    def setConflict(self, conflict):
        self.conflict = conflict

    @loggingInfo
    def getName(self):
        return self.name

    @loggingInfo
    def setName(self, name):
        self.name = str(name)

    @loggingInfo
    def setMode(self, mode):
        self.mode = str(mode)

    @loggingInfo
    def signDriver(self):
        # AS ESRF SAYS, WHEN SIGNING THE DRIVER CONFIG, THE COMMIT SHOULD
        # BE DONE IN THE DATABASE FIRST, AND IF NO ERRORS, THEN COMMUNICATE
        # THE DRIVER THAT THE VALUES SHOULD BE SIGNED.
        try:
            user = ConfigManager().username
            host = socket.gethostname()
            signature = user + "@" + host + "_" + \
                datetime.now().strftime('%Y/%m/%d_%H:%M:%S')
            IcepapsManager().signDriverConfiguration(self.icepapsystem_name,
                                                     self.addr, signature)
            self.mode = str(Mode.OPER)
            db = StormManager()
            db.commitTransaction()
            self.current_cfg.name = str(time.ctime())
            self.current_cfg.setSignature(signature)
            self.startup_cfg = self.current_cfg
            self.conflict = Conflict.NO_CONFLICT
        except Exception as e:
            self.log.error("some exception while trying to sign the driver %s",
                           e)

    @loggingInfo
    def setStartupCfg(self):
        self.current_cfg = self.startup_cfg
        self.conflict = Conflict.NO_CONFLICT

    @loggingInfo
    def undo(self, config):
        self.addConfiguration(config)
        # THE CURRENT CONFIGURATION SHOULD NOT BE IN THE UNDO LIST
        return self._undo_list.pop()

    @loggingInfo
    def getUndoList(self):
        return self._undo_list.pop()

    @loggingInfo
    def hasUndoList(self):
        return len(self._undo_list) > 0

    @loggingInfo
    def saveHistoricCfg(self, now, name, desc):
        self.current_cfg.name = str(name)
        self.current_cfg.description = str(desc)

    @loggingInfo
    def deleteHistoricCfg(self, cfg):
        self.historic_cfgs.remove(cfg)

    @loggingInfo
    def __ne__(self, other):
        return not self.__eq__(other)

    @loggingInfo
    def __eq__(self, other):
        if self.current_cfg == other.current_cfg:
            self.setConflict(Conflict.NO_CONFLICT)
            return True

        self.setConflict(Conflict.DRIVER_CHANGED)

        return False

    # TO SORT THE ICEPAP DRIVERS IN THE TREE
    @loggingInfo
    def __lt__(self, other):
        if isinstance(other, IcepapDriver):
            return self.addr < other.addr
Esempio n. 16
0
    def epilogue(self):
        self.fail_on_count_mismatch['Step'] = False
        self.fail_on_count_mismatch['Field'] = False
        self.fail_on_count_mismatch['FieldOption'] = False
        self.fail_on_count_mismatch['FieldAttr'] = False

        # Add the required references
        Context_v_29.steps = ReferenceSet(Context_v_29.id,
                                          Step_v_29.context_id)
        Step_v_29.children = ReferenceSet(Step_v_29.id,
                                          self.model_from['Field'].step_id)

        default_questionnaire_id = db_get_default_questionnaire_id(
            self.store_new)
        default_language = self.store_old.find(
            self.model_from['Node']).one().default_language

        old_contexts = self.store_old.find(self.model_from['Context'])
        for old_context in old_contexts:
            map_on_default = False
            new_questionnaire_id = None

            for old_step in old_context.steps:
                if old_step.children.count() != 4:
                    break

                for field in old_step.children:
                    if 'en' in field.label and field.label[
                            'en'] == 'Short title':
                        map_on_default = True
                        break

                if map_on_default:
                    break

            if not map_on_default:
                new_questionnaire = self.model_to['Questionnaire']()
                new_questionnaire.name = old_context.name[
                    default_language] if default_language in old_context.name else ''
                new_questionnaire.layout = old_context.questionnaire_layout
                new_questionnaire.show_steps_navigation_bar = old_context.show_steps_navigation_bar
                new_questionnaire.steps_navigation_requires_completion = old_context.steps_navigation_requires_completion
                new_questionnaire.enable_whistleblower_identity = old_context.enable_whistleblower_identity
                self.store_new.add(new_questionnaire)
                new_questionnaire_id = new_questionnaire.id

                for old_step in old_context.steps:
                    new_step = self.model_to['Step']()
                    for _, v in new_step._storm_columns.iteritems():
                        if v.name == 'questionnaire_id':
                            new_step.questionnaire_id = new_questionnaire.id
                            continue

                        setattr(new_step, v.name, getattr(old_step, v.name))

                    self.store_new.add(new_step)

            new_context = self.model_to['Context']()
            for _, v in new_context._storm_columns.iteritems():
                if v.name == 'status_page_message':
                    new_context.status_page_message = ''
                    continue

                if v.name == 'questionnaire_id':
                    new_context.questionnaire_id = default_questionnaire_id if new_questionnaire_id is None else new_questionnaire_id
                    continue

                setattr(new_context, v.name, getattr(old_context, v.name))

            self.store_new.add(new_context)
Esempio n. 17
0
class BugTrackerComponentGroup(StormBase):
    """A collection of components in a remote bug tracker.

    Some bug trackers organize sets of components into higher level
    groups, such as Bugzilla's 'product'.
    """
    implements(IBugTrackerComponentGroup)
    __storm_table__ = 'BugTrackerComponentGroup'

    id = Int(primary=True)
    name = Unicode(allow_none=False)
    bug_tracker_id = Int('bug_tracker')
    bug_tracker = Reference(bug_tracker_id, 'BugTracker.id')
    components = ReferenceSet(id,
                              BugTrackerComponent.component_group_id,
                              order_by=BugTrackerComponent.name)

    def addComponent(self, component_name):
        """Adds a component that is synced from a remote bug tracker"""

        component = BugTrackerComponent()
        component.name = component_name
        component.component_group = self

        store = IStore(BugTrackerComponent)
        store.add(component)
        store.flush()

        return component

    def getComponent(self, component_name):
        """Retrieves a component by the given name or id number.

        None is returned if there is no component by that name in the
        group.
        """

        if component_name is None:
            return None
        elif component_name.isdigit():
            component_id = int(component_name)
            return Store.of(self).find(
                BugTrackerComponent, BugTrackerComponent.id == component_id,
                BugTrackerComponent.component_group == self.id).one()
        else:
            return Store.of(self).find(
                BugTrackerComponent,
                BugTrackerComponent.name == component_name,
                BugTrackerComponent.component_group == self.id).one()

    def addCustomComponent(self, component_name):
        """Adds a component locally that isn't synced from a remote tracker
        """

        component = BugTrackerComponent()
        component.name = component_name
        component.component_group = self
        component.is_custom = True

        store = IStore(BugTrackerComponent)
        store.add(component)
        store.flush()

        return component
Esempio n. 18
0
class IcepapSystem(Storm):
    __storm_table__ = "icepapsystem"
    name = Unicode(primary=True)
    host = Unicode()
    port = Int()
    description = Unicode()
    version = Unicode()
    location_name = Unicode()
    """ references """
    drivers = ReferenceSet(name, "IcepapDriver.icepapsystem_name")
    location = ReferenceSet(location_name, "Location.name")
    log = logging.getLogger('{}.IcepapSystem'.format(__name__))

    @loggingInfo
    def __init__(self, name, host, port, location_name, description=None):
        self.name = str(name)
        if description is None:
            description = str("")
        self.description = str(description)
        self.location_name = location_name
        self.host = str(host)
        self.port = int(port)
        self.initialize()

    @loggingInfo
    def __storm_loaded__(self):
        self.initialize()

    @loggingInfo
    def loadDriversfromDB(self):
        for driver in self.drivers:
            self._inmemory_drivers[driver.addr] = driver

    @loggingInfo
    def initialize(self):
        self._inmemory_drivers = {}
        self.conflict = Conflict.NO_CONFLICT
        self.child_conflicts = 0

    @loggingInfo
    def getDriver(self, addr, in_memory=True):
        if in_memory:
            if addr in self._inmemory_drivers:
                return self._inmemory_drivers[addr]
            else:
                return None
        else:
            return self.drivers.find(IcepapDriver.addr == addr).one()

    @loggingInfo
    def getDrivers(self, in_memory=True):
        if in_memory:
            if len(self._inmemory_drivers) == 0:
                self.loadDriversfromDB()
            return list(self._inmemory_drivers.values())
        else:
            return self.drivers

    @loggingInfo
    def addDriver(self, driver):
        self.drivers.add(driver)
        self._inmemory_drivers[driver.addr] = driver

    @loggingInfo
    def addDriverList(self, driver_list):
        for driver in list(driver_list.values()):
            self.addDriver(driver)

    @loggingInfo
    def removeDriver(self, addr):
        driver = self.drivers.find(IcepapDriver.addr == addr).one()
        StormManager().deleteDriver(driver)
        del self._inmemory_drivers[addr]

    @loggingInfo
    def setConflict(self, conflict):
        self.conflict = conflict

    @loggingInfo
    def signSystem(self):
        for driver in self.getDrivers():
            driver.signDriver()

    @loggingInfo
    def signCrate(self, cratenr):
        min_addr = cratenr * 10
        max_addr = (cratenr + 1) * 10
        for driver in self.drivers.find(IcepapDriver.addr > min_addr,
                                        IcepapDriver.addr < max_addr):
            driver.signDriver()

    @loggingInfo
    def compareDriverList(self, driver_list):
        self.child_conflicts = 0
        conflictsList = []
        self.conflict = Conflict.NO_CONFLICT
        ''' comparing drivers '''
        for driver in self.drivers:
            addr = driver.addr
            if addr not in driver_list:
                conflictsList.append([Conflict.DRIVER_NOT_PRESENT, self, addr])
                self.child_conflicts += 1
            else:
                driver_cmp = driver_list[addr]
                if driver != driver_cmp:

                    # HOOK TO CHECK AUTO-SOLVE CONFLICTS
                    dsp_cfg = driver_cmp.current_cfg
                    db_cfg = driver.current_cfg
                    conflict = self.checkAutoSolvedConflict(dsp_cfg, db_cfg)
                    conflictsList.append([conflict, self, addr])
                    self.child_conflicts += 1

        # checking for new drivers
        for addr, driver in list(driver_list.items()):
            if self.drivers.find(IcepapDriver.addr == addr).count() == 0:
                self.addDriver(driver)
                # determine if it is a new driver or if it has been moved
                # ALWAYS TREAT AS NEW DRIVER, 'MOVED' HAS NO SENSE
                conflictsList.append([Conflict.NEW_DRIVER, self, addr])

        return conflictsList

    def _auto_solved_conflict(self,
                              dsp_cfg,
                              db_cfg,
                              skip_params=[],
                              check_db_values=None,
                              check_dsp_values=None):
        dsp_values = dsp_cfg.toList()
        db_values = db_cfg.toList()
        diff_values = set(dsp_values).difference(db_values)

        # Force to update the DB when the following parameter change. The DSP
        # always is right: VER, IPAPNAME and ID

        if 'VER' not in skip_params:
            skip_params.append('VER')

        if 'IPAPNAME' not in skip_params:
            skip_params.append('IPAPNAME')

        # ID previous IcepapCMS version (2.0.2) the DB only saves the ?ID HW,
        # now the icepap library returns ('?ID HW', '?ID SN')

        if 'ID' not in skip_params:
            skip_params.append('ID')

        # Check skip params
        for p, _ in diff_values:
            if p not in skip_params:
                return Conflict.DRIVER_CHANGED

        # Check DB values
        if check_db_values:
            for p, v in db_values:
                if p in check_db_values:
                    if v not in check_db_values[p]:
                        return Conflict.DRIVER_CHANGED

        # Check DSP values
        if check_dsp_values:
            for p, v in dsp_values:
                if p in check_dsp_values:
                    if v not in check_dsp_values[p]:
                        return Conflict.DRIVER_CHANGED

        return Conflict.DRIVER_AUTOSOLVE_EXPERT

    @loggingInfo
    def checkAutoSolvedConflict(self, dsp_cfg, db_cfg):
        # 20130710 ESRF ASKED FOR A HOOK TO 'SKIP' SOME CONFLICTS
        # ISSUE 053 in WIKI MINUTES
        # http://wikiserv.esrf.fr/esl/index.php/IcePAP_minute_130708
        #
        # TWO NEW CONFLICT TYPES ADDED: DRIVER_AUTOSOLVE,
        # DRIVER_AUTOSOLVE_EXPERT
        # Since there is the possibility to keep current behaviour,
        # the method can return also DRIVER_CHANGED

        # NOTE: u'VER' and u'IPAPNAME' are also available to resolve
        # conflicts...

        # NOTE: configs have the .getParameter(par) method
        #       BUT dsp values are not stored in the database, so in_memory
        #       has to be set to True
        # ## par = u'VER'
        # ## print 'dsp', par, dsp_cfg.getParameter(par, in_memory=True)
        # ## print 'db', par, db_cfg.getParameter(par)

        # NOTE: it is also possible to operate with lists:
        # ##dsp_values = dsp_cfg.toList()
        # ##db_values = db_cfg.toList()
        # ##for p,v in dsp_values:
        # ##    if p == par:
        # ##        print 'dsp', p, v
        # ##for p,v in db_values:
        # ##    if p == par:
        # ##        print 'db', p, v

        try:
            dsp_cfg_ver = float(
                dsp_cfg.getParameter(str("VER"), in_memory=True))
        except Exception:
            self.log.error("%s: missing VERsion parameter in DSP config",
                           self.name)
            return Conflict.DRIVER_CHANGED

        try:
            db_cfg_ver = float(db_cfg.getParameter(str("VER")))
        except Exception:
            self.log.error("%s: missing VERsion parameter in database config",
                           self.name)
            return Conflict.DRIVER_CHANGED

        check_db_values = None

        if dsp_cfg_ver == 2.0 and 1.22 <= db_cfg_ver < 2.0:

            skip_params = [
                'EXTDISABLE', 'PCLMODE', 'EXTBUSY', 'POSUPDATE', 'LNKNAME',
                'EXTPOWER', 'OUTPSRC'
            ]

        elif 3.14 < dsp_cfg_ver <= 3.17 and 2.0 <= db_cfg_ver <= 3.14:

            skip_params = [
                'HOLDTIME', 'EXTHOLD', 'INFOASRC', 'INFOBSRC', 'INFOCSRC'
            ]

        elif dsp_cfg_ver == 3.35 and db_cfg_ver == 3.14:
            # ignore new parameters or parameters that normally change
            # ['VER', 'HOLDTIME', 'EXTHOLD']:
            # parameters which value is not backward compatible
            # ['INFOASRC', 'INFOBSRC', 'INFOCSRC']:

            skip_params = [
                'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL', 'SSIEWPOL',
                'SSIOVF', 'HOLDTIME', 'EXTHOLD', 'INFOASRC', 'INFOBSRC',
                'INFOCSRC'
            ]

        elif (dsp_cfg_ver == 3.35) and (db_cfg_ver == 3.15):
            # ignore new parameters or parameters that normally change
            # [ 'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL', 'SSIEWPOL',
            # 'SSIOVF', 'HOLDTIME', 'EXTHOLD']
            # parameters which value is not backward compatible
            # ['CATENTRY', 'ABSMODE', 'INFOASRC', 'INFOBSRC', 'INFOCSRC']

            skip_params = [
                'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL', 'SSIEWPOL',
                'SSIOVF', 'HOLDTIME', 'EXTHOLD', 'INFOASRC', 'INFOBSRC',
                'INFOCSRC'
            ]

            check_db_values = {'ABSMODE': ['SSI']}

        elif dsp_cfg_ver == 3.35 and db_cfg_ver in [3.17, 3.182, 3.185, 3.187]:
            # ignore new parameters or parameters that normally change
            # ['VER', 'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL',
            # 'SSIEWPOL', 'SSIOVF']

            skip_params = [
                'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL', 'SSIEWPOL',
                'SSIOVF'
            ]

            return self._auto_solved_conflict(dsp_cfg, db_cfg, skip_params)

        elif dsp_cfg_ver == 3.35 and db_cfg_ver in [
                3.184, 3.192, 3.193, 3.195
        ]:
            # ignore new parameters or parameters that normally change
            # ['VER','SSISTRTB','SSILDC','SSIMSKNB','SSIEEPOL', 'SSIEWPOL',
            # 'SSIOVF']
            # parameters which value is not backward compatible
            # ['CATENTRY','ABSMODE','SSIALDC','SSIMSKMSB',
            # 'SSIEECHK','SSIEEPOS','SSIEWCHK', 'SSIEWPOS','SSISIGNED']

            skip_params = [
                'SSISTRTB', 'SSILDC', 'SSIMSKNB', 'SSIEEPOL', 'SSIEWPOL',
                'SSIOVF', 'SSIALDC', 'SSIMSKMSB', 'SSIEECHK', 'SSIEEPOS',
                'SSIEWCHK', 'SSIEWPOS', 'SSISIGNED'
            ]

            check_db_values = {'ABSMODE': ['SSI']}

        elif dsp_cfg_ver == 3.35 and \
                db_cfg_ver in [3.23, 3.25, 3.29, 3.31, 3.33]:
            # ignore new parameters or parameters that normally change
            # ['VER', 'SSIOVF']
            skip_params = ['SSIOVF']
        else:
            skip_params = []

        return self._auto_solved_conflict(dsp_cfg, db_cfg, skip_params,
                                          check_db_values)
Esempio n. 19
0

class Stats(Model):
    """
    Stats collection!
    """
    __storm_table__ = 'stats'

    content = Pickle()


#_*_# References tracking below #_*_#
Receiver.user = Reference(Receiver.user_id, User.id)

Receiver.internaltips = ReferenceSet(Receiver.id,
                                     ReceiverInternalTip.receiver_id,
                                     ReceiverInternalTip.internaltip_id,
                                     InternalTip.id)

InternalTip.receivers = ReferenceSet(InternalTip.id,
                                     ReceiverInternalTip.internaltip_id,
                                     ReceiverInternalTip.receiver_id,
                                     Receiver.id)

InternalTip.context = Reference(InternalTip.context_id, Context.id)

InternalTip.comments = ReferenceSet(InternalTip.id, Comment.internaltip_id)

InternalTip.receivertips = ReferenceSet(InternalTip.id,
                                        ReceiverTip.internaltip_id)

InternalTip.internalfiles = ReferenceSet(InternalTip.id,
Esempio n. 20
0
class Thread(Storm):
    """
    A thread of archived email, from a mailing-list. It is identified by both
    the list name and the thread id.
    """

    __storm_table__ = "thread"
    __storm_primary__ = "list_name", "thread_id"

    list_name = Unicode()
    thread_id = Unicode()
    date_active = DateTime()
    category_id = Int()
    emails = ReferenceSet((list_name, thread_id),
                          (Email.list_name, Email.thread_id),
                          order_by=Email.date)
    emails_by_reply = ReferenceSet((list_name, thread_id),
                                   (Email.list_name, Email.thread_id),
                                   order_by=Email.thread_order)
    category_obj = Reference(category_id, "Category.id")
    _starting_email = None

    def __init__(self, list_name, thread_id, date_active=None):
        self.list_name = unicode(list_name)
        self.thread_id = unicode(thread_id)
        self.date_active = date_active

    @property
    def _starting_email_req(self):
        """ Returns the request to get the starting email.
        If there are no results with in_reply_to IS NULL, then it's
        probably a partial import and we don't have the real first email.
        In this case, use the date.
        """
        return self.emails.order_by(Email.in_reply_to != None, Email.date)

    @property
    def starting_email(self):
        """Return (and cache) the email starting this thread"""
        if self._starting_email is None:
            self._starting_email = self._starting_email_req.first()
        return self._starting_email

    @property
    def last_email(self):
        return self.emails.order_by(Desc(Email.date)).first()

    @property
    def subject(self):
        """Return the subject of this thread"""
        if self._starting_email is not None:
            return self.starting_email.subject
        else:
            # Don't get the whole message if it's not cached yet (useful for
            # HyperKitty's thread view).
            return self._starting_email_req.values(Email.subject).next()

    @property
    def participants(self):
        """Set of email senders in this thread"""
        p = []
        for sender in self.emails.find().config(
                distinct=True).order_by().values(Email.sender_name,
                                                 Email.sender_email):
            p.append(sender)
        return p

    @property
    def email_ids(self):
        return list(self.emails.find().order_by().values(Email.message_id))

    @property
    def email_id_hashes(self):
        return list(self.emails.find().order_by().values(
            Email.message_id_hash))

    def __len__(self):
        return self.emails.count()

    def replies_after(self, date):
        return self.emails.find(Email.date > date)

    def _get_category(self):
        if not self.category_id:
            return None
        return self.category_obj.name

    def _set_category(self, name):
        if not name:
            self.category_id = None
            return
        store = Store.of(self)
        category = store.find(Category, Category.name == name).one()
        if category is None:
            category = Category(name)
            store.add(category)
            store.flush()
        self.category_id = category.id

    category = property(_get_category, _set_category)

    def __storm_pre_flush__(self):
        """Auto-set the active date from the last email in thread"""
        if self.date_active is not None:
            return
        email_dates = list(
            self.emails.order_by(Desc(Email.date)).config(limit=1).values(
                Email.date))
        if email_dates:
            self.date_active = email_dates[0]
        else:
            self.date_active = datetime.datetime.now()
class SourcePackageRecipeData(Storm):
    """The database representation of a BaseRecipeBranch from bzr-builder.

    This is referenced from the SourcePackageRecipe table as the 'recipe_data'
    column and from the SourcePackageRecipeBuild table as the 'manifest'
    column.
    """

    __storm_table__ = "SourcePackageRecipeData"

    id = Int(primary=True)

    base_branch_id = Int(name='base_branch', allow_none=True)
    base_branch = Reference(base_branch_id, 'Branch.id')
    base_git_repository_id = Int(name='base_git_repository', allow_none=True)
    base_git_repository = Reference(base_git_repository_id, 'GitRepository.id')

    @property
    def base(self):
        if self.base_branch is not None:
            return self.base_branch
        else:
            assert self.base_git_repository is not None
            return self.base_git_repository

    @base.setter
    def base(self, value):
        if IGitRepository.providedBy(value):
            self.base_git_repository = value
            self.base_branch = None
        elif IBranch.providedBy(value):
            self.base_branch = value
            self.base_git_repository = None
        else:
            raise AssertionError("Unsupported base: %r" % (value, ))

    recipe_format = Unicode(allow_none=False)
    deb_version_template = Unicode(allow_none=True)
    revspec = Unicode(allow_none=True)

    instructions = ReferenceSet(
        id,
        _SourcePackageRecipeDataInstruction.recipe_data_id,
        order_by=_SourcePackageRecipeDataInstruction.line_number)

    sourcepackage_recipe_id = Int(name='sourcepackage_recipe', allow_none=True)
    sourcepackage_recipe = Reference(sourcepackage_recipe_id,
                                     'SourcePackageRecipe.id')

    sourcepackage_recipe_build_id = Int(name='sourcepackage_recipe_build',
                                        allow_none=True)
    sourcepackage_recipe_build = Reference(sourcepackage_recipe_build_id,
                                           'SourcePackageRecipeBuild.id')

    @staticmethod
    def getParsedRecipe(recipe_text):
        """See `IRecipeBranchSource`."""
        # We're using bzr-builder to parse the recipe text.  While the
        # formats are mostly compatible, the header line must say
        # "bzr-builder" even though git-build-recipe also supports its own
        # name there.
        recipe_text, git_substitutions = re.subn(r"^(#\s*)git-build-recipe",
                                                 r"\1bzr-builder", recipe_text)
        recipe_branch_type = (RecipeBranchType.GIT
                              if git_substitutions else RecipeBranchType.BZR)
        parser = RecipeParser(recipe_text)
        recipe_branch = parser.parse(permitted_instructions=SAFE_INSTRUCTIONS)
        return recipe_branch, recipe_branch_type

    @staticmethod
    def findRecipes(branch_or_repository, revspecs=None):
        """Find recipes for a given branch or repository.

        :param branch_or_repository: The branch or repository to search for.
        :param revspecs: If not None, return only recipes whose `revspec` is
            in this sequence.
        :return: a collection of `ISourcePackageRecipe`s.
        """
        from lp.code.model.sourcepackagerecipe import SourcePackageRecipe
        store = Store.of(branch_or_repository)
        if IGitRepository.providedBy(branch_or_repository):
            data_clause = (SourcePackageRecipeData.base_git_repository ==
                           branch_or_repository)
            insn_clause = (_SourcePackageRecipeDataInstruction.git_repository
                           == branch_or_repository)
        elif IBranch.providedBy(branch_or_repository):
            data_clause = (
                SourcePackageRecipeData.base_branch == branch_or_repository)
            insn_clause = (_SourcePackageRecipeDataInstruction.branch ==
                           branch_or_repository)
        else:
            raise AssertionError("Unsupported source: %r" %
                                 (branch_or_repository, ))
        if revspecs is not None:
            concrete_revspecs = [
                revspec for revspec in revspecs if revspec is not None
            ]
            data_revspec_clause = In(SourcePackageRecipeData.revspec,
                                     concrete_revspecs)
            insn_revspec_clause = In(
                _SourcePackageRecipeDataInstruction.revspec, concrete_revspecs)
            if None in revspecs:
                data_revspec_clause = Or(
                    data_revspec_clause,
                    SourcePackageRecipeData.revspec == None)
                insn_revspec_clause = Or(
                    insn_revspec_clause,
                    _SourcePackageRecipeDataInstruction.revspec == None)
            data_clause = And(data_clause, data_revspec_clause)
            insn_clause = And(insn_clause, insn_revspec_clause)
        return store.find(
            SourcePackageRecipe,
            SourcePackageRecipe.id.is_in(
                Union(
                    Select(SourcePackageRecipeData.sourcepackage_recipe_id,
                           data_clause),
                    Select(
                        SourcePackageRecipeData.sourcepackage_recipe_id,
                        And(
                            _SourcePackageRecipeDataInstruction.recipe_data_id
                            == SourcePackageRecipeData.id, insn_clause)))))

    @classmethod
    def createManifestFromText(cls, text, sourcepackage_recipe_build):
        """See `ISourcePackageRecipeDataSource`."""
        parsed, recipe_branch_type = cls.getParsedRecipe(text)
        return cls(parsed,
                   recipe_branch_type,
                   sourcepackage_recipe_build=sourcepackage_recipe_build)

    def getRecipe(self):
        """The BaseRecipeBranch version of the recipe."""
        base_branch = BaseRecipeBranch(self.base.identity,
                                       self.deb_version_template,
                                       self.recipe_format, self.revspec)
        insn_stack = []
        for insn in self.instructions:
            while insn_stack and \
                      insn_stack[-1]['insn'] != insn.parent_instruction:
                insn_stack.pop()
            if insn_stack:
                target_branch = insn_stack[-1]['recipe_branch']
            else:
                target_branch = base_branch
            recipe_branch = insn.appendToRecipe(target_branch)
            insn_stack.append(dict(insn=insn, recipe_branch=recipe_branch))
        return base_branch

    def _scanInstructions(self, base, recipe_branch):
        """Check the recipe_branch doesn't use 'run' and look up the branches.

        We do all the lookups before we start constructing database objects to
        avoid flushing half-constructed objects to the database.

        :return: A map ``{branch_url: db_branch}``.
        """
        r = {}
        if IGitRepository.providedBy(base):
            lookup = getUtility(IGitLookup)
            missing_error = NoSuchGitRepository
            private_error = PrivateGitRepositoryRecipe
        else:
            lookup = getUtility(IBranchLookup)
            missing_error = NoSuchBranch
            private_error = PrivateBranchRecipe
        for instruction in recipe_branch.child_branches:
            db_branch = lookup.getByUrl(instruction.recipe_branch.url)
            if db_branch is None:
                raise missing_error(instruction.recipe_branch.url)
            if db_branch.private:
                raise private_error(db_branch)
            r[instruction.recipe_branch.url] = db_branch
            r.update(self._scanInstructions(base, instruction.recipe_branch))
        return r

    def _recordInstructions(self,
                            recipe_branch,
                            parent_insn,
                            branch_map,
                            line_number=0):
        """Build _SourcePackageRecipeDataInstructions for the recipe_branch.
        """
        for instruction in recipe_branch.child_branches:
            nest_path = instruction.nest_path
            source_directory = None
            if isinstance(instruction, MergeInstruction):
                type = InstructionType.MERGE
            elif isinstance(instruction, NestInstruction):
                type = InstructionType.NEST
            elif isinstance(instruction, NestPartInstruction):
                type = InstructionType.NEST_PART
                nest_path = instruction.target_subdir
                source_directory = instruction.subpath
            else:
                # Unsupported instructions should have been filtered out by
                # _scanInstructions; if we get surprised here, that's a bug.
                raise AssertionError("Unsupported instruction %r" %
                                     instruction)
            line_number += 1
            comment = None
            db_branch_or_repository = branch_map[instruction.recipe_branch.url]
            insn = _SourcePackageRecipeDataInstruction(
                instruction.recipe_branch.name, type, comment, line_number,
                db_branch_or_repository, instruction.recipe_branch.revspec,
                nest_path, self, parent_insn, source_directory)
            line_number = self._recordInstructions(instruction.recipe_branch,
                                                   insn, branch_map,
                                                   line_number)
        return line_number

    def setRecipe(self, builder_recipe, recipe_branch_type):
        """Convert the BaseRecipeBranch `builder_recipe` to the db form."""
        clear_property_cache(self)
        if builder_recipe.format > MAX_RECIPE_FORMAT:
            raise TooNewRecipeFormat(builder_recipe.format, MAX_RECIPE_FORMAT)
        if recipe_branch_type == RecipeBranchType.BZR:
            base = getUtility(IBranchLookup).getByUrl(builder_recipe.url)
            if base is None:
                raise NoSuchBranch(builder_recipe.url)
            elif base.private:
                raise PrivateBranchRecipe(base)
        elif recipe_branch_type == RecipeBranchType.GIT:
            base = getUtility(IGitLookup).getByUrl(builder_recipe.url)
            if base is None:
                raise NoSuchGitRepository(builder_recipe.url)
            elif base.private:
                raise PrivateGitRepositoryRecipe(base)
        else:
            raise AssertionError('Unknown recipe_branch_type: %r' %
                                 recipe_branch_type)
        branch_map = self._scanInstructions(base, builder_recipe)
        # If this object hasn't been added to a store yet, there can't be any
        # instructions linking to us yet.
        if Store.of(self) is not None:
            self.instructions.find().remove()
        if builder_recipe.revspec is not None:
            self.revspec = unicode(builder_recipe.revspec)
        else:
            self.revspec = None
        self._recordInstructions(builder_recipe,
                                 parent_insn=None,
                                 branch_map=branch_map)
        self.base = base
        if builder_recipe.deb_version is None:
            self.deb_version_template = None
        else:
            self.deb_version_template = unicode(builder_recipe.deb_version)
        self.recipe_format = unicode(builder_recipe.format)

    def __init__(self,
                 recipe,
                 recipe_branch_type,
                 sourcepackage_recipe=None,
                 sourcepackage_recipe_build=None):
        """Initialize from the bzr-builder recipe and link it to a db recipe.
        """
        super(SourcePackageRecipeData, self).__init__()
        self.setRecipe(recipe, recipe_branch_type)
        self.sourcepackage_recipe = sourcepackage_recipe
        self.sourcepackage_recipe_build = sourcepackage_recipe_build

    @staticmethod
    def preLoadReferencedBranches(sourcepackagerecipedatas):
        # Circular imports.
        from lp.code.model.branchcollection import GenericBranchCollection
        from lp.code.model.gitcollection import GenericGitCollection
        # Load the related Branch, _SourcePackageRecipeDataInstruction.
        base_branches = load_related(Branch, sourcepackagerecipedatas,
                                     ['base_branch_id'])
        base_repositories = load_related(GitRepository,
                                         sourcepackagerecipedatas,
                                         ['base_git_repository_id'])
        sprd_instructions = load_referencing(
            _SourcePackageRecipeDataInstruction, sourcepackagerecipedatas,
            ['recipe_data_id'])
        sub_branches = load_related(Branch, sprd_instructions, ['branch_id'])
        sub_repositories = load_related(GitRepository, sprd_instructions,
                                        ['git_repository_id'])
        all_branches = base_branches + sub_branches
        all_repositories = base_repositories + sub_repositories
        # Pre-load branches'/repositories' data.
        if all_branches:
            GenericBranchCollection.preloadDataForBranches(all_branches)
        if all_repositories:
            GenericGitCollection.preloadDataForRepositories(all_repositories)
        # Store the pre-fetched objects on the sourcepackagerecipedatas
        # objects.
        branch_to_recipe_data = {
            instr.branch_id: instr.recipe_data_id
            for instr in sprd_instructions if instr.branch_id is not None
        }
        repository_to_recipe_data = {
            instr.git_repository_id: instr.recipe_data_id
            for instr in sprd_instructions
            if instr.git_repository_id is not None
        }
        caches = {
            sprd.id: [sprd, get_property_cache(sprd)]
            for sprd in sourcepackagerecipedatas
        }
        for _, [sprd, cache] in caches.items():
            cache._referenced_branches = [sprd.base]
        for branch in sub_branches:
            cache = caches[branch_to_recipe_data[branch.id]][1]
            cache._referenced_branches.append(branch)
        for repository in sub_repositories:
            cache = caches[repository_to_recipe_data[repository.id]][1]
            cache._referenced_branches.append(repository)

    def getReferencedBranches(self):
        """Return an iterator of the Branch/GitRepository objects referenced
        by this recipe.
        """
        return self._referenced_branches

    @cachedproperty
    def _referenced_branches(self):
        referenced_branches = [self.base]
        sub_branches = IStore(self).find(
            Branch, _SourcePackageRecipeDataInstruction.recipe_data == self,
            Branch.id == _SourcePackageRecipeDataInstruction.branch_id)
        referenced_branches.extend(sub_branches)
        sub_repositories = IStore(self).find(
            GitRepository,
            _SourcePackageRecipeDataInstruction.recipe_data == self,
            GitRepository.id ==
            _SourcePackageRecipeDataInstruction.git_repository_id)
        referenced_branches.extend(sub_repositories)
        return referenced_branches
Esempio n. 22
0
File: board.py Progetto: JANE-XU/wld
class Board(Storm):
    """
    I represent a category of discussion on the forums.

    @ivar created: Timestamp of my entry in the database
    @ivar name: Word or phrase that will be used to represent me on the website
    @ivar description: A brief explanation of what subject matter my Threads will contain 

    @ReferenceSet threads: A storm ReferenceSet object with all of my Threads
    @ReferenceSet perms: A storm ReferenceSet object with all permissions required for me to be viewed by a User
    """
    __storm_table__ = 'boards'
    id = Int(primary=True)
    created = DateTime(default=datetime.datetime.now())
    name = Unicode(validator=unicoder)
    description = Unicode(validator=unicoder)

    threads = ReferenceSet(id, "Thread.board_id")
    perms = ReferenceSet(id, "_LinkBoardPerms.board_id",
                         "_LinkBoardPerms.perm_id", "BoardPerms.id")

    def getJSON(self, extra=False):
        """
        Get a JSON representation of my attributes and other useful things

        @param extra: Determines if additional data from other classes will be added
        """
        return_json = {
            'id': self.id,
            'created': self.created.strftime('%Y-%m-%d %H:%M:%S'),
            'name': self.name,
            'description': self.description,
        }

        if extra:
            #Other useful things
            threads = self.threads
            thread_count = threads.count()

            messages_count = 0
            for thread in threads:
                messages = thread.messages.count()
                messages_count = messages_count + messages

            extra_data = {'topics': thread_count, 'messages': messages_count}

            return_json.update(extra_data)

        return return_json

    def addPermByName(self, perm_name):
        """
        Tie me to a BoardPerm by it's name.

        @param perm_name: The 'name' value of the BoardPerm to which I'll be joined.
        """
        store = getStore()
        perm = store.find(BoardPerm, BoardPerm.name == perm_name)
        self.perms.add(perm)

    def removePermByName(self, perm_name):
        """
        Remove my ties to a BoardPerm by it's name.

        @param perm_name: The 'name' value of the BoardPerm to which I'll no longer be tied
        """
        store = getStore()
        perm = store.find(BoardPerm, BoardPerm.name == perm_name)
        self.perms.remove(perm)

    def listPerms(self):
        """
        Return a list of names of BoardPerms to which I am tied
    
        @type return: A list of unicodes
        """
        perms = []
        for perm in self.perms:
            perms.append(perm.name)

        return perms
Esempio n. 23
0
class FieldAnswerGroup_v_29(ModelWithID):
    __storm_table__ = 'fieldanswergroup'
    number = Int(default=0)
    fieldanswer_id = Unicode()


class FieldAnswerGroupFieldAnswer_v_29(Model):
    __storm_table__ = 'fieldanswergroup_fieldanswer'
    __storm_primary__ = 'fieldanswergroup_id', 'fieldanswer_id'

    fieldanswergroup_id = Unicode()
    fieldanswer_id = Unicode()


FieldAnswerGroup_v_29.fieldanswers = ReferenceSet(
    FieldAnswerGroup_v_29.id,
    FieldAnswerGroupFieldAnswer_v_29.fieldanswergroup_id,
    FieldAnswerGroupFieldAnswer_v_29.fieldanswer_id, FieldAnswer_v_29.id)


class MigrationScript(MigrationBase):
    def prologue(self):
        appdata = load_appdata()

        steps = appdata['default_questionnaire']['steps']
        del appdata['default_questionnaire']['steps']

        questionnaire = db_forge_obj(self.store_new, Questionnaire,
                                     appdata['default_questionnaire'])

        for step in steps:
            f_children = step['children']
Esempio n. 24
0
    context_id = Unicode()
    receiver_id = Unicode()


class ReceiverInternalTip(BaseModel):
    """
    Class used to implement references between Receivers and IntInternalTips
    """
    __storm_table__ = 'receiver_internaltip'
    __storm_primary__ = 'receiver_id', 'internaltip_id'

    receiver_id = Unicode()
    internaltip_id = Unicode()


Field.options = ReferenceSet(Field.id, FieldOption.field_id)

FieldOption.field = Reference(FieldOption.field_id, Field.id)

Context.steps = ReferenceSet(Context.id, Step.context_id)

Step.context = Reference(Step.context_id, Context.id)

# _*_# References tracking below #_*_#
Receiver.user = Reference(Receiver.user_id, User.id)

Receiver.internaltips = ReferenceSet(Receiver.id,
                                     ReceiverInternalTip.receiver_id,
                                     ReceiverInternalTip.internaltip_id,
                                     InternalTip.id)
Esempio n. 25
0
    maximum_selectable_receivers = Int()
    select_all_receivers = Bool()
    enable_private_messages = Bool()
    tip_timetolive = Int()
    last_update = DateTime()
    name = JSON()
    description = JSON()
    receiver_introduction = JSON()
    can_postpone_expiration = Bool()
    can_delete_submission = Bool()
    show_receivers_in_alphabetical_order = Bool()
    presentation_order = Int()


Context_v_20.receivers = ReferenceSet(Context_v_20.id,
                                      ReceiverContext.context_id,
                                      ReceiverContext.receiver_id,
                                      Receiver_v_20.id)


class Step_v_20(Model):
    __storm_table__ = 'step'
    context_id = Unicode()
    label = JSON()
    description = JSON()
    hint = JSON()
    number = Int()


class Field_v_20(Model):
    __storm_table__ = 'field'
    label = JSON()
Esempio n. 26
0
class SourcePackageRecipeData(Storm):
    """The database representation of a BaseRecipeBranch from bzr-builder.

    This is referenced from the SourcePackageRecipe table as the 'recipe_data'
    column and from the SourcePackageRecipeBuild table as the 'manifest'
    column.
    """

    __storm_table__ = "SourcePackageRecipeData"

    id = Int(primary=True)

    base_branch_id = Int(name='base_branch', allow_none=False)
    base_branch = Reference(base_branch_id, 'Branch.id')

    recipe_format = Unicode(allow_none=False)
    deb_version_template = Unicode(allow_none=True)
    revspec = Unicode(allow_none=True)

    instructions = ReferenceSet(
        id, _SourcePackageRecipeDataInstruction.recipe_data_id,
        order_by=_SourcePackageRecipeDataInstruction.line_number)

    sourcepackage_recipe_id = Int(
        name='sourcepackage_recipe', allow_none=True)
    sourcepackage_recipe = Reference(
        sourcepackage_recipe_id, 'SourcePackageRecipe.id')

    sourcepackage_recipe_build_id = Int(
        name='sourcepackage_recipe_build', allow_none=True)
    sourcepackage_recipe_build = Reference(
        sourcepackage_recipe_build_id, 'SourcePackageRecipeBuild.id')

    @staticmethod
    def getParsedRecipe(recipe_text):
        parser = RecipeParser(recipe_text)
        return parser.parse(permitted_instructions=SAFE_INSTRUCTIONS)

    @staticmethod
    def findRecipes(branch):
        from lp.code.model.sourcepackagerecipe import SourcePackageRecipe
        store = Store.of(branch)
        return store.find(
            SourcePackageRecipe,
            SourcePackageRecipe.id.is_in(Union(
                Select(
                    SourcePackageRecipeData.sourcepackage_recipe_id,
                    SourcePackageRecipeData.base_branch == branch),
                Select(
                    SourcePackageRecipeData.sourcepackage_recipe_id,
                    And(
                        _SourcePackageRecipeDataInstruction.recipe_data_id ==
                        SourcePackageRecipeData.id,
                        _SourcePackageRecipeDataInstruction.branch == branch)
                    )
            ))
        )

    @classmethod
    def createManifestFromText(cls, text, sourcepackage_recipe_build):
        """Create a manifest for the specified build.

        :param text: The text of the recipe to create a manifest for.
        :param sourcepackage_recipe_build: The build to associate the manifest
            with.
        :return: an instance of SourcePackageRecipeData.
        """
        parsed = cls.getParsedRecipe(text)
        return cls(
            parsed, sourcepackage_recipe_build=sourcepackage_recipe_build)

    def getRecipe(self):
        """The BaseRecipeBranch version of the recipe."""
        base_branch = BaseRecipeBranch(
            self.base_branch.bzr_identity, self.deb_version_template,
            self.recipe_format, self.revspec)
        insn_stack = []
        for insn in self.instructions:
            while insn_stack and \
                      insn_stack[-1]['insn'] != insn.parent_instruction:
                insn_stack.pop()
            if insn_stack:
                target_branch = insn_stack[-1]['recipe_branch']
            else:
                target_branch = base_branch
            recipe_branch = insn.appendToRecipe(target_branch)
            insn_stack.append(
                dict(insn=insn, recipe_branch=recipe_branch))
        return base_branch

    def _scanInstructions(self, recipe_branch):
        """Check the recipe_branch doesn't use 'run' and look up the branches.

        We do all the lookups before we start constructing database objects to
        avoid flushing half-constructed objects to the database.

        :return: A map ``{branch_url: db_branch}``.
        """
        r = {}
        for instruction in recipe_branch.child_branches:
            db_branch = getUtility(IBranchLookup).getByUrl(
                instruction.recipe_branch.url)
            if db_branch is None:
                raise NoSuchBranch(instruction.recipe_branch.url)
            if db_branch.private:
                raise PrivateBranchRecipe(db_branch)
            r[instruction.recipe_branch.url] = db_branch
            r.update(self._scanInstructions(instruction.recipe_branch))
        return r

    def _recordInstructions(self, recipe_branch, parent_insn, branch_map,
                            line_number=0):
        """Build _SourcePackageRecipeDataInstructions for the recipe_branch.
        """
        for instruction in recipe_branch.child_branches:
            nest_path = instruction.nest_path
            source_directory = None
            if isinstance(instruction, MergeInstruction):
                type = InstructionType.MERGE
            elif isinstance(instruction, NestInstruction):
                type = InstructionType.NEST
            elif isinstance(instruction, NestPartInstruction):
                type = InstructionType.NEST_PART
                nest_path = instruction.target_subdir
                source_directory = instruction.subpath
            else:
                # Unsupported instructions should have been filtered out by
                # _scanInstructions; if we get surprised here, that's a bug.
                raise AssertionError(
                    "Unsupported instruction %r" % instruction)
            line_number += 1
            comment = None
            db_branch = branch_map[instruction.recipe_branch.url]
            insn = _SourcePackageRecipeDataInstruction(
                instruction.recipe_branch.name, type, comment,
                line_number, db_branch, instruction.recipe_branch.revspec,
                nest_path, self, parent_insn, source_directory)
            line_number = self._recordInstructions(
                instruction.recipe_branch, insn, branch_map, line_number)
        return line_number

    def setRecipe(self, builder_recipe):
        """Convert the BaseRecipeBranch `builder_recipe` to the db form."""
        clear_property_cache(self)
        if builder_recipe.format > MAX_RECIPE_FORMAT:
            raise TooNewRecipeFormat(builder_recipe.format, MAX_RECIPE_FORMAT)
        branch_map = self._scanInstructions(builder_recipe)
        # If this object hasn't been added to a store yet, there can't be any
        # instructions linking to us yet.
        if Store.of(self) is not None:
            self.instructions.find().remove()
        branch_lookup = getUtility(IBranchLookup)
        base_branch = branch_lookup.getByUrl(builder_recipe.url)
        if base_branch is None:
            raise NoSuchBranch(builder_recipe.url)
        if base_branch.private:
            raise PrivateBranchRecipe(base_branch)
        if builder_recipe.revspec is not None:
            self.revspec = unicode(builder_recipe.revspec)
        else:
            self.revspec = None
        self._recordInstructions(
            builder_recipe, parent_insn=None, branch_map=branch_map)
        self.base_branch = base_branch
        if builder_recipe.deb_version is None:
            self.deb_version_template = None
        else:
            self.deb_version_template = unicode(builder_recipe.deb_version)
        self.recipe_format = unicode(builder_recipe.format)

    def __init__(self, recipe, sourcepackage_recipe=None,
                 sourcepackage_recipe_build=None):
        """Initialize from the bzr-builder recipe and link it to a db recipe.
        """
        super(SourcePackageRecipeData, self).__init__()
        self.setRecipe(recipe)
        self.sourcepackage_recipe = sourcepackage_recipe
        self.sourcepackage_recipe_build = sourcepackage_recipe_build

    @staticmethod
    def preLoadReferencedBranches(sourcepackagerecipedatas):
        # Load the related Branch, _SourcePackageRecipeDataInstruction.
        load_related(
            Branch, sourcepackagerecipedatas, ['base_branch_id'])
        sprd_instructions = load_referencing(
            _SourcePackageRecipeDataInstruction,
            sourcepackagerecipedatas, ['recipe_data_id'])
        sub_branches = load_related(
            Branch, sprd_instructions, ['branch_id'])
        # Store the pre-fetched objects on the sourcepackagerecipedatas
        # objects.
        branch_to_recipe_data = dict([
            (instr.branch_id, instr.recipe_data_id)
                for instr in sprd_instructions])
        caches = dict((sprd.id, [sprd, get_property_cache(sprd)])
            for sprd in sourcepackagerecipedatas)
        for unused, [sprd, cache] in caches.items():
            cache._referenced_branches = [sprd.base_branch]
        for recipe_data_id, branches in groupby(
            sub_branches, lambda branch: branch_to_recipe_data[branch.id]):
            cache = caches[recipe_data_id][1]
            cache._referenced_branches.extend(list(branches))

    def getReferencedBranches(self):
        """Return an iterator of the Branch objects referenced by this recipe.
        """
        return self._referenced_branches

    @cachedproperty
    def _referenced_branches(self):
        referenced_branches = [self.base_branch]
        sub_branches = IStore(self).find(
            Branch,
            _SourcePackageRecipeDataInstruction.recipe_data == self,
            Branch.id == _SourcePackageRecipeDataInstruction.branch_id)
        referenced_branches.extend(sub_branches)
        return referenced_branches
Esempio n. 27
0
    """
    lang = Unicode(primary=True, validator=shorttext_v)
    texts = JSON()

    unicode_keys = ['lang']
    json_keys = ['texts']


Context.picture = Reference(Context.img_id, File.id)
User.picture = Reference(User.img_id, File.id)

Field.fieldgroup = Reference(Field.fieldgroup_id, Field.id)
Field.step = Reference(Field.step_id, Step.id)
Field.template = Reference(Field.template_id, Field.id)

Field.options = ReferenceSet(Field.id, FieldOption.field_id)

Field.children = ReferenceSet(Field.id, Field.fieldgroup_id)

Field.attrs = ReferenceSet(Field.id, FieldAttr.field_id)

Field.triggered_by_options = ReferenceSet(Field.id, FieldOption.trigger_field)
Step.triggered_by_options = ReferenceSet(Step.id, FieldOption.trigger_step)

FieldAnswer.groups = ReferenceSet(FieldAnswer.id,
                                  FieldAnswerGroup.fieldanswer_id)

FieldAnswerGroup.fieldanswers = ReferenceSet(FieldAnswerGroup.id,
                                             FieldAnswer.fieldanswergroup_id)

Step.children = ReferenceSet(Step.id, Field.step_id)
Esempio n. 28
0
    preview = Bool()
    stats_enabled = Bool()
    is_template = Bool()
    x = Int()
    y = Int()
    type = Unicode()


class FieldOption_v_22(Model):
    __storm_table__ = 'fieldoption'
    field_id = Unicode()
    presentation_order = Int()
    attrs = JSON()


Field_v_22.options = ReferenceSet(Field_v_22.id, FieldOption_v_22.field_id)


class InternalTip_v_22(Model):
    __storm_table__ = 'internaltip'
    creation_date = DateTime()
    context_id = Unicode()
    wb_steps = JSON()
    preview = JSON()
    progressive = Int()
    tor2web = Bool()
    expiration_date = DateTime()
    last_activity = DateTime()
    new = Int()