def lbl_forgotpwd_click(self, event): if getattr(self, 'txt_in_username').get_text() == '': MessageModal( self, title='Error', message= f'Please enter your username to recieve an email containing the verification code!', messageType='info') else: user = Container.filter( User, User.userName == getattr( self, 'txt_in_username').get_text()).first() if user == None: MessageModal(self, title='Error', message=f'This username doesn\'t exist!', messageType='error') else: sparepwd = Container.filter( SparePwd, SparePwd.userId == user.id).first() if sparepwd == None or sparepwd.expirationDate < datetime.now( ): sparepwd = SparePwd(user=user, expirationDate=datetime.now() + timedelta(days=1), verificationCode=generate_code()) Container.save(sparepwd) MessageModal( self, title='Success', message='A verification code has been sent to your email!', messageType='info') send_email(user, sparepwd.verificationCode)
def getUnreadMessages(self): # first we will get the sessions that this user # has collaborated in sessions = [] # search for collaborations for c in Container.filter(Collaboration, Collaboration.userId == SessionWindow.ACTIVE_USER.id): sessions.append(c.sessionId) # search for owned sessions for s in Container.filter(Session, Session.ownerId == SessionWindow.ACTIVE_USER.id): sessions.append(s.id) # retrieve all received messages allmsgs = [] for s in sessions: for m in Container.filter(Message, Message.sessionId == s): if m not in allmsgs and m != None: allmsgs.append(m) # retrieve seen messages seenmsgs = [] for m in allmsgs: if m.userId == SessionWindow.ACTIVE_USER.id: seenmsgs.append(m) elif len(Container.filter(SeenMessage, SeenMessage.messageId == m.id, SeenMessage.seerId == SessionWindow.ACTIVE_USER.id).all()) > 0: seenmsgs.append(m) # retrieve unseen messages unseenmsgs = [] for m in allmsgs: if m not in seenmsgs: unseenmsgs.append(m) # return return unseenmsgs
def invite_user(self, username): def send_invite(msg, user, privilege): inv = Invitation(privilege=privilege, invitationTime=datetime.datetime.now(), sender=CollaborationWindow.ACTIVE_USER, recipient=user, session=self.session) Container.save(inv) notif = Notification(type=NotificationType.INVITED.value, notificationTime=datetime.datetime.now(), nature=NotificationNature.INV.value, invitationId=inv.id, actor=inv.sender, recipient=inv.recipient) Container.save(notif) msg.destroy() MessageModal( self, title=f'Success', message=f'Invitation sent to {user.userName} successfully!', messageType='info') user = Container.filter(User, User.userName == username).first() collabs = Container.filter( User, Collaboration.sessionId == self.session.id, or_(User.id == Collaboration.userId, User.id == self.session.ownerId)).all() if user == None: MessageModal( self, title='User error 404', message=f'{username} doesn\'t exist!' if username != '' and not str.isspace(username) else 'Please enter a username!', messageType='error') elif user in collabs: MessageModal(self, title='User already in', message=f'{username} is already in the session!', messageType='error') elif Container.filter(Invitation, Invitation.recipientId == user.id, Invitation.sessionId == self.session.id, Invitation.status == Status.PENDING.value).first() != None: MessageModal(self, title='User already invited', message=f'An invite is already sent to {username}!', messageType='info') else: msg = MessageModal( self, title=f'Confirmation', message= f'An invitation will be sent to [{username}], but do you want to give him the right to make changes?', messageType='prompt', actions={ 'yes': lambda e: send_invite(msg, user, 'edit'), 'no': lambda e: send_invite(msg, user, 'read') })
def fill_projects(self): # cleaning up old items self.lv_project.empty() # refilling for item in Container.filter(Project, Project.ownerId == HomeWindow.ACTIVE_USER.id): if Container.filter(Session, Session.projectId == item.id).first() == None: li = self.lv_project.grid_item(item, {'title': item.title, 'creationDate': item.creationDate, 'lastEdited': item.lastEdited, 'image': item.image}, None, lambda i: self.create_list_item(i), 15) self.set_image(li, item.image) li.lbl_image.bind('<Configure>', lambda e, l=li, image= item.image: self.resize_image(e, l, image))
def fill_sessions(self): # cleaning up old items self.lv_session.empty() # refilling for item in Container.filter(Session): if item.owner == HomeWindow.ACTIVE_USER or Container.filter(Collaboration, Collaboration.userId == HomeWindow.ACTIVE_USER.id, Collaboration.sessionId == item.id).first() != None: li = self.lv_session.grid_item(item, {'title': item.title, 'creationDate': item.creationDate, 'lastEdited': item.project.lastEdited, 'memberCount': str(Container.filter(Collaboration,Collaboration.sessionId == item.id).count()+1), 'image': item.project.image}, None, lambda i: self.create_list_item(i, HomeWindow.SESSION_LI), 15) self.set_image(li, item.project.image) li.lbl_image.bind('<Configure>', lambda e, l=li, image= item.project.image: self.resize_image(e, l, image))
def clean_notifications(self): notifs = Container.filter(Notification) for notif in notifs: if notif.nature == NotificationNature.INV.value and Container.filter(Invitation, Invitation.id == notif.invitationId).first() == None: Container.deleteObject(notif) elif notif.nature == NotificationNature.INVLINK.value: invitationLink = Container.filter(InvitationLink, InvitationLink.id == notif.invitationId).first() if invitationLink == None or Container.filter(Collaboration, Collaboration.sessionId == invitationLink.sessionId, Collaboration.userId == notif.actorId).first() == None: Container.deleteObject(notif) elif notif.nature == NotificationNature.SHARELINK.value and Container.filter(ShareLink, ShareLink.id == notif.invitationId).first() == None: Container.deleteObject(notif)
def getLastMessages(self): msgs = [] for i in Container.filter(Session): if i.owner == SessionWindow.ACTIVE_USER or Container.filter(Collaboration, Collaboration.userId == SessionWindow.ACTIVE_USER.id, Collaboration.sessionId == i.id).first() != None: msg = Container.filter(Message, Message.sessionId == i.id).order_by(Message.sentDate.desc()).first() if msg != None: msgs.append(msg) # make the order key def orderKey (e): return e.sentDate # sort msgs.sort(key=orderKey, reverse=True) # return return msgs
def btn_signin_click(self, event): if getattr(self, 'txt_in_username').get_text() == '' or getattr( self, 'txt_in_password').get_text() == '': MessageModal( self, title='Error', message=f'Please enter your username and password to login!', messageType='info') else: user = Container.filter( User, User.userName == getattr( self, 'txt_in_username').get_text()).first() if user == None: MessageModal(self, title='Error', message=f'This username doesn\'t exist!', messageType='error') else: if user.password != getattr(self, 'txt_in_password').get_text(): sparepwd = Container.filter( SparePwd, SparePwd.userId == user.id).order_by( SparePwd.expirationDate.desc()).first() if sparepwd != None and sparepwd.verificationCode == getattr( self, 'txt_in_password').get_text(): if sparepwd.expirationDate < datetime.now(): MessageModal( self, title='Expired code', message=f'This verification code has expired!', messageType='error') else: window = ProfileWindow(self.master, user=user) self.windowManager.run(window) MessageModal( self, title='Change password', message=f'Please change your password!', messageType='info') else: MessageModal( self, title='Wrong password', message= f'Wrong password, please try again or request a verification code!', messageType='error') else: self.windowManager.run(HomeWindow(self.master, user=user))
def generate_share_link(self, dataObject, modal): def set_link(link): modal.form[0]['input'].entry.delete(0,END) modal.form[0]['input'].entry.insert(0,link) def check_privilege(msg, modal, slink): def generate_link(msg2, modal, slink, privilege): msg2.destroy() if slink != None: Container.deleteObject(slink) link= f'bpmntool//{dataObject.title}/{datetime.now()}/' Container.save(ShareLink(link=link, expirationDate=datetime.now()+timedelta(days=1), privilege= privilege, project=dataObject)) self.clean_notifications() set_link(link) if msg != None: msg.destroy() msg2 = MessageModal(self,title=f'Confirmation',message=f'Do you want to grant this link the "edit" privilege?',messageType='prompt',actions={'yes' : lambda e: generate_link(msg2, modal, slink, 'edit'), 'no' : lambda e: generate_link(msg2, modal, slink, 'read')}) def set_old_link(msg,modal): set_link(slink.link) msg.destroy() slink = Container.filter(ShareLink, ShareLink.projectId == dataObject.id).first() if slink != None: msg = check_privilege(None, modal, slink) if slink.expirationDate < datetime.now() else MessageModal(self,title='Link found',message=f'An active link already exists, Do you want to override it?',messageType='prompt',actions={'yes': lambda e: check_privilege(msg, modal, slink) , 'no': lambda e: set_old_link(msg,modal)}) else: check_privilege(None, modal, None)
def btn_signup_next(self, event): validated_fields = self.validate_step() if self.current + 1 == 3 and validated_fields == 2: if Container.filter( User, User.userName == getattr( self, 'txt_up_username').get_text()).first() != None: MessageModal( self, title='UserName taken', message= f'{getattr(self, "txt_up_username").get_text()} is already taken\nplease pick another userName!', messageType='error') else: atts = {} Container.save( User(email=self.txt_email.get_text(), userName=self.txt_up_username.get_text(), firstName=self.txt_firstname.get_text(), lastName=self.txt_lastname.get_text(), password=self.txt_up_pwd.get_text(), company=self.txt_company.get_text(), gender=self.txt_gender.get_text())) self.empty_all() MessageModal( self, title='Success', message= 'Account created !\nFeel free to Login and good luck with your work!', messageType='info') MoveTransition(self.frm_veil_set_x, self.frm_veil_get_x, 0, 2.5) else: return validated_fields
def configure_settings(self): # get_label = lambda prop: getattr(self, f'lbl_{prop}') # change label get_label(CollaborationWindow.lblSettings[0] ['prop'])['text'] = self.session.title get_label( CollaborationWindow.lblSettings[1]['prop'] )['text'] = self.session.creationDate.strftime( "%d/%m/%Y" ) if datetime.datetime.now( ).strftime("%x") != self.session.creationDate.strftime( "%x") else 'Today at - ' + self.session.creationDate.strftime("%X") get_label( CollaborationWindow.lblSettings[2]['prop'] )['text'] = self.session.project.lastEdited.strftime( "%d/%m/%Y" ) if datetime.datetime.now( ).strftime("%x") != self.session.project.lastEdited.strftime( "%x" ) else 'Today at - ' + self.session.project.lastEdited.strftime("%X") get_label(CollaborationWindow.lblSettings[3]['prop'])['text'] = str( Container.filter(Collaboration, Collaboration.sessionId == self.session.id).count() + 1) # change image if self.session.project.image != None: photo = getdisplayableimage(self.session.project.image, (self.frm_preview.winfo_width(), self.frm_preview.winfo_height())) self.lbl_image.configure(image=photo) self.lbl_image.image = photo # fill self.fill_collaboration() self.fill_members()
def join_project(self, modal): link = modal.get_form_data()['txt_link'] slink = Container.filter(ShareLink, ShareLink.link == link).first() if slink == None: MessageModal(self, title= f'Link error' ,message= 'This link doesn\'t exist!', messageType= 'error') elif slink.expirationDate < datetime.now(): MessageModal(self, title= f'Link error' ,message= 'This link has expired!', messageType= 'error') else: if slink.project.owner != HomeWindow.ACTIVE_USER :noti = Notification(notificationTime= datetime.now(), type= NotificationType.JOINED.value, nature= NotificationNature.SHARELINK.value, invitationId= slink.id, actor= HomeWindow.ACTIVE_USER, recipient= slink.project.owner) modal.destroy() self.windowManager.run(EditorWindow(self.master, slink.project))
def join_session(self, modal): link = modal.get_form_data()['txt_link'] date = datetime.now() invlink = Container.filter(InvitationLink, InvitationLink.link == link).first() if invlink == None: MessageModal(self, title= f'Link error' ,message= 'This link doesn\'t exist!', messageType= 'error') elif invlink.expirationDate < datetime.now(): MessageModal(self, title= f'Link error' ,message= 'This link has expired!', messageType= 'error') elif Container.filter(Collaboration, Collaboration.userId == HomeWindow.ACTIVE_USER.id, Collaboration.sessionId == invlink.sessionId).first() != None or invlink.session.owner == HomeWindow.ACTIVE_USER: MessageModal(self, title= f'Error' ,message= f'You are already in {invlink.session.title} session!', messageType= 'error') else: # create relations if they don't exist if Container.filter(Relation,Relation.userOne == HomeWindow.ACTIVE_USER, Relation.userTwo == invlink.sender ).first() == None: Container.save(Relation(userOne= HomeWindow.ACTIVE_USER, userTwo= invlink.sender)) if Container.filter(Relation,Relation.userTwo == HomeWindow.ACTIVE_USER, Relation.userOne == invlink.sender ).first() == None: Container.save(Relation(userTwo= HomeWindow.ACTIVE_USER, userOne= invlink.sender)) # create collaboration Container.save(Collaboration(joiningDate= date, privilege= invlink.privilege, user= HomeWindow.ACTIVE_USER, session= invlink.session)) # add an acceptedInv type notification noti = Notification(notificationTime= date, type= NotificationType.JOINED.value, nature= NotificationNature.INVLINK.value, invitationId= invlink.id, actor= HomeWindow.ACTIVE_USER, recipient= invlink.sender) modal.destroy() self.windowManager.run(CollaborationWindow(self.master, invlink.session))
def getNotificationContent(notification): if notification.type.endswith('Inv'): inv = Container.filter(Invitation).get(notification.invitationId) if notification.type == NotificationType.INVITED.value: return f'{inv.sender.userName} invited you to ({inv.session.title}) session.' elif notification.type == NotificationType.JOINED.value: return f'{inv.recipient.userName} joined ({inv.session.title}) session.' else: decision = 'accepted' if notification.type == NotificationType.ACCEPTED.value else 'declined' return f'{inv.recipient.userName} {decision} the ({inv.session.title}) session invitation.' else: if notification.nature == NotificationNature.INVLINK.value: invlink = Container.filter(InvitationLink).get( notification.invitationId) return f'{notification.actor.userName} joined ({invlink.session.title}) session via link.' elif notification.nature == NotificationNature.SHARELINK.value: sharelink = Container.filter(ShareLink).get( notification.invitationId) return f'{notification.actor.userName} joined ({sharelink.project.title}) project via link.'
def configure_msg_listitem(self, root, item): li = ListItemFactory.DiscussionListItem(root, item) # set message listItem click for c in [li, li.frm_content, li.lbl_username, li.lbl_user, li.lbl_content, li.lbl_time, li.img_photo]: c.bind('<Button-1>', lambda e: self.windowManager.run_tag('discussion',session= item.session)) # change style for unread messages if item.user != self.ACTIVE_USER and Container.filter(SeenMessage, SeenMessage.messageId == item.id,SeenMessage.seerId == SessionWindow.ACTIVE_USER.id).first() == None: self.change_session_item_style(li,self.CHAT_UNREAD) # return list item return li
def configure_notif_listitem(self, root, item): li= ListItemFactory.NotificationListItem(root, item) li.window = self # save notification that are not recieveInv as seen if item.type != NotificationType.INVITED.value and Container.filter(SeenNotification, SeenNotification.notificationId == item.id, SeenNotification.seerId == SessionWindow.ACTIVE_USER.id).first() == None: Container.save(SeenNotification(date= datetime.datetime.now(), seer= SessionWindow.ACTIVE_USER, notification= item)) # append this item to a list self.created_notif_items.append (li) # return return li
def fill_collaboration(self): self.frm_list_view.empty() # BOOKMARK_DONE: Fill Collaboration Session Change History for i in Container.filter( History, History.projectId == self.session.projectId ).order_by(History.editDate.desc()).all( ): #, or_(History.editorId == Collaboration.userId, History.editorId == self.session.ownerId) since the project is gonna be unique if i.project.owner == CollaborationWindow.ACTIVE_USER or Container.filter( Collaboration, Collaboration.sessionId == self.session.id, Collaboration.userId == CollaborationWindow.ACTIVE_USER.id).first() != None: li = ListItem( self.frm_list_view.interior, i, { 'username': f'{i.editor.userName} edited on {i.editDate.strftime("%d/%m/%Y at %X")}', 'image': i.editor.image }, self.get_btn_list(i)) li.pack(anchor=N + W, fill=X, pady=(0, 10), padx=5) self.historyItems.append(li)
def generate_inviationlink(self, modal): # modal.form[0]['input'].entry.get() def set_link(link): modal.form[0]['input'].entry.delete(0, END) modal.form[0]['input'].entry.insert(0, link) def check_privilege(msg, modal, inv): def generate_link(msg2, modal, inv, privilege): msg2.destroy() if inv != None: Container.deleteObject(inv) link = f'bpmntool//{self.session.title}/{datetime.datetime.now()}/' Container.save( InvitationLink(link=link, expirationDate=datetime.datetime.now() + datetime.timedelta(days=1), privilege=privilege, sender=CollaborationWindow.ACTIVE_USER, session=self.session)) self.clean_notifications() set_link(link) if msg != None: msg.destroy() msg2 = MessageModal( self, title=f'Confirmation', message=f'Do you want to grant this link the "edit" privilege?', messageType='prompt', actions={ 'yes': lambda e: generate_link(msg2, modal, inv, 'edit'), 'no': lambda e: generate_link(msg2, modal, inv, 'read') }) def set_old_link(msg, modal): set_link(inv.link) msg.destroy() inv = Container.filter( InvitationLink, InvitationLink.senderId == CollaborationWindow.ACTIVE_USER.id, InvitationLink.sessionId == self.session.id).first() if inv != None: msg = check_privilege( None, modal, inv ) if inv.expirationDate < datetime.datetime.now( ) else MessageModal( self, title='link found', message=f'A link already exists, Do you want to override it?', messageType='prompt', actions={ 'yes': lambda e: check_privilege(msg, modal, inv), 'no': lambda e: set_old_link(msg, modal) }) else: check_privilege(None, modal, None)
def downloadimagefile(userid): if userid != 0: user = Container.filter(User).get(userid) directory = filedialog.askdirectory( initialdir="/", title='select a directory to download the image to') if directory != '': bytestofile(directory, 'test', 'jpg', user.image) image = getdisplayableimage(user.image, (200, 200)) displayimage(image) else: messagebox.askokcancel(root, message='please enter a user id')
def downloadxmlfile(projectid): if projectid != 0: project = Container.filter(Project).get(projectid) directory = filedialog.askdirectory( initialdir="/", title='select a directory to download the xml file to') if directory != '': bytestofile(directory, 'testxml', 'xml', project.file) element = bytestoelement(project.file) displaycontent(element) else: messagebox.askokcancel(root, message='please enter a project id')
def Configure_session(self, event, listItem): self.frm_veil.place_forget() self.fill_discussion(listItem.dataObject.session) self.lbl_sessionName['text'] = listItem.dataObject.session.title self.lbl_memberCount[ 'text'] = f'{Container.filter(Collaboration,Collaboration.sessionId == listItem.dataObject.session.id).count()+1} ' + translate( 'Members') self.txt_message.bind('<Return>', lambda event, listItem=listItem: self. send_message(event, listItem)) if self.currentItem != None: self.change_session_item_style(self.currentItem, self.CHAT_NORMAL) self.currentItem = listItem self.change_session_item_style(self.currentItem, self.CHAT_ACTIVE) currentSession = self.currentItem.dataObject.session # mark previous messages as seen prevmsgs = Container.filter( Message, Message.sessionId == currentSession.id, Message.userId != DiscussionWindow.ACTIVE_USER.id) # mark them as seen for m in prevmsgs: # check if already marked if len( Container.filter( SeenMessage, SeenMessage.messageId == m.id, SeenMessage.seerId == DiscussionWindow.ACTIVE_USER.id).all()) > 0: continue # mark as read Container.save( SeenMessage(date=datetime.datetime.now(), seer=DiscussionWindow.ACTIVE_USER, message=m))
def delete_collaboration(user): Container.deleteObject( Container.filter( Collaboration, Collaboration.userId == user.id, Collaboration.sessionId == self.session.id).first()) msg.destroy() for li in self.collaboratorItems: if li.dataObject == user: li.destroy() getattr( self, 'lbl_' + CollaborationWindow.lblSettings[3]['prop'] )['text'] = str( Container.filter( Collaboration, Collaboration.sessionId == self.session.id).count() + 1) MessageModal( self, title=f'Success', message=f'{user.userName} has been kicked out of the session!', messageType='info')
def fill_history(self): # BOOKMARK: fill history items self.frm_list_view.empty() for i in Container.filter( History, History.projectId == self.project.id).order_by( History.editDate.desc()): li = ListItem( self.frm_list_view.interior, i, { 'username': f'{i.editor.userName} edited on {i.editDate.strftime("%d/%m/%Y at %X")}', 'image': i.editor.image }, self.get_btn_list(i)) li.pack(anchor=N + W, pady=(0, 10), fill=X, padx=5) self.historyItems.append(li)
def fill_sessions(self): self.msgItems.clear() self.lv_sessions.empty() for i in Container.filter(Session): if i.owner == DiscussionWindow.ACTIVE_USER or Container.filter( Collaboration, Collaboration.userId == DiscussionWindow.ACTIVE_USER.id, Collaboration.sessionId == i.id).first() != None: msg = Container.filter(Message, Message.sessionId == i.id).order_by( Message.sentDate.desc()).first() # if msg == None: msg = Message(content=f'welcome to the chat',user=i.owner, session=i, sentDate=i.creationDate) li = ListItemFactory.DiscussionListItem( self.lv_sessions.interior, msg) self.msgItems.append(li) if msg.user != self.ACTIVE_USER and Container.filter( SeenMessage, SeenMessage.messageId == msg.id, SeenMessage.seerId == DiscussionWindow.ACTIVE_USER.id).first() == None: self.change_session_item_style(li, self.CHAT_UNREAD) # append to a static a list # configure item click self.configure_session_click()
def uploadimagefile(userid): if userid != 0: user = Container.filter(User).get(userid) filename = filedialog.askopenfilename( initialdir="/", title="select image to upload to user", filetypes=(("jpeg/jpg files", "*.jpg"), ("png files", "*.png"), ("all files", "*.*"))) if filename.lower().endswith(('.png', '.jpg')) == True: bytesimage = filetobytes(filename) user.image = bytesimage Container.save(user) image = getdisplayableimage(bytesimage, (200, 200)) displayimage(image) else: messagebox.askokcancel(root, message='please choose an image file') else: messagebox.askokcancel(root, message='please enter a user id')
def fill_collaborators(self): self.lv_collabs.empty() for i in Container.filter( Relation, Relation.userOneId == ProfileWindow.ACTIVE_USER.id): self.collaboratorsItems.append( self.lv_collabs.grid_item(i, { 'username': i.userTwo.userName, 'image': i.userTwo.image }, [{ 'text': 'Remove', 'icon': 'cancel.png', 'cmd': lambda e, relation=i: self.remove_collaborator(relation) }], None, 15))
def uploadxmlfile(projectid): if projectid != 0: project = Container.filter(Project).get(projectid) filename = filedialog.askopenfilename( initialdir="/", title="select xml file to upload to project", filetypes=(("xml files", "*.xml"), ("all files", "*.*"))) if filename.lower().endswith('.xml') == True: bytesfile = filetobytes(filename) if len(bytesfile) != 0: project.file = bytesfile Container.save(project) element = bytestoelement(bytesfile) displaycontent(element) else: messagebox.showwarning(root, message='Empty xml file') else: messagebox.askokcancel(root, message='please choose an xml file') else: messagebox.askokcancel(root, message='please enter a project id')
def fill_members(self): # Remove all items self.lv_members.empty() # Append items for i in Container.filter( User, Collaboration.sessionId == self.session.id, or_(User.id == Collaboration.userId, User.id == self.session.ownerId)).all(): li = ListItem(self.lv_members.interior, i, { 'username': i.userName, 'image': i.image }, [{ 'icon': 'cancel.png', 'text': translate('Kick'), 'cmd': lambda e, user=i: self.kick_user(user), }] if i != self.session.owner else None) li.pack(anchor=N + W, pady=(0, 10), padx=(10, 10), fill=X) self.collaboratorItems.append(li)
def runnable2(self): # try: while self.time_to_kill != True: time.sleep(2) # Container.session.commit() for li in self.msgItems: lastmsg = Container.filter( Message, Message.sessionId == li.dataObject.session.id).order_by( Message.sentDate.desc()).first() if lastmsg != None and lastmsg != li.dataObject: li.lbl_content['text'] = lastmsg.content if len( lastmsg.content) < 20 else lastmsg.content[:17] + '...' li.lbl_time['text'] = lastmsg.sentDate.strftime("%X") li.dataObject = lastmsg self.change_session_item_style(li, self.CHAT_UNREAD) if self.currentItem != None and self.currentItem == li: self.currentItem = li self.create_message(lastmsg)
def fill_discussion(self, session): # dispose of old items self.lv_messages.empty() # fill with new items for i in Container.filter(Message, Message.sessionId == session.id).order_by( Message.sentDate.asc()).all(): self.create_message(i) # scroll up self.lv_messages.canvas.yview_moveto(0) # scrolling down thread def scroll_down_thread(): # import sleep method from time import sleep # sleep for a while sleep(0.25) # scroll down self.lv_messages.canvas.yview_moveto(1) # start thread threading.Thread(target=scroll_down_thread).start()