def questions_index_post(): form = QuestionForm(request.form, csrf_enabled=False) form.category.choices = [(str(c.id), c.name) for c in cdw.categories.all()] if form.validate(): return jsonify(cdw.questions.save(form.to_question())) else: return jsonify({"errors":form.errors}, 400)
def questions_index_post(): form = QuestionForm(request.form, csrf_enabled=False) form.category.choices = [(str(c.id), c.name) for c in cdw.categories.all()] if form.validate(): return jsonify(cdw.questions.save(form.to_question())) else: return jsonify({"errors": form.errors}, 400)
def suggest_question(): form = SuggestQuestionForm(as_multidict(request.json), csrf_enabled=False) message = 'We have received your question. Thanks for the suggestion %s!' % current_user.username if form.validate(): form.to_question().save() return jsonify({'status': 200, 'message': message}) else: return jsonify({'status': 500, 'errors': form.errors})
def users_index_post(): current_app.logger.debug('Creating user: %s' % request.form) form = KioskUserForm(request.form, csrf_enabled=False) if form.validate(): user = form.to_user() cdw.users.save(user) return jsonify(user) else: return jsonify({"errors": form.errors}, 400)
def users_index_post(): current_app.logger.debug('Creating user: %s' % request.form) form = KioskUserForm(request.form, csrf_enabled=False) if form.validate(): user = form.to_user() cdw.users.save(user) return jsonify(user) else: return jsonify({"errors":form.errors}, 400)
def questions_posts_get(id): page = int(request.args.get('page', request.args.get('skip', 0))) amt = int(request.args.get('amt', request.args.get('limit', 100))) try: posts, total = cdw.get_posts_for_question( cdw.questions.with_id(id), page, amt) posts = [x.as_dict(full_path=True) for x in posts] return jsonify({'status': 200, 'total': total, 'data': posts}) except Exception, exc: return jsonify({'status': 500, 'error': str(exc)})
def threads_show(id): thread = cdw.threads.with_id(id) result = thread.as_dict() result.update({ "posts": [p.as_dict() for p in cdw.posts.with_fields(**{"thread": thread})] }) return jsonify(result)
def users_authenticate(): try: user = auth_provider.authenticate(request.form) if login_user(user): return jsonify(user) except Exception: pass abort(400)
def kiosk_handler_get(id): kiosk_number = current_app.config['CDW']['kiosks']['kiosk_%s' % id] recentMessages = cdwapi.get_recent_sms_messages(kiosk_number) return jsonify({ "serverTime": str(datetime.datetime.now()), "number": kiosk_number, "recentMessages": recentMessages, })
def threads_posts_post(thread_id): thread = cdw.threads.with_id(thread_id) form = PostForm(request.form, csrf_enabled=False) if form.validate(): post = form.to_post() follow_sms = form.get_follow_sms() follow_email = form.get_follow_email() # Assume kiosk users want to follow by SMS, even if they haven't # provided their phone number since the SMS service is intelligent # enough to ignore users without phone numbers if form.origin.data == 'kiosk': follow_sms = True post = cdw.post_to_thread(thread, post, follow_sms, follow_email) return jsonify(post) else: return jsonify({"errors": form.errors}, 400)
def threads_posts_post(thread_id): thread = cdw.threads.with_id(thread_id) form = PostForm(request.form, csrf_enabled=False) if form.validate(): post = form.to_post() follow_sms = form.get_follow_sms() follow_email = form.get_follow_email() # Assume kiosk users want to follow by SMS, even if they haven't # provided their phone number since the SMS service is intelligent # enough to ignore users without phone numbers if form.origin.data == 'kiosk': follow_sms = True post = cdw.post_to_thread(thread, post, follow_sms, follow_email) return jsonify(post.as_dict(full_path=True)) else: return jsonify({"errors": form.errors}, 400)
def handle_message(user, message): if message in ['stop','unsubscribe']: cdwapi.stop_sms_updates(user) elif message in ['start','resume', 'subscribe']: cdwapi.resume_sms_updates(user) elif message in ['undo','stay']: cdwapi.revert_sms_updates(user) else: cdwapi.post_via_sms(user, message) return jsonify({ "success": True })
def questions_threads_post(id): question = cdw.questions.with_id(id) form = PostForm(request.form, csrf_enabled=False) current_app.logger.debug(request.form.to_dict()) if form.validate(): post = form.to_post() follow_sms = form.get_follow_sms() follow_email = form.get_follow_email() # The kiosk will send a phone number with the post if the user # wants to subscribe via SMS so we need to set the user's phone if form.origin.data == 'kiosk': follow_sms = True thread = cdw.create_thread(question, post, follow_sms, follow_email) return jsonify(thread) else: current_app.logger.debug("Error creating thread: %s" % form.errors) return jsonify({"error":form.errors}, 400)
def questions_threads_post(id): question = cdw.questions.with_id(id) form = PostForm(request.form, csrf_enabled=False) current_app.logger.debug(request.form.to_dict()) if form.validate(): post = form.to_post() follow_sms = form.get_follow_sms() follow_email = form.get_follow_email() # The kiosk will send a phone number with the post if the user # wants to subscribe via SMS so we need to set the user's phone if form.origin.data == 'kiosk': follow_sms = True thread = cdw.create_thread(question, post, follow_sms, follow_email) return jsonify(thread) else: current_app.logger.debug("Error creating thread: %s" % form.errors) return jsonify({"error": form.errors}, 400)
def kiosk_handler_post(id): try: # TODO: Add Twilio Validator kiosk_number = current_app.config['CDW']['kiosks']['kiosk_%s' % id] data = request.form.to_dict() phone = normalize_phonenumber(urllib.unquote(data['From'])) message = urllib.unquote_plus(data['Body']).strip() msg = cdwapi.save_incoming_sms(kiosk_number, phone, message) return jsonify(msg) except Exception, e: current_app.logger.error("Error receiving message from " "Twilio: %s" % e) raise e
def threads_show(id): thread = cdw.threads.with_id(id) result = thread.as_dict(full_path=True) # skip, limit = paginate() skip, limit = pager() if request.args.get('sort') and request.args.get('sort') == '-1': result.update({ "posts": [ p.as_dict(full_path=True) for p in cdw.posts.with_fields_recent_first( **{"thread": thread})[skip:limit] ] }) else: result.update({ "posts": [ p.as_dict(full_path=True) for p in cdw.posts.with_fields( **{"thread": thread})[skip:limit] ] }) return jsonify(result)
def posts_remove(id): cdw.delete_post(cdw.posts.with_id(id)) return jsonify(True)
def questions_threads_get(id): page = int(request.args.get('page', 0)) amt = int(request.args.get('amt', 100)) sort = request.args.get('sort', 'recent') origin = request.args.get('origin', 'web,kiosk,cell').split(',') sort_lookup = { 'recent': '-created', 'yes': '-yesNo', 'no': '+yesNo', 'responses': '-postCount' } order_rule = sort_lookup[sort] if sort in ['yes', 'no']: yesNo = [0] if sort == 'no' else [1] else: yesNo = [0, 1] #current_app.logger.debug('page=%s&amt=%s&sort=%s' % (page, amt, sort)) #current_app.logger.debug('order_rule=%s&start=%s&' # 'end=%s' % (order_rule, start, end)) threads = cdw.threads.with_fields( question=cdw.questions.with_id(id), origin__in=origin, yesNo__in=yesNo, ).order_by(order_rule) total = len(threads) # Index should only come from website # This is to prevent too many items from being loaded into the browser id_offset = request.args.get('id_offset', None) if id_offset: threads.rewind() threads = threads.select_related(1) i = 0 if id_offset != 'current': for t in threads: if str(t.id) == id_offset: break i += 1 # Organize them into a list with the offset in the middle # to give the website a never ending 'loop' feel organized = [] if total < 3: for n in range(0, total): organized.insert(0, threads[n]) else: # most items to each side possible without overlap rl = min(30, (total - 1) / 2) for n in range(i, i + rl + 1): if n >= total: ni = n - total else: ni = n if threads[ni] not in organized: organized.append(threads[ni]) for n in range(i - 1, i - 1 - rl, -1): if n < 0: ni = total + n else: ni = n if threads[ni] not in organized: organized.insert(0, threads[ni]) #current_app.logger.debug(organized) return jsonify(organized) else: start = max(0, page * amt) end = min(start + amt, total) return jsonify(threads[start:end])
def questions_index_get(): return jsonify(cdw.questions.all())
def questions_current(): question = cdw.questions.with_active(True) return jsonify(question)
def users_search(): data = request.args if request.method == 'GET' else request.form return jsonify(cdw.users.with_fields(**data.to_dict()))
def users_index_get(): return jsonify(cdw.users.all())
def users_show(id): return jsonify(cdw.users.with_id(id))
def posts_show(id): return jsonify(cdw.posts.with_id(id))
def posts_flag(id): post = cdw.posts.with_id(id) post.flags += 1 post.thread.flags += 1 post.thread.save() return jsonify(cdw.posts.save(post))
def questions_categories(): return jsonify(cdw.categories.all())
def questions_threads_get(id): page = int(request.args.get('page', 0)) amt = int(request.args.get('amt', 100)) sort = request.args.get('sort', 'recent') origin = request.args.get('origin', 'web,kiosk,cell').split(',') sort_lookup = { 'recent': '-created', 'yes': '-yesNo', 'no': '+yesNo', 'responses': '-postCount' } order_rule = sort_lookup[sort] if sort in ['yes','no']: yesNo = [0] if sort == 'no' else [1] else: yesNo = [0,1] #current_app.logger.debug('page=%s&amt=%s&sort=%s' % (page, amt, sort)) #current_app.logger.debug('order_rule=%s&start=%s&' # 'end=%s' % (order_rule, start, end)) threads = cdw.threads.with_fields( question=cdw.questions.with_id(id), origin__in = origin, yesNo__in = yesNo, ).order_by(order_rule) total = len(threads) # Index should only come from website # This is to prevent too many items from being loaded into the browser id_offset = request.args.get('id_offset', None) if id_offset: threads.rewind() threads = threads.select_related(1) i = 0 if id_offset != 'current': for t in threads: if str(t.id) == id_offset: break; i += 1 # Organize them into a list with the offset in the middle # to give the website a never ending 'loop' feel organized = [] # most items to each side possible without overlap rl = min(30, (total - 1) / 2) for n in range(i, i+rl): if n >= total: ni = n - total else: ni = n if threads[ni] not in organized: organized.append(threads[ni]) for n in range(i-1, i-1-rl, -1): if n < 0: ni = total + n else: ni = n if threads[ni] not in organized: organized.insert(0, threads[ni]) #current_app.logger.debug(organized) return jsonify(organized) else: start = max(0, page * amt) end = min(start + amt, total) return jsonify(threads[start:end])
def questions_show(id): return jsonify(cdw.questions.with_id(id))
def posts_like(id): post = cdw.posts.with_id(id) post.likes += 1 return jsonify(cdw.posts.save(post))
def posts_index_post(): form = PostForm(request.form, csrf_enabled=False) if form.validate(): return jsonify(cdw.posts.save(form.to_post())) else: return jsonify({"errors":form.errors}, 400)
def threads_posts_get(id): return jsonify(cdw.posts.with_fields( **{"thread":cdw.threads.with_id(id)}))
def users_phone(phone): return jsonify(cdw.users.with_phoneNumber(phone))
def stats_question(question_id): question = cdw.questions.with_id(question_id) stats = {} stats['question'] = question.as_dict() threads = cdw.threads.with_fields(question=question).order_by('-created') yes_debate_count = 0 no_debate_count = 0 yes_likes = 0 no_likes = 0 # Most Debated mostDebatedOpinions = list() mostLikedOpinions = list() for thread in threads: posts_in_thread = cdw.posts.with_fields(thread=thread) first_post = posts_in_thread[0] if first_post.likes > 0: mostLikedOpinions.append({ 'id': str(thread.id), 'commentCount': len(posts_in_thread), 'firstPost': first_post.as_dict(), 'likes': first_post.likes }) if len(posts_in_thread) > 1: mostDebatedOpinions.append({ 'id': str(thread.id), 'commentCount': len(posts_in_thread), 'firstPost': first_post.as_dict(), 'likes': first_post.likes }) if first_post.yesNo == 1: yes_debate_count += 1 yes_likes += first_post.likes else: no_debate_count += 1 no_likes += first_post.likes mostDebatedOpinions = sorted(mostDebatedOpinions, key=lambda k: k['commentCount']) mostDebatedOpinions.reverse() # biggest first mostDebatedOpinions = [p for p in mostDebatedOpinions if p['commentCount'] > 0] mostLikedOpinions = sorted(mostLikedOpinions, key=lambda k: k['likes']) mostLikedOpinions.reverse() mostLikedOpinions = [p for p in mostLikedOpinions if p['likes'] > 0] # Debate Totals first_posts = [] # Frequently used words words = dict() connectors = current_app.config['CDWAPI']['connector_words'] for thread in threads: posts_in_thread = cdw.posts.with_fields(thread=thread)[1:] if len(posts_in_thread) == 0: continue first_posts.append(posts_in_thread[0]) for post in posts_in_thread: # Debate totals if post.yesNo == 1: yes_debate_count += 1 else: no_debate_count += 1 # Frequent used words for word in post.text.split(): # strip puncutation #exclude = set(string.punctuation) #word = word.join(ch for ch in word if ch not in exclude) word = re.sub(r'([^\w\s]|_)+(?=\s|$)', '', word) word = re.sub(r'^\W+', '', word).lower() if word in connectors or len(word) < 3: continue if word not in words: words[word] = { 'posts': [post.as_dict()], 'yesCases': 0, 'noCases': 0, 'total': 0 } else: if len(words[word]['posts']) < 20: words[word]['posts'].append(post.as_dict()) words[word]['total'] += 1 if post.yesNo == 1: words[word]['yesCases'] += 1 else: words[word]['noCases'] += 1 """ for thread in threads: first_post = thread.firstPost posts_in_thread = cdw.posts.with_fields(thread=thread) # first from the debate starter for post in posts_in_thread: """ # turn the dictionary into a list of objects so we can sort it wordList = list() for word in words: words[word]['word'] = word wordList.append(words[word]) # for every word, a list of debate threads where it appears sortedWordList = sorted(wordList, key=lambda k: k['total']) sortedWordList.reverse() # biggest first # only the top 20 sortedWordList = sortedWordList[:20] # add a ratio value for item in sortedWordList: ratio = float(item['yesCases']) / float(item['total']) item['ratio'] = ratio #sortedWordList = sorted(sortedWordList, key=lambda k: k['ratio']) sortedWordList = sorted(sortedWordList, key=lambda k: k['ratio']) sortedWordList.reverse() # Trying to sort on multiple keys #sortedWordList = multikeysort(sortedWordList, ['-total','-ratio']) # most liked debates #likedFirstPosts = sorted(first_posts, key=lambda p: p.likes)[:5] #likedFirstPosts.reverse() #liked = list() #for post in likedFirstPosts: # liked.append({'id': str(post.id), 'likes': post.likes}) # gather and return stats['debateTotals'] = {'yes': int(yes_debate_count), 'no': int(no_debate_count)} stats['likeTotals'] = {'yes': int(yes_likes), 'no': int(no_likes)} stats['frequentWords'] = sortedWordList stats['mostLikedOpinions'] = mostLikedOpinions[0:5] # only the top 5 stats['mostDebatedOpinions'] = mostDebatedOpinions[0:5] # only the top 5 return jsonify(stats)
def threads_remove(id): return jsonify(cdw.delete_thread(cdw.threads.with_id(id)))
def threads_posts_get(id): posts = cdw.posts.with_fields(**{"thread": cdw.threads.with_id(id)}) resp = [post.as_dict(full_path=True) for post in posts] return jsonify(resp)
def stats_question(question_id): question = cdw.questions.with_id(question_id) stats = {} stats['question'] = question.as_dict(full_path=True) threads = cdw.threads.with_fields( question=question).order_by('-created') yes_debate_count = 0 no_debate_count = 0 yes_likes = 0 no_likes = 0 # Most Debated mostDebatedOpinions = list() mostLikedOpinions = list() # Debate Totals first_posts = [] # Frequently used words words = dict() connectors = current_app.config['CDWAPI']['connector_words'] for thread in threads: posts_in_thread = cdw.posts.with_fields(thread=thread) commentCount = posts_in_thread.count() first_post = posts_in_thread[0] first_post_dict = first_post.as_dict(full_path=True) if first_post.likes > 0: mostLikedOpinions.append({ 'id': str(thread.id), 'commentCount': commentCount, 'firstPost': first_post_dict, 'likes': first_post.likes }) if commentCount > 1: mostDebatedOpinions.append({ 'id': str(thread.id), 'commentCount': commentCount, 'firstPost': first_post_dict, 'likes': first_post.likes }) if first_post.yesNo == 1: yes_debate_count += 1 yes_likes += first_post.likes else: no_debate_count += 1 no_likes += first_post.likes # Do the debate stats if commentCount > 0: first_posts.append(first_post) else: continue for post in posts_in_thread[1:]: # Debate totals if post.yesNo == 1: yes_debate_count += 1 else: no_debate_count += 1 # Frequent used words for word in post.text.split(): # strip puncutation #exclude = set(string.punctuation) #word = word.join(ch for ch in word if ch not in exclude) word = re.sub(r'([^\w\s]|_)+(?=\s|$)', '', word) word = re.sub(r'^\W+', '', word).lower() if word in connectors or len(word) < 3: continue if word not in words: words[word] = { 'posts': [post.as_dict(full_path=True)], 'yesCases': 0, 'noCases': 0, 'total': 0 } else: if len(words[word]['posts']) < 20: words[word]['posts'].append( post.as_dict(full_path=True)) words[word]['total'] += 1 if post.yesNo == 1: words[word]['yesCases'] += 1 else: words[word]['noCases'] += 1 mostDebatedOpinions = sorted(mostDebatedOpinions, key=lambda k: k['commentCount']) mostDebatedOpinions.reverse() # biggest first mostDebatedOpinions = [ p for p in mostDebatedOpinions if p['commentCount'] > 0 ] mostLikedOpinions = sorted(mostLikedOpinions, key=lambda k: k['likes']) mostLikedOpinions.reverse() mostLikedOpinions = [p for p in mostLikedOpinions if p['likes'] > 0] # turn the dictionary into a list of objects so we can sort it wordList = list() for word in words: words[word]['word'] = word wordList.append(words[word]) # for every word, a list of debate threads where it appears sortedWordList = sorted(wordList, key=lambda k: k['total']) sortedWordList.reverse() # biggest first # only the top 20 sortedWordList = sortedWordList[:20] # add a ratio value for item in sortedWordList: ratio = float(item['yesCases']) / float(item['total']) item['ratio'] = ratio #sortedWordList = sorted(sortedWordList, key=lambda k: k['ratio']) sortedWordList = sorted(sortedWordList, key=lambda k: k['ratio']) sortedWordList.reverse() # Trying to sort on multiple keys #sortedWordList = multikeysort(sortedWordList, ['-total','-ratio']) # most liked debates #likedFirstPosts = sorted(first_posts, key=lambda p: p.likes)[:5] #likedFirstPosts.reverse() #liked = list() #for post in likedFirstPosts: # liked.append({'id': str(post.id), 'likes': post.likes}) # gather and return stats['debateTotals'] = { 'yes': int(yes_debate_count), 'no': int(no_debate_count) } stats['likeTotals'] = {'yes': int(yes_likes), 'no': int(no_likes)} stats['frequentWords'] = sortedWordList stats['mostLikedOpinions'] = mostLikedOpinions[0:5] # only the top 5 stats['mostDebatedOpinions'] = mostDebatedOpinions[0: 5] # only the top 5 return jsonify(stats)
def posts_index_post(): form = PostForm(request.form, csrf_enabled=False) if form.validate(): return jsonify(cdw.posts.save(form.to_post())) else: return jsonify({"errors": form.errors}, 400)
def questions_index_get(): # skip, limit = paginate() skip, limit = pager() return jsonify(cdw.questions.all()[skip:limit])