mirror of https://github.com/kf7eel/hbnet.git
implement pages, clean web service, add option to disable fallback
This commit is contained in:
parent
1e311d86c6
commit
391e76d72c
|
|
@ -1,4 +1,4 @@
|
|||
## HBNet is still under heavy development. Documentation is being added to the Wiki as I write it, so check perodically to see if there is any new information. V1.0 will be ready in the next few months. See [HBNet.xyz](https://hbnet.xyz) or [here](https://github.com/kf7eel/hbnet/discussions/33) for the development news.
|
||||
## HBNet is still under heavy development and currently undergoing a partiaql rewrite. Documentation is being added to the Wiki as I write it, so check perodically to see if there is any new information. V1.0 will be ready in the next few months. See [here](https://github.com/kf7eel/hbnet/discussions/33) for the development news.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -1691,6 +1691,9 @@ if __name__ == '__main__':
|
|||
except Exception as e:
|
||||
logger.error('Control server unreachable or other error. Using local config.')
|
||||
logger.error(e)
|
||||
if LOCAL_CONFIG['WEB_SERVICE']['DISABLE_FALLBACK']:
|
||||
logger.info('Falback disabled. Exiting...')
|
||||
sys.exit()
|
||||
spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE)
|
||||
rules_module = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
|
|
@ -1763,5 +1766,6 @@ if __name__ == '__main__':
|
|||
pass
|
||||
else:
|
||||
Path('/tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/')).mkdir()
|
||||
|
||||
|
||||
|
||||
reactor.run()
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ def build_config(_config_file):
|
|||
'THIS_SERVER_NAME': config.get(section, 'THIS_SERVER_NAME'),
|
||||
'URL': config.get(section, 'URL'),
|
||||
'REMOTE_CONFIG_ENABLED': config.getboolean(section, 'REMOTE_CONFIG_ENABLED'),
|
||||
'DISABLE_FALLBACK': config.getboolean(section, 'DISABLE_FALLBACK'),
|
||||
'APPEND_INT': config.getint(section, 'APPEND_INT'),
|
||||
'EXTRA_INT_1': config.getint(section, 'EXTRA_INT_1'),
|
||||
'EXTRA_INT_2': config.getint(section, 'EXTRA_INT_2'),
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ STALE_DAYS: 7
|
|||
# This is where to configure the details for use with a user managment script
|
||||
[WEB_SERVICE]
|
||||
THIS_SERVER_NAME: MMDVM_Server
|
||||
# When web service unreachable, die.
|
||||
DISABLE_FALLBACK: True
|
||||
REMOTE_CONFIG_ENABLED: True
|
||||
# URL of the user managment server
|
||||
URL: http://localhost:8080/svr
|
||||
|
|
@ -197,7 +199,7 @@ REG_ACL: DENY:1
|
|||
SUB_ACL: DENY:1
|
||||
TGID_TS1_ACL: PERMIT:ALL
|
||||
TGID_TS2_ACL: PERMIT:ALL
|
||||
|
||||
OTHER_OPTIONS:
|
||||
# PEER INSTANCES - DUPLICATE SECTION FOR MULTIPLE PEERS
|
||||
# There are a LOT of errors in the HB Protocol specifications on this one!
|
||||
# MOST of these items are just strings and will be properly dealt with by the program
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ cryptography
|
|||
setproctitle
|
||||
scapy
|
||||
paho-mqtt
|
||||
service_identity
|
||||
|
||||
|
|
|
|||
284
web/app.py
284
web/app.py
|
|
@ -53,8 +53,10 @@ import os, ast
|
|||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from flaskext.markdown import Markdown
|
||||
|
||||
peer_locations = {}
|
||||
hbnet_version = 'HWS 0.0.1-pre_pre_alpha/MQTT'
|
||||
hbnet_version = 'V 09102022'
|
||||
|
||||
# Query radioid.net for list of IDs
|
||||
def get_ids(callsign):
|
||||
|
|
@ -138,6 +140,7 @@ def hbnet_web_service():
|
|||
# Create Flask app load app.config
|
||||
mail = Mail()
|
||||
app = Flask(__name__)
|
||||
Markdown(app)
|
||||
app.config.from_object(__name__+'.ConfigClass')
|
||||
|
||||
# Initialize Flask-BabelEx
|
||||
|
|
@ -544,7 +547,14 @@ def hbnet_web_service():
|
|||
boo_2 = db.Column(db.Boolean(), nullable=True, server_default='1')
|
||||
time = db.Column(db.DateTime())
|
||||
|
||||
|
||||
class Pages(db.Model):
|
||||
__tablename__ = 'pages'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(1000))
|
||||
enabled = db.Column(db.Boolean(), nullable=False, server_default='1')
|
||||
notes = db.Column(db.String(1000))
|
||||
data = db.Column(db.String(10000))
|
||||
time = db.Column(db.DateTime())
|
||||
|
||||
|
||||
|
||||
|
|
@ -642,24 +652,26 @@ def hbnet_web_service():
|
|||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(flash_entry_add)
|
||||
tos_entry_add = Misc(
|
||||
field_1 = 'terms_of_service',
|
||||
field_2 = '''<div class="panel panel-default">
|
||||
<div class="panel-heading" style="text-align: center;"><h4>Terms of Use</h4></div>
|
||||
<div class="panel-body">
|
||||
<p>By using <strong>''' + title + '''</strong>, you agree not to do anything malicious. You agree to use the system with respect and courtesy to others. Please operate within the laws of your country.</p>
|
||||
|
||||
</div>
|
||||
</div>''',
|
||||
|
||||
add_pg = Pages(
|
||||
name='Home Page',
|
||||
data="Welcome to your HBNet installation.",
|
||||
notes = "Created on first start",
|
||||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(tos_entry_add)
|
||||
home_entry_add = Misc(
|
||||
field_1 = 'home_page',
|
||||
field_2 = '<p>Welcome to <strong>' + title + '</strong>.</p>',
|
||||
)
|
||||
db.session.add(add_pg)
|
||||
|
||||
add_tos = Pages(
|
||||
name='Terms of Service',
|
||||
data='''### Terms of Use
|
||||
|
||||
By using this service, you agree not to do anything malicious. You agree to use the system with respect and courtesy to others. Please operate within the laws of your country.
|
||||
''',
|
||||
notes = "Created on first start",
|
||||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(home_entry_add)
|
||||
)
|
||||
db.session.add(add_tos)
|
||||
|
||||
ping_list_initial = Misc(
|
||||
field_1 = 'ping_list',
|
||||
field_2 = '{}',
|
||||
|
|
@ -681,6 +693,15 @@ def hbnet_web_service():
|
|||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(script_links_initial)
|
||||
|
||||
add_news = News(
|
||||
subject = 'Welcome',
|
||||
date = 'Today',
|
||||
text = 'Welcome',
|
||||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(add_news)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Query radioid.net for list of DMR IDs, then add to DB
|
||||
|
|
@ -787,37 +808,85 @@ def hbnet_web_service():
|
|||
@app.route('/')
|
||||
def home_page():
|
||||
if mode == 'FULL' or mode == 'DMR_ONLY':
|
||||
home_text = Misc.query.filter_by(field_1='home_page').first()
|
||||
home_text = Pages.query.filter_by(id=1).first()
|
||||
#content = Markup('<strong>Index</strong>')
|
||||
try:
|
||||
l_news = News.query.order_by(News.time.desc()).first()
|
||||
content = '''
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title"><a href="news/''' + str(l_news.id) + '''">''' + l_news.subject + '''</h4></a>
|
||||
<hr />
|
||||
|
||||
<p style="text-align: center;">''' + l_news.date + '''</p>
|
||||
<hr />
|
||||
|
||||
<p class="card-text">''' + l_news.text + '''</p>
|
||||
<p style="text-align: center;"></p>
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
except:
|
||||
content = ''
|
||||
return render_template('index.html', news = Markup(content), content_block = Markup(home_text.field_2))
|
||||
content = ''
|
||||
# try:
|
||||
l_news = News.query.order_by(News.time.desc()).first()
|
||||
return render_template('index.html', news = Markup(content), content_block = Markup(home_text.data), text = l_news.text, subject = l_news.subject, date = l_news.date, news_id = l_news.id)
|
||||
# except:
|
||||
# content = ''
|
||||
# return render_template('index.html', content_block = Markup(home_text.data))
|
||||
else:
|
||||
return redirect('/data_overview')
|
||||
|
||||
@app.route('/tos')
|
||||
def tos_page():
|
||||
tos_text = Misc.query.filter_by(field_1='terms_of_service').first()
|
||||
content = tos_text.field_2
|
||||
tos_text = Pages.query.filter_by(id=2).first()
|
||||
|
||||
return render_template('generic.html', markup_content = Markup(content))
|
||||
return render_template('generic.html', markup_content = tos_text.data)
|
||||
|
||||
@app.route('/page/<id>')
|
||||
def other_page(id):
|
||||
page = Pages.query.filter_by(id=int(id)).first()
|
||||
|
||||
# return render_template('index.html')
|
||||
return render_template('page.html', content=Markup(page.data), page_title = page.name, page_time = local_time(page.time))
|
||||
|
||||
|
||||
@app.route('/pages')
|
||||
def all_pages():
|
||||
content = ''
|
||||
all_pages = Pages.query.order_by(Pages.name).all()
|
||||
for i in all_pages:
|
||||
if i.id == 1 or i.id == 2:
|
||||
pass
|
||||
else:
|
||||
content = content + '<tr><td><a href="/page/' + str(i.id) + '">' + i.name + '</a></td><td>' + i.notes + '</td></tr>'
|
||||
return render_template('view_pages.html', content = Markup(content))
|
||||
|
||||
|
||||
@app.route('/manage_page', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@roles_required('Admin')
|
||||
def manage_page():
|
||||
if request.args.get('new'):
|
||||
return render_template('add_page.html')
|
||||
elif request.args.get('save'):
|
||||
add_page(request.form.get('name'), request.form.get('data'), request.form.get('notes'))
|
||||
content = '''<h3 style="text-align: center;">Page Saved.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=/manage_page" /> '''
|
||||
return render_template('flask_user_layout.html', markup_content=Markup(content))
|
||||
|
||||
elif request.args.get('delete'):
|
||||
delete_page(int(request.args.get('delete')))
|
||||
content = '''<h3 style="text-align: center;">Page Deleted.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=/manage_page" /> '''
|
||||
return render_template('flask_user_layout.html', markup_content=Markup(content))
|
||||
|
||||
elif request.args.get('edit'):
|
||||
page = Pages.query.filter_by(id=int(request.args.get('edit'))).first()
|
||||
return render_template('edit_page.html', name = page.name, notes = page.notes, data = page.data, id = page.id)
|
||||
|
||||
elif request.args.get('edit_save'):
|
||||
edit_page(int(request.args.get('edit_save')), request.form.get('name'), request.form.get('data'), request.form.get('notes'))
|
||||
content = '''<h3 style="text-align: center;">Page Saved.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=/manage_page" /> '''
|
||||
return render_template('flask_user_layout.html', markup_content=Markup(content))
|
||||
|
||||
else:
|
||||
content = ''
|
||||
all_pages = Pages.query.order_by(Pages.name).all()
|
||||
for i in all_pages:
|
||||
delete_button = ' - <a href="/manage_page?delete=' + str(i.id) + '"><button type="button" class="btn btn-danger">Delete</button></a>'
|
||||
if i.id == 1 or i.id == 2:
|
||||
delete_button = ''
|
||||
content = content + '<tr><td><a href="/page/' + str(i.id) + '">' + i.name + '</a> - <a href="/manage_page?edit=' + str(i.id) + '"><button type="button" class="btn btn-primary">Edit</button></a>' + delete_button + '</td><td>' + i.notes + '</td></tr>'
|
||||
return render_template('view_pages.html', content = Markup(content), admin_page = True)
|
||||
|
||||
|
||||
|
||||
@app.route('/map_gps/<call_ssid>')
|
||||
|
|
@ -2162,54 +2231,24 @@ def hbnet_web_service():
|
|||
## view_news = News.query.order_by(News.time.desc()).paginate(page=page, per_page=1)
|
||||
|
||||
#content = '''<table style="width: 600px; margin-left: auto; margin-right: auto;" border="1"><tbody>'''
|
||||
|
||||
content = ''
|
||||
|
||||
news_content = ''
|
||||
art_count = 0
|
||||
for article in view_news:
|
||||
if request.args.get('all_news'):
|
||||
art_count = 1
|
||||
if art_count < 16:
|
||||
news_content = news_content + '''
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title"><a href="news/''' + str(article.id) + '''">''' + article.subject + '''</h4></a>
|
||||
<hr />
|
||||
|
||||
<p style="text-align: center;">''' + article.date + '''</p>
|
||||
<hr />
|
||||
|
||||
<p class="card-text">''' + article.text + '''</p>
|
||||
<p style="text-align: center;"></p>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
|
||||
|
||||
'''
|
||||
art_count = art_count + 1
|
||||
#content = content + '''</tbody></table><p> </p>'''
|
||||
return render_template('news.html', markup_content = Markup(news_content))
|
||||
print(view_news)
|
||||
for i in view_news:
|
||||
content = content + '<tr><td><a href="/news/' + str(i.id) + '">' + i.subject + '</a></td><td>' + i.date + '</td></tr>'
|
||||
|
||||
return render_template('news_list.html', content = Markup(content))
|
||||
|
||||
@app.route('/news/<article>') #, methods=['POST', 'GET'])
|
||||
def view_arts(article):
|
||||
|
||||
view_arti = News.query.filter_by(id=article).first()
|
||||
|
||||
content = '''
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">''' + view_arti.subject + '''</h4>
|
||||
<hr />
|
||||
|
||||
<p style="text-align: center;">''' + view_arti.date + '''</p>
|
||||
<hr />
|
||||
|
||||
<p class="card-text">''' + view_arti.text + '''</p>
|
||||
<p style="text-align: center;"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
'''
|
||||
return render_template('news.html', markup_content = Markup(content))
|
||||
content = ''
|
||||
return render_template('news.html', markup_content = Markup(content), subject = view_arti.subject, date = view_arti.date, text = view_arti.text)
|
||||
|
||||
|
||||
|
||||
|
|
@ -2284,10 +2323,14 @@ def hbnet_web_service():
|
|||
<tbody>
|
||||
'''
|
||||
for a in view_news:
|
||||
if a.id == 1:
|
||||
delete_button = ''
|
||||
else:
|
||||
delete_button = '''<a href="manage_news?delete=''' + str(a.id )+ '''"><button type="button" class="btn btn-danger">Delete</button></a>'''
|
||||
content = content + '''
|
||||
|
||||
<tr>
|
||||
<td><a href="news/''' + str(a.id) + '''">''' + a.subject + '''</a> | <a href="manage_news?delete=''' + str(a.id )+ '''"><button type="button" class="btn btn-danger">Delete</button></a></td>
|
||||
<td><a href="news/''' + str(a.id) + '''">''' + a.subject + '''</a> | ''' + delete_button + '''</td>
|
||||
<td>''' + a.date + '''</td>
|
||||
<td>''' + str(a.id) + '''</td>
|
||||
|
||||
|
|
@ -2313,16 +2356,6 @@ def hbnet_web_service():
|
|||
content = '''<h3 style="text-align: center;">Saved flash text.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=misc_settings" /> '''
|
||||
elif request.args.get('home') == 'save':
|
||||
misc_edit_field_1('home_page', request.form.get('home_text'), None, None, None, None, None, None, None, None)
|
||||
content = '''<h3 style="text-align: center;">Saved home page.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=misc_settings" /> '''
|
||||
elif request.args.get('tos') == 'save':
|
||||
misc_edit_field_1('terms_of_service', request.form.get('tos_text'), None, None, None, None, None, None, None, None)
|
||||
content = '''<h3 style="text-align: center;">Saved terms of service.</h3>
|
||||
<p style="text-align: center;">Redirecting in 3 seconds.</p>
|
||||
<meta http-equiv="refresh" content="3; URL=misc_settings" /> '''
|
||||
elif request.args.get('aprs') == 'save':
|
||||
misc_edit_field_1('unregistered_aprs', request.form.get('aprs_text'), None, None, None, None, None, None, None, None)
|
||||
content = '''<h3 style="text-align: center;">Saved terms of service.</h3>
|
||||
|
|
@ -2372,39 +2405,6 @@ def hbnet_web_service():
|
|||
|
||||
<p> </p>
|
||||
|
||||
<form action="misc_settings?home=save" method="POST">
|
||||
<table style="width: 500px; margin-left: auto; margin-right: auto;" border="1">
|
||||
<tbody>
|
||||
<tr style="height: 51.1667px;">
|
||||
<td style="height: 51.1667px; text-align: center;"><label for="home_text">Homepage (HTML OK, 5000 characters max):</label><br /> <textarea id="home_text" cols="65" name="home_text" rows="4">''' + home_text.field_2 + '''</textarea></td>
|
||||
</tr>
|
||||
<tr style="height: 27px;">
|
||||
<td style="text-align: center; height: 27px;">
|
||||
<p> </p>
|
||||
<p><input type="submit" value="Submit" /></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
<p> </p>
|
||||
|
||||
<form action="misc_settings?tos=save" method="POST">
|
||||
<table style="width: 500px; margin-left: auto; margin-right: auto;" border="1">
|
||||
<tbody>
|
||||
<tr style="height: 51.1667px;">
|
||||
<td style="height: 51.1667px; text-align: center;"><label for="tos_text">Terms of Service (HTML OK, 5000 characters max):</label><br /> <textarea id="tos_text" cols="65" name="tos_text" rows="4">''' + tos_text.field_2 + '''</textarea></td>
|
||||
</tr>
|
||||
<tr style="height: 27px;">
|
||||
<td style="text-align: center; height: 27px;">
|
||||
<p> </p>
|
||||
<p><input type="submit" value="Submit" /></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
<p> </p>
|
||||
|
||||
<form action="misc_settings?aprs=save" method="POST">
|
||||
<table style="width: 500px; margin-left: auto; margin-right: auto;" border="1">
|
||||
|
|
@ -3404,6 +3404,38 @@ Name: <strong>''' + p.name + '''</strong> - Port: <strong>''' + str(
|
|||
|
||||
###### DB functions #############################
|
||||
|
||||
def local_time(time_utc):
|
||||
l_time = (time_utc + datetime.timedelta(hours=hbnet_tz)).strftime(time_format)
|
||||
return l_time
|
||||
|
||||
|
||||
def local_time_to_utc(time):
|
||||
u_time = (time - datetime.timedelta(hours=hbnet_tz))
|
||||
return u_time
|
||||
|
||||
def add_page(name, data, notes):
|
||||
add_pg = Pages(
|
||||
name=name,
|
||||
data=data,
|
||||
notes = notes,
|
||||
time = datetime.datetime.utcnow()
|
||||
)
|
||||
db.session.add(add_pg)
|
||||
db.session.commit()
|
||||
|
||||
def edit_page(id, name, data, notes):
|
||||
page = Pages.query.filter_by(id=id).first()
|
||||
page.name = name
|
||||
page.data = data
|
||||
page.time = datetime.datetime.utcnow()
|
||||
page.notes = notes
|
||||
db.session.commit()
|
||||
|
||||
def delete_page(id):
|
||||
page = Pages.query.filter_by(id=id).first()
|
||||
db.session.delete(page)
|
||||
db.session.commit()
|
||||
|
||||
def sms_que(_server):
|
||||
que_db = SMS_Que.query.filter_by(server=_server).all()
|
||||
que_list = []
|
||||
|
|
|
|||
|
|
@ -46,15 +46,15 @@ default_account_state = True
|
|||
|
||||
# Allow users to generate and send SMS messages via the web service
|
||||
# and API.
|
||||
allow_user_sms = True
|
||||
allow_user_sms = False
|
||||
|
||||
# Legacy passphrase used in hblink.cfg
|
||||
legacy_passphrase = 'passw0rd'
|
||||
|
||||
# Coordinates to center map over
|
||||
center_map = [45.372, -121.6972]
|
||||
center_map = [00.000, 000.0000]
|
||||
# Default map zoom level
|
||||
map_zoom = 5
|
||||
map_zoom = 10
|
||||
|
||||
# Passphrase calculation config. If REMOTE_CONFIG is not used in your DMR server config
|
||||
# (hblink.cfg), then the values in section [USER_MANAGER] MUST match the values below.
|
||||
|
|
|
|||
|
|
@ -11,3 +11,4 @@ libscrc
|
|||
dmr_utils3
|
||||
cryptography
|
||||
uwsgi
|
||||
Flask-Markdown
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{% extends 'flask_user/_public_base.html' %}
|
||||
{% block content %}
|
||||
|
||||
<h2 style="text-align: center;">Add Page</h2>
|
||||
|
||||
<form action="/manage_page?save=true" method="post">
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text" id="basic-addon1">Title</span>
|
||||
<input type="text" name="name" class="form-control" aria-describedby="basic-addon1">
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<textarea id="ed1" name="data" class="form-control" aria-label="Data"></textarea>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Notes</span>
|
||||
<textarea id="ed1" name="notes" class="form-control" aria-label="Notes"></textarea>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<p style="text-align: center;"><input class="btn btn-primary" type="submit" value="Save" /></form></p>
|
||||
<br />
|
||||
|
||||
<script>
|
||||
const easyMDE = new EasyMDE({element: document.getElementById('ed1')});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -7,12 +7,15 @@
|
|||
|
||||
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="container-fluid col-centered">
|
||||
|
||||
{{markup_content}}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
{% extends 'flask_user/_public_base.html' %}
|
||||
{% block content %}
|
||||
|
||||
<h2 style="text-align: center;">Add Page</h2>
|
||||
|
||||
<form action="/manage_page?edit_save={{id}}" method="post">
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text" id="basic-addon1">Title</span>
|
||||
<input type="text" name="name" class="form-control" aria-describedby="basic-addon1" value="{{name}}">
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<textarea id="ed1" name="data" class="form-control" aria-label="Data">{{data}}</textarea>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Notes</span>
|
||||
<textarea id="ed1" name="notes" class="form-control" aria-label="Notes">{{notes}}</textarea>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<p style="text-align: center;"><input class="btn btn-primary" type="submit" value="Save" /></form></p>
|
||||
<br />
|
||||
|
||||
<script>
|
||||
const easyMDE = new EasyMDE({element: document.getElementById('ed1')});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -6,10 +6,17 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ user_manager.USER_APP_NAME }}</title>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
|
||||
<!-- Bootstrap -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.15.5/dist/bootstrap-table.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
|
||||
<!-- Markdown editor -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">
|
||||
<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
|
||||
|
||||
<!--Bootstrap select-->
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.14.0-beta3/dist/css/bootstrap-select.min.css">
|
||||
|
||||
|
||||
<!-- In-lining styles to avoid needing a separate .css file -->
|
||||
|
|
@ -48,6 +55,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{url}}/"><i class="bi bi-house-fill"></i> Home </a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{url}}/pages"><i class="bi bi-file-earmark-break-fill"></i> Pages </a>
|
||||
</li>
|
||||
{% if global_config['mode'] == 'FULL' or global_config['mode'] == 'DMR_ONLY' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{url}}/talkgroups"><i class="bi bi-card-list"></i> Talkgroups </a>
|
||||
|
|
@ -133,6 +143,7 @@
|
|||
<li><a class="dropdown-item" href="{{url}}/approve_users">Waiting Approval</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="{{url}}/manage_news">Manage News</a></li>
|
||||
<li><a class="dropdown-item" href="/manage_page"> Manage Pages </a></li>
|
||||
<li><a class="dropdown-item" href="{{url}}/misc_settings">Misc Options</a></li>
|
||||
{% if global_config['mode'] == 'FULL' or global_config['mode'] == 'DMR_ONLY' %}
|
||||
<li><a class="dropdown-item" href="{{url}}/auth_log">Authorization Log</a></li>
|
||||
|
|
@ -238,8 +249,10 @@
|
|||
<!-- Bootstrap -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/bootstrap-table@1.18.3/dist/bootstrap-table.min.js"></script>
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.14.0-beta3/dist/js/bootstrap-select.min.js"></script>
|
||||
|
||||
|
||||
{# *** Allow sub-templates to insert extra html to the bottom of the body *** #}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<div class="row">
|
||||
|
||||
|
||||
{{markup_content}}
|
||||
{{markup_content|markdown}}
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<div class="row">
|
||||
|
||||
|
||||
{{content_block}}
|
||||
{{content_block|markdown}}
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -18,6 +18,20 @@
|
|||
<td style="text-align: center;">
|
||||
<h4>Latest News:</h4>
|
||||
{{news}}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title"><a href="news/{{news_id}}">{{subject}}</h4></a>
|
||||
<hr />
|
||||
|
||||
<p style="text-align: center;">{{date}}</p>
|
||||
<hr />
|
||||
|
||||
<p class="card-text">{{text|markdown}}</p>
|
||||
<p style="text-align: center;"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,21 @@
|
|||
{% block content %}
|
||||
<p style="text-align: center;"><a href="/news?all_news=true"><strong><button type="button" class="btn btn-primary">View All News</button></strong></a></p>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">{{markup_content}}</div>
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{subject}}</h4>
|
||||
<hr />
|
||||
|
||||
<p style="text-align: center;">{{date}}</p>
|
||||
<hr />
|
||||
|
||||
<p class="card-text">{{text|markdown}}</p>
|
||||
<p style="text-align: center;"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
{% extends 'flask_user/_public_base.html' %}
|
||||
{% block content %}
|
||||
|
||||
<table data-toggle="table" data-pagination="true" data-search="true" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Subject</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{content}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{% extends 'flask_user/_public_base.html' %}
|
||||
{% block content %}
|
||||
|
||||
<h2 style="text-align: center;">{{page_title}}</h2>
|
||||
<p style="text-align: center;">Last updated: {{page_time}}</p>
|
||||
|
||||
<br />
|
||||
|
||||
{{content|markdown}}
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{% extends 'flask_user/_public_base.html' %}
|
||||
{% block content %}
|
||||
|
||||
<h1 style="text-align: center;">Pages</h1>
|
||||
|
||||
{% if admin_page %}
|
||||
|
||||
{% if call_or_get(current_user.has_roles(['Admin'])) %}
|
||||
<table style="margin-left: auto; margin-right: auto;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="/manage_page?new=yes"><button type="button" class="btn btn-success">Add Page</button></a></td>
|
||||
<td>.</td>
|
||||
<td>.</td>
|
||||
<td>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<table data-toggle="table" data-pagination="true" data-search="true" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{content}}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue