Example #1
0
def handle_assign_admin_to_project(call, tg_id, project_id):
	session = Session()
	selected_user = session.query(User).filter(User.tg_id == tg_id).first()
	selected_project = session.query(Questionnaire).filter(Questionnaire.id == project_id).first()
	if selected_user in selected_project.project_admins:
		selected_project.project_admins.remove(selected_user)
		bot.answer_callback_query(call.id, f'{selected_user} is NOT an admin in {selected_project}')
		bot.send_message(call.message.chat.id, f'{selected_user} is NOT an admin in {selected_project}')
	else:
		selected_project.project_admins.append(selected_user)
		bot.answer_callback_query(call.id, f'{selected_user} IS an admin in {selected_project}')
		bot.send_message(call.message.chat.id, f'{selected_user} IS an admin in {selected_project}')
	session.add(selected_project)
	session.commit()
Example #2
0
def warn_admins(text, session=None):
	if not session:
		session = Session()
	admins = session.query(User).filter(User.is_admin).all()
	for user in admins:
		# bot.send_message(user.chat_id, text)
		bot.send_message(user.tg_id, text)
Example #3
0
def get_user(message, session=None):
	if not session:
		session = Session()
	user = session.query(User).filter(User.tg_id == message.from_user.id).first()
	if not user:
		user = create_user(message, session)
	return user
Example #4
0
def handle_project_edit(call, project_id):
	bot.answer_callback_query(call.id, f'Selected project #{project_id}')
	session = Session()
	user = get_user(call, session=session)
	selected_project = session.query(Questionnaire).filter(Questionnaire.id == project_id).first()
	if user.is_admin or user.is_root or user in selected_project.project_admins:
		list_display = lambda iterable: '[\n\t' + ",\n\t".join([repr(i) for i in iterable]) + '\n]'
		fields = {
			'name': selected_project.name,
			'description': selected_project.description,
			'version': selected_project.version,
			'is active': selected_project.is_active,
			'created by': repr(selected_project.created_by),
			'admins': list_display(selected_project.project_users),
			'interviewers': list_display(selected_project.project_admins),
		}

		markup = InlineKeyboardMarkup(row_width=2)
		btn_is_active = InlineKeyboardButton('Toggle: is active', callback_data=build_callback('toggle_is_active', project_id))
		markup.add(btn_is_active)
		btn_assign_users = InlineKeyboardButton(
			'Assign interviewers',
			callback_data=build_callback('assign_users', project_id)
		)
		markup.add(btn_assign_users)

		msg = []
		msg.append(f'Editing {repr(selected_project)}:')
		for k, v in fields.items():
			msg.append(f'{k}: {v}')
		bot.send_message(call.message.chat.id, '\n'.join(msg), reply_markup=markup)
Example #5
0
def _get_questionnaire(q_name,
                       q_version,
                       q_description,
                       session=None,
                       **kwargs):
    if not session:
        session = Session()
    quest = session.query(Questionnaire).filter(
        and_(Questionnaire.name == q_name,
             Questionnaire.version == q_version)).first()
    if not quest:
        quest = Questionnaire()
        quest.name = q_name
        quest.description = q_description
        quest.version = q_version
        creator = kwargs.get('created_by')
        if creator:
            quest.created_by = creator
            quest.project_users.append(creator)
            quest.project_admins.append(creator)

        quest.results_table_name = get_result_table_name(quest)
        session.add(quest)
        session.commit()
    return quest
Example #6
0
def handle_start_survey_answer(message, questionnaire_id):
	print('handle_start_survey_answer', questionnaire_id)
	if message.text == 'Да':
		session = Session()
		question = session.query(Question).filter(and_(Question.questionnaire_id == questionnaire_id, Question.step == 1)).first()
		handle_answer(message, question=question, flags={Flags.goto_start})
	else:
		handle_cancel(message)
Example #7
0
def handle_users(message):
	user = get_user(message)
	if user.is_admin or user.is_root:
		session = Session()
		users = session.query(User).all()
		bot.send_message(message.chat.id, '\n'.join([repr(i) for i in users]))
	else:
		bot.send_message(message.chat.id, repr(user))
Example #8
0
def handle_toggle_is_active(call, project_id):
	session = Session()
	selected_project = session.query(Questionnaire).filter(Questionnaire.id == project_id).first()
	selected_project.is_active = not selected_project.is_active
	session.add(selected_project)
	session.commit()
	msg = f'Selected project {selected_project} is {"active" if selected_project.is_active else "inactive"} now'
	bot.answer_callback_query(call.id, msg)
	bot.send_message(call.message.chat.id, msg)
Example #9
0
def handle_toggle_is_interviewer(call, tg_id):
	session = Session()
	selected_user = session.query(User).filter(User.tg_id == tg_id).first()
	selected_user.is_interviewer = not selected_user.is_interviewer
	session.add(selected_user)
	session.commit()
	msg = f'Selected user {selected_user} is {"" if selected_user.is_interviewer else " NOT"} an interviewer now'
	bot.answer_callback_query(call.id, msg)
	bot.send_message(call.message.chat.id, msg)
Example #10
0
def handle_start_survey(call, questionnaire_id):
	print('handle_start_survey', questionnaire_id)
	session = Session()
	name, description = session.query(Questionnaire.name, Questionnaire.description).filter(Questionnaire.id == questionnaire_id).first()
	markup = ReplyKeyboardMarkup(one_time_keyboard=True)
	buttons = (KeyboardButton(text='Да'), KeyboardButton(text='Нет'))
	markup.add(*buttons)
	msg = bot.send_message(call.message.chat.id, f'Начать опрос {name}?\n({description})', reply_markup=markup)
	bot.register_next_step_handler(msg, handle_start_survey_answer, questionnaire_id)
Example #11
0
def handle_save(question, message): #todo handle all saves to db
	print('handle_save', question.code)
	if not question.save_in_survey:
		return
	check_data(question, message)
	session = Session()
	try:
		response = question.get_response_object(message.from_user.id)
	except (DetachedInstanceError, ProgrammingError):
		question = session.query(Question).filter(Question.id == question.id).first()
		response = question.get_response_object(message.from_user.id)

	if question.type.code == QuestionTypes.categorical:
		code = None
		for cat in question.categories:
			if cat.text == message.text:
				code = cat.id
				break
		response.__setattr__(question.code, code)
		session.add(response)
		session.commit()
	elif question.type.code == QuestionTypes.location:
		response.__setattr__(f'{question.code}_latitude', message.location.latitude)
		response.__setattr__(f'{question.code}_longitude', message.location.longitude)
		session.add(response)
		session.commit()
	elif question.type.code == QuestionTypes.photo:
		file_info = bot.get_file(message.photo[-1].file_id)
		print('handle_save', 'photo', file_info)
		downloaded_file = bot.download_file(file_info.file_path)
		file_name = '{}_{}'.format(message.from_user.id, file_info.file_path.split('/')[-1])
		file_folder = Path(MEDIA_FOLDER, question.questionnaire.results_table_name)
		file_path = Path(file_folder, file_name)
		# file_path.mkdir(parents=True)
		try:
			with open(file_path, 'wb') as out:
				out.write(downloaded_file)
		except FileNotFoundError:
			file_folder.mkdir(parents=True)
			with open(file_path, 'wb') as out:
				out.write(downloaded_file)
		print('handle_save', 'file saved', file_path)
		print('handle_save', 'file saved relative', str(file_path.relative_to(ROOT_DIR)))
		response.__setattr__(question.code, str(file_path.relative_to(ROOT_DIR)))
		session.add(response)
		session.commit()
	elif question.type.code == QuestionTypes.timestamp:
		response.__setattr__(question.code, datetime.datetime.now())
		session.add(response)
		session.commit()
	elif question.type.code == QuestionTypes.text or question.type.code == QuestionTypes.integer:
		print('TEXT Q TYPE', message.content_type, message.content_type == 'text')
		response.__setattr__(question.code, message.text)
		session.add(response)
		session.commit()
	else:
		print('handle_save', 'QUESTION TYPE NOT HANDLED FOR SAVE', question.type)
Example #12
0
def handle_manage_users(message):
	user = get_user(message)
	if user.is_admin or user.is_root:
		markup = InlineKeyboardMarkup()
		session = Session()
		users = session.query(User).all()
		# u_list = '\n'.join([f'/{i.id}' for i in users])
		for i in users:
			btn = InlineKeyboardButton(repr(i), callback_data=build_callback('user_edit', i.tg_id))
			markup.add(btn)
		bot.send_message(message.chat.id, 'Выбери пользователя для редактирования:', reply_markup=markup)
	else:
		bot.send_message(message.chat.id, repr(user))
Example #13
0
def handle_assign_to_projects(call, tg_id):
	session = Session()
	projects = session.query(Questionnaire).all()
	markup = InlineKeyboardMarkup()
	for i in projects:
		btn_project = InlineKeyboardButton(
			f'{repr(i)} [tap to edit]',
			callback_data=build_callback('project_edit', i.id)
		)
		btn_interviewer = InlineKeyboardButton(
			'as interviewer',
			callback_data=build_callback('assign_user_to_project', tg_id, i.id)
		)
		btn_admin = InlineKeyboardButton(
			'as admin',
			callback_data=build_callback('assign_admin_to_project', tg_id, i.id)
		)
		markup.add(btn_project)
		markup.add(btn_interviewer, btn_admin)
	bot.send_message(call.message.chat.id, 'Select projects to toggle for assignment:', reply_markup=markup)
Example #14
0
def handle_user_edit(call, tg_id):
	bot.answer_callback_query(call.id, f'Selected user #{tg_id}')
	session = Session()
	user = get_user(call, session=session)
	selected_user = session.query(User).filter(User.tg_id == tg_id).first()
	if user.is_admin or user.is_root:
		list_display = lambda iterable: '[\n\t' + ",\n\t".join([repr(i) for i in iterable]) + '\n]'
		fields = {
			'telegram_id': selected_user.tg_id,
			'first_name': selected_user.first_name,
			'last_name': selected_user.last_name,
			'is admin': selected_user.is_admin,
			'is interviewer': selected_user.is_interviewer,
			'projects': list_display(selected_user.available_questionnaires),
			'admin_of': list_display(selected_user.admin_of_projects)
		}

		markup = InlineKeyboardMarkup(row_width=2)
		btn_is_admin = InlineKeyboardButton(
			'Toggle: is admin',
			callback_data=build_callback('toggle_is_admin', selected_user.tg_id)
		)
		btn_is_interviewer = InlineKeyboardButton(
			'Toggle: is interviewer',
			callback_data=build_callback('toggle_is_interviewer', selected_user.tg_id)
		)
		markup.add(btn_is_admin, btn_is_interviewer)
		btn_assign_to_projects = InlineKeyboardButton(
			'Assign to projects',
			callback_data=build_callback('assign_to_projects', selected_user.tg_id)
		)
		markup.add(btn_assign_to_projects)
		# btn_assign_admin = InlineKeyboardButton('Assign as admin', callback_data=build_callback('assign_admin', selected_user.tg_id))
		# markup.add(btn_assign_admin)

		msg = []
		msg.append(f'Editing {repr(selected_user)}:')
		for k, v in fields.items():
			msg.append(f'{k}: {v}')
		bot.send_message(call.message.chat.id, '\n'.join(msg), reply_markup=markup)
Example #15
0
def handle_assign_users(call, project_id):
	print('handle_assign_users', 'start', project_id)
	session = Session()
	users = session.query(User).all()
	markup = InlineKeyboardMarkup()
	for i in users:
		print(i)
		btn_user = InlineKeyboardButton(
			f'{repr(i)} [tap to edit]',
			callback_data=build_callback('user_edit', i.tg_id)
		)
		btn_interviewer = InlineKeyboardButton(
			'as interviewer',
			callback_data=build_callback('assign_user_to_project', i.tg_id, project_id)
		)
		btn_admin = InlineKeyboardButton(
			'as admin',
			callback_data=build_callback('assign_admin_to_project', i.tg_id, project_id)
		)
		markup.add(btn_user)
		markup.add(btn_interviewer, btn_admin)
	bot.send_message(call.message.chat.id, 'Select users to toggle for assignment:', reply_markup=markup)
Example #16
0
def before_question_ask(question, message):
	print('before_question_ask', question.code)
	if question.code == 'shops':
		s = Session()
		result_table = question.questionnaire.result_table
		latitude, longitude = s.query(result_table.q2_latitude, result_table.q2_longitude).filter(result_table.started_by_id == message.from_user.id).first()
		msg = ''
		distance_tolerance = 5
		for shop in shops:
			shop['distance'] = round(get_distance(latitude, longitude, lat2=shop['latitude'], lon2=shop['longitude']), 1)
			msg += '\t{name}, distance: {distance}km\n'.format(**shop)
		print('before_question_ask', 'question.categories', question.categories)
		question.set_filter(func=lambda cat: shops[int(cat.code) - 1]['distance'] < distance_tolerance)
		print('before_question_ask after filter', 'question.categories', question.categories)
		bot.send_message(message.chat.id, f'All shops are:\n{msg}But only the ones within {distance_tolerance}km will be available for selection.')
		if len(question.categories) == 0:
			closest = sorted(shops, key=lambda a: a['distance'])[0]
			bot.send_message(
				message.chat.id,
				'Ни одного магазина поблизости :( Попробуй подойти ближе и отправить точку еще раз\nЕсли что ближайший в {distance}км от тебя:\n{name}, {address}'.format(
					**closest
				)
			)
Example #17
0
def _save(question,
          questionnaire,
          step=None,
          force_save_in_survey=None,
          category_code_start=1,
          allow_overwrite=True,
          session=None):
    if not session:
        session = Session()
    question.questionnaire = questionnaire
    question.step = step
    question.save_in_survey = force_save_in_survey if force_save_in_survey is not None else question.should_be_saved_in_survey
    category_code = category_code_start
    for i in question.categories:
        i.code = i.code if i.code else category_code
        session.add(i)
        category_code += 1
    session.add(question)
    try:
        session.commit()
        print(f'{question.code} created')
    except IntegrityError:
        session.rollback()
        print(f'{question.code} already in database')
        if allow_overwrite:
            session.delete(
                session.query(Question).filter(
                    and_(Question.code == question.code,
                         Question.questionnaire_id ==
                         questionnaire.id)).first())
            session.commit()
            print(f'{question.code} deleted')
            session.add(question)
            session.commit()
            print(f'{question.code} created')
    if step:
        step += 1
Example #18
0
from survey.survey_builder import _get_questionnaire, _save
from survey.models import Question, QuestionTypes as types, Session, Category, User

QUESTIONNAIRE_VERSION = 1
QUESTIONNAIRE_NAME = 'gluten_shops'
QUESTIONNAIRE_DESCRIPTION = 'Исследование магазинов с безглютеновой продукцией'
ROUTE_STEP = 1
ALLOW_OVERWRITE = False


def get_questionnaire(session=None, **kwargs):
	return _get_questionnaire(QUESTIONNAIRE_NAME, QUESTIONNAIRE_VERSION, QUESTIONNAIRE_DESCRIPTION, session=session, **kwargs)


session = Session()
me = session.query(User).filter(User.tg_id == 305258161).first()
questionnaire = get_questionnaire(session=session, created_by=me)


def save(q, make_step=True):
	global ROUTE_STEP
	step = ROUTE_STEP if make_step else None
	saved = _save(q, questionnaire, step=step, allow_overwrite=ALLOW_OVERWRITE, session=session)
	if make_step:
		ROUTE_STEP += 1
	return saved


def emojize(s):
	return _emojize(s, use_aliases=True)
Example #19
0
def get_previous_question(question):
	print('Previous question requested for ', question.code)
	session = Session()
	return session.query(Question).filter(Question.step == question.step - 1).first()
Example #20
0
def get_next_question(question):
	session = Session()
	return session.query(Question).filter(Question.step == question.step + 1).first()