1
0
Fork 0
mirror of https://codeberg.org/vanous/huafetcher synced 2024-06-10 10:26:16 +02:00
huafetcher/main.py

417 lines
15 KiB
Python

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.utils import platform
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from functools import partial
from kivy.clock import Clock
from kivy.logger import Logger
from kivy.uix.dropdown import DropDown
from huami_token import HuamiAmazfit
import urls as urls
from kivy.core.clipboard import Clipboard
from kivy.storage.jsonstore import JsonStore
DEBUG=False
#DEBUG=True
def debug_print(*xargs):
if DEBUG:
print(*xargs)
SPACING=2
Builder.load_string('''
<MyInputy>:
font_size: 30
halign: 'left'
color: 1,1,1,1
bcolor: .1, 0, .6, 0
canvas.before:
Color:
rgba: root.bcolor
Rectangle:
size: (self.width -2, self.height -2)
pos: (self.x+1,self.y +1)
<MyLabel>:
font_size: 30
halign: 'center'
bcolor: .7, .7, .7, 1
canvas.before:
Color:
rgba: root.bcolor
Rectangle:
size: self.size
pos: self.pos
<MyLeftLabel>:
font_size: 30
halign: 'left'
bcolor: .7, .7, .7, 1
canvas.before:
Color:
rgba: root.bcolor
Rectangle:
size: self.size
pos: self.pos
<MyButton>:
font_size: 30
bcolor: .7, .7, .7, 1
background_color: .1, 0, .5, 0
canvas.before:
Color:
rgba: root.bcolor
Rectangle:
size: self.size
pos: self.pos
''')
class MyLabel(Label):
pass
class MyLeftLabel(Label):
pass
class MyButton(Button):
pass
class MyInput(TextInput):
pass
class Main(App):
def build(self):
self.huamidevice=HuamiAmazfit()
self.store = JsonStore('credentials.json')
screen_layout = BoxLayout(orientation="vertical", spacing=SPACING)
buttons_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
rows_layout = BoxLayout(orientation="vertical", spacing=SPACING)
self.instructions_label=MyLeftLabel(text='Huafetcher', halign="left")
rows_layout.add_widget(self.instructions_label)
dropdown = DropDown()
xiaomi_button = MyButton(text='Xiaomi', size_hint_y=None, height=150)
xiaomi_button.bind(on_press=lambda a:self.set_login_method('xiaomi'))
xiaomi_button.bind(on_release=lambda btn: dropdown.select(btn.text))
amazfit_button = MyButton(text='Amazfit', size_hint_y=None, height=150)
amazfit_button.bind(on_press=lambda a:self.set_login_method('amazfit'))
amazfit_button.bind(on_release=lambda btn: dropdown.select(btn.text))
dropdown.add_widget(xiaomi_button)
dropdown.add_widget(amazfit_button)
dropdown_button = MyButton(text='Login method')
dropdown_button.bind(on_release=dropdown.open)
#dropdown_button.bind(on_press=lambda x: setattr(dropdown_button,'text','Select'))
dropdown.bind(on_select=lambda instance, x: setattr(dropdown_button, 'text', x))
get_token_button = MyButton(text='Get token')
get_token_button.bind(on_press=self.on_press_button_gettoken)
fetch_key_button = MyButton(text='Fetch key')
fetch_key_button.bind(on_press=self.on_press_button_fetch_key)
fetch_agps_button = MyButton(text='Fetch aGPS')
fetch_agps_button.bind(on_press=self.on_press_button_agps)
share_agps_button = MyButton(text='Share aGPS')
share_agps_button.bind(on_press=self.on_press_button_share_agps)
buttons_layout.add_widget(get_token_button)
#buttons_layout.add_widget(login_button)
buttons_layout.add_widget(fetch_key_button)
buttons_layout.add_widget(fetch_agps_button)
#sharing doesn't work
#buttons_layout.add_widget(share_agps_button)
paste_token_input_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
paste_token_input_label=MyLabel(text='URL result')
self.paste_token_input = MyInput(text='',
multiline=False,
)
self.paste_token_input.bind(text=self.set_token)
paste_button1=MyButton(text='Paste', size_hint=(.3, 1))
paste_button1.bind(on_press=lambda instance: self.on_press_paste(self.paste_token_input) )
paste_token_input_layout.add_widget(paste_token_input_label)
paste_token_input_layout.add_widget(paste_button1)
paste_token_input_layout.add_widget(self.paste_token_input)
credentials_email_label=MyButton(text='Email' , size_hint=(.7, 1))
self.credentials_email_input = MyInput(text='',
multiline=False,
)
self.credentials_email_input.bind(text=lambda instance,x: setattr(self.huamidevice,'email',x))
credentials_email_label.bind(on_press=self.on_press_paste_email)
paste_button2=MyButton(text='Paste', size_hint=(.3, 1))
paste_button2.bind(on_press=lambda instance: self.on_press_paste(self.credentials_email_input) )
save_button1=MyButton(text='Save', size_hint=(.3, 1))
#load_button1.bind(on_press=lambda instance: )
save_button1.bind(on_press=lambda instance: self.on_press_save(self.credentials_email_input, 'email') )
self.credentials_email_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
self.credentials_email_layout.add_widget(credentials_email_label)
#credentials_email_layout.add_widget(load_button1)
self.credentials_email_layout.add_widget(save_button1)
self.credentials_email_layout.add_widget(paste_button2)
self.credentials_email_layout.add_widget(self.credentials_email_input)
credentials_password_label=MyLabel(text='Password', size_hint=(.7, 1))
self.credentials_password_input = MyInput(text='',
multiline=False,
)
self.credentials_password_input.bind(text=lambda instance,x: setattr(self.huamidevice,'password',x))
credentials_password_label.bind(on_press=self.on_press_paste_password)
paste_button3=MyButton(text='Paste', size_hint=(.3, 1))
paste_button3.bind(on_press=lambda instance: self.on_press_paste(self.credentials_password_input) )
save_button2=MyButton(text='Save', size_hint=(.3, 1))
save_button2.bind(on_press=lambda instance: self.on_press_save(self.credentials_password_input, 'password') )
self.credentials_password_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
self.credentials_password_layout.add_widget(credentials_password_label)
self.credentials_password_layout.add_widget(save_button2)
self.credentials_password_layout.add_widget(paste_button3)
self.credentials_password_layout.add_widget(self.credentials_password_input)
rows_layout.add_widget(dropdown_button)
rows_layout.add_widget(self.credentials_email_layout)
rows_layout.add_widget(self.credentials_password_layout)
rows_layout.add_widget(paste_token_input_layout)
result_value_label=MyButton(text='Found key')
self.result_value_value=TextInput()
copy_button4=MyButton(text='Copy', size_hint=(.3, 1))
copy_button4.bind(on_press=lambda instance: self.on_press_copy(self.result_value_value) )
result_value_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
result_value_layout.add_widget(result_value_label)
result_value_layout.add_widget(copy_button4)
result_value_layout.add_widget(self.result_value_value)
result_value_label.bind(on_press=self.on_press_copy_result)
rows_layout.add_widget(result_value_layout)
rows_layout.add_widget(buttons_layout)
screen_layout.add_widget(rows_layout)
self.on_press_load(self.credentials_email_input, 'email')
self.on_press_load(self.credentials_password_input, 'password')
self.set_login_method('xiaomi')
dropdown_button.text='Xiaomi'
return screen_layout
def hide_widget(self, wid, dohide=True):
debug_print(dohide)
if hasattr(wid, 'saved_attrs'):
debug_print(wid.saved_attrs)
if not dohide:
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = wid.saved_attrs
del wid.saved_attrs
elif dohide:
wid.saved_attrs = wid.height, wid.size_hint_y, wid.opacity, wid.disabled
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = 0, None, 0, True
def set_login_method(self,method):
debug_print(method)
self.huamidevice.method=method
if method == 'xiaomi':
self.hide_widget(self.credentials_email_layout, dohide=True)
self.hide_widget(self.credentials_password_layout, dohide=True)
else:
self.hide_widget(self.credentials_email_layout, dohide=False)
self.hide_widget(self.credentials_password_layout, dohide=False)
def set_token(self, instance, text):
debug_print("got", text)
debug_print(self.huamidevice)
self.huamidevice.parse_token(text)
debug_print(self.huamidevice)
def on_press_button_gettoken(self, instance):
debug_print('You pressed the button login!')
debug_print(self.huamidevice)
if self.huamidevice.method == 'xiaomi':
self.instructions_label.text="log in and paste url here"
login_url = urls.URLS["login_xiaomi"]
if ( platform != 'android' ):
import webbrowser
webbrowser.open(login_url, new = 2)
else:
from jnius import autoclass
from jnius import cast
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Intent = autoclass('android.content.Intent')
Uri = autoclass('android.net.Uri')
intent = Intent()
intent.setAction(Intent.ACTION_VIEW)
intent.setData(Uri.parse(login_url))
currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
currentActivity.startActivity(intent)
try:
res=self.huamidevice.get_access_token()
if res:
if self.huamidevice.user_id is not None:
self.instructions_label.text="Signed in as: {}, getting data".format(self.huamidevice.user_id)
else:
self.instructions_label.text="You must sign in first"
except Exception as e:
debug_print(e)
self.instructions_label.text=f"{e}"
def on_press_button_fetch_key(self, instance):
debug_print('You pressed the button fetch!')
debug_print(self.huamidevice)
self.instructions_label.text="signing in"
try:
res=self.huamidevice.login()
if res:
self.instructions_label.text="Signed in as: {}, getting data".format(self.huamidevice.user_id)
except Exception as e:
debug_print(e)
self.instructions_label.text=f"{e}"
return
device_keys = self.huamidevice.get_wearable_auth_keys()
self.instructions_label.text="Done"
self.result_value_value.text=""
for device_key in device_keys:
debug_print(f"{device_key} {device_keys[device_key]}")
self.result_value_value.text=f"{device_keys[device_key]}"
#Clock.schedule_once(partial(self.doit), 1)
def on_press_paste_token(self, instance):
self.paste_token_input.text=Clipboard.paste()
def on_press_paste_email(self, instance):
self.credentials_email_input.text=Clipboard.paste()
def on_press_paste_password(self, instance):
self.credentials_password_input.text=Clipboard.paste()
def on_press_copy_result(self, instance):
Clipboard.copy(self.result_value_value.text)
def on_press_paste(self, instance):
instance.text=Clipboard.paste()
def on_press_copy(self, instance):
Clipboard.copy(instance.text)
def on_press_load(self, instance, key):
if self.store.exists(key):
instance.text=self.store.get(key)["value"]
def on_press_save(self, instance, key):
self.store.put(key, value=instance.text)
def on_press_button_agps(self, instance):
import zipfile
debug_print('You pressed the button agps!')
debug_print(self.huamidevice)
self.instructions_label.text="signing in"
try:
res=self.huamidevice.login()
if res:
self.instructions_label.text="Signed in as: {}, getting data".format(self.huamidevice.user_id)
except Exception as e:
debug_print(e)
self.instructions_label.text=f"{e}"
return
self.huamidevice.get_gps_data()
agps_file_names = ["cep_alm_pak.zip"]
if ( platform == 'android' ):
import shutil
import os
from jnius import autoclass
from jnius import cast
Environment = autoclass('android.os.Environment')
File = autoclass('java.io.File')
data_dir = Environment.getExternalStorageDirectory().getPath()
debug_print(data_dir)
for filename in agps_file_names:
sdpathfile = os.path.join(data_dir, filename)
shutil.copyfile(filename, sdpathfile)
with zipfile.ZipFile(filename, "r") as zip_f:
#zip_f.extractall()
zip_f.extractall(data_dir)
self.instructions_label.text="Done"
#Clock.schedule_once(partial(self.doit), 1)
def on_press_button_share_agps(self, instance):
#not working because android broke it
if ( platform == 'android' ):
import os
from jnius import autoclass
from jnius import cast
Environment = autoclass('android.os.Environment')
File = autoclass('java.io.File')
data_dir = Environment.getExternalStorageDirectory().getPath()
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Intent = autoclass('android.content.Intent')
Uri = autoclass('android.net.Uri')
intent = Intent()
intent.setAction(Intent.ACTION_VIEW)
data_dir = getattr(self, 'user_data_dir')
file_target=File(os.path.join(data_dir, "cep_pak.bin"))
#target=Uri.parse(os.path.join("file:///", data_dir, "cep_pak.bin"))
target=Uri.fromFile(file_target)
#intent.setData(Uri.parse(os.path.join("file:///", data_dir, "cep_pak.bin")))
#intent.setType("application/octet-stream")
intent.setDataAndType(target, "application/octet-stream")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
currentActivity.startActivity(intent)
#intent = Intent()
#intent.setAction(Intent.ACTION_VIEW)
#intent.setData(Uri.parse("gps_alm.bin"))
#currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
#currentActivity.startActivity(intent)
#def doit(self, *kargs):
def openweb(url):
debug_print("open ", url)
if __name__ == '__main__':
app = Main()
app.run()