def __init__(self):
        super().__init__('s')

        self.add_rule(self.create)
        self.add_rule(self.addQuestion)
        self.add_rule(self.getQuestions)
        self.add_rule(self.publish)
        self.add_rule(self.like)
        self.add_rule(self.getCurrentSurveyId)
        self.add_rule(self.setInfo)
        self.add_rule(self.getInfo)
        self.add_rule(self.setAnswer)
        self.add_rule(self.getAnswer)
        self.add_rule(self.getInfos, methods=['POST', 'GET'])
        self.add_rule(self.getImage, methods=['POST', 'GET'])

        self.app_config = config
        db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.security = Security()
        self.filesender = FileSender()
        self.requester = Requester(self.db)

        self.form_checker = FormChecker()
        self.error = Error()
Exemple #2
0
    def __init__(self):

        db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.security = Security()
Exemple #3
0
 def run(self):
     # 输入搜索结果,输出所需要的搜索内容_url
     search_html = Request(self.url+'/search?q='+self.value, 'search url').request()
     dest_urls = Parse(search_html).parse_search_html()
     
     # 存储所有目标字幕的下载页
     download_urls = []
     for dest_url in dest_urls:
         # 获取每一个字幕文件的主页url
         detail_html = Request(self.url + dest_url, 'detail url').request()
         sub_urls = Parse(detail_html).parse_detail()
         for sub_url in sub_urls:
             # 获取字幕文件下载页的url
             sub_html = Request(self.url + sub_url, 'sub url').request()
             download_page_url = Parse(sub_html).parse_sub_url()
             click_download = Downloader(self.url + download_page_url).download()
Exemple #4
0
def main():

    search = input('请输入您想搜索的美剧,注意声明全名和季数哦: ')

    url = 'https://www.ttkmj.net'
    main_url = Search(url, search).search()
    print(main_url)
    dest_html = Request(main_url, 'search result').request()
    dest_url = Destination(dest_html).parse_result()
    print(dest_url)
    links_html = Request(dest_url, 'target page').request()
    links = Links(links_html).parse_links()
    print(links)
    # 最后写入到目标文件夹中完成保存,学会读写文本:文件夹+操作方式
    f = open('./source/{}.html'.format(search), 'w')
    for link in links:
        f.write(link)
        f.write('\n')
    f.close()
    def __init__(self):
        super().__init__()

        self.add_rule(self.main_page, url='/nt', methods=['GET'])
        self.add_rule(self.favicon, url='/favicon.ico', methods=['GET'])
        self.add_rule(self.style, methods=['GET', 'POST'])
        self.add_rule(self.script, methods=['GET', 'POST'])
        self.add_rule(self.svg, methods=['GET', 'POST'])
        self.add_rule(self.photo, methods=['GET', 'POST'])

        self.add_rule(self.templates)
        self.add_rule(self.svgs)

        self.app_config = config

        self.response = Response()
        self.security = Security()
        self.filesender = FileSender()
        self.request = Request()
Exemple #6
0
    def handle(self, sock):
        bytes = b''
        while not bytes.endswith(b'\n'):
            bytes += sock.recv(1024)

        data = bytes.decode()
        request = Request(data)

        if request.method not in const.ALLOWED_METHODS:
            sock.sendall(ResponseNotAllowed().encode())
            return

        if not request.is_ok:
            sock.sendall(ResponseBadResponse().encode())
            return

        if '/../' in request.path:
            sock.sendall(ResponseForbidden().encode())
            return

        request.path = unquote(request.path.split('?')[0])

        request.path = os.getcwd() + request.path
        if os.path.isdir(request.path):
            request.path += 'index.html'
            if not os.path.isfile(request.path):
                sock.sendall(ResponseForbidden().encode())

        try:
            body = self.read_file(request.path)
        except Exception:
            sock.sendall(ResponseNotFound().encode())
            return

        response = ResponseOK(body, request.path, request.method)
        sock.sendall(response.encode())
Exemple #7
0
class User:
    def __init__(self):

        db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.security = Security()

    def add_before_request(self, app):

        @app.before_request
        def before_request():

            session = self.request.get_session_arg('session')

            is_registered = False
            
            if session:
                is_registered = self.__check_is_registered(session)

            if not is_registered:

                self.__register()

    def __check_is_registered(self, session):
        is_registered = False

        sessions_hashs = self.db('SELECT session FROM users').all()

        for id, sh in enumerate(sessions_hashs):
            if sh['session'] == session:
                is_registered = True

        return is_registered

    def __register(self):
        session = self.security.gen_key(64)

        self.db('INSERT INTO users(session) \
                 VALUES(?)', (session,)).close()

        self.response.set_arg('session', session)
class Surveys(Module):
    def __init__(self):
        super().__init__('s')

        self.add_rule(self.create)

        self.app_config = config

		db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
		tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

		self.db = Database(db_path)
		self.db.execute_file(tables_path)

        self.security = Security()
        self.filesender = FileSender()
        self.request = Request()
        self.requester = Requester(db)

        self.form_checker = FormChecker()
Exemple #9
0
    def run(self):
        self.print_movie_list()
        self.indexstr = input('请输入您需要的电影序号,多个请用空格隔开:')
        self.parse_index()
        self.delete_file()

        for index in self.index_list:
            self.movie_url = Search(
                url_index=index, search_html=self.search_html).get_index_url()
            self.movie_html = Request(self.movie_url, 'movie url').request()

            self.movie_content = Parse(movie_html=self.movie_html)
            self.links = self.movie_content.parse_movie_links()
            self.img = self.movie_content.get_img_url()
            self.movie_name = self.movie_content.get_movie_name()

            self.html = Html(file_name=self.value,
                             links=self.links,
                             img_link=self.img,
                             movie_name=self.movie_name,
                             split=True)
            self.html.write_to_html()
Exemple #10
0
class Surveys(Module):
    def __init__(self):
        super().__init__('s')

        self.add_rule(self.create)
        self.add_rule(self.getCurrentSurveyId)
        self.add_rule(self.setInfo)
        self.add_rule(self.addQuestion)
        self.add_rule(self.publish)

        self.add_rule(self.getAccessUrl)
        self.add_rule(self.addAccess, methods=['POST', 'GET'])

        self.add_rule(self.getInfos)
        self.add_rule(self.getQuestions)

        self.add_rule(self.setAnswer)
        self.add_rule(self.like)

        self.add_rule(self.getLastAnswer)

        self.add_rule(self.getUserAnswer)
        self.add_rule(self.getInfo)

        self.add_rule(self.complete)
        self.add_rule(self.isUserComplete)

        # self.add_rule(self.getImage, methods=['POST', 'GET'])

        self.app_config = config
        db_path = os.path.join(config['DATABASE_PATH'],
                               config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'],
                                   config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.requester = Requester(self.db)

        self.security = Security()
        self.filesender = FileSender()

        self.form_checker = FormChecker()
        self.error = Error()

    def create(self):
        '''
            no if
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data,
                                                  ['name', 'description'])

        if formation == 'ok':

            name = data['name']
            description = data['description']

            is_published = 0
            user_id = self.__get_user_id()
            create_time = self.__get_time()
            secret_code = self.security.gen_key(64)

            c = self.db(
                'INSERT INTO surveys(name, description, create_time, user_id, is_published, secret_code) \
                     VALUES(?,?,?,?,?,?)',
                (name, description, create_time, user_id, is_published,
                 secret_code))

            current_survey_id = c.lastrowid()
            c.close()

            self.db('UPDATE users SET current_survey_id=? WHERE id=?',
                    (current_survey_id, user_id)).close()

            return self.response.send_json({'response': True})

        else:

            return self.response.send_json({'response': {'error': formation}})

    def getCurrentSurveyId(self):
        '''
            if current_survey_id exist
        '''
        survey_id = self.__get_current_survey_id()

        return self.response.send_json({'response': survey_id})

    def setInfo(self):
        '''
            if current_survey_id exist
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data,
                                                  ['name', 'description'])

        if formation == 'ok':
            survey_id = self.__get_current_survey_id()

            if survey_id:

                name = data['name']
                description = data['description']

                self.db('UPDATE surveys SET name=?, description=? WHERE id=?',
                        (name, description, survey_id)).close()

                return self.response.send_json({'response': True})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(4)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def addQuestion(self):
        '''
            if current_survey_id exist
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(
            data, ['question_text', 'answer_type', 'answers'])

        if formation == 'ok':

            survey_id = self.__get_current_survey_id()

            if survey_id:

                answer_type = data['answer_type']
                question_text = data['question_text']

                c = self.db(
                    'INSERT INTO questions(question_text, answer_type, survey_id) \
                         VALUES(?,?,?)',
                    (question_text, answer_type, survey_id))

                question_id = c.lastrowid()
                c.close()

                for answer_text in data['answers']:
                    self.db(
                        'INSERT INTO answer_options(answer_text, question_id) \
                             VALUES(?,?)', (answer_text, question_id)).close()

                return self.response.send_json({'response': True})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(4)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def publish(self):
        '''
            if current_survey_id exist
            if questions > 1
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data,
                                                  ['visability', 'author'])

        if formation == 'ok':

            survey_id = self.__get_current_survey_id()

            if survey_id:

                author = data['author']
                visability = data['visability']

                is_published = 1
                publish_time = self.__get_time()
                questions = self.__get_questions(survey_id)

                if len(questions) >= 2:

                    user_id = self.__get_user_id()

                    self.db('UPDATE users SET current_survey_id=? WHERE id=?',
                            (
                                None,
                                user_id,
                            )).close()

                    self.db(
                        'UPDATE surveys SET author=?, visability=?, is_published=?, publish_time=? WHERE id=?',
                        (author, visability, is_published, publish_time,
                         survey_id)).close()

                    return self.response.send_json({'response': True})

                else:
                    return self.response.send_json(
                        {'response': {
                            'error': self.error(3)
                        }})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(4)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def isUserComplete(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']
            post_type = 0
            user_id = self.__get_user_id()
            post_id = survey_id

            completion = self.db(
                'SELECT * FROM completions WHERE post_type=? AND post_id=? AND user_id=?',
                (post_type, post_id, user_id)).one()

            if completion:
                return self.response.send_json({'response': True})

            else:
                return self.response.send_json({'response': False})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def complete(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            if self.__is_survey_accessable(survey_id):
                is_complete = True

                questions = self.__get_full_questions(survey_id)

                user_id = self.__get_user_id()

                for question in questions:
                    is_answer = False

                    for a in question['answers']:
                        answer_option_id = a['id']
                        answer = self.db(
                            'SELECT * FROM survey_answers WHERE answer_option_id=? AND user_id=?',
                            (answer_option_id, user_id)).one()

                        if answer:
                            is_answer = True
                            break

                    if not is_answer:
                        is_complete = False
                        break

                if is_complete:

                    complete_time = self.__get_time()

                    post_type = 0
                    post_id = survey_id

                    self.db(
                        'INSERT INTO completions(complete_time, post_type, post_id, user_id) \
                                VALUES(?,?,?,?)',
                        (complete_time, post_type, post_id, user_id)).close()

                    return self.response.send_json({'response': True})

                else:
                    return self.response.send_json(
                        {'response': {
                            'error': self.error(5)
                        }})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getAccessUrl(self):
        survey_id = self.__get_current_survey_id()

        if survey_id:

            survey = self.__get_survey(survey_id)

            url = 'https://grafstor.xyz/nt/s/addAccess?id={0}&sc={1}'.format(
                survey_id, survey['secret_code'])

            return self.response.send_json({'response': url})

        else:
            return self.response.send_json(
                {'response': {
                    'error': self.error(4)
                }})

    def addAccess(self):
        survey_id = self.request.get_arg('id')
        secret_code = self.request.get_arg('sc')

        data = {
            'survey_id': survey_id,
            'secret_code': secret_code,
        }

        formation = self.form_checker.is_formated(data,
                                                  ['survey_id', 'secret_code'])

        if formation == 'ok':

            survey_id = data['survey_id']
            secret_code = data['secret_code']

            user_id = self.__get_user_id()

            survey = self.__get_survey(survey_id)

            if survey['secret_code'] == secret_code:

                self.db(
                    'INSERT INTO surveys_accesses(user_id, survey_id) \
                         VALUES(?,?)', (user_id, survey_id)).close()

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getInfos(self):
        '''
            if post_type = 0
        '''
        surveys = self.__get_surveys()

        for i, survey in enumerate(surveys):

            likes = self.db(
                'SELECT * FROM likes WHERE post_id=? and post_type=0',
                (survey['id'], )).all()
            likes_num = len(likes)

            completions = self.db(
                'SELECT * FROM completions WHERE post_id=? and post_type=0',
                (survey['id'], )).all()
            completions_num = len(completions)

            survey = {
                'id': survey['id'],
                'name': survey['name'],
                'description': survey['description'],
                'author': survey['author'],
                'num_likes': likes_num,
                'num_completed': completions_num,
            }

            surveys[i] = survey

        return self.response.send_json({'response': surveys})

    def getQuestions(self):
        '''
            if survey_accessable
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            if self.__is_survey_accessable(survey_id):

                questions = self.__get_full_questions(survey_id)

                return self.response.send_json({'response': questions})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def setAnswer(self):
        '''
            if survey_accessable
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data,
                                                  ['answer_id', 'is_answer'])

        if formation == 'ok':

            is_answer = data['is_answer']
            answer_option_id = data['answer_id']

            survey_id = self.__get_survey_id_by_answer_id(answer_option_id)

            if self.__is_survey_accessable(survey_id):

                user_id = self.__get_user_id()

                if is_answer:

                    self.db(
                        'INSERT INTO survey_answers(answer_option_id, user_id) \
                             VALUES(?,?)',
                        (answer_option_id, user_id)).close()

                    question_id = self.__get_question_id_by_answer_id(
                        answer_option_id)
                    old_question_id = self.db(
                        'SELECT * FROM last_question WHERE user_id=? AND  survey_id=? ',
                        (user_id, survey_id)).one()

                    if old_question_id:
                        self.db(
                            'UPDATE last_question SET question_id=? WHERE user_id=? AND  survey_id=?',
                            (question_id, user_id, survey_id)).close()

                    else:
                        self.db(
                            'INSERT INTO last_question(user_id, survey_id, question_id) \
                                 VALUES(?,?,?)',
                            (user_id, survey_id, question_id)).close()

                    return self.response.send_json({'response': True})

                else:

                    self.db(
                        'DELETE FROM survey_answers WHERE answer_option_id=? AND user_id=?',
                        (answer_option_id, user_id)).close()

                    return self.response.send_json({'response': True})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getLastAnswer(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            if self.__is_survey_accessable(survey_id):

                user_id = self.__get_user_id()

                question_id = self.db(
                    'SELECT * FROM last_question WHERE user_id=? AND  survey_id=? ',
                    (user_id, survey_id)).one()

                if question_id:

                    return self.response.send_json(
                        {'response': question_id['question_id']})

                else:
                    return self.response.send_json({'response': False})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def like(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            if self.__is_survey_accessable(survey_id):

                user_id = self.__get_user_id()
                create_time = self.__get_time()
                post_type = 0

                is_already_like = self.db(
                    'SELECT * FROM likes WHERE post_id=? and post_type=0 and user_id=?',
                    (survey_id, user_id)).one()

                if not is_already_like:
                    self.db(
                        'INSERT INTO likes(create_time, post_type, post_id, user_id) \
                             VALUES(?,?,?,?)',
                        (create_time, post_type, survey_id, user_id)).close()

                else:
                    self.db(
                        'DELETE FROM likes WHERE post_id=? and post_type=0 and user_id=?',
                        (survey_id, user_id)).close()
            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getUserAnswer(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['question_id'])

        if formation == 'ok':

            question_id = data['question_id']
            survey_id = self.__get_survey_id_by_question_id(question_id)

            if self.__is_survey_accessable(survey_id):

                user_id = self.__get_user_id()

                answer = self.db(
                    'SELECT * FROM survey_answers WHERE user_id=?',
                    (user_id)).one()

                if answer:

                    return self.response.send_json(
                        {'response': answer['answer_option_id']})

                else:
                    return self.response.send_json({'response': False})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getInfo(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            if self.__is_survey_accessable(survey_id):

                survey = self.__get_survey(survey_id)

                survey = self.__filter_dict(survey,
                                            ['name', 'description', 'author'])

                return self.response.send_json({'response': survey})

            else:
                return self.response.send_json(
                    {'response': {
                        'error': self.error(0)
                    }})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def __get_answers(self, question_id):

        answers = self.db('SELECT * FROM answer_options WHERE question_id=?',
                          (question_id, )).all()

        return answers

    def __get_survey_id_by_question_id(self, question_id):

        survey_id = self.db('SELECT survey_id FROM questions WHERE id=?',
                            (question_id, )).one()['survey_id']

        return survey_id

    def __get_question_id_by_answer_id(self, answer_id):

        question_id = self.db(
            'SELECT question_id FROM answer_options WHERE id=?',
            (answer_id, )).one()['question_id']

        return question_id

    def __get_survey_id_by_answer_id(self, answer_id):

        question_id = self.__get_question_id_by_answer_id(answer_id)

        survey_id = self.__get_survey_id_by_question_id(question_id)

        return survey_id

    def __get_full_questions(self, survey_id):
        full_questions = self.__get_questions(survey_id)

        for i, question in enumerate(full_questions):

            question = self.__filter_dict(
                question, ['id', 'question_text', 'answer_type'])

            answers = self.__get_answers(question['id'])
            question['answers'] = [
                self.__filter_dict(answer, ['id', 'answer_text'])
                for answer in answers
            ]

            full_questions[i] = question

        return full_questions

    def __get_questions(self, survey_id):

        questions = self.db('SELECT * FROM questions WHERE survey_id=?',
                            (survey_id, )).all()

        return questions

    def __get_survey(self, survey_id):

        survey = self.db('SELECT * FROM surveys WHERE id=?',
                         (survey_id, )).one()

        return survey

    def __is_survey_accessable(self, survey_id):
        survey = self.__get_survey(survey_id)

        if survey['is_published'] == 1:

            if survey['visability'] == 1:

                if self.__is_user_accessed(survey_id):

                    return True

                else:
                    return False

            else:
                return True

        elif survey['is_published'] == 0 and self.__is_user_owner(survey_id):

            return True

        else:
            return False

    def __is_user_accessed(self, survey_id):

        user_id = self.__get_user_id()

        access = self.db(
            'SELECT * FROM surveys_accesses WHERE user_id=? AND survey_id=?', (
                user_id,
                survey_id,
            )).one()

        if access:

            return True

        return False

    def __get_surveys(self):

        surveys = self.db(
            'SELECT * FROM surveys WHERE visability=0 and is_published=1').all(
            )

        return surveys

    def __get_current_survey_id(self):

        user_id = self.__get_user_id()

        current_survey_id = self.db(
            'SELECT current_survey_id FROM users WHERE id=?',
            (user_id, )).one()

        if current_survey_id:

            return current_survey_id['current_survey_id']

        return False

    def __get_time(self):

        return str(datetime.datetime.utcnow()) + ' UTC'

    def __get_user_id(self):

        user_id = self.requester.get_id()

        return user_id

    def __filter_dict(self, d, pass_list):
        new_d = {}

        for e in pass_list:
            new_d[e] = d[e]

        return new_d

    def __is_user_owner(self, survey_id):
        user_id = self.__get_user_id()

        survey_user_id = self.db('SELECT user_id FROM surveys WHERE id=?',
                                 (survey_id, )).one()

        if survey_user_id['user_id'] == user_id:

            return True

        return False
Exemple #11
0
import os
import sys

from tools.config import Config
from tools.request import Request

if __name__ == '__main__':
    status = sys.stdin.read()
    filename = sys.argv[1] if len(sys.argv) == 2 else 'config.json'
    path = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
    config = Config(path)
    request = Request(config)
    result = request.post('statuses', {'status': status})
    if 'error' in result[1]:
        print('an error "{}" occurred while posting a toot.'.format(
            result[1]['error']),
              file=sys.stderr)
        exit(1)
    else:
        print(result[1]['url'])
class Surveys(Module):
    def __init__(self):
        super().__init__('s')

        self.add_rule(self.create)
        self.add_rule(self.addQuestion)
        self.add_rule(self.getQuestions)
        self.add_rule(self.publish)
        self.add_rule(self.like)
        self.add_rule(self.getCurrentSurveyId)
        self.add_rule(self.setInfo)
        self.add_rule(self.getInfo)
        self.add_rule(self.setAnswer)
        self.add_rule(self.getAnswer)
        self.add_rule(self.getInfos, methods=['POST', 'GET'])
        self.add_rule(self.getImage, methods=['POST', 'GET'])

        self.app_config = config
        db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.security = Security()
        self.filesender = FileSender()
        self.requester = Requester(self.db)

        self.form_checker = FormChecker()
        self.error = Error()

    def create(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['name', 'description'])

        if formation == 'ok':
            
            user_id = self.requester.get_id()
            create_time = str(datetime.datetime.utcnow()) + ' UTC'
            secret_code = self.security.gen_key(64)
            is_published = 0
            
            c = self.db('INSERT INTO surveys(name, description, create_time, user_id, is_published, secret_code) \
                     VALUES(?,?,?,?,?,?)', (data['name'], data['description'], create_time, user_id, is_published, secret_code))

            current_survey_id = c.lastrowid()

            c.close()

            self.db('UPDATE users SET current_survey_id=? WHERE id=?',
                    (current_survey_id, user_id)).close()

            return self.response.send_json({'response': True})

        else:

            return self.response.send_json({'response': {'error': formation}})

    def getImage(self):
        survey_id = self.request.get_arg('survey_id')
        data = {'survey_id': survey_id}
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':
            image = self.__get_image(data['survey_id'])
            return self.filesender.send_byte_photo(image)

        else:
            return self.response.send_json({'response': {'error': formation}})


    def addQuestion(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['question_text', 'answer_type', 'answers'])

        if formation == 'ok':            

            user_id = self.requester.get_id()
            current_survey_id = self.__current_survey_id(user_id)

            if current_survey_id:

                current_survey_id = current_survey_id['current_survey_id']
        
                if self.__is_user_owner(current_survey_id):

                    c = self.db('INSERT INTO questions(question_text, answer_type, survey_id) \
                             VALUES(?,?,?)', (data['question_text'], data['answer_type'], current_survey_id))
                    
                    question_id = c.lastrowid()
                    c.close()

                    for answer in data['answers']:
                        self.db('INSERT INTO answer_options(answer_text, question_id) \
                                 VALUES(?,?)', (answer, question_id)).close()

                    return self.response.send_json({'response': True})

                else:
                    return self.response.send_json({'response': {'error': self.error(0)}})

            else:
                return self.response.send_json({'response': {'error': self.error(4)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getQuestions(self):

        data = self.request.get_json()
        print(data)
        formation = self.form_checker.is_formated(data, ['survey_id'])
        if formation == 'ok':

            survey = self.__get_survey(data['survey_id'])
            questions = self.__get_full_questions(data['survey_id'])

            if survey['is_published'] == 1:

                if survey['visability'] == 1:

                    formation = self.form_checker.is_formated(data, ['secret_code'])
                    if formation == 'ok':

                        if survey['secret_code'] == data['secret_code']:
                            return self.response.send_json({'response': questions})

                        else:
                            return self.response.send_json({'response': {'error': self.error(1)}})

                    else:
                        return self.response.send_json({'response': {'error': formation}})

                else:
                    return self.response.send_json({'response': questions})

            elif survey['is_published'] == 0 and self.__is_user_owner(data['survey_id']):

                return self.response.send_json({'response': questions})

            else:
                return self.response.send_json({'response': {'error': self.error(2)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def publish(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['visability', 'author'])

        if formation == 'ok':    

            user_id = self.requester.get_id()
            current_survey_id = self.__current_survey_id(user_id)

            if current_survey_id:
            
                current_survey_id = current_survey_id['current_survey_id']

                if self.__is_user_owner(current_survey_id):


                    publish_time = str(datetime.datetime.utcnow()) + ' UTC'
                    is_published = 1
                    questions = self.__get_questions(current_survey_id)

                    if len(questions) >= 2:

                        self.db('UPDATE users SET current_survey_id=? WHERE id=?',
                                (None, user_id,)).close()

                        self.db('UPDATE surveys SET author=?, visability=?, is_published=?, publish_time=? WHERE id=?',
                                (data['author'], data['visability'], is_published, publish_time, current_survey_id)).close()

                        return self.response.send_json({'response': True})
                    
                    else:
                        return self.response.send_json({'response': {'error': self.error(3)}})

                else:
                    return self.response.send_json({'response': {'error': self.error(0)}})
            else:
                return self.response.send_json({'response': {'error': self.error(4)}})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def getInfos(self):

        surveys = self.__get_surveys()

        for i, survey in enumerate(surveys):

            likes = len(self.db('SELECT * FROM likes WHERE post_id=? and post_type=0', (survey['id'],)).all())
            completions = len(self.db('SELECT * FROM completions WHERE post_id=? and post_type=0', (survey['id'],)).all())

            survey = {
                'id': survey['id'],
                'name': survey['name'],
                'description': survey['description'],
                'author': survey['author'],
                'num_likes': likes,
                'num_completed': completions,
            }

            surveys[i] = survey

        
        return self.response.send_json({'response': surveys})


    def setInfo(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['name', 'description'])

        if formation == 'ok':      
            user_id = self.requester.get_id()
            current_survey_id = self.__current_survey_id(user_id)

            if current_survey_id:
            
                current_survey_id = current_survey_id['current_survey_id']

                if self.__is_user_owner(current_survey_id):

                    self.db('UPDATE surveys SET name=?, description=? WHERE id=?',
                            (data['name'], data['description'], current_survey_id)).close()

                    return self.response.send_json({'response': True})

                else:
                    return self.response.send_json({'response': {'error': self.error(0)}})
            else:
                return self.response.send_json({'response': {'error': self.error(4)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getInfo(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id', 'secret_code'])

        if formation == 'ok':            

            survey = self.db('SELECT * FROM surveys WHERE id=?', (data['survey_id'],)).one()

            if survey['visability'] == 1:

                if survey['secret_code'] == data['secret_code']:
                    
                    survey = {
                        'name': survey['name'],
                        'description': survey['description'],
                        'author': survey['author'],
                    }

                    return self.response.send_json({'response': survey})
                
                else:
                    return self.response.send_json({'response': {'error': self.error(1)}})

            else:
                return self.response.send_json({'response': survey})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def like(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':        

            survey = self.__get_survey(data['survey_id'])

            if survey['is_published'] == 1:

                if survey['visability'] == 1:

                    if survey['secret_code'] == data['secret_code']:
                        self.__like(data['survey_id'])
                
                        return self.response.send_json({'response': True})
                    
                    else:
                        return self.response.send_json({'response': {'error': self.error(1)}})

                else:
                    self.__like(data['survey_id'])
                    return self.response.send_json({'response': True})
            else:
                return self.response.send_json({'response': {'error': self.error(2)}})


        else:
            return self.response.send_json({'response': {'error': formation}})

    def __like(self, survey_id):

        user_id = self.requester.get_id()
        create_time = str(datetime.datetime.utcnow()) + ' UTC'
        post_type = 0

        is_already_like = self.db('SELECT * FROM likes WHERE post_id=? and post_type=0 and user_id=?', (data['survey_id'], user_id)).one()

        if not is_already_like:
            self.db('INSERT INTO likes(create_time, post_type, post_id, user_id) \
                     VALUES(?,?,?,?)', (create_time, post_type, data['survey_id'], user_id)).close()

        else:
            self.db('DELETE FROM likes WHERE post_id=? and post_type=0 and user_id=?', (data['survey_id'], user_id)).close()

    def getAnswer(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['question_id, secret_code'])


        if formation == 'ok':        

            user_id = self.requester.get_id()
            survey = self.__get_survey(data['survey_id'])

            if survey['visability'] == 1:

                if survey['secret_code'] == data['secret_code']:
                    self.__set_answer(answer_id, user_id)
            
                    return self.response.send_json({'response': True})
                
                else:
                    return self.response.send_json({'response': {'error': self.error(1)}})

            else:
                self.__set_answer(answer_id, user_id)
                return self.response.send_json({'response': True})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def setAnswer(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['answer_id, secret_code'])


        if formation == 'ok':        

            user_id = self.requester.get_id()
            survey_id = self.__get_survey_id_by_answer_id(data['answer_id'])
            survey = self.__get_survey(survey_id)

            if survey['visability'] == 1:

                if survey['secret_code'] == data['secret_code']:
                    self.__set_answer(answer_id, user_id)
            
                    return self.response.send_json({'response': True})
                
                else:
                    return self.response.send_json({'response': {'error': self.error(1)}})

            else:
                self.__set_answer(answer_id, user_id)
                return self.response.send_json({'response': True})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def __get_survey_id_by_answer_id(answer_id):


    def __set_answer(self, answer_option_id, user_id):

        self.db('INSERT INTO likes(answer_option_id, user_id) \
                 VALUES(?,?)', (answer_option_id, user_id)).close()

    def getAnswers(self):

        surveys = self.__get_surveys()

        for i, survey in enumerate(surveys):

            likes = len(self.db('SELECT * FROM likes WHERE post_id=? and post_type=0', (survey['id'],)).all())
            completions = len(self.db('SELECT * FROM completions WHERE post_id=? and post_type=0', (survey['id'],)).all())

            survey = {
                'id': survey['id'],
                'name': survey['name'],
                'description': survey['description'],
                'author': survey['author'],
                'num_likes': likes,
                'num_completed': completions,
            }

            surveys[i] = survey

        
        return self.response.send_json({'response': surveys})

    def getCurrentSurveyId(self):
        user_id = self.requester.get_id()
        current_survey_id = self.__current_survey_id(user_id)

        if current_survey_id:
            return self.response.send_json({'response': {'id': current_survey_id['current_survey_id']}})
 
        return self.response.send_json({'response': False})


    def __current_survey_id(self, user_id):

        return self.db('SELECT current_survey_id FROM users WHERE id=?', (user_id,)).one()

    def __get_image(self, survey_id):

        survey = self.db('SELECT image FROM surveys WHERE id=?', (survey_id,)).one()

        return survey['image']

    def __get_full_questions(self, survey_id):
        full_questions = self.__get_questions(survey_id)
                    
        for i, question in enumerate(full_questions):

            question = filter_dict(question, ['id', 'question_text', 'answer_type'])

            answers = self.__get_answers(question['id'])
            question['answers'] = [a['answer_text'] for a in answers]
            
            full_questions[i] = question

        return full_questions

    def __get_survey(self, survey_id):

        survey = self.db('SELECT * FROM surveys WHERE id=?', (survey_id,)).one()

        return survey

    def __get_surveys(self):

        surveys = self.db('SELECT * FROM surveys WHERE visability=0 and is_published=1').all()

        return surveys


    def __get_answers(self, question_id):

        answers = self.db('SELECT * FROM answer_options WHERE question_id=?', (question_id,)).all()

        return answers

    def __get_questions(self, survey_id):
        
        questions = self.db('SELECT * FROM questions WHERE survey_id=?', (survey_id,)).all()

        return questions

    def __is_user_owner(self, survey_id):
        user_id = self.requester.get_id()

        survey_user_id = self.db('SELECT user_id FROM surveys WHERE id=?', (survey_id,)).one()

        if survey_user_id['user_id'] == user_id:
            
            return True

        return False


class Error:
    def __init__(self):
        self.errors_list = ['access denied', 
                            'wrong secret_code',
                            'no survey',
                            'not enaught questions',
                            'create survey at first']
    
    
    def __call__(self, num):
        return self.errors_list[num]


class Form:
    def __init__(self, name, data_type, min_len=None, max_len=None, acceptable_symbols=None):
        self.name = name

        self.data_type = data_type
        self.min_len = min_len
        self.max_len = max_len

        default_as = 'qwertyuiopasdfghjklmnbvcxzёйцукенгшщзхъэждлорпавыфячсмитьбю'
        default_as += default_as.upper()
        default_as += '1234567890.,,.?!- '

        acceptable_symbols = acceptable_symbols if acceptable_symbols \
                                               else default_as

        self.acceptable_symbols = acceptable_symbols

        self.check_list = [self.check_type,
                           self.check_len,
                           self.check_symbols]

    def __call__(self, data):
        for check_foo in self.check_list:
            reply = check_foo(data)

            if reply:
                return reply

        return 'ok'

    def add_check(self, check_foo):
        self.check_list.append(check_foo)

    def check_type(self, data):
        if type(data) != self.data_type:
            return self.name + ' wrong type'

    def check_len(self, data):

        if self.max_len or self.min_len:

            if type(data) == str:

                if len(data) < self.min_len:
                    return self.name + ' too small'

                if len(data) > self.max_len:
                    return self.name + ' too big'

            if type(data) == int:

                if data < self.min_len:
                    return self.name + ' too small'

                if data > self.max_len:
                    return self.name + ' too big'

    def check_symbols(self, data):
        if type(data) == str:
            for symbol in data:
                
                is_acceptable = False

                for asymbol in self.acceptable_symbols:
                    if symbol == asymbol:
                        is_acceptable = True

                if not is_acceptable:
                    return f'not acceptable symbol in {self.name}: {symbol}'

class AnswersForm(Form):
    def __init__(self, name, data_type=None, min_len=None, max_len=None, min_n=None, max_n=None, acceptable_symbols=None):

        self.min_n = min_n
        self.max_n = max_n

        super().__init__(name, data_type, min_len, max_len, acceptable_symbols)

        self.check_list = [self.check_answers]

    def check_answers(self, answers):
        answers_check_list = [
            self.check_type,
            self.check_len,
            self.check_symbols,
        ]

        if len(answers) < self.min_n:
            return self.name + ' number too small'
        
        if len(answers) > self.max_n:
            return self.name + ' number too big'

        for answer in answers:
            for check in answers_check_list:
                reply = check(answer)

                if reply:
                    return reply

        return 'ok'

class FormChecker:
    def __init__(self):
        self.forms_dict = self.create_forms_dict(
            Form('name', str, 4, 32),
            Form('description', str, 4, 128),

            Form('survey_id', int),
            Form('question_text', str, 4, 128),
            Form('answer_type', int, 0, 1),
            AnswersForm('answers', str, 1, 64, 2, 10),

            Form('secret_code', str),

            Form('visability', int, 0, 1),
            Form('author', str, 2, 16),
        )

    def create_forms_dict(self, *forms):
        forms_dict = {}

        for form in forms:
            forms_dict[form.name] = form

        return forms_dict

    def is_formated(self, data, args_names_list):

        for name in args_names_list:

            try:
                user_data = data[name]

                try:
                    replay = self.forms_dict[name](user_data)
                        
                    if replay != 'ok':
                        return replay

                except KeyError:
                    return 'not reg form: ' + name

            except KeyError:
                return 'missing form: ' + name

        return replay

def filter_dict(d, pass_list):
    new_d = {}

    for e in pass_list:
        new_d[e] = d[e]

    return new_d
Exemple #13
0
class Tests(Module):
    def __init__(self):
        super().__init__('t')

        self.add_rule(self.create)
        self.add_rule(self.getCurrentTestId)
        self.add_rule(self.setInfo)

        self.add_rule(self.getInfos)

        self.add_rule(self.getAccessUrl)
        self.add_rule(self.addAccess, methods=['POST', 'GET'])

        self.add_rule(self.publish)
        self.add_rule(self.setSurveyId)
        self.add_rule(self.getSurveyId)
        self.add_rule(self.setKeyQuestionId)
        self.add_rule(self.setAnswer)
        self.add_rule(self.getQuestions)

        self.add_rule(self.getInfo)
        self.add_rule(self.complete)

        self.add_rule(self.predict)

        self.add_rule(self.getLastAnswer)


        self.app_config = config
        db_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_NAME'])
        tables_path = os.path.join(config['DATABASE_PATH'], config['DATABASE_TABLES'])

        self.db = Database(db_path)
        self.db.execute_file(tables_path)

        self.request = Request()
        self.response = Response()
        self.requester = Requester(self.db)
        
        self.security = Security()
        self.filesender = FileSender()

        self.form_checker = FormChecker()
        self.error = Error()


    def __train_nn(self, test_id):
        test = self.__get_test(test_id)

        survey_id = test['survey_id']
        questions = self.__get_full_questions(survey_id)

        users = self.db('SELECT user_id FROM completions WHERE post_type=0 AND post_id=?', (survey_id,)).all()

        x_list = []
        y_list = []

        key_question_id = test['key_question_id']
        print(questions)
        print(key_question_id)

        for user in users:
            xx_list = []
            yy_list = []
            user_id =  user['user_id']
            print(user, 'user')
            for question in questions:
                print(question['id'], key_question_id)
                if question['id'] == key_question_id:
                    for answer in question['answers']:
                        answer_option_id  = answer['id']
                        answer = self.db('SELECT * FROM survey_answers WHERE answer_option_id=? AND user_id=?', (answer_option_id, user_id)).one()

                        if answer:
                            yy_list.append(1)

                        else:
                            yy_list.append(0)
                    
                    k_q_type = question['answer_type']
                    k_q_len = len(question['answers'])

                else:
                    for answer in question['answers']:

                        answer_option_id  = answer['id']
                        answer = self.db('SELECT * FROM survey_answers WHERE answer_option_id=? AND user_id=?', (answer_option_id, user_id)).one()
                        
                        if answer:
                            xx_list.append(1)

                        else:
                            xx_list.append(0)

            y_list.append(yy_list)
            x_list.append(xx_list)

        print(x_list)
        print(y_list)

        x = np.array(x_list)
        y = np.array(y_list)

        print(len(users))
        print(k_q_len)

        if k_q_type:
            model = Model(
                Dense(len(users)),
                Sigmoid(),
                Dense(k_q_len),
                Sigmoid()
            )(Adam(0.05))
        else:
            model = Model(
                Dense(len(users)),
                Sigmoid(),
                Dense(k_q_len),
                Softmax()
            )(Adam(0.05))

        for eph in range(200):
            model.train(x, y)

        kk = pickle.dumps(model, True)
        data = self.db.Binary(kk)

        self.db('INSERT INTO n_networks(weights ,test_id) VALUES(?,?)', (data, test_id)).close()



    def predict(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['test_id'])

        if formation == 'ok':   

            test_id = data['test_id']

            if self.__is_test_accessable(test_id):
                weights = pickle.loads(self.db('SELECT * FROM n_networks WHERE test_id=?', (test_id,)).one()['weights'])


                model = weights

                test = self.__get_test(test_id)

                survey_id = test['survey_id']

                questions = self.__get_full_questions(survey_id)

                user_id = self.__get_user_id()

                key_question_id = test['key_question_id']

                
                x_list = []

                for question in questions:
                    for answer in question['answers']:
                        answer_option_id  = answer['id']
                        if not (question['id'] == key_question_id):
                            answer = self.db('SELECT * FROM test_answers WHERE answer_option_id=? AND user_id=?', (answer_option_id, user_id)).one()
                        
                            if answer:
                                x_list.append(1)

                            else:
                                x_list.append(0)
                        else:
                            kq = question
                print(x_list, 'x_list')

                x = np.array([x_list])


                pr = model.predict(x)

                inex = np.argmax(pr)


                return self.response.send_json({'response': kq['answers'][inex]['answer_text']})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:

            return self.response.send_json({'response': {'error': formation}})

    def create(self):
        '''
            no if
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['name', 'description'])

        if formation == 'ok':
            
            name = data['name']
            description = data['description']

            is_published = 0
            user_id = self.__get_user_id()
            create_time = self.__get_time()
            secret_code = self.security.gen_key(64)

            c = self.db('INSERT INTO tests(name, description, create_time, user_id, is_published, secret_code) \
                     VALUES(?,?,?,?,?,?)', (name, description, create_time, user_id, is_published, secret_code))

            current_test_id = c.lastrowid()
            c.close()

            self.db('UPDATE users SET current_test_id=? WHERE id=?',
                    (current_test_id, user_id)).close()

            return self.response.send_json({'response': True})

        else:

            return self.response.send_json({'response': {'error': formation}})

    def getCurrentTestId(self):
        '''
            if current_test_id exist
        '''
        test_id = self.__get_current_test_id()

        return self.response.send_json({'response': test_id})




    def setInfo(self):
        '''
            if current_test_id exist
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['name', 'description'])

        if formation == 'ok':
            test_id = self.__get_current_test_id()

            if test_id:

                name = data['name']
                description = data['description']

                self.db('UPDATE tests SET name=?, description=? WHERE id=?',
                        (name, description, test_id)).close()

                return self.response.send_json({'response': True})

            else:
                return self.response.send_json({'response': {'error': self.error(6)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def setAnswer(self):
        '''
            if survey_accessable
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['answer_id', 'is_answer'])

        if formation == 'ok':
            
            is_answer = data['is_answer']
            answer_option_id = data['answer_id']

            survey_id = self.__get_survey_id_by_answer_id(answer_option_id)

            test_id = self.__get_test_id_by_survey_id(survey_id)

            if self.__is_test_accessable(test_id):

                user_id = self.__get_user_id()
                test_id = self.__get_test_id_by_survey_id(survey_id)

                if is_answer:

                    self.db('INSERT INTO test_answers(answer_option_id, user_id) \
                             VALUES(?,?)', (answer_option_id, user_id)).close()

                    question_id = self.__get_question_id_by_answer_id(answer_option_id)
                    old_question_id = self.db('SELECT * FROM last_question_test WHERE user_id=? AND  test_id=? ', (user_id, test_id)).one()

                    if old_question_id:
                        self.db('UPDATE last_question_test SET question_id=? WHERE user_id=? AND  test_id=?', (question_id, user_id, test_id)).close()

                    else:
                        self.db('INSERT INTO last_question_test(user_id, test_id, question_id) \
                                 VALUES(?,?,?)', (user_id, test_id, question_id)).close()
                    
                    return self.response.send_json({'response': True})

                else:

                    self.db('DELETE FROM test_answers WHERE answer_option_id=? AND user_id=?',
                            (answer_option_id, user_id)).close()

                    return self.response.send_json({'response': True})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:
            return self.response.send_json({'response': {'error': formation}})



    def complete(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['test_id'])

        if formation == 'ok':

            test_id = data['test_id']

            if self.__is_test_accessable(test_id):
                is_complete = True
                survey_id = self.__get_test(test_id)['survey_id']

                questions = self.__get_full_questions(survey_id)

                user_id = self.__get_user_id()

                test = self.__get_test(test_id)
                key_question_id = test['key_question_id']

                for question in questions:
                    is_answer = False

                    for a in question['answers']:
                        answer_option_id  = a['id']

                        if not (question['id'] == key_question_id):
                            answer = self.db('SELECT * FROM test_answers WHERE answer_option_id=? AND user_id=?', (answer_option_id, user_id)).one()
                            
                            if answer:
                                is_answer = True
                                break
                        else:
                            is_answer = True
                            break

                    if not is_answer:
                        is_complete = False
                        break 

                
                x_list = []


                if is_complete:


                    self.db('DELETE FROM last_question_test WHERE user_id=? AND  test_id=?', (user_id, test_id)).close()

                    complete_time = self.__get_time()

                    post_type = 1
                    post_id = test_id

                    self.db('INSERT INTO completions(complete_time, post_type, post_id, user_id) \
                                VALUES(?,?,?,?)', (complete_time, post_type, post_id, user_id)).close()

                    return self.response.send_json({'response': True})

                else:
                    return self.response.send_json({'response': {'error': self.error(5)}})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getAccessUrl(self):
        test_id = self.__get_current_test_id()

        if test_id:

            test = self.__get_test(test_id)

            url = 'https://grafstor.xyz/nt/t/addAccess?id={0}&sc={1}'.format(test_id, test['secret_code'])

            return self.response.send_json({'response': url})

        else:
            return self.response.send_json({'response': {'error': self.error(6)}})

    def addAccess(self):
        test_id = self.request.get_arg('id')
        secret_code = self.request.get_arg('sc')

        data = {
            'test_id': test_id,
            'secret_code': secret_code,
        }

        formation = self.form_checker.is_formated(data, ['test_id', 'secret_code'])

        if formation == 'ok':

            test_id = data['test_id']
            secret_code = data['secret_code']

            user_id = self.__get_user_id()

            test = self.__get_test(test_id)

            if test['secret_code'] == secret_code:

                self.db('INSERT INTO tests_accesses(user_id, test_id) \
                         VALUES(?,?)', (user_id, test_id)).close()

        else:
            return self.response.send_json({'response': {'error': formation}})


    def getLastAnswer(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['test_id'])

        if formation == 'ok':

            test_id = data['test_id']

            if self.__is_test_accessable(test_id):

                user_id = self.__get_user_id()

                question_id = self.db('SELECT * FROM last_question_test WHERE user_id=? AND  test_id=? ', (user_id, test_id)).one()

                if question_id:

                    return self.response.send_json({'response': question_id['question_id']})

                else:
                    return self.response.send_json({'response': False})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def getInfos(self):
        '''
            if post_type = 1
        '''
        tests = self.__get_tests()

        for i, test in enumerate(tests):

            likes = self.db('SELECT * FROM likes WHERE post_id=? and post_type=1', (test['id'],)).all()
            likes_num = len(likes)

            completions = self.db('SELECT * FROM completions WHERE post_id=? and post_type=1', (test['id'],)).all()
            completions_num = len(completions)

            test = {
                'id': test['id'],
                'name': test['name'],
                'description': test['description'],
                'author': test['author'],
                'num_likes': likes_num,
                'num_completed': completions_num,
            }

            tests[i] = test
        
        return self.response.send_json({'response': tests})


    def setSurveyId(self):
        '''
            if current_test_id exist
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':
            test_id = self.__get_current_test_id()

            if test_id:

                survey_id = data['survey_id']

                self.db('UPDATE tests SET survey_id=? WHERE id=?',
                        (survey_id, test_id)).close()

                return self.response.send_json({'response': True})

            else:
                return self.response.send_json({'response': {'error': self.error(6)}})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def getSurveyId(self):

        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['test_id'])

        if formation == 'ok':
            test_id = data['test_id']
            if test_id:

                if self.__is_test_accessable(test_id):

                    test = self.__get_test(test_id)

                    survey_id = test['survey_id']

                    return self.response.send_json({'response': survey_id})

                else:
                    return self.response.send_json({'response': {'error': self.error(0)}})

            else:
                return self.response.send_json({'response': {'error': self.error(6)}})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def setKeyQuestionId(self):
        '''
            if current_test_id exist
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['question_id'])

        if formation == 'ok':
            test_id = self.__get_current_test_id()

            if test_id:

                question_id = data['question_id']
                question_survey_id = self.__get_survey_id_by_question_id(question_id)

                test_survey_id = self.__get_test(test_id)['survey_id']

                key_question_id = question_id

                if question_survey_id == test_survey_id:

                    self.db('UPDATE tests SET key_question_id=? WHERE id=?',
                            (key_question_id, test_id)).close()

                    return self.response.send_json({'response': True})

                else:

                    return self.response.send_json({'response': {'error': self.error(7)}})

            else:
                return self.response.send_json({'response': {'error': self.error(6)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getQuestions(self):
        '''
            if survey_accessable
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['survey_id'])

        if formation == 'ok':

            survey_id = data['survey_id']

            test_id = self.__get_test_id_by_survey_id(survey_id)
            test = self.__get_test(test_id)

            key_question_id = test['key_question_id']

            if self.__is_survey_accessable(survey_id):

                
                questions = self.__get_full_questions(survey_id)

                for i, q in enumerate(questions):
                    if q['id'] == key_question_id:
                        del questions[i]

                return self.response.send_json({'response': questions})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:
            return self.response.send_json({'response': {'error': formation}})


    def publish(self):
        '''
            if current_survey_id exist
            if questions > 1
        '''
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['visability', 'author'])

        if formation == 'ok':    

            test_id = self.__get_current_test_id()

            if test_id:

                author = data['author']
                visability = data['visability']

                is_published = 1
                publish_time = self.__get_time()

                test = self.__get_test(test_id)

                survey_id = test['survey_id']

                if survey_id:

                    key_question_id = test['key_question_id']

                    if key_question_id:


                        user_id = self.__get_user_id()

                        self.db('UPDATE users SET current_test_id=? WHERE id=?',
                                (None, test_id,)).close()

                        self.db('UPDATE tests SET author=?, visability=?, is_published=?, publish_time=? WHERE id=?',
                                (author, visability, is_published, publish_time, test_id)).close()

                        self.__train_nn(test_id)

                        return self.response.send_json({'response': True})

                    else:
                        return self.response.send_json({'response': {'error': self.error(9)}})

                else:
                    return self.response.send_json({'response': {'error': self.error(8)}})

            else:
                return self.response.send_json({'response': {'error': self.error(10)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def getInfo(self):
        data = self.request.get_json()
        formation = self.form_checker.is_formated(data, ['test_id'])

        if formation == 'ok':               

            test_id = data['test_id']

            if self.__is_test_accessable(test_id):

                test = self.__get_test(test_id)

                test = self.__filter_dict(test, ['name', 'description', 'author'])

                return self.response.send_json({'response': test})

            else:
                return self.response.send_json({'response': {'error': self.error(0)}})

        else:
            return self.response.send_json({'response': {'error': formation}})

    def __is_user_accessed(self, test_id):

        user_id = self.__get_user_id()

        access = self.db('SELECT * FROM tests_accesses WHERE user_id=? AND test_id=?', (user_id, test_id,)).one()

        if access:

            return True

        return False

    def __get_survey_id_by_answer_id(self, answer_id):

        question_id = self.__get_question_id_by_answer_id(answer_id)

        survey_id = self.__get_survey_id_by_question_id(question_id)
        
        return survey_id


    def __is_user_owner(self, test_id):
        user_id = self.__get_user_id()

        test_user_id = self.db('SELECT user_id FROM tests WHERE id=?', (test_id,)).one()

        if test_user_id['user_id'] == user_id:
            
            return True

        return False

    def __get_user_id(self):

        user_id = self.requester.get_id()
        
        return user_id

    def __filter_dict(self, d, pass_list):
        new_d = {}

        for e in pass_list:
            new_d[e] = d[e]

        return new_d

    def __is_test_accessable(self, test_id):
        test = self.__get_test(test_id)

        if test['is_published'] == 1:

            if test['visability'] == 1:

                if self.__is_user_accessed(test_id):

                    return True

                else:
                    return False

            else:
                return True
        
        elif test['is_published'] == 0 and self.__is_user_owner(test_id):

            return True

        else:
            return False

    def __get_time(self):

        return str(datetime.datetime.utcnow()) + ' UTC'


    def __get_survey_id_by_question_id(self, question_id):

        survey_id = self.db('SELECT survey_id FROM questions WHERE id=?', 
                        (question_id,)).one()['survey_id']

        return survey_id

    def __get_tests(self):

        tests = self.db('SELECT * FROM tests WHERE visability=0 and is_published=1').all()

        return tests


    def __get_test_id_by_survey_id(self, survey_id):
        tests = self.__get_tests()

        for test in tests:

            if test['survey_id'] == survey_id:

                return test['id']


    def __get_test(self, test_id):

        test = self.db('SELECT * FROM tests WHERE id=?', (test_id,)).one()

        return test

    def __get_survey_id_by_question_id(self, question_id):

        survey_id = self.db('SELECT survey_id FROM questions WHERE id=?', 
                        (question_id,)).one()['survey_id']

        return survey_id

    def __get_question_id_by_answer_id(self, answer_id):

        question_id = self.db('SELECT question_id FROM answer_options WHERE id=?', 
                                (answer_id,)).one()['question_id']

        return question_id



    def __get_current_test_id(self):
        
        user_id = self.__get_user_id()

        current_test_id = self.db('SELECT current_test_id FROM users WHERE id=?', (user_id,)).one()

        if current_test_id:

            return current_test_id['current_test_id']

        return False
    def __get_answers(self, question_id):

        answers = self.db('SELECT * FROM answer_options WHERE question_id=?', (question_id,)).all()

        return answers
    def __get_full_questions(self, survey_id):
        full_questions = self.__get_questions(survey_id)
                    
        for i, question in enumerate(full_questions):

            question = self.__filter_dict(question, ['id', 'question_text', 'answer_type'])

            answers = self.__get_answers(question['id'])
            question['answers'] = [self.__filter_dict(answer, ['id', 'answer_text']) for answer in answers]
            
            full_questions[i] = question

        return full_questions

    def __get_questions(self, survey_id):
        
        questions = self.db('SELECT * FROM questions WHERE survey_id=?', (survey_id,)).all()

        return questions

    def __get_survey(self, survey_id):

        survey = self.db('SELECT * FROM surveys WHERE id=?', (survey_id,)).one()

        return survey

    def __is_survey_accessable(self, survey_id):
        survey = self.__get_survey(survey_id)

        if survey['is_published'] == 1:

            if survey['visability'] == 1:

                if self.__is_user_accessed_survey(survey_id):

                    return True

                else:
                    return False

            else:
                return True
        
        elif survey['is_published'] == 0 and self.__is_user_owner_survey(survey_id):

            return True

        else:
            return False


    def __is_user_accessed_survey(self, survey_id):

        user_id = self.__get_user_id()

        access = self.db('SELECT * FROM surveys_accesses WHERE user_id=? AND survey_id=?', (user_id, survey_id,)).one()

        if access:

            return True

        return False

    def __is_user_owner_survey(self, survey_id):
        user_id = self.__get_user_id()

        survey_user_id = self.db('SELECT user_id FROM surveys WHERE id=?', (survey_id,)).one()

        if survey_user_id['user_id'] == user_id:
            
            return True

        return False
class Sender(Module):
    def __init__(self):
        super().__init__()

        self.add_rule(self.main_page, url='/nt', methods=['GET'])
        self.add_rule(self.favicon, url='/favicon.ico', methods=['GET'])
        self.add_rule(self.style, methods=['GET', 'POST'])
        self.add_rule(self.script, methods=['GET', 'POST'])
        self.add_rule(self.svg, methods=['GET', 'POST'])
        self.add_rule(self.photo, methods=['GET', 'POST'])

        self.add_rule(self.templates)
        self.add_rule(self.svgs)

        self.app_config = config

        self.response = Response()
        self.security = Security()
        self.filesender = FileSender()
        self.request = Request()

    def main_page(self):
        return self.filesender.send_file(self.app_config['PUBLIC_PATH'],
                                         self.app_config['TEMPLATES_PATH'],
                                         'index.html')

    def favicon(self):
        return self.filesender.send_file(self.app_config['PUBLIC_PATH'],
                                         self.app_config['STATIC_PATH'],
                                         self.app_config['SVGS_PATH'],
                                         'logo3.svg')

    def style(self):
        file_name = self.request.get_arg('filename')
        file_name = self.security.secure_filename(file_name)

        return self.filesender.send_file(self.app_config['PUBLIC_PATH'],
                                         self.app_config['STATIC_PATH'],
                                         self.app_config['STYLES_PATH'],
                                         file_name)

    def script(self):
        file_name = self.request.get_arg('filename')
        file_name = self.security.secure_filename(file_name)

        return self.filesender.send_file(self.app_config['PUBLIC_PATH'],
                                         self.app_config['STATIC_PATH'],
                                         self.app_config['SCRIPTS_PATH'],
                                         file_name)

    def svg(self):
        file_name = self.request.get_arg('filename')
        file_name = self.security.secure_filename(file_name)

        return self.filesender.send_file(self.app_config['PUBLIC_PATH'],
                                         self.app_config['STATIC_PATH'],
                                         self.app_config['SVGS_PATH'],
                                         file_name)


    def templates(self):
        templates_dict = self.filesender.send_files_dict(self.app_config['PUBLIC_PATH'],
                                                         self.app_config['TEMPLATES_PATH'])
        
        del templates_dict['index']

        return self.response.send_json({'response': templates_dict})

    def svgs(self):
        svgs_dict = self.filesender.send_files_dict(self.app_config['PUBLIC_PATH'],
                                                    self.app_config['STATIC_PATH'],
                                                    self.app_config['SVGS_PATH'])
        
        return self.response.send_json({'response': svgs_dict})

    def photo(self):
        file_name = self.request.get_arg('filename')
        file_name = self.security.secure_filename(file_name)

        return self.filesender.send_photo(self.app_config['PUBLIC_PATH'],
                                          self.app_config['STATIC_PATH'],
                                          self.app_config['PHOTOS_PATH'],
                                          file_name)