2222import hashlib
2323
2424from . import crypto
25+ from .context import ctx
2526
2627
2728DIGEST = hashlib .md5
3132class ButtonsRow :
3233 """A row of an inline keyboard"""
3334
34- def __init__ (self , bot ):
35+ def __init__ (self ):
3536 self ._content = []
36- self ._bot = bot
3737
3838 def url (self , label , url ):
3939 """Open an URL when the button is pressed"""
4040 self ._content .append ({"text" : label , "url" : url })
4141
4242 def callback (self , label , callback , data = None ):
4343 """Trigger a callback when the button is pressed"""
44+ def generate_callback_data ():
45+ c = ctx ()
46+
47+ name = "%s:%s" % (c .component_name (), callback )
48+ return get_callback_data (c .bot , name , data )
49+
4450 self ._content .append ({
4551 "text" : label ,
46- "callback_data" : get_callback_data ( self . _bot , callback , data ) ,
52+ "callback_data" : generate_callback_data ,
4753 })
4854
4955 def switch_inline_query (self , label , query = "" , current_chat = False ):
@@ -59,29 +65,46 @@ def switch_inline_query(self, label, query="", current_chat=False):
5965 "switch_inline_query" : query ,
6066 })
6167
68+ def _get_content (self ):
69+ """Get the content of this row"""
70+ for item in self ._content :
71+ new = item .copy ()
72+
73+ # Replace any callable with its value
74+ # This allows to dynamically generate field values
75+ for key , value in new .items ():
76+ if callable (value ):
77+ new [key ] = value ()
78+
79+ yield new
80+
6281
6382class Buttons :
6483 """Factory for inline keyboards"""
6584
66- def __init__ (self , bot ):
85+ def __init__ (self ):
6786 self ._rows = {}
68- self ._bot = bot
6987
7088 def __getitem__ (self , index ):
7189 if index not in self ._rows :
72- self ._rows [index ] = ButtonsRow (self . _bot )
90+ self ._rows [index ] = ButtonsRow ()
7391 return self ._rows [index ]
7492
7593 def _serialize_attachment (self ):
7694 rows = [
77- row ._content for i , row in sorted (
95+ list ( row ._get_content ()) for i , row in sorted (
7896 tuple (self ._rows .items ()), key = lambda i : i [0 ]
7997 )
8098 ]
8199
82100 return {"inline_keyboard" : rows }
83101
84102
103+ def buttons ():
104+ """Create a new inline keyboard"""
105+ return Buttons ()
106+
107+
85108def parse_callback_data (bot , raw ):
86109 """Parse the callback data generated by botogram and return it"""
87110 raw = raw .encode ("utf-8" )
0 commit comments