Exemple #1
0
 def create_new_token(self, fingerprint):
     token = generate_unique_token(self.valid_tokens)
     date = dt.datetime.now()
     expire_date = date + dt.timedelta(0, config.access_token_expire_sec)
     token_data = Token(token, expire_date)
     self.valid_tokens[fingerprint] = token_data
     return token_data
Exemple #2
0
def create_doc_from_edu_file(edu_file, annotate_func):
    with open(edu_file, 'r') as fin:
        doc_tokens = []
        paragraphs = [p.strip() for p in fin.read().split('<P>') if p.strip()]
        previous_edu_num = 0
        for pidx, para in enumerate(paragraphs):
            sentences = [s.strip() for s in para.split('<S>') if s.strip()]
            for sidx, sent in enumerate(sentences):
                edus = [e.strip() + ' ' for e in sent.split('\n') if e.strip()]
                sent_text = ''.join(edus)
                annot_re = annotate_func(sent_text)['sentences'][0]
                sent_tokens = []
                for t in annot_re['tokens']:
                    token = Token()
                    token.tidx, token.word, token.lemma, token.pos = t[
                        'index'], t['word'], t['lemma'], t['pos']
                    token.pidx, token.sidx = pidx + 1, sidx
                    edu_text_length = 0
                    for eidx, edu_text in enumerate(edus):
                        edu_text_length += len(edu_text)
                        if edu_text_length > t['characterOffsetEnd']:
                            token.eduidx = previous_edu_num + eidx + 1
                            break
                    sent_tokens.append(token)
                for dep in annot_re['basicDependencies']:
                    dependent_token = sent_tokens[dep['dependent'] - 1]
                    dependent_token.hidx = dep['governor']
                    dependent_token.dep_label = dep['dep']
                doc_tokens += sent_tokens
                previous_edu_num += len(edus)
    doc = Doc()
    doc.init_from_tokens(doc_tokens)
    return doc
    def token_score(self, token):
        """
        Compute a matching score of a token.

        :param str token: query word.
        :rtype: float
        :returns: Score of the token, higher means better matches dictionary
        """
        if token.word.endswith('-') and token.split == '\n':
            token = Token(token.word[:-1], '')
        if ((len(token.get_word()) <= 4 and len(token.get_word()) >= 3 and
             token.get_word() == token.get_word().upper()) or
                all(c in SPECIAL for c in token.get_word())):
            return self.zeta, token
        score, typo = self.exists(self.trim(token.get_word()),
                                  edit_dist=1)

        if not typo:
            typo = token.get_word()
        w = len(token.get_word())
        # if score < 1.0:
        #     score *= score  # self.density(len(typo)) * score
        # return (score * ((len(token.get_word()) / 15.0) ** 2 + 0.05),
        #         Token(typo, token.get_split()))
        return (score * (w * w * self.alpha + w * self.beta + self.gamma), token)
Exemple #4
0
 async def mutate(self, info, user_password_input: UserPasswordInput):
     repository = UserRepository(info.context.get("client_motor"))
     user = await repository.check_user(login=user_password_input.login, password=user_password_input.password)
     if not user:
         raise Exception("Ошибка при авторизации пользователя.")
     token = Token(repository_user=repository, login=user.meta_info.login)
     return SignIn(token=token.encode())
Exemple #5
0
    def post(self, request):
        forget_pwd_form = ForgetPwdForm(request.POST)
        if forget_pwd_form.is_valid():
            email = forget_pwd_form.cleaned_data.get("email")
            user = UserProfile.objects.get(email=email)

            token_generator = Token(expires_in=1800)
            token = token_generator.generate_token({
                "email": email,
                "token_type": "forget_pwd"
            })

            message = EmailMessage(user=user,
                                   token=token,
                                   send_type="forget_pwd")
            message.send()
            return_msg = "已向{}用户发送验证邮件,邮件有效时间为0.5小时,请注意查收。".format(email)
            return HttpResponse(json.dumps({
                'status': "success",
                "message": return_msg
            }),
                                content_type="application/json")
        else:
            return HttpResponse(json.dumps({'status': "error_email"}),
                                content_type="application/json")
Exemple #6
0
def get_current_user_db_with_token(token: str):
    token_dict: dict = Token().decode(token)
    current_user = crud.get_user_by_id(token_dict['user_id'])
    if not current_user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
                            detail=strings.USER_NOT_FOUND)
    return current_user
    def get(self):
        # first check the auth token
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return "No authorization token", 403

        T = Token()
        identity = T.check(auth_header)
        if not identity:
            return "Wrong token", 403

        if identity['role'] != 1:
            return "Not customer", 403

        # select all purchased items left outer join ratings
        sql_1 = """
            SELECT purchases.item_id, customer_rating.rating
            FROM 
                (SELECT item_id FROM order_item, orders WHERE order_item.ord_id = orders.ord_id and user_id = ?) AS purchases 
                LEFT OUTER JOIN customer_rating 
                ON purchases.item_id = customer_rating.item_id AND customer_rating.user_id = ?
        """

        param_1 = (identity['user_id'], identity['user_id'])

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {
                    c[0]: R[i]
                    for i, c in enumerate(C.description)
                }
                cur = conn.cursor()
                cur.execute(sql_1, param_1)

                result = cur.fetchall()

                if len(result) == 0:
                    return "No purchase records yet", 204
                else:
                    # add the item name and photo into it
                    for d in result:
                        sql_2 = "SELECT name FROM item WHERE item_id = {}".format(
                            d['item_id'])
                        sql_3 = "SELECT photo FROM photo WHERE item_id = {} LIMIT 1".format(
                            d['item_id'])

                        cur.execute(sql_2)
                        d['name'] = cur.fetchone()['name']

                        cur.execute(sql_3)
                        d['photo'] = cur.fetchone()['photo']

                    return result, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
Exemple #8
0
    def get_id(self, request):

        "解密获取用户id"

        token = request.query_params.get("token")
        obj = Token()
        result = obj.decryt(token)

        if result: return result
def login(med: shemas.MedicLogin):
    medico:models.Medico = models.Medico.get_or_none(
        models.Medico.correo == med.correo, 
        models.Medico.clave == med.clave)
    if not medico:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=strings.USER_OR_EMAIL_NOT_FOUND)
    else:
        token =Token().encode(user_id=medico.id, user_email=medico.correo)
        return ServerResponse(msg=strings.LOGGED, token=token)
    def post(self):
        # first check the auth token
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return "No authorization token", 403
        
        T = Token()
        identity = T.check(auth_header)
        if not identity:
            return "Wrong token", 403     

        # unpack the address
        data = request.json 
        if not data:
            return "Malformed request", 400
        
        success, result = unpack(
            data, 
            "unit_number", "street_number", "street_name", "suburb", "postcode", "state",
            required=True
        )

        if not success:
            return "Missing parameter in address", 400
        
        unitnumber, streetnumber, streetname, suburb, postcode, state = result

        # check all validity
        success, msg = check_address(
            unitnumber, streetnumber, streetname, suburb, postcode, state
        )

        if not success:
            return msg, 400 

        sql = """INSERT INTO customer_address(user_id, unit_number, street_number, street_name, suburb, state, postcode)
                VALUES(?, ?, ?, ?, ?, ?, ?)
        """

        values = (identity['user_id'], unitnumber, streetnumber, streetname, suburb, state, postcode)

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {c[0]: R[i] for i, c in enumerate(C.description)}
                cur = conn.cursor()

                cur.execute(sql, values)
                new_address_id = cur.lastrowid
                
                return {"address_id": new_address_id}, 200
        
        except Exception as e:
            print(e)
            return "Internal server error", 500
Exemple #11
0
def login():
    car = g.user.car
    token = None
    car_ip_port = ''
    user_id = g.user.id
    car_id = ''
    is_connected = False
    if car:
        car_id = car.id
        car_ip_port = redis_cli.get('car:' + car_id)
    if not car_ip_port:
        token = Token(user_id)
    else:
        car_ip, car_port = car_ip_port.split(":")
        token = Token(user_id, car_id, car_ip, car_port)
        is_connected = True
    return jsonify({
        'status': 'success',
        'data': token.get(),
        'ísConnected': is_connected
    })
    def retokenise(self, token):
        """
        Attempt to split a given token into good tokens.

        :param Token token: The query token
        :rtype: pair(int, list(Token))
        :returns: A pair of the matching score and splitted portions
        """
        # token = self.dictionary.join_tokens(self.tokens[st: st + window])
        big_word = token.get_word()
        # logger.log_full_debug(big_word)
        F = [NEG_INFINITY for _ in range(len(big_word) + 1)]
        nx = [idx + 1 for idx in range(len(big_word) + 1)]
        F[len(big_word)] = 0
        for i in reversed(range(len(big_word))):
            F[i], nx[i] = \
                findmax((
                    ((self.dictionary.token_score(Token(big_word[i:j]))[0] *
                      (j - i) + (len(big_word) - j) * F[j]) /
                     (len(big_word) - i))
                    for j in range(i + 1, min(len(big_word), i + 25) + 1)),
                    NEG_INFINITY)
            nx[i] += i + 1
        res = []
        idx = 0
        while idx < len(big_word):
            _, tok = self.dictionary.token_score(
                Token(big_word[idx:nx[idx]], ' '))
            if nx[idx] >= len(big_word):
                res.append(Token(tok.get_word(), token.get_split()))
                # logger.log_full_debug(token)
            else:
                res.append(Token(tok.get_word(), ' '))
            idx = nx[idx]

        logger.log_full_debug('retokenized', token, 'into', res)
        logger.log_full_debug('retokenization score:', F)
        logger.log_full_debug('retokenization nexts:', nx)
        # logger.log_full_debug([self.dictionary.token_score(x) for x in res])
        return F[0], res
    def try_to_fix(self, st, window):
        """
        A dynamic programming algorithm using memoization, that tries to find
        the best merging of tokens that maximizes the number of correct tokens
        within a given range.

        :param int st: Start index of tokens' range without offset
        :param int en: End index of tokens' range without offset
        :param int[][] table: The memoization table of the recursion
        :param int[][] split: The memoization table of the split indices
        :param int offset: The offset of the range of tokens
        :rtype: int
        :returns: The number of maximum correct tokens
        """
        assert window > 0
        # if table[st][window] is not None:
        #     return table[st][window][0]
        joined = self.dictionary.join_tokens(self.tokens[st:st + window])
        # return self.retokenise(joined)[0], SPLIT_ENUM
        score, _ = self.dictionary.token_score(joined)
        split_whole = False
        if score < EPS:
            score, _ = self.retokenise(joined)
            if score > EPS:
                split_whole = True
        if split_whole:
            split_whole = SPLIT_ENUM
        else:
            split_whole = USE_WHOLE_ENUM
        if logger.is_full_debug():
            if Token('-', '\n') in self.tokens[st:st + window]:

                logger.log_full_debug('from',
                                      st + 1,
                                      'to',
                                      window,
                                      self.tokens[st:st + window],
                                      score,
                                      split_whole,
                                      joined,
                                      highlight=2)
            else:
                logger.log_full_debug('from',
                                      st + 1,
                                      'to',
                                      window,
                                      self.tokens[st:st + window],
                                      score,
                                      split_whole,
                                      joined,
                                      highlight=2)
        return score, split_whole
    def get(self):
        auth_header = request.headers.get("Authorization")
        if not auth_header:
            return "No authorization token", 403

        T = Token()
        identity = T.check(auth_header)

        if not identity:
            return "Wrong token", 403
        
        result = get_user_profile(identity['user_id'])
        return result
Exemple #15
0
    def perform_create(self, serializer):
        "保存数据前,额外需要传递的参数"
        obj = serializer.save(is_staff=0, is_active=0)

        # 生成激活码
        tk_obj = Token()
        token = tk_obj.encryt(obj.id).decode("utf-8")

        reciver = obj.email
        content = settings.CONTENT.format(obj.username, token, token)
        # celery发送邮件
        send_QQmail.delay(settings.SUBJECT, '', settings.SENDER, reciver,
                          content)
Exemple #16
0
def check_admin_token(header):
    if not header:
        abort(400, "No authorization token")

    T = Token()
    identity = T.check(header)

    if not identity:
        abort(403, "Wrong token")

    if identity['role'] != 0:
        abort(403, "Only admin can access")

    return identity
    def post(self):
        if not request.json:
            return "Malformed request", 400

        data = request.json

        if (not "password" in data) or (not "email" in data):
            return "Missing email / password", 400

        email, password = data['email'], data['password']

        # check the database
        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {
                    c[0]: R[i]
                    for i, c in enumerate(C.description)
                }
                cur = conn.cursor()

                sql = """
                        SELECT user_id, role, password
                        FROM user 
                        WHERE email = ?
                    """

                param = (email, )
                cur.execute(sql, param)
                result = cur.fetchone(
                )  # fetch one: return either a dict or None

                if not result:
                    return "Invalid email/password", 403

                if result['password'] != password:
                    return "Invalid email/password", 403

                # generate token
                T = Token()
                token = T.generate(user_id=result["user_id"],
                                   role=result["role"])

                return_value = {'token': token, 'role': result['role']}

                return return_value, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
Exemple #18
0
def update_email_name(doctor:shemas.MedicNombreCorreo,token:str):
    current_user: models.Medico  = get_current_user_db_with_token(token)
    if check_if_email_is_taken(doctor.correo):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail= strings.USER_ALRRADY_REGISTERED)
    doctor_updated =  crud.update_email_name_doctor(current_user.id, doctor)
    if doctor_updated ==1:
        newToken = Token().encode(current_user.id,
                                  doctor.correo)
        return ServerResponse(msg=strings.DOCTOR_UPDATED, token=newToken)
    else: 
       raise HTTPException(
           status_code=status.HTTP_304_NOT_MODIFIED,
           detail=strings.DOCTOR_NOT_UPDATED)
Exemple #19
0
 def update_session(self, refresh_token):
     db_sess = db_session.create_session()
     q = db_sess.query(SessionModel)
     q = q.filter(SessionModel.refresh_token == refresh_token)
     if not q.all():
         return
     session = q.first()
     if Token(session.refresh_token, session.expires_at).is_expired():
         return
     db_sess.delete(session)
     db_sess.commit()
     new_session = self.create_new(session.user_id, session.fingerprint)
     db_sess.object_session(new_session).add(new_session)
     db_sess.object_session(new_session).commit()
     return new_session
def create_medico(med: shemas.MedicRegister):
    if check_if_email_is_taken(med.correo):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail= strings.USER_ALRRADY_REGISTERED)
    try:
        medico:models.Medico = models.Medico(**med.dict())
        medico.save()
        token = Token().encode(medico.id,medico.correo)
        return ServerResponse(
            msg=strings.DOCTOR_ADED,token = token)
    except:
            raise HTTPException(
                status_code = status.HTTP_400_BAD_REQUEST,
                detail=strings.ERROR)
Exemple #21
0
 def _parse_fmerge_line(line):
     """ Parse one line from *.merge file
     """
     items = line.split("\t")
     tok = Token()
     tok.pidx, tok.sidx, tok.tidx = int(items[-1]), int(items[0]), int(
         items[1])
     # Without changing the case
     tok.word = items[2]
     try:
         tok.eduidx = int(items[9])
     except ValueError:
         print("EDU index for {} is missing in fmerge file".format(
             tok.word))
         pass
     return tok
Exemple #22
0
def check_admin_identity():
    # check token
    auth = request.headers.get("Authorization")
    if not auth:
        return None, "No authorization token", 403

    T = Token()
    identity = T.check(auth)

    if not identity:
        return None, "Wrong token", 403

    if identity['role'] != 0:
        return None, "Only admin can edit", 403

    return identity, None, None
    def get(self):
        # check the token first
        # first check the auth token
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return "No authorization token", 403

        T = Token()
        identity = T.check(auth_header)
        if not identity:
            return "Wrong token", 403

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {
                    c[0]: R[i]
                    for i, c in enumerate(C.description)
                }
                cur = conn.cursor()

                sql_1 = """
                    SELECT orders.ord_id
                    FROM user, orders
                    WHERE user.user_id = orders.user_id AND user.user_id = ?
                    ORDER BY unix_time DESC
                """

                sql_1_param = (identity["user_id"], )
                cur.execute(sql_1, sql_1_param)

                sql_1_result = cur.fetchall()
                order_id_list = [e['ord_id'] for e in sql_1_result]

                if not order_id_list:
                    return "The customer has not made any orders yet", 204

                result = []

                for ord_id in order_id_list:
                    result.append(get_this_order_history(ord_id))

                return result, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
    def join_tokens(self, tokens):
        """
        Join a list of tokens.

        :param list(str) tokens: The list of tokens.
        :rtype: str
        :returns: A string of the combined token.
        """
        last_good_split = list(filter(
            lambda tk: not (tk.get_word().endswith('-') and
                            tk.get_split() == '\n'), tokens))
        if not last_good_split:
            last_good_split = ' '
        else:
            last_good_split = last_good_split[-1].get_split()
        ret = Token(''.join(self.trim(token.get_word()) for token in tokens
                            if token.get_word() != '-'),
                    last_good_split)
        return ret
    def post(self):
        # check the token first
        # first check the auth token
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return "No authorization token", 403

        T = Token()
        identity = T.check(auth_header)
        if not identity:
            return "Wrong token", 403

        # check the payload
        data = request.json
        if not data:
            return "Malformed request", 400

        # submit cart
        code, response = submit_order(data, identity)
        return response, code
Exemple #26
0
 def _parse_fmerge_line(line):
     """ Parse one line from *.merge file
     """
     items = line.split("\t")
     tok = Token()
     tok.pidx, tok.sidx, tok.tidx = int(items[-1]), int(items[0]), int(items[1])
     # Without changing the case
     tok.word, tok.lemma = items[2], items[3]
     tok.pos = items[4]
     tok.dep_label = items[5]
     try:
         tok.hidx = int(items[6])
     except ValueError:
         pass
     tok.ner, tok.partial_parse = items[7], items[8]
     try:
         tok.eduidx = int(items[9])
     except ValueError:
         print("EDU index for {} is missing in fmerge file".format(tok.word))
         # sys.exit()
         pass
     return tok
    def get(self):

        header = request.headers.get("Authorization")
        if not header:
            return "No authorization token", 403
        
        T = Token()
        identity = T.check(header)
        
        if not identity:
            return "Wrong Token", 403
        
        sql = """
            SELECT DISTINCT view_history.item_id 
            FROM view_history LEFT OUTER JOIN item ON view_history.item_id = item.item_id
            WHERE user_id= ? AND item.status = 1
            ORDER BY time DESC 
            LIMIT 8
        """
        
        parameter = (identity["user_id"],)

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {c[0]: R[i] for i, c in enumerate(C.description)}
                cur = conn.cursor()
                
                r = cur.execute(sql, parameter)
                result = r.fetchall()
                
                if len(result) == 0:
                    return "No content", 204
                else:
                    final = get_all_profiles(list(result))
                    return final, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
Exemple #28
0
    def get(self):
        """Recommend items based on popularity and user similarity (need token)"""

        auth_header = request.headers.get("Authorization")
        if not auth_header:
            return "No authorization token", 403

        T = Token()
        identity = T.check(auth_header)

        if not identity:
            return "Wrong token", 403

        sql = """SELECT * FROM customer_rating"""

        u_id = identity['user_id']

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {
                    c[0]: R[i]
                    for i, c in enumerate(C.description)
                }
                cur = conn.cursor()

                r1 = cur.execute(sql)
                result = r1.fetchall()

                # user-rating table
                user_rating = pd.DataFrame(result)

                #if user has not purchased anything before
                if u_id not in user_rating.user_id.values:
                    return "user has not purchased anything", 204

                # mean ratint rated by each user
                ratings_mean_count = pd.DataFrame(
                    user_rating.groupby('item_id')
                    ['rating'].mean().sort_values(ascending=False))

                ratings_mean_count['rating_counts'] = pd.DataFrame(
                    user_rating.groupby('item_id')['rating'].count())

                popular = ratings_mean_count.sort_values(
                    ['rating_counts', 'rating'],
                    ascending=False).reset_index()

                pop_item = popular['item_id'].values.tolist()

                df = user_rating.pivot_table(index='user_id',
                                             columns='item_id',
                                             values='rating')

                # common part item rated by user pair
                def build_xy(user_id1, user_id2):
                    bool_array = df.loc[user_id1].notnull(
                    ) & df.loc[user_id2].notnull()
                    return df.loc[user_id1, bool_array], df.loc[user_id2,
                                                                bool_array]

                # pearsonr to count similarity of user pair
                def pearson(user_id1, user_id2):
                    x, y = build_xy(user_id1, user_id2)
                    mean1, mean2 = x.mean(), y.mean()
                    denominator = (sum((x - mean1)**2) * sum(
                        (y - mean2)**2))**0.5
                    try:
                        value = sum((x - mean1) * (y - mean2)) / denominator
                    except ZeroDivisionError:
                        value = 0
                    return value

                # find nearest user
                def computeNearestNeighbor(user_id, k=8):
                    # the customer may not have purchased before
                    # so need to check, if no purchase, return none
                    # print("1111",df.drop(user_id).index.to_series().apply(pearson, args=(user_id,)).nlargest(k))

                    return df.drop(user_id).index.to_series().apply(
                        pearson, args=(user_id, )).nlargest(k)

                ####CF user-based rec
                def recommend(user_id):
                    # find nearest user_id
                    result = 0

                    nearest_user_id_list = computeNearestNeighbor(
                        user_id).index.tolist()
                    #find out the item that is rated by neighbour but not user self
                    #in case nearest user has the same rated item as user self.
                    for nearest_user_id in nearest_user_id_list:
                        k_near = df.loc[nearest_user_id,
                                        df.loc[user_id].isnull()
                                        & df.loc[nearest_user_id].notnull()]
                        if len(k_near.values) != 0:
                            result = k_near.sort_values(ascending=False)

                            # print("result:",result[:5].index)
                            break

                    ###get top 5
                    return result[:5].index

                # if no purchase record, return 204
                rec_result = recommend(u_id)
                # print(rec_result)

                # for customer with purchase record
                all_result = []

                for i in rec_result:
                    all_result.append(i)

                #recommend to users: top_k
                top_k = 8

                for i in pop_item:
                    if len(all_result) < top_k and i not in all_result:
                        all_result.append(i)
                    elif len(all_result) >= 5:
                        break

                p_all = []

                for i in all_result:
                    profile = {}
                    profile['item_id'] = int(i)
                    p_all.append(profile)

                r = get_all_profiles(p_all)
                return r, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
Exemple #29
0
    def get(self):
        """Recommend items based on user view history (need token)"""

        auth_header = request.headers.get("Authorization")
        if not auth_header:
            return "No authorization token", 403

        T = Token()

        identity = T.check(auth_header)
        if not identity:
            return "Wrong token", 403

        sql = """
                SELECT view_history.*
                FROM view_history, item
                WHERE view_history.item_id = item.item_id 
                AND item.status = 1
            """

        sql2 = """
                SELECT item.*
                FROM item
                WHERE item.status = 1
            """

        sql3 = """
                SELECT laptop.*
                FROM laptop, item
                WHERE laptop.item_id = item.item_id 
                AND item.status = 1
            """

        u_id = identity['user_id']

        #####item-feature
        fea = [
            'item_id', 'price', 'cpu_lithography', 'cpu_cache',
            'cpu_base_speed', 'cpu_boost_speed', 'cpu_cores', 'cpu_tdp',
            'cpu_rating', 'cpu_integrated_video_id', 'display_size',
            'display_horizontal_resolution', 'display_vertical_resolution',
            'display_sRGB', 'memory_size', 'memory_speed',
            'primary_storage_cap', 'primary_storage_read_speed',
            'gpu_lithography', 'gpu_shaders', 'gpu_base_speed',
            'gpu_boost_speed', 'gpu_shader_speed', 'gpu_memory_speed',
            'gpu_memory_bandwidth', 'gpu_memory_size', 'gpu_rating',
            'wireless_card_speed', 'chassis_height_cm', 'chassis_height_inch',
            'chassis_depth_cm', 'chassis_depth_inch', 'chassis_width_cm',
            'chassis_width_inch', 'chassis_weight_kg', 'chassis_weight_lb',
            'battery_capacity', 'config_score', 'battery_life_raw',
            'total_storage_capacity'
        ]

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {
                    c[0]: R[i]
                    for i, c in enumerate(C.description)
                }

                cur = conn.cursor()
                cu1 = conn.cursor()
                cu2 = conn.cursor()

                r = cur.execute(sql)
                r2 = cu1.execute(sql2)
                r3 = cu2.execute(sql3)

                result, result1, result2 = r.fetchall(), r2.fetchall(
                ), r3.fetchall()

                view_history, item, laptop = pd.DataFrame(
                    result), pd.DataFrame(result1), pd.DataFrame(result2)

                most_view = pd.DataFrame(
                    view_history.groupby('user_id')['item_id'].agg(
                        lambda x: stats.mode(x)[0])).reset_index()

                # if this user does not have any view history
                # then return 204
                if not most_view[most_view['user_id'] ==
                                 u_id]['item_id'].any():
                    return "New user, no view history", 204

                # for users with view history
                i_id = most_view[most_view['user_id'] ==
                                 u_id]['item_id'].values[0]

                all_lap = item.merge(laptop, on='item_id', how='left')

                item_fea = all_lap[fea].set_index('item_id')

                new_item = MinMaxScaler().fit_transform(item_fea)

                new_df = pd.DataFrame(new_item, columns=fea[1:])

                df = pd.DataFrame(all_lap['item_id'])

                nor_item = pd.concat((new_df, df), axis=1).set_index("item_id")

                def build_xy(item_id1, item_id2):
                    bool_array = nor_item.loc[item_id1].notnull(
                    ) & nor_item.loc[item_id2].notnull()
                    return nor_item.loc[item_id1,
                                        bool_array], nor_item.loc[item_id2,
                                                                  bool_array]

                ###pearsonr to calculate similarity of pair item
                def pearson(item_id1, item_id2):
                    x, y = build_xy(item_id1, item_id2)
                    mean1, mean2 = x.mean(), y.mean()
                    denominator = (sum((x - mean1)**2) * sum(
                        (y - mean2)**2))**0.5
                    try:
                        value = sum((x - mean1) * (y - mean2)) / denominator
                    except ZeroDivisionError:
                        value = 0
                    return value

                #####find out nearest item
                def computeNearestNeighbor(item_id, k):
                    return nor_item.drop(item_id).index.to_series().apply(
                        pearson, args=(item_id, )).nlargest(k)

                KNN_item = computeNearestNeighbor(i_id, 5).index.tolist()
                p_all = []

                for i in KNN_item:
                    profile = {}
                    profile['item_id'] = int(i)
                    p_all.append(profile)

                r = get_all_profiles(p_all)
                return r, 200

        except Exception as e:
            print(e)
            return "Internal server error", 500
    def put(self):
        auth=request.headers.get("Authorization")
        if not auth:
            return "No authorization token",403
        
        T=Token()
        identity=T.check(auth)
        
        if not identity:
            return"Wrong token",403
        
        ids = identity['user_id']

        data=request.json
        
        if not data:
            return "Malformed request", 400
        
        is_unpack_ok, modified_data = unpack(
            data,
            "first_name","last_name","email","mobile","password",
            required=False
        )

        if not is_unpack_ok:
            return "Malformed request", 400
        
        f_name, l_name, email, mobile, password = modified_data

        # also prepare the sql for the relevant modified data
        # one data => one sql => one tuple in the sql_param_list
        sql_list = []
        sql_param_list = []
        
        if f_name:
            ok, msg = check_name(f_name)
            if not ok:
                return msg, 400
            
            sql_list.append("UPDATE user SET first_name = ? WHERE user_id = ?")
            sql_param_list.append((f_name, ids))


        if l_name:
            ok, msg = check_name(l_name)
            if not ok:
                return msg, 400

            sql_list.append("UPDATE user SET last_name = ? WHERE user_id = ?")
            sql_param_list.append((l_name, ids))       
            

        if email:
            ok, msg = check_email(email)
            if not ok:
                return msg, 400
            
            sql_list.append("UPDATE user SET email = ? WHERE user_id = ?")
            sql_param_list.append((email, ids))


        if mobile:
            ok, msg = check_mobile(mobile);
            if not ok:
                return msg, 400 
        
            sql_list.append("UPDATE user SET mobile = ? WHERE user_id = ?")
            sql_param_list.append((mobile, ids))


        if password:
            ok, msg = check_password(password)
            if not ok: 
                return msg, 400 

            sql_list.append("UPDATE user SET password = ? WHERE user_id = ?")
            sql_param_list.append((password, ids))

        
        # if nothing update, this is a malformed request
        if len(sql_list) == 0:
            return "Malformed request", 400

        try:
            with sqlite3.connect(os.environ.get("DB_FILE")) as conn:
                conn.row_factory = lambda C, R: {c[0]: R[i] for i, c in enumerate(C.description)}
                cur = conn.cursor()

                for i in range(len(sql_list)):
                    cur.execute(sql_list[i], sql_param_list[i])

                return "OK", 200

        except Exception as e:
            print(e)
            return "Internal server error", 500