Skip to content

Commit

Permalink
Add many features + Modifying methods.
Browse files Browse the repository at this point in the history
- Add Firebase support including user authentication,
user database, and file storage
- Add google sign in
- Rename `add_user_database` to `add_user_database_using_sql`
- Replace `get_current_user` with other methods that gets the users data: `get_current_user_data`,
`set_current_user_data`, and `get_current_user_id`.
- Add `email_exists` function.
- Add `is_signed_in` function.
- Add `RedirectingPage` for pages that are created only to redirect to another page.
- Fixes
  • Loading branch information
mubarakalmehairbi committed Jul 29, 2023
1 parent 76a3289 commit fd83f2f
Show file tree
Hide file tree
Showing 13 changed files with 672 additions and 61 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ is usually required.
# Why ToUI
- Converts HTML files into a responsive app.
- Simple to understand for programmers who only know Python and HTML.
- Edit HTML files dynamically.
- The method of creating websites and the method of creating desktop apps are similar, which makes it easy to convert a website to a desktop app and vice versa.
- Contains features that will greatly support you while creating your apps, such as:
- **Sign-in feature**
- **User-specific database**
- **Uploading and downloading files**
- **Google sign in (experimental)**
- **Firebase (experimental)**
- **Password protection for your app**

# How to install
Run this command:
Expand Down
7 changes: 6 additions & 1 deletion docs/gen_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
sys.path.append("..")
from toui import Website, DesktopApp, Page, Element, IFrameElement,\
ToUIBlueprint, quick_website, quick_desktop_app, set_global_app, get_global_app, __version__
ToUIBlueprint, RedirectingPage, quick_website, quick_desktop_app, set_global_app, get_global_app, __version__
from toui._signals import File
from docs.rst_objects import Index, Section, MD, Class, Example, Function

Expand Down Expand Up @@ -33,6 +33,11 @@
cls_object.to_rst()
other_objects.append(cls_object)

cls_object = Class(RedirectingPage)
cls_object.no_inherit_methods = True
cls_object.to_rst()
other_objects.append(cls_object)

functions = []
for func in (quick_website, quick_desktop_app, set_global_app, get_global_app):
func_object = Function(func)
Expand Down
59 changes: 59 additions & 0 deletions examples/advanced_example_3_toui_with_google_sign_in.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
ToUI with Google sign in
ToUI can be used with Google sign in. This example shows how to use Google sign in with ToUI.
Make sure to create a Google app first. Also, add the following as an authorized redirect URI to your Google app:
`https://<your-domain>/toui-google-sign-in`
One way to create a Google app is through Google Firebase. Perhaps check it out.
This example uses the HTML file "test6.html":
.. code-block:: html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="sign-in"><img width="200px" src="./google_button.png"></img></button>
<p id="user-info"></p>
</body>
</html>
Python code:
"""
import os
from toui import Website, Page

# Create app
app = Website(__name__, assets_folder="assets", secret_key="some secret key")
app.add_user_database_using_sql(f"sqlite:///{os.getcwd()}/.user_database.db")

# Create pages
pg = Page(html_file="assets/test6.html", url="/")

# Create functions that will be called from HTML
def get_user_info():
pg = app.get_user_page()
if app.get_current_user():
pg.get_element("user-info").set_content(f"User: {app.get_current_user().username}")

def sign_in():
"""Sign in using Google."""
app.sign_in_using_google(client_id=os.environ['GOOGLE_CLIENT_ID'],
client_secret=os.environ['GOOGLE_CLIENT_SECRET'],
after_auth_url="/")

# Connect functions to elements
pg.get_body_element().on("load", get_user_info)
pg.get_element("sign-in").onclick(sign_in)

# Add pages to app
app.add_pages(pg)

if __name__ == '__main__':
app.run()
104 changes: 104 additions & 0 deletions examples/advanced_example_4_toui_with_firebase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""
ToUI with Firebase
ToUI can be used with Firebase. Create a Firebase app to use this example. In this example, ToUI is used with Firebase for:
- User authentication
- Stroing user data in database
- File storage
- File retrieval
This example uses the HTML file "test7.html":
.. code-block:: html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Sign in users:</h1>
<input id="username"/>
<input id="password"/>
<button id="sign-in">Sign in</button>
<button id="sign-up">Sign up</button>
<p id="output"></p>
<h1>Upload files:</h1>
<input type="file" id="file"/>
<button id="get-file">Download uploaded file</button>
<p id="output2"></p>
</body>
</html>
Python code:
"""
import sys
sys.path.append("..")
import os
from toui import Website, Page

app = Website(__name__, assets_folder="assets", secret_key="some text")
app.add_firebase(".my_firebase_credentials.json") # You can get this file from your firebase project settings
app.add_user_database_using_firebase() # Connects to firestore database. Make sure that you created one in Firebase.
BUCKET_NAME = "test-14583.appspot.com" # Change this value to match your bucket name in Firebase Storage

main_pg = Page(html_file="assets/test7.html", url="/")

def sign_in():
pg = app.get_user_page()
username = pg.get_element("username").get_value()
password = pg.get_element("password").get_value()
pg.get_element("output").set_content("loading")
success = app.signin_user(username=username, password=password)
if success:
age = app.get_current_user_data("age")
pg.get_element("output").set_content(f"Signed in successfully. Age of user: {age}")
else:
pg.get_element("output").set_content("Sign in failed")

def sign_up():
pg = app.get_user_page()
username = pg.get_element("username").get_value()
password = pg.get_element("password").get_value()
pg.get_element("output").set_content("loading")
success = app.signup_user(username=username, password=password)
if success:
app.signin_user(username=username, password=password)
value_added = app.set_current_user_data("age", 20)
pg.get_element("output").set_content(f"Signed up successfully. Age added: {value_added}")
else:
pg.get_element("output").set_content("Sign up failed")


def store_file():
pg = app.get_user_page()
file = pg.get_element("file").get_files()[0]
with open(".test_file", "w") as f:
file.save(f)
app.store_file_using_firebase(destination_path=f"{app.get_current_user_id()}/test_file", file_path=".test_file", bucket_name=BUCKET_NAME)
pg.get_element("output2").set_content("File stored")

def retrieve_file():
pg = app.get_user_page()
if os.path.exists(".new_test_file"):
raise Exception(".new_test_file already exists")
app.get_file_from_firebase(source_path=f"{app.get_current_user_id()}/test_file", new_file_path=".new_test_file", bucket_name=BUCKET_NAME)
with open(".new_test_file", "r") as f:
pg.get_element("output2").set_content("Downloaded file content: " + f.read())


main_pg.get_element("sign-in").onclick(sign_in)
main_pg.get_element("sign-up").onclick(sign_up)
main_pg.get_element("file").on("change", store_file)
main_pg.get_element("get-file").onclick(retrieve_file)

app.add_pages(main_pg)

if __name__ == '__main__':
app.run()


Binary file added examples/assets/google_button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions examples/assets/test6.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="sign-in"><img width="200px" src="./google_button.png"></img></button>
<p id="user-info"></p>
</body>
</html>
20 changes: 20 additions & 0 deletions examples/assets/test7.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Sign in users:</h1>
<input id="username"/>
<input id="password"/>
<button id="sign-in">Sign in</button>
<button id="sign-up">Sign up</button>
<p id="output"></p>
<h1>Upload files:</h1>
<input type="file" id="file"/>
<button id="get-file">Download uploaded file</button>
<p id="output2"></p>
</body>
</html>
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ flask_sock==0.6.0
flask_sqlalchemy==3.0.3
pywebview==4.1
tinycss==0.4
firebase_admin==6.2.0
4 changes: 2 additions & 2 deletions toui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .apps import DesktopApp, Website, quick_website, quick_desktop_app, set_global_app, get_global_app
from .pages import Page
from .pages import Page, RedirectingPage
from .elements import Element, IFrameElement
from .structure import ToUIBlueprint
from . import exceptions

__version__ = "v2.4.3-beta"
__version__ = "v3.0.0-beta"
Loading

0 comments on commit fd83f2f

Please sign in to comment.