Esempio n. 1
0
class GroupWrapper(Fossilizable):
    """Group-like wrapper class that holds a DB-stored (or remote) group."""

    fossilizes(IGroupFossil)

    def __init__(self, group_id):
        self.id = to_unicode(group_id).encode('utf-8')

    @property
    def group(self):
        """Return the underlying GroupProxy.

        :rtype: indico.modules.groups.core.GroupProxy
        """
        raise NotImplementedError

    def getId(self):
        return self.id

    def getName(self):
        raise NotImplementedError

    def getEmail(self):
        return ''

    @return_ascii
    def __repr__(self):
        return u'<{} {}: {}>'.format(type(self).__name__, self.id, self.group)
Esempio n. 2
0
class TaskOccurrence(TimedEvent):
    """
    Wraps around a PeriodicTask object, and represents an occurrence of this task
    """

    fossilizes(ITaskOccurrenceFossil)

    def __init__(self, task):
        self._task = task
        self._startedOn = task.getStartedOn()
        self._endedOn = task.getEndedOn()
        self._id = None

    def getId(self):
        return self._id

    def getUniqueId(self):
        return "%s:%s" % (self._task.getUniqueId(), self._id)

    def setId(self, occId):
        self._id = occId

    def getStartedOn(self):
        return self._startedOn

    def getEndedOn(self):
        return self._endedOn

    def getTask(self):
        return self._task
Esempio n. 3
0
class Consumer(Persistent):
    fossilizes(IConsumerFossil)

    def __init__(self, key, secret, name, trusted=False, blocked=False):
        self._key = key
        self._secret = secret
        self._name = name
        self._trusted = trusted
        self._blocked = blocked

    def getId(self):
        return self._key

    def getSecret(self):
        return self._secret

    def getName(self):
        return self._name

    def isTrusted(self):
        return self._trusted

    def setTrusted(self, trusted):
        self._trusted = trusted

    def isBlocked(self):
        return self._blocked

    def setBlocked(self, blocked):
        self._blocked = blocked
Esempio n. 4
0
class HTTPAPIResult(Fossilizable):
    fossilizes(IHTTPAPIResultFossil)

    def __init__(self, results, path='', query='', ts=None, complete=True, extra=None):
        if ts is None:
            ts = int(time.time())
        self._results = results
        self._path = path
        self._query = query
        self._ts = ts
        self._complete = complete
        self._extra = extra or {}

    def getTS(self):
        return self._ts

    def getURL(self):
        prefix = config.BASE_URL
        if self._query:
            return prefix + self._path + '?' + self._query
        return prefix + self._path

    def getCount(self):
        return len(self._results)

    def getResults(self):
        return self._results

    def getComplete(self):
        return self._complete

    def getAdditionalInfo(self):
        return self._extra
Esempio n. 5
0
class AvatarProvisionalWrapper(Fossilizable):
    """
    Wraps provisional data for users that are not in the DB yet
    """

    fossilizes(IAvatarFossil, IAvatarMinimalFossil)

    def __init__(self, identity_info):
        self.identity_info = identity_info
        self.data = identity_info.data

    def getId(self):
        return u"{}:{}".format(self.identity_info.provider.name,
                               self.identity_info.identifier)

    id = property(getId)

    @encode_utf8
    def getEmail(self):
        return self.data['email']

    def getEmails(self):
        return [self.data['email']]

    @encode_utf8
    def getFirstName(self):
        return self.data['first_name']

    @encode_utf8
    def getFamilyName(self):
        return self.data['last_name']

    def getStraightFullName(self):
        return '{first_name} {last_name}'.format(**self.data.to_dict())

    def getTitle(self):
        return u''

    @encode_utf8
    def getTelephone(self):
        return self.data['phone']

    @encode_utf8
    def getOrganisation(self):
        return self.data['affiliation']

    def getFax(self):
        return None

    def getAddress(self):
        return u''

    @return_ascii
    def __repr__(self):
        return u'<AvatarProvisionalWrapper {}: {} ({first_name} {last_name})>'.format(
            self.identity_info.provider.name, self.identity_info.identifier,
            **self.data.to_dict())
Esempio n. 6
0
class EmailPrincipal(Fossilizable):
    """Wrapper for email principals

    :param email: The email address.
    """

    principal_type = PrincipalType.email
    is_network = False
    is_group = False
    is_single_person = True
    is_event_role = False
    is_category_role = False
    is_registration_form = False
    principal_order = 0
    fossilizes(IEmailPrincipalFossil)

    def __init__(self, email):
        self.email = email.lower()

    @property
    def name(self):
        return self.email

    @property
    def as_legacy(self):
        return self

    @property
    def user(self):
        from indico.modules.users import User
        return User.query.filter(~User.is_deleted,
                                 User.all_emails == self.email).first()

    @property
    def identifier(self):
        return 'Email:{}'.format(self.email)

    def __eq__(self, other):
        return isinstance(other, EmailPrincipal) and self.email == other.email

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.email)

    def __contains__(self, user):
        if not user:
            return False
        return self.email in user.all_emails

    @return_ascii
    def __repr__(self):
        return format_repr(self, 'email')
Esempio n. 7
0
class HTTPAPIError(Exception, Fossilizable):
    fossilizes(IHTTPAPIErrorFossil)

    def __init__(self, message, code=None):
        self.message = message
        self.code = code

    def getMessage(self):
        return self.message

    def getCode(self):
        return self.code
Esempio n. 8
0
class TaskOccurrence(TimedEvent):
    """
    Wraps around a PeriodicTask object, and represents an occurrence of this task
    """

    fossilizes(ITaskOccurrenceFossil)

    def __init__(self, task):
        self._task = task
        self._startedOn = task.getStartedOn()
        self._endedOn = task.getEndedOn()
        self._id = None

    def __cmp__(self, obj):
        if obj is None:
            return 1
        elif isinstance(obj, BaseTask):
            task_cmp = cmp(self.getTask(), obj)
            if task_cmp == 0:
                return 1
            else:
                return task_cmp
        elif not isinstance(obj, TaskOccurrence) or (self._id == obj._id
                                                     and self._id is None):
            return cmp(hash(self), hash(obj))

        occ_task_cmp = cmp(self.getTask(), obj.getTask())
        if occ_task_cmp == 0:
            return cmp(self.getId(), obj.getId())
        else:
            return occ_task_cmp

    def getId(self):
        return self._id

    def getUniqueId(self):
        return "%s:%s" % (self._task.getUniqueId(), self._id)

    def setId(self, occId):
        self._id = occId

    def getStartedOn(self):
        return self._startedOn

    def getEndedOn(self):
        return self._endedOn

    def getTask(self):
        return self._task
Esempio n. 9
0
class GroupWrapper(Fossilizable):
    """Group-like wrapper class that holds a DB-stored (or remote) group."""

    fossilizes(IGroupFossil)

    def __init__(self, group_id):
        self.id = to_unicode(group_id).encode('utf-8')

    @property
    def group(self):
        """Returns the underlying GroupProxy

        :rtype: indico.modules.groups.core.GroupProxy
        """
        raise NotImplementedError

    def getId(self):
        return self.id

    def getName(self):
        raise NotImplementedError

    def getFullName(self):
        return self.getName()

    def getEmail(self):
        return ''

    def exists(self):
        return self.group.group is not None

    def __eq__(self, other):
        if not hasattr(other, 'group') or not isinstance(
                other.group, GroupProxy):
            return False
        return self.group == other.group

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.group)

    @return_ascii
    def __repr__(self):
        return u'<{} {}: {}>'.format(type(self).__name__, self.id, self.group)
Esempio n. 10
0
class EmailPrincipal(Fossilizable):
    """Wrapper for email principals

    :param email: The email address.
    """

    principal_type = PrincipalType.email
    is_group = False
    fossilizes(IEmailPrincipalFossil)

    def __init__(self, email):
        self.email = email.lower()

    @property
    def name(self):
        return self.email

    @property
    def as_legacy(self):
        return self

    @property
    def as_new(self):
        return self

    @property
    def user(self):
        from indico.modules.users import User
        return User.find_first(~User.is_deleted,
                               User.all_emails.contains(self.email))

    def __eq__(self, other):
        return isinstance(other, EmailPrincipal) and self.email == other.email

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.email)

    def __contains__(self, user):
        return self.email in user.all_emails

    @return_ascii
    def __repr__(self):
        return format_repr(self, 'email')
Esempio n. 11
0
class SyncAgent(Fossilizable, Persistent):
    """
    Represents an "agent" (service)
    """

    fossilizes(IAgentFossil)

    _extraOptions = {}

    # TODO: Subclass into PushSyncAgent(task)/PullSyncAgent?

    def __init__(self, aid, name, description, updateTime, access=None):
        self._id = aid
        self._name = name
        self._description = description
        self._updateTime = updateTime
        self._manager = None
        self._active = False
        self._recording = False
        self._access = access

    def record_str(self, (obj, objId, status)):
        """
Esempio n. 12
0
class Wrapper(Persistent):
    """
    Very simple wrapper around Attachment/AttachmentFolder
    that allows them to be stored in obj.nonInheritingChildren
    """

    fossilizes(IWrapperFossil)

    def __init__(self, obj):
        self.id = obj.id

    def getId(self):
        return self.id

    @property
    def title(self):
        return self.as_new.title

    @property
    def as_new(self):
        return self.new_class.get(self.id)

    def __eq__(self, other):
        if self.__class__ is other.__class__:
            return self.id == other.id
        else:
            return False

    def __ne__(self, other):
        return not(self == other)

    def __hash__(self):
        return hash((self.__class__.__name__, self.id))

    def getAccessController(self):
        return AccessControllerAdapter(self)
Esempio n. 13
0
class GroupWrapper(Persistent, Fossilizable):
    """Group-like wrapper class that holds a DB-stored (or remote) group."""

    fossilizes(IGroupFossil)

    def __init__(self, group_id):
        self.id = to_unicode(group_id).encode('utf-8')

    @property
    def group(self):
        """Returns the underlying GroupProxy

        :rtype: indico.modules.groups.core.GroupProxy
        """
        raise NotImplementedError

    def getId(self):
        return self.id

    def getName(self):
        raise NotImplementedError

    def getFullName(self):
        return self.getName()

    def getDescription(self):
        return ''

    def setDescription(self, value):
        pass

    def getEmail(self):
        return ''

    def isObsolete(self):
        return False

    def containsUser(self, avatar):
        if self.group is None or avatar is None:
            return False
        return avatar.user in self.group

    def getMemberList(self):
        return sorted([x.as_avatar for x in self.group.get_members()],
                      key=attrgetter('user.last_name'))

    def canModify(self, aw_or_user):
        if hasattr(aw_or_user, 'getUser'):
            aw_or_user = aw_or_user.getUser()
        return self.canUserModify(aw_or_user)

    def canUserModify(self, avatar):
        return avatar.user.is_admin

    def getLocator(self):
        return Locator(groupId=self.id)

    def exists(self):
        return self.group.group is not None

    @property
    def as_new(self):
        return self.group

    def __eq__(self, other):
        if not hasattr(other, 'group') or not isinstance(
                other.group, GroupProxy):
            return False
        return self.group == other.group

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.group)

    @return_ascii
    def __repr__(self):
        return u'<{} {}: {}>'.format(type(self).__name__, self.id, self.group)
Esempio n. 14
0
class SupportInfo(Persistent):
    """
    Stores support-related information for events
    """

    fossilizes(ISupportInfoFossil)

    def __init__(self, owner, caption="", email="", telephone=""):
        self._owner = owner
        self._caption = caption
        self._email = email
        self._telephone = telephone

    def getOwner(self):
        return self._owner

    def getCaption(self):
        return self._caption

    def setCaption(self, caption):
        self._caption = caption

    def getEmail(self, returnNoReply=False, caption=False):
        """
        Returns the support email address associated with the conference
        :param returnNoReply: Return no-reply address in case there's no support e-mail (default True)
        :type returnNoReply: bool

        """
        if self._email.strip() == "" and returnNoReply:
            # In case there's no conference support e-mail, return the no-reply
            # address, and the 'global' support e-mail if there isn't one
            return Config.getInstance().getNoReplyEmail()
        else:
            if caption and self._caption:
                return '"%s" <%s>' % (self._caption, self._email)
            else:
                return self._email

    def setEmail(self, email):
        self._email = email.strip()

    def hasEmail(self):
        return self._email != "" and self._email != None

    def getTelephone(self):
        return self._telephone

    def setTelephone(self, telephone):
        self._telephone = telephone.strip()

    def hasTelephone(self):
        return self._telephone != "" and self._telephone != None

    def isEmpty(self):
        return not self._email and not self._telephone

    def clone(self, owner):
        supportInfo = SupportInfo(owner)
        supportInfo.setCaption(self.getCaption())
        supportInfo.setEmail(self.getEmail())
        supportInfo.setTelephone(self.getTelephone())
        return supportInfo
Esempio n. 15
0
class BaseStatisticsReport(Fossilizable, object):

    fossilizes(IReportFossil)

    def __init__(self):
        # These are the containers which the report returns to the view.
        self._reportImageSources = {}
        self._reportWidgetSources = {}
        self._reportValueSources = {}

        self._reportGenerators = {}
        self._reportMethods = {}
        self._reportSetters = {}

        self._reportGenerated = None

        self._startDate = None
        self._endDate = None

    def _buildReports(self):
        """
        All reports for this instance should be logged with a generator
        in self._reportGenerators. This method cyclces through these
        generators, executes the get command on the query object and then
        the set command on the report object.
        """

        for resultType, generators in self._reportGenerators.iteritems():
            for resultName, gen in generators.iteritems():
                setMethod = self._reportSetters.get(resultType)
                setFunc = getattr(self, setMethod)

                if setFunc is None:
                    raise Exception('Method %s not implemented' % setMethod)

                setFunc(resultName, gen.getResult())

        self._reportGenerated = utc2server(nowutc(), naive=False)

    def getDateGenerated(self):
        return self._reportGenerated

    def getImagesSources(self):
        return self._reportImageSources

    def getValueSources(self):
        return self._reportValueSources

    def getWidgetSources(self):
        return self._reportWidgetSources

    def getStartDate(self):
        return self._startDate

    def getEndDate(self):
        return self._endDate

    def setImageSource(self, name, source):
        """
        Only want a 1:1 map of key value, each image should have its own
        title, therefore no appending to lists etc. The values of these
        associations will be the raw, base64 encoded value of the image
        itself.
        """
        sources = self.getImagesSources()
        sources[name] = source

    def setValueSource(self, name, source):
        """
        This is a map of key : value relating to metrics retrieved from
        the API which have only a string or numerical value.
        """
        sources = self.getValueSources()
        sources[name] = source

    def setWidgetSource(self, name, source):
        """
        The values of this dictionary will be the full Piwik API URLs for
        widget iframe values.
        """
        sources = self.getWidgetSources()
        sources[name] = source
Esempio n. 16
0
class AvatarUserWrapper(Persistent, Fossilizable):
    """Avatar-like wrapper class that holds a DB-stored user."""

    fossilizes(IAvatarFossil, IAvatarMinimalFossil)

    def __init__(self, user_id):
        self.id = str(user_id)

    @property
    @memoize_request
    def _original_user(self):
        # A proper user, with an id that can be mapped directly to sqlalchemy
        if isinstance(self.id, int) or self.id.isdigit():
            return User.get(int(self.id))
        # A user who had no real indico account but an ldap identifier/email.
        # In this case we try to find his real user and replace the ID of this object
        # with that user's ID.
        data = self.id.split(':')
        # TODO: Once everything is in SQLAlchemy this whole thing needs to go away!
        user = None
        if data[0] == 'LDAP':
            identifier = data[1]
            email = data[2]
            # You better have only one ldap provider or at least different identifiers ;)
            identity = Identity.find_first(Identity.provider != 'indico', Identity.identifier == identifier)
            if identity:
                user = identity.user
        elif data[0] == 'Nice':
            email = data[1]
        else:
            return None
        if not user:
            user = User.find_first(User.all_emails.contains(email))
        if user:
            self._old_id = self.id
            self.id = str(user.id)
            logger.info("Updated legacy user id (%s => %s)", self._old_id, self.id)
        return user

    @property
    @memoize_request
    def user(self):
        user = self._original_user
        if user is not None and user.is_deleted and user.merged_into_id is not None:
            while user.merged_into_id is not None:
                user = user.merged_into_user
        return user

    def getId(self):
        return str(self.user.id) if self.user else str(self.id)

    @property
    def api_key(self):
        return self.user.api_key if self.user else None

    def linkTo(self, obj, role):
        if not self.user or self.user.is_deleted:
            return
        link = self.user.link_to(obj, role)
        if link and redis_write_client:
            event = avatar_links.event_from_obj(obj)
            if event:
                avatar_links.add_link(self.user, event, '{}_{}'.format(link.type, link.role))

    def unlinkTo(self, obj, role):
        if not self.user or self.user.is_deleted:
            return
        links = self.user.unlink_to(obj, role)
        if redis_write_client:
            for link in links:
                event = avatar_links.event_from_obj(obj)
                if event:
                    avatar_links.del_link(self.user, event, '{}_{}'.format(link.type, link.role))

    def getStatus(self):
        return 'deleted' if not self.user or self.user.is_deleted else 'activated'

    def isActivated(self):
        # All accounts are activated during the transition period
        return True

    def isDisabled(self):
        # The user has been blocked or deleted (due to merge)
        return not self.user or self.user.is_blocked or self.user.is_deleted

    def setName(self, name, reindex=False):
        self.user.first_name = to_unicode(name)

    @encode_utf8
    def getName(self):
        return self.user.first_name if self.user else ''

    getFirstName = getName

    def setSurName(self, surname, reindex=False):
        self.user.last_name = to_unicode(surname)

    @encode_utf8
    def getSurName(self):
        return self.user.last_name if self.user else ''

    getFamilyName = getSurName

    @encode_utf8
    def getFullName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=True, last_name_upper=True,
                                       abbrev_first_name=False, show_title=False)

    @encode_utf8
    def getStraightFullName(self, upper=True):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=False, last_name_upper=upper,
                                       abbrev_first_name=False, show_title=False)

    getDirectFullNameNoTitle = getStraightFullName

    @encode_utf8
    def getAbrName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=True, last_name_upper=False,
                                       abbrev_first_name=True, show_title=False)

    @encode_utf8
    def getStraightAbrName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=False, last_name_upper=False,
                                       abbrev_first_name=True, show_title=False)

    def setOrganisation(self, affiliation, reindex=False):
        self.user.affiliation = to_unicode(affiliation)

    @encode_utf8
    def getOrganisation(self):
        return self.user.affiliation if self.user else ''

    getAffiliation = getOrganisation

    def setTitle(self, title):
        self.user.title = to_unicode(title)

    @encode_utf8
    def getTitle(self):
        return self.user.title if self.user else ''

    def setTimezone(self, tz):
        self.user.settings.set('timezone', to_unicode(tz))

    @encode_utf8
    def getTimezone(self):
        default = Config.getInstance().getDefaultTimezone()
        return self.user.settings.get('timezone', default) if self.user else default

    def getDisplayTZMode(self):
        return 'MyTimezone' if self.user and self.user.settings.get('force_timezone') else 'Event Timezone'

    def setDisplayTZMode(self, display_tz='Event Timezone'):
        self.user.settings.set('force_timezone', display_tz == 'MyTimezone')

    @encode_utf8
    def getAddress(self):
        return self.user.address if self.user else ''

    def setAddress(self, address):
        self.user.address = to_unicode(address)

    def getEmails(self):
        # avoid 'stale association proxy'
        user = self.user
        return set(user.all_emails) if user else set()

    @encode_utf8
    def getEmail(self):
        return self.user.email if self.user else ''

    email = property(getEmail)

    def setEmail(self, email, reindex=False):
        self.user.email = to_unicode(email)

    def hasEmail(self, email):
        user = self.user  # avoid 'stale association proxy'
        if not user:
            return False
        return email.lower() in user.all_emails

    @encode_utf8
    def getTelephone(self):
        return self.user.phone if self.user else ''

    def getFax(self):
        # Some older code still clones fax, etc...
        # it's never shown in the interface anyway.
        return ''

    getPhone = getTelephone

    def setTelephone(self, phone):
        self.user.phone = to_unicode(phone)

    setPhone = setTelephone

    def isRegisteredInConf(self, conf):
        if not self.user:
            return False
        return any(obj for obj in self.user.get_linked_objects('registration', 'registrant')
                   if obj.getConference() == conf)

    def getRegistrantById(self, conf_id):
        if not self.user:
            return None
        return next((obj for obj in self.user.get_linked_objects('registration', 'registrant')
                    if obj.getConference().id == conf_id), None)

    def containsUser(self, avatar):
        if self.user is None:
            return False
        return int(avatar.id) == self.user.id if avatar else False

    containsMember = containsUser

    def canModify(self, aw_or_user):
        if hasattr(aw_or_user, 'getUser'):
            aw_or_user = aw_or_user.getUser()
        return self.canUserModify(aw_or_user)

    def canUserModify(self, avatar):
        if not self.user:
            return False
        return avatar.id == str(self.user.id) or avatar.user.is_admin

    def getLocator(self):
        d = Locator()
        if self.user:
            d["userId"] = self.user.id
        return d

    def isAdmin(self):
        if not self.user:
            return False
        return self.user.is_admin

    @property
    def as_new(self):
        return self.user

    def __eq__(self, other):
        if not isinstance(other, (AvatarUserWrapper, User)):
            return False
        elif str(self.id) == str(other.id):
            return True
        elif self.user:
            return str(self.user.id) == str(other.id)
        else:
            return False

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(str(self.id))

    @return_ascii
    def __repr__(self):
        if self.user is None:
            return u'<AvatarUserWrapper {}: user does not exist>'.format(self.id)
        elif self._original_user.merged_into_user:
            return u'<AvatarUserWrapper {}: {} ({}) [{}]>'.format(
                self.id, self._original_user.full_name, self._original_user.email, self.user.id)
        else:
            return u'<AvatarUserWrapper {}: {} ({})>'.format(self.id, self.user.full_name, self.user.email)
Esempio n. 17
0
class BaseTask(TimedEvent):
    """
    A base class for tasks.
    `expiryDate` is the last point in time when the task can run. A task will
    refuse to run if current time is past `expiryDate`
    """

    DISABLE_ZODB_HOOK = False

    fossilizes(ITaskFossil)

    # seconds to consider a task AWOL
    _AWOLThresold = 6000

    def __init__(self, expiryDate=None):
        self.createdOn = self._getCurrentDateTime()
        self.expiryDate = expiryDate
        self.typeId = self.__class__.__name__
        self.id = None
        self.reset()
        self.status = 0

        self.startedOn = None
        self.endedOn = None

    def __cmp__(self, obj):
        from indico.modules.scheduler.tasks.periodic import TaskOccurrence
        if obj is None:
            return 1
        elif isinstance(obj, TaskOccurrence):
            task_cmp = cmp(self, obj.getTask())
            if task_cmp == 0:
                return -1
            else:
                return task_cmp
        # This condition will mostlike never happen
        elif not isinstance(obj, BaseTask) or (self.id == obj.id and self.id is None):
            return cmp(hash(self), hash(obj))
        # This is the 'default case' where we are comparing 2 Tasks
        else:
            return cmp(self.id, obj.id)

    def reset(self):
        '''Resets a task to its state before being run'''

        self.running = False
        self.onRunningListSince = None

    # Time methods

    def getCreatedOn(self):
        return self.createdOn

    def getEndedOn(self):
        return self.endedOn

    def setEndedOn(self, dateTime):
        self.endedOn = dateTime

    def getStartedOn(self):
        return self.startedOn

    def setStartedOn(self, dateTime):
        self.startedOn = dateTime

    def setOnRunningListSince(self, sometime):
        self.onRunningListSince = sometime
        self._p_changed = 1

    def getOnRunningListSince(self):
        return self.onRunningListSince

    def setStatus(self, newstatus):
        self.getLogger().info("%s set status %s" % (self, base.status(newstatus)))
        self.status = newstatus

    def getStatus(self):
        return self.status

    def getId(self):
        return self.id

    def getUniqueId(self):
        return "task%s" % self.id

    def getTypeId(self):
        return self.typeId

    def initialize(self, newid, newstatus):
        self.id = newid
        self.setStatus(newstatus)

    def plugLogger(self, logger):
        self._v_logger = logger

    def getLogger(self):
        if not hasattr(self, '_v_logger') or not self._v_logger:
            self._v_logger = logging.getLogger('task/%s' % self.typeId)
        return self._v_logger

    def prepare(self):
        """
        This information will be saved regardless of the task being repeated or not
        """

        curTime = self._getCurrentDateTime()
        tsDiff = int_timestamp(self.getStartOn()) - int_timestamp(curTime)

        if tsDiff > 0:
            self.getLogger().debug('Task %s will wait for some time. (%s) > (%s)' % \
                                   (self.id, self.getStartOn(), curTime))
            base.TimeSource.get().sleep(tsDiff)

        if self.expiryDate and curTime > self.expiryDate:
            self.getLogger().warning(
                'Task %s will not be executed, expiryDate (%s) < current time (%s)' % \
                (self.id, self.expiryDate, curTime))
            return False

        self.startedOn = curTime
        self.running = True
        self.setStatus(base.TASK_STATUS_RUNNING)

    def start(self, delay):
        if self.DISABLE_ZODB_HOOK:
            update_session_options(db)
        self._executionDelay = delay
        try:
            self.run()
            self.endedOn = self._getCurrentDateTime()
        finally:
            LDAPConnector.destroy()
            self.running = False

    def tearDown(self):
        """
        If a task needs to do something once it has run and been removed
        from runningList, overload this method
        """
        pass

    def __str__(self):
        return "[%s:%s|%s]" % (self.typeId, self.id,
                               base.status(self.status))
Esempio n. 18
0
class PiwikReport(PiwikReportBase):

    fossilizes(IPiwikReportFossil)
    _defaultReportInterval = 14

    def __init__(self, startDate, endDate, confId, contribId=None):
        """
        Builds the map of generators to fill this object's variables before
        fossilization.
        """

        PiwikReportBase.__init__(self)
        report = BaseReportGenerator

        self._conf = ConferenceHolder().getById(confId)
        self._confId = confId
        self._contribId = contribId
        self._buildDateRange(startDate, endDate)
        self._contributions = []

        params = {
            'startDate': self._startDate,
            'endDate': self._endDate,
            'confId': confId
        }

        if contribId:
            params['contribId'] = contribId

        # This report only has need for images and values, not for widgets.
        self._reportGenerators = {
            'values': {
                'visits':
                report(pq.PiwikQueryMetricConferenceVisits, params),
                'uniqueVisits':
                report(pq.PiwikQueryMetricConferenceUniqueVisits, params),
                'visitLength':
                report(pq.PiwikQueryMetricConferenceVisitLength, params),
                'referrers':
                report(pq.PiwikQueryMetricConferenceReferrers, params),
                'peakDate':
                report(pq.PiwikQueryMetricConferencePeakDateAndVisitors,
                       params)
            }
        }

        self._buildReports()
        self._buildConferenceContributions()

    def _buildDateRange(self, startDate, endDate):
        """
        If the default values are passed through, computes the appropriate date
        range based on whether today is before or after the conference end date.
        If after, end of period is set as conference end date. Start date is then
        calculated by the _defaultReportInterval difference.
        """
        def getStartDate():
            interval = datetime.timedelta(days=self._defaultReportInterval)
            adjustedStartDate = self._endDateTime - interval

            return str(adjustedStartDate.date())

        def getEndDate():
            today = nowutc()
            confEndDate = self._conf.getEndDate()

            self._endDateTime = confEndDate if today > confEndDate else today

            return str(self._endDateTime.date())

        self._endDate = endDate if endDate else getEndDate()
        self._startDate = startDate if startDate else getStartDate()

    def _buildConferenceContributions(self):
        """
        As this implementation permits the viewing of individual contributions,
        we make a list of tuples associating the uniqueId with the title
        (and start time) to be fossilized.
        """
        contributions = self._conf.getContributionList()

        if contributions:
            self._contributions.append(
                ('None', str(_('Conference: ') + self._conf.getTitle())))

            for ctrb in contributions:

                if not ctrb.isScheduled():
                    continue

                ctrbTime = str(ctrb.getStartDate().hour) + ':' + str(
                    ctrb.getStartDate().minute)
                ctrbInfo = _(
                    'Contribution: ') + ctrb.getTitle() + ' (' + ctrbTime + ')'
                value = (ctrb.getUniqueId(), ctrbInfo)
                self._contributions.append(value)
        else:
            self._contributions = False

    def _getContributions(self):
        return self._contributions

    def getConferenceId(self):
        return self._confId

    def getContributionId(self):
        return self._contribId
Esempio n. 19
0
class AvatarUserWrapper(Fossilizable):
    """Avatar-like wrapper class that holds a DB-stored user."""

    fossilizes(IAvatarFossil, IAvatarMinimalFossil)

    def __init__(self, user_id):
        self.id = str(user_id)

    @property
    @memoize_request
    def _original_user(self):
        # A proper user, with an id that can be mapped directly to sqlalchemy
        if isinstance(self.id, int) or self.id.isdigit():
            return User.get(int(self.id))
        # A user who had no real indico account but an ldap identifier/email.
        # In this case we try to find his real user and replace the ID of this object
        # with that user's ID.
        data = self.id.split(':')
        # TODO: Once everything is in SQLAlchemy this whole thing needs to go away!
        user = None
        if data[0] == 'LDAP':
            identifier = data[1]
            email = data[2]
            # You better have only one ldap provider or at least different identifiers ;)
            identity = Identity.query.filter(Identity.provider != 'indico', Identity.identifier == identifier).first()
            if identity:
                user = identity.user
        elif data[0] == 'Nice':
            email = data[1]
        else:
            return None
        if not user:
            user = User.query.filter(User.all_emails == email).first()
        if user:
            self._old_id = self.id
            self.id = str(user.id)
            logger.info("Updated legacy user id (%s => %s)", self._old_id, self.id)
        return user

    @property
    @memoize_request
    def user(self):
        user = self._original_user
        if user is not None and user.is_deleted and user.merged_into_id is not None:
            while user.merged_into_id is not None:
                user = user.merged_into_user
        return user

    def getId(self):
        return str(self.user.id) if self.user else str(self.id)

    @property
    def api_key(self):
        return self.user.api_key if self.user else None

    def getStatus(self):
        return 'deleted' if not self.user or self.user.is_deleted else 'activated'

    def isActivated(self):
        # All accounts are activated during the transition period
        return True

    def isDisabled(self):
        # The user has been blocked or deleted (due to merge)
        return not self.user or self.user.is_blocked or self.user.is_deleted

    def setName(self, name, reindex=False):
        self.user.first_name = to_unicode(name)

    @encode_utf8
    def getName(self):
        return self.user.first_name if self.user else ''

    getFirstName = getName

    def setSurName(self, surname, reindex=False):
        self.user.last_name = to_unicode(surname)

    @encode_utf8
    def getSurName(self):
        return self.user.last_name if self.user else ''

    getFamilyName = getSurName

    @encode_utf8
    def getFullName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=True, last_name_upper=True,
                                       abbrev_first_name=False, show_title=False)

    @encode_utf8
    def getStraightFullName(self, upper=True):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=False, last_name_upper=upper,
                                       abbrev_first_name=False, show_title=False)

    getDirectFullNameNoTitle = getStraightFullName

    @encode_utf8
    def getAbrName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=True, last_name_upper=False,
                                       abbrev_first_name=True, show_title=False)

    @encode_utf8
    def getStraightAbrName(self):
        if not self.user:
            return ''
        return self.user.get_full_name(last_name_first=False, last_name_upper=False,
                                       abbrev_first_name=True, show_title=False)

    def setOrganisation(self, affiliation, reindex=False):
        self.user.affiliation = to_unicode(affiliation)

    @encode_utf8
    def getOrganisation(self):
        return self.user.affiliation if self.user else ''

    getAffiliation = getOrganisation

    def setTitle(self, title):
        self.user.title = to_unicode(title)

    @encode_utf8
    def getTitle(self):
        return self.user.title if self.user else ''

    def setTimezone(self, tz):
        self.user.settings.set('timezone', to_unicode(tz))

    @encode_utf8
    def getAddress(self):
        return self.user.address if self.user else ''

    def setAddress(self, address):
        self.user.address = to_unicode(address)

    def getEmails(self):
        # avoid 'stale association proxy'
        user = self.user
        return set(user.all_emails) if user else set()

    @encode_utf8
    def getEmail(self):
        return self.user.email if self.user else ''

    email = property(getEmail)

    def setEmail(self, email, reindex=False):
        self.user.email = to_unicode(email)

    def hasEmail(self, email):
        user = self.user  # avoid 'stale association proxy'
        if not user:
            return False
        return email.lower() in user.all_emails

    @encode_utf8
    def getTelephone(self):
        return self.user.phone if self.user else ''

    def getFax(self):
        # Some older code still clones fax, etc...
        # it's never shown in the interface anyway.
        return ''

    getPhone = getTelephone

    def setTelephone(self, phone):
        self.user.phone = to_unicode(phone)

    setPhone = setTelephone

    def canUserModify(self, avatar):
        if not self.user:
            return False
        return avatar.id == str(self.user.id) or avatar.user.is_admin

    @locator_property
    def locator(self):
        d = {}
        if self.user:
            d['userId'] = self.user.id
        return d

    def isAdmin(self):
        if not self.user:
            return False
        return self.user.is_admin

    @property
    def as_new(self):
        return self.user

    def __eq__(self, other):
        if not isinstance(other, (AvatarUserWrapper, User)):
            return False
        elif str(self.id) == str(other.id):
            return True
        elif self.user:
            return str(self.user.id) == str(other.id)
        else:
            return False

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(str(self.id))

    @return_ascii
    def __repr__(self):
        if self.user is None:
            return u'<AvatarUserWrapper {}: user does not exist>'.format(self.id)
        elif self._original_user.merged_into_user:
            return u'<AvatarUserWrapper {}: {} ({}) [{}]>'.format(
                self.id, self._original_user.full_name, self._original_user.email, self.user.id)
        else:
            return u'<AvatarUserWrapper {}: {} ({})>'.format(self.id, self.user.full_name, self.user.email)
Esempio n. 20
0
class AvatarProvisionalWrapper(Fossilizable):
    """Wrap provisional data for users that are not in the DB yet."""

    fossilizes(IAvatarFossil, IAvatarMinimalFossil)

    def __init__(self, identity_info):
        self.identity_info = identity_info
        self.data = identity_info.data

    def getId(self):
        return u"{}:{}".format(self.identity_info.provider.name, self.identity_info.identifier)

    id = property(getId)

    @encode_utf8
    def getEmail(self):
        return self.data['email']

    def getEmails(self):
        return [self.data['email']]

    @encode_utf8
    def getFirstName(self):
        return self.data.get('first_name', '')

    @encode_utf8
    def getFamilyName(self):
        return self.data.get('last_name', '')

    @encode_utf8
    def getStraightFullName(self, upper=False):
        last_name = to_unicode(self.data.get('last_name', ''))
        if upper:
            last_name = last_name.upper()
        return u'{} {}'.format(to_unicode(self.data.get('first_name', '')), last_name)

    def getTitle(self):
        return ''

    @encode_utf8
    def getTelephone(self):
        return self.data.get('phone', '')

    getPhone = getTelephone

    @encode_utf8
    def getOrganisation(self):
        return self.data.get('affiliation', '')

    getAffiliation = getOrganisation

    def getFax(self):
        return None

    def getAddress(self):
        return u''

    @return_ascii
    def __repr__(self):
        return u'<AvatarProvisionalWrapper {}: {} ({first_name} {last_name})>'.format(
            self.identity_info.provider.name,
            self.identity_info.identifier,
            **self.data.to_dict())
Esempio n. 21
0
class AvatarUserWrapper(Persistent, Fossilizable):
    """Avatar-like wrapper class that holds a DB-stored user."""

    fossilizes(IAvatarFossil, IAvatarMinimalFossil)

    def __init__(self, user_id):
        self.id = str(user_id)

    @property
    @memoize_request
    def _original_user(self):
        # A proper user, with an id that can be mapped directly to sqlalchemy
        if isinstance(self.id, int) or self.id.isdigit():
            return User.get(int(self.id))
        # A user who had no real indico account but an ldap identifier/email.
        # In this case we try to find his real user and replace the ID of this object
        # with that user's ID.
        data = self.id.split(':')
        # TODO: Once everything is in SQLAlchemy this whole thing needs to go away!
        user = None
        if data[0] == 'LDAP':
            identifier = data[1]
            email = data[2]
            # You better have only one ldap provider or at least different identifiers ;)
            identity = Identity.find_first(Identity.provider != 'indico',
                                           Identity.identifier == identifier)
            if identity:
                user = identity.user
        elif data[0] == 'Nice':
            email = data[1]
        else:
            return None
        if not user:
            user = User.find_first(User.all_emails.contains(email))
        if user:
            self._old_id = self.id
            self.id = str(user.id)
        return user

    @property
    @memoize_request
    def user(self):
        user = self._original_user
        if user is None:
            return None
        elif user.is_deleted:
            return user.merged_into_user if user.merged_into_id is not None else None
        else:
            return user

    def getId(self):
        return str(self.user.id)

    @property
    def api_key(self):
        return self.user.api_key

    def linkTo(self, obj, role):
        # deleted users shouldn't be able to be linked
        # TODO: log deleted users?

        if not self.user.is_deleted:
            link = self.user.link_to(obj, role)
            if link and redis_write_client:
                event = avatar_links.event_from_obj(obj)
                if event:
                    avatar_links.add_link(self, event,
                                          '{}_{}'.format(link.type, link.role))

    def unlinkTo(self, obj, role):
        # deleted users shouldn't be able to be linked
        # TODO: log deleted users?
        if not self.user.is_deleted:
            links = self.user.unlink_to(obj, role)
            if redis_write_client:
                for link in links:
                    event = avatar_links.event_from_obj(obj)
                    if event:
                        avatar_links.del_link(
                            self, event, '{}_{}'.format(link.type, link.role))

    def getLinkedTo(self):
        return None

    def getStatus(self):
        return 'deleted' if self.user.is_deleted else 'activated'

    def isActivated(self):
        # All accounts are activated during the transition period
        return True

    def isDisabled(self):
        # The user has been blocked or deleted (due to merge)
        return self.user.is_blocked or self.user.is_deleted

    def setName(self, name, reindex=False):
        self.user.first_name = to_unicode(name)

    @encode_utf8
    def getName(self):
        return self.user.first_name

    getFirstName = getName

    def setSurName(self, surname, reindex=False):
        self.user.last_name = to_unicode(surname)

    @encode_utf8
    def getSurName(self):
        return self.user.last_name

    getFamilyName = getSurName

    @encode_utf8
    def getFullName(self):
        return self.user.get_full_name(last_name_first=True,
                                       last_name_upper=True,
                                       abbrev_first_name=False,
                                       show_title=False)

    @encode_utf8
    def getStraightFullName(self, upper=True):
        return self.user.get_full_name(last_name_first=False,
                                       last_name_upper=True,
                                       abbrev_first_name=False,
                                       show_title=False)

    getDirectFullNameNoTitle = getStraightFullName

    @encode_utf8
    def getAbrName(self):
        return self.user.get_full_name(last_name_first=True,
                                       last_name_upper=False,
                                       abbrev_first_name=True,
                                       show_title=False)

    @encode_utf8
    def getStraightAbrName(self):
        return self.user.get_full_name(last_name_first=False,
                                       last_name_upper=False,
                                       abbrev_first_name=True,
                                       show_title=False)

    def setOrganisation(self, affiliation, reindex=False):
        self.user.affiliation = to_unicode(affiliation)

    @encode_utf8
    def getOrganisation(self):
        return self.user.affiliation

    getAffiliation = getOrganisation

    def setTitle(self, title):
        self.user.title = to_unicode(title)

    @encode_utf8
    def getTitle(self):
        return self.user.title

    def setTimezone(self, tz):
        self.user.settings.set('timezone', to_unicode(tz))

    @encode_utf8
    def getTimezone(self):
        return self.user.settings.get(
            'timezone',
            HelperMaKaCInfo.getMaKaCInfoInstance().getTimezone())

    def getDisplayTZMode(self):
        return 'MyTimezone' if self.user.settings.get(
            'force_timezone') else 'Event Timezone'

    def setDisplayTZMode(self, display_tz='Event Timezone'):
        self.user.settings.set('force_timezone', display_tz == 'MyTimezone')

    @encode_utf8
    def getAddresses(self):
        return [self.user.address]

    @encode_utf8
    def getAddress(self):
        return self.user.address

    def setAddress(self, address):
        self.user.address = to_unicode(address)

    def getEmails(self):
        # avoid 'stale association proxy'
        user = self.user
        return set(user.all_emails)

    @encode_utf8
    def getEmail(self):
        return self.user.email

    def setEmail(self, email, reindex=False):
        self.user.email = to_unicode(email)

    def getSecondaryEmails(self):
        return self.user.secondary_emails

    def addSecondaryEmail(self, email, reindex=False):
        return self.user.secondary_emails.add(to_unicode(
            email.strip().lower()))

    def removeSecondaryEmail(self, email, reindex=False):
        self.user.secondary_emails.remove(email)

    def setSecondaryEmails(self, emails, reindex=False):
        self.user.secondary_emails = {
            to_unicode(email.strip().lower())
            for email in emails
        }

    def hasEmail(self, email):
        return email.lower() in self.user.all_emails

    def hasSecondaryEmail(self, email):
        return email.lower() in self.user.secondary_emails

    @encode_utf8
    def getTelephone(self):
        return self.user.phone

    def getFax(self):
        # Some older code still clones fax, etc...
        # it's never shown in the interface anyway.
        return ''

    getPhone = getTelephone

    def setTelephone(self, phone):
        self.user.phone = to_unicode(phone)

    setPhone = setTelephone

    def clearAuthenticatorPersonalData(self):
        pass

    def setAuthenticatorPersonalData(self, field, value):
        pass

    def getIdentityById(self, id, tag):
        return True

    def addRegistrant(self, r):
        # This doesn't seem to be needed, as it is stored in linkedTo as well
        # TODO: Check that it can be deleted
        pass

    def removeRegistrant(self, r):
        # This doesn't seem to be needed, as it is stored in linkedTo as well
        # TODO: Check that it can be deleted
        pass

    def isRegisteredInConf(self, conf):
        return any(obj for obj in self.user.get_linked_objects(
            'registration', 'registrant') if obj.getConference() == conf)

    def getRegistrantById(self, conf_id):
        return next((obj for obj in self.user.get_linked_objects(
            'registration', 'registrant')
                     if obj.getConference().id == conf_id), None)

    def hasSubmittedEvaluation(self, evaluation):
        for submission in evaluation.getSubmissions():
            submitter = submission.getSubmitter()
            if submitter and submitter.id == self.user.id:
                return True
        return False

    def containsUser(self, avatar):
        if self.user is None:
            return False
        return int(avatar.id) == self.user.id if avatar else False

    containsMember = containsUser

    def canModify(self, aw_or_user):
        if hasattr(aw_or_user, 'getUser'):
            aw_or_user = aw_or_user.getUser()
        return self.canUserModify(aw_or_user)

    def canUserModify(self, avatar):
        return avatar.id == str(self.user.id) or avatar.user.is_admin

    def getLocator(self):
        d = Locator()
        d["userId"] = self.user.id
        return d

    def is_member_of_group(self, group_name):
        group_provider = multipass.default_group_provider
        group = GroupProxy(group_name,
                           group_provider.name if group_provider else None)
        return group.has_member(self.user)

    def isAdmin(self):
        return self.user.is_admin

    @memoize_request
    def isRBAdmin(self):
        """Convenience method for checking whether this user is an admin for the RB module."""
        return rb_is_admin(self)

    @property
    @memoize_request
    def has_rooms(self):
        """Checks if the user has any rooms"""
        from indico.modules.rb.models.rooms import Room  # avoid circular import
        return Room.user_owns_rooms(self)

    @memoize_request
    def get_rooms(self):
        """Returns the rooms this user is responsible for"""
        from indico.modules.rb.models.rooms import Room  # avoid circular import
        return Room.get_owned_by(self)

    @encode_utf8
    def getLang(self):
        return self.user.settings.get('lang')

    def setLang(self, lang):
        self.user.settings.set('lang', to_unicode(lang))

    def __eq__(self, other):
        if not isinstance(other, (AvatarUserWrapper, User)):
            return False
        elif str(self.id) == str(other.id):
            return True
        elif self.user:
            return str(self.user.id) == str(other.id)
        else:
            return False

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(str(self.id))

    @return_ascii
    def __repr__(self):
        if self.user is None:
            return u'<AvatarUserWrapper {}: user does not exist>'.format(
                self.id)
        elif self._original_user.merged_into_user:
            return u'<AvatarUserWrapper {}: {} ({}) [{}]>'.format(
                self.id, self._original_user.full_name,
                self._original_user.email, self.user.id)
        else:
            return u'<AvatarUserWrapper {}: {} ({})>'.format(
                self.id, self.user.full_name, self.user.email)