From 391e76d72c01eeb2a921eca07689cac8a6905d16 Mon Sep 17 00:00:00 2001 From: KF7EEL Date: Sat, 24 Sep 2022 12:24:59 -0700 Subject: [PATCH] implement pages, clean web service, add option to disable fallback --- README.md | 2 +- bridge.py | 6 +- config.py | 1 + hblink-SAMPLE.cfg | 4 +- requirements.txt | 1 + web/app.py | 284 +++++++++++++++------------ web/config-SAMPLE.py | 6 +- web/requirements.txt | 1 + web/templates/add_page.html | 34 ++++ web/templates/aprs_settings.html | 9 +- web/templates/edit_page.html | 33 ++++ web/templates/flask_user_layout.html | 23 ++- web/templates/generic.html | 2 +- web/templates/index.html | 16 +- web/templates/news.html | 16 +- web/templates/news_list.html | 16 ++ web/templates/page.html | 14 ++ web/templates/view_pages.html | 34 ++++ 18 files changed, 359 insertions(+), 143 deletions(-) create mode 100644 web/templates/add_page.html create mode 100644 web/templates/edit_page.html create mode 100644 web/templates/news_list.html create mode 100644 web/templates/page.html create mode 100644 web/templates/view_pages.html diff --git a/README.md b/README.md index c2c1400..2430617 100755 --- a/README.md +++ b/README.md @@ -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. ![ ](https://raw.githubusercontent.com/kf7eel/hblink3/hbnet/HBNet.png "Logo") diff --git a/bridge.py b/bridge.py index 309492b..9a56899 100755 --- a/bridge.py +++ b/bridge.py @@ -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() diff --git a/config.py b/config.py index d046e5f..a546da4 100755 --- a/config.py +++ b/config.py @@ -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'), diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index 5bd30f1..1bcc307 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -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 diff --git a/requirements.txt b/requirements.txt index f2baea6..7ab84cd 100755 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,5 @@ cryptography setproctitle scapy paho-mqtt +service_identity diff --git a/web/app.py b/web/app.py index 732cfb1..6109fd0 100644 --- a/web/app.py +++ b/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 = '''
-

Terms of Use

-
-

By using ''' + title + ''', 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.

- -
-
''', + + 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 = '

Welcome to ' + title + '.

', + ) + 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('Index') - try: - l_news = News.query.order_by(News.time.desc()).first() - content = ''' - -
-
-

''' + l_news.subject + '''

-
-   -

''' + l_news.date + '''

-
-   -

''' + l_news.text + '''

-

-
-
- ''' - 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/') + 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 + '' + i.name + '' + i.notes + '' + 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 = '''

Page Saved.

+

Redirecting in 3 seconds.

+ ''' + return render_template('flask_user_layout.html', markup_content=Markup(content)) + + elif request.args.get('delete'): + delete_page(int(request.args.get('delete'))) + content = '''

Page Deleted.

+

Redirecting in 3 seconds.

+ ''' + 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 = '''

Page Saved.

+

Redirecting in 3 seconds.

+ ''' + 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 = ' - ' + if i.id == 1 or i.id == 2: + delete_button = '' + content = content + '' + i.name + ' - ' + delete_button + '' + i.notes + '' + return render_template('view_pages.html', content = Markup(content), admin_page = True) + @app.route('/map_gps/') @@ -2162,54 +2231,24 @@ def hbnet_web_service(): ## view_news = News.query.order_by(News.time.desc()).paginate(page=page, per_page=1) #content = '''''' + + 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 + ''' -
-
-

''' + article.subject + '''

-
-   -

''' + article.date + '''

-
-   -

''' + article.text + '''

-

-
-
-

 

- - -''' - art_count = art_count + 1 - #content = content + '''

 

''' - return render_template('news.html', markup_content = Markup(news_content)) + print(view_news) + for i in view_news: + content = content + '' + i.subject + '' + i.date + '' + + return render_template('news_list.html', content = Markup(content)) @app.route('/news/
') #, methods=['POST', 'GET']) def view_arts(article): view_arti = News.query.filter_by(id=article).first() - content = ''' -
-
-

''' + view_arti.subject + '''

-
-   -

''' + view_arti.date + '''

-
-   -

''' + view_arti.text + '''

-

-
-
- -''' - 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(): ''' for a in view_news: + if a.id == 1: + delete_button = '' + else: + delete_button = '''''' content = content + ''' -''' + a.subject + ''' | +''' + a.subject + ''' | ''' + delete_button + ''' ''' + a.date + ''' ''' + str(a.id) + ''' @@ -2313,16 +2356,6 @@ def hbnet_web_service(): content = '''

Saved flash text.

Redirecting in 3 seconds.

''' - 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 = '''

Saved home page.

-

Redirecting in 3 seconds.

- ''' - 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 = '''

Saved terms of service.

-

Redirecting in 3 seconds.

- ''' 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 = '''

Saved terms of service.

@@ -2372,39 +2405,6 @@ def hbnet_web_service():

 

-
- - - - - - - - - -

-

 

-

-
-
-

 

- -
- - - - - - - - - -

-

 

-

-
-
-

 

@@ -3404,6 +3404,38 @@ Name: ''' + p.name + '''  -  Port: ''' + 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 = [] diff --git a/web/config-SAMPLE.py b/web/config-SAMPLE.py index 99e7e1c..5eac5cb 100644 --- a/web/config-SAMPLE.py +++ b/web/config-SAMPLE.py @@ -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. diff --git a/web/requirements.txt b/web/requirements.txt index 91b2100..4fa2858 100644 --- a/web/requirements.txt +++ b/web/requirements.txt @@ -11,3 +11,4 @@ libscrc dmr_utils3 cryptography uwsgi +Flask-Markdown \ No newline at end of file diff --git a/web/templates/add_page.html b/web/templates/add_page.html new file mode 100644 index 0000000..d35dd8c --- /dev/null +++ b/web/templates/add_page.html @@ -0,0 +1,34 @@ +{% extends 'flask_user/_public_base.html' %} +{% block content %} + +

Add Page

+ + + +
+ Title + +
+ +
+ + + + +
+ +
+ Notes + +
+ +
+ +

+
+ + + +{% endblock %} diff --git a/web/templates/aprs_settings.html b/web/templates/aprs_settings.html index 96e17be..48872ab 100644 --- a/web/templates/aprs_settings.html +++ b/web/templates/aprs_settings.html @@ -7,12 +7,15 @@ - +
+
+
{{markup_content}} - - +
+
+
diff --git a/web/templates/edit_page.html b/web/templates/edit_page.html new file mode 100644 index 0000000..13da73c --- /dev/null +++ b/web/templates/edit_page.html @@ -0,0 +1,33 @@ +{% extends 'flask_user/_public_base.html' %} +{% block content %} + +

Add Page

+ +
+ +
+ Title + +
+ +
+ + + +
+ +
+ Notes + +
+ +
+ +

+
+ + + +{% endblock %} \ No newline at end of file diff --git a/web/templates/flask_user_layout.html b/web/templates/flask_user_layout.html index d86f6cb..104978f 100644 --- a/web/templates/flask_user_layout.html +++ b/web/templates/flask_user_layout.html @@ -6,10 +6,17 @@ {{ user_manager.USER_APP_NAME }} - - - - + + + + + + + + + + + @@ -48,6 +55,9 @@ + {% if global_config['mode'] == 'FULL' or global_config['mode'] == 'DMR_ONLY' %}
  • Waiting Approval
  • Manage News
  • +
  • Manage Pages
  • Misc Options
  • {% if global_config['mode'] == 'FULL' or global_config['mode'] == 'DMR_ONLY' %}
  • Authorization Log
  • @@ -238,8 +249,10 @@ - + + + {# *** Allow sub-templates to insert extra html to the bottom of the body *** #} diff --git a/web/templates/generic.html b/web/templates/generic.html index 4b6251b..6244bd2 100644 --- a/web/templates/generic.html +++ b/web/templates/generic.html @@ -5,7 +5,7 @@
    -{{markup_content}} +{{markup_content|markdown}}
    diff --git a/web/templates/index.html b/web/templates/index.html index 616515f..c7ac1ae 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -5,7 +5,7 @@
    -{{content_block}} +{{content_block|markdown}}
    @@ -18,6 +18,20 @@
    diff --git a/web/templates/news.html b/web/templates/news.html index 4265ca7..6b345a9 100644 --- a/web/templates/news.html +++ b/web/templates/news.html @@ -2,7 +2,21 @@ {% block content %}

    -
    {{markup_content}}
    +
    +
    +
    +

    {{subject}}

    +
    +   +

    {{date}}

    +
    +   +

    {{text|markdown}}

    +

    +
    +
    + +

     

    diff --git a/web/templates/news_list.html b/web/templates/news_list.html new file mode 100644 index 0000000..8e484b1 --- /dev/null +++ b/web/templates/news_list.html @@ -0,0 +1,16 @@ +{% extends 'flask_user/_public_base.html' %} +{% block content %} + +

    Latest News:

    {{news}} + +
    +
    +

    {{subject}}

    +
    +   +

    {{date}}

    +
    +   +

    {{text|markdown}}

    +

    +
    +
    +
    + + + + + + + + {{content}} + +
    SubjectDate
    + + {% endblock %} diff --git a/web/templates/page.html b/web/templates/page.html new file mode 100644 index 0000000..3d7c38f --- /dev/null +++ b/web/templates/page.html @@ -0,0 +1,14 @@ +{% extends 'flask_user/_public_base.html' %} +{% block content %} + +

    {{page_title}}

    +

    Last updated: {{page_time}}

    + +
    + +{{content|markdown}} + +
    + + +{% endblock %} \ No newline at end of file diff --git a/web/templates/view_pages.html b/web/templates/view_pages.html new file mode 100644 index 0000000..295e68e --- /dev/null +++ b/web/templates/view_pages.html @@ -0,0 +1,34 @@ +{% extends 'flask_user/_public_base.html' %} +{% block content %} + +

    Pages

    + +{% if admin_page %} + +{% if call_or_get(current_user.has_roles(['Admin'])) %} + + + + + + + + + +
    ...
    +{% endif %} + +{% endif %} + + + + + + + + + +{{content}} + +
    NameNotes
    +{% endblock %} \ No newline at end of file