def deleteQuery(self, query_id, *args, **kwargs): ''' Allows user to delete a query. Updates query logging. @param query_id: identifies the query @return: status of attempted delete operation of the query ''' query = session.query(Query).get_by(query_id=int(query_id)) status = "" if not query: status = "Query not found" elif session.query(ChatSession).get_by(query_id=int(query_id)): status = "Chat already started" elif query.user_id != identity.current.user.user_id: status = "Permission denied" else: query.experts[:] = [] query_log=QueryLog( query_id = int(query_id), user_id = query.user_id, user_name = session.query(User).get_by(user_id=query.user_id).user_name, created = datetime.now(), status = 'Deleted') session.save(query_log) session.flush() session.delete(query); session.flush(); return dict(status=status)
def validate_email_change(self, email, key): ''' Validates the email address change and update the database appropriately. @param email: The email to be verified @param key: The verification key @return: Data for template population ''' is_valid = False admin_email = config.get('registration.mail.admin_email') email_change = register_model.RegistrationUserEmailChange.get_by_new_email(email) if not email_change: return dict(is_valid=False, admin_email=admin_email) if email_change.validation_key == key: is_valid = True user = email_change.user # change the user's email address and delete the email_change record user.email_address = email session.save(user) session.flush() email_change.destroy_self() else: return dict(is_valid=False, admin_email=admin_email) return dict(is_valid=is_valid, email=email, name=user.display_name, admin_email=admin_email)
def isOnline(self): ''' @return: Boolean (true if user is online). ''' user_stats = self.user_stats # reload if status is old if not user_stats.isOnlineLastUpdated or user_stats.isOnlineLastUpdated < datetime.now() - timedelta(seconds = constants.isOnlineExpire): t=[] visit=session.query(Visit).select(and_(VisitIdentity.c.visit_key == Visit.c.visit_key, self.user_id == VisitIdentity.c.user_id)) isOnline = 0 for v in visit: t.append(v.expiry) t.sort() t.reverse() if len(t) > 0 and datetime.now()<t[0]: isOnline = 1 user_stats.isOnline = isOnline user_stats.isOnlineLastUpdated = datetime.now() session.save(user_stats) session.flush() return user_stats.isOnline == 1
def update_setting(self, *args, **kwargs): ''' Updates user settings. @param **kwargs: contains information about anonymity, sending a queries by email and newsletter ''' user = User.get_by(User.c.user_id==identity.current.user.user_id) s = user.getSettings() if kwargs['anonymous'] == "true": s.anonymous = 1 user.display_name = "anonymous"; else: s.anonymous = 0 user.display_name = user.user_name; if kwargs['email'] == "true": s.email = 1 else: s.email = 0 if kwargs['newsletter'] == "true": s.newsletter = 1 else: s.newsletter = 0 session.save(user); session.save(s); session.flush(); return dict()
def rate(self, query_id, rating, *args, **kwargs): ''' Rates the chat. Updates user score and statistics. @param query_id: needed to identify chat session @param rate: points given ''' cs = ChatSession.select(ChatSession.c.query_id==query_id)[0]; if not cs.user_id == identity.current.user.user_id: return dict() cs.rating = int(rating) cs.status = "RATED" session.save(cs); session.flush(); expert=session.query(User).get_by(user_id=int(cs.expert_id)) stats = expert.user_stats new_value=round(stats.average_rating*stats.no_of_ques_answered_rated) stats.no_of_ques_answered_rated+=1 stats.average_rating=(new_value+float(rating))/stats.no_of_ques_answered_rated stats.score=round(stats.no_of_ques_answered_rated * stats.average_rating + stats.no_of_blog_ratings * stats.average_blog_rating) session.flush(); return dict()
def doBlogRating(self, blogentry_id, rate, *args, **kwargs): ''' Calculates blog rating. Updates note's score, score of the user who created it and keeps track of who rated which note (this way user can rate note only once). @param blogentry_id: identifies note @param rate: points given ''' #update the blogentry table entry = session.query(BlogEntry).get_by(blogentry_id=int(blogentry_id)) if not entry: return dict() new_value=round(entry.average_rating*entry.no_ratings) #print 'old blog score', new_value,'old average',entry.average_rating entry.no_ratings+=1 entry.average_rating=(new_value+float(rate))/entry.no_ratings #print 'rate', rate,'new average', entry.average_rating session.flush() #updates the user_blog table new_rate=UserBlog() new_rate.user_id = identity.current.user.user_id new_rate.blogentry_id = blogentry_id new_rate.rating = rate new_rate.created = datetime.datetime.now() session.save(new_rate) session.flush() #updates the user_stats table user=session.query(User).get_by(user_id = entry.user_id) user.user_stats.no_of_blog_ratings+=1 #print 'old averege blog rating',user.user_stats.average_blog_rating user_blogs=session.query(BlogEntry).select(BlogEntry.c.user_id==entry.user_id) #[BlogEntry.c.average_rating, BlogEntry.c.no_ratings] sum=0.0 no_blogs=0 for ub in user_blogs: sum+=ub.average_rating*ub.no_ratings no_blogs+=ub.no_ratings sum=round(sum)/no_blogs #print 'new average blog rating',sum user.user_stats.average_blog_rating=sum #print 'old score',user.user_stats.score #print 'new values', user.user_stats.no_of_ques_answered_rated * user.user_stats.average_rating, user.user_stats.no_of_blog_ratings * user.user_stats.average_blog_rating user.user_stats.score=round(user.user_stats.no_of_ques_answered_rated * user.user_stats.average_rating + user.user_stats.no_of_blog_ratings * user.user_stats.average_blog_rating) #print 'new score',user.user_stats.score session.flush() return dict()
def getWebsites(self, websites): ''' Takes the websites one by one and checks their status. @param websites: websites given by the user @return: status and classification for each website ''' status = {} subgraphs = {} new_sites = [] ongoing_crawls = [] # filter impossible websites for website in websites: if website == "": continue if len(website) < 4 or website.find(".") == -1: status[website] = "No valid url" continue #check if the filetype is allowed for bannedStr in self.bannedFileTypes: if website.endswith(bannedStr): status[website] = "Only html supported" break if not website in status: new_sites.append(website) status[website] = "" if len(new_sites) > 0: stored_sites = session.query(Website).select(Website.c.url.in_(*new_sites)) for site in stored_sites: #sometimes the encoding is different ... so better check if site.url in new_sites: new_sites.remove(site.url) if site.crawl == 1: ongoing_crawls.append(site.url) else: status[site.url] = site.status if site.subgraph: subgraphs[site.url] = cPickle.loads(site.subgraph.encode('latin1')) # insert new websites if len(new_sites) > 0: inserts = [] for site in new_sites: print "Adding website ", site new_ws = Website() new_ws.url = site new_ws.alpha = 1.5 session.save(new_ws) session.flush() return (status, subgraphs, ongoing_crawls)
def sendFeedback2DB(self, *args, **kwargs): ''' Stores the users feedback information to the database and sends the information as E-Mail to feedback.mail.receiver ''' user = session.query(User).get_by(User.c.user_id == identity.current.user.user_id) #first: send email for receiver in config.get('feedback.mail.receiver'): self.send_email( receiver, user.user_name + " via " + config.get('feedback.mail.admin_email'), config.get('feedback.mail.subject.prefix') + " " + user.user_name, kwargs['design'], kwargs['interaction'], kwargs['bugs'], kwargs['ideas'] ) #second: write feedback in the database feed = Feedback() feed.user_id = user.user_id feed.design = kwargs['design'] feed.interaction = kwargs['interaction'] feed.bugs = kwargs['bugs'] feed.ideas = kwargs['ideas'] session.save(feed) feed_int = FeedbackInt() feed_int.user_id = user.user_id feed_int.fast_registration = kwargs['fast_registration'] feed_int.ask_many_steps = kwargs['ask_many_steps'] feed_int.change_automatic_classification = kwargs['change_automatic_classification'] feed_int.easy_categorization = kwargs['easy_categorization'] feed_int.right_categorization = kwargs['right_categorization'] feed_int.competent_expert = kwargs['competent_expert'] feed_int.see_answer = kwargs['see_answer'] feed_int.see_question = kwargs['see_question'] feed_int.quick_answer = kwargs['quick_answer'] feed_int.helpful_answer = kwargs['helpful_answer'] feed_int.expert_online = kwargs['expert_online'] feed_int.no_system_errors = kwargs['no_system_errors'] feed_int.system_speed = kwargs['system_speed'] feed_int.everyday = kwargs['everyday'] feed_int.clear_design = kwargs['clear_design'] feed_int.predictable_reaction = kwargs['predictable_reaction'] feed_int.how_to_use = kwargs['how_to_use'] session.save(feed_int) session.flush() return {}
def create(self, user_name, email, email2, password1, password2, nocache=None, **kwargs): ''' Creates a temporary user entry (pending user) in a db (that can be promoted to permanent after validation). @param user_name: Users name @param email: Users email address @param email2: Users email address for verification @param password1: Users password @param password2: Users password for verification @param nocache: Argument for preventing browser caching @return: User name and email address ''' if not identity.current.anonymous: redirect('/') key = self.validation_hash(email + user_name + password1) pend = register_model.RegistrationPendingUser.new( user_name=user_name, email_address=email, display_name=user_name, password=password1, validation_key=key ) if config.get('registration.unverified_user.groups'): # we have unverified_user.groups. Add the user to the User table # and add the appropriate groups user = self.promote_pending_user(pend) self.add_unverified_groups(user) # log them in session.flush() i = identity.current_provider.validate_identity(user_name, password1, identity.current.visit_key) identity.set_current_identity(i) expertise = {} for arg in kwargs: #get int arguments try: expertise[int(arg)] = int(kwargs[arg]) except: pass rpf = RegistrationPendingProfile(pending_user_id=pend.id,expertise=expertise) session.save(rpf) session.flush() self.mail_new_validation_email(pend) return dict(name=user_name, email=email)
def do_BlogPost(self, *args, **kwargs): ''' Creates new note entry. @param **kwargs: contains blogentry_id,text and title of the note, and information weather the note is private ''' id = int(kwargs['blogentry_id']); private = kwargs['private'] == "true"; query_id = None if 'query_id' in kwargs and kwargs['query_id'] > -1: query_id = int(kwargs['query_id']); text=kwargs['text'][:16250] title=kwargs['title'][:50] if id < 0: b = BlogEntry(); b.title = title b.text = text; b.private = private; b.user_id = identity.current.user.user_id; subtree = self.getBlogSubtree("",b.text+" "+b.title) b.profile_subtree=cPickle.dumps(subtree) if query_id: b.query_id = query_id user=session.query(User).get_by(user_id = b.user_id) user.user_stats.no_of_blogs+=1 else: b = session.query(BlogEntry).get_by(blogentry_id=id) b.title = title b.text = text b.private = private; subtree = self.getBlogSubtree("",b.text+" "+b.title) b.profile_subtree=cPickle.dumps(subtree) if query_id: b.query_id = query_id session.save(b); session.flush(); return dict()
def getSettings(self): ''' A user's settings. If user settings are empty, settings are first created. @return: User settings. ''' s = self.settings if s: return s else: from spree.spree_model import Settings self.settings = Settings() session.save(self) session.flush() return self.getSettings()
def new(cls, user, new_email_address, validation_key): ''' Factory method creates a new instance of this class (both in python and in the db). @param cls: The user class @param user: An identity user object @param new_email_address: The new email @param validation_key: The generated validation key ''' kw = dict(user_id=user.user_id, new_email_address=new_email_address, validation_key=validation_key) email_chg = cls(**kw) session.save(email_chg) session.flush() return email_chg
def test_creation(self): """Object creation should set the name.""" obj = User(user_name = u"creosote", email_address = u"*****@*****.**", display_name = u"Mr Creosote", password = u"Wafer-thin Mint") # mark object as 'to be saved' session.save(obj) # flush marked obj to db session.flush() retrieved_user = User.by_email_address(u'*****@*****.**') assert retrieved_user, \ 'User should have been found by email address' assert retrieved_user.user_name == u'creosote', \ "User name should have been creosote, not '%s'" % retrieved_user.user_name assert obj.display_name == u"Mr Creosote"
def updateRanks(): ''' updates all user ranks based on each users score ''' scores = getHighscoreList() stats = session.query(UserStats).select() user2rank = {} count = 1 for s in scores: user2rank[s[1]] = count count += 1 for s in stats: s.rank = user2rank[s.user_id] s.rankLastUpdated = datetime.now() session.save(s) session.flush()
def setUp(self): # Create tables metadata.drop_all() metadata.create_all() user1 = User() user1.user_name='bobvilla' user1.email_address='*****@*****.**' user1.display_name='Bob Villa' user1.password='******' session.save(user1) u2 = User() u2.user_name='bobathome' u2.email_address='*****@*****.**' u2.display_name='Bob Villa' u2.password='******' session.save(u2) session.flush() print 'UuUuUuU %s' % user1 self.user1 = user1 session.clear() session.close()
def new(cls, user_name, email_address, display_name, password, validation_key): ''' Writes temporary data about the user in a dbb @param cls: The user class @param user_name: The users name @param email_address: The users email address @param display_name: The users display name @param password: The users password @param validation_key: The validation key @return: The new pending user object ''' kw = dict ( user_name=user_name, email_address=email_address, display_name=display_name, password=password, validation_key=validation_key) pend = cls(**kw) session.save(pend) session.flush() return pend
def finish(self, query_id, *args, **kwargs): ''' Wreps up the finished chat. @param query_id: needed to identify chat session ''' cs = ChatSession.select(ChatSession.c.query_id==query_id)[0] query = Query.select(Query.c.query_id==cs.query_id)[0] cs.status = 'FINISHED' if query.isDirect == 1: cs.status = 'RATED' cm = ChatMessage(session_id=cs.session_id, user_id = identity.current.user.user_id, type = "FINISHED", text = "__ends the chat") query.status="FINISHED" query.experts = [] try: chat_log=session.query(ChatLog).get_by(ChatLog.c.query_id==cs.query_id) chat_log.chat_ended=datetime.now() if cm.user_id==chat_log.user_id: chat_log.who_ended='User' else: chat_log.who_ended='Expert' session.save(chat_log) except: pass session.save(cm) session.save(cs) session.save(query) session.flush() return dict()
def doDecline(self, query_id, *args, **kwargs): ''' Allows expert to decline query. Updates query logging. @param query_id: identifies the query ''' try: queryExpert = session.query(QueryExpert).select( and_(QueryExpert.c.query_id == query_id, QueryExpert.c.expert_id == identity.current.user.user_id) )[0] except: return {} queryExpert.status = "DECLINED" session.save(queryExpert) session.flush() query_log = QueryLog( query_id=int(query_id), user_id=queryExpert.expert_id, user_name=session.query(User).get_by(user_id=queryExpert.expert_id).user_name, status='Declined', created=datetime.now()) session.save(query_log) no_declined=0 query=session.query(Query).get_by(query_id=int(query_id)) queryExperts = list(session.query(QueryExpert).select(QueryExpert.c.query_id == query_id)) for qe in queryExperts: if qe.status == "DECLINED": no_declined+=1 if no_declined==len(queryExperts): query_log_all = QueryLog( query_id=int(query_id), user_id=query.user_id, user_name=session.query(User).get_by(user_id=query.user_id).user_name, status='Everybody declined', created=datetime.now()) session.save(query_log_all) session.flush() return {}
def join(self, query_id, *args, **kwargs): ''' Joins user and expert into a chat session. Logging about chat and query gets updated. @param query_id: chat evolves from a query @return: values needed for the template ''' ongoingSessions = ChatSession.count(ChatSession.c.query_id == int(query_id)) if ongoingSessions==0: query = session.query(Query).get_by(query_id=int(query_id)) if not query: raise redirect("/content/search/getQueryOverviewContent/"+query_id) query.status='HANDSHAKE'; cs = ChatSession( query_id = int(query_id), user_id = query.user_id, expert_id = identity.current.user.user_id, status='HANDSHAKE', text='', rating=-1) chat_log = ChatLog( query_id = cs.query_id, user_id = cs.user_id, user_name = session.query(User).get_by(user_id=cs.user_id).user_name, expert_id = cs.expert_id, expert_name = session.query(User).get_by(user_id=cs.expert_id).user_name, exp_accepted = datetime.now()) query_log = QueryLog( query_id=cs.query_id, user_id=cs.expert_id, user_name=session.query(User).get_by(user_id=cs.expert_id).user_name, status='Accepted', created=datetime.now()) session.save(query_log) #session.flush() query.experts = [] expert=session.query(User).get_by(user_id=int(cs.expert_id)) if query.isDirect == 0: expert.user_stats.no_of_ques_answered+=1 session.save(query); session.save(chat_log) session.flush(); #get session cs = ChatSession.select(ChatSession.c.query_id==query_id)[0]; isUser = cs.user_id == identity.current.user.user_id isExpert = cs.expert_id == identity.current.user.user_id if not isUser and not isExpert: raise redirect("/content/search/getQueryOverviewContent/"+query_id) # If expert created a note entry blogCount = BlogEntry.count(BlogEntry.c.query_id==cs.query_id) existsBlog = blogCount >0; if existsBlog: be = session.query(BlogEntry).get_by(query_id=int(cs.query_id)) blogentry_id = be.blogentry_id; else: blogentry_id = -1; text = "__joined chat"; if isExpert and cs.status=='HANDSHAKE': cmsCount = ChatMessage.count(ChatMessage.c.session_id==cs.session_id) if cmsCount==0: text = "__Query accepted. Please wait for user to join chat...." # create new "joined" message cm = ChatMessage(session_id=cs.session_id, user_id = identity.current.user.user_id, type = "JOINED", text = text) # label query for consistency query = session.query(Query).get_by(query_id=cs.query_id) if (cs.status=='HANDSHAKE') and isUser: cs.status = 'ONGOING' query.status = 'CHAT' query.experts = [] # create new "joined" message cm = ChatMessage(session_id=cs.session_id, user_id = identity.current.user.user_id, type = "JOINED", text = text) chat_log=session.query(ChatLog).get_by(ChatLog.c.query_id==cs.query_id) chat_log.user_joined=datetime.now() session.save(query); session.save(cm); session.save(cs); session.flush(); messages = ChatMessage.select( and_( ChatSession.c.query_id==int(query_id), ChatSession.c.session_id==ChatMessage.c.session_id ), order_by=ChatMessage.c.created) chat_entries = [] htmlText = "<b>" + query.getTopicString(isUser) + "</b>\n" + query.text + "\n" + "<b>Categories:</b>" + query.getCategoriesString() htmlText = htmlText.replace("\n","<br/>") chat_entries.append({"id":-1, "date": query.created.strftime("%H:%M"), "user": session.query(User).get_by(user_id=query.user_id).display_name[:20], "text": Markup(htmlText)}) chat_entries.extend( [{ "id":m.chat_message_id, "date":m.created.strftime("%H:%M"), "user":session.query(User).get_by(user_id=m.user_id).display_name[:20], "text":Markup(m.text.replace("\n","<br/>")) } for m in messages] ) last_entry_id = -1 #messages[-1].chat_message_id; status = cs.status if cs.rating and cs.rating >= 0: status = "RATED" myName = None if isExpert: username = session.query(User).get_by(user_id = cs.user_id).display_name[:20] expertname = session.query(User).get_by(user_id = cs.expert_id).user_name[:20] myName = expertname else: username = session.query(User).get_by(user_id = cs.user_id).user_name[:20] expertname = session.query(User).get_by(user_id = cs.expert_id).display_name[:20] myName = username return dict(query_id=query_id, topic=query.topic, query=query.text[:60], isDirect=query.isDirect, session_status = status, isExpert = isExpert, blogentry_id = blogentry_id, existsBlog = existsBlog , chat_entries = chat_entries, last_entry_id = last_entry_id, rating = cs.rating, time = helpers.formatDate(cs.created), username = username, expertname = expertname, user_id = cs.user_id, expert_id = cs.expert_id, myName = myName)
if a['major'] < b['major']: return -1 elif a['major'] > b['major']: return 1 else: if a['minor'] < b['minor']: #or c-sharp return -1 elif a['minor'] > b['minor']: return 1 else: return cmp(a['point'], b['point']) update_files = sorted(update_files, lambda a, b: cmp_for_schema_change(a[1], b[1])) def apply_change(file): text = open(file).read() print "applying ", file s = sql.text(text) get_engine().execute(s) for file, data in update_files: with session.begin_nested(): if not session.query(SchemaChange).filter_by(**data).all(): apply_change(file) new_change = SchemaChange(**data) session.save(new_change)
def new_visit_with_key(self, visit_key): visit = visit_class(visit_key=visit_key, expiry=datetime.now()+self.timeout) session.save(visit) return Visit(visit_key, True)
def doQuery(self, *args, **kwargs): ''' Accepts a new query, classifies it (automatic classification could be enough, but manual interruption is allowed in this stage too) and saves it in a db. Updates query logging. If expert settings demand it, email with the query is sent. @param **kwargs: contains text, topic and categories of the query @return: query_id ''' text = kwargs['query'][:16250] topic = kwargs['topic'][:50] categories_set = kwargs['categories_set'] try: # we got only one integer instead of a list nodes = tree_model.getNodesOnPath(int(categories_set)) categories = [int(categories_set)] except: nodes = [] for cat in categories_set: nodes.extend(tree_model.getNodesOnPath(int(cat))) categories = [int(cat) for cat in categories_set] categories_calculated = tree_model.getSubtreeForText(topic + " " + text, 1.5) q = Query(user_id = identity.current.user.user_id, text= text, topic = topic, status='OPEN') q.profile_calculated_subtree=cPickle.dumps(categories_calculated) q.profile_subtree = cPickle.dumps(list(set([node.node_id for node in nodes]))) q.profile = cPickle.dumps(categories) user=session.query(User).get_by(user_id = identity.current.user.user_id) user.user_stats.no_of_ques_asked+=1 query_log=QueryLog( user_id=identity.current.user.user_id, user_name=identity.current.user.user_name ) #-1 means that the question is asked for the first time, not reposted query_id=kwargs.get('query_id',-1) if (int(query_id))!=-1: query_existing=session.query(Query).get_by(Query.c.query_id==query_id) expert_id=query_existing.chatSession.expert_id query_log.status='Asked again' q.findExperts(expert_id) else: query_log.status='New' q.findExperts() q.findRelatedBlogs() session.save(q) session.flush() query_log.query_id=q.query_id session.save(query_log) print 'ZZZZZZZZZZZZZZZZZZZ',query_log.query_id session.flush() # send emails to all experts (if wanted) in a different thread from spree.util.cherrypy import url baseUrl = url.getServerUrl() #threading.Thread(target=q.informExperts, args=[baseUrl]).start() q.informExperts([baseUrl]) return dict(query_id = q.query_id)
print a, b #there has to be a better way! if a['major'] < b['major']: return -1 elif a['major'] > b['major']: return 1 else: if a['minor'] < b['minor']: #or c-sharp return -1 elif a['minor'] > b['minor']: return 1 else: return cmp(a['point'], b['point']) update_files = sorted(update_files, lambda a,b: cmp_for_schema_change(a[1], b[1])) def apply_change(file): text = open(file).read() print "applying ", file s = sql.text(text) get_engine().execute(s) for file, data in update_files: with session.begin_nested(): if not session.query(SchemaChange).filter_by(**data).all(): apply_change(file) new_change = SchemaChange(**data) session.save(new_change)