Compare commits

..

No commits in common. "f78e57f8376aad262a6ac75da360a8e9678d1483" and "1720af54e994779295e20382f7155e49ec245e3d" have entirely different histories.

40 changed files with 187 additions and 1659 deletions

2
.gitignore vendored

@ -158,4 +158,4 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear # and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
config.ini config.ini

@ -1,37 +0,0 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-docstring-first
- id: debug-statements
- id: double-quote-string-fixer
- id: requirements-txt-fixer
- id: check-added-large-files
- id: check-ast
- id: check-builtin-literals
- id: check-case-conflict
- id: destroyed-symlinks
- id: check-merge-conflict
- id: debug-statements
- id: detect-private-key
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: file-contents-sorter
- repo: https://github.com/hhatto/autopep8
rev: v2.1.0
hooks:
- id: autopep8
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
hooks:
- id: pyupgrade
- repo: https://github.com/abdelrahman0w/ouro
rev: v0.2.0
hooks:
- id: ouro

@ -1,66 +1,7 @@
# <img src="https://git.cubable.date/BillPay/app/~raw/dev/assets/icon.png" alt="icon" width="45" height="45"/> BillPay (WIP) # BillPay
A fully Independent Application for cross platform To run the app:
```
[![wakatime](https://wakatime.com/badge/user/198abec6-27b2-419b-87cf-60c4107b01be/project/018ef6c9-2350-4cfa-a556-ccadc51e0aa9.svg)](https://wakatime.com/badge/user/198abec6-27b2-419b-87cf-60c4107b01be/project/018ef6c9-2350-4cfa-a556-ccadc51e0aa9) flet run [app_directory]
```
## 🎯 Purpose for BillPay
It has been difficult for me to manage my bills by having multiple apps installed on my mobile device, and I am sure many other people do too. There are many services here that provide all in one bill pay but they are so locked out we have to login to pay, and to pay we have to communicate with a third party bank account to send it credit so we can process our payments. If those services go down there is no possibility that we can further process our bills through those platforms.
So what could be better than having a fully independent App where YOU control YOUR bills and payments without having to rely on a thirdparty service.
## 💧 Features
**🈚 Independent:**
Application doesnt rely on any thirdparty service to process any bill payments other than banks which are included by the vendor
**🧩 Plugins:**
Apps can be pluggable, if user dont want to see them they can turn it off
***♻️ Backup & Restore:***
Backup Payment History and Restore them on any device
## ⏬ Downloads
- Grab your own copy from [Builds](https://git.cubable.date/BillPay/app/~builds)
## 🦮 Build Guide
### 📜 Requirements
- flutter
- python 3.11.1
- android studio (for android)
- Visual Studio (for Windows)
- Xcode (for IOS)
- Chrome (for Web)
### 🛠️ Build Steps
- Create a python virtualenv: `python -m venv venv`
- Activate virtualenv:
- Windows: `.\venv\Scripts\activate`
- Linux/MacOS: `source venv/bin/activate`
- Install requirements: `pip install -r requirements.txt`
- Run interactive for debugging:
- `flet run --<platform>` where the platform is either `ios` `android` `web`
- To Build Release:
- `flet build <platform> --verbose` where `<platform>` is either `ios` `android` `web`
### Developed with ❤️:
<a href="https://penpot.app">
<img src="https://www.svgrepo.com/download/432263/penpot.svg" alt="penpot" width="50" height="50" class="penpot-color"/>
<style>
.penpot-color{
filter: invert(40%) sepia(0%) saturate(2476%);
}
</style>
</a>
<a href="https://python.org">
<img src="https://asset.brandfetch.io/idbpOFBgcc/idcTemqrrW.svg" alt="python" width="50" height="50"/>
</a>
<a href="https://flutter.dev">
<img src="https://asset.brandfetch.io/idEMZUpQF7/idvArxAqXg.svg" alt="drawing" width="50" height="50"/>
</a>
<a href="https://flet.dev">
<img src="https://github.com/flet-dev/flet/blob/main/media/logo/Icon-192.png?raw=true" alt="drawing" width="50" height="50"/>
</a>

@ -1,5 +0,0 @@
from .apps import Apps
__all__ = [
'Apps',
]

@ -1,448 +0,0 @@
import flet as ft
from utils import AppView, Title
from modules.settings import config
from modules.home import AppRow
def Apps(page: ft.Page):
AppRow.controls = []
appsContainer = ft.ListView(
expand=True,
)
appList = ft.Container(
content=ft.Column(
controls=[],
),
)
appsContainer.controls.append(
appList,
)
if config.getint('apps', 'dhiraagu') == 1:
appList.content.controls.append(
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Image(
border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idZJsIaold/id9-VJM_HU.png',
),
title=ft.Text('Dhiraagu'),
subtitle=ft.Text(
'An ISP Service.',
),
),
],
),
padding=10,
on_click=lambda _: page.go('/apps/dhiraagu'),
),
),
)
AppRow.controls.append(
ft.Text('Dhiraagu'),
)
AppRow.controls.append(
ft.Container(
margin=10,
padding=10,
bgcolor=ft.colors.with_opacity(0.1, '#000000'),
border_radius=10,
content=ft.Row(
[
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.ACCOUNT_BOX,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/dhiraagu',
),
),
ft.Container(
content=ft.Text(
'Gift',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.ELECTRIC_BOLT,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/dhiraagu',
),
),
ft.Container(
content=ft.Text(
'Reload',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.DASHBOARD,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/dhiraagu',
),
),
ft.Container(
content=ft.Text(
'Usage',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.RECEIPT,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/dhiraagu',
),
),
ft.Container(
content=ft.Text(
'Bills',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
],
alignment=ft.MainAxisAlignment.CENTER,
),
),
)
if config.getint('apps', 'ooredoo') == 1:
appList.content.controls.append(
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Image(
border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idR1xFKHLD/idu6J-WQsm.jpeg',
),
title=ft.Text('Ooredoo'),
subtitle=ft.Text(
'An ISP Service.',
),
),
],
),
padding=10,
on_click=lambda _: page.go('/apps/ooredoo'),
),
),
)
AppRow.controls.append(
ft.Text('Ooredoo'),
)
AppRow.controls.append(
ft.Container(
margin=10,
padding=10,
bgcolor=ft.colors.with_opacity(0.1, '#000000'),
border_radius=10,
content=ft.Row(
[
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.SETTINGS_PHONE,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/ooredoo',
),
),
ft.Container(
content=ft.Text(
'Add-ons',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.ELECTRIC_BOLT,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/ooredoo',
),
),
ft.Container(
content=ft.Text(
'Raastas',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.DASHBOARD,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/ooredoo',
),
),
ft.Container(
content=ft.Text(
'Balance',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.RECEIPT,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/apps/ooredoo',
),
),
ft.Container(
content=ft.Text(
'Bills',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
],
alignment=ft.MainAxisAlignment.CENTER,
),
),
)
if config.getint('apps', 'mwsc') == 1:
appList.content.controls.append(
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Image(
border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idOZWUOUm-/idNastd9Bg.jpeg',
),
title=ft.Text('MWSC'),
subtitle=ft.Text(
'Water Bills',
),
),
],
),
padding=10,
on_click=lambda _: page.go('/apps/mwsc'),
),
),
)
if config.getint('apps', 'stelco') == 1:
appList.content.controls.append(
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Image(
border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN,
src='https://www.stelco.com.mv/wp-content/uploads/2022/02/unnamed.png',
),
title=ft.Text('STELCO'),
subtitle=ft.Text(
'Electricity Bills',
),
),
],
),
padding=10,
on_click=lambda _: page.go('/apps/stelco'),
),
),
)
if config.getint('apps', 'medianet') == 1:
appList.content.controls.append(
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Image(
border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idLMZnv5SC/iduyX4keYN.jpeg',
),
title=ft.Text('Dhiraagu'),
subtitle=ft.Text(
'Online Television Service',
),
),
],
),
padding=10,
on_click=lambda _: page.go('/apps/medianet'),
),
),
)
if not AppRow.controls:
AppRow.controls.append(
ft.Container(
content=ft.Card(
content=ft.Container(
content=ft.Container(
ft.Text(
'Add a module from settings to see shortcuts here.',
text_align=ft.TextAlign.CENTER,
),
),
padding=10,
on_click=None,
),
),
),
)
if not appList.content.controls:
appList.content.controls.append(
ft.Text(
'Add a module from settings to see shortcuts here.',
text_align=ft.TextAlign.CENTER,
),
)
appList.alignment = ft.alignment.center
appList.expand = True
return AppView(
'/apps',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
appsContainer,
],
)

@ -1,13 +0,0 @@
from .dhiraagu import Dhiraagu
from .ooredoo import Ooredoo
from .medianet import Medianet
from .mwsc import Mwsc
from .stelco import Stelco
__all__ = [
'Dhiraagu',
'Ooredoo',
'Medianet',
'Stelco',
'Mwsc',
]

@ -1,5 +0,0 @@
from .app import App as Dhiraagu
__all__ = [
'Dhiraagu',
]

@ -1,18 +0,0 @@
import flet as ft
from utils import AppView
def App(page: ft.Page):
return AppView(
'/apps/dhiraagu',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/apps'),
),
title=ft.Text('Dhiraagu'),
bgcolor=ft.colors.TRANSPARENT,
),
],
)

@ -1,5 +0,0 @@
from .app import App as Medianet
__all__ = [
'Medianet',
]

@ -1,18 +0,0 @@
import flet as ft
from utils import AppView
def App(page: ft.Page):
return AppView(
'/apps/medianet',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/apps'),
),
title=ft.Text('Medianet'),
bgcolor=ft.colors.TRANSPARENT,
),
],
)

@ -1,5 +0,0 @@
from .app import App as Mwsc
__all__ = [
'Mwsc',
]

@ -1,18 +0,0 @@
import flet as ft
from utils import AppView
def App(page: ft.Page):
return AppView(
'/apps/mwsc',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/apps'),
),
title=ft.Text('MWSC'),
bgcolor=ft.colors.TRANSPARENT,
),
],
)

@ -1,5 +0,0 @@
from .app import App as Ooredoo
__all__ = [
'Ooredoo',
]

@ -1,18 +0,0 @@
import flet as ft
from utils import AppView
def App(page: ft.Page):
return AppView(
'/apps/ooredoo',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/apps'),
),
title=ft.Text('Ooredoo'),
bgcolor=ft.colors.TRANSPARENT,
),
],
)

@ -1,5 +0,0 @@
from .app import App as Stelco
__all__ = [
'Stelco',
]

@ -1,18 +0,0 @@
import flet as ft
from utils import AppView
def App(page: ft.Page):
return AppView(
'/apps/stelco',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/apps'),
),
title=ft.Text('STELCO'),
bgcolor=ft.colors.TRANSPARENT,
),
],
)

BIN
assets/favicon.png Normal file

Binary file not shown.

After

(image error) Size: 4.3 KiB

Binary file not shown.

Before

(image error) Size: 6.6 KiB

After

(image error) Size: 4.3 KiB

51
main.py

@ -1,61 +1,26 @@
import flet as ft import flet as ft
from utils import views_handler from utils import views_handler
from modules.settings.functions import config
from utils import checkInternet
def main(page: ft.Page): def main(page: ft.Page):
page.title = 'BillPay' page.title = "BillPay"
print('Initial route:', page.route) # print("Initial route:", page.route)
config.save('general', 'ignore_network', '0') def route_change(e):
# print("Route change:", e.route)
def route_change(e: ft.ControlEvent):
print('Route change:', e.route)
page.views.clear() page.views.clear()
page.views.append( page.views.append(
views_handler(page)[page.route], views_handler(page)[page.route]
) )
page.update() page.update()
if not config.getint('general', 'ignore_network') and not checkInternet(): def view_pop(e):
dlg = ft.CupertinoActionSheet( # print("View pop:", e.view)
title=ft.Text('No Internet'),
message=ft.Text(
'Please check your network connectivity and try again',
),
cancel=ft.CupertinoActionSheetAction(
content=ft.Text('Okay'),
on_click=lambda _: (
page.close_bottom_sheet() if checkInternet(
) else None, page.update(), None if e.route == '/' else page.go('/'),
),
),
actions=[
ft.CupertinoActionSheetAction(
content=ft.Text('Ignore Completely'),
is_destructive_action=True,
on_click=lambda e: (
page.close_bottom_sheet(), config.save(
'general', 'ignore_network', '1',
),
),
),
],
)
page.show_bottom_sheet(ft.CupertinoBottomSheet(dlg))
def view_pop(e: ft.ControlEvent):
print('View pop:', e.view)
page.views.pop() page.views.pop()
top_view = page.views[-1] top_view = page.views[-1]
page.go(top_view.route) page.go(top_view.route)
if config.get('general', 'theme') == 'dark':
page.theme_mode = ft.ThemeMode.DARK
else:
page.theme_mode = ft.ThemeMode.LIGHT
page.on_route_change = route_change page.on_route_change = route_change
page.on_view_pop = view_pop page.on_view_pop = view_pop
page.go(page.route) page.go(page.route)
ft.app(target=main, assets_dir='assets') ft.app(target=main, assets_dir="assets")

@ -2,4 +2,4 @@ from .home import Home
from .settings import Settings from .settings import Settings
__all__ = ['Home', 'Settings', 'Apps'] __all__ = ["Home", "Settings"]

@ -1,181 +1,33 @@
import flet as ft import flet as ft
from utils import AppView, Title from utils import AppView, Title
from modules.settings import config from modules.settings import config
from datetime import datetime
def greet(time: datetime):
if 5 <= time.hour < 12:
return 'Goodmorning,'
elif 12 <= time.hour < 18:
return 'Goodafternoon,'
else:
return 'Goodevening,'
AppRow = ft.ResponsiveRow(
alignment=ft.MainAxisAlignment.CENTER,
)
def Home(page: ft.Page): def Home(page: ft.Page):
contentColumn = ft.Container(
padding=10,
content=ft.Column(
controls=[
ft.Text(
greet(datetime.now()),
size=50,
weight=ft.FontWeight.W_500,
),
ft.Text(
config.get('general', 'name').split(' ')[0],
size=40,
weight=ft.FontWeight.W_300,
),
ft.Divider(),
AppRow,
ft.Divider(),
ft.Container(
margin=10,
padding=10,
bgcolor=ft.colors.with_opacity(0.1, '#000000'),
border_radius=10,
content=ft.Row(
[
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.APPS,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go('/apps'),
),
ft.Container(
content=ft.Text(
'Apps',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.HISTORY,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda e: print(
'Clickable with Ink clicked!',
),
),
ft.Container(
content=ft.Text(
'History',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.LIST,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda e: print(
'Clickable with Ink clicked!',
),
),
ft.Container(
content=ft.Text(
'Misc.',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
ft.Column(
controls=[
ft.Container(
content=ft.Icon(
ft.icons.SETTINGS,
color=ft.colors.WHITE,
),
margin=10,
padding=10,
alignment=ft.alignment.center,
bgcolor=ft.colors.GREY_700,
width=60,
height=60,
border_radius=10,
ink=True,
on_click=lambda _: page.go(
'/settings',
),
),
ft.Container(
content=ft.Text(
'Settings',
text_align=ft.TextAlign.CENTER,
),
alignment=ft.alignment.center,
width=80,
),
],
),
],
alignment=ft.MainAxisAlignment.CENTER,
),
),
],
),
)
return AppView( return AppView(
'/', "/",
[ [
ft.AppBar( ft.AppBar(
title=ft.Text(Title(__file__)), title=ft.Text(Title(__file__)),
# actions=[ actions=[
# ft.IconButton( ft.IconButton(
# icon=ft.icons.SETTINGS, icon=ft.icons.SETTINGS,
# on_click=lambda _: page.go('/settings'), on_click=lambda _: page.go("/settings"),
# ), )
# ], ]
),
ft.Container(
height=100,
padding=10,
content=ft.Column(
controls=[
ft.Text(
"Goodmorning,"
),
ft.Text(
config.get("general", "name")
)
],
),
), ),
contentColumn,
], ],
) )

@ -1,4 +1,4 @@
from .settings import Settings from .settings import Settings
from .functions import config from .functions import config
__all__ = ['Settings', 'config'] __all__ = ["Settings", "config"]

@ -1,13 +0,0 @@
from .dhiraagu_settings import Settings as DhiraaguSettings
from .medianet_settings import Settings as MedianetSettings
from .mwsc_settings import Settings as MwscSettings
from .ooredoo_settings import Settings as OoredooSettings
from .stelco_settings import Settings as StelcoSettings
__all__ = [
'DhiraaguSettings',
'MedianetSettings',
'MwscSettings',
'OoredooSettings',
'StelcoSettings',
]

@ -1,117 +0,0 @@
import flet as ft
from utils import AppView, Title
from ..functions import config
def Settings(page: ft.Page):
settingsContainer = ft.ListView(
expand=True,
)
settingsContainer.controls.append(ft.Text('General'))
def _on_enable_change(e: ft.ControlEvent):
if config.getint('apps', 'dhiraagu'):
config.save('apps', 'dhiraagu', '0')
else:
config.save('apps', 'dhiraagu', '1')
page.update()
generalSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
content=ft.Container(
ft.Switch(
label=' Enable this module',
on_change=_on_enable_change,
value=False,
),
),
padding=10,
on_click=None,
),
),
],
),
)
if config.getint('apps', 'dhiraagu') == 1:
generalSettings.content.controls[0].content.content.content.value = True
settingsContainer.controls.append(
generalSettings,
)
settingsContainer.controls.append(
ft.Divider(),
)
# main settings
settingsContainer.controls.append(ft.Text('Account'))
loginForm = ft.Column()
phoneInput = ft.Container(
content=ft.TextField(
config.get('dhiraagu', 'phone'),
label='Phone',
adaptive=True,
),
padding=10,
)
loginForm.controls.append(phoneInput)
otpInput = ft.Container(
content=ft.TextField(
config.get('dhiraagu', 'otp'),
label='OTP',
adaptive=True,
),
padding=10,
)
loginForm.controls.append(otpInput)
sendOTP = ft.CupertinoButton(
content=ft.Text('SEND OTP'),
opacity_on_click=0.3,
on_click=lambda e: print('clicked!'),
)
if config.get('dhiraagu', 'token'):
phoneInput.disabled = True
otpInput.disabled = True
sendOTP.disabled = True
log = ft.CupertinoButton(
content=ft.Text('LOG OUT'),
opacity_on_click=0.3,
on_click=lambda e: print('clicked!'),
)
else:
log = ft.CupertinoButton(
content=ft.Text('LOG IN'),
opacity_on_click=0.3,
on_click=lambda e: print('clicked!'),
)
buttons = ft.Row(
controls=[
sendOTP,
],
)
buttons.controls.append(
log,
)
loginForm.controls.append(
buttons,
)
settingsContainer.controls.append(
loginForm,
)
return AppView(
'/settings/dhiraagu',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/settings'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
settingsContainer,
],
)

@ -1,56 +0,0 @@
import flet as ft
from utils import AppView, Title
from ..functions import config
def Settings(page: ft.Page):
settingsContainer = ft.ListView(
expand=True,
)
settingsContainer.controls.append(ft.Text('General'))
def _on_enable_change(e: ft.ControlEvent):
if config.getint('apps', 'medianet'):
config.save('apps', 'medianet', '0')
else:
config.save('apps', 'medianet', '1')
page.update()
generalSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
content=ft.Container(
ft.Switch(
label=' Enable this module',
on_change=_on_enable_change,
value=False,
),
),
padding=10,
on_click=None,
),
),
],
),
)
if config.getint('apps', 'medianet') == 1:
generalSettings.content.controls[0].content.content.content.value = True
settingsContainer.controls.append(
generalSettings,
)
return AppView(
'/settings/medianet',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/settings'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
settingsContainer,
],
)

@ -1,58 +0,0 @@
import flet as ft
from utils import AppView, Title
from ..functions import config
ft.Control
def Settings(page: ft.Page):
settingsContainer = ft.ListView(
expand=True,
)
settingsContainer.controls.append(ft.Text('General'))
def _on_enable_change(e: ft.ControlEvent):
if config.getint('apps', 'mwsc'):
config.save('apps', 'mwsc', '0')
else:
config.save('apps', 'mwsc', '1')
page.update()
generalSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
content=ft.Container(
ft.Switch(
label=' Enable this module',
on_change=_on_enable_change,
value=False,
),
),
padding=10,
on_click=None,
),
),
],
),
)
if config.getint('apps', 'mwsc') == 1:
generalSettings.content.controls[0].content.content.content.value = True
settingsContainer.controls.append(
generalSettings,
)
return AppView(
'/settings/mwsc',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/settings'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
settingsContainer,
],
)

@ -1,56 +0,0 @@
import flet as ft
from utils import AppView, Title
from ..functions import config
def Settings(page: ft.Page):
settingsContainer = ft.ListView(
expand=True,
)
settingsContainer.controls.append(ft.Text('General'))
def _on_enable_change(e: ft.ControlEvent):
if config.getint('apps', 'ooredoo'):
config.save('apps', 'ooredoo', '0')
else:
config.save('apps', 'ooredoo', '1')
page.update()
generalSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
content=ft.Container(
ft.Switch(
label=' Enable this module',
on_change=_on_enable_change,
value=False,
),
),
padding=10,
on_click=None,
),
),
],
),
)
if config.getint('apps', 'ooredoo') == 1:
generalSettings.content.controls[0].content.content.content.value = True
settingsContainer.controls.append(
generalSettings,
)
return AppView(
'/settings/ooredoo',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/settings'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
settingsContainer,
],
)

@ -1,56 +0,0 @@
import flet as ft
from utils import AppView, Title
from ..functions import config
def Settings(page: ft.Page):
settingsContainer = ft.ListView(
expand=True,
)
settingsContainer.controls.append(ft.Text('General'))
def _on_enable_change(e: ft.ControlEvent):
if config.getint('apps', 'stelco'):
config.save('apps', 'stelco', '0')
else:
config.save('apps', 'stelco', '1')
page.update()
generalSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
content=ft.Container(
ft.Switch(
label=' Enable this module',
on_change=_on_enable_change,
value=False,
),
),
padding=10,
on_click=None,
),
),
],
),
)
if config.getint('apps', 'stelco') == 1:
generalSettings.content.controls[0].content.content.content.value = True
settingsContainer.controls.append(
generalSettings,
)
return AppView(
'/settings/stelco',
[
ft.AppBar(
leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/settings'),
),
title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT,
),
settingsContainer,
],
)

@ -1,4 +1,3 @@
from .config import config from .config import config
from .theme import Theme from .theme import Theme
__all__ = ['config', 'Theme']
__all__ = ['config', 'Theme']

@ -2,69 +2,59 @@ from configparser import ConfigParser
import os import os
static = """ static = """
[general] [general]
name = name = CustomIcon
phone = phone =
email = email =
nid =
theme = light
ignore_network = 0
[apps] [apps]
dhiraagu = 0 dhiraagu = true
ooredoo = 0 ooredoo = true
mwsc = 0 hdc = true
stelco = 0 mwsc = true
medianet = 0 stelco = true
medianet = true
[dhiraagu] [dhiraagu]
phone = phone =
otp = otp =
token = cookie =
account =
[ooredoo] [ooredoo]
phone = phone =
otp = otp =
cookie = cookie =
[hdc] [hdc]
property = property =
nid = nid =
[mwsc] [mwsc]
meter_no = meter_no =
account_no = account_no =
mobile_no = mobile_no =
[stelco] [stelco]
account_no = account_no =
bill_no = bill_no =
[medianet] [medianet]
account_no = account_no =
nid = nid =
phone = phone =
""" """
class Config(ConfigParser): class Config(ConfigParser):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
if not os.path.exists('config.ini'): if not os.path.exists("config.ini"):
self.initialize(content=static) self.initialize(content=static)
self.read('config.ini') self.read("config.ini")
def initialize(self, content): def initialize(self, content):
with open('config.ini', 'a+') as file: with open("config.ini", 'a+') as file:
file.write(content) file.write(content)
def save(self, section, key, value):
config.set(section, key, value)
with open('config.ini', 'w') as configfile:
self.write(configfile)
self.read('config.ini')
config = Config()
config = Config()

@ -1,11 +1,16 @@
import flet as ft import flet as ft
class Theme: class Theme:
def __init__(self, page: ft.Page) -> None: def __init__(self, page: ft.Page) -> None:
self.page = page self.page = page
def change(self, theme: ft.ThemeMode = None): def change(self, theme: ft.ThemeMode = None):
if theme: if theme:
self.page.theme_mode = theme self.page.theme_mode = theme
self.page.update() else:
self.page.theme_mode = (
ft.ThemeMode.DARK
if self.page.theme_mode == ft.ThemeMode.LIGHT
else ft.ThemeMode.LIGHT
)
self.page.update()

@ -1,158 +1,12 @@
import flet as ft import flet as ft
from utils import AppView, Title from utils import AppView, Title
from .functions import Theme, config from .functions import Theme
def Settings(page: ft.Page): def Settings(page: ft.Page):
settingsContainer = ft.ListView( settingsContainer = ft.ListView(
expand=True, expand=True
) )
settingsContainer.controls.append(ft.Text('General')) settingsContainer.controls.append(ft.Text("General"))
def _on_name_change(e: ft.ControlEvent):
newName = ft.CupertinoTextField(value=config.get('general', 'name'))
dlg = ft.CupertinoAlertDialog(
modal=True,
title=ft.Text('Enter your Full name'),
content=newName,
actions=[
ft.CupertinoButton(
'Save',
on_click=lambda _: (
setattr(
dlg,
'open',
False,
),
config.save(
'general',
'name',
newName.value,
),
page.update(),
),
),
ft.CupertinoButton(
'Close',
on_click=lambda _: (
setattr(dlg, 'open', False),
page.update(),
),
),
],
)
page.dialog = dlg
dlg.open = True
page.update()
def _on_phone_change(e: ft.ControlEvent):
newPhone = ft.CupertinoTextField(value=config.get('general', 'phone'))
dlg = ft.CupertinoAlertDialog(
modal=True,
title=ft.Text('Enter your Mobile'),
content=newPhone,
actions=[
ft.CupertinoButton(
'Save',
on_click=lambda _: (
setattr(
dlg,
'open',
False,
),
config.save(
'general',
'phone',
newPhone.value,
),
page.update(),
),
),
ft.CupertinoButton(
'Close',
on_click=lambda _: (
setattr(dlg, 'open', False),
page.update(),
),
),
],
)
page.dialog = dlg
dlg.open = True
page.update()
def _on_email_change(e: ft.ControlEvent):
newEmail = ft.CupertinoTextField(value=config.get('general', 'email'))
dlg = ft.CupertinoAlertDialog(
modal=True,
title=ft.Text('Enter your Email'),
content=newEmail,
actions=[
ft.CupertinoButton(
'Save',
on_click=lambda _: (
setattr(
dlg,
'open',
False,
),
config.save(
'general',
'email',
newEmail.value,
),
page.update(),
),
),
ft.CupertinoButton(
'Close',
on_click=lambda _: (
setattr(dlg, 'open', False),
page.update(),
),
),
],
)
page.dialog = dlg
dlg.open = True
page.update()
def _on_nid_change(e: ft.ControlEvent):
newNID = ft.CupertinoTextField(value=config.get('general', 'nid'))
dlg = ft.CupertinoAlertDialog(
modal=True,
title=ft.Text('Enter your NID'),
content=newNID,
actions=[
ft.CupertinoButton(
'Save',
on_click=lambda _: (
setattr(
dlg,
'open',
False,
),
config.save(
'general',
'nid',
newNID.value,
),
page.update(),
),
),
ft.CupertinoButton(
'Close',
on_click=lambda _: (
setattr(dlg, 'open', False),
page.update(),
),
),
],
)
page.dialog = dlg
dlg.open = True
page.update()
generalSettings = ft.Container( generalSettings = ft.Container(
content=ft.Column( content=ft.Column(
controls=[ controls=[
@ -163,16 +17,16 @@ def Settings(page: ft.Page):
[ [
ft.ListTile( ft.ListTile(
leading=ft.Icon(ft.icons.PERSON), leading=ft.Icon(ft.icons.PERSON),
title=ft.Text('Username'), title=ft.Text("Username"),
subtitle=ft.Text( subtitle=ft.Text(
'The greeting message', "The greeting message"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=_on_name_change, on_click=lambda _: print("clicked username"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -181,16 +35,16 @@ def Settings(page: ft.Page):
[ [
ft.ListTile( ft.ListTile(
leading=ft.Icon(ft.icons.PHONE), leading=ft.Icon(ft.icons.PHONE),
title=ft.Text('Phone'), title=ft.Text("Phone"),
subtitle=ft.Text( subtitle=ft.Text(
'Personal Phone number', "Personal Phone number"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=_on_phone_change, on_click=lambda _: print("clicked phone"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -199,16 +53,16 @@ def Settings(page: ft.Page):
[ [
ft.ListTile( ft.ListTile(
leading=ft.Icon(ft.icons.EMAIL), leading=ft.Icon(ft.icons.EMAIL),
title=ft.Text('Email'), title=ft.Text("Email"),
subtitle=ft.Text( subtitle=ft.Text(
'Personal Email', "Personal Email"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=_on_email_change, on_click=lambda _: print("clicked email"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -217,54 +71,54 @@ def Settings(page: ft.Page):
[ [
ft.ListTile( ft.ListTile(
leading=ft.Icon(ft.icons.CARD_TRAVEL), leading=ft.Icon(ft.icons.CARD_TRAVEL),
title=ft.Text('NID'), title=ft.Text("NID"),
subtitle=ft.Text( subtitle=ft.Text(
'National Idenity Number', "National Idenity Number"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=_on_nid_change, on_click=lambda _: print("clicked email"),
), )
), ),
], ]
), )
) )
settingsContainer.controls.append( settingsContainer.controls.append(
generalSettings, generalSettings
) )
# settingsContainer.controls.append(ft.Divider())
# settingsContainer.controls.append(ft.Text('Notifications'))
# notificationsSettings = ft.Container(
# content=ft.Column(
# controls=[
# ft.Card(
# content=ft.Container(
# ink=True,
# content=ft.Column(
# [
# ft.ListTile(
# leading=ft.Icon(ft.icons.TELEGRAM),
# title=ft.Text('Telegram'),
# subtitle=ft.Text(
# 'Telegram Notifications for reminders and Bill pays',
# ),
# ),
# ],
# ),
# padding=10,
# on_click=lambda _: print('clicked username'),
# ),
# ),
# ],
# ),
# )
# settingsContainer.controls.append(
# notificationsSettings,
# )
settingsContainer.controls.append(ft.Divider()) settingsContainer.controls.append(ft.Divider())
settingsContainer.controls.append(ft.Text('Apps')) settingsContainer.controls.append(ft.Text("Notifications"))
notificationsSettings = ft.Container(
content=ft.Column(
controls=[
ft.Card(
content=ft.Container(
ink=True,
content=ft.Column(
[
ft.ListTile(
leading=ft.Icon(ft.icons.TELEGRAM),
title=ft.Text("Telegram"),
subtitle=ft.Text(
"Telegram Notifications for reminders and Bill pays"
),
),
]
),
padding=10,
on_click=lambda _: print("clicked username"),
)
),
]
)
)
settingsContainer.controls.append(
notificationsSettings
)
settingsContainer.controls.append(ft.Divider())
settingsContainer.controls.append(ft.Text("Apps"))
appsSettings = ft.Container( appsSettings = ft.Container(
content=ft.Column( content=ft.Column(
controls=[ controls=[
@ -277,18 +131,18 @@ def Settings(page: ft.Page):
leading=ft.Image( leading=ft.Image(
border_radius=ft.border_radius.all(10), border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN, fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idZJsIaold/id9-VJM_HU.png', src="https://asset.brandfetch.io/idZJsIaold/id9-VJM_HU.png"
), ),
title=ft.Text('Dhiraagu'), title=ft.Text("Dhiraagu"),
subtitle=ft.Text( subtitle=ft.Text(
'An ISP Service.', "An ISP Service."
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=lambda _: page.go('/settings/dhiraagu'), on_click=lambda _: print("clicked dhiraagu"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -299,18 +153,18 @@ def Settings(page: ft.Page):
leading=ft.Image( leading=ft.Image(
border_radius=ft.border_radius.all(10), border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN, fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idR1xFKHLD/idu6J-WQsm.jpeg', src="https://asset.brandfetch.io/idR1xFKHLD/idu6J-WQsm.jpeg"
), ),
title=ft.Text('Ooredoo'), title=ft.Text("Ooredoo"),
subtitle=ft.Text( subtitle=ft.Text(
'An ISP Service.', "An ISP Service."
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=lambda _: page.go('/settings/ooredoo'), on_click=lambda _: print("clicked ooredoo"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -321,18 +175,18 @@ def Settings(page: ft.Page):
leading=ft.Image( leading=ft.Image(
border_radius=ft.border_radius.all(10), border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN, fit=ft.ImageFit.CONTAIN,
src='https://www.stelco.com.mv/wp-content/uploads/2022/02/unnamed.png', src="https://www.stelco.com.mv/wp-content/uploads/2022/02/unnamed.png"
), ),
title=ft.Text('STELCO'), title=ft.Text("STELCO"),
subtitle=ft.Text( subtitle=ft.Text(
'Electricity Bills', "Electricity Bills"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=lambda _: page.go('/settings/stelco'), on_click=lambda _: print("clicked stelco"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -343,18 +197,18 @@ def Settings(page: ft.Page):
leading=ft.Image( leading=ft.Image(
border_radius=ft.border_radius.all(10), border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN, fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idOZWUOUm-/idNastd9Bg.jpeg', src="https://asset.brandfetch.io/idOZWUOUm-/idNastd9Bg.jpeg"
), ),
title=ft.Text('MWSC'), title=ft.Text("MWSC"),
subtitle=ft.Text( subtitle=ft.Text(
'Water Bills', "Water Bills"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=lambda _: page.go('/settings/mwsc'), on_click=lambda _: print("clicked mwsc"),
), )
), ),
ft.Card( ft.Card(
content=ft.Container( content=ft.Container(
@ -365,41 +219,27 @@ def Settings(page: ft.Page):
leading=ft.Image( leading=ft.Image(
border_radius=ft.border_radius.all(10), border_radius=ft.border_radius.all(10),
fit=ft.ImageFit.CONTAIN, fit=ft.ImageFit.CONTAIN,
src='https://asset.brandfetch.io/idLMZnv5SC/iduyX4keYN.jpeg', src="https://asset.brandfetch.io/idLMZnv5SC/iduyX4keYN.jpeg"
), ),
title=ft.Text('Medianet'), title=ft.Text("Medianet"),
subtitle=ft.Text( subtitle=ft.Text(
'Online Television Service', "Online Television Service"
), ),
), ),
], ]
), ),
padding=10, padding=10,
on_click=lambda _: page.go('/settings/medianet'), on_click=lambda _: print("clicked medianet"),
), )
), ),
], ]
), )
) )
settingsContainer.controls.append(appsSettings) settingsContainer.controls.append(appsSettings)
settingsContainer.controls.append(ft.Divider()) settingsContainer.controls.append(ft.Divider())
settingsContainer.controls.append(ft.Text('Theme')) settingsContainer.controls.append(ft.Text("Theme"))
def _on_theme_change(e):
def _on_theme_change(e: ft.ControlEvent): Theme(page).change()
if page.theme_mode == ft.ThemeMode.LIGHT:
e.value = False
config.save('general', 'theme', 'dark')
else:
e.value = True
config.save('general', 'theme', 'light')
Theme(page).change(
(
ft.ThemeMode.DARK
if page.theme_mode == ft.ThemeMode.LIGHT
else ft.ThemeMode.LIGHT
),
)
themeSettings = ft.Container( themeSettings = ft.Container(
content=ft.Column( content=ft.Column(
controls=[ controls=[
@ -407,30 +247,30 @@ def Settings(page: ft.Page):
content=ft.Container( content=ft.Container(
content=ft.Container( content=ft.Container(
ft.Switch( ft.Switch(
label=' Switch to dark theme',
on_change=_on_theme_change,
value=True, value=True,
label=" Switch to dark theme",
on_change=_on_theme_change
), ),
), ),
padding=10, padding=10,
on_click=None, on_click=None,
), )
), ),
], ]
), )
) )
settingsContainer.controls.append(themeSettings) settingsContainer.controls.append(themeSettings)
return AppView( return AppView(
'/settings', "/settings",
[ [
ft.AppBar( ft.AppBar(
leading=ft.IconButton( leading=ft.IconButton(
ft.icons.ARROW_BACK_IOS_NEW_ROUNDED, ft.icons.ARROW_BACK_IOS_NEW_ROUNDED,
on_click=lambda _: page.go('/'), on_click=lambda _: page.go("/")
), ),
title=ft.Text(Title(str(__file__))), title=ft.Text(Title(str(__file__))),
bgcolor=ft.colors.TRANSPARENT, bgcolor=ft.colors.TRANSPARENT
), ),
settingsContainer, settingsContainer
], ],
) )

@ -1,2 +1 @@
flet==0.22.* flet==0.22.*
requests

@ -1,11 +1,9 @@
from .view import AppView from .view import AppView
from .title import Title from .title import Title
from .views import views_handler from .views import views_handler
from .network import checkInternet
__all__ = [ __all__ = [
'AppView', "AppView",
'Title', "Title",
'views_handler', "views_handler"
'checkInternet', ]
]

@ -1,11 +0,0 @@
import requests
def checkInternet():
try:
requests.get(
'https://rest.ensembl.org/info/ping?content-type=application/json',
)
return True
except requests.ConnectionError:
return False

@ -1,5 +1,4 @@
import os import os
def Title(title: str): def Title(title: str):
return str(os.path.basename(title)).split('.')[0].title().replace('_', ' ') return str(os.path.basename(title)).replace('.py', '').title()

@ -1,8 +1,7 @@
import flet as ft import flet as ft
class AppView(ft.View): class AppView(ft.View):
def __init__(self, route, controls): def __init__(self, route, controls):
super().__init__() super().__init__()
self.controls = controls self.controls = controls
self.route = route self.route = route

@ -1,33 +1,7 @@
from modules import Home, Settings from modules import Home, Settings
from apps import Apps
from apps.plugins import Ooredoo, Dhiraagu, Medianet, Mwsc, Stelco
from modules.settings.appSettings import (
DhiraaguSettings,
MedianetSettings,
StelcoSettings,
OoredooSettings,
MwscSettings,
)
def views_handler(page): def views_handler(page):
views = {} return {
# root '/': Home(page),
views['/'] = Home(page) '/settings': Settings(page)
}
# settings
views['/settings'] = Settings(page)
views['/settings/dhiraagu'] = DhiraaguSettings(page)
views['/settings/ooredoo'] = OoredooSettings(page)
views['/settings/mwsc'] = MwscSettings(page)
views['/settings/medianet'] = MedianetSettings(page)
views['/settings/stelco'] = StelcoSettings(page)
# apps
views['/apps'] = Apps(page)
views['/apps/dhiraagu'] = Dhiraagu(page)
views['/apps/ooredoo'] = Ooredoo(page)
views['/apps/medianet'] = Medianet(page)
views['/apps/mwsc'] = Mwsc(page)
views['/apps/stelco'] = Stelco(page)
return views

@ -1,5 +0,0 @@
from .dhiraagu import DhiraaguAPI
__all__ = [
'DhiraaguAPI',
]

@ -1,43 +0,0 @@
import requests
class DhiraaguAPI:
def __init__(
self,
phone: str = None,
otp: str = None,
token: str = None,
account: str = None,
) -> None:
self.phone = phone
self.otp = otp
self.token = token
self.account = account
self.headers = {
'Host': 'app-production.dhiraagu.com.mv',
'Content-Type': 'application/json',
'Connection': 'keep-alive',
'Accept': '*/*',
'User-Agent': 'MyDhiraagu/5.0 (mv.com.dhiraagu.app; build:1; iOS 17.5.0) Alamofire/5.6.1',
'Accept-Language': 'en-US;q=1.0, dv-MV;q=0.9, ar-MV;q=0.8',
# 'Content-Length': '33',
# 'Accept-Encoding': 'br;q=1.0, gzip;q=0.9, deflate;q=0.8',
}
if self.token:
self.headers['Authorization'] = f'Bearer {self.token}'
def login(self):
data = requests.post(
'https://app-production.dhiraagu.com.mv/auth',
json={
'number': self.phone,
'otp': self.otp,
},
)
return data.json()
def bills(self):
return requests.get(
f'https://app-production.dhiraagu.com.mv/io/v1/info/subscribers/{self.account}/liberate/billinfo',
headers=self.headers,
).json()