def signIn(curr): ''' Prompts the user to enter their user ID and password. Checks if they exist in the database. If not, it returns the user ID. Inputs: curr -- sqlite3.Cursor Returns: str ''' validInfo = False while not validInfo: uid = input('\nEnter your user ID: ') pwd = getpass.getpass('Enter your password: '******'SELECT * FROM users WHERE uid = :userID COLLATE NOCASE AND pwd = :password;', {'userID': uid, 'password': pwd}) userRow = curr.fetchone() if userRow: validInfo = True print(bcolor.green('You have successfully signed in.')) return userRow['uid'] else: print(bcolor.errmsg('error: invalid user ID or password.')) prompt = bcolor.warning('Do you still want to sign in? [y/n] ') uin = getValidInput(prompt, ['y','n']) if uin == 'n': return None
def editPost(conn, curr, pid): ''' Edit the title and body of the selected post. inputs: conn: sqlite3.Connection curr: sqlite3.Cursor pid: pid ''' curr.execute("SELECT title, body FROM posts WHERE pid=?;", (pid, )) currT, currB = curr.fetchone() print(bcolor.pink("\n< Edit Post >")) confirmed = False while not confirmed: nTitle, nBody = changeTitleAndBody(currT, currB) confirmed = isChangeValid(nTitle, nBody) curr.execute(''' UPDATE posts SET title = ?, body = ? WHERE pid = ?;''', (nTitle, nBody, pid)) conn.commit() print(bcolor.green("\nPost Edited!"))
def signUp(conn, curr): ''' Prompt the user for necessary information for account creation, and save it into the database. inputs: conn -- sqlite3.Connection curr -- sqlite3.Cursor ''' valid = False while not valid: print() # ask for id, name, city, password uid = getNewID(curr) f_name = input("Enter your first name: ").capitalize() l_name = input("Enter your last name: ").capitalize() name = ' '.join((f_name, l_name)) city = input("Enter your city: ").capitalize() pwd = getNewPassword() crdate = str(date.today()) if checkValid(uid, name, city): valid = True else: cont = getValidInput(bcolor.warning('Do you still want to sign up? [y/n] '), ['y', 'n']) if cont == 'n': return print(bcolor.green("Sign up successful!")) curr.execute("INSERT INTO users VALUES (?, ?, ?, ?, ?);", [uid, name, pwd, city, crdate]) conn.commit()
def castVote(conn, curr, pid, uid): ''' Prompt the user to cast a vote to the selected post. Inputs: conn -- sqlite3.Connection curr -- sqllite3.Connection pid -- selected post (str) uid -- uid of the current user (str) ''' print('\n' + bcolor.pink('< Vote on the Post >')) prompt = 'Do you want to vote on this post? [y/n] ' confirm = page.getValidInput(prompt, ['y', 'n']) if confirm == 'y': # checks if the user has already voted for the selected post curr.execute('SELECT * FROM votes WHERE pid = ? and uid = ?;', [pid, uid]) if curr.fetchone(): print( bcolor.errmsg( "action failed: you've already voted for this post.")) else: vdate = str(date.today()) vno = getVno(curr) curr.execute('INSERT INTO votes VALUES (?, ?, ?, ?);', [pid, vno, vdate, uid]) conn.commit() print() print(bcolor.green('Voting Completed!'))
def postAns(conn, curr, poster, qid): ''' Prompt the user to post an answer for the selected question. This function assumes the type of the selected post is question. Inputs: conn -- sqlite3.Connection curr -- sqllite3.Connection poster -- uid of the current user (str) qid -- selected post (str) ''' print() print(bcolor.pink('< Write an Answer >')) infoList = getPInfo(curr) if infoList: infoList.append(poster) # infoList = [pid, pdate, title, body, poster] curr.execute('INSERT INTO posts VALUES (?, ?, ?, ?, ?);', infoList) curr.execute('INSERT INTO answers VALUES (?, ?);', [infoList[0], qid]) conn.commit() print() print(bcolor.green('Posting Completed!'))
def mainMenu(conn, curr, uid): ''' The main loop of the main menu available after successful sign in. Inputs: conn -- sqlite3.Connection curr -- sqlite3.Cursor uid -- uid of signed in user ''' isPriv = isPrivileged(curr, uid) valid = False while not valid: name = getName(curr, uid) printMainPage(name, isPriv) option = getValidInput('Enter a command: ', ['pq', 'sp', 'so', 'q']) if option == 'pq': action.postQ(conn, curr, uid) elif option == 'sp': targetPost, act = action.searchPosts(curr, isPriv) if len(targetPost) > 0 and act != '': executeAction(conn, curr, act, uid, targetPost['pid'], targetPost['poster']) else: print(bcolor.errmsg('No posts found.')) elif option == 'so': if checkSignout(): print('...') print(bcolor.green('You have been signed out.')) valid = True elif option == 'q': print('...') print(bcolor.green('You have been signed out.')) sys.exit(0)
def addTag(conn, curr, pid): ''' Add tags to the selected post. Inputs: conn -- sqlite3.Connection curr -- sqllite3.Cursor pid -- pid of the selected post (str) ''' print(bcolor.pink('\n< Add Tags >')) currentTags = getCurrentTag(curr, pid) displayCurrentTag(currentTags) valid = False while not valid: newTags = getValidTag() numNewTags = len(newTags) duplicates, nonDuplicates = getDuplicateTag(currentTags, newTags) numDups = len(duplicates) dsuffix = genSuffix(duplicates) tagsToAdd = True if numDups > 0: print(bcolor.errmsg('error: post already has the following tag{}: {}'.format(dsuffix, ', '.join(duplicates)))) if numNewTags == numDups: # user enters duplicates only tagsToAdd = False prompt = 'Do you want to add another tag to the post? [y/n] ' valid = not page.continueAction(prompt) else: newTags = nonDuplicates nsuffix = genSuffix(newTags) if tagsToAdd: prompt = 'Do you want to add: "{}" ? [y/n] '.format('", "'.join(newTags)) uin = page.getValidInput(prompt, ['y','n']) if uin == 'y': valid = True insertTag(conn, curr, pid, newTags) print(bcolor.green("\nTag{} Added!".format(nsuffix))) else: prompt = 'Do you still want to add tags to the post? [y/n] ' valid = not page.continueAction(prompt)
def giveBadge(conn, curr, uid): ''' Gives a badge to the poster of the selected post. Inputs: conn -- sqlite3.Connection curr -- sqlite3.Cursor uid -- poster of the selected post (str) ''' bdate = str(date.today()) if not badgeAvailable(curr): print(bcolor.errmsg("action failed: badge is not available now.")) elif isBadgeGivenTdy(curr, uid, bdate): print(bcolor.errmsg("action failed: this poster has already received a badge today.")) else: print(bcolor.pink('\n< Give a Badge >')) displayAvailBadges(curr) valid = False while not valid: bname = getBadge() badgeRow = getBadgeRow(curr, bname) if badgeRow: # badge already exists prompt = 'Do you want to give badge: "{}" to the poster? [y/n] '.format(badgeRow['bname']) uin = page.getValidInput(prompt, ['y','n']) if uin == 'y': curr.execute('INSERT INTO ubadges VALUES (?, ?, ?);',(uid, bdate, badgeRow['bname'])) conn.commit() print(bcolor.green('\nBadge Awarded to the poster!')) valid = True else: print(bcolor.errmsg('action failed: badge: "{}" is not available.'.format(bname))) if not valid: prompt = 'Do you still want to give a badge? [y/n] ' valid = not page.continueAction(prompt)
def changeAA(conn, curr, pid, aid): ''' Update the selected answer post as accepted to the database. inputs: conn -- sqlite3.Connection curr -- sqlite3.Cursor pid -- str aid -- str ''' curr.execute('''UPDATE questions SET theaid = :aid WHERE pid = :pid;''', {'aid': aid, 'pid': pid}) conn.commit() print(bcolor.green("\nAccepted Answer Updated!"))
def postQ(conn, curr, poster): ''' Prompt the user for a question post. pid is generated by the system. -- format: p'x', where x is an integer 0 <= x <= 999. Inputs: conn -- sqlite3.Connection curr -- sqllite3.Cursor poster -- uid of the signed in user (str) ''' print('\n' + bcolor.pink('< Post a Question >')) infoList = getPInfo(curr) if infoList: infoList.append(poster) # infoList = [pid, pdate, title, body, poster] curr.execute('INSERT INTO posts VALUES (?, ?, ?, ?, ?);', infoList) curr.execute('INSERT INTO questions VALUES (?, NULL);', [infoList[0]]) conn.commit() print() print(bcolor.green('Posting Completed!'))