Esempio n. 1
0
 class Child(MappedClass):
     class __mongometa__:
         name='child'
         session = self.session
     _id = FieldProperty(S.ObjectId)
     parent_id = ForeignIdProperty(Parent)
     field_with_default_id = ForeignIdProperty(
         Parent,
         if_missing=lambda:bson.ObjectId('deadbeefdeadbeefdeadbeef'))
     field_with_default = RelationProperty('Parent', 'field_with_default_id')
Esempio n. 2
0
 class Parent(MappedClass):
     class __mongometa__:
         name='parent'
         session = self.session
     _id = FieldProperty(S.ObjectId)
     children = ForeignIdProperty('Child', uselist=True)
     field_with_default_id = ForeignIdProperty(
         'Child',
         uselist=True,
         if_missing=lambda:[bson.ObjectId('deadbeefdeadbeefdeadbeef')])
     field_with_default = RelationProperty('Child', 'field_with_default_id')
Esempio n. 3
0
class TPremium(MappedClass, EnhancingClass):
    class __mongometa__:
        session = session
        name = 'testpremiums'
        extensions = [ MyExtension ]
    
    _id = FieldProperty(schema.ObjectId)
    premium_id = ForeignIdProperty(TPremiumSize)
    worker_id = ForeignIdProperty(TWorker)
    earning_date = FieldProperty(schema.DateTime(required=True))
    premium_size = FieldProperty(schema.Int(required=True))
    note = FieldProperty(schema.String(if_missing = '')) 
    
    worker = RelationProperty(TWorker)
    premium = RelationProperty(TPremiumSize)
Esempio n. 4
0
 class Parent(MappedClass):
     class __mongometa__:
         name='parent'
         session = self.session
     _id = FieldProperty(int)
     children = RelationProperty('Child')
     _children = ForeignIdProperty('Child', uselist=True)
Esempio n. 5
0
 class Child(MappedClass):
     class __mongometa__:
         name='child'
         session = self.session
     _id = FieldProperty(int)
     parent_id = ForeignIdProperty('Parent')
     parent = RelationProperty('Parent')
Esempio n. 6
0
class GoogleAuth(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'googleplusauth_info'
        indexes = [(('_user_id', ), )]

    _id = FieldProperty(s.ObjectId)
    registered = FieldProperty(s.Bool, if_missing=False)
    just_connected = FieldProperty(s.Bool, if_missing=False)
    profile_picture = FieldProperty(s.String)

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

    google_id = FieldProperty(s.String, required=True)
    access_token = FieldProperty(s.String, required=True)
    access_token_expiry = FieldProperty(s.DateTime, required=True)

    @classmethod
    def ga_user_by_google_id(cls, google_id):
        google_auth_user = cls.query.find({'google_id': google_id}).first()
        return google_auth_user

    @classmethod
    def googleplusauth_user(cls, user_id):
        return cls.query.find({'_user_id': user_id}).first()
Esempio n. 7
0
class Workspace(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'workspaces'
        custom_indexes = [
            dict(fields=('name', '_owner'), unique=True, sparse=True)
        ]

    _id = FieldProperty(s.ObjectId)

    name = FieldProperty(s.String, required=True)
    visible = FieldProperty(s.Bool, if_missing=True, index=True)
    _owner = ForeignIdProperty('User')
    owner = RelationProperty('User')

    @classmethod
    def per_user(cls, user_id):
        return cls.query.find({
            '_owner': {
                '$in': [user_id, None]
            },
            'visible': True
        }).sort('_id').all()

    @classmethod
    def by_id(cls, _id):
        return cls.query.get(_id=ObjectId(_id))
Esempio n. 8
0
    def setUp(self):
        self.datastore = create_datastore('mim:///test_db')
        session = Session(bind=self.datastore)
        self.session = ODMSession(session)

        class Parent(object):
            pass

        class Child(object):
            pass

        parent = collection('parent', session, Field('_id', int))
        child = collection('child', session, Field('_id', int),
                           Field('parent_id', int))
        mapper(Parent,
               parent,
               self.session,
               properties=dict(children=RelationProperty(Child)))
        mapper(Child,
               child,
               self.session,
               properties=dict(parent_id=ForeignIdProperty(Parent),
                               parent=RelationProperty(Parent)))
        self.Parent = Parent
        self.Child = Child
Esempio n. 9
0
 class Parent(MappedClass):
     class __mongometa__:
         name='parent'
         session = self.session
     _id = FieldProperty(int)
     grandparent_id = ForeignIdProperty('GrandParent')
     grandparent = RelationProperty('GrandParent')
     children = RelationProperty('Child')
Esempio n. 10
0
class WikiComment(MappedClass):
    class __mongometa__:
        session = session
        name = 'wiki_comment'

    _id = FieldProperty(schema.ObjectId)
    page_id = ForeignIdProperty('WikiPage')
    text = FieldProperty(schema.String(if_missing=''))
Esempio n. 11
0
        class TestCollection(MappedClass):
            class __mongometa__:
                name='test_collection'
                session = self.session
            _id = FieldProperty(int)

            children = RelationProperty('TestCollection')
            _children = ForeignIdProperty('TestCollection', uselist=True)
            parents = RelationProperty('TestCollection', via=('_children', False))
Esempio n. 12
0
class Dataset(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'datasets'

    _id = FieldProperty(s.ObjectId)
    homer_q_id = ForeignIdProperty(HomerQ)
    homer_q = RelationProperty(HomerQ)
    metadata_origin = FieldProperty(s.String, index=True)
Esempio n. 13
0
class TemporaryPhotosBucket(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'temporary_photos_bucket'
        unique_indexes = [('created_at',), ]

    _id = FieldProperty(s.ObjectId)
    created_at = FieldProperty(s.DateTime, required=True, if_missing=datetime.utcnow)
    photos = ForeignIdProperty(BucketProductImage, uselist=True)
    photos_rel = RelationProperty('BucketProductImage')
Esempio n. 14
0
class Parent(MappedClass):
    class __mongometa__:
        name = 'parent'
        session = session

    _id = FieldProperty(schema.ObjectId)
    name = FieldProperty(schema.String(required=True))
    _children = ForeignIdProperty('Child', uselist=True)

    children = RelationProperty('Child')
Esempio n. 15
0
        class WikiPage(MappedClass):
            class __mongometa__:
                session = cls.s
                name = 'wiki_page'

            _id = FieldProperty(schema.ObjectId)
            title = FieldProperty(str)
            text = FieldProperty(str)
            order = FieldProperty(int)
            author_id = ForeignIdProperty(Author)
            author = RelationProperty(Author)
Esempio n. 16
0
class TemplateTranslation(MappedClass):
    class __mongometa__:
        name = 'mailtemplates_template_translations'
        session = DBSession

    _id = FieldProperty(s.ObjectId)
    mail_model_id = ForeignIdProperty('MailModel')
    mail_model = RelationProperty('MailModel')
    language = FieldProperty(s.String, required=True)
    subject = FieldProperty(s.String)
    body = FieldProperty(s.String)
Esempio n. 17
0
class Registration(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'registration_registration'
        indexes = [(('activated', ), ('code', ))]
        
    _id = FieldProperty(s.ObjectId)
    time = FieldProperty(s.DateTime, if_missing=datetime.now)
    user_name = FieldProperty(s.String, required=True)
    email_address = FieldProperty(s.String, required=True, index=True)
    password = FieldProperty(s.String, required=True)
    code = FieldProperty(s.String)
    activated = FieldProperty(s.DateTime)
    extras = FieldProperty(s.Anything)

    user_id = ForeignIdProperty(app_model.User)

    @property
    def dictified(self):
        return dict(time=self.time, user_name=self.user_name, email_address=self.email_address,
                    code=self.code, activated=self.activated, user_id=self.user_id,
                    activation_link=self.activation_link)

    @cached_property
    def user(self):
        return app_model.User.get(ObjectId(self.user_id))

    @cached_property
    def activation_link(self):
        return url(mount_point('registration') + '/activate',
                   params=dict(code=self.code),
                   qualified=True)

    @classmethod
    def generate_code(cls, email):
        code_space = string.ascii_letters + string.digits
        def _generate_code_impl():
            base = ''.join(random.sample(code_space, 8))
            base += email
            base += str(time.time())
            return hashlib.sha1(base.encode('utf-8')).hexdigest()
        code = _generate_code_impl()
        while cls.query.find({'code': code}).first():
            code = _generate_code_impl()
        return code

    @classmethod
    def clear_expired(cls):
        for expired_reg in cls.query.find({'activated': None, 'time': {'$lte': datetime.now()-timedelta(days=2)}}):
            expired_reg.delete()

    @classmethod
    def get_inactive(cls, code):
        return cls.query.find(dict(activated=None, code=code)).first()
Esempio n. 18
0
class FlatPage(MappedClass):
    class __mongometa__:
        session = model.DBSession
        name = 'flatpages_page'
        unique_indexes = [('slug', )]
        extensions = [UpdateDate]

    _id = FieldProperty(s.ObjectId)

    template = FieldProperty(
        s.String, if_missing=config['_flatpages'].get('templates')[0][0])
    slug = FieldProperty(s.String, required=True)
    title = FieldProperty(s.String, required=True)
    content = FieldProperty(s.String, if_missing='')
    required_permission = FieldProperty(s.String)

    updated_at = FieldProperty(s.DateTime, if_missing=datetime.utcnow)
    created_at = FieldProperty(s.DateTime, if_missing=datetime.utcnow)

    author_id = ForeignIdProperty('User')
    author = RelationProperty('User')

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

    @classmethod
    def by_slug(cls, slug):
        return cls.query.find(dict(slug=slug)).first()

    @cached_property
    def url(self):
        return plug_url('flatpages', '/' + self.slug)

    @classmethod
    def all_pages(cls):
        """Returns a list of tuples with title and url of all the flat pages"""
        return [(page.title, page.url) for page in cls.query.find()]

    @cached_property
    def html_content(self):
        format = config['_flatpages']['format']
        formatter = FORMATTERS[format]

        content = self.content
        if content.startswith('file://'):
            package_path = config['paths']['root']
            file_path = os.path.join(package_path, content[7:])
            with closing(open(file_path)) as f:
                content = f.read()

        return formatter(content)
Esempio n. 19
0
class CommentVote(MappedClass):
    class __mongometa__:
        session = model.DBSession
        name = 'tgcomments_comments_votes'
        unique_indexes = [(
            "_id",
            "comment_id",
            "user_id",
        )]

    _id = FieldProperty(s.ObjectId)

    created_at = FieldProperty(s.DateTime,
                               if_missing=datetime.now,
                               required=True)
    value = FieldProperty(s.Int, if_missing=1)

    user_id = FieldProperty(s.ObjectId)
    user = ForeignIdProperty(app_model.User)

    comment_id = FieldProperty(s.ObjectId)
    comment = ForeignIdProperty(Comment)
Esempio n. 20
0
class SkeletonClass(MappedClass):
    """
    Sample class with docstring for content. 
    
    Collection: <put collection assoc here>

    Relations:
    
    Fields:
    * _id: Unique Mongodb ID.
    """

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

    # ------------------------------------------------
    # Link information.
    #
    # Put any links here following the model of the
    # dataset link below.
    #
    # NOTE:: The dataset link must be preserved and
    #   updated on imports so that everything points
    #   to the correct dataset.
    # ================================================

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

    # ------------------------------------------------
    # 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)

    # content: (i.e. text) of the post itself.
    content = FieldProperty(str)
    created = FieldProperty(datetime.datetime)
Esempio n. 21
0
class BucketProductImage(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'bucket_product_image'
        indexes = [('bucket_id', )]

    _id = FieldProperty(s.ObjectId)

    image = UploadedFileProperty(
            upload_storage='product_images',
            upload_type=UploadedImageWithThumb
        )

    bucket_id = ForeignIdProperty('TemporaryPhotosBucket')
    bucket = RelationProperty('TemporaryPhotosBucket')
Esempio n. 22
0
class Permission(MappedClass):
    """
    Permission definition.
    """
    class __mongometa__:
        session = DBSession
        name = 'tg_permission'
        unique_indexes = [('permission_name',),]

    _id = FieldProperty(s.ObjectId)
    permission_name = FieldProperty(s.String)
    description = FieldProperty(s.String)

    _groups = ForeignIdProperty(Group, uselist=True)
    groups = RelationProperty(Group)
Esempio n. 23
0
class Rule(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'rules'
        indexes = [
            ('_user', ),
        ]

    _id = FieldProperty(s.ObjectId)

    name = FieldProperty(s.String)
    content = FieldProperty(s.String)

    _user = ForeignIdProperty('User')
    user = RelationProperty('User')
Esempio n. 24
0
class UserAddress(MappedClass):
    class __mongometa__:
        session = DBSession
        name = 'user_addresses'
        indexes = [('user_id',),]

    _id = FieldProperty(s.ObjectId)
    user = RelationProperty(app_model.User)
    user_id = ForeignIdProperty(app_model.User)
    shipping_address = FieldProperty({
        'receiver': s.String,
        'address': s.String,
        'city': s.String,
        'province': s.String,
        'state': s.String,
        'country': s.String,
        'zip': s.String,
        'details': s.Anything
    })
Esempio n. 25
0
class FlatFile(MappedClass):
    class __mongometa__:
        session = model.DBSession
        name = 'flatpages_file'
        unique_indexes = [('name')]
        extensions = [UpdateDate]

    _id = FieldProperty(s.ObjectId)

    name = FieldProperty(s.String, required=True)
    file = UploadedFileProperty(upload_storage='flatfiles')

    updated_at = FieldProperty(s.DateTime, if_missing=datetime.utcnow)
    created_at = FieldProperty(s.DateTime, if_missing=datetime.utcnow)

    author_id = ForeignIdProperty('User')
    author = RelationProperty('User')

    @cached_property
    def url(self):
        return plug_url('flatpages', '/flatfiles/' + self.file.file_id)
Esempio n. 26
0
class DatasetElementCommentDAO(MappedClass):
    class __mongometa__:
        session = session
        name = 'data_element_comment'

    _id = FieldProperty(schema.ObjectId)
    author_name = FieldProperty(schema.String)
    author_link = FieldProperty(schema.String)
    content = FieldProperty(schema.String)
    addition_date = FieldProperty(schema.datetime)
    element_id = ForeignIdProperty('DatasetElementDAO')

    def __init__(self,
                 author_name,
                 author_link,
                 content,
                 addition_date=now(),
                 element_id=None,
                 element=None):
        if element_id is None and element is not None:
            element_id = element._id

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

    @classmethod
    def from_dict(cls, init_dict):
        return cls(**init_dict)

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

    def delete(self):
        DatasetElementCommentDAO.query.remove({'_id': self._id})
Esempio n. 27
0
class User(MappedClass):
    """
    The User class provides a central identifier for a user.  It is
    based on the PiazzaUser instance primarily and includes some of
    the same content including the anonymous ID.  It will ultimately
    be a vehicle for adding in other methods to calculate per-user
    statistics.  
    
    Collection: users

    Relations:
    * PiazzaUser: Link to the associated Piazza User.
    * Dataset: Link to the associated Dataset.
   
    Fields:
    * _id: Unique Mongodb ID.
    * PiazzaUser_ID: Mongo ID of the Piazza User.
    * Dataset_ID: ID of the associated Dataset.
    * local_user_id: Local anonymously assigned user ID info.
    * PiazzaID:      Piazza ID for user.
    * StudentNumber: Student ID number. 
    * name:          Full student name.
    * first_name:    Split first name.
    * middle_name:   Split middle name.
    * last_name:     Split last name.
    * email:         Student's email address.
    * piazza_alt_email: Alternate email address.
    * username:      system username.
    * Instructor:    instructor name.
    * SectionNumber: integer section number. 
    * role:          Role in the course - Student, Instructor, or TA
    * postCount:    Count for number of piazza posts.
    * PiazzaDays:   Days active or logged in.
    * PiazzaViews:  Count of views made.
    * PiazzaAsks:   Count of asks made.
    * PiazzaAnswers:    Count of answers given to question.
    * FinalGrade:   Final grade of the student.
    """

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

    # ------------------------------------------------
    # Link information.
    #
    # Put any links here following the model of the
    # author link below.
    # ================================================

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

    # Link to the associated Piazza User.
    PiazzaUser_ID = ForeignIdProperty('PiazzaUser.PiazzaUser')
    PiazzaUser = RelationProperty('PiazzaUser.PiazzaUser')

    # ------------------------------------------------
    # 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)

    # Unique user ID set on introduction by the counter
    # mechanism.
    local_user_id = FieldProperty(str)

    PiazzaID = FieldProperty(str)
    StudentNumber = FieldProperty(str)

    # Student real name or anonymized name.
    name = FieldProperty(str)

    # Split field for individual names.
    first_name = FieldProperty(str)
    middle_name = FieldProperty(str)
    last_name = FieldProperty(str)

    # User's email address (is in standard form so can be split.)
    email = FieldProperty(str)

    # User's alternate email address (is in standard form so can be split.)
    piazza_alt_email = FieldProperty(str)

    # Username
    username = FieldProperty(str)

    # Instructor they have and Section number to which they are assigned.
    # The loading code needs to be modified based on the inputs to update these field.
    Instructor = FieldProperty(str)
    SectionNumber = FieldProperty(int)

    # Class role - Student, Instructor, or TA
    # The loading code needs to be modified based on the inputs to update this field.
    role = FieldProperty(str)

    #Count for piazza posts
    postCount = FieldProperty(int)

    # Count of answers given to questions.
    PiazzaAnswers = FieldProperty(int)

    # Count of views made.
    PiazzaViews = FieldProperty(int)

    # Count of asks made.
    PiazzaAsks = FieldProperty(int)

    # Days active or logged in?
    PiazzaDays = FieldProperty(int)

    #final letter grade of student
    # The loading code needs to be modified based on the inputs to update this field.
    FinalGrade = FieldProperty(str)

    # -------------------------------------------------
    # Static Constructor.
    # =================================================

    @staticmethod
    def makeNewUser(DatasetID,
                    Name,
                    PiazzaUserID=None,
                    PiazzaId=None,
                    WebAssignUserID=None,
                    MoodleActionID=None,
                    Studentnumber=None,
                    Email=None,
                    Alt_Email=None,
                    FirstName=None,
                    MiddleName=None,
                    LastName=None,
                    Username=None,
                    Instructor=None,
                    SectionNumber=None,
                    isPeerTutor=None,
                    Role=None,
                    FlushSession=True):
        """
        Construct a new user.  This will set the email
        and name fields directly from the argument and
        will then return the user instance.  The
        *_name fields will be set via the split name
        function and the local_user_id field will be
        set based upon the current number of users.
        This is not reset safe.
        """

        # Calculate the new ID.
        LocalID = "USER_%d" % (countAllUsers())
        if not Username and Email:
            Username = Email.split('@')[0]
        # Calculate the Split name field values unless
        # they are supplied.  If however the Name is None
        # then all will be None.
        if (Name == None):
            NewUser = User(Dataset_ID=DatasetID,
                           PiazzaUser_ID=PiazzaUserID,
                           WebAssignUser_ID=WebAssignUserID,
                           MoodleAction_ID=MoodleActionID,
                           local_user_id=LocalID,
                           PiazzaID=PiazzaId,
                           StudentNumber=Studentnumber,
                           name=None,
                           first_name=None,
                           middle_name=None,
                           last_name=None,
                           email=Email,
                           piazza_alt_email=Alt_Email,
                           username=Username,
                           Instructor=Instructor,
                           SectionNumber=SectionNumber)

        elif (FirstName == None):
            SplitNameDict = ModSocDB.NLP.makeSplitNameDict(Name)
            NewUser = User(Dataset_ID=DatasetID,
                           PiazzaUser_ID=PiazzaUserID,
                           WebAssignUser_ID=WebAssignUserID,
                           MoodleAction_ID=MoodleActionID,
                           local_user_id=LocalID,
                           PiazzaID=PiazzaId,
                           StudentNumber=Studentnumber,
                           name=Name,
                           first_name=SplitNameDict["FirstName"],
                           middle_name=SplitNameDict["MiddleName"],
                           last_name=SplitNameDict["LastName"],
                           email=Email,
                           piazza_alt_email=Alt_Email,
                           username=Username,
                           Instructor=Instructor,
                           SectionNumber=SectionNumber)

        else:
            NewUser = User(Dataset_ID=DatasetID,
                           PiazzaUser_ID=PiazzaUserID,
                           WebAssignUser_ID=WebAssignUserID,
                           MoodleAction_ID=MoodleActionID,
                           local_user_id=LocalID,
                           PiazzaID=PiazzaId,
                           StudentNumber=Studentnumber,
                           name=Name,
                           first_name=FirstName,
                           middle_name=MiddleName,
                           last_name=LastName,
                           email=Email,
                           piazza_alt_email=Alt_Email,
                           username=Username,
                           Instructor=Instructor,
                           SectionNumber=SectionNumber)

        # If we are set to flush then do so.
        if (FlushSession == True):
            ModSocDB.Session.flush()

        return NewUser

    # -------------------------------------------------
    # User Data.
    # =================================================

    def getUserDataDict(self):
        """
        Make the user data dictionary.
        """
        Dict = {}
        Dict["UserID"] = self.ID
        return Dict

    # -------------------------------------------------
    # Accessors/Settors
    # =================================================

    def getName(self):
        """
        Return the user name.
        """
        return self.name

    def setName(self, NewName):
        """
        Set the new user name.
        """
        self.name = NewName

    def getLocalUserID(self):
        """
        Get the local user Id value.
        """
        return self.local_user_id

    def setLocalUserID(self, NewID):
        """
        Set the local user ID value.
        """
        self.local_user_id = NewID

    def getFirstName(self):
        """
        Get the first_name value.
        """
        return self.first_name

    def setFirstName(self, NewName):
        """
        Set the first_name field.
        """
        self.first_name = NewName

    def getMiddleName(self):
        """
        Get the middle_name value.
        """
        return self.middle_name

    def setMiddleName(self, NewName):
        """
        Set the middle_name field.
        """
        self.middle_name = NewName

    def getLastName(self):
        """
        Get the last_name value.
        """
        return self.last_name

    def setLastName(self, NewName):
        """
        Set the last_name field.
        """
        self.last_name = NewName

    def getEmail(self):
        """
        Get the email.
        """
        return self.email

    def setEmail(self, NewEmail):
        """
        Set the new email.
        """
        self.email = NewEmail

    def getUsername(self):
        """
        Get the username.
        """
        return self.username

    def setUsername(self, NewUsername):
        """
        Set the new username.
        """
        self.username = NewUsername

    def getRole(self):
        """
        Get the role.
        """
        return self.role

    def setRole(self, NewRole):
        """
        Set the new role.
        """
        self.role = NewRole

    def getPostCount(self):
        """
        Get the role.
        """
        return self.postCount

    def setPostCount(self, NewCount):
        """
        Set the new role.
        """
        self.postCount = NewCount

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

    def anonymizeNameFields(self):
        """
        This code resets all of the local name fields to contain
        an anonymous form based upon the salted user ID.  This
        will simply set the specific name fields for the user to
        the IDs and will purge the group name field.

        For the sake of clarity this will only anonymize cases where
        the field is nonempty.  In cases where it is none then it 
        will simply be left as is.  
        """
        # NewID = self.getUserID()

        if (self.getFirstName() != None):
            self.setFirstName(self.makeFirstNameAnonForm())

        if (self.getMiddleName() != None):
            self.setMiddleName(self.makeMiddleNameAnonForm())

        if (self.getLastName() != None):
            self.setLastName(self.makeLastNameAnonForm())

        if (self.name != None):
            self.setName(self.makeNameAnonForm())

        if (self.email != None):
            self.setEmail(self.makeEmailAnonForm())

        if (self.username != None):
            self.setUsername(self.makeUsernameAnonForm())

    def makeFirstNameAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the first name for later use.
        """
        return "%s_FirstName" % (self.getLocalUserID())

    def makeMiddleNameAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the middle name for later use.
        """
        return "%s_MiddleName" % (self.getLocalUserID())

    def makeLastNameAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the last name for later use.
        """
        return "%s_LastName" % (self.getLocalUserID())

    def makeNameAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the name for later use.
        """
        return "%s_Name" % (self.getLocalUserID())

    def makeEmailAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the email for later use.
        """
        return "%s_Email" % (self.getLocalUserID())

    def makeUsernameAnonForm(self):
        """
        This is a stock method that returns the anon form of
        the username for later use.
        """
        return "%s_Username" % (self.getLocalUserID())

    # ----------------------------------------------------
    # NLP Tasks.
    # ====================================================

    def nameInTextP(self, TextStr):
        """
        Given a text string check to see if the user's first name,
        last name, or full name appear in it.  This depends upon
        the nltk library.  If the Name is None then this will return
        False.
        """
        if (self.name == None): return False
        else: return ModSocDB.NLP.findNameInText(self.name, TextStr)

    def anonymizeNamesInText(self, TextStr):
        """
        Performs a replacement of the names in the text with the anonymized form
        of the names as generated by the makeAnon methods above.
        
        NOTE:: This is not a destructive replacement and only
          returns an updated form.  Or None if no changes are
          made.

        NOTE:: If the name is none then this will do nothing.
        """

        return self.replaceNameInText(self.makeFirstNameAnonForm(),
                                      self.makeLastNameAnonForm(), TextStr)

    def replaceNameInText(self, FirstNameReplacement, LastNameReplacement,
                          TextStr):
        """
        Given a text string replace the user's name in it if
        it is present using the supplied first and last
        replacement strings.

        NOTE:: This is not a destructive replacement and only
          returns an updated form.  Or None if no changes are
          made.

        NOTE:: If the FirstName and LastName are none then this 
          will do nothing.
        """

        if ((self.getFirstName() == None) and (self.getLastName() == None)):
            return None

        return ModSocDB.NLP.replaceNameInText(self.getFirstName(),
                                              self.getLastName(),
                                              FirstNameReplacement,
                                              LastNameReplacement, TextStr)
Esempio n. 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

            # Make sure the hashed password is a unicode object at the end of the
            # process because SQLAlchemy _wants_ unicode objects for Unicode cols
            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)
    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()
class PiazzaContent_ChangeLog(MappedClass):
    """
    This class solely deals with the good tag of the piazza content.  It is
    used to handle the cases where a user has tagged a post as good.  It is
    in a 1-1 relationship with a PiazzaUser and a one to many relationship
    with the PiazzaContent class to which it is attached.

    For the most part these should match the user information in the users
    but because of Piazza's odd data structure this may or may not vary hence
    the decision to combine the information here.

    This class is linked to the "piazza_content_changelog" collection.
    
    Relationships:
    * Dataset: Link to the associated Dataset.
    * Content: Link to the associated PiazzaContent instance.
    * Author:  Link to the associated PiazzaUser instance.
    * CentralAuthor: The Central author object for this user.

    Fields:
    * Course_ID: Link to the associated Dataset.
    * Content_ID: MongoID of the parent content.
    * Author_ID: Mongoid of the author of this change.
    * CentralAuthor_ID: Mongoid of the Central author of this change.
    * _id: Mongodb ID.
    * ParentPostID :   (string) which appears to be an index to a target post;
    * ThreadID: (int) thread ID of the post, similar for content, children and subchildren.
    * data: (string) of the change which appears to be another key;
    * uid:  (string) the uid of the individual making the change;
    * anon: (string) whether or not the change is anonymous;
    * type: (string) the type of the change; and
    * when: (datetime) when the change was made.
    """

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

    # ------------------------------------------------
    # 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 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)

    # The ChangeLog is a record of when updates were
    # made to the relevant content. This stores:
    #   'to': which appears to be an index to a target post;
    #   data: of the change which appears to be another key;
    #   uid:  the uid of the individual making the change;
    #   anon: whether or not the change is anonymous;
    #   type: the type of the change; and
    #   when: it took place (appears to be GMT)
    # int for post number.
    ParentPostID = FieldProperty(str)
    data = FieldProperty(str)
    uid = FieldProperty(str)
    anon = FieldProperty(str)
    type = FieldProperty(str)
    when = FieldProperty(datetime.datetime)
    ThreadID = FieldProperty(int)

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

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        Changelogs = findAllChangeLogs(DatasetID=DatasetID)
        for C in Changelogs:
            C.uid = None
        ModSocDB.Session.flush()
Esempio n. 30
0
class PiazzaUser(MappedClass):
    """
    The PiazzaUser class represents a wrapper for the user records that
    were pulled from the piazza data in the form of the RawPiazzaUser
    instances.  They will be generated by code in the RawPiazzaUser
    module and would then generate the first and last names and perform
    other relevant features.

    Access to the fields will be provided later on as needed and
    anonymization when it happens will be done on this object.

    The user contains the following fields:
  
    Collection: piazza_users


    Relations:
    ---------------------------------------------------
    * Dataset: Link to the associated Dataset.
    * PiazzaContent_GoodTags: Relationship with good tags by this user.
    * PiazzaContent_HistoryEntries: Relationship with edited history elements.
    * PiazzaContent_ChangeLogs: ChangeLog Entries for the PiazzaContent.
    * PiazzaContent_Children: Children authored.
    * PiazzaContent_Child_Endorsements: Endorsements of child posts.
    * PiazzaContent_Child_HistoryEntries: History of children.
    * PiazzaContent_Child_Subchildren: Subchildren authored by this user.


    Fields:
    -------------------------------------------------------------
    * Course_ID: ID of the associated Dataset.
    * _id: Mongodb object ID (unique).
    * user_id: (string) Piazza unique user ID.  
    * answers: (int) Count of answers given to questions.
    * posts: (int) Count of posts made.
    * views: (int) Count of views made.  
    * asks: (int) Count of asks made.  
    * name: (string) Student real name or anonymized name.
    * days: (int) Days active or logged in?
    * email: (string) User's email address (is in standard form so can be split.)
    * first_name: (string) first name of student extracted from name field.
    * middle_name: (string) middle name of student extracted from name field.
    * last_name: (string) last name of student extracted from name field.
    """

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

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

    # Relationship with good tags by this user.
    PiazzaContent_GoodTags = RelationProperty("PiazzaContent_TagGood")

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

    # ChangeLog Entries for the PiazzaContent.
    PiazzaContent_ChangeLogs = RelationProperty("PiazzaContent_ChangeLog")

    # Children authored.
    PiazzaContent_Children = RelationProperty("PiazzaContent_Child")

    # Endorsements of child posts.
    PiazzaContent_Child_Endorsements = RelationProperty(
        "PiazzaContent_Child_Endorsement")

    # History of children.
    PiazzaContent_Child_HistoryEntries = RelationProperty(
        "PiazzaContent_Child_History")

    # Subchildren authored by this user.
    PiazzaContent_Child_Subchildren = RelationProperty(
        "PiazzaContent_Child_Subchild")

    # ID of the main user to which this is linked (updated on MigrateRawContent).
    CentralUser_ID = ForeignIdProperty("User")
    CentralUser = RelationProperty("User")

    # Link to the associated Dataset (updated on MigrateRawContent)
    Course_ID = ForeignIdProperty('Dataset')
    Course = RelationProperty('Dataset')

    # ---------------------------------------------
    # Original Fields.
    #
    # These fields are part of the original Piazza data.
    # as downloaded in the fields.
    # =============================================

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

    # Piazza unique user ID.
    user_id = FieldProperty(str)

    # Count of answers given to questions.
    answers = FieldProperty(int)

    # Count of posts made.
    posts = FieldProperty(int)

    # Count of views made.
    views = FieldProperty(int)

    # Count of asks made.
    asks = FieldProperty(int)

    # Student real name or anonymized name.
    name = FieldProperty(str)

    # Days active or logged in?
    days = FieldProperty(int)

    # User's email address (is in standard form so can be split.)
    email = FieldProperty(str)

    # A note that may indicate specific caveats about this user ID.
    note = FieldProperty(str, required=False, if_missing=None)

    # ---------------------------------------------
    # Added Fields.
    #
    # These are split fields or other resolution fields that
    # will be added to the instance by the migration fields
    # below.
    # =============================================

    # Split field for individual names.
    first_name = FieldProperty(str)
    middle_name = FieldProperty(str)
    last_name = FieldProperty(str)

    # ======================================================================
    # Duplicate Methods.
    #
    # Remove Duplace elements from the database.
    # ======================================================================

    @staticmethod
    def removeDuplicateUsers(DatasetID):
        """
        Remove duplicate users from the dataset.
        """
        UserIDs = set(collectAllPiazzaIDs())
        for ID in UserIDs:
            Users = collectUsersByPiazzaID(ID)
            if (len(Users) > 1):
                # print "%s %d" % (ID, len(Users))
                for U in Users[1:]:
                    U.delete()

        ModSocDB.Session.flush()

    # ======================================================================
    # Migration Function.
    #
    # Migrate or update the initial raw format with one that adds in the
    # split name fields and other data.
    # ======================================================================

    @staticmethod
    def migrateRawContent(DatasetID):
        """
        This is a static method that will extract and iterate over
        the raw user content to generate the additional fields that
        will be used for later evaluation.

        At the same time this will reevaluate the name fields.  If the
        name field is the empty string then it will be set to None. 

        It will also establish a link with an appropriate User instance
        in the database or, if none is present, it will create one.
        """
        Results = []
        RawUserList = PiazzaUser.query.find()
        for PUser in RawUserList:

            # Set the dataset ID.
            PUser.Course_ID = DatasetID

            # If the name field is "" then set it to None so
            # that the absence of a name is clear.  If not then
            # set the split name fields accordingly.  We will
            # then search for a matching user by name for merging.
            #
            # If none is found then we will make a user.  For the sake
            # of clarity we will treat users with None as the name as
            # unique and will not search for them.
            if (PUser.email == "") or (PUser.email == None):
                PUser.email = None
                CUser = None
            else:
                CUser = UserMod.findUserByEmail(PUser.email)

            # print "CUser Found: %s" % (CUser)

            if (CUser == None):
                PUser.makeSplitNameFields()
                first_name = PUser.first_name.title(
                ) if PUser.first_name else ""
                last_name = PUser.last_name.title() if PUser.last_name else ""
                CUser = UserMod.findUserByFirstLast(first_name, last_name)

                # print "CUser Found: %s" % (CUser)

                if (CUser == None):
                    CUser = UserMod.User.makeNewUser(
                        DatasetID=DatasetID,
                        Name=PUser.name.title(),
                        Email=PUser.email,
                        FirstName=first_name,
                        MiddleName=PUser.middle_name,
                        LastName=last_name,
                        PiazzaUserID=PUser._id)
                    # print "CUser Made: %s" % (CUser)
                else:
                    CUser.piazza_alt_email = PUser.email
                # ModSocDB.Session.flush()

            # And now set the appropriate link information to the
            # central user.
            PUser.CentralUser_ID = CUser._id
            CUser.PiazzaUser_ID = PUser._id
            CUser.PiazzaID = PUser.user_id
            ModSocDB.Session.flush()
            Results.append(CUser)

        ModSocDB.Session.flush()
        return Results

    # Add pushCentralAuthor(self) which goes over linked items and sets the
    # CentralAuthor_ID to be the same as the local central author.

    def makeSplitNameFields(self):
        """
        Split the user name into personal and family names so that
        those can be used for searching in the text.  This uses
        the name_tools library to segment the name into the
        standard blocks (Honorific, Personal Name, Family Name,
        Modifier).  It will then split the personal name on
        whitespace to get the first name.  
        """
        # print self.name
        Dict = NLP.makeSplitNameDict(self.name)

        self.first_name = Dict["FirstName"]
        self.middle_name = Dict["MiddleName"]
        self.last_name = Dict["LastName"]

        # print self
        return Dict

    # ---------------------------------------------
    # Simple Accessors/Settors
    # =============================================

    def getUserID(self):
        """
        Get the Piazza User ID set in the system.
        """
        return self.user_id

    def setUserID(self, NewUID):
        """
        Set the user_id field.
        """
        self.user_id = NewUID

    def getName(self):
        """
        Get the User name.
        """
        return self.name

    def setName(self, NewName):
        """
        Set the user name.
        """
        self.name = NewName

    def getFirstName(self):
        """
        Get the first_name value.
        """
        return self.first_name

    def setFirstName(self, NewName):
        """
        Set the first_name field.
        """
        self.first_name = NewName

    def getMiddleName(self):
        """
        Get the middle_name value.
        """
        return self.middle_name

    def setMiddleName(self, NewName):
        """
        Set the middle_name field.
        """
        self.middle_name = NewName

    def getLastName(self):
        """
        Get the last_name value.
        """
        return self.last_name

    def setLastName(self, NewName):
        """
        Set the last_name field.
        """
        self.last_name = NewName

    def getEmail(self):
        """
        Get the email.
        """
        return self.email

    def setEmail(self, NewEmail):
        """
        Set the new email.
        """
        self.email = NewEmail

    # ---------------------------------------------
    # Complex Accessors/Settors
    # =============================================

    def getSplitEmail(self):
        """
        If the e-mail is not null split it around the @
        and return the pairs as a 2-tuple.
        """
        Index = self.email.find('@')
        if (Index == -1): return (None, None)
        else: return (self.email[:Index], self.email[Index + 1:])

    def getSplitName(self):
        """
        This accessor uses the name_tools library to
        get the split name contents as a tuple which
        will then be returned.  It is also used to set
        the standard first-name, middleName, and LastName
        fields above.
        """
        return name_tools.split(self.name)

    @staticmethod
    def overwriteUserData(DatasetID=None, Timeout=False):
        """
        This static method will query for all defined users and will
        overwrite their ID information based upon the information in
        the associated User class instance.

        It is defined here as a static method but will be called
        primarily from the anonymization code after the upstream
        users have been updated.

        Most of the actual work is done by the syncPiazzaAuthorIDs
        method which does the scut work.
        """
        Users = findAllUsers(DatasetID=DatasetID, Timeout=Timeout)
        for U in Users:
            U.user_id = None
            U.syncPiazzaAuthorIDs()
        ModSocDB.Session.flush()

    def syncPiazzaAuthorIDs(self):
        """
        As part of the anonymization process it is necessary to
        reset the anonymous user ID.  This code will first pull
        the name and ID information from the user instance and 
        will then set the values locally.  

        This code will then iterate over all items that are 
        linked to this user and that have a set author or uid 
        field associated with it.  These will then be reset to 
        the current user ID.  This assumes that the links are 
        already set correctly and that the sole purpose is a 
        brute-force reset of the link code.

        This will also foceably sync user names.  Facebook IDs and
        photos will simply be purged if present.

        NOTE:: This makes no attempt to retain separate facebook IDs
        emails or photos from the good tags or endorsements for later
        use.  
        """

        NewID = self.CentralUser.getLocalUserID()
        NewName = self.CentralUser.getName()
        NewFirstName = self.CentralUser.getFirstName()
        NewMiddleName = self.CentralUser.getMiddleName()
        NewLastName = self.CentralUser.getLastName()
        NewEmail = self.CentralUser.getEmail()

        # Set the local information.
        self.setName(NewName)
        self.setFirstName(NewFirstName)
        self.setMiddleName(NewMiddleName)
        self.setLastName(NewLastName)
        self.setEmail(NewEmail)

        # The user ID information is on the id field of the tags.
        for Tag in self.PiazzaContent_GoodTags:
            Tag.id = NewID
            Tag.name = NewName
            Tag.email = None
            Tag.photo = None
            Tag.facebook_id = None

        # The UID author info is on the History entries.
        for Hist in self.PiazzaContent_HistoryEntries:
            Hist.uid = NewID

        # ChangeLog Entries for the PiazzaContent.
        for Change in self.PiazzaContent_ChangeLogs:
            Change.uid = NewID

        # Children authored.
        for Child in self.PiazzaContent_Children:
            Child.uid = NewID
            Child.id = None
            Child.overwriteUserData()

        # Endorsements of child posts.
        for Endorse in self.PiazzaContent_Child_Endorsements:
            Endorse.id = NewID
            Endorse.name = NewName
            Endorse.email = None
            Endorse.photo = None
            Endorse.facebook_id = None

        # History of children.
        for ChildHist in self.PiazzaContent_Child_HistoryEntries:
            ChildHist.id = NewID

        # Subchildren authored by this user.
        for Subchild in self.PiazzaContent_Child_Subchildren:
            Subchild.uid = NewID