예제 #1
0
class Entity(db.Model):
    """
    A table for storing base entities.
    The Entity class serves as a base class
    for users, objects, circles, and channels.

    """
    __tablename__ = 'entity'

    guid = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(30), nullable=False)
    # reference to the object subtype, e.g. post
    # subtype = db.Column(db.String(30))
    owner_guid = db.Column(db.Integer)
    circle_guid = db.Column(db.Integer)
    # container_guid = db.Column(db.Integer)
    # access_id = db.Column(db.Integer)
    created_at = db.Column(db.DateTime, default=now())
    updated_at = db.Column(db.DateTime, default=now())

    __mapper_args__ = {
        'polymorphic_on': type,
        'polymorphic_identity': 'entity'
    }

    def __repr__(self):
        return '<Entity {}>'.format(self.type)
예제 #2
0
def store_calendar_users(users, database_session, sync_id):
    tasks = sync_tasks = SyncTask.query.filter_by(
        sync_id=sync_id,
        class_name=CalendarUser.__name__,
        commit_id='get_pull_users')
    tasks.update({
        'store_start': now(),
        'status': 'storing'
    },
                 synchronize_session=False)
    db.session.commit()
    obs = []
    try:
        for user in users:
            primary_key = user.get('id')
            values = {
                'id': user.get('id'),
                'primary_alias': user.get('primaryEmail'),
                'given_name': get_nested(user, 'name', 'givenName'),
                'family_name': get_nested(user, 'name', 'familyName'),
                'full_name': get_nested(user, 'name', 'fullName'),
                'current_calendar_timezone': user.get('timezone')
            }
            calendar_user = insert_or_update(CalendarUser, primary_key, values,
                                             database_session)
            if user.get('emails'):
                for email in user.get('emails'):
                    primary_key = email.get('address')
                    values = {
                        'alias': primary_key,
                        'calendar_user': calendar_user,
                        'calendar_user_id': calendar_user.id
                    }
                    insert_or_update(CalendarUserAlias, primary_key, values,
                                     database_session)
            else:
                primary_key = user.get('primaryEmail')
                values = {
                    'alias': user.get('primaryEmail'),
                    'calendar_user': calendar_user,
                    'calendar_user_id': calendar_user.id
                }
                insert_or_update(CalendarUserAlias, primary_key, values,
                                 database_session)
        tasks.update({'status': 'success'}, synchronize_session=False)
    except Exception as e:
        tasks.update({
            'status': 'error',
            'errors': str(e)
        },
                     synchronize_session=False)
        raise
    finally:
        tasks.update({'store_end': now()}, synchronize_session=False)

        db.session.commit()
    database_session.commit()
예제 #3
0
def calendar_sync_main(user_id, calendars):
    # Get the API client
    user = User.query.get(int(user_id))
    sync = Sync(status='pending', user=user, start=now())
    db.session.add(sync)
    task = SyncTask(sync=sync,
                    class_name=CalendarUser.__name__,
                    commit_id='get_pull_users',
                    status='pending')
    db.session.add(task)
    for cal in calendars:
        task = SyncTask(sync=sync,
                        class_name=CalendarEvents.__name__,
                        commit_id=cal,
                        status='pending')
        db.session.add(task)
    db.session.commit()

    sync_id = sync.id

    database_session = None
    try:
        # TODO this is assuming the user always has one database, which is true for now
        database = user.databases[0]
        database_url = database.get_url()
        engine = create_engine(database_url)
        database_session = sessionmaker(bind=engine)()

        cal_client = get_calendar_api_client(user.id)

        users = get_calendar_users(user, calendars, cal_client, sync_id)
        store_calendar_users(users, database_session, sync_id)

        for cal in calendars:
            cal_events = get_calendar_events(cal_client, cal, sync_id)
            store_calendar_events(cal, cal_events, database_session, sync_id)

        sync.status = 'success'
    except Exception as e:
        sync.status = 'failed'
        sync.message = str(e)
        raise
    finally:
        sync.end = now()
        if database_session:
            database_session.close()
        db.session.commit()

    return {"DONE": True}
예제 #4
0
class Message(db.Document):

    from_user = db.ReferenceField(User, db_field="fu", reverse_delete_rule=CASCADE)
    to_user = db.ReferenceField(User, db_field="tu", default=None, reverse_delete_rule=CASCADE)
    post = db.StringField(db_field="pt", max_length=1024)
    live = db.BooleanField(db_field="l", default=None)
    create_date = db.LongField(db_field="c", default=now())
    images = db.ListField(db_field="is", default=None)
    parent = db.ObjectIdField(db_field="p", default=None)
    message_type = db.IntField(db_field="mt", default=POST, choices=MESSAGE_TYPE)

    @property
    def likes(self):
        return Message.objects.filter(parent=self.id, message_type=LIKE).order_by("-create_date")

    @property
    def comments(self):
        return Message.objects.filter(parent=self.id, message_type=COMMENT).order_by("create_date")

    @property
    def text_linkified(self):
        return linkify_text(self.post)

    @property
    def human_timestamp(self):
        return ms_stamp_humanize(self.create_date)

    def post_image_src(self, images_time_stamp, size):
        if self.images:
            profile_img = join_path(STATIC_IMAGE_URL, 'posts', "{}.{}.{}.png".format(self.id, images_time_stamp, size))
            return profile_img.replace("\\", '/') # mostly for windows because windows uses a black slash to save.

    meta = {
        'indexes': [("from_user", "to_user", "-create_date", "message_type", "parent", "live")]
    }
예제 #5
0
class User(Entity):
    """
    A table for storing user records.

    """
    __tablename__ = 'user'

    id = db.Column(db.Integer, db.ForeignKey('entity.guid'), primary_key=True)
    name = db.Column(db.String(64), nullable=False)
    username = db.Column(db.String(64), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(128), nullable=False)
    language = db.Column(db.String(64))
    # session code
    code = db.Column(db.Integer)
    last_action = db.Column(db.DateTime, default=now())
    prev_last_action = db.Column(db.DateTime, default=now())
    last_login = db.Column(db.DateTime, default=now())
    prev_last_login = db.Column(db.DateTime, default=now())

    __mapper_args__ = {'polymorphic_identity': 'user'}

    def __repr__(self):
        return '<User {}>'.format(self.username)

    # TODO: add avatar
    @property
    def serialize_user_info(self):
        return {
            'userInfo': {
                'uid': self.id,
                'name': self.name,
                'username': self.username,
                'avatar': 'http://profile.actionsprout.com/default.jpeg',
            },
            'lastUpdated': self.updated_at,
        }

    @property
    def serialize_member(self):
        return {
            'name': self.username,
            'userId': self.id,
            'avatar': 'http://profile.actionsprout.com/default.jpeg',
        }
예제 #6
0
def store_calendar_events(calendar_id, data, database_session, sync_id):
    tasks = sync_tasks = SyncTask.query.filter_by(
        sync_id=sync_id,
        class_name=CalendarEvents.__name__,
        commit_id=calendar_id)
    tasks.update({
        'store_start': now(),
        'status': 'storing'
    },
                 synchronize_session=False)
    db.session.commit()

    try:
        for event in data:
            primary_key = event.get('id')
            values = {
                "event_id": primary_key,
                "organizer_email": get_nested(event, 'organizer', 'email'),
                "creator_email": get_nested(event, 'creator', 'email'),
                "status": event.get('status'),
                "is_recurring": not not event.get('recurringEventId'),
                "recurrence_id": event.get('recurringEventId'),
                "title": event.get('summary'),
                "location": event.get('location'),
                "description": event.get('description')
            }
            if get_nested(event, 'start', 'dateTime'):
                values['start_time'] = dateutil.parser.parse(
                    get_nested(event, 'start', 'dateTime'))

            if get_nested(event, 'end', 'dateTime'):
                values["end_time"] = dateutil.parser.parse(
                    get_nested(event, 'end', 'dateTime'))

            if event.get('created'):
                values["created_at"]: dateutil.parser.parse(
                    event.get('created'))

            if event.get('updated'):
                values["updated_at"]: dateutil.parser.parse(
                    event.get('updated'))

            is_organizer = get_nested(event, 'organizer', 'self')

            calendar_event = insert_or_update(CalendarEvents, primary_key,
                                              values, database_session)
            if event.get('attendees') is None and is_organizer:
                store_calendar_event_attendees(event, None, calendar_id,
                                               database_session, is_organizer)
            else:
                for attendee in event.get('attendees') or []:
                    attendee_primary_key = (event.get('id'),
                                            attendee.get('email'))
                    store_calendar_event_attendees(event, attendee,
                                                   attendee.get('email'),
                                                   database_session,
                                                   is_organizer)
        tasks.update({'status': 'success'}, synchronize_session=False)
    except Exception as err:
        tasks.update({
            'status': 'error',
            'errors': str(err)
        },
                     synchronize_session=False)
        raise err
    finally:
        tasks.update({'store_end': now()}, synchronize_session=False)

        db.session.commit()

    database_session.commit()
예제 #7
0
def get_calendar_users(user, calendars, cal_client, sync_id):
    user_client = get_user_api_client(user.id)
    tasks = SyncTask.query.filter_by(sync_id=sync_id,
                                     class_name=CalendarUser.__name__,
                                     commit_id='get_pull_users')
    tasks.update({
        'pull_start': now(),
        'status': 'pulling'
    },
                 synchronize_session=False)
    db.session.commit()

    # TODO is this the best way to get the domain or customer ID for a user?
    domain = user.email[user.email.find("@") + 1:]
    page_token = None
    users = []
    i = 0
    try:
        while True:
            if domain == 'gmail.com':
                user_list = None
                page_users = [{
                    'id': user.sub,
                    'primaryEmail': user.email,
                    'name': {
                        'givenName': user.given_name,
                        'familyName': user.family_name,
                        'fullName': user.name
                    }
                }]
            else:
                user_list = user_client.users().list(pageToken=page_token,
                                                     viewType='domain_public',
                                                     domain=domain).execute()
                page_users = user_list.get('users', [])
            for entry in page_users:
                if entry['primaryEmail'] in calendars:
                    request = cal_client.calendars().get(
                        calendarId=entry['primaryEmail']).execute()
                    if i == 0:
                        i = 1
                    entry['timezone'] = request.get('timeZone')

                    users.append(entry)
            if user_list:
                page_token = user_list.get('nextPageToken')
            if not page_token:
                break

        tasks.update({'status': 'success'}, synchronize_session=False)
    except Exception as e:
        tasks.update({
            'status': 'error',
            'errors': str(e)
        },
                     synchronize_session=False)
        raise
    finally:
        tasks.update({'pull_end': now()}, synchronize_session=False)

        db.session.commit()

    return users
예제 #8
0
def get_calendar_events(cal_client, cal, sync_id):
    tasks = sync_tasks = SyncTask.query.filter_by(
        sync_id=sync_id, class_name=CalendarEvents.__name__, commit_id=cal)
    tasks.update({
        'pull_start': now(),
        'status': 'pulling'
    },
                 synchronize_session=False)

    db.session.commit()

    # Loop through all the calendars we need to fetch
    start_datetime = datetime.utcnow() - timedelta(days=HISTORIC_DAYS_TO_PULL)
    start_datetime = start_datetime.replace(tzinfo=pytz.UTC)

    end_datetime = datetime.utcnow() + timedelta(days=FUTURE_DAYS_TO_PULL)
    end_datetime = end_datetime.replace(tzinfo=pytz.UTC)

    logging.info(
        f'Getting calendar data for {cal} from {start_datetime} - {end_datetime}'
    )

    try:
        all_events = []
        response = cal_client.events().list(calendarId=cal,
                                            maxResults=100,
                                            singleEvents=True,
                                            orderBy='startTime',
                                            timeMin=start_datetime.isoformat(),
                                            timeMax=end_datetime.isoformat(),
                                            timeZone='UTC').execute()
        nextPageToken = response.get('nextPageToken')
        events = response.get('items', [])

        all_events = events

        while nextPageToken:
            # Fetch this series of results
            response = cal_client.events().list(
                calendarId=cal,
                maxResults=100,
                singleEvents=True,
                orderBy='startTime',
                timeMin=start_datetime.isoformat(),
                timeMax=end_datetime.isoformat(),
                pageToken=nextPageToken).execute()
            nextPageToken = response.get('nextPageToken')
            events = response.get('items', [])
            all_events = all_events + events

        tasks.update({'status': 'success'}, synchronize_session=False)
    except Exception as err:
        tasks.update({
            'status': 'error',
            'errors': str(err)
        },
                     synchronize_session=False)
        raise err
    finally:
        tasks.update({'pull_end': now()}, synchronize_session=False)

        db.session.commit()
    return all_events