Skip to content

Commit

Permalink
Merge pull request #2 from web2py/master
Browse files Browse the repository at this point in the history
Update forked copy of py4web
  • Loading branch information
dan-carroll authored Oct 26, 2024
2 parents 68d84de + 5534540 commit 6908e6e
Show file tree
Hide file tree
Showing 242 changed files with 9,579 additions and 5,065 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ cache: pip
language: python

python:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"

script:
- make test
17 changes: 10 additions & 7 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "Python: py4web",
"type": "python",
"request": "launch",
"program": "py4web.py",
"args": [
"run",
"run", "--errorlog=:stdout", "-L", "20",
"apps"
],
"console": "integratedTerminal",
"justMyCode": true,
"justMyCode": true
},
{
"name": "Python: File",
"type": "python",
"request": "launch",
"program": "${file}",
"justMyCode": true
}
]
}
}
36 changes: 17 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@
.PHONY: clean docs clean-assets assets test setup run build deploy
.PHONY: clean docs clean-assets assets tests setup run build deploy
asset-apps := _dashboard _default _scaffold _minimal _documentation showcase
asset-zips := $(asset-apps:%=py4web/assets/py4web.app.%.zip)
clean:
find . -name '*.pyc' -delete
find . -name '*~' -delete
find . -name '#*' -delete
rm -rf dist/*
clean-assets:
clean-assets: clean
rm -f py4web/assets/*
mkdir -p py4web/assets
assets: clean-assets $(asset-zips)
py4web/assets/py4web.app.%.zip: apps/%
cd $< && find . | \
egrep "\.(py|html|css|js|png|jpg|gif|json|yaml|md|txt|mm|ico)$$" | \
zip -@ $(addprefix ../../, $@)
venv:
python3 -m venv venv
venv/bin/pip install -U pip
venv/bin/pip install ./
docs: venv
venv/bin/pip install -U -r docs/requirements.txt
cd docs; . ../venv/bin/activate && ./updateDocs.sh html
test: venv
venv/bin/pip install -U -r test-requirements.txt
venv/bin/python -m pytest --cov=py4web --cov-report html:cov.html -v -s tests/
docs:
pip install -U -r docs/requirements.txt
cd docs; ./updateDocs.sh html
tests:
pip install -U -r test-requirements.txt
python -m pytest --cov=py4web --cov-report html:cov.html -v tests/
setup:
venv/bin/python py4web.py setup apps
venv/bin/python py4web.py set_password
python py4web.py setup apps
python py4web.py set_password
run:
venv/bin/python py4web.py run -p password.txt apps
python py4web.py run -p password.txt apps -L20
upgrade-utils:
find apps -name "utils.js" -exec cp apps/_dashboard/static/js/utils.js {} \;
upgrade-vue:
curl -L https://unpkg.com/vue/dist/vue.min.js > apps/_dashboard/static/js/vue.min.js
find apps -name "vue.min.js" -exec cp apps/_dashboard/static/js/vue.min.js {} \;
build: clean assets
python3 -m pip install --upgrade build
python3 -m pip install --upgrade twine
python3 -m build
pip install --upgrade build
pip install --upgrade twine
python -m build
deploy: build
python3 -m twine upload dist/*
python -m twine upload dist/*
install:
python -m pip install .
76 changes: 40 additions & 36 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
What is py4web?
===============

.. image:: https://travis-ci.com/web2py/py4web.svg?branch=master
:target: https://travis-ci.com/web2py/py4web

.. image:: https://img.shields.io/pypi/v/py4web.svg
:target: https://pypi.org/project/py4web/

Expand All @@ -22,32 +19,32 @@ Screenshots

Running py4web

.. image:: docs/images/first_run.png
.. image:: https://py4web.com/_documentation/static/en/_images/first_run.png

The main Dashboard

.. image:: docs/images/dashboard_main.png
.. image:: https://py4web.com/_documentation/static/en/_images/dashboard_main.png

Editing a file in the Dashboard

.. image:: docs/images/dashboard_edit.png
.. image:: https://py4web.com/_documentation/static/en/_images/dashboard_edit.png

Editing a database in the Dashboard

.. image:: docs/images/dashboard_restapi.png
.. image:: https://py4web.com/_documentation/static/en/_images/dashboard_restapi.png

Installation
############

PY4WEB runs fine on Windows, MacOS and Linux. There are many installation procedures (see the official documentation for details) but only two of them are summarized here.
PY4WEB runs fine on Windows, MacOS and Linux. There are many installation procedures `(see the official documentation for details) <https://py4web.com/_documentation/static/en/chapter-03.html>`__ but only two of them are summarized here.

The **simplest way** to install py4web is using binaries, but it's only available for Windows and MacOS. It's meant especially for newbies or students, because it does not require Python pre-installed on your system nor administrative rights. You just need to download the latest Windows or MacOS ZIP file from `this external repository <https://github.com/nicozanf/py4web-pyinstaller>`__. Unzip it on a local folder and open a command line there. Finally run the commands (omit './' if you're using Windows)


.. code:: bash
./py4web-start set_password
./py4web-start run apps
./py4web set_password
./py4web run apps
Expand Down Expand Up @@ -78,35 +75,42 @@ Launch Arguments
# py4web run -h
Usage: py4web.py run [OPTIONS] [APPS_FOLDER]
Usage: py4web.py run [OPTIONS] APPS_FOLDER
Run all the applications on apps_folder
Options:
-Y, --yes No prompt, assume yes to questions [default:
False]
-H, --host TEXT Host name [default: 127.0.0.1]
-P, --port INTEGER Port number [default: 8000]
-p, --password_file TEXT File for the encrypted password [default:
password.txt]
-s, --server [default|wsgiref|tornado|gunicorn|gevent|waitress|
geventWebSocketServer|wsgirefThreadingServer|rocketServer]
server to use [default: default]
-w, --number_workers INTEGER Number of workers [default: 0]
-d, --dashboard_mode TEXT Dashboard mode: demo, readonly, full,
none [default: full]
--watch [off|sync|lazy] Watch python changes and reload apps
automatically, modes: off, sync, lazy
[default: lazy]
--ssl_cert PATH SSL certificate file for HTTPS
--ssl_key PATH SSL key file for HTTPS
--errorlog TEXT Where to send error logs
(:stdout|:stderr|tickets_only|{filename})
[default: :stderr]
-L, --logging_level INTEGER The log level (0 - 50) [default: 30
(=WARNING)]
-D, --debug Debug switch [default: False]
-help, -h, --help Show this message and exit.
-Y, --yes No prompt, assume yes to questions
-H, --host TEXT Host listening IP [default: 127.0.0.1]
-P, --port INTEGER Port number [default: 8000]
-A, --app_names TEXT List of apps to run, comma separated (all if
omitted or empty)
-p, --password_file TEXT File for the encrypted password [default:
password.txt]
-Q, --quiet Suppress server output
-R, --routes Write apps routes to file
-s, --server [default|wsgiref|tornado|gunicorn|gevent|waitress|gunicorn|gunicornGevent|
gevent|geventWebSocketServer|geventWs|
wsgirefThreadingServer|wsgiTh|rocketServer]
Web server to use
-w, --number_workers INTEGER Number of workers [default: 0]
-d, --dashboard_mode TEXT Dashboard mode: demo, readonly, full, none
[default: full]
--watch [off|sync|lazy] Watch python changes and reload apps
automatically, modes: off, sync, lazy
[default: lazy]
--ssl_cert PATH SSL certificate file for HTTPS
--ssl_key PATH SSL key file for HTTPS
--errorlog TEXT Where to send error logs
(:stdout|:stderr|tickets_only|{filename})
[default: :stderr]
-L, --logging_level INTEGER The log level (0 - 50) [default: 30
(=WARNING)]
-D, --debug Debug switch
-U, --url_prefix TEXT Prefix to add to all URLs in and out
-m, --mode TEXT default or development [default: default]
-h, -help, --help Show this message and exit.
Expand Down Expand Up @@ -180,4 +184,4 @@ Many thanks to everyone who has contributed to the project, and especially:
- `sugizo <https://github.com/sugizo>`__
- `valq7711 <https://github.com/valq7711>`__
- `Kevin Keller <https://github.com/Kkeller83>`__
- `Sam de Alfaro <sam@dealfaro.com>`__ (logo design)
- Sam de Alfaro sam@dealfaro.com (logo design)
13 changes: 8 additions & 5 deletions apps/_dashboard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def apps():
apps.sort(key=lambda item: item["name"])
return {"payload": apps, "status": "success"}

@action("delete_app/<name:re:\w+>", method="POST")
@action("delete_app/<name:re:\\w+>", method="POST")
@session_secured
def delete_app(name):
"""delete the app"""
Expand All @@ -209,7 +209,7 @@ def delete_app(name):
return {"status": "success", "payload": "Deleted"}
return {"status": "success", "payload": "App does not exist"}

@action("new_file/<name:re:\w+>/<file_name:path>", method="POST")
@action("new_file/<name:re:\\w+>/<file_name:path>", method="POST")
@session_secured
def new_file(name, file_name):
"""creates a new file"""
Expand Down Expand Up @@ -417,9 +417,9 @@ def save(path, reload_app=True):
"""Saves a file"""
app_name = path.split("/")[0]
path = safe_join(FOLDER, path) or abort()
with open(path, "w") as myfile:
with open(path, "wb") as myfile:
body = json.load(request.body)
myfile.write(body)
myfile.write(body.encode("utf8"))
if reload_app:
Reloader.import_app(app_name)
return {"status": "success"}
Expand Down Expand Up @@ -567,7 +567,10 @@ def gitshow(project, commit):
@action.uses(Logged(session), "translations.html")
def translations(name):
"""returns a json with all translations for all languages"""
t = Translator(os.path.join(FOLDER, name, "translations"))
folder = os.path.join(FOLDER, name, "translations")
if not os.path.exists(folder):
os.makedirs(folder)
t = Translator(folder)
return t.languages


Expand Down
33 changes: 18 additions & 15 deletions apps/_dashboard/static/components/mtable.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@
if (filters.length) url += '&'+filters.join('&');
if (self.order) url += '&@order='+self.order;
self.busy = true;
axios.get(url).then(function (res) {
Q.get(url).then(function (res) {
self.busy = false;
if(!length) self.table = res.data;
else self.table.items = self.table.items.concat(res.data.items);
if(!length) self.table = res.json();
else self.table.items = self.table.items.concat(res.json().items);
});
};

Expand Down Expand Up @@ -100,8 +100,8 @@
reference_table_url.pop()
reference_table_url.push(field.references)
reference_table_url = reference_table_url.join('/') + '?@options_list=true';
axios.get(reference_table_url).then(function (res) {
let url_components = res.config.url.split('?')[0].split('/');
Q.get(reference_table_url).then(function (res) {
let url_components = res.json().config.url.split('?')[0].split('/');
self.reference_options[url_components[url_components.length - 1 ]] = res.data.items;
});

Expand Down Expand Up @@ -129,7 +129,7 @@
if (window.confirm("Really delete record?")) {
let url = this.url + '/' + item.id;
this.table.items = this.table.items.filter((i)=>{return i.id != item.id;});
axios.delete(url);
Q.delete(url);
if (item==this.item) this.item = null;
}
};
Expand All @@ -150,27 +150,30 @@
}
if (item.id) {
url += '/' + item.id;
axios.put(url, item).then(mtable.handle_response('put', this),
mtable.handle_response('put', this));
var data = JSON.parse(JSON.stringify(item));
delete data["id"];
Q.put(url, data).then(mtable.handle_response('put', this),
mtable.handle_response('put', this));
} else {
axios.post(url, item).then(mtable.handle_response('post', this),
mtable.handle_response('post', this));
}
Q.post(url, item).then(mtable.handle_response('post', this),
mtable.handle_response('post', this));
}
};

mtable.handle_response = function(method, data) {
self.busy = false;
return function(res) {
if (res.response) res = res.response; // deal with error weirdness
res = res.json();
if (method == 'post') {
data.table.items = [];
mtable.methods.load.call(data);
}
if (res.data.status == 'success') {
if (res.status == 'success') {
data.clear();
location.reload();
} else {
data.errors = res.data.errors;
data.message = res.data.message;
data.errors = res.errors;
data.message = res.message;
}
};
};
Expand Down
Loading

0 comments on commit 6908e6e

Please sign in to comment.