from statemachine import StateMachine, State from pytgbot.api_types.sendable.reply_markup import InlineKeyboardButton,InlineKeyboardMarkup from . import fet,TARGET from urllib.parse import urljoin import logging logger=logging.getLogger() import datetime class TelegramStateMachine(StateMachine): def __init__(self,chat=None,*args,**kwargs): self.chat = chat super().__init__(*args,**kwargs) def send(self,text:str): self.chat.send_msg(text) def send_confirm(self, text:str): "Ask for a specific confirmation" keyboard = [[InlineKeyboardButton("OK", callback_data='ok'), InlineKeyboardButton("Repeat", callback_data='retry')], [ InlineKeyboardButton("Cancel", callback_data='cancel')] ] self.chat.send_msg(text, reply_markup=InlineKeyboardMarkup(keyboard)) class TelegramWorkflow(TelegramStateMachine): def process_message(self, text, is_callback=False): pass pass class CreatePostWorkflow(TelegramWorkflow): # init --> wait step 0 --> confirm --> wait step 1--> confirm -->wait_photo --> finished init =State('init', initial=True) # Initialize the workflow finished = State('finished') # Workflow has ended wait = State('wait',value=0) confirm =State('confirm') wait_photo=State('wait_photo') initialize = init.to(wait) # init --> wait entered = wait.to(confirm) # wait --> confirm next=confirm.to(wait) # confirm --> wait retry=confirm.to(wait) # confirm --> wait get_photo = confirm.to(wait_photo) # confirm --> wait_photo #finish = wait_photo.to(finished) finish = finished.from_(wait_photo, confirm) cancel = finished.from_(wait,confirm,wait_photo) steps= \ [ { "id": "title", "question": "Bitte einen Titel für den Post eingeben" }, { "id": "body", "question": "jetzt bitte den Text" } ] @property def current_field(self): print(self.steps[self.step]) return self.steps[self.step]["id"] @property def value(self): return self.p[self.current_field] def __init__(self,chat=None, debug=False,*args, **kwargs): super().__init__(chat, *args, **kwargs) self.p=dict() self.step=0 self.debug = debug self.initialize() # processing messages def process_message(self, text, is_callback=False,media=None): if self.debug: self.send("Workflow Input: %s" % text) if self.current_state==self.wait and text: self.p[self.current_field]=text if self.debug: self.send(str(self.p)) self.entered() elif self.current_state==self.confirm: if text=="ok": self.confirmed() elif text =='cancel': self.cancel() elif text == 'retry': self.retry() else: self.send("Ich warte noch auf eine Antwort bitte ok/cancel/retry") #elif self.current_state == self.wait_photo: if media: if self.debug: self.send("Danke fürs Foto") self.p["files"]={"image":media} if self.current_state == self.wait_photo: self.finish() #else: # self.retry() return "" def confirmed(self): if self.step >= len(self.steps)-1: self.get_photo() else: self.next() def on_next(self): self.step+=1 def on_retry(self): if self.debug: self.send("retry") def on_cancel(self): if self.debug: self.send("Canceled") def on_finish(self): #self.step=0 self.p["legacy_id"]="" self.p["post_type"]="N" self.p["has_agenda"]="False" self.p["public_date"]=datetime.date.today() self.send("posting to %s" % TARGET) r,d=fet.create(self.p) logger.info(r) if r ==201: self.send("Eingabe fertig:%s" % str(urljoin(TARGET,"posts/"+d["slug"]))) else: self.send("Fehler beim posten -- sorry") def on_enter_confirm(self): self.send_confirm("Bitte die Eingabe von %s bestaetigen" % self.value) def on_enter_wait(self): self.send(self.steps[self.step]["question"]) def on_get_photo(self): if not "files" in self.p: self.send("Bitte jetzt ein Foto schicken .. ") else: self.finish()