Example #1
0
def user():
    """
    Renders the user administration page which is responsible for viewing,
    deleting and adding new users.

    :returns: user view
    """
    form = RegistrationForm(request.form)
    if request.method == 'POST':
        data = JSONService.resp_to_dict(request.form)
        if form.validate() or form.is_update.data:
            add_or_update_user(
                username=form.email.data,
                password=form.password.data,
                active=form.active.data,
                is_admin=form.is_admin.data)
        elif request.form.get('action') == 'delete':
            delete_user(data['username'])
        # POST/Redirect/GET
        return redirect(url_for('user'))

    return render_template('user.html',
                           userbase=User.query.all(),
                           config=JSONService.get('/info'),
                           form=form)
Example #2
0
def settings():
    """
    Provides and receives the settings. If the frontend requests it, the current
    configuration is streamed as a file response to the browser.

    :returns: settings view
    """
    if request.method == 'POST':
        if request.form['action'] == 'save':
            error = JSONService.patch('/cfg', data=request.form,
                                      exclude=['action', 'file'])
            if error is None:
                flash('success')
            else:
                flash('failure')
        elif request.form['action'] == 'download':
            tmstmp = time.strftime("%Y%m%d-%H%M%S")
            data = request.form.copy()
            data.pop('action', None)
            return Response(
                json.dumps(data),
                mimetype='application/json',
                headers={
                    'Content-Disposition':'attachment;filename=minerctl_' +
                                          tmstmp + '.cfg'}
            )
        # POST/Redirect/GET
        return redirect(url_for('settings'))
    return render_template('settings.html',
                           data=JSONService.get('/cfg'),
                           config=JSONService.get('/info'),
                           commit=JSONService.get('/commit'))
Example #3
0
def upload_file():
    """
    Saves file and sends the content to the backend to be parsed.

    :returns: redirects to the settings view
    """
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        # if user does not select file, browser also
        # submit an empty part without filename
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = 'current_conf.cfg'
            path = os.path.join(APP.config['UPLOAD_FOLDER'], filename)
            file.save(path)

            with open(path) as json_file:
                JSONService.patch_str('/cfg', json_file)

            return redirect('/settings')
    return redirect('/')
Example #4
0
def commit():
    """
    PUTs the commit action to persist the microcontroller EEPROMs.

    :returns: nothing, HTTP code 204
    """
    if request.method == 'PUT':
        JSONService.put('/commit', data=request.form)
    return '', 204
Example #5
0
def config():
    """
    Writes the config to a local file.

    :returns: nothing, HTTP code 204
    """
    if request.method == 'PUT':
        JSONService.write_json(request.form)
    return '', 204
Example #6
0
def action():
    """
    PATCHes the action for the specific miner to the backend.

    :returns: nothing, HTTP code 204
    """
    if request.method == 'PATCH':
        JSONService.patch('/miner', request.args)

    return '', 204
Example #7
0
def _prepare_app():
    """
    Setup the initial APP values and initialize various flask plugins.

    :returns: flask app instance
    """
    # init JSGLUE. this is needed to query URLs in javascript
    _js_glue = JSGlue(APP)

    cfg_rdr = ConfigReader()

    APP.config['SECRET_KEY'] = cfg_rdr.get_attr('db_secret_key')
    APP.config['SQLALCHEMY_DATABASE_URI'] = cfg_rdr.get_attr('db_address')
    # needed because this functionality is already depricated
    APP.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    # the salt is a workaround for a bug, as flask-security salts  passwords
    # automatically but somehow it requires and uses this config value which
    # breaks the login if the salt is individually unique (as a salt should be)
    APP.config['SECURITY_PASSWORD_SALT'] = 'fake_salt'
    APP.config['SECURITY_TRACKABLE'] = True
    APP.config['SECURITY_REGISTERABLE'] = True
    APP.config['SECURITY_CONFIRMABLE'] = False

    APP.config['UPLOAD_FOLDER'] = 'config'
    # max upload size is 50 KB
    APP.config['MAX_CONTENT_LENGTH'] = 50 * 1024

    path = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/')

    APP.config['SIJAX_STATIC_PATH'] = path
    APP.config['SIJAX_JSON_URI'] = '/static/js/sijax/json2.js'
    flask_sijax.Sijax(APP)

    APP.config['JWT_ALGORITHM'] = 'RS256'
    with open(cfg_rdr.get_attr('private_key_file_location'), 'rb') as file:
        APP.config['JWT_PRIVATE_KEY'] = file.read()
    JWT = JWTManager(APP)

    with APP.app_context():
        DB.init_app(APP)
        user_datastore = SQLAlchemyUserDatastore(DB, User, Role)
        _security = Security(APP, user_datastore)
        setup(user_datastore)
        rs256_token = create_access_token(str(current_user),
                                          expires_delta=False)

    APP.config['access_headers'] = {'Authorization': 'Bearer {}'
                                    .format(rs256_token)}
    JSONService.init(APP.config['access_headers'])

    return APP
Example #8
0
def _load_or_create_layout():
    """
    Checks whether a local layout.json file is present and then either parses
    or mocks the content of the json file.

    :returns: a nested list filled with the miner_ids
    """
    # first the layout.json has to be converted into an iterable dictionary
    layout = JSONService.read_json('config/layout.json')
    local_config = {'max_number_of_racks': 12}
    if layout is None:
        local_config['number_of_racks'] = 12
        racks = []
        counter = 0
        for rack in range(12):
            rack = []
            for _ in range(10):
                rack.append(counter)
                counter += 1
            racks.append(rack)
        local_config['racks'] = racks
    else:
        local_config['number_of_racks'] = int(layout.pop('number_of_racks'))
        racks = []
        for rack, string in layout.items():
            temp = string.replace('rack=', '')
            ids = temp.split('&')
            # casting all strs to ints
            ids = list(map(int, ids))
            racks.append(ids)
        local_config['racks'] = racks

    return local_config
Example #9
0
    def get_config(obj_response):
        """
        Rewrites a couple of html elements. This is quite ugly as far as ajax
        updating goes but this is the only way which I've found.
        """
        cfg = JSONService.get('/cfg')
        for key, value in cfg['measurements'].items():
            obj_response.html('#card-measurement-' + key,
                              "<span id='card-measurement-'" + key + ">" +
                              str(value) + "</span>")
        obj_response.html('#card-pressure_diff',
                          "<span id='card-pressure_diff'>" +
                          str(cfg['pressure_diff']) + "</span>")
        obj_response.html('#card-rpm',
                          "<span id='card-rpm'>" +
                          str(cfg['rpm']) + "</span>")

        if cfg['pressure_diff'] >= cfg['threshold']:
            obj_response.html('#filter-sign',
                              "<i class='material-icons right blinking' \
                              title='CLEAN FILTER!'>warning</i>")
            obj_response.html('#filter-msg',
                              "<p class='font-bold'>FILTER REQUIRES CLEANING!\
                              </p>")
        else:
            obj_response.html('#filter-sign',
                              "<i class='material-icons right' \
                              title='filter does not need to be cleaned'>\
                              check</i>")
            obj_response.html('#filter-msg',"")
Example #10
0
def index():
    """
    Renders the index page for all logged in users.
    Some of the content of the index page is updated constantly through ajax
    requests which are handled by sijax.

    :returns: index view
    """
    if g.sijax.is_sijax_request:
        g.sijax.register_object(SijaxHandler)
        return g.sijax.process_request()

    miners = JSONService.get('/cfg')

    return render_template('index.html',
                           miners=JSONService.get('/cfg'),
                           local_config=_load_or_create_layout(),
                           config=JSONService.get('/info'),
                           temp=JSONService.get('/temp'),
                           filter=JSONService.get('/filter'),
                           pid=JSONService.get('/pid'),
                           fans=JSONService.get('/fans'),
                           operation=JSONService.get('/mode'))
Example #11
0
    redirect, Response, url_for, flash, g
from flask_security import Security, SQLAlchemyUserDatastore, \
    login_required, roles_required, url_for_security, \
    RegisterForm, current_user
from wtforms import Form, BooleanField, StringField, PasswordField, \
    validators, HiddenField
from flask_jsglue import JSGlue
from flask_jwt_extended import JWTManager, jwt_required, create_access_token
import flask_sijax
from src.json_parser import JSONService
from src.db_init import DB, User, Role, setup, add_or_update_user, \
    delete_user
from src.config_reader import ConfigReader

APP = Flask(__name__)
JSONService = JSONService()

@APP.context_processor
def register_context():
    """
    Adds a couple of useful variables to the application context.

    :returns: current_user, url_for_security, register_user_form, is_admin
    """
    return {
        'url_for_security': url_for_security,
        'register_user_form': RegisterForm(),
        'current_user': current_user,
        'is_admin': current_user.has_role('admin')
    }