Skip to content

Commit c78071d

Browse files
committed
Merge branch 'dev'
2 parents 1559feb + 2abdb91 commit c78071d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1019
-410
lines changed

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ PROJECT_NAME = "pyEchoNext"
4848
# could be handy for archiving the generated documentation or if some version
4949
# control system is used.
5050

51-
PROJECT_NUMBER = "0.6.11"
51+
PROJECT_NUMBER = "0.7.11"
5252

5353
# Using the PROJECT_BRIEF tag one can provide an optional one line description
5454
# for a project that appears at the top of each page and should give viewer a

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Welcome to **EchoNext**, where innovation meets simplicity! Are you tired of the
4545

4646
**Imagine** a lightweight framework that empowers you to create modern web applications with lightning speed and flexibility. With EchoNext, you're not just coding; you're building a masterpiece!
4747

48-
> Last stable version: 0.6.11 alpha
48+
> Last stable version: 0.7.11 alpha
4949
5050
> Next Big Update: ASYNC & unicorn support
5151
@@ -767,7 +767,7 @@ To test the web framework, PyTest with the pytest-cov plugin is used. You can lo
767767

768768
| Statements | Miss | Coverage |
769769
|------------|------------|----------|
770-
| 1327 | 997 | 28% |
770+
| 1327 | 936 | 34% |
771771

772772
## Documentation 🌍
773773
Extended documentation and framework specifications are available at the following links:

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ currently being supported with security updates.
77

88
| Version | Supported |
99
| ------- | ------------------ |
10+
| 0.7.11 | :white_check_mark: |
1011
| 0.6.11 | :white_check_mark: |
1112
| 0.6.10 | :white_check_mark: |
1213
| 0.6.9 | :white_check_mark: |

docs/en/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
4. [Request/Response](./requests_responses.md)
99
5. [i18n](./i18n_locales.md)
1010
6. [Security](./security.md)
11+
7. [MVC](./mvc.md)
1112

1213
## Additional materials
1314

docs/en/mvc.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# pyEchoNext / MVC Architecture
2+
3+
---
4+
5+
MVC stands for Model-View-Controller, an architectural pattern that divides an application into three logical components: the model, the View, and the controller.
6+
7+
The main idea of the MVC pattern is that each section of code has its own purpose. Part of the code contains application data, the other is responsible for how the user sees it, the latter controls its operation.
8+
9+
+ Model code **Model** stores data and associated logic, and anchors the structure of the application. That is, the programmer will determine the main components of the application using the template.
10+
+ The application's appearance code, **View**, consists of functions that are responsible for the interface and how the user interacts with it. Views are created based on data collected from the model.
11+
+ The controller code, **Controller**, links the model and view. It receives user input, interprets it and informs about the necessary changes. For example, sends commands to update state, such as saving a document.
12+
13+
---
14+
15+
[Contents](./index.md)
16+
17+

docs/ru/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
4. [Request/Response](./requests_responses.md)
99
5. [i18n](./i18n_locales.md)
1010
6. [Безопасность](./security.md)
11+
7. [MVC](./mvc.md)
1112

1213
## Дополнительные материалы
1314

docs/ru/mvc.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# pyEchoNext / MVC Architecture
2+
3+
---
4+
5+
MVC - Model-View-Controller, архитектурный паттерн, который разделяет приложение на три логических компонента: модель, View (представление) и контроллер.
6+
7+
Основная идея паттерна MVC в том, что у каждого раздела кода есть своя цель. Часть кода содержит данные приложения, друга отвечает за то, каким видит его пользователь, последняя управлеяет его работой.
8+
9+
+ Код модели **Model** хранит данные и связанную с ними логику, а также закрепляет структуру приложения. То есть программист по шаблону будет определять основные компоненты приложения.
10+
+ Код внешнего вида приложения, **View**, состоит из функций, которые отвечают за интерфейс и способы взаимодействия пользователя с ним. Представления создают на основе данных, собранных из модели.
11+
+ Код контроллера, **Controller**, связывает модель и представление. Он получает на вход пользовательский ввод, интепретирует его и информирует о необходимых изменениях. Например, отправляет команды для обновления состояния, таких как сохранение документа.
12+
13+
---
14+
15+
[Содержание](./index.md)
16+
17+

examples/advanced_app.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,35 @@
33
from pyechonext.app import ApplicationType, EchoNext
44
from pyechonext.config import Settings
55
from pyechonext.middleware import middlewares
6-
from pyechonext.urls import URL, IndexView
7-
from pyechonext.views import View
6+
from pyechonext.mvc.controllers import PageController
7+
from pyechonext.urls import URL
88

99

10-
class UsersView(View):
11-
def get(self, request, response, **kwargs):
12-
return "users get"
10+
class UsersPageController(PageController):
11+
def get(self, request, response, **kwargs):
12+
return "users get"
1313

14-
def post(self, request, response, **kwargs):
15-
return "users post"
14+
def post(self, request, response, **kwargs):
15+
return "users post"
1616

1717

18-
url_patterns = [URL(url="/", view=IndexView), URL(url="/users", view=UsersView)]
18+
url_patterns = [URL(path="/users", controller=UsersPageController)]
1919
settings = Settings(
20-
BASE_DIR=os.path.dirname(os.path.abspath(__file__)), TEMPLATES_DIR="templates"
20+
BASE_DIR=os.path.dirname(os.path.abspath(__file__)), TEMPLATES_DIR="templates"
2121
)
2222
echonext = EchoNext(
23-
__name__,
24-
settings,
25-
middlewares,
26-
urls=url_patterns,
27-
application_type=ApplicationType.HTML,
23+
__name__,
24+
settings,
25+
middlewares,
26+
urls=url_patterns,
27+
application_type=ApplicationType.HTML,
2828
)
2929

3030

3131
@echonext.route_page("/book")
32-
class BooksResource(View):
33-
def get(self, request, response, **kwargs):
34-
return f"Books Page: {request.GET}"
32+
class BooksResource(PageController):
33+
def get(self, request, response, **kwargs):
34+
return f"Books Page: {request.GET}"
3535

36-
def post(self, request, response, **kwargs):
37-
return "Endpoint to create a book"
36+
def post(self, request, response, **kwargs):
37+
return "Endpoint to create a book"

examples/example_locale.py

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,83 @@
1-
import os
2-
31
from pyechonext.apidoc_ui import APIDocUI, APIDocumentation
42
from pyechonext.app import ApplicationType, EchoNext
53
from pyechonext.config import SettingsConfigType, SettingsLoader
64
from pyechonext.middleware import middlewares
7-
from pyechonext.response import Response
5+
from pyechonext.mvc.controllers import PageController
86
from pyechonext.static import StaticFile
97
from pyechonext.template_engine.jinja import render_template
10-
from pyechonext.urls import URL, IndexView
8+
from pyechonext.urls import URL
119
from pyechonext.utils.exceptions import MethodNotAllow
12-
from pyechonext.views import View
1310

1411

15-
class UsersView(View):
16-
def get(self, request, response, **kwargs):
17-
return render_template(
18-
request,
19-
"index.html",
20-
user_name="User",
21-
session_id=request.session_id,
22-
friends=["Bob", "Anna", "John"],
23-
)
12+
class UsersView(PageController):
13+
def get(self, request, response, *args, **kwargs):
14+
return render_template(
15+
request,
16+
"index.html",
17+
user_name="User",
18+
session_id=request.session_id,
19+
friends=["Bob", "Anna", "John"],
20+
)
2421

25-
def post(self, request, response, **kwargs):
26-
raise MethodNotAllow(f"Request {request.path}: method not allow")
22+
def post(self, request, response, *args, **kwargs):
23+
raise MethodNotAllow(f"Request {request.path}: method not allow")
2724

2825

29-
url_patterns = [URL(url="/", view=IndexView), URL(url="/users", view=UsersView)]
26+
url_patterns = [URL(path="/users", controller=UsersView)]
3027
config_loader = SettingsLoader(SettingsConfigType.PYMODULE, "el_config.py")
3128
settings = config_loader.get_settings()
3229
static_files = [StaticFile(settings, "styles.css")]
3330
echonext = EchoNext(
34-
__name__,
35-
settings,
36-
middlewares,
37-
urls=url_patterns,
38-
application_type=ApplicationType.HTML,
39-
static_files=static_files,
31+
__name__,
32+
settings,
33+
middlewares,
34+
urls=url_patterns,
35+
application_type=ApplicationType.HTML,
36+
static_files=static_files,
4037
)
4138
apidoc = APIDocumentation(echonext)
4239

4340

4441
@echonext.route_page("/api-docs")
4542
def api_docs(request, response):
46-
ui = APIDocUI(apidoc.generate_spec())
47-
return ui.generate_html_page()
43+
ui = APIDocUI(apidoc.generate_spec())
44+
return ui.generate_html_page()
4845

4946

5047
@echonext.route_page("/book")
51-
class BooksResource(View):
52-
"""
53-
This class describes a books resource.
54-
"""
55-
56-
def get(self, request, response, **kwargs):
57-
"""
58-
get queries
59-
60-
:param request: The request
61-
:type request: Request
62-
:param response: The response
63-
:type response: Response
64-
:param kwargs: The keywords arguments
65-
:type kwargs: dictionary
66-
67-
:returns: result
68-
:rtype: str
69-
"""
70-
return echonext.i18n_loader.get_string("title %{name}", name=str(request.GET))
71-
72-
def post(self, request, response, **kwargs):
73-
"""
74-
post queries
75-
76-
:param request: The request
77-
:type request: Request
78-
:param response: The response
79-
:type response: Response
80-
:param kwargs: The keywords arguments
81-
:type kwargs: dictionary
82-
83-
:returns: result
84-
:rtype: str
85-
"""
86-
return echonext.l10n_loader.format_currency(1305.50)
48+
class BooksResource(PageController):
49+
"""
50+
This class describes a books resource.
51+
"""
52+
53+
def get(self, request, response, **kwargs):
54+
"""
55+
get queries
56+
57+
:param request: The request
58+
:type request: Request
59+
:param response: The response
60+
:type response: Response
61+
:param kwargs: The keywords arguments
62+
:type kwargs: dictionary
63+
64+
:returns: result
65+
:rtype: str
66+
"""
67+
return echonext.i18n_loader.get_string("title %{name}", name=str(request.GET))
68+
69+
def post(self, request, response, **kwargs):
70+
"""
71+
post queries
72+
73+
:param request: The request
74+
:type request: Request
75+
:param response: The response
76+
:type response: Response
77+
:param kwargs: The keywords arguments
78+
:type kwargs: dictionary
79+
80+
:returns: result
81+
:rtype: str
82+
"""
83+
return echonext.l10n_loader.format_currency(1305.50)

examples/hashing.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from pyechonext.security.hashing import HashAlgorithm, PlainHasher, SaltedHasher
2+
3+
hasher = PlainHasher(HashAlgorithm.BLAKE2S)
4+
old_hash = hasher.hash("TEXT")
5+
new_hash = hasher.hash("TEXT")
6+
7+
if hasher.verify("TEXT", new_hash): # true
8+
print("Yes!")
9+
10+
if hasher.verify("TEXT2", old_hash): # false
11+
print("Yes!")
12+
13+
14+
hasher = SaltedHasher(HashAlgorithm.BLAKE2S, salt="bob")
15+
old_hash = hasher.hash("TEXT")
16+
new_hash = hasher.hash("TEXT")
17+
18+
if hasher.verify("TEXT", new_hash): # true
19+
print("Yes!")
20+
21+
if hasher.verify("TEXT2", old_hash): # false
22+
print("Yes!")

0 commit comments

Comments
 (0)