Пример #1
0
    def get_next_task_view(self):
        self.client.login(username="******", password="******")
        ## get the next task
        self.task_expectation.check(self)
        ## tweak the database to put a response and a review in
        response = Response(task=self.t, user=self.user, start_time=datetime.datetime.now())
        response.full_clean()
        response.save()
        review = Review(response=response, comment="I have reviewed this task.")
        review.full_clean()
        review.save()
        ## check to see if next_task now redirects to review
        ## if we actually execute the view code, we will get an error,
        ## because the task associated with the review has no result;
        ## therefore the code below is a bit hackish
        review_target = WebTarget("GET", main.views.base.next_task, statuses=(301, 302))

        def redirects_to_review(input_context, output_context):
            return "/review/next/" in output_context["__redirected_to__"]

        review_expectation = ViewExpectation(Conditions.post(redirects_to_review), review_target)
        review_expectation.check(self)
        ## tweak the database to complete the review
        review.complete = True
        review.full_clean()
        review.save()
        ## try getting the next task again
        self.task_expectation.check(self)
Пример #2
0
def respondchannel(request, pk1, pk2, num):
    context = {}
    if request.user.is_authenticated():
        print 'response'
        print request.GET.get('response')
        new_response = Response()
        print num
        if int(num) == 1:
            new_response.is_resp_to_reply = False
        else:
            new_response.is_resp_to_reply = True
        print 'New resp' + str(new_response.is_resp_to_reply)
        new_response.text = request.GET.get('response')
        new_response.channel = Channel.objects.get(pk=pk1)
        new_response.original_comment = Comment.objects.get(pk=pk2)
        new_response.user = request.user
        new_response.save()
        return HttpResponseRedirect('/channel_detail/%s' % pk1)

    else:
        print 'anonymous user'
        return HttpResponseRedirect('/please_login/')
    return render_to_response('channel_detail.html',
                              context,
                              context_instance=RequestContext(request))
def crowd_respond_to_study(request, study_id):
    # There are two ways the client makes ajax calls. Once at the beginning just to get the first segment,
    # and also after a response is made to record the response AND get a new segment
    if request.is_ajax():

        # This is true if the ajax is returning a response
        if not request.POST.get('segment_ajax') is None:
            seg = Segment.objects.get(id=request.POST.get('segment_id'))
            new_response = Response(segment=seg,
                                    user=request.user,
                                    label_id=request.POST.get('label_id'))
            new_response.save()
            check_segment(seg)
        prev_responses = list(
            Response.objects.filter(
                worker_id=request.user.id).values('segment_id'))
        high_priorities = Segment.objects.filter(
            study_id=study_id,
            status='high_priority').exclude(id__in=prev_responses)

        if high_priorities.exists():
            available_segments = high_priorities
        else:
            available_segments = Segment.objects.filter(study_id=study_id,
                                                        status='low_priority')

        chosen_segment = available_segments[random.randint(
            0,
            len(available_segments) - 1)]
        data = {
            'seg_id': chosen_segment.id,
            'file_name': chosen_segment.file.filename,
            'start': float(chosen_segment.start),
            'stop': float(chosen_segment.stop),
            'duration': float(chosen_segment.duration),
        }
        return render_to_json_response(data)
    study_worker = StudyWorker.objects.filter(study_id=study_id,
                                              worker_id=request.user.id)
    if study_worker is None:
        return redirect('/')
    template = loader.get_template('main/respond_to_study.html')
    labels = Label.objects.filter(study_id=study_id)
    context = {
        'study': Study.objects.get(id=study_id),
        'labels': labels,
        'remaining': 17
    }
    return HttpResponse(template.render(context, request))
Пример #4
0
def message(request):

    if request.method == 'POST':
        request_data = ((request.body).decode('utf-8'))
        request_data = json.loads(request_data)
        userMessage = request_data['content']
        user_key = request_data['user_key']

    user = User.getOrCreate(user_key)

    start = datetime.datetime.now()
    botMessageDict = Response.getResponseDict(user, userMessage)
    timeDiff = datetime.datetime.now() - start

    numOfMails = Mail.getNumOfMails(user)
    if numOfMails:
        botMessageDict['message']['text'] = '[\'메시지\'라고 입력해주세요!(' + str(
            numOfMails) + '개)]\n\n' + botMessageDict['message']['text']

    Log.write(user, userMessage, botMessageDict['message']['text'],
              timeDiff.total_seconds())

    botMessageDumped = json.dumps(botMessageDict)

    return HttpResponse(botMessageDumped)
Пример #5
0
    def get_next_task_view(self):
        self.client.login(username="******", password="******")
        ## get the next task
        self.task_expectation.check(self)
        ## tweak the database to put a response and a review in
        response = Response(task=self.t,
                            user=self.user,
                            start_time=timezone.now())
        response.full_clean()
        response.save()
        review = Review(response=response,
                        comment="I have reviewed this task.")
        review.full_clean()
        review.save()
        ## check to see if next_task now redirects to review
        ## if we actually execute the view code, we will get an error,
        ## because the task associated with the review has no result;
        ## therefore the code below is a bit hackish
        review_target = WebTarget("GET",
                                  main.views.base.next_task,
                                  statuses=(301, 302))

        def redirects_to_review(input_context, output_context):
            return "/review/next/" in output_context["__redirected_to__"]

        review_expectation = ViewExpectation(
            Conditions.post(redirects_to_review), review_target)
        review_expectation.check(self)
        ## tweak the database to complete the review
        review.complete = True
        review.full_clean()
        review.save()
        ## try getting the next task again
        self.task_expectation.check(self)
Пример #6
0
def user_rating():
    """
    打分
    /api/user-rating
    """

    try:
        token = request.headers.get('Authorization', '')

        # by convention jwt token is like "Bearer <token string>"
        uname = verify_auth_token(token[7:])
        if not uname:
            raise ValueError('Invalid Token')

        user = DB['users'].find_one({'username': uname})
        user_rates = user.get('rates', [])
        user_eval = user.get('evaluation', [])

        if not user_rates:
            user_rates = []
        if not user_eval:
            user_eval = []
        response = Response(ResponseType.SUCCESS)
        response.update_attr(
            'rates', {str(rate['cid']): rate['rate']
                      for rate in user_rates})
        response.update_attr(
            'evaluation',
            {str(rate['cid']): rate['rate']
             for rate in user_eval})

    except ValueError as ve:
        response = Response.get_custom_response(ResponseType.FAILURE, str(ve))
    except Exception as e:
        print(e)
        response = Response(ResponseType.INTERNAL_ERR)

    return response.get_json()
Пример #7
0
def respondchannel(request, pk1, pk2, num):
    context = {}
    if request.user.is_authenticated():
        print 'response'
        print request.GET.get('response')
        new_response = Response() 
        print num
        if int(num) == 1:
            new_response.is_resp_to_reply = False
        else:
            new_response.is_resp_to_reply = True
        print  'New resp' + str(new_response.is_resp_to_reply)
        new_response.text = request.GET.get('response')
        new_response.channel = Channel.objects.get(pk=pk1)
        new_response.original_comment = Comment.objects.get(pk=pk2)
        new_response.user = request.user
        new_response.save()
        return HttpResponseRedirect('/channel_detail/%s' %pk1) 
   
    else:  
        print 'anonymous user'
        return HttpResponseRedirect('/please_login/')
    return render_to_response('channel_detail.html', context, context_instance=RequestContext(request))
Пример #8
0
def get_graph():
    """
    get explicit params from url
    接受url的Param作为root nodeId, 然后返回一张dag
    dag似乎可以提前就计算好? 因为要有children node的相关度排序
    计算好之后就直接提出来用? 在app载入的时候就加到内存里面去
    考虑可拓展性? 如果图特别大呢, 那显然和设计的架构不一致, 
    因为构想是前端处理整个graph的裁剪, 后端提供整张图
    如果图很大, 那么后端必须裁剪好前端直接用, 不能指望前端那点计算能力
    因为不止一个点, <del>但是现在没做多关键词查询</del>, 如果做了那么就是一个列表
    <del>params里面传入的应该是一个serialized json string, 然后解析为json然后得到数组</del>
    使用;分隔, 就像search那样
    """

    # 然而现在需要考虑同时查询两个
    wids = request.args.get('wids', '').lower()

    print('graph params', wids)

    # params = GraphParams(request.args)
    if not wids:
        response = Response(ResponseType.PARAMETERS_ERR)
        return response.get_json()

    try:
        # 由于概念格的特点, 子节点关键词集合一定包含父节点的关键词集合, 文档集合反之
        # 找到含有extent的所有点, 然后把data里面无关的连线删掉, 找到fah==[]就是新root
        wids = convert_int(wids.split(';'))
        g = sub_graph(NODES, wids)
        # add data in g
        g = add_info(g, KEYWORDS_DICT)
        if len(g) == 1:
            # response = Response.get_custom_response(ResponseType.FAILURE, 'No Such sub graph')
            response = Response(ResponseType.SUCCESS)
            response.update_attr('graph', g)
        else:
            response = Response(ResponseType.SUCCESS)
            response.update_attr('graph', g)
    except Exception as e:
        print(e)
        response = Response(ResponseType.INTERNAL_ERR)
    return response.get_json()
Пример #9
0
def parsePrompt(chunk):
    global tab, vars, storyName, promptIdCounter

    #print(chunk)
    #find the offset, and then change the chunk to a standard form
    offset = 0
    for c in chunk[0]:
        if c == tab:
            offset += 1
        else:
            break

    #standardize
    for i in range(len(chunk)):
        chunk[i] = chunk[i][offset:]

    #print(chunk)

    prompt = Prompt(promptText=chunk[0],
                    storyId=storyName,
                    option1="",
                    promptId=promptIdCounter)
    promptIdCounter += 1
    prompt.save()

    #starting with first line of first option, iterate through the lines
    for j in range(1, len(chunk)):
        line = chunk[j]
        #print(line)

        # check if the line is set off by a tab
        # if not, then we found an option
        if line[0] != tab and prompt.option1 == "":
            #set the option1 for the prompt to this line
            prompt.option1 = line
            #then create the response object
            option1 = Response(storyId=storyName,
                               option1or2="1",
                               previousPrompt=prompt,
                               ifStatement="")
            print("response created for option1", option1)
            option1.save()
            optionsToPassUp1 = [option1]
            #now we start from what comes under the option
            #these sublines will be offset by 1 tab
            k = j + 1
            for notk in range(j + 1, len(chunk)):
                subline = chunk[k]
                #print("subline1",[subline.split()])
                #if there is no tab, then we have reached the end
                if subline[0] != tab:
                    #print('move on')
                    break
                #this means that we have found the nextPrompt
                elif subline[1] == tab:
                    #print('go deeper')
                    countForNextPrompt = 0
                    for l in range(k, len(chunk) + 1):
                        #print(chunk[l])
                        # the nextPrompt will be in atleast 2 deep, anything shallower is not a part of it
                        if l == len(chunk) or chunk[l][1] != tab:
                            #print(k,l)
                            option1.nextPrompt, subOptionsToPassUp1 = parsePrompt(
                                chunk[k:l])
                            print("retrieved response from deeper option1")
                            optionsToPassUp1.pop(-1)
                            optionsToPassUp1.extend(subOptionsToPassUp1)
                            #print(optionsToPassUp1)
                            #print("returned up")
                            k = l - 1
                            #print("option1: ",option1)
                            option1.save()
                            break
                #if statement
                elif subline[1:3] == "if" and subline[-1] == ":":
                    if option1.ifStatement == "":
                        option1.ifStatement = subline[1:]
                    else:
                        option1.save()
                        option1 = Response(storyId=storyName,
                                           option1or2="1",
                                           previousPrompt=prompt)
                        print("created an if response for options 1", option1)
                        option1.ifStatement = subline[1:]
                        option1.save()
                        optionsToPassUp1.append(option1)
                #set variable statement
                elif len(subline[1:].split()) > 2 and subline[1:].split(
                )[1] == ":=" and subline.split()[0][1:] in vars:
                    option1.setVariable = subline[1:]
                #otherwise, it's (hopefully) the response text, if any
                else:
                    #print("response text: ",subline)
                    option1.responseText = subline[1:]
                k += 1
                if k >= len(chunk): break
            option1.save()

        #for option 2
        elif line[0] != tab and prompt.option1 != "":
            #set the option2 for the prompt to this line
            prompt.option2 = line
            #then create the response object
            option2 = Response(storyId=storyName,
                               option1or2="2",
                               previousPrompt=prompt,
                               ifStatement="")
            print("response created for option2", option2)
            option2.save()
            optionsToPassUp2 = [option2]
            #now we start from what comes under the option
            #these sublines will be offset by 1 tab
            k = j + 1
            for notk in range(j + 1, len(chunk)):
                subline = chunk[k]
                #print("subline2",[subline.split()])
                #if there is no tab, then we have reached the end
                if subline[0] != tab:
                    #print('move on')
                    break
                #this means that we have found the nextPrompt
                elif subline[1] == tab:
                    print('go deeper')
                    print(chunk)
                    countForNextPrompt = 0
                    for l in range(k, len(chunk) + 1):
                        #print(chunk[l])
                        # the nextPrompt will be in atleast 2 deep, anything shallower is not a part of it
                        if l == len(chunk) or chunk[l][1] != tab:
                            #print(k,l)
                            option2.nextPrompt, subOptionsToPassUp2 = parsePrompt(
                                chunk[k:l])
                            print("retrieved response from deeper option2")
                            optionsToPassUp2.pop(-1)
                            optionsToPassUp2.extend(subOptionsToPassUp2)
                            #print(optionsToPassUp2)
                            print("returned up")
                            k = l - 1
                            #print("option1: ",option1)
                            option2.save()
                            break
                #if statement
                elif subline[1:3] == "if" and subline[-1] == ":":
                    if option2.ifStatement == "":
                        option2.ifStatement = subline[1:]
                    else:
                        option2.save()
                        option2 = Response(storyId=storyName,
                                           option1or2="2",
                                           previousPrompt=prompt)
                        print("created an if response for options 2", option2)
                        option2.ifStatement = subline[1:]
                        option2.save()
                        optionsToPassUp2.append(option2)
                #set variable statement
                elif len(subline[1:].split()) > 2 and subline[1:].split(
                )[1] == ":=" and subline.split()[0][1:] in vars:
                    option2.setVariable = subline[1:]
                #otherwise, it's (hopefully) the response text, if any
                else:
                    #print("response text: ",subline)
                    option2.responseText = subline[1:]
                k += 1
                if k >= len(chunk): break
            option2.save()

    prompt.save()
    optionsToPassUp2.extend(optionsToPassUp1)
    return prompt, optionsToPassUp2
Пример #10
0
def get_courses_list():
    # 返回图和返回文章的接口分离
    # 因为文章还要翻页 查询文章直接在mongodb中查询
    # 因为不需要做查询相关度排序, 提供排序为, 年份, 默认(字典序), 被引量

    try:
        course_params = CourseListParams(request.args)
        # validate params passed in
        if not course_params.validate():
            raise ValidationError
        # return courses
        node_id = course_params.node_id.data
        page = course_params.page.data
        page_size = course_params.page_size.data
        # order = course_params.order.data

        node = DB['nodes'].find_one({'nid': node_id})
        if not node:
            raise ValueError('no such node id exists')
        extents = node['extent']
        courses = DB['courses'].find({'cid': {"$in": extents}}) \
                                .limit(page_size) \
                                .skip((page-1)*page_size)
        # if order == 'time':
        #     courses = DB['courses'].find({'cid': {"$in": extents}}) \
        #                         .sort([('date',-1)]).limit(page_size) \
        #                         .skip((page-1)*page_size)
        # elif order == 'citation':
        #     courses = DB['courses'].find({'cid': {"$in": extents}}) \
        #                         .sort([('citation',-1)]).limit(page_size) \
        #                         .skip((page-1)*page_size)
        courses = [after_pop(d, '_id') for d in courses]
        response = Response(ResponseType.SUCCESS)
        response.update_attr('courses', courses)
        response.update_attr('page', page)
        response.update_attr('pageSize', page_size)
        response.update_attr('totalSize', len(extents))
    except ValidationError as ve:
        print(ve)
        response = Response(ResponseType.PARAMETERS_ERR)
    except ValueError as ve:
        response = Response.get_custom_response(ResponseType.FAILURE, str(ve))
    except Exception as e:
        print(e)
        response = Response(ResponseType.INTERNAL_ERR)

    return response.get_json()
Пример #11
0
def rating():
    """
    打分
    /api/rating?course_id=<int>&rate=<int>&is_evaluation=<bool>
    """

    try:
        rate_params = RatingParams(request.args)
        if not rate_params.validate():
            raise ValidationError
        rate = rate_params.rate.data
        course_id = rate_params.course_id.data
        is_evalution = rate_params.is_evaluation.data
        token = request.headers.get('Authorization', '')

        # by convention jwt token is like "Bearer <token string>"
        uname = verify_auth_token(token[7:])
        if not uname:
            raise ValueError('Invalid Token')

        if is_evalution:
            # check whether this rate exists
            if not DB['users'].find_one({
                    'username': uname,
                    'evaluation.cid': course_id
            }):
                DB['users'].update({'username': uname}, {
                    '$push': {
                        'evaluation': {
                            'cid': course_id,
                            'rate': rate
                        }
                    }
                })
            else:
                DB['users'].update(
                    {
                        'username': uname,
                        'evaluation.cid': course_id
                    }, {'$set': {
                        'evaluation.$.rate': rate
                    }})
        else:
            # check whether this rate exists
            if not DB['users'].find_one({
                    'username': uname,
                    'rates.cid': course_id
            }):
                DB['users'].update(
                    {'username': uname},
                    {'$push': {
                        'rates': {
                            'cid': course_id,
                            'rate': rate
                        }
                    }})
            else:
                DB['users'].update({
                    'username': uname,
                    'rates.cid': course_id
                }, {'$set': {
                    'rates.$.rate': rate
                }})

        response = Response(ResponseType.SUCCESS)

    except ValidationError:
        response = Response(ResponseType.VALIDATION_ERR)
    except ValueError as ve:
        response = Response.get_custom_response(ResponseType.FAILURE, str(ve))
    except Exception as e:
        print(e)
        response = Response(ResponseType.INTERNAL_ERR)

    return response.get_json()
Пример #12
0
def recommend_courses():
    """
    recommend courses
    /api/recommend?page=<int>&page_size=<int>
    """

    try:
        recommend_params = RecommendCoursesParams(request.args)
        if not recommend_params.validate():
            raise ValidationError

        page = recommend_params.page.data
        page_size = recommend_params.page_size.data
        mode = recommend_params.mode.data
        token = request.headers.get('Authorization', '')

        # auth validation
        uname = verify_auth_token(token[7:])
        if not uname:
            raise ValueError('Invalid Token')

        # find user
        user = DB['users'].find_one({'username': uname})
        if not user:
            raise ValueError('User Not Found')

        # create user model
        user_rates = user.get('rates', None)
        if not user_rates:
            return Response.get_custom_response(
                ResponseType.FAILURE, "unable to recommend").get_json()

        course_vectors = COURSE_VECTORS_DICT[str(mode)]
        user_model = recommend(user_rates, course_vectors)

        # store user model
        DB['users'].update({'username': uname},
                           {'$set': {
                               'usermodel': user_model
                           }})

        user_courses = [x['cid'] for x in user_model]

        # change the order the full rating items
        user_rates_dict = {x['cid']: x['rate'] for x in user_rates}
        rate5 = [c for c in user_courses if user_rates_dict.get(c, 0) == 5]
        rate4 = [c for c in user_courses if user_rates_dict.get(c, 0) == 4]
        other_rates = [
            c for c in user_courses if user_rates_dict.get(c, 0) < 4
        ]
        user_courses = rate5 + rate4 + other_rates

        courses = [
            after_pop(DB['courses'].find_one({'cid': a}), '_id')
            for a in user_courses[(page - 1) * page_size:page * page_size]
        ]

        response = Response(ResponseType.SUCCESS)
        response.update_attr('courses', courses)
        response.update_attr('page', page)
        response.update_attr('pageSize', page_size)
        response.update_attr('totalSize', len(user_courses))

    except ValidationError:
        response = Response(ResponseType.VALIDATION_ERR)
    except ValueError as ve:
        response = Response.get_custom_response(ResponseType.FAILURE, str(ve))
    except Exception as e:
        print('unknown err', e)
        response = Response(ResponseType.INTERNAL_ERR)
    return response.get_json()
Пример #13
0
def search():
    '''
    得到一个或者关键词之后, 如果这个或者这些关键词命中了
    返回命中和未命中的关键词, 以及命中的关键词分别的kId
    目前只做一个关键词的好了
    来了一个新词之后, 在所有关键词里面匹配, 精准命中就是直接返回
    如果不中, 那么就计算相似度, 然后返回相似度top5的关键词

    相似度计算可以使用编辑距离自动机或者是BK树, 不想写, 好麻烦
    如果之后要做到实时推荐, 输入一个词出一个词, 那么就需要这样做
    '''

    # 从url的请求参数中获取keyword, like /api/search?keywords=xxx;xxx
    keywords = request.args.get('keywords', '').lower()
    # keywords为一个string, 多个keywords使用;分隔, 因为一个keyword可能是phrase
    keywords = keywords.split(';')
    print(keywords)

    # 同时因为mongodb不会parse指定的key, 所以不存在sql注入的安全风险

    mongo_col = DB['keywords']  # keywords collection
    fail_list = []
    matched_list = []
    match = True
    wids = []
    recommend = []
    try:
        for k in keywords:
            res = mongo_col.find_one({'keyword': k})
            if res:
                matched_list.append(res['keyword'])
                wids.append(res['wid'])
            else:
                match = False
                fail_list.append(k)
        # 将匹配失败的词汇和所有的keywords进行相似度匹配
        match_num = 5
        if fail_list:
            best_matches = sorted(
                KEYWORDS,
                reverse=True,
                key=lambda kwobj: max(fail_list,
                                      key=lambda fail_kw: Levenshtein.ratio(
                                          kwobj['keyword'], fail_kw)))
            recommend = [x['keyword'] for x in best_matches[:match_num]]

        response = Response(ResponseType.SUCCESS)
        response.update_attr('keywords', matched_list)
        response.update_attr('match', match)
        response.update_attr('wids', wids)
        response.update_attr('recommend', recommend)
    except Exception as e:
        print(e)
        response = Response(ResponseType.FAILURE)
    return response.get_json()


# @app.route('/api/root', methods=['GET'], strict_slashes=False)
# def get_root():
#         rootId = 1
#         response = Response(ResponseType.SUCCESS)
#         response.update_attr('rootId', rootId)
#     except Exception as e:
#         print(e)
#         response = Response(ResponseType.FAILURE)
#     return response.get_json()