Skip to content

Commit 0a51c2b

Browse files
committed
L:Merge branch 'master' of https://github.com/milselarch/RCV-tele-bot
2 parents 72d3250 + 08a25aa commit 0a51c2b

29 files changed

+1309
-858
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ __pycache__/
33
*.py[cod]
44
*$py.class
55

6+
logs/*
7+
68
# C extensions
79
*.so
810

base_api.py

+35-30
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from strenum import StrEnum
2020
from requests import PreparedRequest
2121

22-
from helpers import strings, constants
22+
from helpers.start_get_params import StartGetParams
23+
from helpers import constants
2324
from helpers.strings import generate_poll_closed_message
2425
from load_config import TELEGRAM_BOT_TOKEN
2526
from telegram.ext import ApplicationBuilder
@@ -379,18 +380,19 @@ def get_poll_voter(
379380
def verify_voter(
380381
cls, poll_id: int, user_id: UserID, username: Optional[str] = None,
381382
chat_id: Optional[int] = None
382-
) -> Result[int, UserRegistrationStatus]:
383+
) -> Result[tuple[PollVoters, bool], UserRegistrationStatus]:
383384
"""
384385
Checks if the user is a member of the poll
385386
Attempts to auto enroll user if their username is whitelisted
386387
and the username whitelist entry is empty
387-
Returns PollVoters entry id of user for the specified poll
388+
Returns PollVoters entry id of user for the specified poll,
389+
and whether user was newly whitelisted from chat whitelist
388390
"""
389391

390392
poll_voter_res = cls.get_poll_voter(poll_id, user_id)
391393
if poll_voter_res.is_ok():
392394
poll_voter = poll_voter_res.unwrap()
393-
return Ok(poll_voter.id)
395+
return Ok((poll_voter, False))
394396
else:
395397
poll_voter_err = poll_voter_res.unwrap_err()
396398
if poll_voter_err is None:
@@ -409,8 +411,7 @@ def verify_voter(
409411
ignore_voter_limit=False, chat_id=chat_id
410412
)
411413
if chat_register_result.is_ok():
412-
poll_voter: PollVoters = chat_register_result.unwrap()
413-
return Ok(poll_voter.id)
414+
return chat_register_result
414415

415416
whitelist_user_result = cls.get_whitelist_entry(
416417
username=username_str, poll_id=poll_id,
@@ -431,15 +432,19 @@ def verify_voter(
431432
)
432433
if register_result.is_ok():
433434
poll_voter: PollVoters = register_result.unwrap()
434-
return Ok(poll_voter.id)
435+
return Ok((poll_voter, False))
435436

436437
return register_result
437438

438439
@classmethod
439440
def _register_voter_from_chat_whitelist(
440441
cls, poll_id: int, user_id: UserID, ignore_voter_limit: bool = False,
441442
chat_id: int | None = None
442-
) -> Result[PollVoters, UserRegistrationStatus]:
443+
) -> Result[tuple[PollVoters, bool], UserRegistrationStatus]:
444+
"""
445+
return Ok value is poll_voter, and whether registration
446+
was newly made
447+
"""
443448
if chat_id is None:
444449
return Err(UserRegistrationStatus.NOT_WHITELISTED)
445450

@@ -460,8 +465,7 @@ def _register_voter_from_chat_whitelist(
460465
transaction.rollback()
461466
return register_result
462467

463-
poll_voter_row, _ = register_result.unwrap()
464-
return Ok(poll_voter_row)
468+
return register_result
465469

466470
@classmethod
467471
def register_from_username_whitelist(
@@ -643,7 +647,7 @@ def generate_poll_message(
643647
poll_message = cls.generate_poll_info(
644648
poll_metadata.id, poll_metadata.question,
645649
poll_info.poll_options, closed=poll_metadata.closed,
646-
bot_username=bot_username,
650+
bot_username=bot_username, max_voters=poll_metadata.max_voters,
647651
num_voters=poll_metadata.num_active_voters,
648652
num_votes=poll_metadata.num_votes,
649653
add_webapp_link=add_webapp_link
@@ -696,7 +700,7 @@ def build_private_vote_markup(
696700
poll_url = cls.generate_poll_url(
697701
poll_id=poll_id, tele_user=tele_user
698702
)
699-
logger.info(f'POLL_URL = {poll_url}')
703+
logger.warning(f'POLL_URL = {poll_url}')
700704
# create vote button for reply message
701705
markup_layout = [[KeyboardButton(
702706
text=f'Vote for Poll #{poll_id}', web_app=WebAppInfo(url=poll_url)
@@ -906,16 +910,17 @@ def get_whitelist_entry(
906910
@staticmethod
907911
def generate_poll_info(
908912
poll_id, poll_question, poll_options: list[str],
909-
bot_username: str, num_votes: int = 0, num_voters: int = 0,
910-
closed: bool = False, add_webapp_link: bool = True
913+
bot_username: str, max_voters: int, num_votes: int = 0,
914+
num_voters: int = 0, closed: bool = False,
915+
add_webapp_link: bool = True
911916
):
912917
close_tag = '(closed)' if closed else ''
913918
numbered_poll_options = [
914919
f'{k + 1}. {poll_option}' for k, poll_option
915920
in enumerate(poll_options)
916921
]
917922

918-
args = f'{strings.POLL_ID_GET_PARAM}={poll_id}'
923+
args = f'{StartGetParams.POLL_ID}={poll_id}'
919924
stamp = int(time.time())
920925
deep_link_url = (
921926
f'https://t.me/{bot_username}?start={args}&stamp={stamp}'
@@ -933,7 +938,7 @@ def generate_poll_info(
933938
Poll #{poll_id} {close_tag}
934939
{poll_question}
935940
——————————————————
936-
{num_votes} / {num_voters} voted
941+
{num_votes} / {num_voters} voted (max {max_voters})
937942
——————————————————
938943
""") +
939944
f'\n'.join(numbered_poll_options) +
@@ -1133,7 +1138,7 @@ def validate_ranked_options(
11331138
def register_vote(
11341139
cls, poll_id: int, rankings: List[int], user_tele_id: int,
11351140
username: Optional[str], chat_id: Optional[int]
1136-
) -> Result[int, MessageBuilder]:
1141+
) -> Result[tuple[bool, bool], MessageBuilder]:
11371142
"""
11381143
registers a vote for the poll
11391144
checks that:
@@ -1149,7 +1154,7 @@ def register_vote(
11491154
:param user_tele_id: voter's telegram user tele id
11501155
:param username: voter's telegram username
11511156
:param chat_id: telegram chat id that message originated from
1152-
:return:
1157+
:return is_first_vote, newly_registered:
11531158
"""
11541159
error_message = MessageBuilder()
11551160
if len(rankings) == 0:
@@ -1179,31 +1184,27 @@ def register_vote(
11791184
user_id = user.get_user_id()
11801185
# verify that the user can vote for the poll
11811186
# print('PRE_VERIFY', poll_id, user_id, username)
1187+
# TODO: include whether registration was from chat whitelist in return
11821188
verify_result = cls.verify_voter(
11831189
poll_id, user_id, username=username, chat_id=chat_id
11841190
)
11851191
if verify_result.is_err():
11861192
error_message.add(f"You're not a voter of poll {poll_id}")
11871193
return Err(error_message)
11881194

1189-
poll_voter_id: int = verify_result.unwrap()
1190-
# print('POLL_VOTER_ID', poll_voter_id)
1195+
poll_voter, newly_registered_voter = verify_result.unwrap()
1196+
print('verify_result', verify_result, poll_voter)
11911197
vote_register_result = cls.__unsafe_register_vote(
1192-
poll_id=poll_id, poll_voter_id=poll_voter_id,
1198+
poll_id=poll_id, poll_voter_id=int(poll_voter.id),
11931199
rankings=rankings
11941200
)
11951201

11961202
if vote_register_result.is_err():
11971203
assert isinstance(vote_register_result, Err)
11981204
return vote_register_result
11991205

1200-
vote_registered = vote_register_result.unwrap()
1201-
1202-
if vote_registered:
1203-
return Ok(poll_id)
1204-
else:
1205-
error_message.add('Vote registration failed')
1206-
return Err(error_message)
1206+
is_first_vote = vote_register_result.unwrap()
1207+
return Ok((is_first_vote, newly_registered_voter))
12071208

12081209
@classmethod
12091210
def __unsafe_register_vote(
@@ -1213,11 +1214,15 @@ def __unsafe_register_vote(
12131214
registers a vote for the poll
12141215
checks that poll option numbers are valid for the current poll
12151216
does not check if poll_voter_id is valid for poll {poll_id}
1216-
does not check if poll has already been closed
1217+
does not check if poll has already been closed.
1218+
1219+
Return Ok result is a bool indicating if the new vote is
1220+
the first one to be registered, or if it replaces an existing vote
12171221
12181222
:param poll_id:
12191223
:param poll_voter_id:
12201224
:param rankings:
1225+
:return Result[bool, MessageBuilder]:
12211226
"""
12221227
error_message = MessageBuilder()
12231228
poll_option_rows = PollOptions.select().where(
@@ -1290,7 +1295,7 @@ def __unsafe_register_vote(
12901295
Polls.id == poll_id
12911296
).execute()
12921297

1293-
return Ok(True)
1298+
return Ok(is_first_vote)
12941299

12951300
@classmethod
12961301
def generate_vote_markup(

0 commit comments

Comments
 (0)