def question_list(request): """ 自分の質問を表示する """ # 自分の質問を取ってきて時系列に並べる q = Question.objects.filter(questioner=request.user).order_by('date') # 各質問の状態を調べる q_manager = QAManager(request.user) qa_list = q_manager.question_state(q) # 自分の質問を時系列に並べる qa_list = sorted(qa_list, reverse=True, key=lambda x: x[0].date if isinstance(x[0], Question) else x[0].question.date) # プロフィール for qa in qa_list: if isinstance(qa[0], Question): profile = UserProfile.objects.get(user=qa[0].questioner) elif isinstance(qa[0], ReplyList): profile = UserProfile.objects.get(user=qa[0].question.questioner) qa.append(profile) histories = None return render_to_response('question/top_q.html', {'histories': histories, 'qa_list': qa_list, 'last_login': request.user.last_login}, context_instance=RequestContext(request))
def auto_rand_pass(): import django django.setup() tz_tokyo = pytz.timezone('Asia/Tokyo') time = datetime.datetime.now() print(tz_tokyo.localize(time)) reply_list_list = ReplyList.objects.filter(time_limit_date__lt=tz_tokyo.localize(time), has_replied=False).filter(~Q(time_limit_date=None)) #r_list_list = ReplyList.objects.filter(time_limit_date__it=datetime.datetime.now()) from one_month import settings print("---------------") if not reply_list_list: print("@@@@skip@@@@") print("パスすべき質問がありませんでした。スキップします") return 1 for reply_list in reply_list_list: print("###pass###") qa_manager = QAManager() pass_success = qa_manager.pass_question(reply_list.question, qa_manager.reply_list_update_random_except) if pass_success: # 宛先にロボットが含まれるかどうか調べる try: to_robot = QuestionDestination.objects.filter(question=reply_list.question) to_robot = [i for i in to_robot if i.tag.code == 99] except QuestionDestination.DoesNotExist: to_robot = [] # 何回目のパスでロボットが返信してくるか。現在は1に固定 if len(to_robot) and reply_list.question.pass_counter() == 1 and not reply_list.question.has_reply(): text = '' reply_data = ReplyRobot().reply(reply_list.question) if len(reply_data['reply_list']) == 0: text += "難問です。答えられたらすごいです。\n" else: text = "[StackOverFlowより] 以下のページはどうでしょうか?\n\n" + "\n".join(reply_data['reply_list']) + "\n" if len(reply_data['word_list']) != 0: urls = [] for w in reply_data['word_list']: # すべてのユーザの過去の全質問(各質問の回答は含まない)の中から、抽出結果でキーワード検索をかける(最大3件) questions, reply_lists = QAManager.search_keyword_all_user(keyword=str(w), question=True, tag=True, reply=False) for q in questions: if q.id != reply_list.question.id and len(urls) <= 2: urls.append(q.title + "\n" + 'http://' + settings.HOST_NAME + '/dotchain/q_detail/' + str(q.id) + '\n') text += "\n[過去の質問より] 以下のページはどうでしょうか?\n\n" + "\n".join(list(set(urls))) if len( urls) else "\n過去の関連質問はありませんでした。" text += "\n\n抽出結果:" + "、".join(reply_data['word_list']) text += "\n推定ジャンル:" + reply_data['genre'] robot, created = User.objects.get_or_create(username='******', defaults=dict(first_name='太郎', last_name='ロボット', ), ) Reply.objects.create(question=reply_list.question, answerer=robot, text=text) else: reply_list.question.update(is_closed=True)
def question_pass(request, id=None): """ 来た質問をパスする。 次に質問を回す人は、質問者と既にパスした人にはならないようにする。 また、質問者以外のユーザを質問が回り終わったら、質問者にお知らせする。 v1.1新機能:ロボット(AI)による自動返信。 ある回数(現在は1回に固定)だけパスされたら質問から抽出されたキーワードを使って検索URLを返信する。 カテゴリがITの場合はStackOverFlowで検索+過去の関連質問を返信する。 その他の場合は過去の関連質問を返信する。 """ reply_list = ReplyList.objects.get(id=id) if reply_list.has_replied: return top_default(request, msg=m.INFO_QUESTION_ALREADY_AUTO_PASS) qa_manager = QAManager() pass_success = qa_manager.pass_question(reply_list.question, qa_manager.reply_list_update_random_except) if pass_success: # 宛先にロボットが含まれるかどうか調べる try: to_robot = QuestionDestination.objects.filter(question=reply_list.question) to_robot = [i for i in to_robot if i.tag.code == 99] except QuestionDestination.DoesNotExist: to_robot = [] # 何回目のパスでロボットが返信してくるか。現在は1に固定 if len(to_robot) and reply_list.question.pass_counter() == 1 and not reply_list.question.has_reply(): text = '' reply_data = ReplyRobot().reply(reply_list.question) if len(reply_data['reply_list']) == 0: text += "難問です。答えられたらすごいです。\n" else: text = "[StackOverFlowより] 以下のページはどうでしょうか?\n\n" + "\n".join(reply_data['reply_list']) + "\n" if len(reply_data['word_list']) != 0: urls = [] for w in reply_data['word_list']: # すべてのユーザの過去の全質問(各質問の回答は含まない)の中から、抽出結果でキーワード検索をかける(最大3件) questions, reply_lists = QAManager.search_keyword_all_user(keyword=str(w), question=True, tag=True, reply=False) for q in questions: if q.id != reply_list.question.id and len(urls) <= 2: urls.append(q.title + "\n" + 'http://' + settings.HOST_NAME + '/dotchain/q_detail/' + str(q.id) + '\n') text += "\n[過去の質問より] 以下のページはどうでしょうか?\n\n" + "\n".join(list(set(urls))) if len( urls) else "\n過去の関連質問はありませんでした。" text += "\n\n抽出結果:" + "、".join(reply_data['word_list']) text += "\n推定ジャンル:" + reply_data['genre'] robot, created = User.objects.get_or_create(username='******', defaults=dict(first_name='太郎', last_name='ロボット', ), ) Reply.objects.create(question=reply_list.question, answerer=robot, text=text) return top_default(request, msg=m.INFO_QUESTION_PASS) else: reply_list.question.update(is_closed=True) return top_default(request, msg='{0}\n{1}'.format(m.INFO_QUESTION_PASS, m.INFO_PASS_FINISH))
def question_list(request): """ 自分の質問を表示する """ # 自分の質問を取ってきて時系列に並べる q = Question.objects.filter(questioner=request.user).order_by('-date') # 各質問の状態を調べる qa_manager = QAManager(request.user) qa_list = qa_manager.question_state(q) return render_to_response('question/top_q.html', {'qa_list': qa_list, 'last_login': request.user.last_login}, context_instance=RequestContext(request))
def reply_list(request): """ 自分に来た質問一覧を表示する """ r = Reply() """ # ランダムに質問取ってくる #下書きにチェックがはいっていないもののみ最新のものから順に表示 question_tmp = Question.objects.filter(~Q(questioner=request.user))#.order_by('-date')[:] question = list(filter(lambda x: x.draft==False, question_tmp)) question = random.choice(question) #ランダムに質問を取ってくる """ # 06/09 返信リストの中から自分あて、かつ返信済みでない質問を取ってくる # 返信期限がまだ来てないもの、かつ返信期限が早いものから順に表示 # replylist = ReplyList.objects.filter(answerer=request.user, has_replied=False,time_limit_date__gte=datetime.datetime.now(pytz.utc)).order_by('time_limit_date')[:] # questions = [r.question for r in replylist] # return render_to_response('question/reply_list.html', # {'questions':questions,}, # context_instance=RequestContext(request)) # 自分宛の質問のうち、自分の回答待ちになっている質問を取ってくる reply_list = ReplyList.objects.filter(answerer=request.user, has_replied=False) # 自分宛の質問を時系列に並べる reply_list = sorted(reply_list, reverse=True, key=lambda x: x.question.date) # 各質問の状態を調べる q_manager = QAManager(request.user) qa_list = q_manager.reply_state(reply_list=reply_list) # プロフィール for qa in qa_list: if isinstance(qa[0], Question): profile = UserProfile.objects.get(user=qa[0].questioner) elif isinstance(qa[0], ReplyList): profile = UserProfile.objects.get(user=qa[0].question.questioner) qa.append(profile) histories = None return render_to_response('question/top_r.html', {'histories': histories, 'qa_list': qa_list, 'last_login': request.user.last_login}, context_instance=RequestContext(request))
def reply_list(request): """ 自分に来た質問一覧を表示する """ # 自分宛の質問のうち、自分の回答待ちになっている質問を取ってきて時系列に並べる reply_list = ReplyList.objects.filter(answerer=request.user, has_replied=False) reply_list = QAManager.sort_qa(qa_list=reply_list, reverse=True) if reply_list is not None: q_manager = QAManager(request.user) qa_list = q_manager.reply_state(reply_list=reply_list) else: qa_list = None return render_to_response('question/top_r.html', {'qa_list': qa_list, 'last_login': request.user.last_login}, context_instance=RequestContext(request))
def auto_rand_pass(): import django django.setup() tz_tokyo = pytz.timezone('Asia/Tokyo') time = datetime.datetime.now() print(tz_tokyo.localize(time)) reply_list_list = ReplyList.objects.filter(time_limit_date__lt=tz_tokyo.localize(time), has_replied=False).filter(~Q(time_limit_date=None)) #r_list_list = ReplyList.objects.filter(time_limit_date__it=datetime.datetime.now()) print("---------------") if not reply_list_list: print("@@@@skip@@@@") print("パスすべき質問がありませんでした。スキップします") return 1 for reply_list in reply_list_list: print("###pass###") qa_manager = QAManager() qa_manager.pass_question(reply_list.question, qa_manager.reply_list_update_random_except)
def top_default(request, msg=None): """ トップページ """ # 自分の質問 questions = Question.objects.filter(questioner=request.user) # 自分宛の質問リスト reply_lists = ReplyList.objects.filter(answerer=request.user) if request.method == 'POST': form = KeywordSearchForm(request.POST) """ 以下の質問をキーワード検索で取ってくる * 自分がした質問のタイトル・内容・タグいずれかがキーワードと部分一致 * 相手から自分へ来た質問のタイトル・内容・タグいずれかがキーワードと部分一致 * 自分の回答内容がキーワードと部分一致 * 自分の投稿に対する相手の回答内容がキーワードと部分一致 """ if form.is_valid(): keyword = form.clean()['keyword'] questions, reply_lists = QAManager.search_keyword(user=request.user, keyword=keyword, question=True, reply=True, tag=True) result = len(questions) + len(reply_lists) msg = '「'+keyword+'」の検索結果: '+str(result)+'件' # 自分の質問と自分宛ての質問の状態を調べる qa_manager = QAManager(request.user) questions = qa_manager.question_state(questions) reply_lists = qa_manager.reply_state(reply_lists) # 自分と自分宛の質問を結合して時系列に並べる qa_list = list() qa_list.extend(questions) qa_list.extend(reply_lists) qa_list = QAManager.sort_qa(qa_list=qa_list, reverse=True) return render_to_response('question/top_all.html', {'qa_list': qa_list, 'last_login': request.user.last_login, 'msg': msg}, context_instance=RequestContext(request))
def question_pass(request, id=None): """ 来た質問をパスする。 次に質問を回す人は、質問者と既にパスした人にはならないようにする。 また、質問者以外のユーザを質問が回り終わったら、質問者にお知らせする。 """ reply_list = ReplyList.objects.get(id=id) if reply_list.has_replied: msg = 'すでにパスした質問です。' return top_default(request, msg) qa_manager = QAManager() if qa_manager.pass_question(reply_list.question, qa_manager.reply_list_update_random_except): msg = '質問をパスしました。' # 何回目のパスでロボットが返信してくるか if reply_list.question.pass_counter() == 1 and not reply_list.question.has_reply(): reply = Reply() reply.question = reply_list.question reply_data = ReplyRobot().reply(reply_list.question) if len(reply_data['reply_list']) == 0: reply.text = "難問です。答えられたらすごいです。" else: reply.text = "以下のページはどうでしょうか?\n\n" + "\n".join(reply_data['reply_list']) if len(reply_data['word_list']) != 0: reply.text += "\n\n抽出結果:" + "、".join(reply_data['word_list']) reply.text += "\n推定ジャンル:" + reply_data['genre'] # ロボットのidを指定 reply.answerer = User.objects.get(id=1) reply.save() return top_default(request, msg) else: reply_list.question.is_closed = True reply_list.question.save() msg = '質問をパスしました。\n' msg += '次の送信先がないため質問は締め切られます。' return top_default(request, msg)
def question_edit(request, id=None, msg=None): """ 質問ページ """ # edit # 質問の編集機能は今は下書きの場合のみ使う if id: q = get_object_or_404(Question, pk=id) # user check if q.questioner != request.user: return top_default(request, msg=m.INFO_INVALID_ACCESS) # new else: q = Question() # edit if request.method == 'POST': form = QuestionEditForm(request.POST, instance=q) if form.is_valid(): # 質問を保存 q = form.save(commit=False) q.update(questioner=request.user, draft=form.cleaned_data['draft']) if q.draft: return top_default(request, msg=m.INFO_QUESTION_SAVE_OK) # 質問の宛先(複数)を生成 div_list = form.cleaned_data['destination'] for div in div_list: QuestionDestination.objects.create(question=q, tag=div) # ランダムに質問者を選んでReplyListを生成 qa_manager = QAManager() r_list = qa_manager.make_reply_list(q, qa_manager.reply_list_update_random_except) if r_list is None: q.delete() msg = m.INFO_NO_DESTINATION return render_to_response('question/question_edit.html', {'form': form, 'id': id, 'msg': msg}, context_instance=RequestContext(request)) else: r_list.save() # 選択されたタグから、新規にQuestionTagを生成 q_tags = form.cleaned_data['tag'] for q_tag in q_tags: QuestionTag.objects.create(tag=q_tag, question=q) # 追加されたタグ名が新規に追加されたタグだったら生成 tag_name = Tag.get_all_tags_name() tag_added_name = form.cleaned_data['tag_added'] if tag_added_name != "" and tag_added_name not in tag_name: QuestionTag.objects.create(tag=Tag.objects.create(name=tag_added_name), question=q) return top_default(request, msg=m.INFO_QUESTION_SEND_OK) pass # new else: form = QuestionEditForm(instance=q, initial={'time_limit': datetime.timedelta(minutes=1)}) return render_to_response('question/question_edit.html', {'form': form, 'id': id}, context_instance=RequestContext(request))
def top_default(request, msg=None): """ トップページ """ # added # form = None # if request.method == 'GET': form = KeywordSearchForm() # 自分の質問を取ってくる questions = Question.objects.filter(questioner=request.user) # 自分宛の質問リストを取ってくる reply_lists = ReplyList.objects.filter(answerer=request.user) if request.method == 'POST': form = KeywordSearchForm(request.POST) """ 以下の質問をキーワード検索で取ってくる * 自分がした質問のタイトル・内容・タグいずれかがキーワードと部分一致 * 相手から自分へ来た質問のタイトル・内容・タグいずれかがキーワードと部分一致 * 自分の回答内容がキーワードと部分一致 * 自分の投稿に対する相手の回答内容がキーワードと部分一致 """ # 自分宛の質問リストを取ってくる(パス含む) reply_lists = ReplyList.objects.filter(answerer=request.user) if form.is_valid(): # すべての質問の中からキーワードに合致する質問のみ取り出す questions = list(Question.objects.filter(Q(title__contains=form.clean()['keyword']) | Q(text__contains=form.clean()['keyword']))) # 回答内容にキーワードが含まれるもののうち自分が答えた質問のみ取り出す replies = list(Reply.objects.filter(Q(text__contains=form.clean()['keyword']))) # キーワードに合致するすべての質問のうち、自分が投稿した質問と、自分に来た質問を取り出す q_list_tmp = [] r_list_tmp = [] for ql in questions: if ql.questioner == request.user: q_list_tmp.append(ql) rl = [rl for rl in reply_lists if ql.id == rl.question.id] r_list_tmp.extend(rl) # 自分の返信内容とキーワードが合致するものを取り出す for r in replies: if r.answerer == request.user: rl = [rl for rl in reply_lists if r.question.id == rl.question.id] r_list_tmp.extend(rl) elif r.question.questioner == request.user: reply_lists = ReplyList.objects.filter(question=r.question) rl = [rl for rl in reply_lists if r.question.id == rl.question.id] r_list_tmp.extend(rl) reply_lists = r_list_tmp # キーワードに合致するすべてのタグを取り出す tags = list(Tag.objects.filter(Q(name__contains=form.clean()['keyword']))) # キーワードが含まれるタグ(複数) # 自分が投稿した質問のタグと一致するもののみ取り出す for tag in tags: q_tags = QuestionTag.objects.filter(tag=tag) # タグ名が合致する質問タグ q = [q_tag.question for q_tag in q_tags if q_tag.question.questioner == request.user] q_list_tmp.extend(q) q_list_tmp = list(set(q_list_tmp)) questions = q_list_tmp # 自分が答えた質問のタグと一致するもののみ取り出す replies = list(Reply.objects.filter(answerer=request.user)) for r in replies: for tag in tags: q_tags = QuestionTag.objects.filter(tag=tag) # タグ名が合致する質問タグ q = [q_tag.question for q_tag in q_tags if r.question.id == q_tag.question.id and r.answerer == request.user] q_list_tmp.extend(q) q_list_tmp = list(set(q_list_tmp)) a = [] b = [] r_list_tmp = ReplyList.objects.filter(answerer=request.user) for tag in tags: q_tags = QuestionTag.objects.filter(tag=tag) # タグ名が合致する質問タグ for rl in r_list_tmp: # 自分に来た質問 for q_tag in q_tags: if rl.question.id == q_tag.question.id: a.append(rl) b = list(set(a)) reply_lists.extend(b) reply_lists = list(set(reply_lists)) # 自分の質問と自分宛ての質問の状態を調べる qa_manager = QAManager(request.user) questions = qa_manager.question_state(questions) reply_lists = qa_manager.reply_state(reply_lists) # 自分と自分宛の質問を結合して時系列に並べる qa_list = list() qa_list.extend(questions) qa_list.extend(reply_lists) qa_list = sorted(qa_list, reverse=True, key=lambda x: x[0].date if isinstance(x[0], Question) else x[0].question.date) # プロフィール for qa in qa_list: if isinstance(qa[0], Question): profile = UserProfile.objects.get(user=qa[0].questioner) elif isinstance(qa[0], ReplyList): profile = UserProfile.objects.get(user=qa[0].question.questioner) qa.append(profile) histories = None return render_to_response('question/top_all.html', {'histories': histories, 'qa_list': qa_list, 'last_login': request.user.last_login, 'msg': msg}, context_instance=RequestContext(request))
def question_edit(request, id=None, msg=None): """ 質問ページ """ # edit if id: q = get_object_or_404(Question, pk=id) # user check if q.questioner != request.user: print("不正なアクセスです!") return redirect('dotchain:top') # new else: q = Question() # edit if request.method == 'POST': form = QuestionEditForm(request.POST, instance=q) # 完了がおされたら if form.is_valid(): # 質問を保存 q = form.save(commit=False) q.questioner = request.user q.draft = form.cleaned_data['draft'] q.save() div_list = form.cleaned_data['destination'] for div in div_list: d = QuestionDestination() d.question = q d.tag = div d.save() # ランダムに質問者を選んでからReplyListを生成して保存 qa_manager = QAManager() r_list = qa_manager.make_reply_list(q, qa_manager.reply_list_update_random_except) if r_list is None: q.delete() msg = '宛先ユーザが見つかりませんでした。入力された質問は消去されます。\n' msg += '次の原因が考えられます。\n' msg += '・送信先にユーザがいない\n' msg += '・送信先に1日以内にログインしたユーザがいない\n' msg += '・送信先に受信拒否のユーザしかいない' return render_to_response('question/question_edit.html', {'form': form, 'id': id, 'msg': msg}, context_instance=RequestContext(request)) else: r_list.save() # 選択されたタグから、新規にQuestionTagを生成して保存 q_tags = form.cleaned_data['tag'] for q_tag in q_tags: qt = QuestionTag() qt.tag = q_tag qt.question = q qt.save() # 追加されたタグ名から、新規にTagとQuestionTagを生成して保存 tag_added_name = form.cleaned_data['tag_added'] tags = Tag.objects.all() tag_name = [t.name for t in tags] if tag_added_name != "" and tag_added_name not in tag_name: # 新規に追加されたタグだったら保存 t = Tag() t.name = tag_added_name t.save() qt = QuestionTag() qt.tag = t qt.question = q qt.save() return redirect('dotchain:top') pass # new else: form = QuestionEditForm(instance=q, initial={'time_limit': datetime.timedelta(minutes=1)}) return render_to_response('question/question_edit.html', {'form': form, 'id': id}, context_instance=RequestContext(request))