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)
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()
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}
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")] }
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', }
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()
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
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