pkscreener 0.46.20250210.702__cp312-cp312-win_amd64.whl → 0.46.20250212.704__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/README.txt +9 -7
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/MarketMonitor.py +16 -5
- pkscreener-0.46.20250212.704.data/purelib/pkscreener/classes/__init__.py +1 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/globals.py +3 -3
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/pkscreenerbot.py +331 -243
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/requirements.txt +1 -1
- {pkscreener-0.46.20250210.702.dist-info → pkscreener-0.46.20250212.704.dist-info}/METADATA +11 -9
- pkscreener-0.46.20250212.704.dist-info/RECORD +58 -0
- pkscreener-0.46.20250210.702.data/purelib/pkscreener/classes/__init__.py +0 -1
- pkscreener-0.46.20250210.702.dist-info/RECORD +0 -58
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/Disclaimer.txt +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/LICENSE-Others.txt +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/LICENSE.txt +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/LogoWM.txt +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/__init__.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ArtTexts.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/AssetsManager.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Backtest.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Barometer.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/BaseScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/CandlePatterns.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Changelog.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ConfigManager.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ConsoleMenuUtility.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ConsoleUtility.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Fetcher.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/GlobalStore.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ImageUtility.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/MarketStatus.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/MenuOptions.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Messenger.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/OtaUpdater.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKAnalytics.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKDataService.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKDemoHandler.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKMarketOpenCloseAnalyser.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKPremiumHandler.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKScanRunner.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKScheduledTaskProgress.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKScheduler.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKSpreadsheets.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKTask.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PKUserRegistration.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Pktalib.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Portfolio.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/PortfolioXRay.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/ScreeningStatistics.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/StockScreener.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/StockSentiment.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/UserMenuChoicesHandler.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/Utility.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/WorkflowManager.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/classes/keys.py +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/courbd.ttf +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/pkscreener.ini +0 -0
- {pkscreener-0.46.20250210.702.data → pkscreener-0.46.20250212.704.data}/purelib/pkscreener/pkscreenercli.py +0 -0
- {pkscreener-0.46.20250210.702.dist-info → pkscreener-0.46.20250212.704.dist-info}/LICENSE +0 -0
- {pkscreener-0.46.20250210.702.dist-info → pkscreener-0.46.20250212.704.dist-info}/WHEEL +0 -0
- {pkscreener-0.46.20250210.702.dist-info → pkscreener-0.46.20250212.704.dist-info}/entry_points.txt +0 -0
- {pkscreener-0.46.20250210.702.dist-info → pkscreener-0.46.20250212.704.dist-info}/top_level.txt +0 -0
@@ -102,6 +102,12 @@ from telegram.ext import (
|
|
102
102
|
Filters,
|
103
103
|
CallbackContext
|
104
104
|
)
|
105
|
+
from PKDevTools.classes.Singleton import SingletonType, SingletonMixin
|
106
|
+
|
107
|
+
class PKLocalCache(SingletonMixin, metaclass=SingletonType):
|
108
|
+
def __init__(self):
|
109
|
+
super(PKLocalCache, self).__init__()
|
110
|
+
self.registeredIDs = []
|
105
111
|
|
106
112
|
# Enable logging
|
107
113
|
logging.basicConfig(
|
@@ -137,6 +143,8 @@ _updater = None
|
|
137
143
|
|
138
144
|
TOP_LEVEL_SCANNER_MENUS = ["X", "B", "MI","DV", "P"] #
|
139
145
|
TOP_LEVEL_SCANNER_SKIP_MENUS = ["M", "S", "F", "G", "C", "T", "D", "I", "E", "U", "L", "Z", "P"] # Last item will be skipped.
|
146
|
+
TOP_LEVEL_MARKUP_SKIP_MENUS = TOP_LEVEL_SCANNER_SKIP_MENUS[:len(TOP_LEVEL_SCANNER_SKIP_MENUS)-1]
|
147
|
+
TOP_LEVEL_MARKUP_SKIP_MENUS.extend(["X","P","B"])
|
140
148
|
INDEX_SKIP_MENUS_1_To_4 = ["W","E","M","Z","0","5","6","7","8","9","10","11","12","13","14","S","15"]
|
141
149
|
INDEX_SKIP_MENUS_5_TO_9 = ["W","E","M","Z","N","0","1","2","3","4","10","11","12","13","14","S","15"]
|
142
150
|
INDEX_SKIP_MENUS_10_TO_15 = ["W","E","M","Z","N","0","1","2","3","4","5","6","7","8","9","S"]
|
@@ -158,6 +166,21 @@ PIPED_SCAN_SKIP_INDEX_MENUS =["W","N","E","S","0","Z","M","15"]
|
|
158
166
|
UNSUPPORTED_COMMAND_MENUS =["22","M","Z","0",str(MAX_MENU_OPTION)]
|
159
167
|
SUPPORTED_COMMAND_MENUS = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45"]
|
160
168
|
|
169
|
+
def registerUser(user,forceFetch=False):
|
170
|
+
otpValue, subsModel,subsValidity,alertUser = 0,0,None,None
|
171
|
+
if user is not None and (user.id not in PKLocalCache().registeredIDs or forceFetch):
|
172
|
+
dbManager = DBManager()
|
173
|
+
otpValue, subsModel,subsValidity,alertUser = dbManager.getOTP(user.id,user.username,f"{user.first_name} {user.last_name}",validityIntervalInSeconds=configManager.otpInterval)
|
174
|
+
if str(otpValue).strip() != '0' and user.id not in PKLocalCache().registeredIDs:
|
175
|
+
PKLocalCache().registeredIDs.append(alertUser.userid)
|
176
|
+
return otpValue, subsModel,subsValidity,alertUser
|
177
|
+
|
178
|
+
def loadRegisteredUsers():
|
179
|
+
dbManager = DBManager()
|
180
|
+
users = dbManager.getUsers(fieldName="userid")
|
181
|
+
userIDs = [user.userid for user in users]
|
182
|
+
PKLocalCache().registeredIDs.extend(userIDs)
|
183
|
+
|
161
184
|
def initializeIntradayTimer():
|
162
185
|
try:
|
163
186
|
if (not PKDateUtilities.isTodayHoliday()[0]):
|
@@ -249,65 +272,17 @@ def matchUTR(update: Update, context: CallbackContext) -> str:
|
|
249
272
|
updatedResults = "We could not find any transaction details with the provided UTR.\nUPI transaction reference number is a 12-digit alphanumeric/numeric code that serves as a unique identifier for transactions. It is also known as the Unique Transaction Reference (UTR) number.\nYou can find your UPI reference number in the UPI-enabled app you used to make the transaction.\nFor example, you can find your UPI reference number in the History section of Google Pay. \nIn the Paytm app, you can find it by clicking View Details.\n\nIf you still cannot find it, please drop a message with transaction details/snapshot to @ItsOnlyPK to enable subscription."
|
250
273
|
else:
|
251
274
|
updatedResults = "Did you forget to include the UTR number with /Check ?\nYou should use it like this:\n\n/Check UTR_Here\n\nUPI transaction reference number is a 12-digit alphanumeric/numeric code that serves as a unique identifier for transactions. It is also known as the Unique Transaction Reference (UTR) number.\nYou can find your UPI reference number in the UPI-enabled app you used to make the transaction.\nFor example, you can find your UPI reference number in the History section of Google Pay. \nIn the Paytm app, you can find it by clicking View Details.\n\nIf you still cannot find it, please drop a message with transaction details/snapshot to @ItsOnlyPK to enable subscription."
|
252
|
-
update.message.reply_text(sanitiseTexts(updatedResults), parse_mode="HTML")
|
275
|
+
update.message.reply_text(sanitiseTexts(updatedResults), reply_markup=default_markup(user=user),parse_mode="HTML")
|
253
276
|
shareUpdateWithChannel(update=update, context=context, optionChoices=f"/otp\n{updatedResults}")
|
254
277
|
return START_ROUTES
|
255
278
|
|
256
|
-
def
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
return
|
261
|
-
else:
|
262
|
-
if update.callback_query is not None:
|
263
|
-
updateCarrier = update.callback_query
|
264
|
-
if update.message is not None:
|
265
|
-
updateCarrier = update.message
|
266
|
-
if updateCarrier is None:
|
267
|
-
return
|
268
|
-
# Get user that sent /start and log his name
|
269
|
-
user = updateCarrier.from_user
|
270
|
-
logger.info("User %s started the conversation.", user.first_name)
|
271
|
-
if not bot_available:
|
272
|
-
# Sometimes, either the payment does not go through or
|
273
|
-
# it takes time to process the last month's payment if
|
274
|
-
# done in the past 24 hours while the last date was today.
|
275
|
-
# If that happens, we won't be able to run bots or scanners
|
276
|
-
# without incurring heavy charges. Let's run in the
|
277
|
-
# unavailable mode instead until this gets fixed.
|
278
|
-
updatedResults = APOLOGY_TEXT
|
279
|
-
|
280
|
-
if bot_available:
|
281
|
-
try:
|
282
|
-
otpValue = 0
|
283
|
-
dbManager = DBManager()
|
284
|
-
otpValue, subsModel,subsValidity = dbManager.getOTP(user.id,user.username,f"{user.first_name} {user.last_name}",validityIntervalInSeconds=configManager.otpInterval)
|
285
|
-
except Exception as e: # pragma: no cover
|
286
|
-
logger.error(e)
|
287
|
-
pass
|
288
|
-
userText = f"\nUserID: <b>{user.id}</b>"
|
289
|
-
try:
|
290
|
-
subscriptionModelNames = "\n<pre>Following basic and premium subscription models are available. Premium subscription allows for unlimited premium scans:\n"
|
291
|
-
for name,value in PKUserSusbscriptions().subscriptionKeyValuePairs.items():
|
292
|
-
if name == PKSubscriptionModel.No_Subscription.name:
|
293
|
-
subscriptionModelNames = f"{subscriptionModelNames}\n{name} : ₹ {value} (Only Basic Scans are free)\n"
|
294
|
-
else:
|
295
|
-
subscriptionModelNames = f"{subscriptionModelNames}\n{name.ljust(15)} : ₹ {value}"
|
296
|
-
subscriptionModelNames = f"{subscriptionModelNames}</pre>\nPlease pay to subscribe:\n\n1. Using UPI(India) to <b>PKScreener@APL</b> \nor\n2. Proudly <b>sponsor</b>: https://github.com/sponsors/pkjmesra?frequency=recurring&sponsor=pkjmesra\n\nPlease drop a message to @ItsOnlyPK on Telegram after paying to enable subscription manually or use \n\n/check UPI_UTR_HERE_After_Making_Payment to share transaction reference number to automatically enable subscription after making payment via UPI\n!"
|
279
|
+
def editMessageText(query,editedText,reply_markup):
|
280
|
+
editedText = f"{PKDateUtilities.currentDateTime()}:\n{editedText}"
|
281
|
+
if query is not None and hasattr(query, "edit_message_text"):
|
282
|
+
query.edit_message_text(text=editedText, reply_markup=reply_markup,parse_mode="HTML")
|
297
283
|
|
298
|
-
|
299
|
-
|
300
|
-
subscriptionModelName = f"{subscriptionModelName} (Expires on: {subsValidity})"
|
301
|
-
except Exception as e:
|
302
|
-
logger.error(e)
|
303
|
-
subscriptionModelName = PKSubscriptionModel.No_Subscription.name
|
304
|
-
pass
|
305
|
-
if otpValue == 0:
|
306
|
-
updatedResults = f"We are having difficulty generating OTP for your {userText}. Please try again later."
|
307
|
-
else:
|
308
|
-
updatedResults = f"Please use your {userText} \nwith the following OTP to login to PKScreener:\n<b>{otpValue}</b>\n\nYour current subscription : <b>{subscriptionModelName}</b>. {subscriptionModelNames}"
|
309
|
-
update.message.reply_text(sanitiseTexts(updatedResults), parse_mode="HTML")
|
310
|
-
shareUpdateWithChannel(update=update, context=context, optionChoices=f"/otp\n{updatedResults}")
|
284
|
+
def otp(update: Update, context: CallbackContext) -> str:
|
285
|
+
viewSubscriptionOptions(update,context,sendOTP=True)
|
311
286
|
return START_ROUTES
|
312
287
|
|
313
288
|
def start(update: Update, context: CallbackContext, updatedResults=None, monitorIndex=0,chosenBotMenuOption="") -> str:
|
@@ -339,32 +314,7 @@ def start(update: Update, context: CallbackContext, updatedResults=None, monitor
|
|
339
314
|
# The keyboard is a list of button rows, where each row is in turn
|
340
315
|
# a list (hence `[[...]]`).
|
341
316
|
if bot_available:
|
342
|
-
|
343
|
-
if (PKDateUtilities.isTradingTime() and not PKDateUtilities.isTodayHoliday()[0]) or ("PKDevTools_Default_Log_Level" in os.environ.keys()) or sys.argv[0].endswith(".py"):
|
344
|
-
mns.append(menu().create(f"MI_{monitorIndex}", "👩💻 🚀 Intraday Monitor", 2))
|
345
|
-
if user.username == OWNER_USER:
|
346
|
-
mns.append(menu().create(f"DV_0", ("✅ Enable Logging" if not configManager.logsEnabled else "🚫 Disable Logging"), 2))
|
347
|
-
mns.append(menu().create(f"DV_1", "🔄 Restart Bot", 2))
|
348
|
-
|
349
|
-
inlineMenus = []
|
350
|
-
keyboard = []
|
351
|
-
rowIndex = 0
|
352
|
-
iconDict = {"X":"🕵️♂️ 🔍 ","B":"📈 🎯 ","P":"🧨 💥 ","MI":"","DV":""}
|
353
|
-
for mnu in mns:
|
354
|
-
if mnu.menuKey[0:2] in TOP_LEVEL_SCANNER_MENUS:
|
355
|
-
rowIndex +=1
|
356
|
-
inlineMenus.append(
|
357
|
-
InlineKeyboardButton(
|
358
|
-
iconDict.get(str(mnu.menuKey[0:2])) + mnu.menuText.split("(")[0],
|
359
|
-
callback_data="C" + str(mnu.menuKey),
|
360
|
-
)
|
361
|
-
)
|
362
|
-
if rowIndex % 2 == 0:
|
363
|
-
keyboard.append(inlineMenus)
|
364
|
-
inlineMenus = []
|
365
|
-
if len(inlineMenus) > 0:
|
366
|
-
keyboard.append(inlineMenus)
|
367
|
-
reply_markup = InlineKeyboardMarkup(keyboard)
|
317
|
+
reply_markup = default_markup(user=user,monitorIndex=monitorIndex)
|
368
318
|
cmds = m0.renderForMenu(
|
369
319
|
selectedMenu=None,
|
370
320
|
skip=TOP_LEVEL_SCANNER_SKIP_MENUS[:len(TOP_LEVEL_SCANNER_SKIP_MENUS)-1],
|
@@ -375,22 +325,23 @@ def start(update: Update, context: CallbackContext, updatedResults=None, monitor
|
|
375
325
|
reply_markup = None
|
376
326
|
|
377
327
|
if updatedResults is None:
|
378
|
-
cmdText = "\n/otp
|
328
|
+
cmdText = "\n/otp : To generate an OTP to login to PKScreener desktop console\n/check UPI_UTR_HERE_After_Making_Payment : To share transaction reference number to automatically enable subscription after making payment via UPI\n"
|
379
329
|
for cmd in cmds:
|
380
|
-
|
381
|
-
|
382
|
-
|
330
|
+
if cmd.menuKey not in TOP_LEVEL_MARKUP_SKIP_MENUS:
|
331
|
+
cmdText = f"{cmdText}\n{cmd.commandTextKey()} : {cmd.commandTextLabel()}"
|
332
|
+
tosDisclaimerText = "By using this Software, you agree to\n[+] having read through the <a href='https://pkjmesra.github.io/PKScreener/Disclaimer.txt'>Disclaimer</a>\n[+] and accept <a href='https://pkjmesra.github.io/PKScreener/tos.txt'>Terms Of Service</a> of PKScreener.\n[+] If that is not the case, you MUST immediately terminate using PKScreener and exit now!\n"
|
333
|
+
menuText = f"Welcome {user.first_name}, {(user.username)}!\n{tosDisclaimerText}Please choose a menu option by selecting a button from below.{cmdText}"
|
383
334
|
try:
|
384
335
|
if updateCarrier is not None and hasattr(updateCarrier, "data") and updateCarrier.data is not None and updateCarrier.data == "CP":
|
385
|
-
menuText = f"Piped Scanners are available using /P . Click on this /P to begin using piped scanners. To use other scanners, choose a menu option by selecting a button from below.\n
|
336
|
+
menuText = f"Piped Scanners are available using /P . Click on this /P to begin using piped scanners. To use other scanners, choose a menu option by selecting a button from below.\n{cmdText}"
|
386
337
|
except Exception as e: # pragma: no cover
|
387
338
|
logger.error(e)
|
388
339
|
pass
|
389
|
-
menuText = f"{menuText}\
|
340
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
390
341
|
else:
|
391
342
|
if not isUserSubscribed(user):
|
392
|
-
updatedResults = f"Thank you for choosing Intraday Monitor!\n\nThis scan request is, however
|
393
|
-
updatedResults = f"{updatedResults}\
|
343
|
+
updatedResults = f"Thank you for choosing Intraday Monitor!\n\nThis scan request is, however, protected and is only available to premium subscribers. It seems like you are not subscribed to the paid/premium subscription to PKScreener.\nPlease checkout all premium options by sending out a request:\n/OTP\n\nFor basic/unpaid users, you can try out the following:\n/X_0 StockCode1,StockCode2,etc.\n/X_N\n/X_1"
|
344
|
+
updatedResults = f"{updatedResults}\nClick /start if you want to restart the session."
|
394
345
|
chosenBotMenuOption = f"{chosenBotMenuOption}\nInt. Monitor. MonitorIndex:{monitorIndex}\n{updatedResults}"
|
395
346
|
menuText = updatedResults
|
396
347
|
# Send message with text and appended InlineKeyboard
|
@@ -402,6 +353,7 @@ def start(update: Update, context: CallbackContext, updatedResults=None, monitor
|
|
402
353
|
update.message.reply_text(
|
403
354
|
sanitiseTexts(menuText),
|
404
355
|
reply_markup=reply_markup,
|
356
|
+
parse_mode="HTML"
|
405
357
|
)
|
406
358
|
if Channel_Id is not None and len(str(Channel_Id)) > 0:
|
407
359
|
context.bot.send_message(
|
@@ -409,7 +361,7 @@ def start(update: Update, context: CallbackContext, updatedResults=None, monitor
|
|
409
361
|
text=f"Name: {user.first_name}, Username:@{user.username} with ID: {str(user.id)} started using the bot!\n{chosenBotMenuOption}",
|
410
362
|
parse_mode="HTML",
|
411
363
|
)
|
412
|
-
|
364
|
+
registerUser(user)
|
413
365
|
# Tell ConversationHandler that we're in state `FIRST` now
|
414
366
|
return START_ROUTES
|
415
367
|
|
@@ -583,11 +535,74 @@ def PScanners(update: Update, context: CallbackContext) -> str:
|
|
583
535
|
)
|
584
536
|
keyboard = [inlineMenus]
|
585
537
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
586
|
-
if
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
538
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
539
|
+
editMessageText(query=query,editedText=menuText,reply_markup=reply_markup)
|
540
|
+
registerUser(user)
|
541
|
+
return START_ROUTES
|
542
|
+
|
543
|
+
def viewSubscriptionOptions(update:Update,context:CallbackContext,sendOTP=False):
|
544
|
+
global bot_available
|
545
|
+
updateCarrier = None
|
546
|
+
updatedResults= ""
|
547
|
+
if update is None:
|
548
|
+
return
|
549
|
+
else:
|
550
|
+
if update.callback_query is not None:
|
551
|
+
updateCarrier = update.callback_query
|
552
|
+
if update.message is not None:
|
553
|
+
updateCarrier = update.message
|
554
|
+
if updateCarrier is None:
|
555
|
+
return
|
556
|
+
# Get user that sent /start and log his name
|
557
|
+
user = updateCarrier.from_user
|
558
|
+
logger.info("User %s started the conversation.", user.first_name)
|
559
|
+
if not bot_available:
|
560
|
+
# Sometimes, either the payment does not go through or
|
561
|
+
# it takes time to process the last month's payment if
|
562
|
+
# done in the past 24 hours while the last date was today.
|
563
|
+
# If that happens, we won't be able to run bots or scanners
|
564
|
+
# without incurring heavy charges. Let's run in the
|
565
|
+
# unavailable mode instead until this gets fixed.
|
566
|
+
updatedResults = APOLOGY_TEXT
|
567
|
+
|
568
|
+
if bot_available:
|
569
|
+
try:
|
570
|
+
otpValue = 0
|
571
|
+
alertUser = None
|
572
|
+
dbManager = DBManager()
|
573
|
+
otpValue, subsModel,subsValidity,alertUser = registerUser(user,forceFetch=True)
|
574
|
+
except Exception as e: # pragma: no cover
|
575
|
+
logger.error(e)
|
576
|
+
pass
|
577
|
+
userText = f"<b>UserID</b> : <code>{user.id}</code>"
|
578
|
+
try:
|
579
|
+
subscriptionModelNames = "\n<pre>Following basic and premium subscription models are available. Premium subscription allows for unlimited premium scans:\n"
|
580
|
+
for name,value in PKUserSusbscriptions().subscriptionKeyValuePairs.items():
|
581
|
+
if name == PKSubscriptionModel.No_Subscription.name:
|
582
|
+
subscriptionModelNames = f"{subscriptionModelNames}\n₹ {str(value).ljust(6)}: {name} (Only Basic Scans are free)\n"
|
583
|
+
else:
|
584
|
+
subscriptionModelNames = f"{subscriptionModelNames}\n₹ {str(value).ljust(6)}: {name}"
|
585
|
+
subscriptionModelNames = f"{subscriptionModelNames}</pre>\nPlease pay to subscribe:\n1. Using UPI(India) to <a href='https://tinyurl.com/v7h3t233'>PKScreener@APL</a> or\n2. Proudly <a href='https://github.com/sponsors/pkjmesra?frequency=recurring&sponsor=pkjmesra'><b>sponsor</b></a>\n\nPlease drop a message to @ItsOnlyPK on Telegram after paying to enable subscription manually or use \n\n/check UPI_UTR_HERE_After_Making_Payment to share transaction reference number to automatically enable subscription after making payment via UPI\n"
|
586
|
+
|
587
|
+
subscriptionModelName = PKUserSusbscriptions().subscriptionValueKeyPairs[subsModel]
|
588
|
+
if subscriptionModelName != PKSubscriptionModel.No_Subscription.name:
|
589
|
+
subscriptionModelName = f"{subscriptionModelName} (Expires on: {subsValidity})"
|
590
|
+
except Exception as e:
|
591
|
+
logger.error(e)
|
592
|
+
subscriptionModelName = PKSubscriptionModel.No_Subscription.name
|
593
|
+
pass
|
594
|
+
if sendOTP:
|
595
|
+
if otpValue == 0:
|
596
|
+
updatedResults = f"We are having difficulty generating OTP for your {userText}. Please try again later or reach out to @ItsOnlyPK."
|
597
|
+
else:
|
598
|
+
updatedResults = f"Please use the following to login to PKScreener:\n{userText}\n<b>OTP</b> : <code>{otpValue}</code>\n\nCurrent subscription : <b>{subscriptionModelName}</b>.\nCurrent alerts balance: <b>₹ {alertUser.balance if alertUser is not None else 0}</b>. {subscriptionModelNames}"
|
599
|
+
else:
|
600
|
+
updatedResults = f"Current subscription: <b>{subscriptionModelName}</b>.\nCurrent alerts balance: <b>₹ {alertUser.balance if alertUser is not None else 0}</b>. {subscriptionModelNames}"
|
601
|
+
if hasattr(updateCarrier, "reply_text"):
|
602
|
+
updateCarrier.reply_text(text=sanitiseTexts(updatedResults), reply_markup=default_markup(user=user),parse_mode="HTML")
|
603
|
+
elif hasattr(updateCarrier, "edit_message_text"):
|
604
|
+
editMessageText(query=updateCarrier,editedText=sanitiseTexts(updatedResults),reply_markup=default_markup(user=user))
|
605
|
+
shareUpdateWithChannel(update=update, context=context, optionChoices=f"/otp\n{updatedResults}")
|
591
606
|
return START_ROUTES
|
592
607
|
|
593
608
|
def subscribeToScannerAlerts(update: Update, context: CallbackContext) -> str:
|
@@ -622,11 +637,11 @@ def subscribeToScannerAlerts(update: Update, context: CallbackContext) -> str:
|
|
622
637
|
return START_ROUTES
|
623
638
|
dbManager = DBManager()
|
624
639
|
alertUser = dbManager.alertsForUser(int(user.id))
|
625
|
-
inlineMenus = []
|
626
640
|
query.answer()
|
627
641
|
menuText = ""
|
628
642
|
requiredBalance = 40 if str(scanId).upper().startswith("P") else 31
|
629
|
-
|
643
|
+
# upi://pay?pa=PKScreener@APL&pn=PKScreener&cu=INR
|
644
|
+
payWall = "Please pay to subscribe:\n1. Using UPI(India) to <a href='https://tinyurl.com/v7h3t233'>PKScreener@APL</a> or\n2. Proudly <a href='https://github.com/sponsors/pkjmesra?frequency=recurring&sponsor=pkjmesra'>sponsor</a>\n\nPlease drop a message to @ItsOnlyPK along with UTR and Scan details on Telegram after paying to enable subscription manually or use \n\n/check UPI_UTR_HERE_After_Making_Payment to share transaction reference number to automatically update your balance after making payment via UPI.\nAfter that you can try re-subscribing!"
|
630
645
|
if alertUser is not None and alertUser.balance >= 0:
|
631
646
|
# User has some balance
|
632
647
|
if len(alertUser.scannerJobs) > 0:
|
@@ -636,7 +651,7 @@ def subscribeToScannerAlerts(update: Update, context: CallbackContext) -> str:
|
|
636
651
|
else:
|
637
652
|
if alertUser.balance < requiredBalance:
|
638
653
|
# Insufficient balance
|
639
|
-
menuText = f"You need at least
|
654
|
+
menuText = f"You need at least <b>₹ {requiredBalance}</b> to subscribe to <b>{scanId} alerts for a day</b> ! Your current balance <b>₹ {alertUser.balance}</b> is <b>insufficient</b>. {payWall}"
|
640
655
|
else:
|
641
656
|
# Sufficient balance to subscribe to scanId
|
642
657
|
subscribed = dbManager.updateAlertSubscriptionModel(user.id,requiredBalance,scanId)
|
@@ -647,19 +662,10 @@ def subscribeToScannerAlerts(update: Update, context: CallbackContext) -> str:
|
|
647
662
|
|
648
663
|
elif alertUser is None or alertUser.balance == 0:
|
649
664
|
# Either user is not subscribed or has 0 balance
|
650
|
-
menuText = f"You need at least
|
665
|
+
menuText = f"You need at least <b>₹ {requiredBalance}</b> to subscribe to <b>{scanId} alerts for a day</b> ! Your current balance <b>₹ 0</b> is <b>insufficient</b>. {payWall}"
|
651
666
|
|
652
|
-
|
653
|
-
|
654
|
-
"Start", callback_data="start"
|
655
|
-
)
|
656
|
-
)
|
657
|
-
keyboard = [inlineMenus]
|
658
|
-
reply_markup = InlineKeyboardMarkup(keyboard)
|
659
|
-
if query.message.text == menuText:
|
660
|
-
menuText = f"{PKDateUtilities.currentDateTime()}:\n{menuText}"
|
661
|
-
menuText = f"{menuText}\n\nClick /start if you want to restart the session."
|
662
|
-
query.edit_message_text(text=menuText, reply_markup=reply_markup)
|
667
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
668
|
+
editMessageText(query=query,editedText=sanitiseTexts(menuText),reply_markup=default_markup(user=user))
|
663
669
|
return START_ROUTES
|
664
670
|
|
665
671
|
|
@@ -756,11 +762,9 @@ def XScanners(update: Update, context: CallbackContext) -> str:
|
|
756
762
|
)
|
757
763
|
keyboard = [inlineMenus]
|
758
764
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
759
|
-
if
|
760
|
-
|
761
|
-
|
762
|
-
query.edit_message_text(text=menuText, reply_markup=reply_markup)
|
763
|
-
DBManager().getOTP(user.id,user.username,f"{user.first_name} {user.last_name}",validityIntervalInSeconds=configManager.otpInterval)
|
765
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
766
|
+
editMessageText(query=query,editedText=sanitiseTexts(menuText),reply_markup=reply_markup)
|
767
|
+
registerUser(user)
|
764
768
|
return START_ROUTES
|
765
769
|
|
766
770
|
def getinlineMenuListRow(keyboardRows=[]):
|
@@ -817,21 +821,23 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
817
821
|
start(update, context)
|
818
822
|
return START_ROUTES
|
819
823
|
|
820
|
-
|
824
|
+
reply_markup = default_markup(user=user)
|
825
|
+
if (len(selection) == 2 and selection[0] in ["X","B"] and selection[1] in ["P1","P2","P3"]) or \
|
826
|
+
(len(selection) == 4 and selection[0] in ["P"] and selection[3] in ["P1","P2","P3"]): # Piped scan index options
|
821
827
|
nextOption = ""
|
822
|
-
if selection[1] == "P2":
|
828
|
+
if selection[1] == "P2" or (selection[0] in ["P"] and selection[3] == "P2"):
|
823
829
|
skipMenus = INDEX_SKIP_MENUS_5_TO_9
|
824
830
|
nextOption = "P3"
|
825
|
-
elif selection[1] == "P3":
|
831
|
+
elif selection[1] == "P3" or (selection[0] in ["P"] and selection[3] == "P3"):
|
826
832
|
skipMenus = INDEX_SKIP_MENUS_10_TO_15
|
827
833
|
nextOption = "P1"
|
828
|
-
elif selection[1] == "P1":
|
834
|
+
elif selection[1] == "P1" or (selection[0] in ["P"] and selection[3] == "P1"):
|
829
835
|
skipMenus = INDEX_SKIP_MENUS_1_To_4
|
830
836
|
nextOption = "P2"
|
831
837
|
# Create the menu text labels
|
832
838
|
menuText = (
|
833
839
|
m1.renderForMenu(
|
834
|
-
m0.find(selection[0]),
|
840
|
+
m0.find(selection[0] if selection[0] not in ["P"] else "X"),
|
835
841
|
skip=skipMenus,
|
836
842
|
renderStyle=MenuRenderStyle.STANDALONE,
|
837
843
|
)
|
@@ -846,7 +852,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
846
852
|
|
847
853
|
# Create the menu buttons
|
848
854
|
mns = m1.renderForMenu(
|
849
|
-
m0.find(selection[0]),
|
855
|
+
m0.find(selection[0] if selection[0] not in ["P"] else "X"),
|
850
856
|
skip=skipMenus,
|
851
857
|
asList=True,
|
852
858
|
)
|
@@ -856,14 +862,12 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
856
862
|
for mnu in mns:
|
857
863
|
activeInlineRow = getinlineMenuListRow(keyboardRows)
|
858
864
|
activeInlineRow.append(
|
859
|
-
InlineKeyboardButton(mnu.menuKey, callback_data=str(f"C{selection[0]}_{mnu.menuKey}")))
|
865
|
+
InlineKeyboardButton(mnu.menuKey, callback_data=str(f"C{(selection[0]+'_'+selection[1]+'_'+selection[2]) if selection[0] in ["P"] else selection[0]}_{mnu.menuKey}")))
|
860
866
|
|
861
867
|
keyboard = keyboardRows
|
862
868
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
863
|
-
if
|
864
|
-
|
865
|
-
menuText = f"{menuText}\n\nClick /start if you want to restart the session."
|
866
|
-
query.edit_message_text(text=menuText, reply_markup=reply_markup)
|
869
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
870
|
+
editMessageText(query=query,editedText=sanitiseTexts(menuText),reply_markup=reply_markup)
|
867
871
|
return START_ROUTES
|
868
872
|
if len(selection) == 2 or (len(selection) == 3 and selection[2] == "P"):
|
869
873
|
if str(selection[1]).isnumeric():
|
@@ -984,7 +988,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
984
988
|
)
|
985
989
|
mns.append(menu().create("H", "Home", 2))
|
986
990
|
mns.append(menu().create("P", "More Options", 2))
|
987
|
-
elif str(selection[2]).isnumeric():
|
991
|
+
elif str(selection[2]).isnumeric() and selection[0].lower() not in ["p"]:
|
988
992
|
preSelection = f"{selection[0]}_{selection[1]}_{selection[2]}"
|
989
993
|
if selection[2] in SCANNER_MENUS_WITH_SUBMENU_SUPPORT:
|
990
994
|
menuText = m3.renderForMenu(
|
@@ -999,7 +1003,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
999
1003
|
skip=["0","M","Z"],
|
1000
1004
|
)
|
1001
1005
|
menuText = f"{menuText}\n\nH > Home"
|
1002
|
-
menuText = f"{menuText}\
|
1006
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
1003
1007
|
mns.append(menu().create("H", "Home", 2))
|
1004
1008
|
else:
|
1005
1009
|
if selection[2] == "4": # Last N days
|
@@ -1028,7 +1032,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
1028
1032
|
)
|
1029
1033
|
keyboard = keyboardRows
|
1030
1034
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
1031
|
-
|
1035
|
+
if (len(selection) >= 4 and selection[0].lower() not in ["p"]) or (len(selection) >= 3 and selection[0].lower() in ["p"]):
|
1032
1036
|
if len(selection) == 4:
|
1033
1037
|
if selection[2] in SCANNER_SUBMENUS_CHILDLEVEL_SUPPORT.keys() and selection[3] in SCANNER_SUBMENUS_CHILDLEVEL_SUPPORT[selection[2]]:
|
1034
1038
|
m0.renderForMenu(
|
@@ -1077,7 +1081,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
1077
1081
|
)
|
1078
1082
|
menuText = f"{menuText}\n\nH > Home"
|
1079
1083
|
mns.append(menu().create("H", "Home", 3))
|
1080
|
-
menuText = f"{menuText}\
|
1084
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session."
|
1081
1085
|
if mns is not None:
|
1082
1086
|
for mnu in mns:
|
1083
1087
|
activeInlineRow = getinlineMenuListRow(keyboardRows)
|
@@ -1086,21 +1090,57 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
1086
1090
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
1087
1091
|
if len(mns) == 0:
|
1088
1092
|
menuText = ''
|
1089
|
-
elif len(selection) > 4:
|
1090
|
-
|
1093
|
+
elif len(selection) > 4 or (len(selection) >= 3 and selection[0].lower() in ["p"]):
|
1094
|
+
if (selection[0] in 'P' and ((len(selection) >= 4 and len(selection[3]) == 0) or (len(selection) == 3 and str(selection[2]).isnumeric()))):
|
1095
|
+
preSelection = query.data.upper().replace("C", "")
|
1096
|
+
skipMenus = ["N"]
|
1097
|
+
skipMenus.extend(INDEX_SKIP_MENUS_1_To_4)
|
1098
|
+
# Create the menu text labels
|
1099
|
+
menuText = (
|
1100
|
+
m1.renderForMenu(
|
1101
|
+
m0.find("X"),
|
1102
|
+
skip=skipMenus,
|
1103
|
+
renderStyle=MenuRenderStyle.STANDALONE,
|
1104
|
+
)
|
1105
|
+
.replace(" ", "")
|
1106
|
+
.replace(" ", "")
|
1107
|
+
.replace(" ", "")
|
1108
|
+
.replace("\t", "")
|
1109
|
+
.replace(colorText.FAIL,"").replace(colorText.END,"").replace(colorText.WHITE,"")
|
1110
|
+
)
|
1111
|
+
menuText = f"{menuText}\n\nH > Home"
|
1112
|
+
menuText = f"{menuText}\n\nP2 > More Options"
|
1091
1113
|
|
1092
|
-
|
1093
|
-
|
1114
|
+
# Create the menu buttons
|
1115
|
+
mns = m1.renderForMenu(
|
1116
|
+
m0.find("X"),
|
1117
|
+
skip=skipMenus,
|
1118
|
+
asList=True,
|
1119
|
+
)
|
1120
|
+
mns.append(menu().create("H", "Home", 2))
|
1121
|
+
mns.append(menu().create("P2", "Next", 2))
|
1122
|
+
inlineMenus = []
|
1123
|
+
query.answer()
|
1124
|
+
for mnu in mns:
|
1125
|
+
inlineMenus.append(
|
1126
|
+
InlineKeyboardButton(
|
1127
|
+
mnu.menuKey, callback_data=str(f"C{preSelection}_{mnu.menuKey}")
|
1128
|
+
)
|
1129
|
+
)
|
1130
|
+
keyboard = [inlineMenus]
|
1131
|
+
reply_markup = InlineKeyboardMarkup(keyboard)
|
1132
|
+
elif len(mns) == 0:
|
1133
|
+
menuText = ''
|
1094
1134
|
|
1095
1135
|
if menuText is None or len(menuText) == 0:
|
1096
1136
|
optionChoices = (
|
1097
|
-
f"{selection[0]} > {selection[1]} > {selection[2]} > {selection[3]}"
|
1137
|
+
f"{selection[0]} > {selection[1]} > {selection[2]} > {selection[3]}".replace(" > >","").strip()
|
1098
1138
|
)
|
1099
|
-
optionChoices = f"{optionChoices}{f' > {selection[4]}' if len(selection) > 4 else ''}"
|
1139
|
+
optionChoices = f"{optionChoices}{f' > {selection[4]}' if len(selection) > 4 else ''}".replace(" > >","").strip()
|
1100
1140
|
expectedTime = f"{'10 to 15' if '> 15' in optionChoices else '1 to 2'}"
|
1101
|
-
menuText = f"Thank you for choosing {optionChoices.replace(' > > ','')}. You will receive the notification/results in about {expectedTime} minutes. It generally takes 1-2 minutes for NSE (2000+) stocks and 10-15 minutes for NASDAQ (7300+).\n\nPKScreener had been free for a long time, but owing to cost/budgeting issues, only a basic set of features will always remain free for everyone. Consider donating to help cover the basic server costs or subscribe to premium, if not subscribed yet:\n\nUPI (India): PKScreener@APL \n\nor
|
1141
|
+
menuText = f"Thank you for choosing {optionChoices.replace(' > > ','')}. You will receive the notification/results in about {expectedTime} minutes. It generally takes 1-2 minutes for NSE (2000+) stocks and 10-15 minutes for NASDAQ (7300+).\n\nPKScreener had been free for a long time, but owing to cost/budgeting issues, only a basic set of features will always remain free for everyone. Consider donating to help cover the basic server costs or subscribe to premium, if not subscribed yet:\n\nUPI (India): <a href='https://tinyurl.com/v7h3t233'>PKScreener@APL</a> \n\nor <a href='https://github.com/sponsors/pkjmesra?frequency=recurring&sponsor=pkjmesra'>sponsor</a>"
|
1102
1142
|
|
1103
|
-
reply_markup = default_markup(
|
1143
|
+
reply_markup = default_markup(user=user)
|
1104
1144
|
options = ":".join(selection)
|
1105
1145
|
shouldSendUpdate = launchScreener(
|
1106
1146
|
options=options,
|
@@ -1110,7 +1150,7 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
1110
1150
|
update=update,
|
1111
1151
|
)
|
1112
1152
|
if not shouldSendUpdate:
|
1113
|
-
|
1153
|
+
registerUser(user)
|
1114
1154
|
return START_ROUTES
|
1115
1155
|
try:
|
1116
1156
|
if optionChoices != "" and Channel_Id is not None and len(str(Channel_Id)) > 0:
|
@@ -1127,20 +1167,54 @@ def Level2(update: Update, context: CallbackContext) -> str:
|
|
1127
1167
|
sendUpdatedMenu(
|
1128
1168
|
menuText=menuText, update=update, context=context, reply_markup=reply_markup
|
1129
1169
|
)
|
1130
|
-
|
1170
|
+
scanRequest = optionChoices.replace(" ", "").replace(">", "_").replace(":","_").replace("_D","").upper()
|
1171
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1172
|
+
registerUser(user)
|
1131
1173
|
return START_ROUTES
|
1132
1174
|
|
1133
|
-
def default_markup(
|
1134
|
-
mns = m0.renderForMenu(
|
1175
|
+
def default_markup(user=None,monitorIndex=0):
|
1176
|
+
mns = m0.renderForMenu(selectedMenu=None,
|
1177
|
+
skip=TOP_LEVEL_SCANNER_SKIP_MENUS[:len(TOP_LEVEL_SCANNER_SKIP_MENUS)-1],
|
1178
|
+
asList=True,
|
1179
|
+
renderStyle=MenuRenderStyle.STANDALONE,
|
1180
|
+
)
|
1181
|
+
if (PKDateUtilities.isTradingTime() and not PKDateUtilities.isTodayHoliday()[0]) or ("PKDevTools_Default_Log_Level" in os.environ.keys()) or sys.argv[0].endswith(".py"):
|
1182
|
+
mns.append(menu().create(f"MI_{monitorIndex}", "👩💻 🚀 Intraday Monitor", 2))
|
1183
|
+
if user is not None and user.username == OWNER_USER:
|
1184
|
+
mns.append(menu().create(f"DV_0", ("✅ Enable Logging" if not configManager.logsEnabled else "🚫 Disable Logging"), 2))
|
1185
|
+
mns.append(menu().create(f"DV_1", "🔄 Restart Bot", 2))
|
1186
|
+
keyboard = []
|
1187
|
+
inlineMenus = []
|
1188
|
+
lastRowMenus = []
|
1189
|
+
rowIndex = 0
|
1190
|
+
iconDict = {"X":"🕵️♂️ 🔍 ","B":"📈 🎯 ","P":"🧨 💥 ","MI":"","DV":"","VS":"🔔 📣 ","start":"🟢 🏁 "}
|
1135
1191
|
for mnu in mns:
|
1136
|
-
if mnu.menuKey in TOP_LEVEL_SCANNER_MENUS:
|
1192
|
+
if mnu.menuKey[0:2] in TOP_LEVEL_SCANNER_MENUS:
|
1193
|
+
rowIndex +=1
|
1137
1194
|
inlineMenus.append(
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
)
|
1195
|
+
InlineKeyboardButton(
|
1196
|
+
iconDict.get(str(mnu.menuKey[0:2])) + mnu.menuText.split("(")[0],
|
1197
|
+
callback_data="C" + str(mnu.menuKey),
|
1142
1198
|
)
|
1143
|
-
|
1199
|
+
)
|
1200
|
+
if rowIndex % 2 == 0:
|
1201
|
+
keyboard.append(inlineMenus)
|
1202
|
+
inlineMenus = []
|
1203
|
+
lastRowMenus.append(
|
1204
|
+
InlineKeyboardButton(
|
1205
|
+
iconDict.get("VS") + "Subscriptions",
|
1206
|
+
callback_data="VS_",
|
1207
|
+
)
|
1208
|
+
)
|
1209
|
+
lastRowMenus.append(
|
1210
|
+
InlineKeyboardButton(
|
1211
|
+
iconDict.get("start") + "Start",
|
1212
|
+
callback_data="start",
|
1213
|
+
)
|
1214
|
+
)
|
1215
|
+
if len(inlineMenus) > 0:
|
1216
|
+
keyboard.append(inlineMenus)
|
1217
|
+
keyboard.append(lastRowMenus)
|
1144
1218
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
1145
1219
|
return reply_markup
|
1146
1220
|
|
@@ -1148,14 +1222,8 @@ def default_markup(inlineMenus):
|
|
1148
1222
|
def sendUpdatedMenu(menuText, update: Update, context, reply_markup, replaceWhiteSpaces=True):
|
1149
1223
|
try:
|
1150
1224
|
menuText.replace(" ", "").replace(" ", "").replace("\t", "").replace(colorText.FAIL,"").replace(colorText.END,"").replace(colorText.WHITE,"") if replaceWhiteSpaces else menuText
|
1151
|
-
menuText = f"{menuText}\
|
1152
|
-
|
1153
|
-
menuText = f"{PKDateUtilities.currentDateTime()}:\n{menuText}"
|
1154
|
-
update.callback_query.edit_message_text(
|
1155
|
-
text=menuText,
|
1156
|
-
parse_mode="HTML",
|
1157
|
-
reply_markup=reply_markup,
|
1158
|
-
)
|
1225
|
+
menuText = f"{menuText}\nClick /start if you want to restart the session." if "/start" not in menuText else menuText
|
1226
|
+
editMessageText(query=update.callback_query,editedText=sanitiseTexts(menuText),reply_markup=reply_markup)
|
1159
1227
|
except Exception as e:# pragma: no cover
|
1160
1228
|
logger.log(e)
|
1161
1229
|
start(update, context)
|
@@ -1176,16 +1244,14 @@ def launchScreener(options, user, context, optionChoices, update):
|
|
1176
1244
|
isBasicScanRequest = True
|
1177
1245
|
break
|
1178
1246
|
if not isBasicScanRequest:
|
1179
|
-
responseText = f"Thank you for choosing {scanRequest}!\n\nThis
|
1247
|
+
responseText = f"Thank you for choosing {scanRequest}!\n\nThis {'Backtest' if str(scanRequest).startswith('B') else 'Scan'} request is, however, protected and is only available to premium subscribers. It seems like you are not subscribed to the paid/premium subscription to PKScreener.\nPlease checkout all premium options by sending out a request:\n\n/OTP\n\nFor basic/unpaid users, you can try out the following:\n/X_0 StockCode1,StockCode2,etc.\n/X_N\n/X_1\n"
|
1180
1248
|
if update is not None and update.message is not None:
|
1181
|
-
update.message.reply_text(sanitiseTexts(responseText))
|
1249
|
+
update.message.reply_text(sanitiseTexts(responseText),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1182
1250
|
else:
|
1183
|
-
responseText = f"{responseText}\
|
1184
|
-
|
1185
|
-
text=responseText,
|
1186
|
-
reply_markup=default_markup([]),
|
1187
|
-
)
|
1251
|
+
responseText = f"{responseText}\nClick /start if you want to restart the session."
|
1252
|
+
editMessageText(query=update.callback_query,editedText=sanitiseTexts(responseText),reply_markup=default_markup(user=user))
|
1188
1253
|
shareUpdateWithChannel(update=update, context=context, optionChoices=responseText)
|
1254
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1189
1255
|
return False
|
1190
1256
|
|
1191
1257
|
if str(optionChoices.upper()).startswith("B"):
|
@@ -1199,13 +1265,10 @@ def launchScreener(options, user, context, optionChoices, update):
|
|
1199
1265
|
responseText = f"{responseText}\n\nStock-wise: https://pkjmesra.github.io/PKScreener/Backtest-Reports/PKScreener_{optionChoices}_backtest_result_StockSorted.html"
|
1200
1266
|
responseText = f"{responseText}\n\nOther Reports: https://pkjmesra.github.io/PKScreener/BacktestReports.html"
|
1201
1267
|
if update is not None and update.message is not None:
|
1202
|
-
update.message.reply_text(sanitiseTexts(responseText))
|
1268
|
+
update.message.reply_text(sanitiseTexts(responseText),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1203
1269
|
else:
|
1204
|
-
responseText = f"{responseText}\
|
1205
|
-
update.callback_query
|
1206
|
-
text=responseText,
|
1207
|
-
reply_markup=default_markup([]),
|
1208
|
-
)
|
1270
|
+
responseText = f"{responseText}\nClick /start if you want to restart the session."
|
1271
|
+
editMessageText(query=update.callback_query,editedText=sanitiseTexts(responseText),reply_markup=default_markup(user=user))
|
1209
1272
|
shareUpdateWithChannel(
|
1210
1273
|
update=update, context=context, optionChoices=optionChoices
|
1211
1274
|
)
|
@@ -1272,15 +1335,35 @@ def BBacktests(update: Update, context: CallbackContext) -> str:
|
|
1272
1335
|
]
|
1273
1336
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
1274
1337
|
responseText = "Backtesting NOT implemented yet in this Bot!\n\n\nYou can use backtesting by downloading the software from https://github.com/pkjmesra/PKScreener/"
|
1275
|
-
responseText = f"{responseText}\
|
1276
|
-
query
|
1277
|
-
|
1278
|
-
reply_markup=reply_markup,
|
1279
|
-
)
|
1280
|
-
DBManager().getOTP(user.id,user.username,f"{user.first_name} {user.last_name}",validityIntervalInSeconds=configManager.otpInterval)
|
1338
|
+
responseText = f"{responseText}\nClick /start if you want to restart the session."
|
1339
|
+
editMessageText(query=query,editedText=sanitiseTexts(responseText),reply_markup=default_markup(user=user))
|
1340
|
+
registerUser(user)
|
1281
1341
|
return START_ROUTES
|
1282
1342
|
|
1283
|
-
|
1343
|
+
def sendSubscriptionOption(update:Update,context:CallbackContext,scanId):
|
1344
|
+
updateCarrier = None
|
1345
|
+
if update is None:
|
1346
|
+
return
|
1347
|
+
else:
|
1348
|
+
if update.callback_query is not None:
|
1349
|
+
updateCarrier = update.callback_query
|
1350
|
+
if update.message is not None:
|
1351
|
+
updateCarrier = update.message
|
1352
|
+
if updateCarrier is None:
|
1353
|
+
return
|
1354
|
+
# Get user that sent /start and log his name
|
1355
|
+
user = updateCarrier.from_user
|
1356
|
+
reply_markup = {
|
1357
|
+
"inline_keyboard": [
|
1358
|
+
[{"text": f"Yes! Subscribe", "callback_data": f"SUB_{scanId}"}]
|
1359
|
+
],
|
1360
|
+
}
|
1361
|
+
message=f"Would you like to subscribe to this (<b>{scanId}</b>) automated scan alert for a day during market hours (NSE - IST timezone)? You will need to pay <b>₹ {'40' if str(scanId).upper().startswith('P') else '31'} (One time per day)</b> for automated alerts to only <b>{scanId}</b> all day on the day of subscription."
|
1362
|
+
if len(str(scanId).strip()) > 0 and not str(scanId).startswith("B"):
|
1363
|
+
context.bot.send_message(
|
1364
|
+
chat_id=user.id, text=message, reply_markup=reply_markup, parse_mode="HTML"
|
1365
|
+
)
|
1366
|
+
|
1284
1367
|
def end(update: Update, context: CallbackContext) -> str:
|
1285
1368
|
"""Returns `ConversationHandler.END`, which tells the
|
1286
1369
|
ConversationHandler that the conversation is over.
|
@@ -1288,10 +1371,8 @@ def end(update: Update, context: CallbackContext) -> str:
|
|
1288
1371
|
query = update.callback_query
|
1289
1372
|
query.answer()
|
1290
1373
|
responseText = "See https://github.com/pkjmesra/PKScreener/ for more details or join https://t.me/PKScreener. \n\n\nSee you next time!"
|
1291
|
-
responseText = f"{responseText}\
|
1292
|
-
query.
|
1293
|
-
text=responseText
|
1294
|
-
)
|
1374
|
+
responseText = f"{responseText}\nClick /start if you want to restart the session."
|
1375
|
+
editMessageText(query=query,editedText=sanitiseTexts(responseText),reply_markup=default_markup(query.from_user))
|
1295
1376
|
return ConversationHandler.END
|
1296
1377
|
|
1297
1378
|
|
@@ -1384,6 +1465,21 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1384
1465
|
if not bot_available:
|
1385
1466
|
start(update, context)
|
1386
1467
|
return START_ROUTES
|
1468
|
+
updateCarrier = None
|
1469
|
+
if update is None:
|
1470
|
+
return
|
1471
|
+
else:
|
1472
|
+
if hasattr(update, "callback_query") and update.callback_query is not None:
|
1473
|
+
updateCarrier = update.callback_query
|
1474
|
+
if hasattr(update, "message") and update.message is not None:
|
1475
|
+
updateCarrier = update.message
|
1476
|
+
if hasattr(update, "effective_message") and update.effective_message is not None:
|
1477
|
+
updateCarrier = update.effective_message
|
1478
|
+
if updateCarrier is None:
|
1479
|
+
return
|
1480
|
+
# Get user that sent /start and log his name
|
1481
|
+
user = updateCarrier.from_user
|
1482
|
+
|
1387
1483
|
msg = update.effective_message
|
1388
1484
|
try:
|
1389
1485
|
m = re.match(r"\s*/([0-9a-zA-Z_-]+)\s*(.*)", msg.text)
|
@@ -1414,7 +1510,7 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1414
1510
|
cmdText = f"{cmdText}\n/F_0 STOCK_CODE1,STOCK_CODE2 To find which all scanners had these stock codes(Reverse look up)"
|
1415
1511
|
|
1416
1512
|
if cmd.upper() in TOP_LEVEL_SCANNER_MENUS:
|
1417
|
-
shareUpdateWithChannel(update=update, context=context)
|
1513
|
+
shareUpdateWithChannel(update=update, context=context,optionChoices=msg)
|
1418
1514
|
m0.renderForMenu(
|
1419
1515
|
selectedMenu=None,
|
1420
1516
|
skip=TOP_LEVEL_SCANNER_SKIP_MENUS[:len(TOP_LEVEL_SCANNER_SKIP_MENUS)-1],
|
@@ -1437,8 +1533,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1437
1533
|
if cmd in ["x"]:
|
1438
1534
|
cmdText = f"{cmdText}\n\nFor option 0 <Screen stocks by the stock name>, please type in the command in the following format\n/X_0 SBIN\n or \n/X_0_0 SBIN\nand hit send where SBIN is the NSE stock code.For multiple stocks, you can type in \n/X_0 SBIN,ICICIBANK,OtherStocks\nYou can put in any number of stocks separated by space or comma(,)."
|
1439
1535
|
"""Send a message when the command /help is issued."""
|
1440
|
-
cmdText = f"{cmdText}\
|
1441
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1536
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1537
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1442
1538
|
return START_ROUTES
|
1443
1539
|
|
1444
1540
|
if update.message is None:
|
@@ -1446,7 +1542,7 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1446
1542
|
return START_ROUTES
|
1447
1543
|
|
1448
1544
|
if "x_0" in cmd or "x_0_0" in cmd or "b_0" in cmd or "g_0" in cmd or "f_0" in cmd:
|
1449
|
-
shareUpdateWithChannel(update=update, context=context)
|
1545
|
+
shareUpdateWithChannel(update=update, context=context,optionChoices=msg)
|
1450
1546
|
shouldScan = False
|
1451
1547
|
if len(args) > 0:
|
1452
1548
|
shouldScan = True
|
@@ -1467,17 +1563,19 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1467
1563
|
)
|
1468
1564
|
if result:
|
1469
1565
|
sendRequestSubmitted(cmd.upper(), update=update, context=context)
|
1566
|
+
scanRequest = cmd.upper().replace(" ", "").replace(">", "_").replace(":","_").replace("_D","").upper()
|
1567
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1470
1568
|
return START_ROUTES
|
1471
1569
|
else:
|
1472
1570
|
if cmd in ["x"]:
|
1473
1571
|
cmdText = "For option 0 <Screen stocks by the stock name>, please type in the command in the following format\n/X_0 SBIN or /X_0_0 SBIN and hit send where SBIN is the NSE stock code.For multiple stocks, you can type in /X_0 SBIN,ICICIBANK,OtherStocks . You can put in any number of stocks separated by space or comma(,)."
|
1474
1572
|
"""Send a message when the command /help is issued."""
|
1475
|
-
cmdText = f"{cmdText}\
|
1476
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1573
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1574
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1477
1575
|
return START_ROUTES
|
1478
1576
|
|
1479
1577
|
if "p_" in cmd:
|
1480
|
-
shareUpdateWithChannel(update=update, context=context)
|
1578
|
+
shareUpdateWithChannel(update=update, context=context,optionChoices=msg)
|
1481
1579
|
selection = cmd.split("_")
|
1482
1580
|
if len(selection) == 2:
|
1483
1581
|
m0.renderForMenu(
|
@@ -1504,8 +1602,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1504
1602
|
cmdText = (
|
1505
1603
|
f"{cmdText}\n\n{cmd.commandTextKey()} for {cmd.commandTextLabel()}"
|
1506
1604
|
)
|
1507
|
-
cmdText = f"{cmdText}\
|
1508
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1605
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1606
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1509
1607
|
return START_ROUTES
|
1510
1608
|
elif len(selection) == 3:
|
1511
1609
|
m0.renderForMenu(
|
@@ -1519,8 +1617,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1519
1617
|
cmdText = (
|
1520
1618
|
f"{cmdText}\n\n/{cmd.upper()}{indexCmd.commandTextKey().replace('/X','')} for Piped scan of {indexCmd.commandTextLabel().replace('Scanners >',cmd.upper()+' >')}"
|
1521
1619
|
)
|
1522
|
-
cmdText = f"{cmdText}\
|
1523
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1620
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1621
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1524
1622
|
return START_ROUTES
|
1525
1623
|
elif len(selection) == 4:
|
1526
1624
|
options = ":".join(selection)
|
@@ -1533,10 +1631,12 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1533
1631
|
)
|
1534
1632
|
if result:
|
1535
1633
|
sendRequestSubmitted(cmd.upper(), update=update, context=context)
|
1634
|
+
scanRequest = cmd.upper().replace(" ", "").replace(">", "_").replace(":","_").replace("_D","").upper()
|
1635
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1536
1636
|
return START_ROUTES
|
1537
1637
|
|
1538
1638
|
if "x_" in cmd or "b_" in cmd or "g_" in cmd:
|
1539
|
-
shareUpdateWithChannel(update=update, context=context)
|
1639
|
+
shareUpdateWithChannel(update=update, context=context,optionChoices=msg)
|
1540
1640
|
selection = cmd.split("_")
|
1541
1641
|
if len(selection) == 2:
|
1542
1642
|
m0.renderForMenu(
|
@@ -1568,14 +1668,16 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1568
1668
|
)
|
1569
1669
|
if result:
|
1570
1670
|
sendRequestSubmitted(cmd.upper(), update=update, context=context)
|
1671
|
+
scanRequest = cmd.upper().replace(" ", "").replace(">", "_").replace(":","_").replace("_D","").upper()
|
1672
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1571
1673
|
return START_ROUTES
|
1572
1674
|
elif (
|
1573
1675
|
"x_" in cmd and selectedMenu.menuKey == "0"
|
1574
1676
|
): # a specific stock by name
|
1575
1677
|
cmdText = "For option 0 <Screen stocks by the stock name>, please type in the command in the following format\n/X_0 SBIN or /X_0_0 SBIN and hit send where SBIN is the NSE stock code.For multiple stocks, you can type in /X_0 SBIN,ICICIBANK,OtherStocks. You can put in any number of stocks separated by space or comma(,)."
|
1576
1678
|
"""Send a message when the command /help is issued."""
|
1577
|
-
cmdText = f"{cmdText}\
|
1578
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1679
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1680
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1579
1681
|
return START_ROUTES
|
1580
1682
|
cmds = m2.renderForMenu(
|
1581
1683
|
selectedMenu=selectedMenu,
|
@@ -1587,8 +1689,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1587
1689
|
cmdText = (
|
1588
1690
|
f"{cmdText}\n\n{cmd.commandTextKey()} for {cmd.commandTextLabel()}"
|
1589
1691
|
)
|
1590
|
-
cmdText = f"{cmdText}\
|
1591
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1692
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1693
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1592
1694
|
return START_ROUTES
|
1593
1695
|
elif len(selection) == 3:
|
1594
1696
|
m0.renderForMenu(
|
@@ -1625,8 +1727,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1625
1727
|
)
|
1626
1728
|
for cmd in cmds:
|
1627
1729
|
cmdText = f"{cmdText}\n\n{cmd.commandTextKey()} for {cmd.commandTextLabel()}"
|
1628
|
-
cmdText = f"{cmdText}\
|
1629
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1730
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1731
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1630
1732
|
return START_ROUTES
|
1631
1733
|
else:
|
1632
1734
|
if selection[2] == "4": # Last N days
|
@@ -1683,8 +1785,8 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1683
1785
|
)
|
1684
1786
|
for cmd in cmds:
|
1685
1787
|
cmdText = f"{cmdText}\n\n{cmd.commandTextKey()} for {cmd.commandTextLabel()}"
|
1686
|
-
cmdText = f"{cmdText}\
|
1687
|
-
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"))
|
1788
|
+
cmdText = f"{cmdText}\nClick /start if you want to restart the session."
|
1789
|
+
update.message.reply_text(sanitiseTexts(f"Choose an option:\n{cmdText}"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1688
1790
|
return START_ROUTES
|
1689
1791
|
|
1690
1792
|
options = ":".join(selection)
|
@@ -1697,31 +1799,39 @@ def command_handler(update: Update, context: CallbackContext) -> None:
|
|
1697
1799
|
)
|
1698
1800
|
if result:
|
1699
1801
|
sendRequestSubmitted(cmd.upper(), update=update, context=context)
|
1802
|
+
scanRequest = cmd.upper().replace(" ", "").replace(">", "_").replace(":","_").replace("_D","").upper()
|
1803
|
+
sendSubscriptionOption(update,context,scanRequest)
|
1700
1804
|
return START_ROUTES
|
1701
1805
|
if cmd == "y" or cmd == "h":
|
1702
|
-
shareUpdateWithChannel(update=update, context=context)
|
1806
|
+
shareUpdateWithChannel(update=update, context=context,optionChoices=msg)
|
1703
1807
|
from pkscreener.globals import showSendConfigInfo, showSendHelpInfo
|
1704
1808
|
if cmd == "y":
|
1705
1809
|
showSendConfigInfo(defaultAnswer='Y',user=str(update.message.from_user.id))
|
1706
1810
|
elif cmd == "h":
|
1707
1811
|
showSendHelpInfo(defaultAnswer='Y',user=str(update.message.from_user.id))
|
1708
|
-
# result = launchScreener(
|
1709
|
-
# options=f"{cmd.upper()}:",
|
1710
|
-
# user=update.message.from_user,
|
1711
|
-
# context=context,
|
1712
|
-
# optionChoices=cmd.upper(),
|
1713
|
-
# update=update,
|
1714
|
-
# )
|
1715
|
-
# sendRequestSubmitted(cmd.upper(), update=update, context=context)
|
1716
1812
|
return START_ROUTES
|
1717
|
-
update.message.reply_text(sanitiseTexts(f"{cmd.upper()} : Not implemented yet!"))
|
1813
|
+
update.message.reply_text(sanitiseTexts(f"{cmd.upper()} : Not implemented yet!"),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1718
1814
|
help_command(update=update, context=context)
|
1719
1815
|
|
1720
1816
|
|
1721
1817
|
def sendRequestSubmitted(optionChoices, update, context):
|
1722
|
-
|
1723
|
-
update
|
1724
|
-
|
1818
|
+
updateCarrier = None
|
1819
|
+
if update is None:
|
1820
|
+
return
|
1821
|
+
else:
|
1822
|
+
if hasattr(update, "callback_query") and update.callback_query is not None:
|
1823
|
+
updateCarrier = update.callback_query
|
1824
|
+
if hasattr(update, "message") and update.message is not None:
|
1825
|
+
updateCarrier = update.message
|
1826
|
+
if hasattr(update, "effective_message") and update.effective_message is not None:
|
1827
|
+
updateCarrier = update.effective_message
|
1828
|
+
if updateCarrier is None:
|
1829
|
+
return
|
1830
|
+
# Get user that sent /start and log his name
|
1831
|
+
user = updateCarrier.from_user
|
1832
|
+
menuText = f"Thank you for choosing {optionChoices}. You will receive the notification/results in about 1-2 minutes! \n\nConsider donating to help keep this project going:\nUPI: <a href='https://tinyurl.com/v7h3t233'>PKScreener@APL</a> \nor <a href='https://github.com/sponsors/pkjmesra?frequency=recurring&sponsor=pkjmesra'>sponsor</a>"
|
1833
|
+
update.message.reply_text(sanitiseTexts(menuText),reply_markup=default_markup(user=user),parse_mode="HTML")
|
1834
|
+
# help_command(update=update, context=context)
|
1725
1835
|
shareUpdateWithChannel(
|
1726
1836
|
update=update, context=context, optionChoices=optionChoices
|
1727
1837
|
)
|
@@ -1762,15 +1872,16 @@ def help_command(update: Update, context: CallbackContext) -> None:
|
|
1762
1872
|
asList=True,
|
1763
1873
|
renderStyle=MenuRenderStyle.STANDALONE,
|
1764
1874
|
)
|
1765
|
-
cmdText = "
|
1875
|
+
cmdText = "/otp to generate an OTP to login to PKScreener desktop console\n/check UPI_UTR_HERE_After_Making_Payment to share transaction reference number to automatically enable subscription after making payment via UPI"
|
1766
1876
|
for cmd in cmds:
|
1767
|
-
|
1768
|
-
|
1877
|
+
if cmd.menuKey not in TOP_LEVEL_MARKUP_SKIP_MENUS:
|
1878
|
+
cmdText = f"{cmdText}\n{cmd.commandTextKey()} : {cmd.commandTextLabel()}"
|
1769
1879
|
|
1770
1880
|
"""Send a message when the command /help is issued."""
|
1771
1881
|
if update is not None and update.message is not None:
|
1772
1882
|
update.message.reply_text(
|
1773
|
-
sanitiseTexts(f"You can begin by typing in /start (Recommended) and hit send!\
|
1883
|
+
sanitiseTexts(f"You can begin by typing in /start (Recommended) and hit send!\nOR\nChoose an option:\n{cmdText}\n\nWe recommend you start by clicking on this /start"),
|
1884
|
+
reply_markup=default_markup(user=user),parse_mode="HTML"
|
1774
1885
|
) # \n\nThis bot restarts every hour starting at 5:30am IST until 10:30pm IST to keep it running on free servers. If it does not respond, please try again in a minutes to avoid the restart duration!
|
1775
1886
|
query = update.message
|
1776
1887
|
message = f"Name: <b>{query.from_user.first_name}</b>, Username:@{query.from_user.username} with ID: <b>@{str(query.from_user.id)}</b> began using the bot!"
|
@@ -1778,8 +1889,7 @@ def help_command(update: Update, context: CallbackContext) -> None:
|
|
1778
1889
|
context.bot.send_message(
|
1779
1890
|
chat_id=int(f"-{Channel_Id}"), text=message, parse_mode="HTML"
|
1780
1891
|
)
|
1781
|
-
|
1782
|
-
|
1892
|
+
registerUser(user)
|
1783
1893
|
|
1784
1894
|
def _shouldAvoidResponse(update):
|
1785
1895
|
sentFrom = []
|
@@ -1957,30 +2067,6 @@ def runpkscreenerbot(availability=True) -> None:
|
|
1957
2067
|
# ^ means "start of line/string"
|
1958
2068
|
# $ means "end of line/string"
|
1959
2069
|
# So ^ABC$ will only allow 'ABC'
|
1960
|
-
# conv_handler = ConversationHandler(
|
1961
|
-
# entry_points=[CommandHandler("start", start),
|
1962
|
-
# CommandHandler("otp", otp),
|
1963
|
-
# CommandHandler("check", matchUTR)],
|
1964
|
-
# states={
|
1965
|
-
# START_ROUTES: [
|
1966
|
-
# CallbackQueryHandler(XScanners, pattern="^" + str("CX") + "$"),
|
1967
|
-
# CallbackQueryHandler(XScanners, pattern="^" + str("CB") + "$"),
|
1968
|
-
# CallbackQueryHandler(PScanners, pattern="^" + str("CP") + "$"),
|
1969
|
-
# CallbackQueryHandler(XScanners, pattern="^" + str("CMI_")),
|
1970
|
-
# CallbackQueryHandler(XDevModeHandler, pattern="^" + str("CDV_")),
|
1971
|
-
# # CallbackQueryHandler(XScanners, pattern="^" + str("CG") + "$"),
|
1972
|
-
# CallbackQueryHandler(Level2, pattern="^" + str("CX_")),
|
1973
|
-
# CallbackQueryHandler(Level2, pattern="^" + str("CB_")),
|
1974
|
-
# CallbackQueryHandler(Level2, pattern="^" + str("CP_")),
|
1975
|
-
# CallbackQueryHandler(subscribeToScannerAlerts, pattern="^" + str("SUB_")),
|
1976
|
-
# # CallbackQueryHandler(Level2, pattern="^" + str("CG_")),
|
1977
|
-
# CallbackQueryHandler(end, pattern="^" + str("CZ") + "$"),
|
1978
|
-
# CallbackQueryHandler(start, pattern="^"),
|
1979
|
-
# ],
|
1980
|
-
# END_ROUTES: [],
|
1981
|
-
# },
|
1982
|
-
# fallbacks=[CommandHandler("start", start)],
|
1983
|
-
# )
|
1984
2070
|
conv_handler = ConversationHandler(
|
1985
2071
|
entry_points=[CommandHandler("start", start),
|
1986
2072
|
CommandHandler("otp", otp),
|
@@ -1997,6 +2083,7 @@ def runpkscreenerbot(availability=True) -> None:
|
|
1997
2083
|
CallbackQueryHandler(Level2, pattern="^" + str("CB_")),
|
1998
2084
|
CallbackQueryHandler(Level2, pattern="^" + str("CP_")),
|
1999
2085
|
CallbackQueryHandler(subscribeToScannerAlerts, pattern="^" + str("SUB_")),
|
2086
|
+
CallbackQueryHandler(viewSubscriptionOptions, pattern="^" + str("VS_")),
|
2000
2087
|
# CallbackQueryHandler(Level2, pattern="^" + str("CG_")),
|
2001
2088
|
CallbackQueryHandler(end, pattern="^" + str("CZ") + "$"),
|
2002
2089
|
CallbackQueryHandler(start, pattern="^"),
|
@@ -2025,6 +2112,7 @@ def runpkscreenerbot(availability=True) -> None:
|
|
2025
2112
|
if bot_available:
|
2026
2113
|
# Run the intraday monitor
|
2027
2114
|
initializeIntradayTimer()
|
2115
|
+
loadRegisteredUsers()
|
2028
2116
|
# Run the bot until the user presses Ctrl-C
|
2029
2117
|
# application.run_polling(allowed_updates=Update.ALL_TYPES)
|
2030
2118
|
# Start the Bot
|