Fixes in admin

This commit is contained in:
Antonio de la Rosa 2025-01-18 01:48:46 +01:00
parent 8a3c58d969
commit 573b0c4917
9 changed files with 744 additions and 16 deletions

View file

@ -4,6 +4,7 @@ from pydantic import BaseModel
from settings import config from settings import config
#from parameciofast.fastadmin import admin_app #from parameciofast.fastadmin import admin_app
from importlib import import_module from importlib import import_module
from parameciofast.libraries.datetime import set_timezone
import os import os
app=FastAPI() app=FastAPI()
@ -13,7 +14,7 @@ yes_static=True
if hasattr(config, 'yes_static'): if hasattr(config, 'yes_static'):
yes_static=config.yes_static yes_static=config.yes_static
set_timezone()
# apps={'admin': ['paramecio2.modules.admin', 'admin_app']} # apps={'admin': ['paramecio2.modules.admin', 'admin_app']}
# Get all apps, load. # Get all apps, load.

View file

@ -0,0 +1,452 @@
"""
Parameciofast is a series of wrappers for FastAPI, mako and others and construct a simple headless cms.
Copyright (C) 2025 Antonio de la Rosa Caballero
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
#By default id is not showed
from parameciofast.libraries.pages import Pages
from parameciofast.libraries.urls import add_get_parameters
from parameciofast.libraries.i18n import I18n, PGetText
#from flask import request, session
#from parameciofast.libraries.get_data import get_query_args
import sys
import re
pgettext=PGetText(__file__)
_=pgettext.gettext
class SimpleList:
"""Class for create item list from a model table
"""
def __init__(self, model, url, t, request):
"""Class for create item list from a model table
You can create lists using a WebModel. You can select the show fields, and you have features how order by field and simple searchs.
Args:
model (WebModel): A WebModel model (equivalent to database mysql table)
url (str): A string with the base url for the forms.
t (PTemplate): Template used for the class. Normally template subclassed from admin_t PTemplate
Attributes:
raw_query (boolean): If True then raw query is done, if False then query with all related fields is done
t (PTemplate): Template used for the class. Normally template subclassed from admin_t PTemplate
model (WebModel): The webmodel used for generate the admin model form
fields (list): A list with fields names of model getting of db query
fields_showed (list): A list with fields names of model showed in list
url (str): Base url used by SimpleList for generate edit, insert and other urls.
limit_pages (int): The number of items by page. By default, 20 items
order_defaults (list): Internal list used for define Ascendent and Descendent in sql queries
order_class (list): Internal list used for show icons for ascendent or descendent field selection
order (str): Default order used in order_defaults list
order_field (str): The default field used for order the list. By default is the model id field
order_by (str): The default order ASC or DESC defined in order_class list. By default is 0 or ASC
change_order (dict): Internal dict used for get all ordenable fields from model
yes_search (boolean): If True, a search form is showed, if False, the search form is hidden.
search_text (str): Used for save the search text sended via POST.
initial_num_pages (int): Initial number of pages showed in pagination.
table_div (boolean): If True, use div for create the table, if False, use standard html table for create the table.
begin_page (int): Number that is used for begin the elements to get from query
search_fields (list): The fields used for search data in form.
arr_extra_fields (list): List with the names of extra fields
arr_extra_options (list): List with a set of functions used how extra fields. This functions return lists with different options, joined with jln attribute.
jln (list): Jump line for join options by default.
ajax (boolean): If True, ajax is used for get items for the list and change page, if False, typical httpd request is used for change the items page.
request(Request): A request objets from FastAPI/Starlette for get parameters
"""
self.raw_query=True
self.t=t
self.model=model
#if len(self.model.forms)==0:
#self.model.create_forms()
self.fields=model.fields.keys()
self.fields_showed=self.fields
self.url=url
self.limit_pages=20
self.order_defaults=['ASC', 'DESC']
self.order_class=['down', 'up']
#self.s=get_session()
#clean session
self.order='0'
self.order_field=self.model.name_field_id
self.order_by=self.order_defaults[0]
self.change_order={}
self.yes_search=True
self.search_text=''
self.initial_num_pages=20
self.table_div=False
self.request=request
try:
#self.begin_page=int(request.args.get('begin_page', '0'))
#self.begin_page=int(get_query_args('begin_page', '0'))
self.begin_page=int(self.request.query_params.get('begin_page', '0'))
except ValueError:
self.begin_page=0
if self.begin_page<0:
self.begin_page=0
self.search_fields=self.fields
#self.yes_options=True
self.arr_extra_fields=[_('Options')]
self.arr_extra_options=[SimpleList.standard_options]
self.jln='<br />'
self.ajax=False
def restore_fields(self):
"""Simple method for restore default fields from model
"""
self.fields=self.model.fields.keys()
def obtain_order(self):
"""Function for set the order query defaults for list from http request query args.
"""
#self.order=request.args.get('order', self.order) #self.getpostfiles.get.get('order', self.order)
#self.order=get_query_args('order', self.order)
self.order=self.request.query_params.get('order', self.order)
order_k=int(self.order)
#Obtain from get
"""
if 'order' in request.query.keys():
"""
#order_k=int(request.query.get('order', 0))
if order_k>1 or order_k<0:
order_k=0
self.order_by=self.order_defaults[ order_k ]
self.order=order_k
def obtain_field_search(self):
"""Function for set the field search query defaults for list from http request query args.
"""
#self.order_field=get_query_args('order_field', self.order_field)
self.order_field=self.request.query_params.get('order_field', self.order_field)
field_k=self.order_field
"""
if 'order_field' in request.query.keys():
field_k=request.query.order_field
"""
if field_k in self.model.fields.keys():
self.order_field=field_k
for field in self.fields:
#Initialize foreignkeyfield fields too
if type(self.model.fields[field]).__name__=='ForeignKeyField':
name_related=self.model.fields[field].related_model.name
for k in self.model.fields[field].related_model.fields.keys():
self.change_order[field+'_'+k]=self.order
self.change_order[field]=self.order
if self.order==0:
self.change_order[field_k]=1
else:
self.change_order[field_k]=0
#self.order_field=self.order_field
def search(self):
"""Function for set the text order query defaults for list from http request query args.
"""
#self.search_text=get_query_args('search_text', '')
self.search_text=self.request.query_params.get('search_text', self.search_text)
self.search_text=self.search_text.replace('"', '&quot;')
#self.model.conditions='AND
#self.search_field=get_query_args('search_field', '')
self.search_field=self.request.query_params.get('search_field', '')
if self.search_field not in self.model.fields.keys():
self.search_field=''
if self.search_field!='' and self.search_text!='':
self.model.conditions[0]+=' AND '+self.search_field+' LIKE %s'
self.model.conditions[1].append('%'+self.search_text+'%')
pass
def set_options(self, options_func, arr_row):
"""Method for join options list returns with jln attributte separator
Returns:
options (str): Return a string with joined options
"""
#SimpleList.standard_options(arr_row)
return self.jln.join(options_func(self.url, arr_row[self.model.name_field_id], arr_row))
@staticmethod
def standard_options(url, id, arr_row):
"""Static method for get standar options for make things with the items row.
Returns:
options (list): Return a list of basic options for items row
"""
options=[]
options.append('<a href="'+add_get_parameters(url, op_admin=1, id=id)+'">'+_('Edit')+'</a>')
options.append('<a href="'+add_get_parameters(url, op_admin=3, id=id)+'">'+_('Delete')+'</a>')
return options
def show(self):
"""Method for show the table
The principal method of the class. The list is showed with the selected fields, search form, pagination...
"""
self.model.yes_reset_conditions=False
self.obtain_order()
self.obtain_field_search()
self.search()
total_elements=self.model.select_count()
num_elements=self.limit_pages
link=add_get_parameters(self.url, search_text=self.search_text, search_field=self.search_field, order=self.order)
begin_page=self.begin_page
self.model.order_by='order by '+self.order_field+' '+self.order_by
if self.limit_pages>0:
self.model.limit='limit '+str(begin_page)+','+str(self.limit_pages)
list_items=self.model.select(self.fields, self.raw_query)
#print(self.model.fields.keys())
func_jscript=''
if self.ajax==True:
func_jscript='get_page()'
pages=''
if self.limit_pages>0:
pages=Pages.show( begin_page, total_elements, num_elements, link ,initial_num_pages=self.initial_num_pages, variable='begin_page', label='', func_jscript='')
self.begin_page=str(self.begin_page)
self.model.yes_reset_conditions=True
listing=self.t.load_template('utils/list.phtml', simplelist=self, list=list_items, pages=pages, ajax=self.ajax)
list_items.close()
return listing
"""
@staticmethod
def get_ajax_page(model):
pass
"""
class AjaxList(SimpleList):
"""Class for make a list from a table based in Ajax
"""
# Fields example: [['Hostname', True], ['IP', True], ['Options', False]]
# arr_order_fields=['server.hostname', 'server.ip']
# 'select count(servercloud.id) as num_elements from servercloud where servercloud.user_id=%s'
# params count_query [s['cu_id']]
# str_query no order, no limit -> select server.hostname, server.ip, servercloud.id from server, servercloud where server.id=servercloud.server_id and servercloud.user_id=%s
# str_query_params -> [s['cu_id'], begin_page, limit]
def __init__(self, db, fields, arr_order_fields, count_query, str_query):
"""Class for make a list from a table based in Ajax
A class that is useful for creating listings based on database models using Ajax
Args:
db (sql connection): A MySQL connection used for get the model.
fields (list): A list with the fields showed in table
arr_order_fields (list): A list with the sql names of selected fields for show.
count_query (str): sql segment for count query sentence. Example: select count(id) from table WHERE name=%s
str_query (str): sql segment for query sentence. Example: select id from table WHERE name=%s
Attributes:
fields (list): A list with the fields showed in table
arr_order_fields (list): A list with the sql names of selected fields for show.
limit (int): the number of items selected in query sentence.
count_query (str): sql segment for count query sentence. Example: select count(id) from table WHERE name=%s
count_query_params (list): A list with the params for parse a sql count query with %s symbols (View python help about sql sentences and connectors)
str_query (str): sql segment for query sentence. Example: select id from table WHERE name=%s
str_query_params (list): A list with the params for parse a sql query with %s symbols (View python help about sql sentences and connectors)
initial_num_pages (int): Initial number of pages showed in pagination.
db (sql connection): A MySQL connection used for get the model.
func_fields (dict): A series of functions used for a series of extra fields referring to each row of the table
initial_order_field (str): FIeld used for order the table in first execution
initial_order (int): If 0, the initial order is Ascendent, if 1, the initial order is Descendent.
"""
self.fields=fields
self.arr_order_fields=arr_order_fields
self.limit=20
self.count_query=count_query[0]
self.count_query_params=count_query[1]
self.str_query=str_query[0]
self.str_query_params=str_query[1]
self.initial_num_pages=20
self.db=db
self.func_fields={}
self.initial_order_field=''
self.initial_order=0
def show(self):
"""Method for show the table
The principal method of the class. The list is showed with the selected fields, search form, pagination...
"""
#begin_page=int(get_query_args('position', 0))
begin_page=int(self.request.query_params.get('position', 0))
#order_field=get_query_args('order_field', self.initial_order_field)
order_field=self.request.query_params.get('order_field', self.initial_order_field)
#order=get_query_args('order', self.initial_order)
order=self.request.query_params.get('order', self.initial_order)
limit=self.limit
arr_order=['ASC', 'DESC']
order_sql=''
order_params=[]
if order_field!='':
try:
order_field=int(order_field)
order=int(order)
if order_field>=0 and order_field<len(self.arr_order_fields):
order_sql='order by %s' % self.arr_order_fields[order_field]
if order>=0 and order<2:
order_sql+=' %s' % arr_order[order]
#order_params=[self.arr_order_fields[order_field]]
except:
order_field=0
order=0
rows=[]
with self.db.query(self.count_query, self.count_query_params) as cursor:
total_elements=cursor.fetchone()['num_elements']
str_query=self.str_query+' '+order_sql
params=self.str_query_params
html_pages=''
if self.limit>0:
str_query+=' limit %s, %s'
params.append(begin_page)
params.append(limit)
pages=Pages()
html_pages=_('Pages')+': '+pages.show( begin_page, total_elements, limit, '#' ,initial_num_pages=self.initial_num_pages, variable='begin_page', label='', func_jscript='')
with self.db.query(str_query, params) as cursor:
for row in cursor:
"""
c=len(self.arr_order_fields)
for x in range(c, len(row)):
key_field=list(row.keys())[x]
#print(key_field)
pass
"""
for func_field in self.func_fields:
if func_field in row:
row[func_field]=self.func_fields[func_field](row[func_field], row)
rows.append(row)
#{k:d[k] for in set(d).intersection(l)}
return {'fields': self.fields, 'rows': rows, 'html_pages': html_pages}
class SimpleAjaxList():
pass

View file

@ -37,11 +37,6 @@ from parameciofast.libraries.i18n import I18n, PGetText
from parameciofast.libraries.urls import make_url, make_media_url, add_get_parameters from parameciofast.libraries.urls import make_url, make_media_url, add_get_parameters
#from parameciofast.libraries.formsutils import csrf_token #from parameciofast.libraries.formsutils import csrf_token
framework='flask'
if hasattr(config, 'framework'):
framework=config.framework
""" """
def _(text): def _(text):
@ -149,7 +144,7 @@ class PTemplate:
#self.add_filter(csrf_token) #self.add_filter(csrf_token)
#self.add_filter(add_get_parameters) self.add_filter(add_get_parameters)
self.add_filter(self.add_js) self.add_filter(self.add_js)

View file

@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""
Paramecio2fm is a series of wrappers for Flask, mako and others and construct a simple headless cms.
Copyright (C) 2023 Antonio de la Rosa Caballero
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from math import ceil, floor
from parameciofast.libraries.urls import add_get_parameters
from parameciofast.libraries.i18n import I18n
class Pages:
"""Simple class for create html pagination code"""
css_class='link_pages'
@staticmethod
def show( begin_page, total_elements, num_elements, link ,initial_num_pages=20, variable='begin_page', label='', func_jscript=''):
"""Static method for create the html pagination
With this method, you can create html pagination code with automated urls for load every page. You can use it also how base for ajax pagination
Args:
begin_page (int): The number where pagination begin
total_elements (int): The total items in pages
num_elements (int): The number of items for every page
link (str): The url of every page
initial_num_pages (int): Optional. Number of pages showed in pagination, if you have 50 pages, if this value is 20, an interval of 20 pages is showed, with first pages links, and after pages links for navigate between many pages.
variable (str): Optional. The name of GET url variable used for send the first element in the query for get the page.
label (str): Optional. In the future will be used for identify some html tags
func_jscript (str): Javascript function to be executed when page url is clicked.
"""
pages='';
if begin_page>total_elements:
begin_page=0
# Calculamos el total de todas las páginas
total_page=ceil(total_elements/num_elements)
# Calculamos en que página nos encontramos
actual_page=ceil(begin_page/num_elements)
# Calculamos el total de intervalos
total_interval=ceil(total_page/initial_num_pages)
# Calculamos el intervalo en el que estamos
actual_interval=floor(actual_page/initial_num_pages)
# Calculamos el elemento de inicio del intervalo
initial_page=ceil(actual_interval*initial_num_pages*num_elements)
last_page=ceil(actual_interval*initial_num_pages*num_elements)+ceil(initial_num_pages*num_elements)
if last_page>total_elements:
last_page=total_elements
if initial_page>0:
initial_link=add_get_parameters(link, **{variable: '0'});
middle_link=add_get_parameters(link, **{variable: str((initial_page-num_elements)) } );
pages += "<a class=\""+Pages.css_class+"\" href=\""+initial_link+"\" onclick=\"${func_jscript}\">1</a> <a class=\""+Pages.css_class+"\" href=\""+middle_link+"\">&lt;&lt;</a> "
arr_pages={}
#for(x=initial_page;x<last_page;x+=num_elements)
for x in range(initial_page, last_page, num_elements):
middle_link=add_get_parameters(link, **{variable: str(x)} )
num_page=ceil(x/num_elements)+1;
arr_pages[x]="<a class=\""+Pages.css_class+"\" href=\""+middle_link+"\">"+str(num_page)+"</a> "
arr_pages[begin_page]='<span class="selected_page">'+str(num_page)+'</span> ';
pages += arr_pages[x]
if last_page<total_elements:
middle_link=add_get_parameters(link, **{variable: str(x+num_elements)} );
last_link=add_get_parameters(link, **{variable: str( ( ( total_page*num_elements ) - num_elements) ) } )
pages += "<a class=\""+Pages.css_class+"\" href=\""+middle_link+"\" onclick=\"func_jscript\">&gt;&gt;</a> <a class=\"link_pages\" href=\""+last_link+"\" onclick=\"func_jscript\">"+I18n.lang('common', 'last', 'Last')+"</a>"
return pages

View file

@ -0,0 +1,137 @@
<%def name="select_field(field)">
% if simplelist.search_field==field:
selected \
% endif
</%def>
<%def name="set_css_arrow(simplelist, field)">
% if simplelist.order_field==field:
<i class="fa fa-arrow-${simplelist.order_class[simplelist.order]}" aria-hidden="true"></i>
% endif
</%def>
% if simplelist.yes_search:
<div class="form mb-4">
<form method="get" action="${simplelist.url}">
${_('Search')}: <input type="text" name="search_text" value="${simplelist.search_text|n}">
<select name="search_field">
% for field in simplelist.search_fields:
<option value="${simplelist.model.fields[field].name}" ${select_field(field)}>${simplelist.model.fields[field].label}</option>
% endfor
</select>
<input type="submit" value="${_('Search')}" />
</form>
</div>
% endif
% if not simplelist.table_div:
<table class="table" id="${simplelist.model.name}_table">
<thead>
<tr class="title_list">
% for field in simplelist.fields_showed:
<th class="${simplelist.model.fields[field].name}_td" scope="col"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></th>
% endfor
% for extra_field in simplelist.arr_extra_fields:
<td class="options_td">${ extra_field }</td>
% endfor
</th>
</thead>
<%
pos=0
%>
% for row in list:
<%
if not 'pos' in row:
row['pos']=pos
%>
<tr class="row_list">
% for field in simplelist.fields_showed:
% if simplelist.model.fields[field].escape==True:
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}</td>
% else:
<td class="${simplelist.model.fields[field].name}_td">${simplelist.model.fields[field].show_formatted(row[field])}${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}</td>
% endif
% else:
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].show_formatted(row[field]))|n}</td>
% else:
<td class="${simplelist.model.fields[field].name}_td">${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}</td>
% endif
% endif
% endfor
% for extra_field_func in simplelist.arr_extra_options:
<td class="options_td">${ simplelist.set_options(extra_field_func, row)|n }</td>
% endfor
</tr>
<%
pos+=1
%>
% endfor
</table>
% else:
<%
size_td=round(100/(len(simplelist.fields_showed)+len(simplelist.arr_extra_options)))
%>
<div class="table_list" id="${simplelist.model.name}_table">
<div class="${simplelist.model.name}_tr tr_list_div">
% for field in simplelist.fields_showed:
<div class="${simplelist.model.fields[field].name}_td fields_span_title" style="width: ${size_td}%;"><a href="${add_get_parameters(simplelist.url, order_field=field, begin_page=simplelist.begin_page, order=simplelist.change_order[field], search_text=simplelist.search_text, search_field=simplelist.search_field)}" class="">${set_css_arrow(simplelist, field)}${simplelist.model.fields[field].label}</a></div>
% endfor
% for extra_field in simplelist.arr_extra_fields:
<div class="fields_span_title options_td" style="width: ${size_td}%;">${ extra_field }</div>
% endfor
</div>
<div class="table_rows ${simplelist.model.name}_table_rows" id="${simplelist.model.name}_table_rows">
<%
pos=0
%>
% for row in list:
<div id="${simplelist.model.name}_table_${row['id']}" class="${simplelist.model.name}_table_row" style="clear: both;overflow: hidden;">
<%
if not 'pos' in row:
row['pos']=pos
%>
% for field in simplelist.fields_showed:
% if simplelist.model.fields[field].escape==True:
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
${simplelist.model.fields[field].show_formatted(row[field])}
% else:
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))}
% endif
</div>
% else:
<div class="${simplelist.model.fields[field].name}_td fields_span_table_data" style="width: ${size_td}%;">
%if type(simplelist.model.fields[field]).__name__!='ForeignKeyField':
${str(simplelist.model.fields[field].show_formatted(row[field]))|n}
% else:
${str(simplelist.model.fields[field].related_model.fields[simplelist.model.fields[field].named_field].show_formatted(row[field]))|n}
% endif
</div>
% endif
% endfor
% for extra_field_func in simplelist.arr_extra_options:
<div class="options_td fields_span_table_data" style="width: ${size_td}%;">${ simplelist.set_options(extra_field_func, row)|n }</div>
% endfor
<%
pos+=1
%>
</div>
% endfor
</div>
<br clear="all" />
</div>
% endif
<p>
% if pages!='':
${_('Pages')}: ${pages|n}
% endif
</p>

View file

@ -5,7 +5,8 @@ from settings import config
#from parameciofast.fast import app #from parameciofast.fast import app
from parameciofast.libraries.session import ParamecioSession from parameciofast.libraries.session import ParamecioSession
from starlette.middleware.sessions import SessionMiddleware from starlette.middleware.sessions import SessionMiddleware
from parameciofast.fast import app from parameciofast.libraries.db.webmodel import WebModel
#from parameciofast.fast import app
cookie_name='paramecio_session' cookie_name='paramecio_session'
@ -17,19 +18,38 @@ url_app=config.apps['admin'][2]
admin_app=FastAPI(docs_url="/docs", openapi_url="/docs/openapi.json", title='Paramecio Admin', version='0.9') admin_app=FastAPI(docs_url="/docs", openapi_url="/docs/openapi.json", title='Paramecio Admin', version='0.9')
@admin_app.middleware('http')
async def check_session(request: Request, call_next):
db=WebModel.connection()
try:
request.state.db=db
response = await call_next(request)
except:
db.close()
raise
return response
# FastAPI set the middlewares in reversed order. # FastAPI set the middlewares in reversed order.
@admin_app.middleware("http") @admin_app.middleware("http")
async def check_session(request: Request, call_next): async def check_session(request: Request, call_next):
#print(request.scope['route'].name) path=request.scope['path']
response = await call_next(request) if not request.session.get('login_admin', None) and path!=url_app+'login' and path!=url_app+'signup' and path!=url_app+'logout':
if not request.session.get('login_admin', None) and request.scope['endpoint'].__name__!='login_admin' and request.scope['endpoint'].__name__!='signup_admin' and request.scope['endpoint'].__name__!='check_login_admin' and request.scope['endpoint'].__name__!='signup_insert_admin' and request.scope['endpoint'].__name__!='logout_admin':
return RedirectResponse(request.url_for('login_admin')) return RedirectResponse(request.url_for('login_admin'))
response = await call_next(request)
return response return response

View file

@ -1,4 +1,6 @@
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from fastapi import Request
from parameciofast.modules.fastadmin.models.admin import UserAdmin
from parameciofast.modules.fastadmin import admin_app from parameciofast.modules.fastadmin import admin_app
from parameciofast.modules.fastadmin.libraries.config import modules_admin, modules_admin_icons from parameciofast.modules.fastadmin.libraries.config import modules_admin, modules_admin_icons
from parameciofast.libraries.mtemplates import PTemplate, env_theme from parameciofast.libraries.mtemplates import PTemplate, env_theme
@ -6,6 +8,9 @@ from parameciofast.libraries.i18n import I18n
import parameciofast.modules.fastadmin.libraries.i18n import parameciofast.modules.fastadmin.libraries.i18n
from parameciofast.fast import app from parameciofast.fast import app
import os import os
from pydantic import BaseModel
from parameciofast.libraries.lists import SimpleList
env=env_theme(__file__) env=env_theme(__file__)
@ -23,9 +28,19 @@ modules_admin.append(['fastadmin_users', 'people-circle'])
modules_admin_icons.append('<symbol id="people-circle" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></symbol>') modules_admin_icons.append('<symbol id="people-circle" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></symbol>')
@admin_app.get('/ausers', response_class=HTMLResponse) @admin_app.get('/ausers', response_class=HTMLResponse)
def fastadmin_users(): def fastadmin_users(request: Request):
i18n=I18n('fastadmin') i18n=I18n('fastadmin')
return t.load_template('users.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='fastadmin_users') db=request.state.db
users=UserAdmin(db)
url=app.url_path_for('fastadmin_users')
slist=SimpleList(users, url, t, request)
slist.fields_showed=['username', 'email', 'double_auth', 'last_login']
return t.load_template('users.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='fastadmin_users', slist=slist)

View file

@ -48,7 +48,7 @@ class UserAdmin(WebModel):
self.register(corefields.CharField('token_login')) self.register(corefields.CharField('token_login'))
self.register(PasswordField('token_auth')) #self.register(PasswordField('token_auth'))
self.register(PrivilegesField('privileges')) self.register(PrivilegesField('privileges'))

View file

@ -1,3 +1,4 @@
<%inherit file="layout.phtml"/> <%inherit file="layout.phtml"/>
<%block name="content"> <%block name="content">
${slist.show()|n}
</%block> </%block>