# HBNet Web Server ############################################################################### # HBNet Web Server - Copyright (C) 2020 Eric Craw, KF7EEL # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################### ''' Flask based application that is the web server for HBNet. Controls user authentication, DMR server config, etc. ''' from flask import Flask, render_template_string, request, make_response, jsonify, render_template, Markup, flash, redirect, url_for, current_app, Response from flask_sqlalchemy import SQLAlchemy from flask_user import login_required, UserManager, UserMixin, user_registered, roles_required from werkzeug.security import check_password_hash from flask_login import current_user, login_user, logout_user from wtforms import StringField, SubmitField import requests import base64, hashlib from dmr_utils3.utils import int_id, bytes_4 from config import * import ast import json import datetime, time from flask_babelex import Babel import libscrc import random from flask_mail import Message, Mail from socket import gethostbyname import re import folium from gen_script_template import gen_script import os, ast ##import hb_config from cryptography.fernet import Fernet ##script_links = {} ##active_tgs = {} ##ping_list = {} peer_locations = {} # Query radioid.net for list of IDs def get_ids(callsign): try: url = "https://www.radioid.net" response = requests.get(url+"/api/dmr/user/?callsign=" + callsign) result = response.json() ## print(result) # id_list = [] id_list = {} f_name = result['results'][0]['fname'] l_name = result['results'][0]['surname'] try: city = str(result['results'][0]['city'] + ', ' + result['results'][0]['state'] + ', ' + result['results'][0]['country']) except: city = result['results'][0]['country'] for i in result['results']: id_list[i['id']] = 0 return str([id_list, f_name, l_name, city]) except: return str([{}, '', '', '']) # Return string in NATO phonetics def convert_nato(string): d_nato = { 'A': 'ALPHA', 'B': 'BRAVO', 'C': 'CHARLIE', 'D': 'DELTA', 'E': 'ECHO', 'F': 'FOXTROT', 'G': 'GOLF', 'H': 'HOTEL', 'I': 'INDIA', 'J': 'JULIETT','K': 'KILO', 'L': 'LIMA', 'M': 'MIKE', 'N': 'NOVEMBER','O': 'OSCAR', 'P': 'PAPA', 'Q': 'QUEBEC', 'R': 'ROMEO', 'S': 'SIERRA', 'T': 'TANGO', 'U': 'UNIFORM', 'V': 'VICTOR', 'W': 'WHISKEY', 'X': 'X-RAY', 'Y': 'YANKEE', 'Z': 'ZULU', '0': 'zero(0)', '1': 'one(1)', '2': 'two(2)', '3': 'three(3)', '4': 'four(4)', '5': 'five(5)', '6': 'six(6)', '7': 'seven(7)', '8': 'eight(8)', '9': 'nine(9)', 'a': 'alpha', 'b': 'bravo', 'c': 'charlie', 'd': 'delta', 'e': 'echo', 'f': 'foxtrot', 'g': 'golf', 'h': 'hotel', 'i': 'india', 'j': 'juliett','k': 'kilo', 'l': 'lima', 'm': 'mike', 'n': 'november','o': 'oscar', 'p': 'papa', 'q': 'quebec', 'r': 'romeo', 's': 'sierra', 't': 'tango', 'u': 'uniform', 'v': 'victor', 'w': 'whiskey', 'x': 'x-ray', 'y': 'yankee', 'z': 'Zulu'} ns = '' for c in string: try: ns = ns + d_nato[c] + ' ' except: ns = ns + c + ' ' return ns # Convert APRS to map coordinates def aprs_to_latlon(x): degrees = int(x) // 100 minutes = x - 100*degrees return degrees + minutes/60 # Class-based application configuration class ConfigClass(object): from config import MAIL_SERVER, MAIL_PORT, MAIL_USE_SSL, MAIL_USE_TLS, MAIL_USERNAME, MAIL_PASSWORD, MAIL_DEFAULT_SENDER, USER_ENABLE_EMAIL, USER_ENABLE_USERNAME, USER_REQUIRE_RETYPE_PASSWORD, USER_ENABLE_CHANGE_USERNAME, USER_ENABLE_MULTIPLE_EMAILS, USER_ENABLE_CONFIRM_EMAIL, USER_ENABLE_REGISTER, USER_AUTO_LOGIN_AFTER_CONFIRM, USER_SHOW_USERNAME_DOES_NOT_EXIST """ Flask application config """ # Flask settings SECRET_KEY = secret_key # Flask-SQLAlchemy settings SQLALCHEMY_DATABASE_URI = db_location # File-based SQL database SQLALCHEMY_TRACK_MODIFICATIONS = False # Avoids SQLAlchemy warning # Flask-User settings USER_APP_NAME = title # Shown in and email templates and page footers USER_EMAIL_SENDER_EMAIL = MAIL_DEFAULT_SENDER USER_EDIT_USER_PROFILE_TEMPLATE = 'flask_user/edit_user_profile.html' # Setup Flask-User def hbnet_web_service(): """ Flask application factory """ # Create Flask app load app.config mail = Mail() app = Flask(__name__) app.config.from_object(__name__+'.ConfigClass') # Initialize Flask-BabelEx babel = Babel(app) # Initialize Flask-SQLAlchemy db = SQLAlchemy(app) # Define the User data-model. # NB: Make sure to add flask_user UserMixin !!! class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1') # User authentication information. The collation='NOCASE' is required # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'. username = db.Column(db.String(100,), nullable=False, unique=True) password = db.Column(db.String(255), nullable=False, server_default='') email_confirmed_at = db.Column(db.DateTime()) email = db.Column(db.String(255), nullable=True, unique=False, server_default='') # User information first_name = db.Column(db.String(100), nullable=False, server_default='') last_name = db.Column(db.String(100), nullable=False, server_default='') dmr_ids = db.Column(db.String(1000), nullable=False, server_default='') city = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(2000), nullable=False, server_default='') aprs = db.Column(db.String(2000), nullable=False, server_default='{}') #Used for initial approval initial_admin_approved = db.Column('initial_admin_approved', db.Boolean(), nullable=False, server_default='1') # Define the relationship to Role via UserRoles roles = db.relationship('Role', secondary='user_roles') # Define the Role data-model class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) # Define the UserRoles association table class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) class BurnList(db.Model): __tablename__ = 'burn_list' ## id = db.Column(db.Integer(), primary_key=True) dmr_id = db.Column(db.Integer(), unique=True, primary_key=True) version = db.Column(db.Integer(), primary_key=True) class AuthLog(db.Model): __tablename__ = 'auth_log' id = db.Column(db.Integer(), primary_key=True) login_dmr_id = db.Column(db.Integer()) login_time = db.Column(db.DateTime()) peer_ip = db.Column(db.String(100), nullable=False, server_default='') server_name = db.Column(db.String(100)) login_auth_method = db.Column(db.String(100), nullable=False, server_default='') portal_username = db.Column(db.String(100), nullable=False, server_default='') login_type = db.Column(db.String(100), nullable=False, server_default='') class mmdvmPeer(db.Model): __tablename__ = 'MMDVM_peers' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False, server_default='') enabled = db.Column(db.Boolean(), nullable=False, server_default='1') loose = db.Column(db.Boolean(), nullable=False, server_default='1') ip = db.Column(db.String(100), nullable=False, server_default='127.0.0.1') port = db.Column(db.Integer(), primary_key=False) master_ip = db.Column(db.String(100), nullable=False, server_default='') master_port = db.Column(db.Integer(), primary_key=False) passphrase = db.Column(db.String(100), nullable=False, server_default='') callsign = db.Column(db.String(100), nullable=False, server_default='') radio_id = db.Column(db.Integer(), primary_key=False) rx_freq = db.Column(db.String(100), nullable=False, server_default='') tx_freq = db.Column(db.String(100), nullable=False, server_default='') tx_power = db.Column(db.String(100), nullable=False, server_default='') color_code = db.Column(db.String(100), nullable=False, server_default='') latitude = db.Column(db.String(100), nullable=False, server_default='') longitude = db.Column(db.String(100), nullable=False, server_default='') height = db.Column(db.String(100), nullable=False, server_default='') location = db.Column(db.String(100), nullable=False, server_default='') description = db.Column(db.String(100), nullable=False, server_default='') slots = db.Column(db.String(100), nullable=False, server_default='') url = db.Column(db.String(100), nullable=False, server_default='') group_hangtime = db.Column(db.String(100), nullable=False, server_default='') enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') options = db.Column(db.String(100), nullable=False, server_default='') use_acl = db.Column(db.Boolean(), nullable=False, server_default='0') sub_acl = db.Column(db.String(100), nullable=False, server_default='') tg1_acl = db.Column(db.String(100), nullable=False, server_default='') tg2_acl = db.Column(db.String(100), nullable=False, server_default='') server = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(500), nullable=False, server_default='') other_options = db.Column(db.String(1000), nullable=False, server_default='') class xlxPeer(db.Model): __tablename__ = 'XLX_peers' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False, server_default='') enabled = db.Column(db.Boolean(), nullable=False, server_default='1') loose = db.Column(db.Boolean(), nullable=False, server_default='1') ip = db.Column(db.String(100), nullable=False, server_default='127.0.0.1') port = db.Column(db.Integer(), primary_key=False) master_ip = db.Column(db.String(100), nullable=False, server_default='') master_port = db.Column(db.Integer(), primary_key=False) passphrase = db.Column(db.String(100), nullable=False, server_default='') callsign = db.Column(db.String(100), nullable=False, server_default='') radio_id = db.Column(db.Integer(), primary_key=False) rx_freq = db.Column(db.String(100), nullable=False, server_default='') tx_freq = db.Column(db.String(100), nullable=False, server_default='') tx_power = db.Column(db.String(100), nullable=False, server_default='') color_code = db.Column(db.String(100), nullable=False, server_default='') latitude = db.Column(db.String(100), nullable=False, server_default='') longitude = db.Column(db.String(100), nullable=False, server_default='') height = db.Column(db.String(100), nullable=False, server_default='') location = db.Column(db.String(100), nullable=False, server_default='') description = db.Column(db.String(100), nullable=False, server_default='') slots = db.Column(db.String(100), nullable=False, server_default='') url = db.Column(db.String(100), nullable=False, server_default='') group_hangtime = db.Column(db.String(100), nullable=False, server_default='') xlxmodule = db.Column(db.String(100), nullable=False, server_default='') options = db.Column(db.String(100), nullable=False, server_default='') enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') use_acl = db.Column(db.Boolean(), nullable=False, server_default='0') sub_acl = db.Column(db.String(100), nullable=False, server_default='') tg1_acl = db.Column(db.String(100), nullable=False, server_default='') tg2_acl = db.Column(db.String(100), nullable=False, server_default='') server = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(500), nullable=False, server_default='') other_options = db.Column(db.String(1000), nullable=False, server_default='') class ServerList(db.Model): __tablename__ = 'server_list' name = db.Column(db.String(100), unique=True, primary_key=True) secret = db.Column(db.String(255), nullable=False, server_default='') ## public_list = db.Column(db.Boolean(), nullable=False, server_default='1') id = db.Column(db.Integer(), primary_key=False) ip = db.Column(db.String(100), nullable=False, server_default='') global_path = db.Column(db.String(100), nullable=False, server_default='./') global_ping_time = db.Column(db.Integer(), primary_key=False) global_max_missed = db.Column(db.Integer(), primary_key=False) global_use_acl = db.Column(db.Boolean(), nullable=False, server_default='1') global_reg_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL') global_sub_acl = db.Column(db.String(100), nullable=False, server_default='DENY:1') global_tg1_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL') global_tg2_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL') ai_try_download = db.Column(db.Boolean(), nullable=False, server_default='1') ai_path = db.Column(db.String(100), nullable=False, server_default='./') ai_peer_file = db.Column(db.String(100), nullable=False, server_default='peer_ids.json') ai_subscriber_file = db.Column(db.String(100), nullable=False, server_default='subscriber_ids.json') ai_tgid_file = db.Column(db.String(100), nullable=False, server_default='talkgroup_ids.json') ai_peer_url = db.Column(db.String(100), nullable=False, server_default='https://www.radioid.net/static/rptrs.json') ai_subs_url = db.Column(db.String(100), nullable=False, server_default='https://www.radioid.net/static/users.json') ai_stale = db.Column(db.Integer(), primary_key=False, server_default='7') # Pull from config file for now ## um_append_int = db.Column(db.Integer(), primary_key=False, server_default='2') um_shorten_passphrase = db.Column(db.Boolean(), nullable=False, server_default='0') um_burn_file = db.Column(db.String(100), nullable=False, server_default='./burned_ids.txt') # Pull from config file for now ## um_burn_int = db.Column(db.Integer(), primary_key=False, server_default='6') report_enable = db.Column(db.Boolean(), nullable=False, server_default='1') report_interval = db.Column(db.Integer(), primary_key=False, server_default='60') report_port = db.Column(db.Integer(), primary_key=False, server_default='4321') report_clients =db.Column(db.String(100), nullable=False, server_default='127.0.0.1') unit_time = db.Column(db.Integer(), primary_key=False, server_default='10080') notes = db.Column(db.String(100), nullable=False, server_default='') dash_url = db.Column(db.String(1000), nullable=True, server_default='https://hbnet.xyz') public_notes = db.Column(db.String(1000), nullable=False, server_default='') other_options = db.Column(db.String(1000), nullable=False, server_default='') class MasterList(db.Model): __tablename__ = 'master_list' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False, server_default='') static_positions = db.Column(db.Boolean(), nullable=False, server_default='0') repeat = db.Column(db.Boolean(), nullable=False, server_default='1') active = db.Column(db.Boolean(), nullable=False, server_default='1') max_peers = db.Column(db.Integer(), primary_key=False, server_default='10') ip = db.Column(db.String(100), nullable=False, server_default='') port = db.Column(db.Integer(), primary_key=False) enable_um = db.Column(db.Boolean(), nullable=False, server_default='1') passphrase = db.Column(db.String(100), nullable=False, server_default='') group_hang_time = db.Column(db.Integer(), primary_key=False, server_default='5') use_acl = db.Column(db.Boolean(), nullable=False, server_default='1') reg_acl = db.Column(db.String(100), nullable=False, server_default='') sub_acl = db.Column(db.String(100), nullable=False, server_default='') tg1_acl = db.Column(db.String(100), nullable=False, server_default='') tg2_acl = db.Column(db.String(100), nullable=False, server_default='') enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') server = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(500), nullable=False, server_default='') public_list = db.Column(db.Boolean(), nullable=False, server_default='1') other_options = db.Column(db.String(1000), nullable=False, server_default='') class ProxyList(db.Model): __tablename__ = 'proxy_list' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False, server_default='') active = db.Column(db.Boolean(), nullable=False, server_default='1') static_positions = db.Column(db.Boolean(), nullable=False, server_default='0') repeat = db.Column(db.Boolean(), nullable=False, server_default='1') enable_um = db.Column(db.Boolean(), nullable=False, server_default='1') passphrase = db.Column(db.String(100), nullable=False, server_default='') external_proxy = db.Column(db.Boolean(), nullable=False, server_default='0') external_port = db.Column(db.Integer(), primary_key=False) group_hang_time = db.Column(db.Integer(), primary_key=False) internal_start_port = db.Column(db.Integer(), primary_key=False) internal_stop_port = db.Column(db.Integer(), primary_key=False) use_acl = db.Column(db.Boolean(), nullable=False, server_default='1') reg_acl = db.Column(db.String(100), nullable=False, server_default='') sub_acl = db.Column(db.String(100), nullable=False, server_default='') tg1_acl = db.Column(db.String(100), nullable=False, server_default='') tg2_acl = db.Column(db.String(100), nullable=False, server_default='') enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') server = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(500), nullable=False, server_default='') public_list = db.Column(db.Boolean(), nullable=False, server_default='1') other_options = db.Column(db.String(1000), nullable=False, server_default='') class OBP(db.Model): __tablename__ = 'OpenBridge' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False, server_default='') enabled = db.Column(db.Boolean(), nullable=False, server_default='1') network_id = db.Column(db.Integer(), primary_key=False) ip = db.Column(db.String(100), nullable=False, server_default='') port = db.Column(db.Integer(), primary_key=False) passphrase = db.Column(db.String(100), nullable=False, server_default='') target_ip = db.Column(db.String(100), nullable=False, server_default='') target_port = db.Column(db.Integer(), primary_key=False) both_slots = db.Column(db.Boolean(), nullable=False, server_default='1') use_acl = db.Column(db.Boolean(), nullable=False, server_default='1') sub_acl = db.Column(db.String(100), nullable=False, server_default='') tg_acl = db.Column(db.String(100), nullable=False, server_default='') enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') server = db.Column(db.String(100), nullable=False, server_default='') notes = db.Column(db.String(500), nullable=False, server_default='') other_options = db.Column(db.String(1000), nullable=False, server_default='') encryption_key = db.Column(db.String(200), nullable=False, server_default='') obp_encryption = db.Column(db.Boolean(), nullable=False, server_default='0') class BridgeRules(db.Model): __tablename__ = 'bridge_rules' id = db.Column(db.Integer(), primary_key=True) bridge_name = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') ts = db.Column(db.Integer(), primary_key=False) tg = db.Column(db.Integer(), primary_key=False) active = db.Column(db.Boolean(), nullable=False, server_default='1') timeout = db.Column(db.Integer(), primary_key=False) to_type = db.Column(db.String(100), nullable=False, server_default='') on = db.Column(db.String(100), nullable=False, server_default='') off = db.Column(db.String(100), nullable=False, server_default='') reset = db.Column(db.String(100), nullable=False, server_default='') server = db.Column(db.String(100), nullable=False, server_default='') ## public_list = db.Column(db.Boolean(), nullable=False, server_default='0') proxy = db.Column(db.Boolean(), nullable=False, server_default='0') class BridgeList(db.Model): __tablename__ = 'bridge_list' id = db.Column(db.Integer(), primary_key=True) bridge_name = db.Column(db.String(100), nullable=False, server_default='') description = db.Column(db.String(5000), nullable=False, server_default='') public_list = db.Column(db.Boolean(), nullable=False, server_default='0') tg = db.Column(db.Integer(), primary_key=False) class GPS_LocLog(db.Model): __tablename__ = 'gps_locations' id = db.Column(db.Integer(), primary_key=True) callsign = db.Column(db.String(100), nullable=False, server_default='') comment = db.Column(db.String(150), nullable=False, server_default='') lat = db.Column(db.String(100), nullable=False, server_default='') lon = db.Column(db.String(100), nullable=False, server_default='') time = db.Column(db.DateTime()) server = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') dmr_id = db.Column(db.Integer(), primary_key=False) class BulletinBoard(db.Model): __tablename__ = 'sms_bb' id = db.Column(db.Integer(), primary_key=True) callsign = db.Column(db.String(100), nullable=False, server_default='') bulletin = db.Column(db.String(150), nullable=False, server_default='') time = db.Column(db.DateTime()) server = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') dmr_id = db.Column(db.Integer(), primary_key=False) class SMSLog(db.Model): __tablename__ = 'sms_log' id = db.Column(db.Integer(), primary_key=True) snd_callsign = db.Column(db.String(100), nullable=False, server_default='') rcv_callsign = db.Column(db.String(100), nullable=False, server_default='') message = db.Column(db.String(100), nullable=False, server_default='') time = db.Column(db.DateTime()) server = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') snd_id = db.Column(db.Integer(), primary_key=False) rcv_id = db.Column(db.Integer(), primary_key=False) class MailBox(db.Model): __tablename__ = 'sms_aprs_mailbox' id = db.Column(db.Integer(), primary_key=True) snd_callsign = db.Column(db.String(100), nullable=False, server_default='') rcv_callsign = db.Column(db.String(100), nullable=False, server_default='') message = db.Column(db.String(150), nullable=False, server_default='') time = db.Column(db.DateTime()) server = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') snd_id = db.Column(db.Integer(), primary_key=False) rcv_id = db.Column(db.Integer(), primary_key=False) class News(db.Model): __tablename__ = 'news' id = db.Column(db.Integer(), primary_key=True) subject = db.Column(db.String(100), nullable=False, server_default='') text = db.Column(db.String(5000), nullable=False, server_default='') date = db.Column(db.String(100), nullable=False, server_default='') time = db.Column(db.DateTime()) class PeerLoc(db.Model): __tablename__ = 'peer_locations' id = db.Column(db.Integer(), primary_key=True) callsign = db.Column(db.String(100), nullable=False, server_default='') comment = db.Column(db.String(100), nullable=False, server_default='') lat = db.Column(db.String(100), nullable=False, server_default='') lon = db.Column(db.String(100), nullable=False, server_default='') time = db.Column(db.DateTime()) server = db.Column(db.String(100), nullable=False, server_default='') system_name = db.Column(db.String(100), nullable=False, server_default='') user = db.Column(db.String(100), nullable=False, server_default='') dmr_id = db.Column(db.Integer(), primary_key=False) url = db.Column(db.String(100), nullable=False, server_default='') software = db.Column(db.String(100), nullable=False, server_default='') loc = db.Column(db.String(100), nullable=False, server_default='') class CustomID(db.Model): __tablename__ = 'custom_dmr_id' id = db.Column(db.Integer(), primary_key=True) callsign = db.Column(db.String(100), nullable=False, server_default='') f_name = db.Column(db.String(100), nullable=False, server_default='') l_name = db.Column(db.String(100), nullable=False, server_default='') city = db.Column(db.String(100), nullable=False, server_default='') country = db.Column(db.String(100), nullable=False, server_default='') dmr_id = db.Column(db.Integer(), primary_key=False) class Social(db.Model): __tablename__ = 'social' id = db.Column(db.Integer(), primary_key=True) callsign = db.Column(db.String(100), nullable=False, server_default='') message = db.Column(db.String(150), nullable=False, server_default='') time = db.Column(db.DateTime()) dmr_id = db.Column(db.Integer(), primary_key=False) class TinyPage(db.Model): __tablename__ = 'tiny_pages' id = db.Column(db.Integer(), primary_key=True) author = db.Column(db.String(100), nullable=False, server_default='') content = db.Column(db.String(150), nullable=False, server_default='') query_term = db.Column(db.String(100), nullable=False, server_default='', unique=False) time = db.Column(db.DateTime()) class Misc(db.Model): __tablename__ = 'misc' id = db.Column(db.Integer(), primary_key=True) field_1 = db.Column(db.String(500), nullable=True, server_default='') field_2 = db.Column(db.String(500), nullable=True, server_default='') field_3 = db.Column(db.String(500), nullable=True, server_default='') field_4 = db.Column(db.String(500), nullable=True, server_default='') int_1 = db.Column(db.Integer(), nullable=True) int_2 = db.Column(db.Integer(), nullable=True) int_3 = db.Column(db.Integer(), nullable=True) int_4 = db.Column(db.Integer(), nullable=True) boo_1 = db.Column(db.Boolean(), nullable=True, server_default='1') boo_2 = db.Column(db.Boolean(), nullable=True, server_default='1') time = db.Column(db.DateTime()) # Customize Flask-User class CustomUserManager(UserManager): # Override or extend the default login view method def login_view(self): """Prepare and process the login form.""" # Authenticate username/email and login authenticated users. safe_next_url = self._get_safe_next_url('next', self.USER_AFTER_LOGIN_ENDPOINT) safe_reg_next = self._get_safe_next_url('reg_next', self.USER_AFTER_REGISTER_ENDPOINT) # Immediately redirect already logged in users if self.call_or_get(current_user.is_authenticated) and self.USER_AUTO_LOGIN_AT_LOGIN: return redirect(safe_next_url) # Initialize form login_form = self.LoginFormClass(request.form) # for login.html register_form = self.RegisterFormClass() # for login_or_register.html if request.method != 'POST': login_form.next.data = register_form.next.data = safe_next_url login_form.reg_next.data = register_form.reg_next.data = safe_reg_next # Process valid POST if request.method == 'POST' and login_form.validate(): # Retrieve User user = None user_email = None if self.USER_ENABLE_USERNAME: # Find user record by username user = self.db_manager.find_user_by_username(login_form.username.data) # Find user record by email (with form.username) if not user and self.USER_ENABLE_EMAIL: user, user_email = self.db_manager.get_user_and_user_email_by_email(login_form.username.data) else: # Find user by email (with form.email) user, user_email = self.db_manager.get_user_and_user_email_by_email(login_form.email.data) #Add aditional message flash_text = Misc.query.filter_by(field_1='approval_flash').first() if not user.initial_admin_approved: flash(flash_text.field_2, 'success') if user: # Log user in safe_next_url = self.make_safe_url(login_form.next.data) return self._do_login_user(user, safe_next_url, login_form.remember_me.data) # Render form tos_db = Misc.query.filter_by(field_1='terms_of_service').first() print(Misc.query.filter_by(field_1='terms_of_service').first()) self.prepare_domain_translations() template_filename = self.USER_LOGIN_AUTH0_TEMPLATE if self.USER_ENABLE_AUTH0 else self.USER_LOGIN_TEMPLATE return render_template(template_filename, form=login_form, login_form=login_form, tos='hello there!', register_form=register_form) #user_manager = UserManager(app, db, User) user_manager = CustomUserManager(app, db, User) # Create all database tables db.create_all() if not User.query.filter(User.username == 'admin').first(): user = User( username='admin', email='admin@no.reply', email_confirmed_at=datetime.datetime.utcnow(), password=user_manager.hash_password('admin'), initial_admin_approved = True, notes='Default admin account created during installation.', dmr_ids='{}', aprs = '{}' ) user.roles.append(Role(name='Admin')) user.roles.append(Role(name='User')) db.session.add(user) # Add approval messages to DB for editing email_entry_add = Misc( field_1 = 'approval_email', field_2 = 'You are receiving this message because an administrator has approved your account. You may now login and use ' + title + '.', time = datetime.datetime.utcnow() ) db.session.add(email_entry_add) flash_entry_add = Misc( field_1 = 'approval_flash', field_2 = 'You account is waiting for approval from an administrator. See the Help page for more information. You will receive an email when your account is approved.', 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 with the laws of your country.

''', time = datetime.datetime.utcnow() ) db.session.add(tos_entry_add) home_entry_add = Misc( field_1 = 'home_page', field_2 = '

Welcome to ' + title + '

.', time = datetime.datetime.utcnow() ) db.session.add(home_entry_add) ping_list_initial = Misc( field_1 = 'ping_list', field_2 = '{}', time = datetime.datetime.utcnow() ) db.session.add(ping_list_initial) script_links_initial = Misc( field_1 = 'script_links', field_2 = '{}', time = datetime.datetime.utcnow() ) db.session.add(script_links_initial) db.session.commit() # Query radioid.net for list of DMR IDs, then add to DB @user_registered.connect_via(app) def _after_user_registered_hook(sender, user, **extra): aprs_dict = {} edit_user = User.query.filter(User.username == user.username).first() radioid_data = ast.literal_eval(get_ids(user.username)) ## edit_user.notes = '' edit_user.dmr_ids = str(radioid_data[0]) edit_user.first_name = str(radioid_data[1]) edit_user.last_name = str(radioid_data[2]) edit_user.city = str(radioid_data[3]) for i in radioid_data[0].items(): aprs_dict[i[0]] = 'default' edit_user.aprs = str(aprs_dict) user_role = UserRoles( user_id=edit_user.id, role_id=2, ) db.session.add(user_role) if default_account_state == False: edit_user.active = default_account_state edit_user.initial_admin_approved = False if USER_ENABLE_CONFIRM_EMAIL == False: edit_user.email_confirmed_at = datetime.datetime.utcnow() db.session.commit() def gen_passphrase(dmr_id): _new_peer_id = bytes_4(int(str(dmr_id)[:7])) trimmed_id = int(str(dmr_id)[:7]) b_list = get_burnlist() # print(b_list) burned = False for ui in b_list.items(): # print(ui) #print(b_list) if ui[0] == trimmed_id: if ui[0] != 0: calc_passphrase = hashlib.sha256(str(extra_1).encode() + str(extra_int_1).encode() + str(_new_peer_id).encode()[-3:]).hexdigest().upper().encode()[::14] + base64.b64encode(bytes.fromhex(str(hex(libscrc.ccitt((_new_peer_id) + b_list[trimmed_id].to_bytes(2, 'big') + burn_int.to_bytes(2, 'big') + append_int.to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + b_list[trimmed_id].to_bytes(2, 'big') + burn_int.to_bytes(2, 'big') + append_int.to_bytes(2, 'big'))))[2:].zfill(8)))))[2:].zfill(4)) + (_new_peer_id) + b_list[trimmed_id].to_bytes(2, 'big') + burn_int.to_bytes(2, 'big') + append_int.to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + b_list[trimmed_id].to_bytes(2, 'big') + burn_int.to_bytes(2, 'big') + append_int.to_bytes(2, 'big'))))[2:].zfill(8))) + hashlib.sha256(str(extra_2).encode() + str(extra_int_2).encode() + str(_new_peer_id).encode()[-3:]).hexdigest().upper().encode()[::14] burned = True if burned == False: calc_passphrase = hashlib.sha256(str(extra_1).encode() + str(extra_int_1).encode() + str(_new_peer_id).encode()[-3:]).hexdigest().upper().encode()[::14] + base64.b64encode(bytes.fromhex(str(hex(libscrc.ccitt((_new_peer_id) + append_int.to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + append_int.to_bytes(2, 'big'))))[2:].zfill(8)))))[2:].zfill(4)) + (_new_peer_id) + append_int.to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + append_int.to_bytes(2, 'big'))))[2:].zfill(8))) + hashlib.sha256(str(extra_2).encode() + str(extra_int_2).encode() + str(_new_peer_id).encode()[-3:]).hexdigest().upper().encode()[::14] if use_short_passphrase == True: trim_pass = str(calc_passphrase)[2:-1] new_pass = trim_pass[::int(shorten_sample)][-int(shorten_length):] return str(new_pass) elif use_short_passphrase ==False: return str(calc_passphrase)[2:-1] def update_from_radioid(callsign): edit_user = User.query.filter(User.username == callsign).first() #edit_user.dmr_ids = str(ast.literal_eval(get_ids(callsign))[0]) radioid_dict = ast.literal_eval(get_ids(callsign))[0] db_id_dict = ast.literal_eval(edit_user.dmr_ids) new_id_dict = db_id_dict.copy() for i in radioid_dict.items(): if i[0] in db_id_dict: pass elif i[0] not in db_id_dict: new_id_dict[i[0]] = 0 edit_user.dmr_ids = str(new_id_dict) edit_user.first_name = str(ast.literal_eval(get_ids(callsign))[1]) edit_user.last_name = str(ast.literal_eval(get_ids(callsign))[2]) edit_user.city = str(ast.literal_eval(get_ids(callsign))[3]) db.session.commit() # The Home page is accessible to anyone @app.route('/') def home_page(): home_text = Misc.query.filter_by(field_1='home_page').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)) @app.route('/tos') def tos_page(): tos_text = Misc.query.filter_by(field_1='terms_of_service').first() content = tos_text.field_2 return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/map_info/') ## @login_required def single_peer(dmr_id): try: l = PeerLoc.query.filter_by(dmr_id=dmr_id).first() content = '''
 

''' + l.callsign + '''

 
DMR ID:  ''' + str(l.dmr_id) + ''' 
Location:  ''' + l.loc + ''' 
Lat, Lon:  ''' + l.lat + ''', ''' + l.lon + ''' 
Description:  ''' + l.comment + ''' 

URL:

 ''' + l.url + ''' 
Device:  ''' + l.software + ''' 
''' except: content = 'No peer found.' return render_template('single_map_peer.html', markup_content = Markup(content)) @app.route('/map') ## @login_required def map_page(): dev_loc = GPS_LocLog.query.order_by(GPS_LocLog.time.desc()).limit(300).all() dev_list = [] f_map = folium.Map(location=center_map, zoom_start=map_zoom) peer_l = PeerLoc.query.all() print(peer_l) for i in dev_loc: if i.callsign in dev_list: pass elif i.callsign not in dev_list: dev_list.append(i.callsign) lat = i.lat lon = i.lon if 'S' in i.lat: lat = aprs_to_latlon(float(re.sub('[A-Za-z]','', i.lat))) lat = -lat if 'S' not in i.lat: lat = aprs_to_latlon(float(re.sub('[A-Za-z]','', i.lat))) if 'W' in i.lon: lon = aprs_to_latlon(float(re.sub('[A-Za-z]','', i.lon))) lon = -lon if 'W' not in i.lon: lon = aprs_to_latlon(float(re.sub('[A-Za-z]','', i.lon))) folium.Marker([lat, lon], popup="""
Last Location:
"""+ str(i.callsign) +"""
"""+ str(i.time.strftime(time_format)) +"""
""", icon=folium.Icon(color="blue", icon="record"), tooltip='' + i.callsign + '').add_to(f_map) for l in peer_l: ## folium.Marker([float(l[1][1]), float(l[1][2])], popup=''' ##
##

''' + l[1][0] + '''

##
## ''' + l[1][5] + ''' ##
## ''' + l[1][1] + ''', ''' + l[1][2] + ''' ##
## ''' + l[1][3] + ''' ##
## ''' + l[1][4] + ''' ##
## ''' + l[1][6] + ''' ##
##
## ''', icon=folium.Icon(color="red", icon="record"), tooltip='' + l[1][0] + '').add_to(f_map) folium.Marker([float(l.lat), float(l.lon)], popup='''

''' + l.callsign + '''

''' + l.loc + '''
''', icon=folium.Icon(color="red", icon="record"), tooltip='' + l.callsign + '').add_to(f_map) content = f_map._repr_html_() return render_template('map.html', markup_content = Markup(content)) @app.route('/help') def help_page(): return render_template('help.html') @app.route('/generate_passphrase/pi-star', methods = ['GET']) @login_required def gen_pi_star(): try: u = current_user id_dict = ast.literal_eval(u.dmr_ids) script_l = Misc.query.filter_by(field_1='script_links').first() script_links = ast.literal_eval(script_l.field_2) #u = User.query.filter_by(username=user).first() ## print(request.args.get('mode')) ## if request.args.get('mode') == 'generated': content = '' for i in id_dict.items(): #if i[1] == '': link_num = str(random.randint(1,99999999)).zfill(8) + str(time.time()) + str(random.randint(1,99999999)).zfill(8) script_links[i[0]] = link_num misc_edit_field_1('script_links', str(script_links), '', '', 0, 0, 0, 0, False, False) content = content + '''

ID: ''' + str(i[0]) + '''

rpi-rw; wget -O /root/auto_pistar.py "''' + str(url) + '/get_script?dmr_id=' + str(i[0]) + '&number=' + str(link_num) + '''"; chmod +x /root/auto_pistar.py; python3 /root/auto_pistar.py; pistar-update
''' #else: # content = content + '''\n

Error

''' except: content = Markup('No DMR IDs found or other error.') #return str(content) return render_template('pi-star_gen.html', markup_content = Markup(content)) @app.route('/generate_passphrase', methods = ['GET']) @login_required def gen(): #print(str(gen_passphrase(3153591))) #(int(i[0]))) pl = Misc.query.filter_by(field_1='ping_list').first() ping_list = ast.literal_eval(pl.field_2) sl = ServerList.query.all() script_l = Misc.query.filter_by(field_1='script_links').first() script_links = ast.literal_eval(script_l.field_2) svr_content = '' for i in sl: try: if time.time() - ping_list[i.name] < 20: svr_status = '''
Online
''' elif time.time() - ping_list[i.name] <= 300: svr_status = '''
Unknown
(No pings, less than 5 min.)
''' elif time.time() - ping_list[i.name] > 300: svr_status = '''
Offline
''' else: svr_status = '''
Unknown Condition
''' print(ping_list) print(time.time()) except: svr_status = '''
Unknown
''' if i.ip == '': pass else: svr_content = svr_content + '''

''' + i.name + '''


''' + svr_status + '''
''' + i.public_notes + '''

 


''' try: #user_id = request.args.get('user_id') u = current_user id_dict = ast.literal_eval(u.dmr_ids) #u = User.query.filter_by(username=user).first() ## if request.args.get('mode') == 'generated': content = '\n' for i in id_dict.items(): if isinstance(i[1], int) == True and i[1] != 0: link_num = str(random.randint(1,99999999)).zfill(8) + str(time.time()) + str(random.randint(1,99999999)).zfill(8) script_links[i[0]] = link_num misc_edit_field_1('script_links', str(script_links), '', '', 0, 0, 0, 0, False, False) #print(script_links) content = content + '''\n
MMDVM Passphrase:
''' + str(gen_passphrase(int(i[0]))) + '''


''' + convert_nato(str(gen_passphrase(int(i[0])))) + '''

''' elif i[1] == 0: link_num = str(random.randint(1,99999999)).zfill(8) + str(time.time()) + str(random.randint(1,99999999)).zfill(8) script_links[i[0]] = link_num misc_edit_field_1('script_links', str(script_links), '', '', 0, 0, 0, 0, False, False) #print(script_links) content = content + '''\n
MMDVM Passphrase:
''' + str(gen_passphrase(int(i[0]))) + '''


''' + convert_nato(str(gen_passphrase(int(i[0])))) + '''

''' elif i[1] == '': content = content + '''
MMDVM Passphrase:
''' + legacy_passphrase + '''


''' + convert_nato(legacy_passphrase) + '''

''' else: content = content + '''
MMDVM Passphrase:
''' + str(i[1]) + '''


''' + convert_nato(str(i[1])) + '''

''' #content = content + '\n\n' + str(script_links[i[0]]) except: content = Markup('No DMR IDs found or other error.') #return str(content) return render_template('view_passphrase.html', passphrase_content = Markup(content), server_content = Markup(svr_content)) @app.route('/update_ids', methods=['POST', 'GET']) @login_required # User must be authenticated def update_info(): #print(request.args.get('callsign')) #print(current_user.username) if request.args.get('callsign') == current_user.username or request.args.get('callsign') and request.args.get('callsign') != current_user.username and current_user.has_roles('Admin'): content = '

Updated your information.

' update_from_radioid(request.args.get('callsign')) else: content = '''

Use this page to sync changes from RadioID.net with this system (such as a new DMR ID, name change, etc.).

Update your information from RadioID.net to change your city, name, or add any additional DMR IDs.

 

Yes, update my information.

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/email_user', methods=['POST', 'GET']) @roles_required('Admin') @login_required # User must be authenticated def email_user(): if request.method == 'GET' and request.args.get('callsign'): content = '''

Send email to user: ''' + request.args.get('callsign') + '''







 

''' elif request.method == 'POST': # and request.form.get('callsign') and request.form.get('subject') and request.form.get('message'): u = User.query.filter_by(username=request.args.get('callsign')).first() msg = Message(recipients=[u.email], sender=(title, MAIL_DEFAULT_SENDER), subject=request.form.get('subject'), body=request.form.get('message')) mail.send(msg) content = '

Sent email to: ' + u.email + '

' else: content = '''

Find user in "List Users", then click on the email link.'

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/list_users') @roles_required('Admin') @login_required # User must be authenticated def list_users(): u = User.query.all() # Broken for now, link taken out -

List/edit users:

 

Enter Callsign

u_list = ''' ''' for i in u: u_list = u_list + ''' '''+ '\n' content = u_list + '''
Callsign Name Enabled DMR ID:Authentication Notes
 ''' + str(i.first_name) + ' ' + str(i.last_name) + '''   ''' + str(i.active) + '''   ''' + str(i.dmr_ids) + '''   ''' + str(i.notes) + ''' 

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/approve_users', methods=['POST', 'GET']) @login_required @roles_required('Admin') # Use of @roles_required decorator def approve_list(): u = User.query.all() wait_list = '''

Users waiting for approval:

 

Click on the callsign to approve user. An email may be sent to inform the user that they can login.

 

''' for i in u: ## print(i.username) ## print(i.initial_admin_approved) if i.initial_admin_approved == False: wait_list = wait_list+ ''' '''+ '\n' content = wait_list + '''
Callsign Name Enabled DMR ID:Authentication
    ''' + str(i.first_name) + ' ' + str(i.last_name) + '''   ''' + str(i.active) + '''   ''' + str(i.dmr_ids) + ''' 

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) # The Admin page requires an 'Admin' role. @app.route('/edit_user', methods=['POST', 'GET']) @login_required @roles_required('Admin') # Use of @roles_required decorator def admin_page(): #print(request.args.get('callsign')) #print(request.args.get('callsign')) ## if request.method == 'POST' and request.form.get('callsign'): ## #result = request.json ## callsign = request.form.get('callsign') ## u = User.query.filter_by(username=callsign).first() ## content = u.dmr_ids if request.method == 'POST' and request.args.get('callsign') == None: content = 'Not found' elif request.method == 'POST' and request.args.get('callsign') and request.form.get('user_status'): user = request.args.get('callsign') #print(user) edit_user = User.query.filter(User.username == user).first() content = '' if request.form.get('user_status') != edit_user.active: if request.form.get('user_status') == "True": edit_user.active = True content = content + '''

User ''' + str(user) + ''' has been enabled.

\n''' if request.form.get('user_status') == "False": edit_user.active = False content = content + '''

User ''' + str(user) + ''' has been disabled.

\n''' ## print(request.form.get('username')) if user != request.form.get('username'): #### #print(edit_user.username) content = content + '''

User ''' + str(user) + ''' changed to ''' + request.form.get('username') + '''.

\n''' edit_user.username = request.form.get('username') if request.form.get('email') != edit_user.email: edit_user.email = request.form.get('email') content = content + '''

Changed email for user: ''' + str(user) + ''' to ''' + request.form.get('email') + '''

\n''' if request.form.get('aprs') != edit_user.aprs: edit_user.aprs = request.form.get('aprs') content = content + '''

Changed APRS settings for user: ''' + str(user) + ''' to ''' + request.form.get('aprs') + '''

\n''' if request.form.get('notes') != edit_user.notes: edit_user.notes = request.form.get('notes') content = content + '''

Changed notes for user: ''' + str(user) + '''.

\n''' if request.form.get('password') != '': edit_user.password = user_manager.hash_password(request.form.get('password')) content = content + '''

Changed password for user: ''' + str(user) + '''

\n''' if request.form.get('dmr_ids') != edit_user.dmr_ids: edit_user.dmr_ids = request.form.get('dmr_ids') dmr_auth_dict = ast.literal_eval(request.form.get('dmr_ids')) for id_user in dmr_auth_dict: if isinstance(dmr_auth_dict[id_user], int) == True and dmr_auth_dict[id_user] != 0: #print('burn it') if id_user in get_burnlist(): ## print('burned') if get_burnlist()[id_user] != dmr_auth_dict[id_user]: ## print('update vers') update_burnlist(id_user, dmr_auth_dict[id_user]) else: pass ## print('no update') else: add_burnlist(id_user, dmr_auth_dict[id_user]) ## print('not in list, adding') elif isinstance(dmr_auth_dict[id_user], int) == False and id_user in get_burnlist(): delete_burnlist(id_user) ## print('remove from burn list - string') elif dmr_auth_dict[id_user] == 0: ## print('remove from burn list') if id_user in get_burnlist(): delete_burnlist(id_user) content = content + '''

Changed authentication settings for user: ''' + str(user) + '''

\n''' db.session.commit() #edit_user = User.query.filter(User.username == request.args.get('callsign')).first() elif request.method == 'GET' and request.args.get('callsign') and request.args.get('delete_user') == 'true': delete_user = User.query.filter(User.username == request.args.get('callsign')).first() db.session.delete(delete_user) db.session.commit() content = '''

Deleted user: ''' + str(delete_user.username) + '''

\n''' elif request.method == 'GET' and request.args.get('callsign') and request.args.get('make_user_admin') == 'true': u = User.query.filter_by(username=request.args.get('callsign')).first() u_role = UserRoles.query.filter_by(user_id=u.id).first() u_role.role_id = 1 db.session.commit() content = '''

User now Admin: ''' + str(request.args.get('callsign')) + '''

\n''' elif request.method == 'GET' and request.args.get('callsign') and request.args.get('make_user_admin') == 'false': u = User.query.filter_by(username=request.args.get('callsign')).first() u_role = UserRoles.query.filter_by(user_id=u.id).first() u_role.role_id = 2 db.session.commit() content = '''

Admin now a user: ''' + str(request.args.get('callsign') ) + '''

\n''' elif request.method == 'GET' and request.args.get('callsign') and request.args.get('admin_approve') == 'true': edit_user = User.query.filter(User.username == request.args.get('callsign')).first() edit_user.active = True edit_user.initial_admin_approved = True db.session.commit() email_text = Misc.query.filter_by(field_1='approval_email').first() try: msg = Message(recipients=[edit_user.email], sender=(title, MAIL_DEFAULT_SENDER), subject='Account Approval', body = str(email_text.field_2)) mail.send(msg) except: content = 'Failed to send email. Approved user anyway' content = content + '''

User approved: ''' + str(request.args.get('callsign')) + '''

\n''' elif request.method == 'GET' and request.args.get('callsign') and request.args.get('email_verified') == 'true': edit_user = User.query.filter(User.username == request.args.get('callsign')).first() edit_user.email_confirmed_at = datetime.datetime.utcnow() db.session.commit() content = '''

Email verified for: ''' + str(request.args.get('callsign')) + '''

\n''' elif request.method == 'POST' and request.form.get('callsign') and not request.form.get('user_status') or request.method == 'GET' and request.args.get('callsign'):# and request.form.get('user_status') : if request.args.get('callsign'): callsign = request.args.get('callsign') if request.form.get('callsign'): callsign = request.form.get('callsign') u = User.query.filter_by(username=callsign).first() user_email_address = 'None' if str(u.email): user_email_address = str(u.email) confirm_link = '' if u.email_confirmed_at == None: confirm_link = '''

Verify email - ''' + str(u.username) + '''

\n''' u_role = UserRoles.query.filter_by(user_id=u.id).first() if u_role.role_id == 2: # Link to promote to Admin role_link = '''

\n''' if u_role.role_id == 1: # Link to promote to User role_link = '''

\n''' id_dict = ast.literal_eval(u.dmr_ids) passphrase_list = ''' ''' for i in id_dict.items(): ## print(i[1]) if isinstance(i[1], int) == True: passphrase_list = passphrase_list + ''' \n''' if i[1] == '': passphrase_list = passphrase_list + ''' \n''' if not isinstance(i[1], int) == True and i[1] != '': passphrase_list = passphrase_list + ''' \n''' passphrase_list = passphrase_list + '
DMR ID Passphrase
''' + str(gen_passphrase(int(i[0]))) + '''
''' + legacy_passphrase + '''
''' + str(i[1]) + '''
' content = '''

 

First Name Last Name
 ''' + u.first_name + '''  ''' + u.last_name + '''
City ''' + u.city + '''

 

''' + passphrase_list + '''

 Options for: ''' + u.username + ''' 

 

 
 ''' + confirm_link + ''' 

Email confirmed: ''' + str(u.email_confirmed_at.strftime(time_format)) + '''

 

 
 ''' + role_link + ''' 
 

 
 

 














 

 Passphrase Authentication Method Key

Calculated Legacy (config) Custom
0 - default,
1-999 - new calculation
'' 'passphrase'

{DMR ID: Method, 2nd DMR ID: Method}

Example:
{1234567: '', 134568: 0, 1234569: 'passphr8s3'}

''' else: content = '''

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/get_script') def get_script(): dmr_id = int(request.args.get('dmr_id')) number = float(request.args.get('number')) #print(type(script_links[dmr_id])) script_l = Misc.query.filter_by(field_1='script_links').first() script_links = ast.literal_eval(script_l.field_2) u = User.query.filter(User.dmr_ids.contains(request.args.get('dmr_id'))).first() pub_list = [] #print(u.dmr_ids) if authorized_peer(dmr_id)[1] == 0: passphrase = gen_passphrase(dmr_id) elif authorized_peer(dmr_id)[1] != 0 and isinstance(authorized_peer(dmr_id)[1], int) == True: passphrase = gen_passphrase(dmr_id) elif authorized_peer(dmr_id)[1] == '': passphrase = legacy_passphrase elif authorized_peer(dmr_id)[1] != '' or authorized_peer(dmr_id)[1] != 0: passphrase = authorized_peer(dmr_id)[1] #try: if dmr_id in script_links and number == float(script_links[dmr_id]): script_links.pop(dmr_id) misc_edit_field_1('script_links', str(script_links), '', '', 0, 0, 0, 0, False, False) ml = MasterList.query.filter_by(public_list=True).filter_by(active=True).all() pl = ProxyList.query.filter_by(public_list=True).filter_by(active=True).all() print(ml) print(pl) for m in ml: print(m.name) ## print(m.server) ## print(m.port) ## print(m.enable_um) ## print(m.passphrase) sl = ServerList.query.filter_by(name=m.server).first() ## print(sl.ip) if m.enable_um == True: passp = passphrase pub_list.append([m.server + '_' + m.name, sl.ip, passphrase, m.port]) for p in pl: sl = ServerList.query.filter_by(name=p.server).first() if p.enable_um == True: passp = passphrase pub_list.append([p.server + '_' + p.name, sl.ip, passphrase, p.external_port]) return str(gen_script(dmr_id, pub_list)) #except: #else: #content = 'Link used or other error.' #return content #return render_template('flask_user_layout.html', markup_content = content, logo = logo) def authorized_peer(peer_id): try: u = User.query.filter(User.dmr_ids.contains(str(peer_id))).first() login_passphrase = ast.literal_eval(u.dmr_ids) return [u.is_active, login_passphrase[peer_id], str(u.username)] except: return [False] @app.route('/auth_log', methods=['POST', 'GET']) @login_required # User must be authenticated @roles_required('Admin') def all_auth_list(): if request.args.get('flush_db') == 'true': content = '''

Flushed entire auth DB.

\n''' authlog_flush() elif request.args.get('flush_user_db') == 'true' and request.args.get('portal_username'): content = '''

Flushed auth DB for: ''' + request.args.get('portal_username') + '''

\n''' authlog_flush_user(request.args.get('portal_username')) elif request.args.get('flush_db_mmdvm') == 'true' and request.args.get('mmdvm_server'): content = '''

Flushed auth DB for: ''' + request.args.get('mmdvm_server') + '''

\n''' authlog_flush_mmdvm_server(request.args.get('mmdvm_server')) elif request.args.get('flush_db_ip') == 'true' and request.args.get('peer_ip'): content = '''

Flushed auth DB for: ''' + request.args.get('peer_ip') + '''

\n''' authlog_flush_ip(request.args.get('peer_ip')) elif request.args.get('flush_dmr_id_db') == 'true' and request.args.get('dmr_id'): content = '''

Flushed auth DB for: ''' + request.args.get('dmr_id') + '''

\n''' authlog_flush_dmr_id(request.args.get('dmr_id')) elif request.args.get('portal_username') and not request.args.get('flush_user_db') and not request.args.get('flush_dmr_id_db') or request.args.get('dmr_id') and not request.args.get('flush_user_db') and not request.args.get('flush_dmr_id_db'): if request.args.get('portal_username'): ## s_filter = portal_username=request.args.get('portal_username') a = AuthLog.query.filter_by(portal_username=str(request.args.get('portal_username')).strip('"')).order_by(AuthLog.login_time.desc()).all() g_arg = str(request.args.get('portal_username')).strip('"') f_link = '''

''' elif request.args.get('dmr_id'): ## s_filter = login_dmr_id=request.args.get('dmr_id') a = AuthLog.query.filter_by(login_dmr_id=request.args.get('dmr_id')).order_by(AuthLog.login_time.desc()).all() g_arg = request.args.get('dmr_id') f_link = '''

''' ## print(s_filter) ## a = AuthLog.query.filter_by(s_filter).order_by(AuthLog.login_dmr_id.desc()).all() content = '''

 

Log for: ''' + g_arg + '''

''' + f_link + '''
  Failed = Not authorized.   Attempt = Checking if authorized.   Confirmed = Authorized, connection comfirmed. 

 

\n''' for i in a: if i.login_type == 'Attempt': content = content + ''' ''' if i.login_type == 'Confirmed': content = content + ''' ''' if i.login_type == 'Failed': content = content + ''' ''' content = content + '

 DMR ID 

 Portal Username 

 Login IP 

 Passphrase 

 Server 

 Time (UTC) 

 Login Status 

 ''' + str(i.login_dmr_id) + '''    ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
' elif request.args.get('mmdvm_server') and not request.args.get('flush_db_mmdvm'): a = AuthLog.query.filter_by(server_name=request.args.get('mmdvm_server')).order_by(AuthLog.login_time.desc()).all() content = '''

 

Log for MMDVM server: ''' + request.args.get('mmdvm_server') + '''

  Failed = Not authorized.   Attempt = Checking if authorized.   Confirmed = Authorized, connection comfirmed. 

 

\n''' for i in a: if i.login_type == 'Attempt': content = content + ''' ''' if i.login_type == 'Confirmed': content = content + ''' ''' if i.login_type == 'Failed': content = content + ''' ''' content = content + '

 DMR ID 

 Portal Username 

 Login IP 

 Passphrase 

 Server 

 Time (UTC) 

 Login Status 

 ''' + str(i.login_dmr_id) + '''    ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + i.server_name + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + i.server_name + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + i.server_name + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
' elif request.args.get('peer_ip') and not request.args.get('flush_db_ip'): a = AuthLog.query.filter_by(peer_ip=request.args.get('peer_ip')).order_by(AuthLog.login_time.desc()).all() content = '''

 

Log for IP address: ''' + request.args.get('peer_ip') + '''

  Failed = Not authorized.   Attempt = Checking if authorized.   Confirmed = Authorized, connection comfirmed. 

 

\n''' for i in a: if i.login_type == 'Attempt': content = content + ''' ''' if i.login_type == 'Confirmed': content = content + ''' ''' if i.login_type == 'Failed': content = content + ''' ''' content = content + '

 DMR ID 

 Portal Username 

 Login IP 

 Passphrase 

 Server 

 Time (UTC) 

 Login Status 

 ''' + str(i.login_dmr_id) + '''    ''' + i.portal_username + '''   ''' + i.peer_ip + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''   ''' + i.peer_ip + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''   ''' + i.peer_ip + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
' else: #a = AuthLog.query.all() ## a = AuthLog.query.order_by(AuthLog.login_time.desc()).limit(300).all() a = AuthLog.query.order_by(AuthLog.login_time.desc()).all() recent_list = [] ## r = AuthLog.query.order_by(AuthLog.login_dmr_id.desc()).all() content = '''

 

Authentication log by DMR ID

  Failed = Not authorized.   Attempt = Checking if authorized.   Confirmed = Authorized, connection comfirmed. 

 

\n''' for i in a: if i.login_dmr_id not in recent_list: recent_list.append(i.login_dmr_id) if i.login_type == 'Attempt': content = content + ''' ''' if i.login_type == 'Confirmed': content = content + ''' ''' if i.login_type == 'Failed': content = content + ''' ''' content = content + '

 DMR ID 

 Portal Username 

 Login IP 

 Passphrase 

 Server 

 Time (UTC) 

 Last Login Status 

 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
 ''' + str(i.login_dmr_id) + '''   ''' + i.portal_username + '''    ''' + str(i.peer_ip) + '''   ''' + i.login_auth_method + '''   ''' + str(i.server_name) + '''   ''' + str(i.login_time) + '''   ''' + str(i.login_type) + ''' 
' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/news') #, methods=['POST', 'GET']) ## @login_required def view_news(): view_news = News.query.order_by(News.time.desc()).all() ## page = request.args.get('page', 1, type=int) ## view_news = News.query.order_by(News.time.desc()).paginate(page=page, per_page=1) #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)) @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)) @app.route('/add_news', methods=['POST', 'GET']) @login_required @roles_required('Admin') def edit_news(): if request.args.get('add') == 'new': content = '''

Added news article.

Redirecting in 3 seconds.

''' news_add(request.form.get('subject'), request.form.get('time'), request.form.get('news')) else: content = '''

 

Post News Article

 


 


 


 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/manage_news', methods=['POST', 'GET']) @login_required @roles_required('Admin') def manage_news(): view_news = News.query.order_by(News.time.desc()).all() if request.args.get('delete'): content = '''

Deleted news article.

Redirecting in 3 seconds.

''' news_delete(request.args.get('delete')) else: content = '''

 

 

''' for a in view_news: content = content + ''' ''' content = content + '''
Subject Date ID
''' + a.subject + ''' | ''' + a.date + ''' ''' + str(a.id) + '''

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/misc_settings', methods=['POST', 'GET']) @login_required @roles_required('Admin') def misc_sett(): if request.args.get('approve_email') == 'save': misc_edit_field_1('approval_email', request.form.get('email_text'), None, None, None, None, None, None, None, None) content = '''

Saved email text.

Redirecting in 3 seconds.

''' elif request.args.get('approve_flash') == 'save': misc_edit_field_1('approval_flash', request.form.get('flash_text'), None, None, None, None, None, None, None, None) 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.

''' else: email_text = Misc.query.filter_by(field_1='approval_email').first() flash_text = Misc.query.filter_by(field_1='approval_flash').first() home_text = Misc.query.filter_by(field_1='home_page').first() tos_text = Misc.query.filter_by(field_1='terms_of_service').first() content = '''

 


 

 


 

 


 

 

 


 

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/import_rules/', methods=['POST', 'GET']) @login_required @roles_required('Admin') def import_rules(server): if request.args.get('import') == 'true': try: imp_dict = ast.literal_eval(request.form.get('rules')) for e in imp_dict.items(): b_db = BridgeList.query.filter_by(bridge_name=e[0]).first() if b_db == None: bridge_add(e[0], 'Add a description', True, 0) for i in e[1]: #.items(): add_system_rule(e[0], i['SYSTEM'], i['TS'], i['TGID'], i['ACTIVE'], i['TIMEOUT'], i['TO_TYPE'], re.sub('\[|\]', '', str(i['ON'])), re.sub('\[|\]', '', str(i['OFF'])), re.sub('\[|\]', '', str(i['RESET'])), server) content = '''

Sucessfully imported rules (or something else).

Redirecting in 3 seconds.

''' except: content = '''

Rules import failed.

Redirecting in 3 seconds.

''' else: content = '''

Before importing:

1. You must have master, proxy, and peer connections set up prior to importing rules. The names of each master, proxy, or peer must match 'SYSTEM' in your rules.py.

2. In rules.py, locate BRIDGES = {...................}. Copy and paste the brackets, { and }, and everything in between into the box below.


 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) ## @app.route('/user_tg') ## def tg_status(): ## cu = current_user ## u = User.query.filter_by(username=cu.username).first() ## sl = ServerList.query.all() ## user_ids = ast.literal_eval(u.dmr_ids) ## content = '

Currently active talkgroups. Updated every 2 minutes.

' #### print(active_tgs) ## for s in sl: ## for i in user_ids.items(): ## for ts in active_tgs[s.name].items(): #### print(ts) #### print(ts[1][3]['peer_id']) ## if i[0] == ts[1][3]['peer_id']: #### print(i[0]) ## print(ts) #### if i[0] in active_tgs[s.name]: #### for x in ts[1]: #### print(x) #### ## if i[0] != ts[1][x][3]['peer_id']: #### ## print('nope') #### ## pass #### ## elif i[0] == ts[1][x][3]['peer_id']: #### ## print(x) #### ## print(s.name) #### ## print('-----ts-----') #### ## print(ts[1][x][3]['peer_id']) #[s.name][3]['peer_id']) #### ## print(active_tgs) #### #### ## print(active_tgs[s.name]) #### ## print(str(active_tgs[ts[1]])) #### # Remove 0 from TG list ## try: ## active_tgs[s.name][ts[0]][0]['1'].remove(0) ## active_tgs[s.name][ts[0]][1]['2'].remove(0) ## except: ## pass ###### try: ## content = content + ''' ## ## ## ## ## ## ## ## ##
##

Server: ''' + str(s.name) + '''

##

DMR ID: ''' + str(i[0]) + '''

##
  ## ## ## ## ## ## ## ## ## ## ## ##
Timeslot 1 ''' + str(active_tgs[s.name][ts[0]][0]['1'])[1:-1] + '''
Timeslot 2 ''' + str(active_tgs[s.name][ts[0]][1]['2'])[1:-1] + '''
##
''' #### except: #### pass ## ## #### #TS1 #### for tg in active_tgs[s.name][i[0]][1]['2']: #### content = content + ''' ''' + str(tg) + ''' ####''' #### print(active_tgs[s.name][i[0]]) #### content = active_tgs[s.name][i[0]][1]['2'] #### content = 'hji' ## ## return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/tg/') #, methods=['POST', 'GET']) ## @login_required def tg_details(name): tg_d = BridgeList.query.filter_by(bridge_name=name).first() content = '''

''' + tg_d.bridge_name + '''


TG #: ''' + str(tg_d.tg) + '''
''' + tg_d.description + '''
''' return render_template('tg.html', markup_content = Markup(content)) @app.route('/hbnet_tg.csv') ## @login_required def tg_csv(): cbl = BridgeList.query.filter_by(public_list=True).all() gen_csv = 'TG, Name\n' for t in cbl: gen_csv = gen_csv + str(t.tg) + ', ' + t.bridge_name + '\n' response = Response(gen_csv, mimetype="text/csv") return response @app.route('/hbnet_tg_anytone.csv') ## @login_required def anytone_tg_csv(): cbl = BridgeList.query.filter_by(public_list=True).all() gen_csv = 'No., Radio ID, Name, Call Type, Call Alert\n' num = 1 for t in cbl: gen_csv = gen_csv + str(num) + ', ' + str(t.tg) + ', ' + t.bridge_name + ', Group Call, None' + '\n' num = num + 1 response = Response(gen_csv, mimetype="text/csv") return response @app.route('/talkgroups') ## @login_required def tg_list(): cbl = BridgeList.query.filter_by(public_list=True).all() content = '' for i in cbl: print(str(re.sub('<[^>]*>', '', i.description))[:50]) content = content + '''    ''' + str(i.tg) + '''  ''' + str(re.sub('<[^>]*>|\s\s+', ' ', i.description))[:50] + '''... ''' return render_template('tg_all.html', markup_content = Markup(content)) @app.route('/sms.xml') def rss_sms(): rss_header = """ """ + title + """ - SMS Feed """ + url + """/sms This is a feed of all SMS received.""" smsl = SMSLog.query.order_by(SMSLog.time.desc()).all() content = ''' ''' for i in smsl: content = content + """ To: """ + i.rcv_callsign + ' (' + str(i.rcv_id) + ') - From: ' + i.snd_callsign + """ (""" + str(i.snd_id) + """ """ + url + """/sms """ + i.message + """ - """ + str(i.time.strftime(time_format)) + """ """ + i.time.strftime('%a, %d %b %y') +""" """ return Response(rss_header + content + "\n\n", mimetype='text/xml') @app.route('/sms') def all_sms(): smsl = SMSLog.query.order_by(SMSLog.time.desc()).all() content = ''' ''' for i in smsl: content = content + '''

''' + i.snd_callsign + '''

\n

''' + i.rcv_callsign + '''

\n ''' + i.message + ''' ''' + i.server + ' - ' + i.system_name + ''' ''' return render_template('sms.html', markup_content = Markup(content)) @app.route('/bulletin_rss.xml') def rss_bb(): rss_header = """ """ + title + """ - Bulletin Board Feed """ + url + """/bb This is a feed of all posts from the Bulletin Board.""" bbl = BulletinBoard.query.order_by(BulletinBoard.time.desc()).all() bb_content = ''' ''' for i in bbl: bb_content = bb_content + """ """ + i.callsign + ' - ' + str(i.dmr_id) + """ """ + url + """/bb """ + i.bulletin + """ - """ + str(i.time.strftime(time_format)) + """ """ + i.time.strftime('%a, %d %b %y') +""" """ return Response(rss_header + bb_content + "\n\n", mimetype='text/xml') @app.route('/bb') def all_bb(): bbl = BulletinBoard.query.order_by(BulletinBoard.time.desc()).all() content = ''' ''' for i in bbl: content = content + '''

''' + i.callsign + '''

\n ''' + i.bulletin + ''' ''' + str(i.time.strftime(time_format)) + ''' ''' + i.server + ' - ' + i.system_name + ''' ''' return render_template('bb.html', markup_content = Markup(content)) @app.route('/tp') def all_tp(): tpl = TinyPage.query.order_by(TinyPage.time.desc()).all() content = ''' ''' for i in tpl: content = content + ''' ''' + i.query_term + ''' ''' + i.content + ''' ''' + i.author + ''' ''' return render_template('tp_all.html', markup_content = Markup(content)) @app.route('/add_tp', methods=['POST', 'GET']) ## @app.route('/add_tp') def new_tp(): u = current_user print(u.username) if request.args.get('add_page'): tp_add(u.username, request.form.get('query'), request.form.get('content')) content = '''

Saved Tiny Page.

Redirecting in 1 seconds.

''' else: content = '' ## tpl = TinyPage.query.order_by(TinyPage.time.desc()).all() ## content = ''' ''' ## for i in tpl: ## content = content + ''' ## ## ''' + i.query_term + ''' ## ''' + i.content + ''' ## ''' + i.author + ''' ## ## ''' return render_template('tp_add.html', markup_content = Markup(content), url = url) @app.route('/ss') def get_all_ss(): ss_all = Social.query.order_by(Social.time.desc()).all() content = '' disp_list = [] for i in ss_all: if i.dmr_id not in disp_list: content = content + '''

''' + i.callsign + '''

\n

''' + i.message + ''' ''' disp_list.append(i.dmr_id) elif i.dmr_id in disp_list: pass print(content) return render_template('ss_all.html', markup_content = Markup(content)) @app.route('/ss/.xml') def get_ss_rss(dmr_id): rss_header = """ """ + title + """ - Social Status Feed for """ + str(dmr_id) + """ """ + url + """/ss/""" + dmr_id + """ This is a feed of all posts from """ + dmr_id + """""" ss_all = Social.query.filter_by(dmr_id=dmr_id).order_by(Social.time.desc()).all() ss_content = '' for i in ss_all: ss_content = ss_content + """ """ + str(dmr_id) + ' - ' + str(i.time.strftime(time_format)) + """ """ + url + """/ss/""" + dmr_id + """ """ + str(i.message) + """ - """ + str(i.time.strftime(time_format)) + """ """ + str(i.time.strftime('%a, %d %b %y')) + """ """ return Response(rss_header + ss_content + "\n\n", mimetype='text/xml') @app.route('/ss/') def get_ss(dmr_id): try: ssd = Social.query.filter_by(dmr_id=dmr_id).order_by(Social.time.desc()).first() ss_all = Social.query.filter_by(dmr_id=dmr_id).order_by(Social.time.desc()).all() post_content = '' content = '''

''' + ssd.callsign + ' - ' + str(ssd.dmr_id) + '''

\n

''' + str(ssd.time.strftime(time_format)) + '''




''' + ssd.message + '''




''' for i in ss_all: post_content = post_content + ''' ''' + i.message + ''' ''' + str(i.time.strftime(time_format)) + ''' ''' except: content = '

No posts by user.

' all_post = '' return render_template('ss.html', markup_content = Markup(content), all_post = Markup(post_content), user_id = dmr_id) @app.route('/all_mail/', methods=['GET', 'POST']) @roles_required('Admin') @login_required def get_all_mail(user): show_mailbox = False if request.args.get('delete_mail'): mailbox_del(int(request.args.get('delete_mail'))) content = '''

Deleted message.

Redirecting in 1 seconds.

''' elif request.args.get('send_mail'): if request.form.get('username').upper() == '*ALL': all_users = User.query.all() for i in all_users: mailbox_add(str(i.username), user, '

Sent via portal:

' + request.form.get('message'), 0, 0, '', '') elif ',' in request.form.get('username').upper(): splt_usr = str(request.form.get('username')).split(',') for i in splt_usr: mailbox_add(i, user, '

Sent via portal:

' + request.form.get('message'), 0, 0, '', '') else: mailbox_add(user, request.form.get('username').upper(), '

Sent via portal:

' + request.form.get('message'), 0, 0, '', '') content = '''

Message sent.

Redirecting in 1 seconds.

''' else: show_mailbox = True mail_all_users = MailBox.query.order_by(MailBox.time.desc()).all() content = '' for i in mail_all_users: content = content + ''' To: ''' + i.snd_callsign + ''' - ''' + str(i.snd_id) + '''
From: ''' + i.rcv_callsign + ''' - ''' + str(i.rcv_id) + ''' ''' + i.message + ''' ''' + str(i.time.strftime(time_format)) + ''' ''' return render_template('all_mail.html', markup_content = Markup(content), show_mail = show_mailbox) @app.route('/mail/', methods=['GET', 'POST']) @login_required def get_mail(user): show_mailbox = False if current_user.username == user: if request.args.get('delete_mail'): mailbox_del(int(request.args.get('delete_mail'))) content = '''

Deleted message.

Redirecting in 1 seconds.

''' elif request.args.get('send_mail'): mailbox_add(user, request.form.get('username').upper(), '

Sent via portal:

' + request.form.get('message'), 0, 0, '', '') content = '''

Message sent.

Redirecting in 1 seconds.

''' else: show_mailbox = True mail_all = MailBox.query.filter_by(rcv_callsign=user.upper()).order_by(MailBox.time.desc()).all() content = '' for i in mail_all: content = content + ''' ''' + i.snd_callsign + ''' - ''' + str(i.snd_id) + ''' ''' + i.message + ''' ''' + str(i.time.strftime(time_format)) + ''' ''' else: content = '

Not your mailbox.

' return render_template('mail.html', markup_content = Markup(content), user_id = user, show_mail = show_mailbox) @app.route('/talkgroups/') #, methods=['POST', 'GET']) @login_required def tg_list_server(server): svr = ServerList.query.filter_by(name=server).first() content = '''

 

''' m_list = MasterList.query.filter_by(server=server).filter_by(active=True).filter_by(public_list=True).all() p_list = ProxyList.query.filter_by(server=server).filter_by(active=True).filter_by(public_list=True).all() tg_list = '' for m in m_list: br = BridgeRules.query.filter_by(server=server).filter_by(system_name=m.name).all() print(br) ## for t in br: ## print(t.tg) for b in br: print(b.bridge_name) bl = BridgeList.query.filter_by(bridge_name=b.bridge_name).first() ## print(bl) if m.name == b.system_name and m.server == b.server and bl.public_list == True: ## print(b.bridge_name) tg_list = tg_list + ''' ''' content = content + '''''' tg_list = '' for p in p_list: br = BridgeRules.query.filter_by(server=server).filter_by(system_name=p.name).all() for b in br: bl = BridgeList.query.filter_by(bridge_name=b.bridge_name).first() ## print(bl.bridge_name) if p.name == b.system_name and p.server == b.server and bl.public_list == True: ## print(b.bridge_name) tg_list = tg_list + ''' ''' content = content + '''''' tg_list = '' content = content + '''
 

Server: ''' + svr.name + '''  -  IP/Host: ''' + str(svr.ip) + '''

   ''' + str(b.tg) + '''  ''' + str(b.ts) + '''  ''' + b.to_type + '''  ''' + str(b.timeout) + '''
''' + '''
Name: ''' + m.name + '''  -  Port: ''' + str(m.port) + '''
''' + tg_list + '''
Name TG TS Timer Type Time (Min)

''' + '''
   ''' + str(b.tg) + '''  ''' + str(b.ts) + '''  ''' + b.to_type + '''  ''' + str(b.timeout) + '''
''' + '''
Name: ''' + p.name + '''  -  Port: ''' + str(p.external_port) + '''
''' + tg_list + '''
Name TG TS Timer Type Time (Min)
 Disconnect from all activated TGs.  4000  
''' + '''

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) ###### DB functions ############################# def get_peer_configs(_server_name): mmdvm_pl = mmdvmPeer.query.filter_by(server=_server_name).filter_by(enabled=True).all() xlx_pl = xlxPeer.query.filter_by(server=_server_name).filter_by(enabled=True).all() ## print(mmdvm_pl) peer_config_list = {} for i in mmdvm_pl: ## print(i.master_ip) peer_config_list.update({i.name: { 'MODE': 'PEER', 'ENABLED': i.enabled, 'LOOSE': i.loose, 'SOCK_ADDR': (gethostbyname(i.ip), i.port), 'IP': i.ip, 'PORT': i.port, 'MASTER_SOCKADDR': (gethostbyname(i.master_ip), i.master_port), 'MASTER_IP': i.master_ip, 'MASTER_PORT': i.master_port, 'PASSPHRASE': i.passphrase, 'CALLSIGN': i.callsign, 'RADIO_ID': int(i.radio_id), #int(i.radio_id).to_bytes(4, 'big'), 'RX_FREQ': i.rx_freq, 'TX_FREQ': i.tx_freq, 'TX_POWER': i.tx_power, 'COLORCODE': i.color_code, 'LATITUDE': i.latitude, 'LONGITUDE': i.longitude, 'HEIGHT': i.height, 'LOCATION': i.location, 'DESCRIPTION': i.description, 'SLOTS': i.slots, 'URL': i.url, 'GROUP_HANGTIME': i.group_hangtime, 'OPTIONS': i.options, 'USE_ACL': i.use_acl, 'SUB_ACL': i.sub_acl, 'TG1_ACL': i.tg1_acl, 'TG2_ACL': i.tg2_acl, 'OTHER_OPTIONS': i.other_options }}) for i in xlx_pl: peer_config_list.update({i.name: { 'MODE': 'XLXPEER', 'ENABLED': i.enabled, 'LOOSE': i.loose, 'SOCK_ADDR': (gethostbyname(i.ip), i.port), 'IP': i.ip, 'PORT': i.port, 'MASTER_SOCKADDR': (gethostbyname(i.master_ip), i.master_port), 'MASTER_IP': i.master_ip, 'MASTER_PORT': i.master_port, 'PASSPHRASE': i.passphrase, 'CALLSIGN': i.callsign, 'RADIO_ID': int(i.radio_id), #int(i.radio_id).to_bytes(4, 'big'), 'RX_FREQ': i.rx_freq, 'TX_FREQ': i.tx_freq, 'TX_POWER': i.tx_power, 'COLORCODE': i.color_code, 'LATITUDE': i.latitude, 'LONGITUDE': i.longitude, 'HEIGHT': i.height, 'LOCATION': i.location, 'DESCRIPTION': i.description, 'SLOTS': i.slots, 'URL': i.url, 'OPTIONS': i.options, 'GROUP_HANGTIME': i.group_hangtime, 'XLXMODULE': i.xlxmodule, 'USE_ACL': i.use_acl, 'SUB_ACL': i.sub_acl, 'TG1_ACL': i.tg1_acl, 'TG2_ACL': i.tg2_acl, 'OTHER_OPTIONS': i.other_options }}) #### print('peers') ## print('----------------') return peer_config_list def get_burnlist(): b = BurnList.query.all() #print(b) burn_dict = {} for i in b: #print(i.dmr_id) burn_dict[i.dmr_id] = i.version return burn_dict def add_burnlist(_dmr_id, _version): burn_list = BurnList( dmr_id=_dmr_id, version=_version, ) db.session.add(burn_list) db.session.commit() def peer_loc_add(_call, _lat, _lon, _comment, _dmr_id, _server, _user, _url, _software, _loc): add_peer_loc = PeerLoc( callsign = _call, lat = _lat, lon = _lon, time = datetime.datetime.utcnow(), comment = _comment, dmr_id = _dmr_id, server = _server, user = _user, url = _url, software = _software, system_name = '', loc = _loc ) db.session.add(add_peer_loc) db.session.commit() def del_peer_loc(_dmr_id): try: _peer_loc = PeerLoc.query.filter_by(dmr_id=_dmr_id).first() db.session.delete(_peer_loc) db.session.commit() except: print('Peer not in DB') pass def dash_loc_add(_call, _lat, _lon, _comment, _dmr_id, _server): add_loc = GPS_LocLog( callsign = _call, lat = _lat, lon = _lon, time = datetime.datetime.utcnow(), comment = _comment, dmr_id = _dmr_id, server = _server, system_name = '' ) db.session.add(add_loc) db.session.commit() def tp_add(_author, _query_term, _content): add_tp = TinyPage( author = _author, query_term = _query_term, content = _content, time = datetime.datetime.utcnow(), ) db.session.add(add_tp) db.session.commit() def bb_add(_callsign, _bulletin, _dmr_id, _server, _system_name): add_bb = BulletinBoard( callsign = _callsign, bulletin = _bulletin, time = datetime.datetime.utcnow(), dmr_id = _dmr_id, server = _server, system_name = _system_name ) db.session.add(add_bb) db.session.commit() def del_ss(_dmr_id): try: ## ss_post = Social.query.filter_by(dmr_id=_dmr_id).first() ## db.session.delete(ss_post) ## db.session.commit() ss_post = Social.query.filter_by(dmr_id=_dmr_id).all() for i in ss_post: elap_time = int(datetime.datetime.utcnow().strftime('%s')) - int(i.time.strftime('%s')) # Remove entries more than 1 year old if elap_time > 31536000: db.session.delete(i) except: print('Social Status not in DB') pass def ss_add(_callsign, _message, _dmr_id): add_ss = Social( callsign = _callsign, message = _message, time = datetime.datetime.utcnow(), dmr_id = _dmr_id ) db.session.add(add_ss) db.session.commit() def tp_del(_id): tpd = TinyPage.query.filter_by(id=_id).first() db.session.delete(tpd) db.session.commit() def sms_log_add(_snd_call, _rcv_call, _msg, _snd_id, _rcv_id, _server, _system_name): add_sms = SMSLog( snd_callsign = _snd_call, rcv_callsign = _rcv_call, message = _msg, time = datetime.datetime.utcnow(), snd_id = _snd_id, rcv_id = _rcv_id, server = _server, system_name = _system_name ) add_sms_mail = MailBox( snd_callsign = _snd_call, rcv_callsign = _rcv_call, message = _msg, time = datetime.datetime.utcnow(), snd_id = _snd_id, rcv_id = _rcv_id, server = _server, system_name = _system_name ) db.session.add(add_sms) db.session.add(add_sms_mail) db.session.commit() def mailbox_add(_snd_call, _rcv_call, _msg, _snd_id, _rcv_id, _server, _system_name): add_sms_mail = MailBox( snd_callsign = _snd_call, rcv_callsign = _rcv_call, message = _msg, time = datetime.datetime.utcnow(), snd_id = _snd_id, rcv_id = _rcv_id, server = _server, system_name = _system_name ) db.session.add(add_sms_mail) db.session.commit() def mailbox_del(_id): mbd = MailBox.query.filter_by(id=_id).first() db.session.delete(mbd) db.session.commit() def trim_bb(): trim_bb = BulletinBoard.query.all() for i in trim_bb: elap_time = int(datetime.datetime.utcnow().strftime('%s')) - int(i.time.strftime('%s')) # Remove entries more than 1 month old if elap_time > 2678400: db.session.delete(i) def trim_sms_log(): trim_sms = SMSLog.query.all() for i in trim_sms: elap_time = int(datetime.datetime.utcnow().strftime('%s')) - int(i.time.strftime('%s')) # Remove entries more than 1 month old if elap_time > 2678400: db.session.delete(i) def trim_dash_loc(): trim_dash = GPS_LocLog.query.all() ## db.session.delete(delete_b) ## db.session.commit() for i in trim_dash: elap_time = int(datetime.datetime.utcnow().strftime('%s')) - int(i.time.strftime('%s')) # Remove entries more than 2 weeks old if elap_time > 1209600: db.session.delete(i) db.session.commit() def update_burnlist(_dmr_id, _version): update_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() update_b.version=_version db.session.commit() def delete_burnlist(_dmr_id): delete_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() db.session.delete(delete_b) db.session.commit() def authlog_add(_dmr_id, _peer_ip, _server_name, _portal_username, _auth_method, _login_type): auth_log_add = AuthLog( login_dmr_id=_dmr_id, login_time=datetime.datetime.utcnow(), portal_username = _portal_username, peer_ip = _peer_ip, server_name = _server_name, login_auth_method=_auth_method, login_type=_login_type ) db.session.add(auth_log_add) db.session.commit() def misc_add(_field_1, _field_2, _field_3, _field_4, _int_1, _int_2, _int_3, _int_4, _boo_1, _boo_2): misc_entry_add = Misc( field_1 = _field_1, field_2 = _field_2, field_3 = _field_3, field_4 = _field_4, int_1 = _int_1, int_2 = _int_2, int_3 = _int_3, int_4 = _int_4, boo_1 = _boo_1, boo_2 = _boo_2, time = datetime.datetime.utcnow() ) db.session.add(misc_entry_add) db.session.commit() def misc_edit_field_1(_field_1, _field_2, _field_3, _field_4, _int_1, _int_2, _int_3, _int_4, _boo_1, _boo_2): m = Misc.query.filter_by(field_1=_field_1).first() m.field_1 = _field_1 m.field_2 = _field_2 m.field_3 = _field_3 m.field_4 = _field_4 m.int_1 = _int_1 m.int_2 = _int_2 m.int_3 = _int_3 m.int_4 = _int_4 m.boo_1 = _boo_1 m.boo_2 = _boo_2 db.session.commit() def delete_misc_field_1(_field_1): delete_f1 = Misc.query.filter_by(field_1=_field_1).first() db.session.delete(delete_f1) db.session.commit() def authlog_flush(): AuthLog.query.delete() db.session.commit() def authlog_flush_user(_user): flush_e = AuthLog.query.filter_by(portal_username=_user).all() for i in flush_e: db.session.delete(i) db.session.commit() def authlog_flush_dmr_id(_dmr_id): flush_e = AuthLog.query.filter_by(login_dmr_id=_dmr_id).all() for i in flush_e: db.session.delete(i) db.session.commit() def authlog_flush_mmdvm_server(_mmdvm_serv): flush_e = AuthLog.query.filter_by(server_name=_mmdvm_serv).all() for i in flush_e: db.session.delete(i) db.session.commit() def authlog_flush_ip(_ip): flush_e = AuthLog.query.filter_by(peer_ip=_ip).all() for i in flush_e: db.session.delete(i) db.session.commit() ## def peer_delete(_mode, _id): ## if _mode == 'xlx': ## p = xlxPeer.query.filter_by(id=_id).first() ## if _mode == 'mmdvm': ## p = mmdvmPeer.query.filter_by(id=_id).first() ## db.session.delete(p) ## db.session.commit() def news_delete(_id): del_n = News.query.filter_by(id=_id).all() for i in del_n: db.session.delete(i) db.session.commit() def news_add(_subject, _time, _news): add_news = News( subject = _subject, date = _time, text = _news, time = datetime.datetime.utcnow() ) db.session.add(add_news) db.session.commit() def server_delete(_name): s = ServerList.query.filter_by(name=_name).first() m = MasterList.query.filter_by(server=_name).all() p = ProxyList.query.filter_by(server=_name).all() o = OBP.query.filter_by(server=_name).all() dr = BridgeRules.query.filter_by(server=_name).all() mp = mmdvmPeer.query.filter_by(server=_name).all() xp = xlxPeer.query.filter_by(server=_name).all() for d in m: db.session.delete(d) for d in p: db.session.delete(d) for d in o: db.session.delete(d) for d in dr: db.session.delete(d) for d in mp: db.session.delete(d) for d in xp: db.session.delete(d) db.session.delete(s) db.session.commit() def peer_delete(_mode, _server, _name): if _mode == 'mmdvm': p = mmdvmPeer.query.filter_by(server=_server).filter_by(name=_name).first() if _mode == 'xlx': p = xlxPeer.query.filter_by(server=_server).filter_by(name=_name).first() dr = BridgeRules.query.filter_by(server=_server).filter_by(system_name=_name).all() for d in dr: db.session.delete(d) db.session.delete(p) db.session.commit() def shared_secrets(): s = ServerList.query.all() #filter_by(name=_name).first() r_list = [] for i in s: r_list.append(str(i.secret)) return r_list def bridge_add(_name, _desc, _public, _tg): add_bridge = BridgeList( bridge_name = _name, description = _desc, public_list = _public, tg = _tg ) db.session.add(add_bridge) db.session.commit() def update_bridge_list(_name, _desc, _public, _new_name, _tg): bl = BridgeList.query.filter_by(bridge_name=_name).first() bl.bridge_name = _new_name bl.description = _desc bl.public_list = _public bl.tg = _tg br = BridgeRules.query.filter_by(bridge_name=_name).all() for b in br: b.bridge_name = _new_name db.session.commit() def bridge_delete(_name): #, _server): bl = BridgeList.query.filter_by(bridge_name=_name).first() db.session.delete(bl) sl = ServerList.query.all() for i in sl: delete_system_bridge(_name, i.name) db.session.commit() def generate_rules(_name): # generate UNIT list ## print('get rules') ## print(_name) xlx_p = xlxPeer.query.filter_by(server=_name).all() mmdvm_p = mmdvmPeer.query.filter_by(server=_name).all() all_m = MasterList.query.filter_by(server=_name).all() all_o = OBP.query.filter_by(server=_name).all() all_p = ProxyList.query.filter_by(server=_name).all() rules = BridgeRules.query.filter_by(server=_name).all() UNIT = [] BRIDGES = {} disabled = {} for i in all_m: if i.active == False: disabled[i.name] = i.name else: if i.enable_unit == True: UNIT.append(i.name) for i in all_p: if i.active == False: disabled[i.name] = i.name else: if i.enable_unit == True: n_systems = i.internal_stop_port - i.internal_start_port n_count = 0 while n_count < n_systems: UNIT.append(i.name + '-' + str(n_count)) n_count = n_count + 1 for i in all_o: if i.enabled == False: disabled[i.name] = i.name else: if i.enable_unit == True: UNIT.append(i.name) for i in xlx_p: if i.enabled == False: disabled[i.name] = i.name else: if i.enable_unit == True: UNIT.append(i.name) for i in mmdvm_p: if i.enabled == False: disabled[i.name] = i.name else: if i.enable_unit == True: UNIT.append(i.name) temp_dict = {} # populate dict with needed bridges for r in rules: ## print(r.bridge_name) ## b = BridgeRules.query.filter_by(server=_name).filter_by(server=_name).all() ## for d in temp_dict.items(): ## if r.bridge_name == d[0]: ## print('update rule') ## if r.bridge_name != d[0]: ## print('add dict entry and rule') temp_dict[r.bridge_name] = [] ## print(temp_dict) BRIDGES = temp_dict.copy() for r in temp_dict.items(): b = BridgeRules.query.filter_by(bridge_name=r[0]).filter_by(server=_name).all() for s in b: try: if s.system_name == disabled[s.system_name]: pass except: if s.timeout == '': timeout = 0 else: timeout = int(s.timeout) if s.proxy == True: p = ProxyList.query.filter_by(server=_name).filter_by(name=s.system_name).first() ## print(p.external_port) n_systems = p.internal_stop_port - p.internal_start_port n_count = 0 while n_count < n_systems: BRIDGES[r[0]].append({'SYSTEM': s.system_name + '-' + str(n_count), 'TS': s.ts, 'TGID': s.tg, 'ACTIVE': s.active, 'TIMEOUT': timeout, 'TO_TYPE': s.to_type, 'ON': ast.literal_eval(str('[' + s.on + ']')), 'OFF': ast.literal_eval(str('[4000,' + s.off + ']')), 'RESET': ast.literal_eval(str('[' + s.reset + ']'))}) n_count = n_count + 1 else: BRIDGES[r[0]].append({'SYSTEM': s.system_name, 'TS': s.ts, 'TGID': s.tg, 'ACTIVE': s.active, 'TIMEOUT': timeout, 'TO_TYPE': s.to_type, 'ON': ast.literal_eval(str('[' + s.on + ']')), 'OFF': ast.literal_eval(str('[' + s.off + ']')), 'RESET': ast.literal_eval(str('[' + s.reset + ']'))}) ## for d in b: ## print(b.system_name) ## if r.bridge_name == d[0]: ## print('update rule') ## if r.bridge_name != d[0]: ## print('add dict entry and rule') ## print(r.tg) ## print(BRIDGES) return [UNIT, BRIDGES] def server_get(_name): ## print(_name) #s = ServerList.query.filter_by(name=_name).first() # print(s.name) i = ServerList.query.filter_by(name=_name).first() ## print(i.name) s_config = {} s_config['GLOBAL'] = {} s_config['REPORTS'] = {} s_config['ALIASES'] = {} s_config['WEB_SERVICE'] = {} s_config['OTHER'] = {} s_config['GLOBAL'].update({ 'PATH': i.global_path, 'PING_TIME': i.global_ping_time, 'MAX_MISSED': i.global_max_missed, 'USE_ACL': i.global_use_acl, 'REG_ACL': i.global_reg_acl, 'SUB_ACL': i.global_sub_acl, 'TG1_ACL': i.global_tg1_acl, 'TG2_ACL': i.global_tg2_acl }) s_config['REPORTS'].update({ 'REPORT': i.report_enable, 'REPORT_INTERVAL': i.report_interval, 'REPORT_PORT': i.report_port, 'REPORT_CLIENTS': i.report_clients.split(',') }) s_config['ALIASES'].update({ 'TRY_DOWNLOAD':i.ai_try_download, 'PATH': i.ai_path, 'PEER_FILE': i.ai_peer_file, 'SUBSCRIBER_FILE': i.ai_subscriber_file, 'TGID_FILE': i.ai_tgid_file, 'PEER_URL': i.ai_peer_url, 'SUBSCRIBER_URL': i.ai_subs_url, 'STALE_TIME': i.ai_stale * 86400, }) s_config['WEB_SERVICE'].update({ 'SHORTEN_LENGTH': shorten_length, 'SHORTEN_SAMPLE': shorten_sample, 'EXTRA_1': extra_1, 'EXTRA_2': extra_2, 'EXTRA_INT_1': extra_int_1, 'EXTRA_INT_2': extra_int_2, 'APPEND_INT': append_int, 'SHORTEN_PASSPHRASE': i.um_shorten_passphrase, 'BURN_FILE': i.um_burn_file, 'BURN_INT': burn_int, }) s_config['OTHER'].update({ 'UNIT_TIME': i.unit_time, 'OTHER_OPTIONS': i.other_options }) ## print(s_config['REPORTS']) return s_config def masters_get(_name): ## # print(_name) #s = ServerList.query.filter_by(name=_name).first() # print(s.name) i = MasterList.query.filter_by(server=_name).filter_by(active=True).all() o = OBP.query.filter_by(server=_name).filter_by(enabled=True).all() p = ProxyList.query.filter_by(server=_name).filter_by(active=True).all() # print('get masters') master_config_list = {} ## master_config_list['SYSTEMS'] = {} # print(i) for m in i: ## print (m.name) master_config_list.update({m.name: { 'MODE': 'MASTER', 'ENABLED': m.active, 'USE_USER_MAN': m.enable_um, 'STATIC_APRS_POSITION_ENABLED': m.static_positions, 'REPEAT': m.repeat, 'MAX_PEERS': m.max_peers, 'IP': m.ip, 'PORT': m.port, 'PASSPHRASE': m.passphrase, #bytes(m.passphrase, 'utf-8'), 'GROUP_HANGTIME': m.group_hang_time, 'USE_ACL': m.use_acl, 'REG_ACL': m.reg_acl, 'SUB_ACL': m.sub_acl, 'TG1_ACL': m.tg1_acl, 'TG2_ACL': m.tg2_acl, 'OTHER_OPTIONS': m.other_options }}) master_config_list[m.name].update({'PEERS': {}}) for obp in o: ## print(type(obp.network_id)) master_config_list.update({obp.name: { 'MODE': 'OPENBRIDGE', 'ENABLED': obp.enabled, 'NETWORK_ID': obp.network_id, #int(obp.network_id).to_bytes(4, 'big'), 'IP': gethostbyname(obp.ip), 'PORT': obp.port, 'PASSPHRASE': obp.passphrase, #bytes(obp.passphrase.ljust(20,'\x00')[:20], 'utf-8'), 'TARGET_SOCK': (obp.target_ip, obp.target_port), 'TARGET_IP': gethostbyname(obp.target_ip), 'TARGET_PORT': obp.target_port, 'BOTH_SLOTS': obp.both_slots, 'USE_ACL': obp.use_acl, 'SUB_ACL': obp.sub_acl, 'TG1_ACL': obp.tg_acl, 'TG2_ACL': 'PERMIT:ALL', 'USE_ENCRYPTION': obp.obp_encryption, 'ENCRYPTION_KEY': obp.encryption_key, 'OTHER_OPTIONS': obp.other_options }}) for pr in p: master_config_list.update({pr.name: { 'MODE': 'PROXY', 'ENABLED': pr.active, 'EXTERNAL_PROXY_SCRIPT': pr.external_proxy, 'STATIC_APRS_POSITION_ENABLED': pr.static_positions, 'USE_USER_MAN': pr.enable_um, 'REPEAT': pr.repeat, 'PASSPHRASE': pr.passphrase, #bytes(pr.passphrase, 'utf-8'), 'EXTERNAL_PORT': pr.external_port, 'INTERNAL_PORT_START': pr.internal_start_port, 'INTERNAL_PORT_STOP': pr.internal_stop_port, 'GROUP_HANGTIME': pr.group_hang_time, 'USE_ACL': pr.use_acl, 'REG_ACL': pr.reg_acl, 'SUB_ACL': pr.sub_acl, 'TG1_ACL': pr.tg1_acl, 'TG2_ACL': pr.tg2_acl, 'OTHER_OPTIONS': pr.other_options }}) master_config_list[pr.name].update({'PEERS': {}}) # print(master_config_list) return master_config_list def add_system_rule(_bridge_name, _system_name, _ts, _tg, _active, _timeout, _to_type, _on, _off, _reset, _server): proxy = ProxyList.query.filter_by(server=_server).filter_by(name=_system_name).first() is_proxy = False try: if _system_name == proxy.name: is_proxy = True except: pass add_system = BridgeRules( bridge_name = _bridge_name, system_name = _system_name, ts = _ts, tg = _tg, active = _active, timeout = _timeout, to_type = _to_type, on = _on, off = _off, reset = _reset, server = _server, proxy = is_proxy ) db.session.add(add_system) db.session.commit() def edit_system_rule(_bridge_name, _system_name, _ts, _tg, _active, _timeout, _to_type, _on, _off, _reset, _server): proxy = ProxyList.query.filter_by(server=_server).filter_by(name=_system_name).first() is_proxy = False try: if _system_name == proxy.name: is_proxy = True except: pass r = BridgeRules.query.filter_by(system_name=_system_name).filter_by(bridge_name=_bridge_name).first() ## print('---') ## print(_system_name) ## print(_bridge_name) ## print(r) ## for i in r: ## print(i.name) ## add_system = BridgeRules( r.bridge_name = _bridge_name r.system_name = _system_name r.ts = _ts r.tg = _tg r.active = _active r.timeout = _timeout r.to_type = _to_type r.on = _on r.off = _off r.reset = _reset r.server = _server #r.public_list = _public_list r.proxy = is_proxy ## db.session.add(add_system) db.session.commit() def delete_system_bridge(_name, _server): dr = BridgeRules.query.filter_by(server=_server).filter_by(bridge_name=_name).all() for i in dr: db.session.delete(i) db.session.commit() def delete_system_rule(_name, _server, _system): dr = BridgeRules.query.filter_by(server=_server).filter_by(bridge_name=_name).filter_by(system_name=_system).first() db.session.delete(dr) db.session.commit() def server_edit(_name, _secret, _ip, _global_path, _global_ping_time, _global_max_missed, _global_use_acl, _global_reg_acl, _global_sub_acl, _global_tg1_acl, _global_tg2_acl, _ai_subscriber_file, _ai_try_download, _ai_path, _ai_peer_file, _ai_tgid_file, _ai_peer_url, _ai_subs_url, _ai_stale, _um_shorten_passphrase, _um_burn_file, _report_enable, _report_interval, _report_port, _report_clients, _unit_time, _notes, _dash_url, _public_notes, _other_options): print(_public_notes) s = ServerList.query.filter_by(name=_name).first() # print(_name) if _secret == '': s.secret = s.secret else: s.secret = hashlib.sha256(_secret.encode()).hexdigest() s.ip = _ip s.global_path =_global_path s.global_ping_time = _global_ping_time s.global_max_missed = _global_max_missed s.global_use_acl = _global_use_acl s.global_reg_acl = _global_reg_acl s.global_sub_acl = _global_sub_acl s.global_tg1_acl = _global_tg1_acl s.global_tg2_acl = _global_tg2_acl s.ai_try_download = _ai_try_download s.ai_path = _ai_path s.ai_peer_file = _ai_peer_file s.ai_subscriber_file = _ai_subscriber_file s.ai_tgid_file = _ai_tgid_file s.ai_peer_url = _ai_peer_url s.ai_subs_url = _ai_subs_url s.ai_stale = _ai_stale # Pull from config file for now ## um_append_int = db.Column(db.Integer(), primary_key=False, server_default='2') s.um_shorten_passphrase = _um_shorten_passphrase s.um_burn_file = _um_burn_file # Pull from config file for now ## um_burn_int = db.Column(db.Integer(), primary_key=False, server_default='6') s.report_enable = _report_enable s.report_interval = _report_interval s.report_port = _report_port s.report_clients = _report_clients s.unit_time = int(_unit_time) s.notes = _notes s.dash_url = _dash_url s.public_notes = _public_notes s.other_options = _other_options db.session.commit() def master_delete(_mode, _server, _name): if _mode == 'MASTER': m = MasterList.query.filter_by(server=_server).filter_by(name=_name).first() if _mode == 'PROXY': m = ProxyList.query.filter_by(server=_server).filter_by(name=_name).first() if _mode == 'OBP': m = OBP.query.filter_by(server=_server).filter_by(name=_name).first() dr = BridgeRules.query.filter_by(server=_server).filter_by(system_name=_name).all() for d in dr: db.session.delete(d) db.session.delete(m) db.session.commit() def edit_master(_mode, _name, _server, _static_positions, _repeat, _active, _max_peers, _ip, _port, _enable_um, _passphrase, _group_hang_time, _use_acl, _reg_acl, _sub_acl, _tg1_acl, _tg2_acl, _enable_unit, _notes, _external_proxy, _int_start_port, _int_stop_port, _network_id, _target_ip, _target_port, _both_slots, _public, _other_options, _encryption_key, _obp_encryption): ## print(_mode) #### print(_server) ## print(_name) if _mode == 'MASTER': ## print(_name) m = MasterList.query.filter_by(server=_server).filter_by(name=_name).first() ## m.name = _name, m.static_positions = _static_positions m.repeat = _repeat m.active = _active m.max_peers = int(_max_peers) m.ip = _ip m.port = int(_port) m.enable_um = _enable_um m.passphrase = str(_passphrase) m.group_hang_time = int(_group_hang_time) m.use_acl = _use_acl m.reg_acl = _reg_acl m.sub_acl = _sub_acl m.tg1_acl = _tg1_acl m.tg2_acl = _tg2_acl m.enable_unit = _enable_unit ## m.server = _server m.notes = _notes m.public_list = _public m.other_options = _other_options db.session.commit() if _mode == 'OBP': # print(_enable_unit) ## print(enable_unit) o = OBP.query.filter_by(server=_server).filter_by(name=_name).first() o.enabled = _active o.network_id = _network_id o.ip = _ip o.port = _port o.passphrase = _passphrase o.target_ip = _target_ip o.target_port = _target_port o.both_slots = _both_slots o.use_acl = _use_acl o.sub_acl = _sub_acl o.tg1_acl = _tg1_acl o.tg2_acl = _tg2_acl o.enable_unit = _enable_unit o.notes = _notes o.other_options = _other_options o.encryption_key = _encryption_key o.obp_encryption = _obp_encryption db.session.commit() if _mode == 'PROXY': ## print(_int_start_port) ## print(_int_stop_port) p = ProxyList.query.filter_by(server=_server).filter_by(name=_name).first() p.name = _name p.static_positions = _static_positions p.repeat = _repeat p.active = _active p.enable_um = _enable_um p.passphrase = _passphrase p.external_proxy = _external_proxy external_port = int(_port) p.group_hang_time = int(_group_hang_time) p.internal_start_port = _int_start_port p.internal_stop_port = _int_stop_port p.use_acl = _use_acl p.reg_acl = _reg_acl p.sub_acl = _sub_acl p.tg1_acl = _tg1_acl p.tg2_acl = _tg2_acl p.enable_unit = _enable_unit p.server = _server p.notes = _notes p.public_list = _public p.other_options = _other_options db.session.commit() ## add_proxy = ProxyList( ## name = _name, ## static_positions = _static_positions, ## repeat = _repeat, ## active = _active, ## enable_um = _enable_um, ## passphrase = _passphrase, ## external_proxy = _external_proxy, ## group_hang_time = int(_group_hang_time), ## internal_start_port = int(_int_start_port), ## internal_stop_port = int(_int_stop_port), ## use_acl = _use_acl, ## reg_acl = _reg_acl, ## sub_acl = _sub_acl, ## tg1_acl = _tg1_acl, ## tg2_acl = _tg2_acl, ## enable_unit = _enable_unit, ## server = _server, ## notes = _notes ## ) ## db.session.add(add_master) def add_master(_mode, _name, _server, _static_positions, _repeat, _active, _max_peers, _ip, _port, _enable_um, _passphrase, _group_hang_time, _use_acl, _reg_acl, _sub_acl, _tg1_acl, _tg2_acl, _enable_unit, _notes, _external_proxy, _int_start_port, _int_stop_port, _network_id, _target_ip, _target_port, _both_slots, _public, _other_options, _encryption_key, _obp_encryption): # print(_mode) if _mode == 'MASTER': add_master = MasterList( name = _name, static_positions = _static_positions, repeat = _repeat, active = _active, max_peers = int(_max_peers), ip = _ip, port = int(_port), enable_um = _enable_um, passphrase = _passphrase, group_hang_time = int(_group_hang_time), use_acl = _use_acl, reg_acl = _reg_acl, sub_acl = _sub_acl, tg1_acl = _tg1_acl, tg2_acl = _tg2_acl, enable_unit = _enable_unit, server = _server, notes = _notes, public_list = _public, other_options = _other_options ) db.session.add(add_master) db.session.commit() if _mode == 'PROXY': add_proxy = ProxyList( name = _name, static_positions = _static_positions, repeat = _repeat, active = _active, enable_um = _enable_um, passphrase = _passphrase, external_proxy = _external_proxy, external_port = int(_port), group_hang_time = int(_group_hang_time), internal_start_port = int(_int_start_port), internal_stop_port = int(_int_stop_port), use_acl = _use_acl, reg_acl = _reg_acl, sub_acl = _sub_acl, tg1_acl = _tg1_acl, tg2_acl = _tg2_acl, enable_unit = _enable_unit, server = _server, notes = _notes, public_list = _public, other_options = _other_options ) db.session.add(add_proxy) db.session.commit() if _mode == 'OBP': # print(_name) # print(_network_id) add_OBP = OBP( name = _name, enabled = _active, network_id = _network_id, # ip = _ip, port = _port, passphrase = _passphrase, target_ip = _target_ip,# target_port = _target_port,# both_slots = _both_slots,# use_acl = _use_acl, sub_acl = _sub_acl, tg_acl = _tg1_acl, enable_unit = _enable_unit, server = _server, notes = _notes, other_options = _other_options, encryption_key = _encryption_key, obp_encryption = _obp_encryption ) db.session.add(add_OBP) db.session.commit() def server_add(_name, _secret, _ip, _global_path, _global_ping_time, _global_max_missed, _global_use_acl, _global_reg_acl, _global_sub_acl, _global_tg1_acl, _global_tg2_acl, _ai_subscriber_file, _ai_try_download, _ai_path, _ai_peer_file, _ai_tgid_file, _ai_peer_url, _ai_subs_url, _ai_stale, _um_shorten_passphrase, _um_burn_file, _report_enable, _report_interval, _report_port, _report_clients, _unit_time, _notes, _dash_url, _public_notes, _other_options): add_server = ServerList( name = _name, secret = hashlib.sha256(_secret.encode()).hexdigest(), ## public_list = _public_list, ip = _ip, global_path =_global_path, global_ping_time = _global_ping_time, global_max_missed = _global_max_missed, global_use_acl = _global_use_acl, global_reg_acl = _global_reg_acl, global_sub_acl = _global_sub_acl, global_tg1_acl = _global_tg1_acl, global_tg2_acl = _global_tg2_acl, ai_try_download = _ai_try_download, ai_path = _ai_path, ai_peer_file = _ai_peer_file, ai_subscriber_file = _ai_subscriber_file, ai_tgid_file = _ai_tgid_file, ai_peer_url = _ai_peer_url, ai_subs_url = _ai_subs_url, ai_stale = _ai_stale, # Pull from config file for now ## um_append_int = db.Column(db.Integer(), primary_key=False, server_default='2') um_shorten_passphrase = _um_shorten_passphrase, um_burn_file = _um_burn_file, # Pull from config file for now ## um_burn_int = db.Column(db.Integer(), primary_key=False, server_default='6') report_enable = _report_enable, report_interval = _report_interval, report_port = _report_port, report_clients = _report_clients, unit_time = int(_unit_time), notes = _notes, dash_url = _dash_url, public_notes = _public_notes, other_options = _other_options ) db.session.add(add_server) db.session.commit() def peer_add(_mode, _name, _enabled, _loose, _ip, _port, _master_ip, _master_port, _passphrase, _callsign, _radio_id, _rx, _tx, _tx_power, _cc, _lat, _lon, _height, _loc, _desc, _slots, _url, _grp_hang, _xlx_mod, _opt, _use_acl, _sub_acl, _1_acl, _2_acl, _svr, _enable_unit, _notes, _other_options): if _mode == 'xlx': xlx_peer_add = xlxPeer( name = _name, enabled = _enabled, loose = _loose, ip = _ip, port = _port, master_ip = _master_ip, master_port = _master_port, passphrase = _passphrase, callsign = _callsign, radio_id = _radio_id, rx_freq = _rx, tx_freq = _tx, tx_power = _tx_power, color_code = _cc, latitude = _lat, longitude = _lon, height = _height, location = _loc, description = _desc, slots = _slots, xlxmodule = _xlx_mod, url = _url, enable_unit = _enable_unit, group_hangtime = _grp_hang, use_acl = _use_acl, sub_acl = _sub_acl, tg1_acl = _1_acl, tg2_acl = _2_acl, server = _svr, notes = _notes, other_options = _other_options ) db.session.add(xlx_peer_add) db.session.commit() if _mode == 'mmdvm': mmdvm_peer_add = mmdvmPeer( name = _name, enabled = _enabled, loose = _loose, ip = _ip, port = _port, master_ip = _master_ip, master_port = _master_port, passphrase = _passphrase, callsign = _callsign, radio_id = _radio_id, rx_freq = _rx, tx_freq = _tx, tx_power = _tx_power, color_code = _cc, latitude = _lat, longitude = _lon, height = _height, location = _loc, description = _desc, slots = _slots, url = _url, enable_unit = _enable_unit, group_hangtime = _grp_hang, use_acl = _use_acl, sub_acl = _sub_acl, tg1_acl = _1_acl, tg2_acl = _2_acl, server = _svr, notes = _notes, other_options = _other_options ) db.session.add(mmdvm_peer_add) db.session.commit() def peer_edit(_mode, _server, _name, _enabled, _loose, _ip, _port, _master_ip, _master_port, _passphrase, _callsign, _radio_id, _rx, _tx, _tx_power, _cc, _lat, _lon, _height, _loc, _desc, _slots, _url, _grp_hang, _xlx_mod, _opt, _use_acl, _sub_acl, _1_acl, _2_acl, _enable_unit, _notes, _other_options): ## print(_mode) if _mode == 'mmdvm': ## print(_server) ## print(_name) ## print(_name) ## s = mmdvmPeer.query.filter_by(server=_server).filter_by(name=_name).first() p = mmdvmPeer.query.filter_by(server=_server).filter_by(name=_name).first() p.enabled = _enabled p.loose = _loose p.ip = _ip p.port = _port p.master_ip = _master_ip p.master_port = _master_port p.passphrase = _passphrase p.callsign = _callsign p.radio_id = _radio_id p.rx_freq = _rx p.tx_freq = _tx p.tx_power = _tx_power p.color_code = _cc p.latitude = _lat p.longitude = _lon p.height = _height p.location = _loc p.description = _desc p.slots = _slots p.url = _url p.enable_unit = _enable_unit p.group_hangtime = _grp_hang p.options = _opt p.use_acl = _use_acl p.sub_acl = _sub_acl p.tg1_acl = _1_acl p.tg2_acl = _2_acl p.notes = _notes p.other_options = _other_options if _mode == 'xlx': ## print(type(_server)) ## print(type(_name)) ## print(type(_enabled)) ## print((_enable_unit)) ## print(type(_use_acl)) #### print(_port) ## s = mmdvmPeer.query.filter_by(server=_server).filter_by(name=_name).first() p = xlxPeer.query.filter_by(server=_server).filter_by(name=_name).first() # print(type(p.enable_unit)) p.enabled = _enabled p.loose = _loose p.ip = _ip p.port = _port p.master_ip = _master_ip p.master_port = _master_port p.passphrase = _passphrase p.callsign = _callsign p.radio_id = _radio_id p.rx_freq = _rx p.tx_freq = _tx p.tx_power = _tx_power p.color_code = _cc p.latitude = _lat p.longitude = _lon p.height = _height p.location = _loc p.description = _desc p.slots = _slots p.url = _url p.options = _opt p.enable_unit = _enable_unit p.xlxmodule = _xlx_mod p.group_hangtime = _grp_hang p.use_acl = _use_acl p.sub_acl = _sub_acl p.tg1_acl = _1_acl p.tg2_acl = _2_acl p.notes = _notes p.other_options = _other_options db.session.commit() # Test server configs @app.route('/manage_servers', methods=['POST', 'GET']) @login_required @roles_required('Admin') def edit_server_db(): # Edit server if request.args.get('save_mode'):# == 'new' and request.form.get('server_name'): ## _port = int(request.form.get('server_port')) _global_ping_time = int(request.form.get('ping_time')) _global_max_missed = int(request.form.get('max_missed')) _ai_stale = int(request.form.get('stale_days')) _report_interval = int(request.form.get('report_interval')) _report_port = int(request.form.get('report_port')) _global_use_acl = False _ai_try_download = False _um_shorten_passphrase = False _report_enabled = False if request.form.get('use_acl') == 'True': _global_use_acl = True if request.form.get('aliases_enabled') == 'True': _ai_try_download = True if request.form.get('um_shorten_passphrase') == 'True': _um_shorten_passphrase = True if request.form.get('report') == 'True': _report_enabled = True ## if request.form.get('public_list') == 'True': ## public_list = True ## else: ## _global_use_acl = False ## _ai_try_download = False ## _um_shorten_passphrase = False ## _report_enabled = False ## public_list = False if request.args.get('save_mode') == 'new': if request.form.get('server_name') == '': content = '''

Server can't have blank name.

Redirecting in 3 seconds.

''' else: server_add(request.form.get('server_name'), request.form.get('server_secret'), request.form.get('server_ip'), request.form.get('global_path'), _global_ping_time, _global_max_missed, _global_use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('global_ts1_acl'), request.form.get('global_ts2_acl'), request.form.get('sub_file'), _ai_try_download, request.form.get('aliases_path'), request.form.get('peer_file'), request.form.get('tgid_file'), request.form.get('peer_url'), request.form.get('sub_url'), _ai_stale, _um_shorten_passphrase, request.form.get('um_burn_file'), _report_enabled, _report_interval, _report_port, request.form.get('report_clients'), request.form.get('unit_time'), request.form.get('notes'), request.form.get('dash_url'), request.form.get('public_notes'), request.form.get('other_options')) content = '''

Server saved.

Redirecting in 3 seconds.

''' if request.args.get('save_mode') == 'edit': ## print(_ai_try_download) ## print(request.args.get('server')) server_edit(request.args.get('server'), request.form.get('server_secret'), request.form.get('server_ip'), request.form.get('global_path'), _global_ping_time, _global_max_missed, _global_use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('global_ts1_acl'), request.form.get('global_ts2_acl'), request.form.get('sub_file'), _ai_try_download, request.form.get('aliases_path'), request.form.get('peer_file'), request.form.get('tgid_file'), request.form.get('peer_url'), request.form.get('sub_url'), _ai_stale, _um_shorten_passphrase, request.form.get('um_burn_file'), _report_enabled, _report_interval, _report_port, request.form.get('report_clients'), request.form.get('unit_time'), request.form.get('notes'), request.form.get('dash_url'), request.form.get('public_notes'), request.form.get('other_options')) content = '''

Server changed.

Redirecting in 3 seconds.

''' elif request.args.get('delete_server'): server_delete(request.args.get('delete_server')) content = '''

Server deleted.

Redirecting in 3 seconds.

''' elif request.args.get('edit_server'): s = ServerList.query.filter_by(name=request.args.get('edit_server')).first() content = '''

 

Delete server

Import Rules

 

Server

 Server Name:  ''' + str(s.name) + '''
 Server Secret:  
 Dashboard URL:  
 Host (IP/DNS, for listing on passphrase page):  
 Unit Call Timeout (minutes):  
 Misc Options:  
 Notes:  
 Public Notes:  

Global

 Path:  
 Ping Time:  
 Max Missed:  
 Use ACLs:  
 Regular ACLs:  
 Subscriber ACSs:  
 Timeslot 1 ACLs:  
 Timeslot 2 ACLs:  

 

Reports

 Enable:  
 Interval:  
 Port:  
 Clients:  

 

Aliases

 Download:  
 Path:  
 Peer File:  
 Subscriber File:  
 Talkgroup ID File:  
 Peer URL:  
 Subscriber URL:  
 Stale time(days):  

 

User Manager

 Use short passphrase:
 Burned IDs File:  

 

 

''' # Add new server elif request.args.get('add'): # == 'yes': content = '''

 

Server

 Server Name:  
 Server Secret:  
 Dashboard URL:  
 Host (IP/DNS):  
 Unit Call Timeout (minutes):  
 Misc Options:  
 Notes (HTML OK):  
 Public Notes (HTML OK):  

Global

 Path:  
 Ping Time:  
 Max Missed:  
 Use ACLs:  
 Regular ACLs:  
 Subscriber ACSs:  
 Timeslot 1 ACLs:  
 Timeslot 2 ACLs:  

 

Reports

 Enable:  
 Interval:  
 Port:  
 Clients:  

 

Aliases

 Download:  
 Path:  
 Peer File:  
 Subscriber File:  
 Talkgroup ID File:  
 Peer URL:  
 Subscriber URL:  
 Stale time(days):  

 

User Manager

 Use short passphrase:
 Burned IDs File:  

 

 

''' else: all_s = ServerList.query.all() pl = Misc.query.filter_by(field_1='ping_list').first() ping_list = ast.literal_eval(pl.field_2) p_list = '''

View/Edit Servers

 

''' for s in all_s: try: if time.time() - ping_list[s.name] < 30: svr_status = '''''' elif time.time() - ping_list[s.name] <= 300: svr_status = '''''' elif time.time() - ping_list[s.name] > 300: svr_status = '''''' else: svr_status = '''''' except: svr_status = '''''' p_list = p_list + ''' \n ''' p_list = p_list + '''
Name
Notes
''' + svr_status + ''' ''' + s.notes + '''
''' content = p_list return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/manage_peers', methods=['POST', 'GET']) @login_required @roles_required('Admin') def test_peer_db(): if request.args.get('save_mode'): if request.form.get('enabled') == 'true': peer_enabled = True ## if request.form.get('loose') == 'true': ## peer_loose = True if request.form.get('use_acl') == 'true': use_acl = True if request.form.get('enable_unit') == 'True': unit_enabled = True ## else: ## peer_loose = False peer_enabled = False use_acl = False unit_enabled = False peer_loose = True ## print(request.form.get('enable_unit')) ## print(enable_unit) if request.form.get('name_text') == '': content = '''

Peer can't have blank name.

Redirecting in 3 seconds.

''' else: if request.args.get('save_mode') == 'mmdvm_peer': peer_add('mmdvm', request.form.get('name_text'), peer_enabled, peer_loose, request.form.get('ip'), request.form.get('port'), request.form.get('master_ip'), request.form.get('master_port'), request.form.get('passphrase'), request.form.get('callsign'), request.form.get('radio_id'), request.form.get('rx'), request.form.get('tx'), request.form.get('tx_power'), request.form.get('cc'), request.form.get('lat'), request.form.get('lon'), request.form.get('height'), request.form.get('location'), request.form.get('description'), request.form.get('slots'), request.form.get('url'), request.form.get('group_hangtime'), 'MMDVM', request.form.get('options'), use_acl, request.form.get('sub_acl'), request.form.get('tgid_ts1_acl'), request.form.get('tgid_ts2_acl'), request.form.get('server'), unit_enabled, request.form.get('notes'), request.form.get('other_options')) content = '''

MMDVM PEER saved.

Redirecting in 3 seconds.

''' if request.args.get('save_mode') == 'xlx_peer': peer_add('xlx', request.form.get('name_text'), peer_enabled, peer_loose, request.form.get('ip'), request.form.get('port'), request.form.get('master_ip'), request.form.get('master_port'), request.form.get('passphrase'), request.form.get('callsign'), request.form.get('radio_id'), request.form.get('rx'), request.form.get('tx'), request.form.get('tx_power'), request.form.get('cc'), request.form.get('lat'), request.form.get('lon'), request.form.get('height'), request.form.get('location'), request.form.get('description'), request.form.get('slots'), request.form.get('url'), request.form.get('group_hangtime'), request.form.get('xlxmodule'), request.form.get('options'), use_acl, request.form.get('sub_acl'), request.form.get('tgid_ts1_acl'), request.form.get('tgid_ts2_acl'), request.form.get('server'), unit_enabled, request.form.get('notes'), request.form.get('other_options')) content = '''

XLX PEER saved.

Redirecting in 3 seconds.

''' elif request.args.get('add') == 'mmdvm' or request.args.get('add') == 'xlx': s = ServerList.query.all() if request.args.get('add') == 'mmdvm': mode = 'MMDVM' submit_link = 'manage_peers?save_mode=mmdvm_peer' xlx_module = '' if request.args.get('add') == 'xlx': xlx_module = '''  XLX Module:   ''' mode = 'XLX' submit_link = 'manage_peers?save_mode=xlx_peer' server_options = '' for i in s: server_options = server_options + '''\n''' content = '''

 

Add an ''' + mode + ''' peer

Notice: Before connecting this server to another network, such as Brandmeister, be sure you have permission.
Connecting servers together via PEER connection can cause problems such as audio looping.
OpenBridge connections are designed for server to server connections.

 

''' + xlx_module + '''
Assign to Server:  
Connection Name:  
 Active:  
 IP:  
 Port:  
 Passphrase:  
 Master IP:  
 Master Port:  
 Callsign:  
 Radio ID:  
 Transmit Frequency:  
 Receive Frequency:  
 Transmit Power:  
 Color Code:  
 Slots:  
 Latitude:  
 Longitude:  
 Height  
 Location:  
 Description:  
 URL:  
 Group Hangtime:  
 Options:  
 Enable Unit Calls:  
 Use ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Misc Options:  
 Notes:  

 

''' ## elif request.args.get('edit_server') and request.args.get('edit_peer') and request.args.get('mode') == 'mmdvm': elif request.args.get('delete_peer') and request.args.get('peer_server'): peer_delete(request.args.get('mode'), request.args.get('peer_server'), request.args.get('delete_peer')) content = '''

PEER deleted.

Redirecting in 3 seconds.

''' elif request.args.get('edit_mmdvm') == 'save' or request.args.get('edit_xlx') == 'save': peer_enabled = False use_acl = False peer_loose = True unit_enabled = False if request.form.get('enabled') == 'true': peer_enabled = True ## if request.form.get('loose') == 'true': ## peer_loose = True if request.form.get('use_acl') == 'True': use_acl = True if request.form.get('enable_unit') == 'True': unit_enabled = True ## else: ## peer_loose = False ## print((unit_enabled)) ## print(type(peer_enabled)) ## print(type(use_acl)) if request.args.get('edit_mmdvm') == 'save': peer_edit('mmdvm', request.args.get('server'), request.args.get('name'), peer_enabled, peer_loose, request.form.get('ip'), request.form.get('port'), request.form.get('master_ip'), request.form.get('master_port'), request.form.get('passphrase'), request.form.get('callsign'), request.form.get('radio_id'), request.form.get('rx'), request.form.get('tx'), request.form.get('tx_power'), request.form.get('cc'), request.form.get('lat'), request.form.get('lon'), request.form.get('height'), request.form.get('location'), request.form.get('description'), request.form.get('slots'), request.form.get('url'), request.form.get('group_hangtime'), 'MMDVM', request.form.get('options'), use_acl, request.form.get('sub_acl'), request.form.get('tgid_ts1_acl'), request.form.get('tgid_ts2_acl'), unit_enabled, request.form.get('notes'), request.form.get('other_options')) content = '''

MMDVM PEER changed.

Redirecting in 3 seconds.

''' if request.args.get('edit_xlx') == 'save': peer_edit('xlx', request.args.get('server'), request.args.get('name'), peer_enabled, peer_loose, request.form.get('ip'), request.form.get('port'), request.form.get('master_ip'), request.form.get('master_port'), request.form.get('passphrase'), request.form.get('callsign'), request.form.get('radio_id'), request.form.get('rx'), request.form.get('tx'), request.form.get('tx_power'), request.form.get('cc'), request.form.get('lat'), request.form.get('lon'), request.form.get('height'), request.form.get('location'), request.form.get('description'), request.form.get('slots'), request.form.get('url'), request.form.get('group_hangtime'), request.form.get('xlxmodule'), request.form.get('options'), use_acl, request.form.get('sub_acl'), request.form.get('tgid_ts1_acl'), request.form.get('tgid_ts2_acl'), unit_enabled, request.form.get('notes'), request.form.get('other_options')) content = '''

XLX PEER changed.

Redirecting in 3 seconds.

''' elif request.args.get('server') and request.args.get('peer_name') and request.args.get('mode'): # and request.args.get('edit_peer') and request.args.get('mode') == 'mmdvm': if request.args.get('mode') == 'mmdvm': p = mmdvmPeer.query.filter_by(server=request.args.get('server')).filter_by(name=request.args.get('peer_name')).first() xlx_module = '' mode = "MMDVM" form_submit = '''
''' if request.args.get('mode') == 'xlx': p = xlxPeer.query.filter_by(server=request.args.get('server')).filter_by(name=request.args.get('peer_name')).first() form_submit = '''''' xlx_module = '''  XLX Module:   ''' mode = "XLX" content = '''

 

View/Edit an ''' + mode + ''' peer

Delete peer

''' + form_submit + ''' ''' + xlx_module + '''
Connection Name:  ''' + str(p.name) + '''
 Active:  
 IP:  
 Port:  
 Passphrase:  
 Master IP:  
 Master Port:  
 Callsign:  
 Radio ID:  
 Transmit Frequency:  
 Receive Frequency:  
 Transmit Power:  
 Color Code:  
 Slots:  
 Latitude:  
 Longitude:  
 Height  
 Location:  
 Description:  
 URL:  
 Group Call Hangtime:  
 Options:  
 Enable Unit Calls:  
 Use ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Misc Options:  
 Notes:  

 

 

''' else: all_s = ServerList.query.all() p_list = '' for s in all_s: # print(s.name) p_list = p_list + '''

Server: ''' + str(s.name) + '''

\n ''' all_p = mmdvmPeer.query.filter_by(server=s.name).all() all_x = xlxPeer.query.filter_by(server=s.name).all() for p in all_p: p_list = p_list + ''' ''' for x in all_x: p_list = p_list + ''' ''' p_list = p_list + '''
Name Mode Notes
''' + str(p.name) + ''' MMDVM ''' + p.notes + '''
''' + str(x.name) + ''' XLX ''' + x.notes + '''
\n''' content = '''

View/Edit Peers

Add MMDVM peer Add XLX peer

 

''' + p_list return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/manage_masters', methods=['POST', 'GET']) @login_required @roles_required('Admin') def manage_masters(): #PROXY if request.args.get('proxy_save'): active = False use_acl = False enable_unit = False repeat = True aprs_pos = False enable_um = True external_proxy = False public = False if request.form.get('enable_um') == 'False': enable_um = False if request.form.get('aprs_pos') == 'True': aprs_pos = True if request.form.get('enabled') == 'True': active = True if request.form.get('use_acl') == 'True': use_acl = True if request.form.get('enable_unit') == 'True': enable_unit = True if request.form.get('repeat') == 'False': repeat = False if request.form.get('external_proxy') == 'True': external_proxy = True if request.form.get('public_list') == 'True': public = True if request.args.get('proxy_save') == 'add': if request.form.get('name_text') == '': content = '''

PROXY can't have blank name.

Redirecting in 3 seconds.

''' else: add_master('PROXY', request.form.get('name_text'), request.form.get('server'), aprs_pos, repeat, active, 0, request.form.get('ip'), request.form.get('external_port'), enable_um, request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('ts1_acl'), request.form.get('ts2_acl'), enable_unit, request.form.get('notes'), external_proxy, request.form.get('int_port_start'), request.form.get('int_port_stop'), '', '', '', '', public, request.form.get('other_options'), '', '') content = '''

PROXY saved.

Redirecting in 3 seconds.

''' elif request.args.get('proxy_save') == 'edit': ## print(request.args.get('name')) edit_master('PROXY', request.args.get('name'), request.args.get('server'), aprs_pos, repeat, active, 0, request.form.get('ip'), request.form.get('external_port'), enable_um, request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('ts1_acl'), request.form.get('ts2_acl'), enable_unit, request.form.get('notes'), external_proxy, request.form.get('int_port_start'), request.form.get('int_port_stop'), '', '', '', '', public, request.form.get('other_options'), '', '') content = '''

PROXY changed.

Redirecting in 3 seconds.

''' elif request.args.get('proxy_save') == 'delete': master_delete('PROXY', request.args.get('server'), request.args.get('name')) content = '''

PROXY deleted.

Redirecting in 3 seconds.

''' # OBP elif request.args.get('OBP_save'): enabled = False use_acl = False enable_unit = False both_slots = True obp_encryption = False if request.form.get('obp_encryption') == 'True': obp_encryption = True if request.form.get('enabled') == 'True': enabled = True if request.form.get('use_acl') == 'True': use_acl = True if request.form.get('enable_unit') == 'True': enable_unit = True if request.form.get('both_slots') == 'False': both_slots = False if request.args.get('OBP_save') == 'add': if request.form.get('name_text') == '': content = '''

OpenBridge connection can't have blank name.

Redirecting in 3 seconds.

''' else: add_master('OBP', request.form.get('name_text'), request.form.get('server'), '', '', enabled, request.form.get('max_peers'), request.form.get('ip'), request.form.get('port'), '', request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('tg_acl'), '', enable_unit, request.form.get('notes'), '', '', '', request.form.get('network_id'), request.form.get('target_ip'), request.form.get('target_port'), both_slots, '', request.form.get('other_options'), request.form.get('encryption_key'), obp_encryption) content = '''

OpenBridge connection saved.

Redirecting in 3 seconds.

''' elif request.args.get('OBP_save') == 'edit': edit_master('OBP', request.args.get('name'), request.args.get('server'), '', '', enabled, request.form.get('max_peers'), request.form.get('ip'), request.form.get('port'), '', request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('tg_acl'), '', enable_unit, request.form.get('notes'), '', '', '', request.form.get('network_id'), request.form.get('target_ip'), request.form.get('target_port'), both_slots, '', request.form.get('other_options'), request.form.get('encryption_key'), obp_encryption) content = '''

OpenBridge connection changed.

Redirecting in 3 seconds.

''' elif request.args.get('OBP_save') == 'delete': master_delete('OBP', request.args.get('server'), request.args.get('name')) content = '''

OpenBridge connection deleted.

Redirecting in 3 seconds.

''' # MASTER elif request.args.get('master_save'): aprs_pos = False repeat = False active = False use_acl = False enable_um = False enable_unit = False public = False if request.form.get('aprs_pos') == 'True': aprs_pos = True if request.form.get('repeat') == 'True': repeat = True if request.form.get('enabled') == 'True': active = True if request.form.get('use_acl') == 'True': use_acl = True if request.form.get('enable_um') == 'True': enable_um = True if request.form.get('enable_unit') == 'True': enable_unit = True if request.form.get('public_list') == 'True': public = True if request.args.get('master_save') == 'add': if request.form.get('name_text') == '': content = '''

MASTER can't have blank name.

Redirecting in 3 seconds.

''' else: add_master('MASTER', request.form.get('name_text'), request.form.get('server'), aprs_pos, repeat, active, request.form.get('max_peers'), request.form.get('ip'), request.form.get('port'), enable_um, request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('ts1_acl'), request.form.get('ts2_acl'), enable_unit, request.form.get('notes'), '', '', '', '', '', '', '', public, request.form.get('other_options'), '', '') content = '''

MASTER saved.

Redirecting in 3 seconds.

''' elif request.args.get('master_save') == 'edit': edit_master('MASTER', request.args.get('name'), request.args.get('server'), aprs_pos, repeat, active, request.form.get('max_peers'), request.form.get('ip'), request.form.get('port'), enable_um, request.form.get('passphrase'), request.form.get('group_hangtime'), use_acl, request.form.get('reg_acl'), request.form.get('sub_acl'), request.form.get('ts1_acl'), request.form.get('ts2_acl'), enable_unit, request.form.get('notes'), '', '', '', '', '', '', '', public, request.form.get('other_options'), '', '') content = '''

MASTER changed.

Redirecting in 3 seconds.

''' elif request.args.get('master_save') == 'delete': master_delete('MASTER', request.args.get('server'), request.args.get('name')) content = '''

MASTER deleted.

Redirecting in 3 seconds.

''' elif request.args.get('add_OBP'): s = ServerList.query.all() server_options = '' for i in s: server_options = server_options + '''\n''' content = '''

 

Add an OpenBridge Connection

 

 Name:  
 Assign to Server:  
 Active:  
 IP:  
 Port:  
 Passphrase:  
 Network ID:  
 Target IP:  
 Target Port:  
 Use ACLs:  
 Subscriber ACLs:  
 Talkgroup ACLs:  
 Use Both Slots:  
 Enable Unit Calls:  
 Use Encryption:  
 Encryption_key:  
 Misc Options:  
 Notes:  

 

 

''' elif request.args.get('edit_proxy'): # print(request.args.get('server')) # print(request.args.get('edit_proxy')) p = ProxyList.query.filter_by(server=request.args.get('server')).filter_by(name=request.args.get('edit_proxy')).first() content = '''

 

View/Edit Proxy

Delete Proxy

 Name:  ''' + str(p.name) + '''
 Active:  
 Repeat:  
 External Proxy Script:  
 Static APRS positions:  
 User Manager for login:  
 External Port:  
 Internal Port Start:  
 Internal Port Stop:  
 Passphrase:  
 Group Hangtime:  
 Use ACLs:  
 Register ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Enable Unit Calls:  
 Public List:  
 Misc Options:  
 Notes:  

 

 

''' elif request.args.get('add_proxy'): s = ServerList.query.all() server_options = '' for i in s: server_options = server_options + '''\n''' content = '''

 

Add a PROXY

 

Assign to Server:  
 Name:  
 Active:  
 Repeat:  
 External Proxy Script:  
 Static APRS positions:  
 User Manager for login:  
 IP:  
 External Port:  
 Internal Port Start (lower than stop port):  
 Internal Port Stop:  
 Passphrase:  
 Group Hangtime:  
 Use ACLs:  
 Register ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Enable Unit Calls:  
 Public List:  
 Misc Options:  
 Notes:  

 

 

''' elif request.args.get('add_master'): s = ServerList.query.all() server_options = '' for i in s: server_options = server_options + '''\n''' content = '''

 

Add an MASTER

 

Assign to Server:  
 Name:  
 Active:  
 Repeat:  
 Max Peers:  
 Static APRS positions:  
 User Manager for login:  
 IP:  
 PORT:  
 Passphrase:  
 Group Hangtime:  
 Use ACLs:  
 Register ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Enable Unit Calls:  
 Public List:  
 Misc Options:  
 Notes:  

 

 

''' elif request.args.get('edit_OBP'): ## print(request.args.get('server')) ## print(request.args.get('edit_OBP')) ## s = ServerList.query.all() o = OBP.query.filter_by(server=request.args.get('server')).filter_by(name=request.args.get('edit_OBP')).first() ## print(o.notes) content = '''

 

View/Edit OpenBridge Connection

Delete OpenBridge Connection

 Name:  ''' + str(o.name) + '''
 Active:  
 IP:  
 Port:  
 Passphrase:  
 Network ID:  
 Target IP:  
 Target Port:  
 Use ACLs:  
 Subscriber ACLs:  
 Talkgroup ACLs:  
 Use Both Slots:  
 Enable Unit Calls:  
 Use Encryption:  
 Encryption_key:  
 Misc Options:  
 Notes:  

 

 

''' elif request.args.get('edit_master'): ## s = ServerList.query.all() m = MasterList.query.filter_by(server=request.args.get('server')).filter_by(name=request.args.get('edit_master')).first() content = '''

 

View/Edit a MASTER

Delete MASTER

 Name:  ''' + str(m.name) + '''
 Active:  
 Repeat:  
 Max Peers:  
 Static APRS positions:  
 User Manager for login:  
 IP:  
 PORT:  
 Passphrase:  
 Group Hangtime:  
 Use ACLs:  
 Register ACLs:  
 Subscriber ACLs:  
 Talkgroup Slot 1 ACLs:  
 Talkgroup Slot 2 ACLs:  
 Enable Unit Calls:  
 Public List:  
 Misc Options:  
 Notes:  

 

 

''' ## elif not request.args.get('edit_master') and not request.args.get('edit_OBP') and not request.args.get('add_OBP') and not request.args.get('add_master'): ## content = 'jglkdjklsd' else: #elif not request.args.get('add_proxy') or not request.args.get('add_OBP') or not request.args.get('add_master'): # or not request.args.get('proxy_save') or not request.args.get('master_save') or not request.args.get('OBP_save'): all_s = ServerList.query.all() m_list = '' for s in all_s: ## print(s.name) m_list = m_list + '''

Server: ''' + str(s.name) + '''

''' all_m = MasterList.query.filter_by(server=s.name).all() all_p = ProxyList.query.filter_by(server=s.name).all() all_o = OBP.query.filter_by(server=s.name).all() for o in all_o: m_list = m_list + ''' ''' for p in all_p: m_list = m_list + ''' ''' for x in all_m: m_list = m_list + ''' ''' m_list = m_list + '''
Name Mode Notes
''' + str(o.name) + ''' OpenBridge ''' + str(o.notes) + '''
''' + str(p.name) + ''' PROXY ''' + str(p.notes) + '''
''' + str(x.name) + ''' MASTER ''' + str(x.notes) + '''
\n''' content = '''

View/Edit Masters

Add MASTER Add PROXY Add OpenBridge

 

 

''' + m_list return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/add_user', methods=['POST', 'GET']) @login_required @roles_required('Admin') def add_admin(): if request.method == 'GET': content = '''






 

''' elif request.method == 'POST' and request.form.get('username'): if not User.query.filter(User.username == request.form.get('username')).first(): radioid_data = ast.literal_eval(get_ids(request.form.get('username'))) aprs_dict = {} for i in radioid_data[0].items(): aprs_dict[i[0]] = 'default' user = User( username=request.form.get('username'), email=request.form.get('email'), email_confirmed_at=datetime.datetime.utcnow(), aprs = str(aprs_dict), password=user_manager.hash_password(request.form.get('password')), dmr_ids = str(radioid_data[0]), initial_admin_approved = True, first_name = str(radioid_data[1]), last_name = str(radioid_data[2]), city = str(radioid_data[3]) ) db.session.add(user) u = User.query.filter_by(username=request.form.get('username')).first() user_role = UserRoles( user_id=u.id, role_id=2, ) db.session.add(user_role) db.session.commit() content = '''

Created user: ''' + str(request.form.get('username')) + '''

\n''' elif User.query.filter(User.username == request.form.get('username')).first(): content = 'Existing user: ' + str(request.form.get('username') + '. New user not created.') return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/manage_rules', methods=['POST', 'GET']) @login_required @roles_required('Admin') def manage_rules(): if request.args.get('save_bridge') == 'save': public = False if request.form.get('public_list') == 'True': public = True if request.form.get('bridge_name') == '': content = '''

Bridge can't have blank name.

Redirecting in 3 seconds.

''' else: bridge_add(request.form.get('bridge_name'), request.form.get('description'), public, request.form.get('tg')) content = '''

Bridge (talkgroup) saved.

Redirecting in 3 seconds.

''' elif request.args.get('save_bridge') == 'edit': public = False if request.form.get('public_list') == 'True': public = True update_bridge_list(request.args.get('bridge'), request.form.get('description'), public, request.form.get('bridge_name'), request.form.get('tg')) content = '''

Bridge (talkgroup) changed.

Redirecting in 3 seconds.

''' elif request.args.get('save_bridge') == 'delete': bridge_delete(request.args.get('bridge')) content = '''

Bridge (talkgroup) deleted.

Redirecting in 3 seconds.

''' #Rules elif request.args.get('save_rule'): ## public_list = False active = False if request.form.get('active_dropdown') == 'True': active = True if request.args.get('save_rule') == 'new': add_system_rule(request.form.get('bridge_dropdown'), request.form.get('system_text'), request.form.get('ts_dropdown'), request.form.get('tgid'), active, request.form.get('timer_time'), request.form.get('type_dropdown'), request.form.get('on'), request.form.get('off'), request.form.get('reset'), request.args.get('server')) content = '''

Bridge (talkgroup) rule saved.

Redirecting in 3 seconds.

''' elif request.args.get('save_rule') == 'edit': content = '''

Bridge (talkgroup) rule changed.

Redirecting in 3 seconds.

''' elif request.args.get('save_rule') == 'delete': # print(request.args.get('bridge')) # print(request.args.get('server')) if request.args.get('system'): delete_system_rule(request.args.get('bridge'), request.args.get('server'), request.args.get('system')) else: delete_system_bridge(request.args.get('bridge'), request.args.get('server')) ## delete_system_rule(request.args.get('bridge'), request.args.get('server'), request.args.get('system')) content = '''

System rule deleted.

Redirecting in 3 seconds.

''' elif request.args.get('add_rule'): ## svl = ServerList.query.all() bl = BridgeList.query.all() #filter(bridge_name== request.form.get('username')).all() all_o = OBP.query.filter_by(server=request.args.get('add_rule')).all() all_m = MasterList.query.filter_by(server=request.args.get('add_rule')).all() all_p = ProxyList.query.filter_by(server=request.args.get('add_rule')).all() m_l = mmdvmPeer.query.filter_by(server=request.args.get('add_rule')).all() x_l = xlxPeer.query.filter_by(server=request.args.get('add_rule')).all() ## print(sl) ## print(bl) ## svl_option = '' bl_option = '' sl_option = '' for i in all_o: sl_option = sl_option + '''''' for i in all_m: sl_option = sl_option + '''''' for i in all_p: sl_option = sl_option + '''''' for i in m_l: sl_option = sl_option + '''''' for i in x_l: sl_option = sl_option + '''''' for i in bl: bl_option = bl_option + '''''' content = '''

Add rule to server: ''' + request.args.get('add_rule') + '''

 

Bridge (Talkgroup): System: Timeslot: Talkgroup number: Activate on start:  
Timer Time (minutes):   Timer Type:   Trigger ON TGs:   Trigger OFF TGs:   Trigger Reset TGs:  

 

 

''' elif request.args.get('edit_rule') and request.args.get('bridge'): br = BridgeRules.query.filter_by(server=request.args.get('edit_rule')).filter_by(bridge_name=request.args.get('bridge')).all() print(br) br_view = '''

Rules for bridge ''' + request.args.get('bridge') + ''' on server ''' + request.args.get('edit_rule') + '''.

''' for i in br: br_view = br_view + '''  
Delete SYSTEM Rule

 

Bridge (Talkgroup): ''' + str(i.bridge_name) + ''' System: ''' + str(i.system_name) + ''' Timeslot: Talkgroup number: Activate on start:  
Timer Time (minutes):   Timer Type:   Trigger ON TGs:   Trigger OFF TGs:   Trigger Reset TGs:  

 

 

 

''' content = br_view elif request.args.get('edit_rule') == 'save' and request.args.get('bridge_edit'): ## public_list = False active = False if request.form.get('active_dropdown') == 'True': active = True edit_system_rule(request.args.get('bridge_edit'), request.args.get('system'), request.form.get('ts_dropdown'), request.form.get('tgid'), active, request.form.get('timer_time'), request.form.get('type_dropdown'), request.form.get('on'), request.form.get('off'), request.form.get('reset'), request.args.get('server')) content = '''

System rule changed.

Redirecting in 3 seconds.

''' elif request.args.get('add_bridge'): s = ServerList.query.all() ## server_options = '' ## for i in s: ## server_options = server_options + '''\n''' content = '''

 

Add a Talk Group


 


 



 

 

''' elif request.args.get('edit_bridge'): b = BridgeList.query.filter_by(bridge_name=request.args.get('edit_bridge')).first() ## s = ServerList.query.all() ## server_options = '' ## for i in s: ## server_options = server_options + '''\n''' content = '''

 

Edit a Talk Group

Delete Talk Group

 


 


 



 

 

''' else: all_b = BridgeList.query.all() s = ServerList.query.all() b_list = '''

View/Edit Talk Groups

 

''' for i in all_b: b_list = b_list + ''' ''' b_list = b_list + '''
Name Public Description TGID
''' + str(i.bridge_name) + ''' ''' + str(i.public_list) + ''' ''' + str(re.sub('<[^>]*>|\s\s+', ' ', i.description))[:50] + '''... ''' + str(i.tg) + '''

View/Edit Rules (Bridges)

/ ''' r_list = '' for i in s: # print(i) r_list = r_list + '''
''' br = BridgeRules.query.filter_by(server=i.name).all() temp_list = [] for x in br: #.filter_by(bridge_name=request.args.get('bridge')).all() if x.bridge_name in temp_list: pass else: temp_list.append(x.bridge_name) r_list = r_list + ''' ''' r_list = r_list + '''
Bridge Name - -
''' + str(x.bridge_name) + ''' Edit Bridge Rules Delete Bridge from this server

 

''' content = b_list + r_list + '''''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @login_required @roles_required('Admin') @app.route('/unit/') def get_unit_table(server): unit_table = Misc.query.filter_by(field_1='unit_table_' + server).first() table_dict = ast.literal_eval(unit_table.field_2) print(table_dict) content = '''

UNIT Call Routing Table for ''' + server + '''

 

''' try: for i in table_dict.items(): content = content + ''' ''' content = content + '
ID System Expiration
''' + str(int_id(i[0])) + ''' ''' + str((i[1][0])) + ''' ''' + str(i[1][1]) + '''
' except: content = '

No UNIT table.

' return render_template('flask_user_layout.html', markup_content = Markup(content)) @login_required @roles_required('Admin') @app.route('/OBP_key_gen') def obp_key_gen(): key = Fernet.generate_key() ## content = str(key)[2:-1] content = '''

Generate OpenBridge Encryption Key

 

Both ends of the OpenBridge connection must share this same key.

 

KEY: (Copy and Paste)
''' + str(key)[2:-1] + '''

 

''' return render_template('flask_user_layout.html', markup_content = Markup(content)) @app.route('/aprs') def data_dash(): ## dev_loc = GPS_LocLog.query.order_by(time).limit(3).all() dev_loc = GPS_LocLog.query.order_by(GPS_LocLog.time.desc()).limit(50).all() content = '' dev_lst = [] for i in dev_loc: if i.callsign not in dev_lst: dev_lst.append(i.callsign) content = content + '''  ''' + i.lat + '''   ''' + i.lon + '''   ''' + str(i.time.strftime(time_format)) + '''  ''' ## content = dev_loc return render_template('aprs_page.html', markup_content = Markup(content)) @app.route('/svr', methods=['POST']) def svr_endpoint(): hblink_req = request.json print((hblink_req)) if hblink_req['secret'] in shared_secrets(): try: if hblink_req['ping']: pl = Misc.query.filter_by(field_1='ping_list').first() ping_list = ast.literal_eval(pl.field_2) ping_list[hblink_req['ping']] = time.time() misc_edit_field_1('ping_list', str(ping_list), '', '', 0, 0, 0, 0, True, True) response = '' except: pass if 'login_id' in hblink_req and 'login_confirmed' not in hblink_req: if type(hblink_req['login_id']) == int: if authorized_peer(hblink_req['login_id'])[0]: ## print(active_tgs) if isinstance(authorized_peer(hblink_req['login_id'])[1], int) == True: authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], authorized_peer(hblink_req['login_id'])[2], gen_passphrase(hblink_req['login_id']), 'Attempt') ## active_tgs[hblink_req['login_server']][hblink_req['system']] = [{'1':[]}, {'2':[]}, {'SYSTEM': ''}, {'peer_id':hblink_req['login_id']}] response = jsonify( allow=True, mode='normal', ) elif authorized_peer(hblink_req['login_id'])[1] == '': authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], authorized_peer(hblink_req['login_id'])[2], 'Config Passphrase: ' + legacy_passphrase, 'Attempt') ## active_tgs[hblink_req['login_server']][hblink_req['system']] = [{'1':[]}, {'2':[]}, {'SYSTEM': ''}, {'peer_id':hblink_req['login_id']}] response = jsonify( allow=True, mode='legacy', ) elif authorized_peer(hblink_req['login_id'])[1] != '' or isinstance(authorized_peer(hblink_req['login_id'])[1], int) == False: authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], authorized_peer(hblink_req['login_id'])[2], authorized_peer(hblink_req['login_id'])[1], 'Attempt') ## active_tgs[hblink_req['login_server']][hblink_req['system']] = [{'1':[]}, {'2':[]}, {'SYSTEM': ''}, {'peer_id':hblink_req['login_id']}] # print(authorized_peer(hblink_req['login_id'])) response = jsonify( allow=True, mode='override', value=authorized_peer(hblink_req['login_id'])[1] ) ## try: ## active_tgs[hblink_req['login_server']][hblink_req['system']] = [{'1':[]}, {'2':[]}, {'SYSTEM': ''}, {'peer_id':hblink_req['login_id']}] ## print('Restart ' + hblink_req['login_server'] + ' please.') ## except: ## active_tgs[hblink_req['login_server']] = {} ## pass elif authorized_peer(hblink_req['login_id'])[0] == False: ## print('log fail') authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], 'Not Registered', '-', 'Failed') response = jsonify( allow=False) elif not type(hblink_req['login_id']) == int: user = hblink_req['login_id'] u = User.query.filter_by(username=user).first() if not u: msg = jsonify(auth=False, reason='User not found') response = make_response(msg, 401) if u: u_role = UserRoles.query.filter_by(user_id=u.id).first() password = user_manager.verify_password(hblink_req['password'], u.password) if u_role.role_id == 2: role = 'user' if u_role.role_id == 1: role = 'admin' if password: response = jsonify(auth=True, role=role) else: msg = jsonify(auth=False, reason='Incorrect password') response = make_response(msg, 401) elif 'login_id' in hblink_req and 'login_confirmed' in hblink_req: if hblink_req['old_auth'] == True: authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], authorized_peer(hblink_req['login_id'])[2], 'CONFIG, NO UMS', 'Confirmed') else: authlog_add(hblink_req['login_id'], hblink_req['login_ip'], hblink_req['login_server'], authorized_peer(hblink_req['login_id'])[2], 'USER MANAGER', 'Confirmed') response = jsonify( logged=True ) elif 'burn_list' in hblink_req: # ['burn_list']: # == 'burn_list': response = jsonify( burn_list=get_burnlist() ) elif 'loc_callsign' in hblink_req: if hblink_req['lat'] == '*' and hblink_req['lon'] == '*': ## del peer_locations[hblink_req['dmr_id']] del_peer_loc(hblink_req['dmr_id']) print('del peer loc') else: ## peer_locations[hblink_req['dmr_id']] = [hblink_req['loc_callsign'], hblink_req['lat'], hblink_req['lon'], hblink_req['url'], hblink_req['description'], hblink_req['loc'], hblink_req['software']] del_peer_loc(hblink_req['dmr_id']) peer_loc_add(hblink_req['loc_callsign'], hblink_req['lat'], hblink_req['lon'], hblink_req['description'], hblink_req['dmr_id'], '', '', hblink_req['url'], hblink_req['software'], hblink_req['loc']) print(PeerLoc.query.all()) response = '' elif 'dashboard' in hblink_req: if 'lat' in hblink_req: # Assuming this is a GPS loc dash_loc_add(hblink_req['call'], hblink_req['lat'], hblink_req['lon'], hblink_req['comment'], hblink_req['dmr_id'], hblink_req['dashboard']) trim_dash_loc() response = 'yes' elif 'log_sms' in hblink_req: sms_log_add(hblink_req['snd_call'], hblink_req['rcv_call'], hblink_req['message'], hblink_req['snd_id'], hblink_req['rcv_id'], hblink_req['log_sms'], hblink_req['system_name']) trim_sms_log() response = 'rcvd' elif 'bb_send' in hblink_req: bb_add(hblink_req['callsign'], hblink_req['bulletin'], hblink_req['dmr_id'], hblink_req['bb_send'], hblink_req['system_name']) trim_bb() response = 'rcvd' elif 'ss_update' in hblink_req: del_ss(hblink_req['dmr_id']) ss_add(hblink_req['callsign'], str(hblink_req['message']), hblink_req['dmr_id']) response = 'rcvd' elif 'unit_table' in hblink_req: ## del_unit_table(hblink_req['unit_table']) try: delete_misc_field_1('unit_table_' + hblink_req['unit_table']) except: print('entry error') misc_add('unit_table_' + hblink_req['unit_table'], str(hblink_req['data']), '', '', 0, 0, 0, 0, False, False) ## unit_table_add(hblink_req['data']) response = 'rcvd' elif 'get_config' in hblink_req: if hblink_req['get_config']: ## active_tgs[hblink_req['get_config']] = {} pl = Misc.query.filter_by(field_1='ping_list').first() ping_list = ast.literal_eval(pl.field_2) ping_list[hblink_req['get_config']] = time.time() misc_edit_field_1('ping_list', str(ping_list), '', '', 0, 0, 0, 0, True, True) ## print(active_tgs) ## try: ## print(get_peer_configs(hblink_req['get_config'])) print(masters_get(hblink_req['get_config'])) response = jsonify( config=server_get(hblink_req['get_config']), peers=get_peer_configs(hblink_req['get_config']), masters=masters_get(hblink_req['get_config']), ## OBP=get_OBP(hblink_req['get_config']) ) ## except: ## message = jsonify(message='Config error') ## response = make_response(message, 401) elif 'get_rules' in hblink_req: if hblink_req['get_rules']: # == 'burn_list': ## try: response = jsonify( rules=generate_rules(hblink_req['get_rules']), ## OBP=get_OBP(hblink_req['get_config']) ) ## except: ## message = jsonify(message='Config error') ## response = make_response(message, 401) #################### Work in progress ###########################33 ## elif 'update_tg' in hblink_req: ## if hblink_req['update_tg']: ## print(hblink_req) #### print(hblink_req['data'][0]['SYSTEM']) ## if 'on' == hblink_req['mode']: #### try: ## if hblink_req['dmr_id'] == 0: ## print('id 0') #### print(active_tgs) ## for system in active_tgs[hblink_req['update_tg']].items(): ## ## print(system) ## ## print('sys') ## if system[0] == hblink_req['data'][0]['SYSTEM']: ## print(active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1']) #### print(hblink_req['data'][2]['tg']) ## print('---------') ## print(active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2']) ## ## print(hblink_req['data'][1]['ts']) ## if hblink_req['data'][1]['ts'] == 1: ## #### print(active_tgs[hblink_req['update_tg']][system[0]][0]['1']) ## ## if active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1'] == hblink_req['data'][2]['tg']: ## pass ## else: ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1'].append(hblink_req['data'][2]['tg']) ## #### active_tgs[hblink_req['update_tg']][system[0]][0]['1'].append(0) ## if hblink_req['data'][1]['ts'] == 2: ## if active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2'] == hblink_req['data'][2]['tg']: ## pass ## #### print(active_tgs[hblink_req['update_tg']][system[0]][1]['2']) ## else: ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2'].append(hblink_req['data'][2]['tg']) ## else: ## try: ## print('---------on------------') ## print(hblink_req['data']) ## print(active_tgs[hblink_req['update_tg']]) ## print(hblink_req['data'][2]['ts2']) ## print('-----------------------') ## ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][2]['SYSTEM'] = hblink_req['data'][0]['SYSTEM'] ## #### active_tgs[hblink_req['update_tg']][hblink_req['dmr_id']].update({hblink_req['data'][0]['SYSTEM']: [{1:[hblink_req['data'][1]['ts1']]}, {2:[hblink_req['data'][2]['ts2']]}]}) #.update({[hblink_req['dmr_id']]:hblink_req['data']}) ## if hblink_req['data'][1]['ts1'] not in active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1']: ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1'].append(hblink_req['data'][1]['ts1']) ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][2]['SYSTEM'] = hblink_req['data'][0]['SYSTEM'] ## if hblink_req['data'][2]['ts2'] not in active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2']: ## print('---0---') ## print(hblink_req['data'][0]['SYSTEM']) ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][2]['SYSTEM'] = hblink_req['data'][0]['SYSTEM'] ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2'].append(hblink_req['data'][2]['ts2']) #### print('append') ## #### active_tgs[hblink_req['update_tg']][system[0]][1]['2'].append(0) ## ## print(hblink_req['data'][0]['SYSTEM']) ## ## ## print(active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']]) ## ## print(active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][2]['2']) ## ## print(hblink_req['data'][1]['ts2']) ## ## print(active_tgs[hblink_req['update_tg']]) ## except: #### active_tgs[hblink_req['update_tg']] = {} ## pass ## #### except: #### pass ## ## ## elif 'off' == hblink_req['mode']: ## print('off') ## for system in active_tgs[hblink_req['update_tg']].items(): ## print(system) ## if system[0] == hblink_req['data'][0]['SYSTEM']: ## print('yes it is') ###### print(system[0]) ###### print(active_tgs[hblink_req['update_tg']][system[0]]) ## if hblink_req['data'][1]['ts'] == 1: ###### print(active_tgs[hblink_req['update_tg']][system[0]][0]['1']) ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][0]['1'].remove(hblink_req['data'][2]['tg']) ###### active_tgs[hblink_req['update_tg']][system[0]][0]['1'].append(0) ## if hblink_req['data'][1]['ts'] == 2: ###### print(active_tgs[hblink_req['update_tg']][system[0]][1]['2']) ## active_tgs[hblink_req['update_tg']][hblink_req['data'][0]['SYSTEM']][1]['2'].remove(hblink_req['data'][2]['tg']) ###### active_tgs[hblink_req['update_tg']][system[0]][1]['2'].append(0) ## ## ## #### print() #### print(system) #### print(system[1][2]['SYSTEM']) #### print('off') #### print(hblink_req['data'][1]['ts']) #### print(hblink_req['data'][2]['tg']) ## print(active_tgs) ## response = 'got it' else: message = jsonify(message='Authentication error') response = make_response(message, 401) return response return app if __name__ == '__main__': app = hbnet_web_service() app.run(debug = True, port=hws_port, host=hws_host)