2
0
mirror of https://github.com/ComradCollective/Comrad synced 2024-11-03 23:15:33 +00:00

got requests async using asyncio and threads

This commit is contained in:
quadrismegistus 2020-09-23 19:47:42 +01:00
parent bfc616148b
commit 348dc4b30b
6 changed files with 814 additions and 105 deletions

View File

@ -22,7 +22,7 @@ os.environ['KIVY_EVENTLOOP'] = 'asyncio'
# loop.set_debug(True)
# prefer experimental kivy if possible
sys.path.insert(0,os.path.join(PATH_KOMRADE_LIB,'KivyMD'))
# sys.path.insert(0,os.path.join(PATH_KOMRADE_LIB,'KivyMD'))
import kivymd
# print(kivymd.__file__)
# exit()
@ -103,14 +103,15 @@ class MyLayout(MDBoxLayout):
from komrade.app.screens.dialog import MDDialog2
class ProgressPopup(MDDialog): pass
class ProgressPopup(MDDialog2): pass
class MessagePopup(MDDialog):
class MessagePopup(MDDialog2):
pass
# def __init__(self,*x,**y):
# super().__init__(*x,**y)
@ -124,9 +125,13 @@ class MessagePopup(MDDialog):
pass
class MessagePopupCard(MDDialog):
class MessagePopupCard(MDDialog2):
def __init__(self,*x,**y):
# y['color_bg']=rgb(*COLOR_CARD)
y['type']='custom'
y['overlay_color']=(0,0,0,0)
super().__init__(*x,**y)
# self.color_bg=rgb(*COLOR_CARD)
self.ok_to_continue=False
#def on_dismiss(self):
@ -139,7 +144,110 @@ class MessagePopupCard(MDDialog):
# logger.info(str(self.msg_dialog))
class BooleanInputPopupCard(MDDialog):
class TextInputPopupCard(MDDialog2):
def say(self,x):
self.ok_to_continue=True
self.response=self.field.text
return self.response
def __init__(self,msg,password=False,input_name='',komrade_name='',*x,**y):
self.ok_to_continue=False
self.response=None
title=msg
from komrade.app.screens.login.login import UsernameField,PasswordField,UsernameLayout,UsernameLabel
self.layout=MDBoxLayout()
self.layout.orientation='vertical'
self.layout.cols=1
self.layout.size_hint=('333sp','222sp')
# self.layout.md_bg_color=(1,1,0,1)
self.layout.adaptive_height=True
self.layout.height=self.layout.minimum_height
self.layout.spacing='0sp'
self.layout.padding='0sp'
# self.layout.size=('333sp','333sp')
self.field_layout=UsernameLayout()
self.field = PasswordField() if password else UsernameField()
self.field.line_color_focus=rgb(*COLOR_TEXT)
self.field.line_color_normal=rgb(*COLOR_TEXT,a=0.25)
self.field.font_name=FONT_PATH
self.field_label = UsernameLabel(text='password:' if password else input_name)
self.field_label.font_name=FONT_PATH
if title:
self.title_label = UsernameLabel(text=title)
self.title_label.halign='center'
self.title_label.pos_hint={'center_x':0.5}
self.title_label.font_name=FONT_PATH
#self.field_layout.add_widget(self.title_label)
self.layout.add_widget(self.title_label)
self.field_layout.add_widget(self.field_label)
self.field_layout.add_widget(self.field)
self.layout.add_widget(self.field_layout)
# do dialog's intro
super().__init__(
type='custom',
text=msg,
content_cls=self.layout,
buttons=[
MDFlatButton(
text="cancel",
text_color=rgb(*COLOR_TEXT),
md_bg_color = (0,0,0,1),
theme_text_color='Custom',
on_release=self.dismiss,
font_name=FONT_PATH
),
MDFlatButton(
text="enter",
text_color=rgb(*COLOR_TEXT),
md_bg_color = (0,0,0,1),
theme_text_color='Custom',
on_release=self.say,
font_name=FONT_PATH
),
],
color_bg = rgb(*COLOR_CARD)
)
self.ids.text.text_color=rgb(*COLOR_TEXT)
self.ids.text.font_name=FONT_PATH
self.size=('333sp','111sp')
self.adaptive_height=True
# wait and show
async def open(self,maxwait=666,pulse=0.1):
super().open()
await asyncio.sleep(pulse)
waited=0
while not self.ok_to_continue:
await asyncio.sleep(pulse)
waited+=pulse
if waited>maxwait: break
# logger.info(f'waiting for {waited} seconds... {self.ok_to_continue} {self.response}')
return self.response
class BooleanInputPopupCard(MDDialog2):
def say_yes(self,x):
# logger.info('say_yes got:',str(x))
self.ok_to_continue=True
@ -180,11 +288,8 @@ class BooleanInputPopupCard(MDDialog):
color_bg = rgb(*COLOR_CARD)
)
self.md_bg_color='1,1,0,1'
#self.ids.spacer_top_box.md_bg_color=(1,1,0,1)
#self.ids.spacer_bottom_box.md_bg_color=(1,1,0,1)
#self.ids.text.text_color=rgb(*COLOR_TEXT)
#self.ids.text.font_name=FONT_PATH
self.ids.text.text_color=rgb(*COLOR_TEXT)
self.ids.text.font_name=FONT_PATH
# wait and show
async def open(self,maxwait=666,pulse=0.1):
@ -198,19 +303,6 @@ class BooleanInputPopupCard(MDDialog):
# logger.info(f'waiting for {waited} seconds... {self.ok_to_continue} {self.response}')
return self.response
# class MessageInputPopupCard(MDDialog):
# def __init__(self,*x,**y):
# super().__init__(*x,**y)
# self.ok_to_continue=False
# def on_touch_down(self,touch):
# self.ok_to_continue=True
# logger.info('oof!')
# if hasattr(self,'msg_dialog'):
# logger.info(str(self.msg_dialog))
class MyBoxLayout(MDBoxLayout): pass
class MyLabel(MDLabel): pass
@ -475,60 +567,29 @@ class MainApp(MDApp, Logger):
self.dialog.open()
#stop
async def get_input(self,msg,komrade_name='Telephone',get_pass=False,**y):
async def get_input(self,msg,komrade_name='Telephone',get_pass=False,yesno=False,**y):
from komrade.app.screens.feed.feed import PostCardInputPopup
if hasattr(self,'msg_dialog') and self.msg_dialog:# and hasattr(self.msg_dialog,'card') and self.msg_dialog.card:
self.msg_dialog0=self.msg_dialog
self.msg_dialog0.dismiss()
self.msg_dialog0=None
self.msg_dialog = BooleanInputPopupCard(msg)
# self.msg_dialog.card = postcard = PostCardInputPopup({
# 'author':komrade_name,
# 'author_prefix':'@',
# 'to_name':'me',
# 'content':msg,
# 'timestamp':time.time(),
# 'author_label_font_size':'18sp',
# **y
# },
# msg_dialog=self.msg_dialog)
# postcard.font_size='16sp'
# postcard.size_hint=(None,None)
# postcard.size=('600sp','600sp')
# postcard.ok_to_continue=False
# if get_pass:
# from komrade.app.screens.login.login import PasswordField
# self.msg_dialog.field = field = PasswordField()
# field.line_color_focus=rgb(*COLOR_TEXT)
# field.line_color_normal=rgb(*COLOR_TEXT,a=0.25)
# field.font_name='assets/font.otf'
# postcard.add_widget(field)
# self.msg_dialog.add_widget(postcard)
if yesno:
self.msg_dialog = BooleanInputPopupCard(msg,komrade_name=komrade_name,**y)
else:
self.msg_dialog = TextInputPopupCard(msg,password=get_pass,komrade_name=komrade_name,**y)
response = await self.msg_dialog.open()
logger.info(f'get_input got user response {response}')
return response
if hasattr(self,'msg_dialog0'):
self.msg_dialog0.remove_widget(self.msg_dialog0.card)
self.root.remove_widget(self.msg_dialog0)
await asyncio.sleep(0.1)
while not self.msg_dialog.ok_to_continue:
await asyncio.sleep(0.1)
# logger.info(str(postcard), postcard.ok_to_continue,'??')
# self.msg_dialog.dismiss()
# self.msg_dialog.remove_widget(postcard)
# self.msg_dialog.card = postcard = self.msg_dialog = None
await asyncio.sleep(0.1)
return {'success':True, 'status':'Delivered popup message'}
async def stat(self,msg,komrade_name='Telephone',pause=False,get_pass=False,**y):
from komrade.app.screens.feed.feed import PostCard,PostCardPopup
if hasattr(self,'msg_dialog') and self.msg_dialog:# and hasattr(self.msg_dialog,'card') and self.msg_dialog.card:
self.msg_dialog0=self.msg_dialog
self.msg_dialog0.dismiss()
self.msg_dialog = MessagePopupCard()
# self.msg_dialog.ids.msg_label.text=msg
@ -550,10 +611,9 @@ class MainApp(MDApp, Logger):
self.msg_dialog.add_widget(postcard)
self.msg_dialog.open()
self.msg_dialog.open(animation=False)
if hasattr(self,'msg_dialog0'):
self.msg_dialog0.remove_widget(self.msg_dialog0.card)
self.root.remove_widget(self.msg_dialog0)
await asyncio.sleep(0.1)

View File

@ -0,0 +1,598 @@
"""
Components/Dialog
=================
.. seealso::
`Material Design spec, Dialogs <https://material.io/components/dialogs>`_
.. rubric:: Dialogs inform users about a task and can contain critical
information, require decisions, or involve multiple tasks.
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialogs.png
:align: center
Usage
-----
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog2
KV = '''
FloatLayout:
MDFlatButton:
text: "ALERT DIALOG"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_alert_dialog()
'''
class Example(MDApp):
dialog = None
def build(self):
return Builder.load_string(KV)
def show_alert_dialog(self):
if not self.dialog:
self.dialog = MDDialog2(
text="Discard draft?",
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color
),
MDFlatButton(
text="DISCARD", text_color=self.theme_cls.primary_color
),
],
)
self.dialog.open()
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/alert-dialog.png
:align: center
"""
__all__ = ("MDDialog2",)
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import (
ListProperty,
NumericProperty,
ObjectProperty,
OptionProperty,
StringProperty,
)
from kivy.uix.modalview import ModalView
from kivymd.material_resources import DEVICE_TYPE
from kivymd.theming import ThemableBehavior
from kivymd.uix.button import BaseButton
from kivymd.uix.card import MDSeparator
from kivymd.uix.list import BaseListItem
Builder.load_string(
"""
#:import images_path kivymd.images_path
<BaseDialog>
background: '{}/transparent.png'.format(images_path)
canvas.before:
PushMatrix
RoundedRectangle:
pos: self.pos
size: self.size
radius: [5]
Scale:
origin: self.center
x: root._scale_x
y: root._scale_y
canvas.after:
PopMatrix
<MDDialog2>
MDCard:
id: container
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
elevation: 4
md_bg_color: 0, 0, 0, 0
padding: "24dp", "24dp", "8dp", "8dp"
canvas:
Color:
rgba: root.color_bg #root.theme_cls.bg_dark
RoundedRectangle:
pos: self.pos
size: self.size
radius: root.radius
MDLabel:
id: title
text: root.title
font_style: "H6"
bold: True
markup: True
size_hint_y: None
height: self.texture_size[1]
valign: "top"
BoxLayout:
id: spacer_top_box
size_hint_y: None
height: root._spacer_top
MDLabel:
id: text
text: root.text
font_style: "Body1"
theme_text_color: "Custom"
text_color: root.theme_cls.disabled_hint_text_color
size_hint_y: None
height: self.texture_size[1]
markup: True
ScrollView:
id: scroll
size_hint_y: None
height: root._scroll_height
MDGridLayout:
id: box_items
adaptive_height: True
cols: 1
BoxLayout:
id: spacer_bottom_box
size_hint_y: None
height: self.minimum_height
AnchorLayout:
id: root_button_box
size_hint_y: None
height: "52dp"
anchor_x: "right"
MDBoxLayout:
id: button_box
adaptive_size: True
spacing: "8dp"
"""
)
class BaseDialog(ThemableBehavior, ModalView):
_scale_x = NumericProperty(1)
_scale_y = NumericProperty(1)
class MDDialog2(BaseDialog):
title = StringProperty()
"""
Title dialog.
.. code-block:: python
self.dialog = MDDialog2(
title="Reset settings?",
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color
),
MDFlatButton(
text="ACCEPT", text_color=self.theme_cls.primary_color
),
],
)
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-title.png
:align: center
:attr:`title` is an :class:`~kivy.properties.StringProperty`
and defaults to `''`.
"""
text = StringProperty()
"""
Text dialog.
.. code-block:: python
self.dialog = MDDialog2(
title="Reset settings?",
text="This will reset your device to its default factory settings.",
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color
),
MDFlatButton(
text="ACCEPT", text_color=self.theme_cls.primary_color
),
],
)
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-text.png
:align: center
:attr:`text` is an :class:`~kivy.properties.StringProperty`
and defaults to `''`.
"""
radius = ListProperty([7, 7, 7, 7])
color_bg=ListProperty([0,0,0,1])
"""
Dialog corners rounding value.
.. code-block:: python
self.dialog = MDDialog2(
text="Oops! Something seems to have gone wrong!",
radius=[20, 7, 20, 7],
)
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-radius.png
:align: center
:attr:`radius` is an :class:`~kivy.properties.ListProperty`
and defaults to `[7, 7, 7, 7]`.
"""
buttons = ListProperty()
"""
List of button objects for dialog.
Objects must be inherited from :class:`~kivymd.uix.button.BaseButton` class.
.. code-block:: python
self.dialog = MDDialog2(
text="Discard draft?",
buttons=[
MDFlatButton(text="CANCEL"), MDRaisedButton(text="DISCARD"),
],
)
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-buttons.png
:align: center
:attr:`buttons` is an :class:`~kivy.properties.ListProperty`
and defaults to `[]`.
"""
items = ListProperty()
"""
List of items objects for dialog.
Objects must be inherited from :class:`~kivymd.uix.list.BaseListItem` class.
With type 'simple'
-----------------
.. code-block:: python
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog2
from kivymd.uix.list import OneLineAvatarListItem
KV = '''
<Item>
ImageLeftWidget:
source: root.source
FloatLayout:
MDFlatButton:
text: "ALERT DIALOG"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_simple_dialog()
'''
class Item(OneLineAvatarListItem):
divider = None
source = StringProperty()
class Example(MDApp):
dialog = None
def build(self):
return Builder.load_string(KV)
def show_simple_dialog(self):
if not self.dialog:
self.dialog = MDDialog2(
title="Set backup account",
type="simple",
items=[
Item(text="user01@gmail.com", source="user-1.png"),
Item(text="user02@gmail.com", source="user-2.png"),
Item(text="Add account", source="add-icon.png"),
],
)
self.dialog.open()
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-items.png
:align: center
With type 'confirmation'
-----------------------
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog2
from kivymd.uix.list import OneLineAvatarIconListItem
KV = '''
<ItemConfirm>
on_release: root.set_icon(check)
CheckboxLeftWidget:
id: check
group: "check"
FloatLayout:
MDFlatButton:
text: "ALERT DIALOG"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_confirmation_dialog()
'''
class ItemConfirm(OneLineAvatarIconListItem):
divider = None
def set_icon(self, instance_check):
instance_check.active = True
check_list = instance_check.get_widgets(instance_check.group)
for check in check_list:
if check != instance_check:
check.active = False
class Example(MDApp):
dialog = None
def build(self):
return Builder.load_string(KV)
def show_confirmation_dialog(self):
if not self.dialog:
self.dialog = MDDialog2(
title="Phone ringtone",
type="confirmation",
items=[
ItemConfirm(text="Callisto"),
ItemConfirm(text="Luna"),
ItemConfirm(text="Night"),
ItemConfirm(text="Solo"),
ItemConfirm(text="Phobos"),
ItemConfirm(text="Diamond"),
ItemConfirm(text="Sirena"),
ItemConfirm(text="Red music"),
ItemConfirm(text="Allergio"),
ItemConfirm(text="Magic"),
ItemConfirm(text="Tic-tac"),
],
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color
),
MDFlatButton(
text="OK", text_color=self.theme_cls.primary_color
),
],
)
self.dialog.open()
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-confirmation.png
:align: center
:attr:`items` is an :class:`~kivy.properties.ListProperty`
and defaults to `[]`.
"""
type = OptionProperty(
"alert", options=["alert", "simple", "confirmation", "custom"]
)
"""
Dialog type.
Available option are `'alert'`, `'simple'`, `'confirmation'`, `'custom'`.
:attr:`type` is an :class:`~kivy.properties.OptionProperty`
and defaults to `'alert'`.
"""
content_cls = ObjectProperty()
"""
Custom content class.
.. code-block::
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog2
KV = '''
<Content>
orientation: "vertical"
spacing: "12dp"
size_hint_y: None
height: "120dp"
MDTextField:
hint_text: "City"
MDTextField:
hint_text: "Street"
FloatLayout:
MDFlatButton:
text: "ALERT DIALOG"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_confirmation_dialog()
'''
class Content(BoxLayout):
pass
class Example(MDApp):
dialog = None
def build(self):
return Builder.load_string(KV)
def show_confirmation_dialog(self):
if not self.dialog:
self.dialog = MDDialog2(
title="Address:",
type="custom",
content_cls=Content(),
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color
),
MDFlatButton(
text="OK", text_color=self.theme_cls.primary_color
),
],
)
self.dialog.open()
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-custom.png
:align: center
:attr:`content_cls` is an :class:`~kivy.properties.ObjectProperty`
and defaults to `'None'`.
"""
_scroll_height = NumericProperty("28dp")
_spacer_top = NumericProperty("24dp")
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.color_bg = kwargs.get('color_bg',self.theme_cls.bg_dark)
if 'color_bg' in kwargs:
del kwargs['color_bg']
if self.size_hint == [1, 1] and DEVICE_TYPE == "mobile":
self.size_hint = (None, None)
self.width = dp(280)
elif self.size_hint == [1, 1] and DEVICE_TYPE == "desktop":
self.size_hint = (None, None)
self.width = dp(560)
if not self.title:
self._spacer_top = 0
if not self.buttons:
self.ids.root_button_box.height = 0
else:
self.create_buttons()
update_height = False
if self.type in ("simple", "confirmation"):
if self.type == "confirmation":
self.ids.spacer_top_box.add_widget(MDSeparator())
self.ids.spacer_bottom_box.add_widget(MDSeparator())
self.create_items()
if self.type == "custom":
if self.content_cls:
self.ids.container.remove_widget(self.ids.scroll)
self.ids.container.remove_widget(self.ids.text)
self.ids.spacer_top_box.add_widget(self.content_cls)
self.ids.spacer_top_box.padding = (0, "24dp", "16dp", 0)
update_height = True
if self.type == "alert":
self.ids.scroll.bar_width = 0
if update_height:
Clock.schedule_once(self.update_height)
def update_height(self, *_):
self._spacer_top = self.content_cls.height + dp(24)
def on_open(self):
# TODO: Add scrolling text.
self.height = self.ids.container.height
def set_normal_height(self):
self.size_hint_y = 0.8
def get_normal_height(self):
return (
(Window.height * 80 / 100)
- self._spacer_top
- dp(52)
- self.ids.container.padding[1]
- self.ids.container.padding[-1]
- 100
)
def edit_padding_for_item(self, instance_item):
instance_item.ids._left_container.x = 0
instance_item._txt_left_pad = "56dp"
def create_items(self):
self.ids.container.remove_widget(self.ids.text)
height = 0
for item in self.items:
if issubclass(item.__class__, BaseListItem):
height += item.height # calculate height contents
self.edit_padding_for_item(item)
self.ids.box_items.add_widget(item)
if height > Window.height:
self.set_normal_height()
self.ids.scroll.height = self.get_normal_height()
else:
self.ids.scroll.height = height
def create_buttons(self):
for button in self.buttons:
if issubclass(button.__class__, BaseButton):
self.ids.button_box.add_widget(button)

View File

@ -17,7 +17,7 @@
orientation:'vertical'
cols:1
size_hint:None,None
width: '300sp'
width: '333sp'
pos_hint: {'center_x':0.5,'center_y':0.5}
md_bg_color: rgb(*COLOR_CARD)
radius:[20,]
@ -59,7 +59,7 @@
<UsernameLabel>:
theme_text_color: 'Custom'
text_color: rgb(*COLOR_TEXT)
width:'100sp'
width:'150sp'
# adaptive_width: True
size_hint:None,None
# md_bg_color:rgb(*COLOR_TEXT)

View File

@ -23,11 +23,11 @@ class LoginButton(MDRectangleFlatButton): pass
class RegisterButton(MDRectangleFlatButton,Logger):
def enter(self):
un=self.parent.parent.parent.username_field.text
pw=self.parent.parent.parent.password_field.text
# pw=self.parent.parent.parent.password_field.text
login_screen = self.parent.parent.parent
time.sleep(0.1)
asyncio.create_task(login_screen.boot(un,pw))
asyncio.create_task(login_screen.boot(un))
# logger.info('types',type(self.parent),type(self.parent.parent.parent))
@ -62,7 +62,7 @@ class LoginScreen(BaseScreen):
self.label_title.markup=True
self.label_title.color=rgb(*COLOR_TEXT)
self.label_title.text='Welcome,'
# self.label_title.font_size*=1.5
self.label_title.font_size='28sp'
self.layout.add_widget(get_separator('20sp'))
self.layout.add_widget(self.label_title)
self.layout.add_widget(get_separator('30sp'))
@ -70,7 +70,7 @@ class LoginScreen(BaseScreen):
self.layout_username = UsernameLayout()
self.label_username = UsernameLabel(text="Komrade")
self.label_username = UsernameLabel(text="Komrade @")
self.username_field = UsernameField()
self.username_field.line_color_focus=rgb(*COLOR_TEXT)
@ -84,20 +84,20 @@ class LoginScreen(BaseScreen):
#log(self.username_field)
# self.username_field.text='hello????'
self.layout_password = UsernameLayout()
self.label_password = UsernameLabel(text='password:')
# self.layout_password = UsernameLayout()
# self.label_password = UsernameLabel(text='password:')
self.label_password.font_name='assets/font.otf'
# self.label_password.font_name='assets/font.otf'
self.label_username.font_name='assets/font.otf'
self.password_field = PasswordField()
self.password_field.line_color_focus=rgb(*COLOR_TEXT)
self.password_field.line_color_normal=rgb(*COLOR_TEXT,a=0.25)
self.password_field.font_name='assets/font.otf'
# self.password_field = PasswordField()
# self.password_field.line_color_focus=rgb(*COLOR_TEXT)
# self.password_field.line_color_normal=rgb(*COLOR_TEXT,a=0.25)
# self.password_field.font_name='assets/font.otf'
self.layout_password.add_widget(self.label_password)
self.layout_password.add_widget(self.password_field)
self.layout.add_widget(self.layout_password)
# self.layout_password.add_widget(self.label_password)
# self.layout_password.add_widget(self.password_field)
# self.layout.add_widget(self.layout_password)
self.layout_buttons = LoginButtonLayout()
self.layout.add_widget(get_separator('20sp'))
@ -117,16 +117,18 @@ class LoginScreen(BaseScreen):
self.layout.add_widget(self.login_status)
self.label_title.font_size='18sp'
self.label_password.font_size='18sp'
self.label_username.font_size='20sp'
self.label_title.font_size='24sp'
# self.label_password.font_size='18sp'
self.label_username.font_size='22sp'
self.login_button.font_size='12sp'
self.register_button.font_size='9sp'
self.register_button.text='enter'
self.username_field.font_size='20sp'
self.username_field.font_size='24sp'
self.label_username.padding_x=(10,20)
self.username_field.padding_x=(20,10)
self.username_field.padding_y=(25,0)
# self.username_field.padding_y=(25,0)
self.username_field.pos_hint={'center_y':0.5}
self.label_username.halign='right'
@ -164,22 +166,23 @@ class LoginScreen(BaseScreen):
async def boot(self,un,pw=None):
# await self.stat('hello',img_src='/home/ryan/komrade/data/contacts/marxxx.png',komrade_name='Keymaker')
await self.app.get_input('hello?',get_pass=True)
return
# await self.app.get_input('hello?',get_pass=True,title='gimme your passwrdd')
# await self.app.get_input('hello?',get_pass=False,title='gimme your fav color bitch')
# return
# return
name=un
from komrade.backend import Komrade
kommie = Komrade(un,getpass_func=lambda why: pw)
kommie = Komrade(un)
self.log('KOMMIE!?!?',kommie)
logger.info(f'booted kommie: {kommie}')
if kommie.exists_locally_as_account():
await self.app.stat('You have already created this account. Logging you back in...')
pw=await self.app.get_input('Welcome back.')
kommie=Komrade(un,getpass_func=lambda why: pw)
logger.info(f'is account')
self.login_status.text='You should be able to log into this account.'
# self.login_status.text='You should be able to log into this account.'
if kommie.privkey:
logger.info(f'passkey login succeeded')
self.login_status.text=f'Welcome back, Komrade @{un}'
@ -201,7 +204,8 @@ class LoginScreen(BaseScreen):
# self.login_status.text='Komrade not known on this device. Registering...'
### REGISTER
res = await self.register(kommie,logfunc=self.app.stat,passphrase=pw)
self.remove_widget(self.layout)
res = await self.register(un)
if kommie.privkey:
self.login_status.text='Registered'
@ -215,9 +219,12 @@ class LoginScreen(BaseScreen):
return 1
async def register(self,kommie,logfunc=None,passphrase=None):
if not logfunc: logfunc=self.app.stat
name=kommie.name
async def register(self,name):
async def logfunc(*x,**y):
if not 'komrade_name' in y: y['komrade_name']='Keymaker'
await self.app.stat(*x,**y)
kommie = Komrade(name)
# already have it?
if kommie.exists_locally_as_account():
@ -267,6 +274,10 @@ class LoginScreen(BaseScreen):
### PRIVATE KEY
await logfunc(f"(2) Your PRIVATE encryption key, on the other hand, must be stored only on your device hardware. In fact it's so sensitive we'll even encrypt the encryption key itself.",pause=True,use_prefix=False)
passphrase = await self.app.get_input('Please enter a memorable password.',
get_pass=True
)
passhash = hasher(passphrase)
privkey_decr = KomradeSymmetricKeyWithPassphrase(passhash=passhash)
print()

View File

@ -67,7 +67,13 @@ class TheTelephone(Operator):
URL = self.api_url + msg_b64_str_esc + '/'
self.log("DIALING THE OPERATOR:",URL)
phonecall=await self.komrade_request_async(URL)
# phonecall=await self.komrade_request_async(URL)
import asyncio
loop = asyncio.get_event_loop()
texec = ThreadExecutor()
# phonecall=self.komrade_request(URL)
phonecall = await texec(self.komrade_request, URL)
if phonecall.status_code!=200:
self.log('!! error in request',phonecall.status_code,phonecall.text)
@ -128,19 +134,19 @@ class TheTelephone(Operator):
def tor_request_in_proxy(self,url):
with self.get_tor_proxy_session() as s:
return s.get(url,timeout=60)
return s.get(url,timeout=600)
async def tor_request_in_python_async(self,url):
import requests_async as requests
import requests_async
tor = TorClient()
with tor.get_guard() as guard:
adapter = TorHttpAdapter(guard, 3, retries=RETRIES)
async with requests.Session() as s:
async with requests_async.Session() as s:
s.headers.update({'User-Agent': 'Mozilla/5.0'})
s.mount('http://', adapter)
s.mount('https://', adapter)
r = await s.get(url, timeout=60)
r = s.get(url, timeout=600)
self.log('<-- r',r)
return r
@ -154,7 +160,7 @@ class TheTelephone(Operator):
s.headers.update({'User-Agent': 'Mozilla/5.0'})
s.mount('http://', adapter)
s.mount('https://', adapter)
r = s.get(url, timeout=60)
r = s.get(url, timeout=600)
return r
def get_tor_proxy_session(self):

View File

@ -451,4 +451,38 @@ def multiline_input(msg=None):
break
txt="\n".join(contents) if contents else contents
return txt
return txt
class ThreadExecutor:
"""In most cases, you can just use the 'execute' instance as a
function, i.e. y = await execute(f, a, b, k=c) => run f(a, b, k=c) in
the executor, assign result to y. The defaults can be changed, though,
with your own instantiation of Executor, i.e. execute =
Executor(nthreads=4)"""
def __init__(self, loop=None, nthreads=1):
import asyncio
from concurrent.futures import ThreadPoolExecutor
if not loop: loop=asyncio.get_event_loop()
self._ex = ThreadPoolExecutor(nthreads)
self._loop = loop
def __call__(self, f, *args, **kw):
from functools import partial
return self._loop.run_in_executor(self._ex, partial(f, *args, **kw))
# execute = Executor()
# ...
# def cpu_bound_operation(t, alpha=30):
# sleep(t)
# return 20*alpha
# async def main():
# y = await execute(cpu_bound_operation, 5, alpha=-2)
# loop.run_until_complete(main())