Пример #1
0
class Email(Channel):
    class __mongometa__:
        session = session
        name = 'Email'

    _id = FieldProperty(ins.Email)
Пример #2
0
class FileContentDAO(FileDAO):
    content = FieldProperty(schema.Binary)
Пример #3
0
class Proposition(MappedClass):
    class __mongometa__:
        session = session
        name = 'Proposition'
    _id = FieldProperty(schema.ObjectId)
    name = FieldProperty(str)
Пример #4
0
class PiazzaContent_Child_History(MappedClass):
    """
    History elements for the child posts.  This tracks updates to
    them and can be used as needed.

    Collection: piazza_content_children_history

    Relations:
    * Dataset: Link to the associated Dataset.
    * Parent: Link to parent PiazzaContent_Child instance.
    * Author: Link to PiazzaUser author instance. 
    * CentralAuthor: The Central author object for this user.

    Fields:
    * Course_ID: ID of the associated Dataset.
    * Parent_ID: unique mongodb id of the child post.
    * Author_ID: unique mongodb id of the author.   
    * CentralAuthor_ID: Mongoid of the Central author of this change.
    * _id: Mongodb object ID (unique).
    * ThreadID: (int) Unknown int believed to be post number.
    * content: (string) Content of the history change. 
    * anon: (string) Whether this was an anonymous change.
    * subject: (string) Subject of the content.
    * uid: (string) Piazza id of the author (may be hidden if anon).
    * created: (datetime) Datetime this was created. 
    """

    # ---------------------------------------------
    # Mongometa information.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "piazza_content_children_history"

    
    # ------------------------------------------------
    # Link information.
    # ================================================

    # Link to the associated Dataset.
    Course_ID = ForeignIdProperty('Dataset')
    Course    = RelationProperty('Dataset')

    # Parent Piazza Content.
    Parent_ID = ForeignIdProperty('PiazzaContent_Child')
    Parent = RelationProperty('PiazzaContent_Child')

    # Link to the associated user.
    Author_ID = ForeignIdProperty('PiazzaUser.PiazzaUser')
    Author = RelationProperty('PiazzaUser.PiazzaUser')

    # Direct link to the central author instance.
    CentralAuthor_ID = ForeignIdProperty('User')
    CentralAuthor = RelationProperty('User')


    # ------------------------------------------------
    # Fields
    # ================================================

    # Mongodb object ID (unique).
    _id     = FieldProperty(schema.ObjectId)
    
    # int for post number.
    ThreadID = FieldProperty(int)

    # Content of the history change. 
    content = FieldProperty(str)

    # Whether this was an anonymous change.
    anon = FieldProperty(str)

    # Subject of the content.
    subject = FieldProperty(str)

    # UID of the author (may be hidden if anon).
    uid = FieldProperty(str)

    # Datetime this was created. 
    created = FieldProperty(datetime.datetime)

    # ---------------------------------------------
    # Anonymization Code.
    # =============================================

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Histories = findAllChildHistories(DatasetID=DatasetID)
        for H in Histories:
            H.uid = None
        ModSocDB.Session.flush()
Пример #5
0
class History(MappedClass):
    """
    History record defenition

    """
    class __mongometa__:
        session = DBSession
        name = 'history'

    _id = FieldProperty(s.ObjectId)
    history_id = FieldProperty(s.Int)

    _user_id = ForeignIdProperty(User)
    user = RelationProperty(User)

    _box_id = ForeignIdProperty(Box)
    box = RelationProperty(Box)

    datetime = FieldProperty(s.datetime)

    info = FieldProperty(s.String)

    @staticmethod
    def add_record(user_name, box_id, info):
        """
        Add new history record to db

        Args:
            user_name (string): user name
            box_id (id): related box id in db
            info (string): info

        """

        record = History()
        record.history_id = Counter.get_next_id('history')
        record.user = User.query.get(user_name=user_name)
        if box_id is not None:
            record.box = Box.query.get(box_id=box_id)
        record.datetime = datetime.now()
        record.info = info

        DBSession.flush()
        DBSession.clear()

    @staticmethod
    def get_all_user_records(user_id):
        """
        Get all user history records from db

        Args:
            user_id (int): user id in db

        Returns:
            Collection of all history records

        """

        return History.query.find({'_user_id': user_id})

    @staticmethod
    def get_all_records():
        """
        Get all history records from db

        Returns:
            Collection of all history records

        """

        return History.query.find()
Пример #6
0
class Document(MappedEntity):
    class __mongometa__:
        session = DBSession
        name = 'documents'
        indexes = [('_owner', ), ('public', ), ('title', ), ('_workspace', ),
                   ('html', 'text')]
        extensions = [TriggerExtension]

    def custom_title(self):
        return Markup("<a href='%s'>%s</a>" % (tg.url(
            '/document/edit',
            params=dict(_id=self._id, workspace=self._workspace)), self.title))

    def content_preview(self):
        from ksweb.lib.utils import five_words
        return five_words(self.html)

    __ROW_COLUM_CONVERTERS__ = {
        'title': custom_title,
        'content': content_preview
    }

    html = FieldProperty(s.String, required=True, if_missing='')
    description = FieldProperty(s.String, required=False)
    license = FieldProperty(s.String, required=False)
    version = FieldProperty(s.String, required=False)
    tags = FieldProperty(s.Anything, required=False)

    @classmethod
    def document_available_for_user(cls, user_id, workspace=None):
        return User.query.get(_id=user_id).owned_entities(cls, workspace)

    @property
    def entity(self):
        return 'document'

    @property
    def children(self):
        from ksweb.lib.utils import get_entities_from_str
        outputs, __ = get_entities_from_str(self.html)
        return outputs

    @property
    def content(self):
        return [{
            'content': str(__._id),
            'title': __.title,
            'type': 'output'
        } for __ in self.children]

    def exportable_dict(self):
        filter_out = ['_workspace', '_owner', 'created_at', '_id']
        filter_json = {
            k: v
            for k, v in self.__json__().items() if k not in filter_out
        }
        for __ in [
                'outputs', 'advanced_preconditions', 'qa',
                'simple_preconditions'
        ]:
            filter_json[__] = {}
        return filter_json

    def export_items(self):
        items = set()
        [items.update(__.export_items()) for __ in self.children]
        items.discard(None)
        return items

    def __group_export_items_by_type(self):
        from itertools import groupby
        items = list(self.export_items())
        items.sort(key=lambda __: __.entity)
        return {k: list(v) for k, v in groupby(items, lambda __: __.entity)}

    def export(self):
        json_result = self.exportable_dict()
        items = self.__group_export_items_by_type()
        content_types = {
            'qa': 'qa',
            'output': 'outputs',
            'precondition/simple': 'simple_preconditions',
            'precondition/advanced': 'advanced_preconditions'
        }
        for entity_name, export_name in content_types.items():
            for __ in items.get(entity_name, []):
                json_result[export_name][__.hash] = __.exportable_dict()

        return json_result
Пример #7
0
class Dataset(MappedClass):
    """
    The Dataset class has a simple pair of fields and acts as
    an index to more complex content.  It should have a set of
    relations to the underlying indexed content such as users
    and content as they are needed.  
    
    Collection: Datasets

    Relations:
    * Users:       A list of users in this dataset.
    * PiazzaUsers: A list of Piazza Users in this dataset.
    * ExamGrades:  A list of all the exam grades from this dataset.

    
    Fields:
    * _id: Unique  Mongodb ID.
    * ShortName:   Mnemonic name.
    * LongName:    Full name.
    * Description: Descriptive text.
    """

    # ---------------------------------------------
    # Mongometa information.
    #
    # You should change only the "name" field to be
    # the name of the associated database collection.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "datasets"

    # ------------------------------------------------
    # Link information.
    #
    # The dataset is a hub class.  It should have a link here
    # to every single other class who will connect to it with
    # a back-link and an ID to make it link back.
    #
    # TODO:: Add back-links to Piazza Data.
    # ================================================

    # Base Classes.
    # -------------------------------------------------
    Users = RelationProperty('User')

    # Piazza Classes
    # ------------------------------------------------
    PiazzaUsers = RelationProperty('PiazzaUser')

    # Grade Classes, removed since was not being filled anymore
    # ---------------------------------------------
    # ExamGrades = RelationProperty("ExamGrade")

    # ------------------------------------------------
    # Link information.
    #
    # Every object will have an _id field so that need
    # not be changed.  Other lines will be a FieldProperty
    # for the association information.
    # ================================================

    # Mongodb object ID (unique).
    _id = FieldProperty(schema.ObjectId)

    # ShortName: Mnemonic name.
    ShortName = FieldProperty(str)

    # LongName: Full name.
    LongName = FieldProperty(str)

    # Description: Descriptive text.
    Description = FieldProperty(str)

    # -------------------------------------------------
    # Accessors
    # =================================================

    def getShortName(self):
        """
        Get the short name of the dataset.
        """
        return self.ShortName

    # -------------------------------------------------
    # Input Functions.
    # =================================================

    @staticmethod
    def loadDescriptionFile(DescFile):
        """
        Load the supplied description file and return
        a new instance of a Dataset with it.

        Note, this does *not* add it to the database
        with a flush.  That is up to the user.
        """
        In = open(DescFile)

        # Read in the ShortName from the top of the list.
        NewShort = In.readline()[:-1]

        # Read the Long name.
        NewLong = In.readline()[:-1]

        # Read in the remaining text.
        NewDesc = ""
        for Line in In.readlines():
            NewDesc += Line

        In.close()

        # Generate the new Dataset instance.
        NewDataset = Dataset(ShortName=NewShort,
                             LongName=NewLong,
                             Description=NewDesc)
        return NewDataset
Пример #8
0
        class GrandParent(MappedClass):
            class __mongometa__:
                name = 'grand_parent'
                session = self.session

            _id = FieldProperty(int)
Пример #9
0
        class Derived(Base):
            class __mongometa__:
                polymorphic_identity = 'derived'

            type = FieldProperty(str, if_missing='derived')
            b = FieldProperty(int)
Пример #10
0
class PiazzaContent_Child_Endorsement(MappedClass):
    """
    This class deals with the TagEndorse Dict element of the
    child elements.  This is a list of all of the users that
    chose to endorse this child post as being good.

    Collection: piazza_content_children_tagendorse

    Relations:
    * Dataset: Link to the associated Dataset.
    * Parent: PiazzaContent_Child instance.
    * Author: PiazzaUser instance who authored this.
    * CentralAuthor: The Central author object for this user.

    Fields:
    * Dataset_ID: ID of the associated Dataset.
    * Parent_ID: Mongodb ID of the Piazza Content Child that
                 this is an endorsement of
    * Author_ID: Mongodb id of the piazza user that endorsed
                 this content.
    * CentralAuthor_ID: Mongoid of the Central author of this change.
    * _id: unique mongodb Id.
    * name: (string) piazza user name if included.
    * admin: (bool) flag indicating whether the user was in admin status
             when this endorsement was made.
    * photo: (string) binary string representing the user photo if uploaded.
    * email: (string) the endorsers e-mail if given.
    * role: (string) the endorsers role at the time of endorsement.
    * facebook_id: (string) the facebook id of the endorsing party.
    * class_sections: (string) class section of the endorser.
    * admin_permission: (int) numerical indication of whether the admin
                         permission was used.
    """

    # ---------------------------------------------
    # Mongometa information.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "piazza_content_children_tagendorse"

    # ------------------------------------------------
    # Link information.
    # ================================================

    # Link to the associated Dataset.
    Dataset_ID = ForeignIdProperty('Dataset')
    Dataset = RelationProperty('Dataset')

    # Parent Piazza Content.
    Parent_ID = ForeignIdProperty('PiazzaContent_Child')
    Parent = RelationProperty('PiazzaContent_Child')

    # Link to the associated user.
    Author_ID = ForeignIdProperty('PiazzaUser.PiazzaUser')
    Author = RelationProperty('PiazzaUser.PiazzaUser')

    # Direct link to the central author instance.
    CentralAuthor_ID = ForeignIdProperty('User')
    CentralAuthor = RelationProperty('User')

    # ------------------------------------------------
    # Fields
    # ================================================

    # Mongodb object ID (unique).
    _id = FieldProperty(schema.ObjectId)

    # User name.
    name = FieldProperty(str)

    # Admin status for the user at the time this was done?
    admin = FieldProperty(bool)

    # String content for a photo.
    photo = FieldProperty(str)

    # False for all the data, so removed
    # us = FieldProperty(bool)

    # User e-mail.
    email = FieldProperty(str)

    # Role of the user at the time done.
    role = FieldProperty(str)

    # Facebook id of the user.
    facebook_id = FieldProperty(str)

    # Id of the author, redundant so removed
    # id = FieldProperty(str)

    # Class section of the endorsement.
    class_sections = FieldProperty([str])

    # Admin permissions used?
    admin_permission = FieldProperty(int)

    # ---------------------------------------------
    # Anonymization Code.
    # =============================================

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Endorsements = findAllChildEndorsements(DatasetID=DatasetID)
        for E in Endorsements:
            E.name = None
            E.email = None
            E.id = None
        ModSocDB.Session.flush()
Пример #11
0
        class Test(MappedClass):
            class __mongometa__:
                indexes = ['abc']

            _id = FieldProperty(S.Int)
            abc = FieldProperty(S.Int, if_missing=None)
Пример #12
0
class GeoIP(MappedClass):
    """
    GeoIP definition.
    """
    class __mongometa__:
        session = DBSession
        name = 'geoip'
        indexes = [('country', ), ('country_code', )]
        unique_indexes = [('range1', ), ('range2', )]

    def __json__(self):
        return dict(country=self.country,
                    country_code=self.country_code,
                    region=self.region,
                    city=self.city,
                    latitude=self.lat,
                    longitude=self.lng,
                    zipcode=self.zipcode,
                    timezone=self.timezone)

    _id = FieldProperty(s.ObjectId)
    range1 = FieldProperty(s.Int)
    range2 = FieldProperty(s.Int)
    country = FieldProperty(s.String)
    country_code = FieldProperty(s.String)
    region = FieldProperty(s.String)
    city = FieldProperty(s.String)
    lat = FieldProperty(s.String)
    lng = FieldProperty(s.String)
    zipcode = FieldProperty(s.String)
    timezone = FieldProperty(s.String)

    @classmethod
    def getRange(cls, decimal_ip):
        return cls.query.find({
            "range1": {
                "$lt": decimal_ip
            },
            "range2": {
                "$gt": decimal_ip
            }
        }).first()
Пример #13
0
class Action(MappedClass):
    class __mongometa__:
        session = model.DBSession
        name = 'activity_stream_action'
        indexes = [
            (('actor_id', ), ('timestamp', DESCENDING)),
            ('actor_type', ),
            (('_recipients.recipient_id', ), ('timestamp', DESCENDING)),
            ('_recipients.recipient_type', ),
        ]

    _id = FieldProperty(s.ObjectId)

    actor_type = FieldProperty(s.String)
    actor_id = FieldProperty(s.ObjectId)

    verb = FieldProperty(s.String)

    description = FieldProperty(s.String)
    extra = FieldProperty(s.String)

    target_type = FieldProperty(s.String)
    target_id = FieldProperty(s.ObjectId)

    action_obj_type = FieldProperty(s.String)
    action_obj_id = FieldProperty(s.ObjectId)

    timestamp = FieldProperty(s.DateTime, if_missing=datetime.utcnow)

    _recipients = FieldProperty(
        s.Array(s.Object(fields={
            '_type': s.String,
            '_id': s.ObjectId
        })))

    @property
    def timestamp_24_hh_mm(self):
        return datetime.strftime(self.timestamp, '%X')

    @cached_property
    def actor(self, default=None):
        if not (self.actor_type and self.actor_id):
            return default
        entity = get_obj(self.actor_type, self.actor_id)
        return getattr(entity, 'as_str', entity)

    @cached_property
    def target(self, default=None):
        if not (self.target_type and self.target_id):
            return default
        entity = get_obj(self.target_type, self.target_id)
        return getattr(entity, 'as_str', entity)

    @property
    def target_link(self):
        entity = get_obj(self.target_type, self.target_id)
        return getattr(entity, 'as_link', None)

    @property
    def action_obj(self, default=None):
        if not (self.action_obj_type and self.action_obj_id):
            return default
        return get_obj(self.action_obj_type, self.action_obj_id)

    @property
    def timestamp_since(self):
        diff = datetime.utcnow() - self.timestamp

        minutes = diff.total_seconds() / 60

        if minutes <= 1:
            timestamp_since_ = _(u'less than 1 minute ago')
        elif int(minutes) == 1:
            timestamp_since_ = _(u'about 1 minute ago')
        elif minutes < 60:
            timestamp_since_ = _(u'about %s minutes ago') % int(minutes)
        elif 60 <= minutes < 119:
            timestamp_since_ = _(u'about 1 hour ago')
        elif minutes < 60 * 24:
            timestamp_since_ = _(u'about %s hours ago') % int(minutes / 60)
        else:
            timestamp_since_ = datetime.strftime(self.timestamp, '%x')

        return timestamp_since_

    @property
    def recipients(self):
        return (get_obj(r._type, r._id) for r in self._recipients)

    @classmethod
    def get_by_recipient(cls, recipient):
        return cls.query.find({
            '$or': [{
                '_recipients._id': instance_primary_key(recipient)
            }, {
                '_recipients': {
                    '$eq': None
                }
            }]
        }).sort('timestamp', DESCENDING)

    @classmethod
    def count_not_seen_by_recipient(cls, recipient):
        return cls.query.find({
            '$or': [
                {
                    '_recipients._id': instance_primary_key(recipient)
                },
                {
                    '_recipients': {
                        '$eq': None
                    }
                },
            ],
            'timestamp': {
                '$gt': recipient.last_activity_seen
            },
        }).count()

    @classmethod
    def render_str(cls, action, **kw):
        '''

        <actor> <verb> <time>
        <actor> <verb> <target> <time>
        <actor> <verb> <action_object> <target> <time>
        '''

        timestamp_format = kw.get('timestamp_format',
                                  lambda t: datetime.strftime(t, '%x'))
        timestamp_since = None

        if kw.get('timestamp_since', False):
            timestamp_since = action.timestamp_since

        str_ = u'{actor} {verb} {action_object} {target} {time}'.format(
            actor=action.actor,
            verb=action.verb,
            target=action.target or '',
            action_object=action.action_obj or '',
            time=timestamp_since or timestamp_format(action.timestamp))

        return str_
Пример #14
0
class Precondition(MappedClass):
    PRECONDITION_TYPE = [u"simple", u"advanced"]
    PRECONDITION_OPERATOR = ['and', 'or', 'not', '(', ')']
    PRECONDITION_CONVERTED_OPERATOR = ['&', '|', 'not', '(', ')']

    class __mongometa__:
        session = DBSession
        name = 'preconditions'
        indexes = [
            ('_owner', ),
        ]

    __ROW_COLUM_CONVERTERS__ = {
        'title': _custom_title,
        'content': _content_preview
    }

    _id = FieldProperty(s.ObjectId)

    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    _category = ForeignIdProperty('Category')
    category = RelationProperty('Category')

    title = FieldProperty(s.String, required=False)
    type = FieldProperty(s.OneOf(*PRECONDITION_TYPE), required=True)
    condition = FieldProperty(s.Anything)
    """
    In case of type: simple
    the condition is like: [ObjectId('qa'), 'String_response']

    In case of type advanced
    the condition is like: [ObjectId(precond_1), &, ObjectId(precond_2), | , ObjectId(precond_3)]
    """

    public = FieldProperty(s.Bool, if_missing=True)
    visible = FieldProperty(s.Bool, if_missing=True)

    @classmethod
    def precondition_available_for_user(cls, user_id, workspace=None):
        if workspace:
            return cls.query.find({
                '_owner': user_id,
                'visible': True,
                '_category': ObjectId(workspace)
            }).sort('title')
        return cls.query.find({
            '_owner': user_id,
            'visible': True
        }).sort('title')

    @property
    def evaluate(self):
        if self.type == 'simple':
            print("evaluate simple precondition")
            return
        if self.type == 'advanced':
            print("evaluate advanced precondition")
            return

    @property
    def is_simple(self):
        return self.type == 'simple'

    @property
    def response_interested(self):
        """
        Example of the return value
        {
            '5772314bc42d7513bb31e17c': <Qa title=u'Sesso'
              _category=ObjectId('575581e4c42d75124a0a9601')
              question=u'Di che sesso sei?' tooltip=None visible=True
              _owner=ObjectId('575581e4c42d75124a0a95fc') link=None
              answers=I[u'Maschio', u'Femmina']
              _id=ObjectId('5772314bc42d7513bb31e17c') type=u'single'
              public=True>,
            '57723171c42d7513bb31e17d': <Qa title=u'Colori'
              _category=ObjectId('575581e4c42d75124a0a9602')
              question=u'Che colori ti piacciono?' tooltip=u'che colori
              ti piacciono' visible=True
              _owner=ObjectId('575581e4c42d75124a0a95fc') link=None
              answers=I[u'Rosso', u'Verde', u'Blu', u'Giallo']
              _id=ObjectId('57723171c42d7513bb31e17d') type=u'multi'
              public=True>
        }
        :return:
        """
        res_dict = {}
        if self.type == 'simple':
            qa = Qa.query.get(_id=self.condition[0])
            res_dict[str(qa._id)] = qa
            if qa.parent_precondition:
                res_dict.update(qa.parent_precondition.response_interested)
            return res_dict
        for cond in self.condition:
            if cond in Precondition.PRECONDITION_OPERATOR:
                continue
            else:
                rel_ent = Precondition.query.get(_id=ObjectId(cond))
                print(cond)
                res_dict.update(rel_ent.response_interested)

        return res_dict

    def get_qa(self):
        from . import Qa
        if not self.is_simple:
            return None
        return Qa.query.get(_id=ObjectId(self.condition[0]))

    @property
    def simple_text_response(self):
        """
        Usato per verificare i filtri di tipo testo che abbiano risposta
        :return:
        """
        return self.type == "simple" and self.condition[1] == ""

    @property
    def multiple_choice_response(self):
        if self.is_simple:
            qa = self.get_qa()
            return qa.is_multi
        return False

    @property
    def single_choice_response(self):
        if self.is_simple:
            qa = self.get_qa()
            return qa.is_single
        return False

    @property
    def entity(self):
        return 'precondition/simple' if self.is_simple else 'precondition/advanced'

    def __json__(self):
        from ksweb.lib.utils import to_dict
        _dict = to_dict(self)
        _dict['entity'] = self.entity
        return _dict
Пример #15
0
class Timeable(MappedClass):
    created_at = FieldProperty(DateTime(if_missing=datetime.utcnow))
    updated_at = FieldProperty(DateTime(if_missing=datetime.utcnow))

    class __mongometa__:
        extensions = [UpdatedAtExtension]
Пример #16
0
class Document(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'documents'
        indexes = [
            ('_owner', ),
            ('public', ),
            ('title', ),
            ('_category', ),
        ]

    __ROW_COLUM_CONVERTERS__ = {
        'title': _custom_title,
        'content': _content_preview
    }

    _id = FieldProperty(s.ObjectId)

    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    _category = ForeignIdProperty('Category')
    category = RelationProperty('Category')

    title = FieldProperty(s.String, required=True)

    html = FieldProperty(s.String, required=True, if_missing='')

    content = FieldProperty(s.Anything, required=True)

    description = FieldProperty(s.String, required=False)
    licence = FieldProperty(s.String, required=False)
    version = FieldProperty(s.String, required=False)
    tags = FieldProperty(s.Anything, required=False)
    """
    Possible content of the document is a list with two elements type:
        - text
        - output

        If the type is text the content contain the text
        If the type is output the content contain the obj id of the related output


        An example of the content is this
        "content" : [
            {
                "content" : "575eb879c42d7518bb972256",
                "type" : "output",
                "title" : "ciao"
            },
        ]
    """

    public = FieldProperty(s.Bool, if_missing=True)
    visible = FieldProperty(s.Bool, if_missing=True)

    @classmethod
    def document_available_for_user(cls, user_id, workspace=None):
        return User.query.get(_id=user_id).owned_entities(cls, workspace)

    @property
    def entity(self):
        return 'document'

    @property
    def upcast(self):
        from ksweb.lib.utils import _upcast
        """
        This property replace widget placeholder into html widget

        {output_589066e6179280afa788035e}
            ->
        <span class="objplaceholder output-widget output_589066e6179280afa788035e"></span>
        """
        return _upcast(self)

    def __json__(self):
        from ksweb.lib.utils import to_dict
        _dict = to_dict(self)
        _dict['entity'] = self.entity
        return _dict
Пример #17
0
        class Parent(MappedClass):
            class __mongometa__:
                name = 'parent'
                session = self.session

            _id = FieldProperty(S.ObjectId)
Пример #18
0
class PiazzaContent(MappedClass):
    """
    The PiazzaContent class is used to represent the PiazzaContent
    with the complex sub-classes such as children linked separately
    allowing us to iterate over all of the elements and the sub-
    posts.

    Collection: piazza_content

    Relations:
    --------------------------------------------------------
    * Dataset: Link to the associated Dataset.
    * Author: PiazzaUser who wrote the Content.
    * CentralAuthor: The Central author object for this user.
    * GoodTags: Relationship with good tags by this user. The GoodTag objects are used intermediately. They get removed while data cleanup
    * History: Relationship with edited history elements.
    * ChangeLog: Change Log listing.
    * Children: Child Posts.

    Fields:
    --------------------------------------------------------
    * Course_ID: ID of the associated Dataset.
    * Author_ID: Mongo ID of the associated PiazzaUser.
    * CentralAuthor_ID: Mongoid of the Central author of this change.
    * _id: Mongodb object ID (unique).
    * tags: (list of strings) Array of Tags on the posts.
    * status: (string) Status of the post.
    * folders: (list of strings) List of folders this is a part of.
    * id: piazza id of post.
    * type: (string) Post system type.
    * unique_views: (int) View count.
    * created: (datetime) Date created.
    * ThreadID: (int) An ID, same for each post and all the follow-ups
    * no_answer_followup: (int) Followups with no answer?
    * tag_good_arr(str): Array of "good" tags, ids of GoodTags related to this post. 
    *   This is kept because GoodTags are intermediate. They get filled while initialization
    *   and get removed while cleanup. This should be used to access good tags
     
    """

    # ---------------------------------------------
    # Mongometa information.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "piazza_content"


    # ---------------------------------------------
    # Link Information
    # =============================================

    # Link to the associated Dataset.
    Course_ID = ForeignIdProperty('Dataset')
    Course    = RelationProperty('Dataset')

    # Link to the associated PiazzaUser (author of the content)
    Author_ID = ForeignIdProperty('PiazzaUser')
    Author = RelationProperty('PiazzaUser')

    # Direct link to the central author instance.
    CentralAuthor_ID = ForeignIdProperty('User')
    CentralAuthor = RelationProperty('User')

    # Relationship with good tags by this user.
    # The GoodTag objects are used intermediately. They get removed while data cleanup
    GoodTags = RelationProperty("PiazzaContent_TagGood")

    # Relationship with edited history elements.
    History = RelationProperty("PiazzaContent_History")

    # Change Log listing.
    ChangeLog = RelationProperty("PiazzaContent_ChangeLog")

    # Children.
    Children = RelationProperty("PiazzaContent_Child")

    
    # ------------------------------------------------------------
    # Fields
    # =================================================

    # Mongodb object ID (unique).
    _id     = FieldProperty(schema.ObjectId)


    # Status of the post. active or private
    status = FieldProperty(str)

    # Array of "good" tags, ids of GoodTags related to this post. 
    # This is kept because GoodTags are intermediate. They get filled while initialization
    # and get removed while cleanup. This should be used to access good tags
    tag_good_arr = FieldProperty([str])

    # List of folders this is a part of.
    folders = FieldProperty([str])

    # Post key ID.
    id = FieldProperty(str)

    # Post system type. note, question, or poll
    type = FieldProperty(str)

    # View count.
    unique_views = FieldProperty(int)

    # Date created.
    created = FieldProperty(datetime.datetime)
    # created = FieldProperty(str)

    # int for post number.
    ThreadID = FieldProperty(int)

    # Followups with no answer?
    no_answer_followup = FieldProperty(int)


    # ------------------------------------------------------------
    # Anonymization Methods.
    # =================================================

    def resetTagGoodArr(self, UIDMap):
        """
        The Tag_Good_array contains a list of users who have
        tagged this array as good via the links.  This code
        will iterate over the contents of the TagGood array
        updating with the new user IDs.
        """
        NewArr = []
        for ID in self.tag_good_arr:
            if ID in UIDMap:
                NewArr.append(UIDMap[ID])
            else:
                print "User with id %s not fount in UIDMap to be updated in tag_good_arr" % ID
        self.tag_good_arr = NewArr
        # self.tag_good_arr = [T.id for T in self.GoodTags]




    # ----------------------------------------------------
    # Relational Accessors.
    # ====================================================

    def getFirstSubject(self):
        """
        Get the first subject line for the content from the first history.
        """
        FirstHist = self.getEarliestHistory()
        return FirstHist.subject
    
    
    def getEarliestHistory(self):
        """
        Get the earliest history entry by date.
        """
        First = self.History[0]

        for Hist in self.History[1:]:
            if (Hist.created < First.created):
                First = Hist

        return First

    
    def getFirstAuthor(self):
        """
        Get the first author of this content based upon the
        history entries.
        """
        Hist = self.getEarliestHistory()
        return Hist.Author

    def getLatestHistory(self):
        if len(self.History) < 1:
            # print 'hereeee', self.subject
            return None
        Last = self.History[0]

        # print 'some history found', len(self.History)
        for Hist in self.History[1:]:
            if ((Hist.created > Last.created) and Hist.subject and Hist.content):
                Last = Hist

        return Last

    def getAuthors(self):
        """
        This code iterates over the history extracting all authors
        from the content updates.
        """
        Authors = []
        for Hist in self.History:
            if (not Hist.Author in Authors):
                Authors.append(Hist.Author)
        return Authors


    def getOlderChildren(self, Date):
        """
        Get children that predate the specified cutoff
        """
        return [ C for C in self.Children
                 if (C.created <= Date) ]
    
    
    # ---------------------------------------------
    # Anonymization Code.
    # =============================================

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Contents = findAllContent(DatasetID=DatasetID)
        for C in Contents:
            C.id = None
        ModSocDB.Session.flush()
Пример #19
0
class TokenDAO(MappedClass):

    class __mongometa__:
        session = session
        name = 'token'

    _id = FieldProperty(schema.ObjectId)
    token_gui = FieldProperty(schema.String)
    description = FieldProperty(schema.String)
    max_dataset_count = FieldProperty(schema.Int)
    max_dataset_size = FieldProperty(schema.Int)
    creation_date = FieldProperty(schema.datetime)
    modification_date = FieldProperty(schema.datetime)
    end_date = FieldProperty(schema.datetime)
    privileges = FieldProperty(schema.Int)
    url_prefix = FieldProperty(schema.String)
    _datasets= ForeignIdProperty('DatasetDAO', uselist=True)

    class DIterator(object):
        def __init__(self, dataset_list):
            try:
                self.cursor = DatasetDAO.query.find({'_id': {'$in': list(dataset_list)}})
            except Exception as ex:
                print(ex)
                exit(0)

        def __iter__(self):
            return self.cursor

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


    @property
    def datasets(self):
        return self.DIterator(self._datasets)

    def __init__(self, description, max_dataset_count, max_dataset_size, url_prefix, token_gui=None,
                 creation_date=now(), modification_date=now(), end_date=token_future_end(),
                 privileges=Privileges.RO_WATCH_DATASET):

        if token_gui is None:
            token_gui = self.generate_token()
        else:
            if self.query.get(token_gui=token_uuid) is not None:
                raise Exception("Specified token GUI already exists.")

        kwargs = {k: v for k, v in locals().items() if k not in ["self", "__class__"]}
        super().__init__(**kwargs)

    def generate_token(self):

        token_uuid = str(uuid.uuid4().hex)
        while self.query.get(token_gui=token_uuid) is not None:
            token_uuid = str(uuid.uuid4().hex)

        return token_uuid

    def unlink_dataset(self, dataset):
        return self.unlink_datasets([dataset])

    def unlink_datasets(self, datasets):
        datasets_translated = [d._id for d in datasets]
        self._datasets = [d for d in self._datasets if d not in datasets_translated]
        return self

    def link_dataset(self, dataset):
        return self.link_datasets([dataset])

    def link_datasets(self, datasets):
        self._datasets += [d._id for d in datasets]
        return self

    def has_dataset(self, dataset):
        return self.has_dataset_id(dataset._id)

    def has_dataset_id(self, dataset_id: ObjectId):
        return dataset_id in self._datasets

    def update(self):
        return session.refresh(self)

    def serialize(self):
        fields = ["token_gui", "url_prefix", "description", "max_dataset_count",
                  "max_dataset_size", "creation_date",
                  "modification_date", "end_date", "privileges"]

        return {f: str(self[f]) for f in fields}
Пример #20
0
class Questionary(MappedClass):
    __ROW_COLUM_CONVERTERS__ = {
        'title': _compile_questionary,
        '_owner': _owner_name,
        '_user': _shared_with,
    }

    class __mongometa__:
        session = DBSession
        name = 'questionaries'
        indexes = [
            ('_user',),
            ('_owner',),
            ('_document',),
        ]

    _id = FieldProperty(s.ObjectId)

    title = FieldProperty(s.String, required=False)

    #  User is the the target of the questionary
    _user = ForeignIdProperty('User')
    user = RelationProperty('User')

    #  Owner is the owner of the questionary who send id to the user
    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    #  Document is the related document
    _document = ForeignIdProperty('Document')
    document = RelationProperty('Document')

    # document_values = FieldProperty(s.Anything, if_missing=[])
    """
    A list with a compiled document values
    """

    expressions = FieldProperty(s.Anything, if_missing={})

    output_values = FieldProperty(s.Anything, if_missing={})
    """
    Is a nested dictionary with:
    key: Obj(id) of the related output
    value:
        evaluation: Boolean evaluation of the related precondition, for determinate if show,
                    or hide the related output text
        evaluated_text: Text of the related output when is evaluated
    """

    precond_values = FieldProperty(s.Anything, if_missing={})
    """
    Is a dictionary with:
    key: Obj(id) of the precondition
    value: Boolean evaluation of the precondition
           True: if true
           False: if False
           None: if is not yet processed
    """

    qa_values = FieldProperty(s.Anything, if_missing={})
    """
    Is a dictionary with:
    key: Obj(id) of the qa
    value:
        In case of text or single response of the qa, the response are simply text.
        In case of multiple response of the qa, the response is a list with ['Res1', 'Resp4']
    """

    @property
    def creation_date(self):
        return self._id.generation_time

    @property
    def completion(self):
        log.error(self.evaluate_questionary)
        if self.evaluate_questionary.get('completed', False):
            return "100 %"
        if not len(self.expressions):
            return "0 %"
        return "%d %%" % int(len(self.qa_values)*1.0/len(self.expressions)*100)

    @property
    def evaluate_questionary(self):
        log.debug("evaluate_questionary")
        """
        Valutazione del questionario, ogni volta svuoto i valori delle valutazioni di documenti,
        output e precond, così nel caso venga riaperto il questionario dopo che è stata inserita
        una nuova domanda, viene ricalcolato tutto e sarà aggiornato.
        Va a recuperare il documento collegato e ne analizza tutto il content
        :return: Se a tutti gli output del content sono stati valutati restituisce come stato
                 completed: True
        :return: Se invece non sono stati ancora valutati degli output restituisce come stato
                 completed: False e la qa alla quale bisogna rispondere
        """

        # self.document_values = []
        self.output_values = {}
        self.generate_expression()

        # document contains outputs only
        for output in self.document.content:
            output_id = output['content']
            output_res = self.evaluate_expression(output_id)

            if not output_res['completed']:
                return output_res
            else:
                if self.output_values[output_id].get('evaluation'):
                    res = self.compile_output(output_id)
                    # this need for to show other questions though output is already evaluated,
                    # for example when output uses some response to a certain questions
                    if res:
                        return res

        return {
            'completed': True
        }

    def generate_expression(self):
        log.debug("generate_expression")
        from . import Output
        for o in self.document.content:
            output = Output.query.get(_id=ObjectId(o['content']))
            self.expressions[str(output._id)] = self._generate(output.precondition)

    def _generate(self, precondition):
        log.debug("_generate")
        parent_expression, expression = '', ''
        if not precondition:
            return "()"

        if precondition.is_simple:
            qa = precondition.get_qa()

            if qa._parent_precondition:
                parent_expression = '(' + self._generate(qa.parent_precondition) + ') and '
            if precondition.simple_text_response:
                expression = "q_%s != ''" % str(precondition.condition[0])
            elif precondition.single_choice_response:
                expression = "q_%s == %s" % (str(precondition.condition[0]),
                                             repr(precondition.condition[1]))
            elif precondition.multiple_choice_response:
                expression = "%s in q_%s" % (str(repr(precondition.condition[1])),
                                             precondition.condition[0])
            return parent_expression + expression
        else:
            advanced_expression = ""
            for item in precondition.condition:
                if isinstance(item, basestring):
                    advanced_expression += ' %s ' % item
                elif isinstance(item, ObjectId):
                    from . import Precondition
                    p = Precondition.query.get(_id=item)
                    advanced_expression += '( %s )' % self._generate(p)

        return advanced_expression

    def compile_output(self, output_id):
        log.debug("compile_output")

        """
        Questo metodo serve per salvare direttamente dell'output in chiaro nel risultato finale del
        questionario.

        Questo metodo appende all'array di stringhe document_values i vari componenti trovati nel
        documento, che siano testo semplice o risposte, un elemento per ogni cella dell'array

        :param output_id:

        """
        from . import Output
        output = Output.query.get(_id=ObjectId(output_id))

        for elem in output.content:
            if elem['type'] == "qa_response":
                content = self.qa_values.get(elem['content'])
                if not content:
                    # no answer found for this question
                    return {'qa': elem['content']}
            elif elem['type'] == 'output':  # nested output
                output_nested_id = elem['content']
                output_nested = Output.query.get(_id=ObjectId(output_nested_id))
                if output_nested.precondition:
                    self.expressions[str(output_nested_id)] = self._generate(output_nested.precondition)
                    output_res = self.evaluate_expression(output_nested_id)
                else:
                    log.error(output_nested)
                    log.error(elem['content'])
                if not output_res['completed']:
                    return output_res
                else:
                    if self.output_values[output_nested_id].get('evaluation'):
                        res = self.compile_output(output_nested_id)
                        # this need for to show other questions though output is already evaluated,
                        # for example when output uses some response to a certain questions
                        if res:
                            return res
        return None

    def evaluate_expression(self, output_id):
        log.debug("evaluate_expression")

        expression = self.expressions[output_id]

        answers = dict()

        for _id, resp in self.qa_values.items():
            answer = resp['qa_response']
            if isinstance(answer, basestring):
                answers['q_' + _id] = answer
            else:
                # array
                answers['q_' + _id] = "[%s]" % ' ,'.join(map(lambda x: "'%s'" % x, answer))

        try:
            evaluation = eval(expression, answers)
        except NameError as ne:
            message = str(getattr(ne, 'message', ne))
            _id = message.split("'")[1][2:]
            return {
                'completed': False,
                'qa': _id
            }

        self.output_values[output_id] = {
            'evaluation': evaluation
        }

        DBSession.flush_all()

        return {
            'completed': True
        }
Пример #21
0
class Box(MappedClass):
    """
    Box definition

    """
    class __mongometa__:
        session = DBSession
        name = 'box'

    _id = FieldProperty(s.ObjectId)
    box_id = FieldProperty(s.Int)

    datetime_of_creation = FieldProperty(s.datetime)
    datetime_of_modify = FieldProperty(s.datetime)

    _user_id = ForeignIdProperty(User)
    user = RelationProperty(User)

    port = FieldProperty(s.Int)
    status = FieldProperty(s.String)
    name = FieldProperty(s.String)
    vagrantfile_path = FieldProperty(s.String)

    @staticmethod
    def add_new_box(user_name, box_name, port, vagrantfile_path):
        """
        Add new box to db

        Args:
            user_name (string): user name
            box_name (string): name of new box
            vagrantfile_path (string): path to vagrantfile\

        Returns:
            Id of created box

        """

        box = Box()
        box.box_id = Counter.get_next_id('box')
        box.user = User.query.get(user_name=user_name)
        box.datetime_of_creation = datetime.now()
        box.datetime_of_modify = box.datetime_of_creation
        box.status = 'created'
        box.name = box_name
        box.port = port
        box.vagrantfile_path = vagrantfile_path

        DBSession.flush()
        DBSession.clear()

        return box.box_id

    @staticmethod
    def is_author(user_name, box_id):
        """
        Detect is user author of box

        Args:
            user_name (string): user name

        Raises:
            IndexError: no box with given box_id

        Returns:
            True if user is author, otherwise - False

        """

        box = Box.get_by_box_id(box_id)

        if box is None:
            raise IndexError("Виртуальная среда #" + str(box_id) +
                             " не найдена")

        if box.user == User.query.get(user_name=user_name):
            return True
        else:
            return False

    @staticmethod
    def is_port_free(port):
        """
        Detect is given port free

        Args:
            port (int): port number

        Returns:
            True if port is free, otherwise - False

        """

        return Box.query.get(port=port) == None

    @staticmethod
    def get_by_box_id(box_id):
        """
        Get box with given box_id

        Args:
            box_id (int): box_id in db

        Returns:
            Box

        """

        return Box.query.get(box_id=box_id)

    @staticmethod
    def get_all_user_boxes(user_id):
        """
        Get all user boxes from db

        Args:
            user_id (int): user id in db

        Returns:
            Collection of all boxes

        """

        return Box.query.find({'_user_id': user_id})

    @staticmethod
    def get_all_boxes():
        """
        Get all boxes from db

        Returns:
            Collection of all boxes

        """

        return Box.query.find()

    @staticmethod
    def get_number_of_user_boxes(user_id, status):
        """
        Get number of all users boxes with given status from db

        Args:
            user_id (int): user id in db
            status (string): box's status

        Returns:
            Number of all user's boxes

        """

        return Box.query.find({'status': status, '_user_id': user_id}).count()

    @staticmethod
    def get_number_of_all_boxes(status):
        """
        Get number of all boxes with given status from db

        Args:
            status (string): box's status

        Returns:
            Number of all boxes

        """

        return Box.query.find({'status': status}).count()

    @staticmethod
    def change_status(box_id, status):
        """
        Change status of box

        Args:
            box_id (int): box_id in db
            status (string): box's new status

        Raises:
            IndexError: no box with given box_id

        """

        box = Box.get_by_box_id(box_id)

        if box is None:
            raise IndexError("Виртуальная среда #" + str(box_id) +
                             " не найдена")

        box.status = status
        DBSession.flush()
        DBSession.clear()

        Box.update_datetime_of_modify(box_id)

    @staticmethod
    def update_datetime_of_modify(box_id):
        """
        Change datetime of modify of box

        Args:
            box_id (int): box_id in db

        Raises:
            IndexError: no box with given box_id

        """

        box = Box.get_by_box_id(box_id)

        if box is None:
            raise IndexError("Виртуальная среда #" + str(box_id) +
                             " не найдена")

        box.datetime_of_modify = datetime.now()
        DBSession.flush()
        DBSession.clear()

    @staticmethod
    def delete_box(box_id):
        """
        Delete box with given box_id

        Args:
            box_id (int): id of box

        """

        Box.query.remove({'box_id': box_id})

        DBSession.flush()
        DBSession.clear()
Пример #22
0
class Qa(MappedClass):
    QA_TYPE = [u"text", u"single", u"multi"]

    class __mongometa__:
        session = DBSession
        name = 'qas'
        indexes = [
            ('title',),
            ('_owner',),
            ('_category',),
            ('type', 'public',),
        ]

    # __ROW_TYPE_CONVERTERS__ = {
    #     #InstrumentedObj: _format_instrumented_obj,
    #     InstrumentedList: _format_instrumented_list,
    # }

    __ROW_COLUM_CONVERTERS__ = {
        'title': _custom_title,
    }

    _id = FieldProperty(s.ObjectId)

    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    _category = ForeignIdProperty('Category')
    category = RelationProperty('Category')

    _parent_precondition = ForeignIdProperty('Precondition')
    parent_precondition = RelationProperty('Precondition')

    title = FieldProperty(s.String, required=True)
    question = FieldProperty(s.String, required=True)
    tooltip = FieldProperty(s.String, required=False)
    link = FieldProperty(s.String, required=False)
    type = FieldProperty(s.OneOf(*QA_TYPE), required=True)

    answers = FieldProperty(s.Anything)

    public = FieldProperty(s.Bool, if_missing=True)
    visible = FieldProperty(s.Bool, if_missing=True)

    @classmethod
    def qa_available_for_user(cls, user_id, workspace=None):
        return User.query.get(_id=user_id).owned_entities(cls, workspace)

    @property
    def entity(self):
        return 'qa'

    @property
    def is_text(self):
        return self.type == self.QA_TYPE[0]

    @property
    def is_single(self):
        return self.type == self.QA_TYPE[1]

    @property
    def is_multi(self):
        return self.type == self.QA_TYPE[2]

    def __json__(self):
        from ksweb.lib.utils import to_dict
        _dict = to_dict(self)
        _dict['entity'] = self.entity
        return _dict
Пример #23
0
class PiazzaContent_History(MappedClass):
    """
    This class deals with history updates to the piazza content
    itself.  This will include a link to the parent post being
    edited as well as to the updated author information.  It is
    In turn linked to by the history information.
      
    Collection: piazza_content_history

    Relations:
    * Dataset: Link to the associated Dataset.
    * Content: Parent Piazza Content.
    * Author: Link to the user that authored this change.
    * CentralAuthor: The Central author object for this user.
    
    Fields:
    * Course_ID: ID of the associated Dataset.
    * Content_ID: ID of parent content.
    * Author_ID: ID of original author.
    * _id: Mongodb object ID (unique).
    * ThreadID: (int) Unknown int believed to be post number.
    * content: (string) (i.e. text) of the post itself.
    * subject: (string) line of the post.
    * uid: (string) of the author (will be None if anon is 'Full')
    * anon: (string) whether or not the change is anonymous (full | no)
    * created: (datetime) date the history element was created.
                (appears to be GMT)
    """

    # ---------------------------------------------
    # Mongometa information.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "piazza_content_history"

    # ------------------------------------------------
    # Link information.
    # ================================================

    # Link to the associated Dataset.
    Course_ID = ForeignIdProperty('Dataset')
    Course = RelationProperty('Dataset')

    # Parent Piazza Content.
    Content_ID = ForeignIdProperty('PiazzaContent')
    Content = RelationProperty('PiazzaContent')

    # Link to the user that authored this change.
    Author_ID = ForeignIdProperty('PiazzaUser.PiazzaUser')
    Author = RelationProperty('PiazzaUser.PiazzaUser')

    # Direct link to the central author instance.
    CentralAuthor_ID = ForeignIdProperty('User')
    CentralAuthor = RelationProperty('User')

    # ------------------------------------------------
    # Link information.
    # ================================================

    # Mongodb object ID (unique).
    _id = FieldProperty(schema.ObjectId)

    # History of the content for the post.
    #   content: (i.e. text) of the post itself.
    #   subject: line of the post.
    #   uid:     of the author (will be None if anon is 'Full')
    #   anon:    whether or not the change is anonymous (full | no)
    #   created: date the history element was created.  (appears to be GMT)
    # int for post number.
    content = FieldProperty(str)
    subject = FieldProperty(str)
    uid = FieldProperty(str)
    anon = FieldProperty(str)
    created = FieldProperty(datetime.datetime)
    ThreadID = FieldProperty(int)

    # ---------------------------------------------
    # Anonymization Code.
    # =============================================

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Histories = findAllContentHistory(DatasetID=DatasetID)
        for H in Histories:
            H.uid = None
        ModSocDB.Session.flush()
Пример #24
0
class Comment(MappedClass):
    class __mongometa__:
        session = model.DBSession
        name = 'tgcomments_comments'
        indexes = [(
            'entity_type',
            'entity_id',
        )]

    _id = FieldProperty(s.ObjectId)

    body = FieldProperty(s.String, required=True)
    created_at = FieldProperty(s.DateTime, if_missing=datetime.now)
    hidden = FieldProperty(s.Bool, if_missing=False)

    user_id = ForeignIdProperty(app_model.User)
    user = RelationProperty(app_model.User)

    author_username = FieldProperty(s.String, if_missing='anon')
    author_name = FieldProperty(s.String, if_missing='Anonymous')
    author_pic = FieldProperty(s.String, if_missing='')

    entity_id = FieldProperty(s.ObjectId, required=True)
    entity_type = FieldProperty(s.String, required=True)

    @property
    def votes(self):
        return model.provider.query(CommentVote,
                                    filters={'comment_id': self._id})[1]

    @property
    def voters(self):
        return [vote.user for vote in self.votes]

    @property
    def my_vote(self):
        values = [
            vote.value for vote in self.votes if vote.user_id ==
            instance_primary_key(tg.request.identity['user'])
        ]
        return values[0] if len(values) != 0 else None

    @property
    def rank(self):
        return sum((v.value for v in self.votes))

    def votes_by_value(self, v):
        return [vote for vote in self.votes if vote.value == v]

    @classmethod
    def get_entity_descriptor(cls, entity):
        Type = entity.__class__
        type_primary_key = primary_key(Type)
        return Type.__name__, getattr(entity, type_primary_key.name)

    @classmethod
    def comments_for(cls, entity, hidden='auto'):
        entity_type, entity_id = cls.get_entity_descriptor(entity)

        comments = model.provider.query(cls,
                                        filters={
                                            'entity_type': entity_type,
                                            'entity_id': entity_id
                                        })[1]

        if not (hidden == True or (hidden == 'auto' and manager_permission())):
            comments = (comment for comment in comments if not comment.hidden)

        return sorted(comments, key=lambda c: c.created_at, reverse=True)

    @classmethod
    def add_comment(cls, entity, user, body):
        entity_type, entity_id = cls.get_entity_descriptor(entity)

        c = dict(body=body, entity_type=entity_type, entity_id=entity_id)
        if isinstance(user, dict):
            c['author_username'] = user['user_name']
            c['author_name'] = user['name']
            c['author_pic'] = user.get('avatar')
        else:
            c['user_id'] = instance_primary_key(user)
            c['user'] = user
            c['author_username'] = user.user_name
            c['author_name'] = user.display_name
            c['author_pic'] = get_user_avatar(user)

        return model.provider.create(cls, c)
class PiazzaContent_Child_Subchild(MappedClass):
    """
    Subchildren of the child posts that is, replies to replies.
  
    Collection: piazza_content_children_subchildren  

    Relations:
    * Dataset: Link to the associated Dataset.
    * Parent: Parent Piazza Content.
    * Author: Link to the associated user.
    * CentralAuthor: The Central author object for this user.

    Fields:
    * Course_ID: ID of the associated Dataset.
    * Parent_ID: ID of parent content.
    * Author_ID: ID of original author.
    * CentralAuthor_ID: Mongoid of the Central author of this change.
    * _id: Mongodb object ID (unique).
    * ThreadID: (int) Unknown int believed to be post number.
    * folders: (string) Folders this element is in.
    * updated: (datetime) Date of last update?
    * uid: (string) Piazza id of original author.
    * created: (datetime) Date created.
    * anon: (string) setting indicating anonymous creation.
    * bucket_name: (string) Storage bucket for this item.
    * bucket_order: (int) Location in the bucket.
    * id: (string) internal id of the subchild item.
    * type: (string) Sub-post type.  
    * subject: (string) Sub-post subject.
    """

    # ---------------------------------------------
    # Mongometa information.
    # =============================================
    class __mongometa__:
        session = ModSocDB.Session
        name = "piazza_content_children_subchildren"

    # ------------------------------------------------
    # Link information.
    # ================================================

    # Link to the associated Dataset.
    Course_ID = ForeignIdProperty('Dataset')
    Course = RelationProperty('Dataset')

    # Parent Piazza Content.
    Parent_ID = ForeignIdProperty('PiazzaContent_Child')
    Parent = RelationProperty('PiazzaContent_Child')

    # Link to the associated user.
    Author_ID = ForeignIdProperty('PiazzaUser.PiazzaUser')
    Author = RelationProperty('PiazzaUser.PiazzaUser')

    # Direct link to the central author instance.
    CentralAuthor_ID = ForeignIdProperty('User')
    CentralAuthor = RelationProperty('User')

    # ------------------------------------------------
    # Fields
    # ================================================

    # Mongodb object ID (unique).
    _id = FieldProperty(schema.ObjectId)

    # Folders this element is in.
    folders = FieldProperty([str])

    # Date of last update?
    updated = FieldProperty(datetime.datetime)

    # Not containing a valuable information, removed for now
    # d_bucket = FieldProperty(str)

    # int for post number.
    ThreadID = FieldProperty(int)

    # UID of author now in link.
    uid = FieldProperty(str)

    # Date created.
    created = FieldProperty(datetime.datetime)

    # config information empty at present.
    config = FieldProperty(dict())

    # Created anonymously
    anon = FieldProperty(str)

    # Storage bucket for this item.
    bucket_name = FieldProperty(str)

    # Location in the bucket.
    bucket_order = FieldProperty(int)

    # Id of the subchild item.
    id = FieldProperty(str)

    # Sub-post type.
    type = FieldProperty(str)

    # Sub-post subject.
    content = FieldProperty(str)

    #
    # NOTE:: None in extant data. So should be removed for now
    # data = FieldProperty(str)

    #
    # NOTE:: Empty in extant data. So should be removed for now
    # children = FieldProperty([str])

    def getLatestHistory(self):
        """
        Get the latest history entry by date.
        """

        print 'subchild', self.subject
        if len(self.History) < 1:
            return None
        Last = self.History[0]

        for Hist in self.History[1:]:
            if (Hist.created > Last.created):
                Last = Hist

        return Last

    # ---------------------------------------------
    # Anonymization Code.
    # =============================================

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Subchildren = findAllSubchildren(DatasetID=DatasetID)
        for S in Subchildren:
            S.uid = None
            S.id = None
        ModSocDB.Session.flush()
Пример #26
0
class MappedEntity(MappedClass):
    STATUS = Bunch(READ="READ", UNREAD="UNREAD", INCOMPLETE="INCOMPLETE")

    _id = FieldProperty(s.ObjectId)

    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    _workspace = ForeignIdProperty('Workspace')
    workspace = RelationProperty('Workspace')

    hash = FieldProperty(s.String)
    title = FieldProperty(s.String, required=True)
    public = FieldProperty(s.Bool, if_missing=True)
    visible = FieldProperty(s.Bool, if_missing=True)
    status = FieldProperty(s.OneOf(*STATUS.values()),
                           required=True,
                           if_missing=STATUS.UNREAD)
    auto_generated = FieldProperty(s.Bool, if_missing=False)

    @property
    def created_at(self):
        return self._id.generation_time

    @classmethod
    def unread_count(cls, workspace_id):
        return cls.query.find({
            'status': cls.STATUS.UNREAD,
            '_workspace': ObjectId(workspace_id)
        }).count() or ''

    @property
    def dependencies(self):
        return []

    @property
    def descendants(self):
        return []

    @property
    def entity(self):
        return ''

    @property
    def url(self):
        return lurl('/%s/edit/' % self.entity,
                    params=dict(workspace=self.workspace._id, _id=self._id))

    @classmethod
    def by_id(cls, _id):
        return cls.query.get(ObjectId(_id))

    @classmethod
    def upsert(cls, find, replace):
        # find_and_modify or other methods does not work for ming mapper extensions
        # so this is an artisan upsert implementation with instant flushes out of uow
        found = cls.query.get(**find)
        if not found:
            o = cls(**replace)
            DBSession.flush(o)
            return o

        for k, v in replace.items():
            found[k] = v
        DBSession.flush(found)
        return found

    @classmethod
    def by_hash(cls, _hash):
        return cls.query.get(hash=_hash)

    @classmethod
    def mark_as_read(cls, user_oid, workspace_id):
        from ming.odm import mapper
        collection = mapper(cls).collection.m.collection
        collection.update_many(
            {
                '_owner': user_oid,
                'status': cls.STATUS.UNREAD,
                '_workspace': ObjectId(workspace_id)
            },
            update={'$set': {
                'status': cls.STATUS.READ
            }})

    @classmethod
    def available_for_user(cls, user_id, workspace=None):
        from ksweb.model import User
        return User.query.get(_id=user_id).owned_entities(cls, workspace).sort(
            [
                ('auto_generated', pymongo.ASCENDING),
                ('status', pymongo.DESCENDING),
                ('title', pymongo.ASCENDING),
            ])

    def update_dependencies(self, old):
        log = logging.getLogger(__name__)
        log.info(
            "Please implement this method in models if some action is needed for %s => %s"
            % (old, self.hash))

    def dependent_filters(self):
        from ksweb.model import Precondition
        simple = Precondition.query.find(dict(condition=self._id)).all()
        simple_id = [_._id for _ in simple]
        advanced = Precondition.query.find(
            dict(workspace=self._workspace, condition={'$in':
                                                       simple_id})).all()
        return simple + advanced

    def dependent_outputs(self):
        from ksweb.model import Output
        outputs = Output.query.find({'html': self.hash}).all()
        return outputs

    def __json__(self):
        _dict = dictify(self)
        _dict['entity'] = self.entity
        return _dict

    def exportable_dict(self):
        filter_out = [
            '_workspace', '_owner', 'created_at', 'auto_generated', 'status',
            '_id'
        ]
        return {
            k: v
            for k, v in self.__json__().items() if k not in filter_out
        }
Пример #27
0
class User(MappedClass):
    """
    User definition

    This is the user definition used by :mod:`repoze.who`, which requires at
    least the ``user_name`` column.

    """
    class __mongometa__:
        session = DBSession
        name = 'user'
        unique_indexes = [
            ('user_name', ),
        ]

    class PasswordProperty(FieldProperty):
        @classmethod
        def _hash_password(cls, password):
            salt = sha256()
            salt.update(os.urandom(60))
            salt = salt.hexdigest()

            hash = sha256()
            hash.update((password + salt).encode('utf-8'))
            hash = hash.hexdigest()

            password = salt + hash
            password = password.decode('utf-8')

            return password

        def __set__(self, instance, value):
            value = self._hash_password(value)
            return FieldProperty.__set__(self, instance, value)

    _id = FieldProperty(s.ObjectId)
    user_name = FieldProperty(s.String)
    display_name = FieldProperty(s.String)

    _groups = ForeignIdProperty(Group, uselist=True)
    groups = RelationProperty(Group)

    password = PasswordProperty(s.String)
    created = FieldProperty(s.DateTime, if_missing=datetime.now)

    @property
    def permissions(self):
        """Get all user's permissions"""

        return Permission.query.find(dict(_groups={'$in': self._groups})).all()

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

        :param password: the password that was provided by the user to
            try and authenticate. This is the clear text version that we will
            need to match against the hashed one in the database.
        :type password: unicode object.
        :return: Whether the password is valid.
        :rtype: bool

        """

        hash = sha256()
        hash.update((password + self.password[:64]).encode('utf-8'))
        return self.password[64:] == hash.hexdigest()
Пример #28
0
class User(MappedClass):
    """
    User definition.

    This is the user definition used by :mod:`repoze.who`, which requires at
    least the ``user_name`` column.

    """
    class __mongometa__:
        session = DBSession
        name = 'tg_user'
        unique_indexes = [
            ('user_name', ),
        ]

    class PasswordProperty(FieldProperty):
        @classmethod
        def _hash_password(cls, password):
            salt = sha256()
            salt.update(os.urandom(60))
            salt = salt.hexdigest()

            hash = sha256()
            # Make sure password is a str because we cannot hash unicode objects
            hash.update((password + salt).encode('utf-8'))
            hash = hash.hexdigest()

            password = salt + hash
            return password

        def __set__(self, instance, value):
            value = self._hash_password(value)
            return FieldProperty.__set__(self, instance, value)

    _id = FieldProperty(s.ObjectId)
    user_name = FieldProperty(s.String)
    email_address = FieldProperty(s.String)
    display_name = FieldProperty(s.String)

    _groups = ForeignIdProperty(Group, uselist=True)
    groups = RelationProperty(Group)

    password = PasswordProperty(s.String)
    created = FieldProperty(s.DateTime, if_missing=datetime.now)

    @property
    def permissions(self):
        return Permission.query.find(dict(_groups={'$in': self._groups})).all()

    @classmethod
    def by_email_address(cls, email):
        """Return the user object whose email address is ``email``."""
        return cls.query.get(email_address=email)

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

        :param password: the password that was provided by the user to
            try and authenticate. This is the clear text version that we will
            need to match against the hashed one in the database.
        :type password: unicode object.
        :return: Whether the password is valid.
        :rtype: bool

        """
        hash = sha256()
        hash.update((password + self.password[:64]).encode('utf-8'))
        return self.password[64:] == hash.hexdigest()

    def owned_entities(self, entity_model, workspace=None):
        query = {'_owner': self._id}
        if workspace:
            query['_category'] = ObjectId(workspace)
        return entity_model.query.find(query).sort('title')