shopyo-appadmin 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,20 @@
1
+ from typing import Any
2
+
3
+ from flask import Flask
4
+ from shopyo_appadmin.view import module_blueprint
5
+
6
+ __version__ = "1.0.0"
7
+
8
+
9
+ class ShopyoAppAdmin:
10
+ def __init__(self, app: Any = None) -> None:
11
+ if app is not None:
12
+ self.init_app(app)
13
+
14
+ def init_app(self, app: Flask) -> None:
15
+ if not hasattr(app, "extensions"):
16
+ app.extensions = {}
17
+
18
+ app.extensions["shopyo_appadmin"] = self
19
+ bp = module_blueprint
20
+ app.register_blueprint(bp)
@@ -0,0 +1,26 @@
1
+ from functools import wraps
2
+
3
+ from flask import redirect
4
+ from flask_login import current_user
5
+ from init import login_manager
6
+ from shopyo_auth.models import User
7
+
8
+ from shopyo.api.html import notify_warning
9
+
10
+ login_manager.login_message = notify_warning("Please login for access")
11
+
12
+
13
+ @login_manager.user_loader
14
+ def load_user(id):
15
+ return User.query.get(id)
16
+
17
+
18
+ def admin_required(f):
19
+ @wraps(f)
20
+ def wrap(*args, **kwargs):
21
+ if current_user.is_admin:
22
+ return f(*args, **kwargs)
23
+ else:
24
+ return redirect("/")
25
+
26
+ return wrap
@@ -0,0 +1,12 @@
1
+ {
2
+ "display_string": "Admin",
3
+ "type": "show",
4
+ "fa-icon": "fas fa-user-lock",
5
+ "url_prefix": "/appadmin",
6
+ "module_name": "appadmin",
7
+ "author": {
8
+ "name":"Abdur-Rahmaan Janhangeer",
9
+ "website":"https://www.pythonkitchen.com/about-me/",
10
+ "mail":"arj.python@gmail.com"
11
+ }
12
+ }
File without changes
@@ -0,0 +1,86 @@
1
+ {% extends "shopyo_base/module_base.html" %}
2
+ {% set active_page = "admin" %}
3
+ {% block pagehead %}
4
+ <title>{{active_page.capitalize()}}</title>
5
+ <style>
6
+ .hidden {
7
+ display: none;
8
+ }
9
+
10
+ .show {
11
+ display: inline-block;
12
+ }
13
+
14
+ .active {
15
+ width: 6rem;
16
+ color: white;
17
+ background-color: #34ce57;
18
+ }
19
+
20
+ .inactive {
21
+ width: 6rem;
22
+ color: white;
23
+ background-color: #ff253a;
24
+ }
25
+
26
+ .all_inactive {
27
+ display: none;
28
+ }
29
+ </style>
30
+ {% endblock %}
31
+ {% block sidebar %}
32
+ {%include 'appadmin/blocks/sidebar.html'%}
33
+ {%endblock%}
34
+ {% block content %}
35
+ <br>
36
+ <div class="container col-md-6 off-set-3">
37
+ <div class="card">
38
+ <div class="card-body">
39
+ <form action="/appadmin/add" method="post">
40
+ <div class="input-group mb-3">
41
+ <div class="input-group-prepend">
42
+ <span class="input-group-text"><i class="fa fa-user"></i></span>
43
+ </div>
44
+ <input type="email" name="email" class="form-control" id="email" placeholder="Email" required autocomplete="off">
45
+ </div>
46
+ <div class="input-group mb-3">
47
+ <div class="input-group-prepend">
48
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
49
+ </div>
50
+ <input type="password" name="password" class="form-control" id="user_password" placeholder="Password" required autocomplete="off">
51
+ </div>
52
+ <div class="input-group mb-3">
53
+ <div class="input-group-prepend">
54
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
55
+ </div>
56
+ <input type="text" name="first_name" class="form-control" placeholder="First Name" autocomplete="off">
57
+ </div>
58
+ <div class="input-group mb-3">
59
+ <div class="input-group-prepend">
60
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
61
+ </div>
62
+ <input type="text" name="last_name" class="form-control" placeholder="Last Name" autocomplete="off">
63
+ </div>
64
+ <div class="input-group mb-3">
65
+ <div class="custom-control custom-checkbox">
66
+ <input type="checkbox" name="is_admin" class="custom-control-input" id="is_admin" value="True" checked>
67
+ <label for="is_admin" class="custom-control-label">Admin User</label>
68
+ </div>
69
+ </div>
70
+ <table class="table">
71
+ <tbody>
72
+ {%for role in roles%}
73
+ <tr>
74
+ <td><input type="checkbox" name="role_{{role.id}}"></td>
75
+ <td>{{role.name}}</td>
76
+ </tr>
77
+ {%endfor%}
78
+ </tbody>
79
+ </table>
80
+ <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
81
+ <input type="submit" class="btn btn-info" value="add" required>
82
+ </form>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ {% endblock %}
@@ -0,0 +1,25 @@
1
+ {{
2
+ sidebar_item(
3
+ 'Home',
4
+ icon='fas fa-user-lock',
5
+ url=url_for('appadmin.user_list')
6
+ )
7
+ }}
8
+
9
+
10
+ {{
11
+ sidebar_item(
12
+ 'Add',
13
+ icon='fas fa-plus-circle',
14
+ url=url_for('appadmin.user_add')
15
+ )
16
+ }}
17
+
18
+
19
+ {{
20
+ sidebar_item(
21
+ 'Roles',
22
+ icon='fa fa-shield-alt',
23
+ url=url_for('appadmin.roles')
24
+ )
25
+ }}
@@ -0,0 +1,69 @@
1
+ {% extends "shopyo_base/module_base.html" %}
2
+ {% set active_page = "admin" %}
3
+ {% block pagehead %}
4
+ <title>edit</title>
5
+ {% endblock %}
6
+ {% block sidebar %}
7
+ {%include 'appadmin/blocks/sidebar.html'%}
8
+ {%endblock%}
9
+ {% block content %}
10
+ <br>
11
+ <div class="card">
12
+ <div class="card-body">
13
+ <h2>Edit User</h2>
14
+ <form action='/appadmin/update' method="post">
15
+ <label>Edit User:<span> {{ user.email }} </span></label>
16
+ <div class="input-group mb-3">
17
+ </div>
18
+ <div class="input-group mb-3">
19
+ <div class="input-group-prepend">
20
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
21
+ </div>
22
+ <input type="text" name="email" class="form-control" id="user_email" value="{{ user.email }}" required autocomplete="off">
23
+ </div>
24
+ <div class="input-group mb-3">
25
+ <div class="input-group-prepend">
26
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
27
+ </div>
28
+ <input type="password" name="password" class="form-control" id="user_password" value="" autocomplete="off">
29
+ </div>
30
+ <div class="">
31
+ <div class="">
32
+ <input type="checkbox" name="is_admin" id="is_admin" class="" {{'checked' if user.is_admin}}>
33
+ <label for="is_admin" class="custom-control-label">Admin User</label>
34
+ </div>
35
+ </div>
36
+ <div class="input-group mb-3">
37
+ <div class="input-group-prepend">
38
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
39
+ </div>
40
+ <input type="text" name="first_name" class="form-control" placeholder="First Name" autocomplete="off" value="{{ user.first_name }}">
41
+ </div>
42
+ <div class="input-group mb-3">
43
+ <div class="input-group-prepend">
44
+ <span class="input-group-text"><i class="fa fa-key"></i></span>
45
+ </div>
46
+ <input type="text" name="last_name" class="form-control" placeholder="Last Name" autocomplete="off" value="{{ user.last_name }}">
47
+ </div>
48
+ <input required name="id" id="user_id" type="hidden" class="form-control" value="{{ user.id }}">
49
+ <div>
50
+ Roles<br>
51
+ <table class="table">
52
+ <tbody>
53
+ {%for role in roles%}
54
+ <tr>
55
+ <td><input type="checkbox" name="role_{{role.id}}" {%if role.name in user_roles%} checked {%endif%}></td>
56
+ <td>{{role.name}}</td>
57
+ </tr>
58
+ {%endfor%}
59
+ </tbody>
60
+ </table>
61
+ </div>
62
+ <div class="input-group mb-3">
63
+ <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
64
+ <input required type="submit" class="btn btn-info" value="edit">
65
+ </div>
66
+ </form>
67
+ </div>
68
+ </div>
69
+ {% endblock %}
@@ -0,0 +1,81 @@
1
+ {% extends "shopyo_base/module_base.html" %}
2
+ {% set active_page ='admin' %}
3
+ {% block pagehead %}
4
+ <title>{{active_page.capitalize()}}</title>
5
+ <style>
6
+ .hidden{
7
+ display: none;
8
+ }
9
+ .show{
10
+ display: inline-block;
11
+ }
12
+ </style>
13
+ {% endblock %}
14
+ {% block sidebar %}
15
+ {%include 'appadmin/blocks/sidebar.html'%}
16
+ {%endblock%}
17
+ {% block content %}
18
+ <br>
19
+ <script type="text/javascript">
20
+ $(function() {
21
+ $('.delete_me').click(function() {
22
+ var id = $(this).data('id');
23
+ console.log(id);
24
+ var ask = confirm("Do you want to delete ?");
25
+ if (ask == true) {
26
+ window.open("/appadmin/delete/" + id, "_self")
27
+ } else {
28
+
29
+ }
30
+ });
31
+ });
32
+ </script>
33
+ <div class="container">
34
+ <div class="card">
35
+ <div class="card-body">
36
+ <h2>{{active_page.capitalize()}}</h2>
37
+ <table class="table table-responsive table-bordered">
38
+ <thead>
39
+ <tr>
40
+ <th>ID</th>
41
+ <th>Email</th>
42
+ <th>Password</th>
43
+ <th>Admin</th>
44
+ <th>Roles</th>
45
+ <th style="border: none;"></th>
46
+ </tr>
47
+ </thead>
48
+ <tbody>
49
+ {% for user in users %}
50
+ <tr>
51
+ <td>{{user.id}}</td>
52
+ <td>{{user.email}}</td>
53
+ <td>*******</td>
54
+ <td>{{user.is_admin}}</td>
55
+ <td>
56
+ {%for role in user.roles%}
57
+ <div class="badge badge-primary">
58
+ {{role.name}}
59
+ </div>
60
+ {%endfor%}
61
+ </td>
62
+ <td style="border: none;">
63
+ <div style='display: inline-block; '>
64
+ <a style="text-decoration: none;">
65
+ <button id='delete' data-id="{{ user.id }}" class="delete_me btn btn-dark" type="" name="{{ user.id }}"><i class="fas fa-trash-alt"></i></button>
66
+ </a>
67
+ &nbsp;
68
+ <a href="/appadmin/edit/{{ user.id }}" style="text-decoration: none;">
69
+ <button data-name="{{ user.id }}" class="btn btn-warning"><i id="ico-{{user.id}}" class="fas fa-pencil-alt"></i>
70
+ </button>
71
+ </a>
72
+ </div>
73
+ </td>
74
+ </tr>
75
+ {% endfor %}
76
+ </tbody>
77
+ </table>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ {% endblock %}
@@ -0,0 +1,40 @@
1
+ {% extends "shopyo_base/module_base.html" %}
2
+ {% set active_page = "admin" %}
3
+ {% block pagehead %}
4
+ {% endblock %}
5
+ {% block sidebar %}
6
+ {%include 'appadmin/blocks/sidebar.html'%}
7
+ {%endblock%}
8
+ {% block content %}
9
+ <br>
10
+ <div class="card">
11
+ <div class="card-body">
12
+ <h2>Roles</h2>
13
+ <div class="">
14
+ <form class="" method="POST" action='{{url_for("appadmin.roles_add")}}'>
15
+ <div class="form-group">
16
+ <input name="csrf_token" value="{{csrf_token()}}" type="hidden">
17
+ <input class="form-control" type="" name="name"><br>
18
+ <button class="btn btn-info" type="submit">add</button>
19
+ </div>
20
+ </form>
21
+ <table>
22
+ <tbody>
23
+ {%for role in roles%}
24
+ <tr>
25
+ <form action="{{url_for('appadmin.roles_update')}}" method="POST">
26
+ <td>
27
+ <input value="{{role.name}}" class="form-control" type="" name="role_name"></td>
28
+ <input type="hidden" name="role_id" value="{{role.id}}">
29
+ <input type="hidden" name="csrf_token" value="{{csrf_token()}}">
30
+ <td><button class="btn btn-info form-control" type="submit">save</button></td>
31
+ <td><a class="btn btn-danger" href="{{url_for('appadmin.roles_delete', role_id=role.id)}}">delete</a></td>
32
+ </form>
33
+ </tr>
34
+ {%endfor%}
35
+ </tbody>
36
+ </table>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ {% endblock %}
@@ -0,0 +1,236 @@
1
+ """
2
+ .. module:: AdminViews
3
+ :synopsis: All endpoints of the admin views are defined here.
4
+
5
+ """
6
+
7
+ from flask import flash
8
+ from flask import redirect
9
+ from flask import render_template
10
+ from flask import request
11
+ from flask import url_for
12
+ from flask_login import login_required
13
+ from init import db
14
+ from shopyo_auth.models import Role
15
+ from shopyo_auth.models import User
16
+ from sqlalchemy import exists
17
+
18
+ from .admin import admin_required
19
+ from shopyo.api.html import notify_success
20
+ from shopyo.api.html import notify_warning
21
+ from shopyo.api.module import ModuleHelp
22
+
23
+ # from config import Config
24
+
25
+ mhelp = ModuleHelp(__file__, __name__)
26
+ globals()[mhelp.blueprint_str] = mhelp.blueprint
27
+ module_blueprint = globals()[mhelp.blueprint_str]
28
+
29
+
30
+ @module_blueprint.route("/")
31
+ @login_required
32
+ @admin_required
33
+ def user_list():
34
+ """
35
+ **Get The List of User**
36
+
37
+ Lists all users in the database.
38
+
39
+ """
40
+ context = {}
41
+ context["users"] = User.query.all()
42
+ return render_template("appadmin/index.html", **context)
43
+
44
+
45
+ @module_blueprint.route("/add", methods=["GET", "POST"])
46
+ @login_required
47
+ @admin_required
48
+ def user_add():
49
+ """
50
+ **Adds a User**
51
+
52
+ adds a user to database.
53
+
54
+ """
55
+ context = {}
56
+ if request.method == "POST":
57
+ email = request.form["email"]
58
+ password = request.form["password"]
59
+ first_name = request.form["first_name"]
60
+ last_name = request.form["last_name"]
61
+ admin_user = request.form.get("is_admin")
62
+ if admin_user == "True":
63
+ is_admin = True
64
+ else:
65
+ is_admin = False
66
+
67
+ has_user = db.session.query(exists().where(User.email == email)).scalar()
68
+
69
+ if not has_user:
70
+ new_user = User()
71
+ new_user.email = email
72
+ new_user.is_admin = is_admin
73
+ new_user.first_name = first_name
74
+ new_user.last_name = last_name
75
+ new_user.password = password
76
+
77
+ for key in request.form:
78
+ if key.startswith("role_"):
79
+ role_id = key.split("_")[1]
80
+ role = Role.get_by_id(role_id)
81
+ new_user.roles.append(role)
82
+ new_user.save()
83
+ return redirect(url_for("appadmin.user_add"))
84
+
85
+ flash(notify_warning("User with same email already exists"))
86
+
87
+ context["roles"] = Role.query.all()
88
+ return render_template("appadmin/add.html", **context)
89
+
90
+
91
+ @module_blueprint.route("/delete/<id>", methods=["GET"])
92
+ @login_required
93
+ @admin_required
94
+ def admin_delete(id):
95
+ """
96
+ **Delete a User**
97
+
98
+ :param id: id of the user
99
+ :type id: int
100
+
101
+ """
102
+ user = User.query.get(id)
103
+
104
+ if user is None:
105
+ flash(notify_warning("Unable to delete. Invalid user id"))
106
+ return redirect("/appadmin")
107
+
108
+ user.delete()
109
+ flash(notify_success("User successfully deleted"))
110
+ return redirect("/appadmin")
111
+
112
+
113
+ @module_blueprint.route("/edit/<id>", methods=["GET"])
114
+ @login_required
115
+ @admin_required
116
+ def admin_edit(id):
117
+ """
118
+ **Update information for a User**
119
+
120
+ :param id: id of the user
121
+ :type id: int
122
+
123
+ """
124
+ context = {}
125
+ user = User.query.get(id)
126
+
127
+ if user is None:
128
+ flash(notify_warning("Unable to edit. Invalid user id"))
129
+ return redirect("/appadmin")
130
+
131
+ context["user"] = user
132
+ context["user_roles"] = [r.name for r in user.roles]
133
+ context["roles"] = Role.query.all()
134
+ return render_template("appadmin/edit.html", **context)
135
+
136
+
137
+ @module_blueprint.route("/update", methods=["POST"])
138
+ @login_required
139
+ @admin_required
140
+ def admin_update():
141
+ """
142
+ **Update a User record**
143
+
144
+ """
145
+ id = request.form["id"]
146
+ password = request.form["password"]
147
+ email = request.form["email"]
148
+ first_name = request.form["first_name"]
149
+ last_name = request.form["last_name"]
150
+ is_admin = request.form.get("is_admin")
151
+
152
+ if is_admin:
153
+ is_admin = True
154
+ else:
155
+ is_admin = False
156
+
157
+ user = User.query.get(id)
158
+
159
+ if user is None:
160
+ flash(notify_warning("Unable to update. User does not exist."))
161
+ return redirect("/admin")
162
+
163
+ user.is_admin = is_admin
164
+ user.email = email
165
+ user.first_name = first_name
166
+ user.last_name = last_name
167
+ user.roles[:] = []
168
+
169
+ if password.strip():
170
+ user.password = password
171
+
172
+ for key in request.form:
173
+ if key.startswith("role_"):
174
+ role_id = key.split("_")[1]
175
+ role = Role.get_by_id(role_id)
176
+ user.roles.append(role)
177
+
178
+ user.update()
179
+ flash(notify_success("User successfully updated"))
180
+ return redirect("/appadmin")
181
+
182
+
183
+ @module_blueprint.route("/roles")
184
+ @login_required
185
+ @admin_required
186
+ def roles():
187
+ context = {}
188
+ context["roles"] = Role.query.all()
189
+ return render_template("appadmin/roles.html", **context)
190
+
191
+
192
+ @module_blueprint.route("/roles/add", methods=["POST"])
193
+ @login_required
194
+ @admin_required
195
+ def roles_add():
196
+ if request.method == "POST":
197
+ if not Role.query.filter(Role.name == request.form["name"]).first():
198
+ role = Role(name=request.form["name"])
199
+ role.save()
200
+ flash(notify_success("Role successfully added"))
201
+ return redirect(url_for("appadmin.roles"))
202
+ flash(notify_warning("Role already exists"))
203
+ return redirect(url_for("appadmin.roles"))
204
+
205
+
206
+ @module_blueprint.route("/roles/<role_id>/delete", methods=["GET"])
207
+ @login_required
208
+ @admin_required
209
+ def roles_delete(role_id):
210
+ role = Role.get_by_id(role_id)
211
+
212
+ if role is None:
213
+ flash(notify_warning("Unable to delete. Invalid role id"))
214
+ return redirect(url_for("appadmin.roles"))
215
+
216
+ role.delete()
217
+ flash(notify_success("Role successfully deleted"))
218
+ return redirect(url_for("appadmin.roles"))
219
+
220
+
221
+ @module_blueprint.route("/roles/update", methods=["POST"])
222
+ @login_required
223
+ @admin_required
224
+ def roles_update():
225
+ if request.method == "POST":
226
+ role = Role.get_by_id(request.form["role_id"])
227
+
228
+ if role is None:
229
+ flash(notify_warning("Unable to update. Role does not exist"))
230
+ return redirect(url_for("appadmin.roles"))
231
+
232
+ role.name = request.form["role_name"]
233
+ role.update()
234
+ flash(notify_success("Role successfully updated"))
235
+
236
+ return redirect(url_for("appadmin.roles"))
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.1
2
+ Name: shopyo_appadmin
3
+ Version: 1.0.0
4
+ Summary: Base module containing jinja macros and templates
5
+ Author-email: Abdur-Rahmaan Janhangeer <arj.python@gmail.com>
6
+ Project-URL: Homepage, https://github.com/shopyo/shopyo
7
+ Project-URL: Bug Tracker, https://github.com/shopyo/shopyo/issues
8
+ Keywords: shopyo
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.8
13
+ Requires-Dist: shopyo
14
+
@@ -0,0 +1,14 @@
1
+ shopyo_appadmin/__init__.py,sha256=v4NkmixHhPJDjpMwKB2vR8nG6lhp86LGreyKzBmINPI,488
2
+ shopyo_appadmin/admin.py,sha256=92Liq0xfGiSn8Ie1zpMuhNeRpzbEzp1Y9wRdqI39y7k,561
3
+ shopyo_appadmin/info.json,sha256=XOcVuIDmjVnNqvJX5fISAgLbUqOCoX0COZf6aJD8bOk,278
4
+ shopyo_appadmin/models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ shopyo_appadmin/view.py,sha256=HXbMiQ09WIOQcvDhjgEycSGsP9ki9Mo3tFXFGTZ8iTc,6231
6
+ shopyo_appadmin/templates/shopyo_appadmin/add.html,sha256=jpjWCxqcdJrRqdMdF0yll-Y6e8OAkmCEPEzr1sI-Uro,3347
7
+ shopyo_appadmin/templates/shopyo_appadmin/edit.html,sha256=5Pt6g_Uv-aJyE3crFNsdqRl59qNjIO3kj-RZ4t10npo,3126
8
+ shopyo_appadmin/templates/shopyo_appadmin/index.html,sha256=wZvex5N0DpYOO1ZpS7I_Uw2xEqPM1XQW3Jm_DqDhgwg,2803
9
+ shopyo_appadmin/templates/shopyo_appadmin/roles.html,sha256=_AZBH9xcZ19zAZUL4yTdkI20iE1oYPGm2LDUeEDYkJY,1661
10
+ shopyo_appadmin/templates/shopyo_appadmin/blocks/sidebar.html,sha256=wkOXPTxapMpDqpExCMYTRaq7TKT-UID2Qyo9YuyBZcw,268
11
+ shopyo_appadmin-1.0.0.dist-info/METADATA,sha256=ctsQ_6tkhXNlUtPerGYED-_9sRzMGz-eCTwa8RIpf6Y,511
12
+ shopyo_appadmin-1.0.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
13
+ shopyo_appadmin-1.0.0.dist-info/top_level.txt,sha256=KVlLWbVgtnB1dbH6wjKC0qPnkO4J5g5BsF8fIDOau7E,16
14
+ shopyo_appadmin-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ shopyo_appadmin