19
19
from strenum import StrEnum
20
20
from requests import PreparedRequest
21
21
22
- from helpers import strings , constants
22
+ from helpers .start_get_params import StartGetParams
23
+ from helpers import constants
23
24
from helpers .strings import generate_poll_closed_message
24
25
from load_config import TELEGRAM_BOT_TOKEN
25
26
from telegram .ext import ApplicationBuilder
@@ -379,18 +380,19 @@ def get_poll_voter(
379
380
def verify_voter (
380
381
cls , poll_id : int , user_id : UserID , username : Optional [str ] = None ,
381
382
chat_id : Optional [int ] = None
382
- ) -> Result [int , UserRegistrationStatus ]:
383
+ ) -> Result [tuple [ PollVoters , bool ] , UserRegistrationStatus ]:
383
384
"""
384
385
Checks if the user is a member of the poll
385
386
Attempts to auto enroll user if their username is whitelisted
386
387
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
388
390
"""
389
391
390
392
poll_voter_res = cls .get_poll_voter (poll_id , user_id )
391
393
if poll_voter_res .is_ok ():
392
394
poll_voter = poll_voter_res .unwrap ()
393
- return Ok (poll_voter . id )
395
+ return Ok (( poll_voter , False ) )
394
396
else :
395
397
poll_voter_err = poll_voter_res .unwrap_err ()
396
398
if poll_voter_err is None :
@@ -409,8 +411,7 @@ def verify_voter(
409
411
ignore_voter_limit = False , chat_id = chat_id
410
412
)
411
413
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
414
415
415
416
whitelist_user_result = cls .get_whitelist_entry (
416
417
username = username_str , poll_id = poll_id ,
@@ -431,15 +432,19 @@ def verify_voter(
431
432
)
432
433
if register_result .is_ok ():
433
434
poll_voter : PollVoters = register_result .unwrap ()
434
- return Ok (poll_voter . id )
435
+ return Ok (( poll_voter , False ) )
435
436
436
437
return register_result
437
438
438
439
@classmethod
439
440
def _register_voter_from_chat_whitelist (
440
441
cls , poll_id : int , user_id : UserID , ignore_voter_limit : bool = False ,
441
442
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
+ """
443
448
if chat_id is None :
444
449
return Err (UserRegistrationStatus .NOT_WHITELISTED )
445
450
@@ -460,8 +465,7 @@ def _register_voter_from_chat_whitelist(
460
465
transaction .rollback ()
461
466
return register_result
462
467
463
- poll_voter_row , _ = register_result .unwrap ()
464
- return Ok (poll_voter_row )
468
+ return register_result
465
469
466
470
@classmethod
467
471
def register_from_username_whitelist (
@@ -643,7 +647,7 @@ def generate_poll_message(
643
647
poll_message = cls .generate_poll_info (
644
648
poll_metadata .id , poll_metadata .question ,
645
649
poll_info .poll_options , closed = poll_metadata .closed ,
646
- bot_username = bot_username ,
650
+ bot_username = bot_username , max_voters = poll_metadata . max_voters ,
647
651
num_voters = poll_metadata .num_active_voters ,
648
652
num_votes = poll_metadata .num_votes ,
649
653
add_webapp_link = add_webapp_link
@@ -696,7 +700,7 @@ def build_private_vote_markup(
696
700
poll_url = cls .generate_poll_url (
697
701
poll_id = poll_id , tele_user = tele_user
698
702
)
699
- logger .info (f'POLL_URL = { poll_url } ' )
703
+ logger .warning (f'POLL_URL = { poll_url } ' )
700
704
# create vote button for reply message
701
705
markup_layout = [[KeyboardButton (
702
706
text = f'Vote for Poll #{ poll_id } ' , web_app = WebAppInfo (url = poll_url )
@@ -906,16 +910,17 @@ def get_whitelist_entry(
906
910
@staticmethod
907
911
def generate_poll_info (
908
912
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
911
916
):
912
917
close_tag = '(closed)' if closed else ''
913
918
numbered_poll_options = [
914
919
f'{ k + 1 } . { poll_option } ' for k , poll_option
915
920
in enumerate (poll_options )
916
921
]
917
922
918
- args = f'{ strings . POLL_ID_GET_PARAM } ={ poll_id } '
923
+ args = f'{ StartGetParams . POLL_ID } ={ poll_id } '
919
924
stamp = int (time .time ())
920
925
deep_link_url = (
921
926
f'https://t.me/{ bot_username } ?start={ args } &stamp={ stamp } '
@@ -933,7 +938,7 @@ def generate_poll_info(
933
938
Poll #{ poll_id } { close_tag }
934
939
{ poll_question }
935
940
——————————————————
936
- { num_votes } / { num_voters } voted
941
+ { num_votes } / { num_voters } voted (max { max_voters } )
937
942
——————————————————
938
943
""" ) +
939
944
f'\n ' .join (numbered_poll_options ) +
@@ -1133,7 +1138,7 @@ def validate_ranked_options(
1133
1138
def register_vote (
1134
1139
cls , poll_id : int , rankings : List [int ], user_tele_id : int ,
1135
1140
username : Optional [str ], chat_id : Optional [int ]
1136
- ) -> Result [int , MessageBuilder ]:
1141
+ ) -> Result [tuple [ bool , bool ] , MessageBuilder ]:
1137
1142
"""
1138
1143
registers a vote for the poll
1139
1144
checks that:
@@ -1149,7 +1154,7 @@ def register_vote(
1149
1154
:param user_tele_id: voter's telegram user tele id
1150
1155
:param username: voter's telegram username
1151
1156
:param chat_id: telegram chat id that message originated from
1152
- :return:
1157
+ :return is_first_vote, newly_registered :
1153
1158
"""
1154
1159
error_message = MessageBuilder ()
1155
1160
if len (rankings ) == 0 :
@@ -1179,31 +1184,27 @@ def register_vote(
1179
1184
user_id = user .get_user_id ()
1180
1185
# verify that the user can vote for the poll
1181
1186
# print('PRE_VERIFY', poll_id, user_id, username)
1187
+ # TODO: include whether registration was from chat whitelist in return
1182
1188
verify_result = cls .verify_voter (
1183
1189
poll_id , user_id , username = username , chat_id = chat_id
1184
1190
)
1185
1191
if verify_result .is_err ():
1186
1192
error_message .add (f"You're not a voter of poll { poll_id } " )
1187
1193
return Err (error_message )
1188
1194
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 )
1191
1197
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 ) ,
1193
1199
rankings = rankings
1194
1200
)
1195
1201
1196
1202
if vote_register_result .is_err ():
1197
1203
assert isinstance (vote_register_result , Err )
1198
1204
return vote_register_result
1199
1205
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 ))
1207
1208
1208
1209
@classmethod
1209
1210
def __unsafe_register_vote (
@@ -1213,11 +1214,15 @@ def __unsafe_register_vote(
1213
1214
registers a vote for the poll
1214
1215
checks that poll option numbers are valid for the current poll
1215
1216
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
1217
1221
1218
1222
:param poll_id:
1219
1223
:param poll_voter_id:
1220
1224
:param rankings:
1225
+ :return Result[bool, MessageBuilder]:
1221
1226
"""
1222
1227
error_message = MessageBuilder ()
1223
1228
poll_option_rows = PollOptions .select ().where (
@@ -1290,7 +1295,7 @@ def __unsafe_register_vote(
1290
1295
Polls .id == poll_id
1291
1296
).execute ()
1292
1297
1293
- return Ok (True )
1298
+ return Ok (is_first_vote )
1294
1299
1295
1300
@classmethod
1296
1301
def generate_vote_markup (
0 commit comments