python - telegram bot sendMessage in specific date - python-2.7

I am terribly new in python and my progress is like a snail:(
I want to make a telegram bot that send a message at specific date and time. I used apscheduler and telepot libraries for that. and this is my code:
import telepot
import sys
import time
from time import sleep
from datetime import datetime
from apscheduler.scheduler import Scheduler
import logging
bot = telepot.Bot("***")
logging.basicConfig()
sched = Scheduler()
sched.start()
exec_date = datetime(2017, 9, 12 ,1,51,0)
def handle(msg):
content_type,chat_type,chat_id = telepot.glance(msg)
print(content_type,chat_type,chat_id)
if content_type == 'text' :
bot.sendMessage(chat_id,msg['text'])
def sendSimpleText():
# content_type,chat_type,chat_id = telepot.glance(msg)
# print(content_type,chat_type,chat_id)
#
# if content_type == 'text' :
chat_id = telepot.
bot.sendMessage(chat_id,'faez')
def main():
job = sched.add_date_job(sendSimpleText, exec_date)
while True:
sleep(1)
sys.stdout.write('.'); sys.stdout.flush()
# bot.message_loop(handle)
# # job = sched.add_date_job(sendSimpleText, '2017-09-11 21:35:00', ['testFuckBot'])
# while True:
# time.sleep(10)
if __name__ == '__main__':
main()
my question is what do I pass to sendSimpleText as argument in add_date_job? in this line:
job = sched.add_date_job(sendSimpleText, exec_date)
I know that msg is the message that user is typed so for add_date_job I have nothing?

You are used an old (2.1.2) version of APScheduler.
New version has a new syntax.
A function add_date_job no more available.
This is a worked solution for you:
import telepot
import sys
import time
from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
from telepot.loop import MessageLoop
import logging
bot = telepot.Bot("***YOUR_BOT_TOKEN***")
logging.basicConfig()
sched = BackgroundScheduler()
exec_date = datetime(2017, 9, 12 ,3,5,0)
def handle(msg):
content_type,chat_type,chat_id = telepot.glance(msg)
print(content_type,chat_type,chat_id)
if content_type == 'text' :
bot.sendMessage(chat_id,msg['text'])
def sendSimpleText(chat_id):
bot.sendMessage(chat_id,'faez')
def main():
MessageLoop(bot, handle).run_as_thread()
job = sched.add_job(sendSimpleText, run_date=exec_date, args=['**YOUR_TELEGRAM_ID**'])
while True:
time.sleep(1)
sys.stdout.write('.'); sys.stdout.flush()
if __name__ == '__main__':
sched.start()
main()

Related

telebot register_next_step_handler_by_chat_id not works in celery shared task

I have a small Telegram bot Django project and the bot needs to send a message to users that have been inactive for over an hour and then wait for input from the user using tg_nick_or_phone_input_handler and write it to the TelegramBotClientModel instance, sending more messages to chat.
def tg_nick_or_phone_input_handler(message):
chat_id = message.chat.id
bot_client = TelegramBotClientModel.objects.get(chat_id=chat_id)
bot_client.phone_or_nickname = message.text
bot_client.request_sent = True
bot_client.save()
bot.send_message(
chat_id=chat_id,
text='REQUEST SENT'
)
bot.send_message(
chat_id=chat_id,
text='some message'
)
import django.utils.timezone as tz
from celery import shared_task
from tg_funnel_bot.bot import bot
from .views import tg_nick_or_phone_input_handler
from .models import TelegramBotClientModel, BotMessagesSettingsModel
# celery task where should register next step handler
#shared_task(name='send_message_for_interrupted_dialog_after_one_hour')
def send_message_for_interrupted_dialog_after_one_hour():
bot_messages_settings = BotMessagesSettingsModel.objects.all().first()
inactive_for_hour_clients = TelegramBotClientModel.objects.filter(
updated_at__lte=tz.now() - tz.timedelta(minutes=5),
request_sent=False,
message_for_one_hour_inactive_sent=False
)
for inactive_client in inactive_for_hour_clients:
chat_id = inactive_client.chat_id
bot.send_message(
chat_id=chat_id,
text=bot_messages_settings.user_inactive_for_hour_message_text_first_part
)
bot.send_message(
chat_id=chat_id,
text=bot_messages_settings.user_inactive_for_hour_message_text_second_part,
reply_markup=bot_messages_settings.get_inactive_message_second_part_markup()
)
bot.register_next_step_handler_by_chat_id(
chat_id=chat_id,
callback=tg_nick_or_phone_input_handler
)
inactive_client = TelegramBotClientModel.objects.get(pk=inactive_client.pk)
inactive_client.message_for_one_hour_inactive_sent = True
inactive_client.save()
return tz.now()
bot.register_next_step_handler_by_chat_id not register handler and follow input in bot chat not processing.
Maybe I cannot use bot instance in another processes, but I can send messages and register_next_step_handler_by_chat_id works if use it in file with webhook update APIView like this:
from telebot import types
from rest_framework.views import APIView
from rest_framework.response import Response
from tg_funnel_bot.bot import bot
from .models import BotMessagesSettingsModel, TelegramBotClientModel
class UpdatesHandlerBotAPIView(APIView):
def post(self, request):
json_data = request.body.decode('UTF-8')
update_data = types.Update.de_json(json_data)
bot.process_new_updates([update_data])
return Response({'code': 200})
def after_loading_questions_data_handler(message):
chat_id = message.chat.id
bot_messages_settings = BotMessagesSettingsModel.objects.all().first()
after_loading_questions_data_text = bot_messages_settings.after_data_loading_text
bot.send_message(
chat_id=chat_id,
text=after_loading_questions_data_text
)
bot.register_next_step_handler_by_chat_id(
chat_id=chat_id,
callback=tg_nick_or_phone_input_handler
)
def tg_nick_or_phone_input_handler(message):
chat_id = message.chat.id
bot_client = TelegramBotClientModel.objects.get(chat_id=chat_id)
bot_client.phone_or_nickname = message.text
bot_client.request_sent = True
bot_client.save()
bot.send_message(
chat_id=chat_id,
text='REQUEST SENT'
)
bot.send_message(
chat_id=chat_id,
text='some text'
)
Celery configs
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_BEAT_SCHEDULE = {
'add-every-10-minutes': {
'task': 'send_message_for_interrupted_dialog_after_one_hour',
'schedule': crontab(minute='*/1'),
}
}
This is so strange, Give me a hand, please.

python populate.py wont populate my database

After writing the following code and expecting the output to be an updated database with random names, websites, etc., I get no error message and no updated database
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'First_project.settings')
import django
django.setup()
import random
from first_app.models import AccessRecord,Webpage,Topic
from faker import Faker
fakegen = Faker()
topics = ['Search','Social','Marketplace','News','Games']
def add_topic():
t = Topic.object.get_or_create(top_name=random.choice(topics))[0]
t.save()
return t
def populate(N=5):
for entry in range(N):
top = add_topic()
fake_url = fakegen.url()
fake_date = fakegen.date()
fake_name = fakegen.company()
webpg = webpage.objects.get_or_create(topic=top, url=fake_ur, name=fake_name)[0]
acc_rec = AccessRecord.object.get_or_create(name=webpg,date=fake_date)[0]
if __name__ == ' __main__':
print("populate")
populate(20)
print("populating complete!")
please what do I do?
i ran the whole code in my terminal and it populated the database

How to get record in string format from socketTextStream

I am trying to get each record from the socket stream. I want the record to be a string data type from lines. How to write the code in python? Thanks!
model = pipeline.PipelineModel.read().load(model_path)
sc = spark.sparkContext
ssc = StreamingContext(sc, 1)
lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))
if (lines is not None):
lines.foreachRDD(lambda rdd: rdd.foreach(processRecord))
def processRecord(record):
print("test")
...
from __future__ import print_function
import sys
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
if __name__ == "__main__":
sc = SparkContext(appName="Demo")
ssc = StreamingContext(sc, 1)
#record = ssc.socketTextStream("localhost", 9999)
record = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))
# print out each single word
record.flatMap(lambda line: line.split(" ")).pprint()
# start streaming
ssc.start()
# stop when the socket we are listening is dead
ssc.awaitTermination()
Thanks.

Alarm clock that interacted with google calendar API

I am looking for some help on an alarm clock that interacted with google calendar.
I have some problem with the code now where is not pulling down the events.
here is the errore i get now:
INFO:main:Polling calendar for events...
INFO:googleapiclient.discovery:URL being requested: GET https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json&singleEvents=true
INFO:main:Polling calendar for events...
INFO:googleapiclient.discovery:URL being requested: GET https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json&singleEvents=true
Process finished with exit code -1
# Inspired from 'Raspberry Pi as a Google Calender Alarm Clock'
# http://www.esologic.com/?p=634
#and this link as well https://github.com/ehamiter/get-on-the-bus
from datetime import datetime
import logging, os, platform, re, time
from apiclient import discovery
import httplib2
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run_flow
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Calendar API Python Quickstart'
FREQUENCY_CHECK = 5 # in second
MP3_FOLDER = 'E:\Users\Andrew.Price\PycharmProjects\SimpleAlarm\MP3'
CALENDAR_ID ='primary'
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class Alarm():
system = platform.system().lower()
flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.params['access_type'] = 'offline'
flow.params['approval_prompt'] = 'force'
storage = Storage('calendar.dat')
credentials = storage.get()
if credentials is None or credentials.invalid == True:
credentials = run_flow(flow, storage)
http = httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('calendar', 'v3', http=http)
#service = build(serviceName='calendar', version='v3', http=http, developerKey=API_KEY)
def check_credentials(self):
if self.credentials is None or self.credentials.invalid == True:
credentials = run_flow(self.flow, self.storage)
def calendar_event_query(self):
self.check_credentials()
today = datetime.today()
events = self.service.events().list(singleEvents=True, calendarId=CALENDAR_ID).execute()
#events = self.service.events().list(singleEvents=True).execute()
for i, event in enumerate(events['items']):
name = event['summary'].lower()
try:
start = event['start']['dateTime'][:-9]
except KeyError:
start = ''
description = event.get('description', '')
repeat = True if description.lower() == 'repeat' else False
now = today.strftime('%Y-%m-%dT%H:%M')
if start >= now:
logger.debug('Event #%s, Name: %s, Start: %s', i, name, start)
if start == now:
if name.startswith('say'):
name = re.sub(r'[^a-zA-Z0-9\s\']', '', name)
command = '{0} "{1}"'.format('say' if system == 'darwin' else 'espeak -ven+m2', name[4:])
logger.info('Event starting. Announcing \'%s\'...', name[4:])
else:
mp3_files = os.listdir(MP3_FOLDER)
mp3_name = name.replace(' ', '_') + '.mp3'
mp3_name = mp3_name if mp3_name in mp3_files else 'default.mp3'
command = 'mpg123 \'{}/{}\''.format(MP3_FOLDER, mp3_name)
logger.info('Event %s starting. Playing mp3 file %s...', name, mp3_name)
os.system(command)
if repeat == False:
time.sleep(60)
def poll(self):
logger.info('Polling calendar for events...')
self.calendar_event_query()
while True:
a = Alarm()
a.poll()
time.sleep(FREQUENCY_CHECK)
I have changed the code and got it to work using this code from Matt http://mattdyson.org/projects/alarmpi/#comment-20249
This is the code that I have changed. It is not pretty yet just works for now
from __future__ import print_function
import pytz
import dateutil.parser
import httplib2
from oauth2client import tools
from oauth2client import client
import datetime
import logging
from googleapiclient.discovery import build
from apiclient import discovery
from oauth2client.file import Storage
import Settings
import os
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
log = logging.getLogger('root')
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/calendar-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Smart-Alarm'
class AlarmGatherer:
def __init__(self):
#home_dir = os.path.expanduser('~')
#credential_dir = os.path.join(home_dir, 'calendar.dat')
#if not os.path.exists(credential_dir):
# os.makedirs(credential_dir)
#credential_path = os.path.join(credential_dir, 'client_secret.json')
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Smart-Alarm'
self.FLOW = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
self.storage = Storage('calendar.dat')
self.credentials = self.storage.get()
if not self.checkCredentials():
log.error("GCal credentials have expired")
log.warn("Remove calendar.dat and run 'python AlarmGatherer.py' to fix")
return
http = httplib2.Http()
http = self.credentials.authorize(http)
self.service = build('calendar', 'v3', http=http)
def checkCredentials(self):
return not (self.credentials is None or self.credentials.invalid == True)
def generateAuth(self):
self.credentials = tools.run_flow(self.FLOW, self.storage)
def getNextEvent(self, today=False):
log.debug("Fetching details of next event")
if not self.checkCredentials():
log.error("GCal credentials have expired")
log.warn("Remove calendar.dat and run 'python AlarmGatherer.py' to fix")
raise Exception("GCal credentials not authorized")
#time = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC
time = datetime.datetime.now()
if not today:
# We want to find events tomorrow, rather than another one today
log.debug("Skipping events from today")
#time += datetime.timedelta(days=1) # Move to tomorrow
time = time.replace(hour=10, minute=0, second=0, microsecond=0) # Reset to 10am the next day
# 10am is late enough that a night shift from today won't be caught, but a morning shift
# from tomorrow will be caught
result = self.service.events().list(
calendarId='primary',
timeMin="%sZ" % (time.isoformat()),
maxResults=1,
singleEvents=True,
orderBy='startTime'
).execute()
events = result.get('items', [])
return events[0]
def getNextEventTime(self, includeToday=False):
log.debug("Fetching next event time (including today=%s)" % (includeToday))
nextEvent = self.getNextEvent(today=includeToday)
start = dateutil.parser.parse(nextEvent['start']['dateTime'])
# start = dateutil.parser.parse(nextEvent['start']['dateTime'],ignoretz=True)
# start = start.replace(tzinfo=pytz.timezone('Africa/Johannesburg'))
return start
def getNextEventLocation(self, includeToday=False):
log.debug("Fetching next event location (including today=%s)" % (includeToday))
nextEvent = self.getNextEvent(today=includeToday)
if (nextEvent['location']):
return nextEvent['location']
return None
def getDefaultAlarmTime(self):
defaultTime = ('0600')
#defaultTime = self.settings.getint('default_wake')
#defaultTime = self.settings.getint('default_wake')
defaultHour = int(defaultTime[:2])
defaultMin = int(defaultTime[2:])
alarm = datetime.datetime.now(pytz.timezone('Africa/Johannesburg'))
alarm += datetime.timedelta(days=1) # Move to tomorrow
alarm = alarm.replace(hour=defaultHour, minute=defaultMin, second=0, microsecond=0)
return alarm
if __name__ == '__main__':
print("Running credential check")
a = AlarmGatherer()
try:
if not a.checkCredentials():
raise Exception("Credential check failed")
except:
print("Credentials not correct, please generate new code")
a.generateAuth()
a = AlarmGatherer()
print(a.getNextEventTime())
print(a.getNextEventLocation())

How to get ATR of a smard card from HID omnilkey

I want to get ATR of the smartcard. I am using HID omnikey 5321. I am following this link "http://pyscard.sourceforge.net/user-guide.html#requesting-any-card"
so far i have tried:
>>>from smartcard.CardType import AnyCardType
>>>from smartcard.CardRequest import CardRequest
>>>from smartcard.util import toHexString
>>>
>>> cardtype = AnyCardType()
>>> cardrequest = CardRequest( timeout=1, cardType=cardtype )
>>> cardservice = cardrequest.waitforcard()
>>>
>>>>>> cardservice.connection.connect()
i am getting error at the
cardservice.connection.connect()
error like:
raise CardConnectionException('Unable to connect with ptotocol[pcscprotocol] + . '+ScardGetErrorMessage(hresult)
CardConnectionException: Unable to conenct the card with T0 or T1 . Card is not responding to reset.
Because You dont specify the reader to connect:
r=readers()
#r[Number of reader list].
cardservice.connection = r[0].createConnection()
cardservice.connection.connect()
A simple Example:
from __future__ import print_function
from smartcard.Exceptions import NoCardException
from smartcard.System import readers
from smartcard.util import toHexString
for reader in readers():
try:
connection = reader.createConnection()
connection.connect()
print(reader, toHexString(connection.getATR()))
except NoCardException:
print(reader, 'no card inserted')
import sys
if 'win32' == sys.platform:
print('press Enter to continue')
sys.stdin.read(1)
-Another Selecting Reader:
from __future__ import print_function
from smartcard.Exceptions import NoCardException
from smartcard.System import readers
from smartcard.util import toHexString
from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
cardtype = AnyCardType()
r=readers()
cardrequest = CardRequest( timeout=10, cardType=cardtype )
cardservice = cardrequest.waitforcard()
print('Available Readers:')
for i in range(len(readers())):
print('[',i+1,']',r[i])
if(len(readers()) < 1):
print("\nNO AVAILABLE READERS!\n")
else:
print("Select you Reader: (Ctrl+C to Exit)")
my_input = input()
selectReader = clamp(int(my_input)-1,0,len(readers()))
print('Selected: ',r[selectReader])
cardservice.connection = r[selectReader].createConnection()
cardservice.connection.connect()
try:
print('Card ATR:',toHexString(cardservice.connection.getATR()),file=f)
except:
print("Cant not Get ATR")
.
Full Information:
https://pyscard.sourceforge.io/pyscard-framework.html#framework-samples
https://github.com/LudovicRousseau/pyscard
https://pyscard.sourceforge.io/user-guide.html
In python, you can use the pyscard library to interact with smart cards, there is an example that should help you display the ATR at http://pyscard.sourceforge.net/pyscard-framework.html#framework-samples