platzky 0.2.13__tar.gz → 0.2.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {platzky-0.2.13 → platzky-0.2.16}/PKG-INFO +2 -2
  2. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/db.py +4 -0
  3. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/graph_ql_db.py +15 -0
  4. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/json_db.py +9 -0
  5. {platzky-0.2.13 → platzky-0.2.16}/platzky/platzky.py +1 -0
  6. platzky-0.2.16/platzky/plugin_loader.py +81 -0
  7. platzky-0.2.16/platzky/static/styles.css +96 -0
  8. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/base.html +2 -97
  9. {platzky-0.2.13 → platzky-0.2.16}/pyproject.toml +1 -1
  10. platzky-0.2.13/platzky/plugin_loader.py +0 -39
  11. {platzky-0.2.13 → platzky-0.2.16}/README.md +0 -0
  12. {platzky-0.2.13 → platzky-0.2.16}/platzky/__init__.py +0 -0
  13. {platzky-0.2.13 → platzky-0.2.16}/platzky/blog/__init__.py +0 -0
  14. {platzky-0.2.13 → platzky-0.2.16}/platzky/blog/blog.py +0 -0
  15. {platzky-0.2.13 → platzky-0.2.16}/platzky/blog/comment_form.py +0 -0
  16. {platzky-0.2.13 → platzky-0.2.16}/platzky/config.py +0 -0
  17. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/__init__.py +0 -0
  18. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/db_loader.py +0 -0
  19. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/google_json_db.py +0 -0
  20. {platzky-0.2.13 → platzky-0.2.16}/platzky/db/json_file_db.py +0 -0
  21. {platzky-0.2.13 → platzky-0.2.16}/platzky/locale/en/LC_MESSAGES/messages.po +0 -0
  22. {platzky-0.2.13 → platzky-0.2.16}/platzky/locale/pl/LC_MESSAGES/messages.po +0 -0
  23. {platzky-0.2.13 → platzky-0.2.16}/platzky/models.py +0 -0
  24. {platzky-0.2.13 → platzky-0.2.16}/platzky/plugins/google-tag-manager/entrypoint.py +0 -0
  25. {platzky-0.2.13 → platzky-0.2.16}/platzky/plugins/redirections/entrypoint.py +0 -0
  26. {platzky-0.2.13 → platzky-0.2.16}/platzky/plugins/sendmail/entrypoint.py +0 -0
  27. {platzky-0.2.13 → platzky-0.2.16}/platzky/seo/seo.py +0 -0
  28. {platzky-0.2.13 → platzky-0.2.16}/platzky/static/blog.css +0 -0
  29. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/404.html +0 -0
  30. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/blog.html +0 -0
  31. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/body_meta.html +0 -0
  32. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/feed.xml +0 -0
  33. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/head_meta.html +0 -0
  34. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/home.html +0 -0
  35. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/page.html +0 -0
  36. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/post.html +0 -0
  37. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/robots.txt +0 -0
  38. {platzky-0.2.13 → platzky-0.2.16}/platzky/templates/sitemap.xml +0 -0
  39. {platzky-0.2.13 → platzky-0.2.16}/platzky/www_handler.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: platzky
3
- Version: 0.2.13
3
+ Version: 0.2.16
4
4
  Summary: Not only blog engine
5
5
  License: MIT
6
6
  Requires-Python: >=3.10,<4.0
@@ -44,6 +44,10 @@ class DB(ABC):
44
44
  except Exception as e:
45
45
  raise ValueError(f"Failed to extend DB with function {function_name}: {e}")
46
46
 
47
+ @abstractmethod
48
+ def get_app_description(self, lang) -> str:
49
+ pass
50
+
47
51
  @abstractmethod
48
52
  def get_all_posts(self, lang) -> list[Post]:
49
53
  pass
@@ -259,6 +259,21 @@ class GraphQL(DB):
259
259
  except IndexError:
260
260
  return ""
261
261
 
262
+ def get_app_description(self, lang):
263
+ description_query = gql(
264
+ """
265
+ query myquery($lang: Lang!) {
266
+ applicationSetups(where: {language: $lang}, stage: PUBLISHED) {
267
+ applicationDescription
268
+ }
269
+ }
270
+ """
271
+ )
272
+
273
+ return self.client.execute(description_query, variable_values={"lang": lang})[
274
+ "applicationSetups"
275
+ ][0].get("applicationDescription", None)
276
+
262
277
  def get_favicon_url(self):
263
278
  favicon = gql(
264
279
  """
@@ -24,6 +24,11 @@ def db_from_config(config: JsonDbConfig):
24
24
  return Json(config.data)
25
25
 
26
26
 
27
+ # TODO make all language specific methods to be available without language
28
+ # this will allow to have a default language and if there is one language
29
+ # there will be no need to pass it to the method or in db
30
+
31
+
27
32
  class Json(DB):
28
33
  def __init__(self, data: Dict[str, Any]):
29
34
  super().__init__()
@@ -31,6 +36,10 @@ class Json(DB):
31
36
  self.module_name = "json_db"
32
37
  self.db_name = "JsonDb"
33
38
 
39
+ def get_app_description(self, lang):
40
+ description = self._get_site_content().get("app_description", {})
41
+ return description.get(lang, None)
42
+
34
43
  def get_all_posts(self, lang):
35
44
  return [
36
45
  Post.model_validate(post)
@@ -102,6 +102,7 @@ def create_engine(config: Config, db) -> Engine:
102
102
  country = lang.country if (lang := config.languages.get(locale)) is not None else ""
103
103
  return {
104
104
  "app_name": config.app_name,
105
+ "app_description": app.db.get_app_description(locale) or config.app_name,
105
106
  "languages": languages_dict(config.languages),
106
107
  "current_flag": flag,
107
108
  "current_lang_country": country,
@@ -0,0 +1,81 @@
1
+ import importlib.util
2
+ import logging
3
+ import os
4
+ import sys
5
+ from os.path import abspath, dirname
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class PluginError(Exception):
11
+ pass
12
+
13
+
14
+ # TODO remove find_local_plugin after all plugins will be extracted
15
+ def find_local_plugin(plugin_name):
16
+ """Find plugin by name and return it as module.
17
+ :param plugin_name: name of plugin to find
18
+ :return: module of plugin
19
+ """
20
+ plugins_dir = os.path.join(dirname(abspath(__file__)), "plugins")
21
+ module_name = plugin_name.removesuffix(".py")
22
+ spec = importlib.util.spec_from_file_location(
23
+ module_name, os.path.join(plugins_dir, plugin_name, "entrypoint.py")
24
+ )
25
+ assert spec is not None
26
+ plugin = importlib.util.module_from_spec(spec)
27
+ sys.modules[module_name] = plugin
28
+ assert spec.loader is not None
29
+ spec.loader.exec_module(plugin)
30
+ return plugin
31
+
32
+
33
+ def find_installed_plugin(plugin_name):
34
+ """Find plugin by name and return it as module.
35
+ :param plugin_name: name of plugin to find
36
+ :raises PluginError: if plugin cannot be imported
37
+ :return: module of plugin
38
+ """
39
+ try:
40
+ return importlib.import_module(f"platzky_{plugin_name}")
41
+ except ImportError as e:
42
+ raise PluginError(
43
+ f"Plugin {plugin_name} not found. Ensure it's installed and follows "
44
+ f"the 'platzky_<plugin_name>' naming convention"
45
+ ) from e
46
+
47
+
48
+ def find_plugin(plugin_name):
49
+ """Find plugin by name and return it as module.
50
+ :param plugin_name: name of plugin to find
51
+ :raises PluginError: if plugin cannot be found or imported
52
+ :return: module of plugin
53
+ """
54
+ plugin = None
55
+ try:
56
+ plugin = find_local_plugin(plugin_name)
57
+ except FileNotFoundError:
58
+ logger.info(f"Local plugin {plugin_name} not found, trying installed version")
59
+ plugin = find_installed_plugin(plugin_name)
60
+
61
+ return plugin
62
+
63
+
64
+ def plugify(app):
65
+ """Load plugins and run their entrypoints.
66
+ :param app: Flask app
67
+ :return: Flask app
68
+ """
69
+
70
+ plugins_data = app.db.get_plugins_data()
71
+
72
+ for plugin_data in plugins_data:
73
+ plugin_config = plugin_data["config"]
74
+ plugin_name = plugin_data["name"]
75
+ try:
76
+ plugin = find_plugin(plugin_name)
77
+ plugin.process(app, plugin_config)
78
+ except Exception as e:
79
+ raise PluginError(f"Error processing plugin {plugin_name}: {e}") from e
80
+
81
+ return app
@@ -0,0 +1,96 @@
1
+ html,
2
+ body {
3
+ height: 100%;
4
+ }
5
+
6
+ body {
7
+ font-family: {{ font.name }};
8
+ }
9
+
10
+ .logo {
11
+ max-height: 6rem;
12
+ max-width: 50vw;
13
+ }
14
+
15
+ .header-row {
16
+ z-index: 1;
17
+ background-color: {{ primary_color }};
18
+ height: min-content;
19
+ display: flex;
20
+ justify-content: center;
21
+ align-items: center;
22
+ }
23
+
24
+ #main-row {
25
+ position: relative;
26
+ flex-grow: 1;
27
+ z-index: 0;
28
+ }
29
+
30
+ .left-panel-contents {
31
+ padding: 16px;
32
+ }
33
+
34
+ .left-panel {
35
+ background-color: {{ secondary_color }};
36
+ }
37
+
38
+ #left-panel {
39
+ background-color: {{ secondary_color }};
40
+ position: absolute;
41
+ height: 100%;
42
+ max-width: 80vw;
43
+ overflow-y: auto;
44
+ color: white;
45
+ inline-size: 80vw;
46
+ overflow-wrap: break-word;
47
+ z-index: 999999999;
48
+ }
49
+
50
+ @media only screen and (min-width: 768px) {
51
+ #left-panel {
52
+ inline-size: calc(100vw * 0.1666666667);
53
+ }
54
+ }
55
+
56
+ .language-indicator-text {
57
+ color: white;
58
+ font-weight: normal;
59
+ }
60
+
61
+ #languages-menu {
62
+ background-color: {{ secondary_color }};
63
+ padding: 5px 10px;
64
+ border-radius: 5px;
65
+ color: white;
66
+ }
67
+
68
+ .offcanvas-lg.offcanvas-start {
69
+ top: auto;
70
+ width: auto;
71
+ }
72
+
73
+ #filter-form form > div {
74
+ padding-bottom: 1rem;
75
+ }
76
+
77
+ #filter-form form div > span {
78
+ font-weight: bold;
79
+ padding-bottom: 0.5rem;
80
+ }
81
+
82
+ .dropdown-menu {
83
+ z-index: 1;
84
+ }
85
+
86
+ .btn {
87
+ padding: 0;
88
+ }
89
+
90
+ .btn-close {
91
+ opacity: 1;
92
+ }
93
+
94
+ i.fi {
95
+ margin: 0 0.5em;
96
+ }
@@ -4,104 +4,9 @@
4
4
  {% include "head_meta.html" %}
5
5
  {% block head_meta %}{% endblock %}
6
6
  {{ dynamic_head | safe }}
7
-
8
-
9
-
7
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
10
8
  <title>{% block title %}{{app_name}}{% endblock %}</title>
11
- <meta name="description" content=" {% block description %} {% endblock %} ">
12
- <style>
13
- html,
14
- body {
15
- height: 100%;
16
-
17
- }
18
- body {
19
- font-family: {{ font.name }}
20
- }
21
- .logo {
22
- max-height: 6rem;
23
- max-width: 50vw;
24
- }
25
- .header-row {
26
- z-index: 1;
27
- background-color: {{ primary_color }};
28
- height: min-content;
29
- display: flex;
30
- justify-content: center;
31
- align-items: center;
32
- }
33
- #main-row {
34
- position: relative;
35
- flex-grow: 1;
36
- z-index: 0;
37
- }
38
-
39
- .left-panel-contents {
40
- padding: 16px;
41
- }
42
-
43
- .left-panel {
44
- background-color: {{ secondary_color }};
45
- }
46
-
47
- #left-panel {
48
- background-color: {{ secondary_color }};
49
- position: absolute;
50
- height: 100%;
51
- max-width: 80vw;
52
- overflow-y: auto;
53
- color: white;
54
- inline-size: 80vw;
55
- overflow-wrap: break-word;
56
- z-index: 999999999;
57
- }
58
-
59
- @media only screen and (min-width: 768px) {
60
- #left-panel {
61
- inline-size: calc(100vw * 0.1666666667);
62
- }
63
-
64
- .language-indicator-text {
65
- color: white;
66
- font-weight: normal;
67
- }
68
-
69
- #languages-menu {
70
- background-color: {{ secondary_color }};
71
- padding: 5px 10px;
72
- border-radius: 5px;
73
- color: white;
74
- }
75
-
76
- .offcanvas-lg.offcanvas-start {
77
- top: auto;
78
- width: auto;
79
- }
80
-
81
- #filter-form form > div {
82
- padding-bottom: 1rem;
83
- }
84
-
85
- #filter-form form div > span {
86
- font-weight: bold;
87
- padding-bottom: 0.5rem;
88
- }
89
-
90
- .dropdown-menu {
91
- z-index: 1;
92
- }
93
-
94
- .btn {
95
- padding: 0;
96
- }
97
-
98
- .btn-close {
99
- opacity: 1;
100
- }
101
- i.fi {
102
- margin: 0 0.5em;
103
- }
104
- </style>
9
+ <meta name="description" content="{% block description %} {{ app_description }} {% endblock %}">
105
10
  </head>
106
11
  <body>
107
12
  {% block body_meta %}
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "platzky"
3
- version = "0.2.13"
3
+ version = "0.2.16"
4
4
  description = "Not only blog engine"
5
5
  authors = []
6
6
  license = "MIT"
@@ -1,39 +0,0 @@
1
- import importlib.util
2
- import os
3
- import sys
4
- from os.path import abspath, dirname
5
-
6
-
7
- def find_plugin(plugin_name):
8
- """Find plugin by name and return it as module.
9
- :param plugin_name: name of plugin to find
10
- :return: module of plugin
11
- """
12
- plugins_dir = os.path.join(dirname(abspath(__file__)), "plugins")
13
- module_name = plugin_name.removesuffix(".py")
14
- spec = importlib.util.spec_from_file_location(
15
- module_name, os.path.join(plugins_dir, plugin_name, "entrypoint.py")
16
- )
17
- assert spec is not None
18
- plugin = importlib.util.module_from_spec(spec)
19
- sys.modules[module_name] = plugin
20
- assert spec.loader is not None
21
- spec.loader.exec_module(plugin)
22
- return plugin
23
-
24
-
25
- def plugify(app):
26
- """Load plugins and run their entrypoints.
27
- :param app: Flask app
28
- :return: Flask app
29
- """
30
-
31
- plugins_data = app.db.get_plugins_data()
32
-
33
- for plugin_data in plugins_data:
34
- plugin_config = plugin_data["config"]
35
- plugin_name = plugin_data["name"]
36
- plugin = find_plugin(plugin_name)
37
- plugin.process(app, plugin_config)
38
-
39
- return app
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes