first commit
This commit is contained in:
commit
417e54da96
5696 changed files with 900003 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,53 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import socket
|
||||
|
||||
import requests
|
||||
from firebase import firebase
|
||||
|
||||
|
||||
def get_connect(func, host="8.8.8.8", port=53, timeout=3):
|
||||
"""Checks for an active Internet connection."""
|
||||
|
||||
def wrapped(*args):
|
||||
try:
|
||||
socket.setdefaulttimeout(timeout)
|
||||
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(
|
||||
(host, port)
|
||||
)
|
||||
return func(*args)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
class DataBase:
|
||||
"""
|
||||
Your methods for working with the database should be implemented in this
|
||||
class.
|
||||
"""
|
||||
|
||||
name = "Firebase"
|
||||
|
||||
def __init__(self):
|
||||
self.DATABASE_URL = "https://fir-db73a-default-rtdb.firebaseio.com/"
|
||||
# Address for users collections.
|
||||
self.USER_DATA = "Userdata"
|
||||
# RealTime Database attribute.
|
||||
self.real_time_firebase = firebase.FirebaseApplication(
|
||||
self.DATABASE_URL, None
|
||||
)
|
||||
|
||||
@get_connect
|
||||
def get_data_from_collection(self, name_collection: str) -> dict | bool:
|
||||
"""Returns data of the selected collection from the database."""
|
||||
|
||||
try:
|
||||
data = self.real_time_firebase.get(
|
||||
self.DATABASE_URL, name_collection
|
||||
)
|
||||
except requests.exceptions.ConnectionError:
|
||||
return False
|
||||
|
||||
return data
|
|
@ -0,0 +1,134 @@
|
|||
"""
|
||||
Restdb.io API Wrapper
|
||||
---------------------
|
||||
|
||||
This package is an API Wrapper for the website `restdb.io <https://restdb.io>`_,
|
||||
which allows for online databases.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def get_connect(func, host="8.8.8.8", port=53, timeout=3):
|
||||
"""Checks for an active Internet connection."""
|
||||
|
||||
def wrapped(*args):
|
||||
try:
|
||||
socket.setdefaulttimeout(timeout)
|
||||
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(
|
||||
(host, port)
|
||||
)
|
||||
return func(*args)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
class DataBase:
|
||||
name = "RestDB"
|
||||
|
||||
def __init__(self):
|
||||
database_url = "https://restdbio-5498.restdb.io"
|
||||
api_key = "7ce258d66f919d3a891d1166558765f0b4dbd"
|
||||
|
||||
self.HEADERS = {"x-apikey": api_key, "Content-Type": "application/json"}
|
||||
# Address for file collections.
|
||||
self.USER_MEDIA = f"{database_url}/media"
|
||||
# Address for users collections.
|
||||
self.USER_DATA = f"{database_url}/rest/userdata"
|
||||
|
||||
@get_connect
|
||||
def upload_file(self, path_to_file: str) -> dict | bool:
|
||||
"""
|
||||
Uploads a file to the database.
|
||||
You can upload a file to the database only from a paid account.
|
||||
"""
|
||||
|
||||
HEADERS = self.HEADERS.copy()
|
||||
del HEADERS["Content-Type"]
|
||||
payload = {}
|
||||
name_file = os.path.split(path_to_file)[1]
|
||||
files = [("file", (name_file, open(path_to_file, "rb"), name_file))]
|
||||
response = requests.post(
|
||||
url=self.USER_MEDIA,
|
||||
headers=HEADERS,
|
||||
data=payload,
|
||||
files=files,
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
# {
|
||||
# "msg":"OK",
|
||||
# "uploadid": "ed1bca42334f68d873161641144e57b7",
|
||||
# "ids": ["62614fb90f9df71600284aa7"],
|
||||
# }
|
||||
json = response.json()
|
||||
if "msg" in json and json["msg"] == "OK":
|
||||
return json
|
||||
else:
|
||||
return False
|
||||
|
||||
@get_connect
|
||||
def get_data_from_collection(self, collection_address: str) -> bool | list:
|
||||
"""Returns data of the selected collection from the database."""
|
||||
|
||||
response = requests.get(url=collection_address, headers=self.HEADERS)
|
||||
if response.status_code != 200:
|
||||
return False
|
||||
else:
|
||||
return response.json()
|
||||
|
||||
@get_connect
|
||||
def delete_doc_from_collection(self, collection_address: str) -> bool:
|
||||
"""
|
||||
Delete data of the selected collection from the database.
|
||||
|
||||
:param collection_address: "database_url/id_collection".
|
||||
"""
|
||||
|
||||
response = requests.delete(collection_address, headers=self.HEADERS)
|
||||
if response.status_code == 200:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@get_connect
|
||||
def add_doc_to_collection(
|
||||
self, data: dict, collection_address: str
|
||||
) -> bool:
|
||||
"""Add collection to the database."""
|
||||
|
||||
response = requests.post(
|
||||
url=collection_address,
|
||||
data=json.dumps(data),
|
||||
headers=self.HEADERS,
|
||||
)
|
||||
if response.status_code == 201:
|
||||
if "_id" in response.json():
|
||||
return response.json()
|
||||
else:
|
||||
return False
|
||||
|
||||
@get_connect
|
||||
def edit_data(
|
||||
self, collection: dict, collection_address: str, collection_id: str
|
||||
) -> bool:
|
||||
"""Modifies data in a collection of data in a database."""
|
||||
|
||||
response = requests.put(
|
||||
url=f"{collection_address}/{collection_id}",
|
||||
headers=self.HEADERS,
|
||||
json=collection,
|
||||
)
|
||||
if response.status_code == 200:
|
||||
if "_id" in response.json():
|
||||
return True
|
||||
else:
|
||||
return False
|
Binary file not shown.
|
@ -0,0 +1,12 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-10-27 18:54+0300\n"
|
||||
"PO-Revision-Date: 2019-09-22 23:12+0300\n"
|
||||
"Last-Translator: KivyMD library https://github.com/kivymd/KivyMD\n"
|
||||
"Language-Team: KivyMD library https://github.com/kivymd/KivyMD\n"
|
||||
"Language: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
|
@ -0,0 +1,12 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-10-27 18:54+0300\n"
|
||||
"PO-Revision-Date: 2019-09-22 23:12+0300\n"
|
||||
"Last-Translator: KivyMD library https://github.com/kivymd/KivyMD\n"
|
||||
"Language-Team: KivyMD library https://github.com/kivymd/KivyMD\n"
|
||||
"Language: English\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
|
@ -0,0 +1 @@
|
|||
# This package is for additional application modules.
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,49 @@
|
|||
import gettext
|
||||
|
||||
from kivy.lang import Observable
|
||||
|
||||
|
||||
class Translation(Observable):
|
||||
"""Original source - https://github.com/tito/kivy-gettext-example."""
|
||||
|
||||
observers = []
|
||||
|
||||
def __init__(self, defaultlang, domian, resource_dir):
|
||||
super().__init__()
|
||||
self.ugettext = None
|
||||
self.lang = defaultlang
|
||||
self.domian = domian
|
||||
self.resource_dir = resource_dir
|
||||
self.switch_lang(self.lang)
|
||||
|
||||
def _(self, text):
|
||||
return self.ugettext(text)
|
||||
|
||||
def fbind(self, name, func, args, **kwargs):
|
||||
if name == "_":
|
||||
self.observers.append((func, args, kwargs))
|
||||
else:
|
||||
return super().fbind(name, func, *args, **kwargs)
|
||||
|
||||
def funbind(self, name, func, args, **kwargs):
|
||||
if name == "_":
|
||||
key = (func, args, kwargs)
|
||||
if key in self.observers:
|
||||
self.observers.remove(key)
|
||||
else:
|
||||
return super().funbind(name, func, *args, **kwargs)
|
||||
|
||||
def switch_lang(self, lang):
|
||||
locales = gettext.translation(
|
||||
self.domian, self.resource_dir, languages=[lang]
|
||||
)
|
||||
try:
|
||||
self.ugettext = locales.ugettext
|
||||
except AttributeError:
|
||||
self.ugettext = locales.gettext
|
||||
|
||||
for func, largs, kwargs in self.observers:
|
||||
try:
|
||||
func(largs, None, None)
|
||||
except ReferenceError:
|
||||
pass
|
|
@ -0,0 +1,18 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-10-27 18:54+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,210 @@
|
|||
"""
|
||||
The script creates a new View package
|
||||
=====================================
|
||||
|
||||
The script creates a new View package in an existing project with an MVC
|
||||
template created using the create_project utility.
|
||||
|
||||
.. versionadded:: 1.0.0
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Utility create_project <https://kivymd.readthedocs.io/en/latest/api/kivymd/tools/patterns/create_project/>`_
|
||||
|
||||
.. rubric:: Use a clean architecture for your applications.
|
||||
|
||||
To add a new view to an existing project that was created using the
|
||||
`create_project` utility, use the following command::
|
||||
|
||||
kivymd.add_view \\
|
||||
name_pattern \\
|
||||
path_to_project \\
|
||||
name_view
|
||||
|
||||
Example command::
|
||||
|
||||
kivymd.add_view \\
|
||||
MVC \\
|
||||
/Users/macbookair/Projects \\
|
||||
NewScreen
|
||||
|
||||
You can also add new views with responsive behavior to an existing project::
|
||||
|
||||
kivymd.add_view \\
|
||||
MVC \\
|
||||
/Users/macbookair/Projects \\
|
||||
NewScreen \\
|
||||
--use_responsive yes
|
||||
|
||||
For more information about adaptive design,
|
||||
`see here <https://kivymd.readthedocs.io/en/latest/components/responsivelayout/>`_.
|
||||
"""
|
||||
|
||||
__all__ = [
|
||||
"main",
|
||||
]
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from kivy import Logger
|
||||
|
||||
from kivymd.tools.argument_parser import ArgumentParserWithHelp
|
||||
from kivymd.tools.patterns.create_project import (
|
||||
chek_camel_case_name_project,
|
||||
create_common_responsive_module,
|
||||
create_controller,
|
||||
create_model,
|
||||
create_view,
|
||||
)
|
||||
|
||||
screens_data = """%s
|
||||
|
||||
screens = {%s
|
||||
}"""
|
||||
|
||||
screns_comment = """# The screen's dictionary contains the objects of the models and controllers
|
||||
# of the screens of the application.
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
"""The function of adding a new view to the project."""
|
||||
|
||||
global screens_data
|
||||
|
||||
parser = create_argument_parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
# pattern_name isn't used currently, will be used if new patterns is added in future
|
||||
pattern_name = args.pattern # noqa F841
|
||||
path_to_project = args.directory
|
||||
name_view = args.name
|
||||
use_responsive = args.use_responsive
|
||||
|
||||
if not os.path.exists(path_to_project):
|
||||
parser.error(f"Project <{path_to_project}> does not exist...")
|
||||
|
||||
if name_view[-6:] != "Screen":
|
||||
parser.error(
|
||||
f"The name of the <{name_view}> screen should contain the word "
|
||||
f"'Screen' at the end.\n"
|
||||
"For example - '--name_screen MyFirstScreen ...'"
|
||||
)
|
||||
|
||||
if name_view in os.listdir(os.path.join(path_to_project, "View")):
|
||||
parser.error(
|
||||
f"The <{name_view}> view also exists in the <{path_to_project}> project..."
|
||||
)
|
||||
|
||||
# Create model.
|
||||
name_database = (
|
||||
"yes"
|
||||
if "database.py" in os.listdir(os.path.join(path_to_project, "Model"))
|
||||
else "no"
|
||||
)
|
||||
module_name = chek_camel_case_name_project(name_view)
|
||||
if not module_name:
|
||||
parser.error(
|
||||
"The name of the screen should be written in camel case style. "
|
||||
"\nFor example - 'MyFirstScreen'"
|
||||
)
|
||||
module_name = "_".join([name.lower() for name in module_name])
|
||||
path_to_project = path_to_project
|
||||
create_model(name_view, module_name, name_database, path_to_project)
|
||||
|
||||
# Create controller.
|
||||
# FIXME: This is not a very good solution in order to understand whether
|
||||
# a project uses a hot reload or not. Because the string
|
||||
# 'from kivymd.tools.hotreload.app import MDApp' in the project can just
|
||||
# be commented out and the project does not actually use hot reload.
|
||||
with open(os.path.join(path_to_project, "main.py")) as main_module:
|
||||
if "from kivymd.tools.hotreload.app import MDApp" in main_module.read():
|
||||
use_hotreload = "yes"
|
||||
else:
|
||||
use_hotreload = "no"
|
||||
create_controller(
|
||||
name_view, module_name, use_hotreload, path_to_project
|
||||
)
|
||||
# Create View.
|
||||
if use_responsive == "no":
|
||||
create_view(name_view, module_name, [], path_to_project)
|
||||
else:
|
||||
create_view(name_view, module_name, [name_view], path_to_project)
|
||||
create_common_responsive_module([name_view], path_to_project)
|
||||
# Create 'View.screens.py module'.
|
||||
create_screens_data(name_view, module_name, path_to_project)
|
||||
Logger.info(
|
||||
f"KivyMD: The {name_view} view has been added to the project..."
|
||||
)
|
||||
|
||||
|
||||
def create_screens_data(
|
||||
name_view: str, module_name: str, path_to_project: str
|
||||
) -> None:
|
||||
with open(
|
||||
os.path.join(path_to_project, "View", "screens.py")
|
||||
) as screen_module:
|
||||
screen_module = screen_module.read()
|
||||
imports = re.findall(
|
||||
"from Model.*Model|from Controller.*Controller", screen_module
|
||||
)
|
||||
screens = ""
|
||||
path_to_view = os.path.join(path_to_project, "View")
|
||||
|
||||
for name in os.listdir(path_to_view):
|
||||
if os.path.isdir(os.path.join(path_to_view, name)):
|
||||
res = re.findall("[A-Z][a-z]*", name)
|
||||
if res and len(res) == 2 and res[-1] == "Screen":
|
||||
screens += (
|
||||
"\n '%s': {"
|
||||
"\n 'model': %s,"
|
||||
"\n 'controller': %s,"
|
||||
"\n },"
|
||||
% (
|
||||
f"{res[0].lower()} {res[1].lower()}",
|
||||
f'{"".join(res)}Model',
|
||||
f'{"".join(res)}Controller',
|
||||
)
|
||||
)
|
||||
|
||||
imports.append(f"from Model.{module_name} import {name_view}Model")
|
||||
imports.append(
|
||||
f"from Controller.{module_name} import {name_view}Controller"
|
||||
)
|
||||
imports.insert(0, screns_comment)
|
||||
screens = screens_data % ("\n".join(imports), screens)
|
||||
|
||||
with open(
|
||||
os.path.join(path_to_project, "View", "screens.py"), "w"
|
||||
) as screen_module:
|
||||
screen_module.write(screens)
|
||||
|
||||
|
||||
def create_argument_parser() -> ArgumentParserWithHelp:
|
||||
parser = ArgumentParserWithHelp(
|
||||
prog="create_project.py",
|
||||
allow_abbrev=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"pattern",
|
||||
help="the name of the pattern with which the project will be created.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"directory",
|
||||
help="the directory of the project to which you want to add a new view.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"name",
|
||||
help="the name of the view to add to an existing project.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--use_responsive",
|
||||
default="no",
|
||||
help="whether to create a view with responsive behavior.",
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue