Merge pull request #7 from technikamateur/beta

merging v1.0.1
This commit is contained in:
Daniel 2019-10-18 11:17:20 +02:00 committed by GitHub
commit f4cc0bc354
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 295 additions and 180 deletions

View file

@ -1,4 +1,6 @@
from flask_wtf import csrf, CSRFProtect import datetime
from flask_wtf import CSRFProtect
import dirkules.config as config import dirkules.config as config
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
@ -12,6 +14,7 @@ csrf.init_app(app)
app_version = app.config["VERSION"] app_version = app.config["VERSION"]
import dirkules.models import dirkules.models
import dirkules.samba.models
# create db if not exists # create db if not exists
db.create_all() db.create_all()
@ -21,3 +24,15 @@ scheduler.init_app(app)
scheduler.start() scheduler.start()
# import views # import views
import dirkules.views import dirkules.views
from dirkules.samba import bp_samba as bp_samba
app.register_blueprint(bp_samba, url_prefix='/samba')
from dirkules.models import Drive
@app.before_request
def check_drives():
if Drive.query.first() is None:
scheduler.get_job("refresh_disks").modify(next_run_time=datetime.datetime.now())

View file

@ -5,7 +5,7 @@ from logging.config import dictConfig
from apscheduler.jobstores.base import ConflictingIdError from apscheduler.jobstores.base import ConflictingIdError
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
VERSION = "1.0" VERSION = "1.0.1"
baseDir = os.path.abspath(os.path.dirname(__file__)) baseDir = os.path.abspath(os.path.dirname(__file__))
staticDir = os.path.join(baseDir, 'static') staticDir = os.path.join(baseDir, 'static')

View file

@ -66,10 +66,10 @@ def part_for_disk(device):
# lsblk /dev/sdd -b -o NAME,LABEL,FSTYPE,SIZE,UUID,MOUNTPOINT # lsblk /dev/sdd -b -o NAME,LABEL,FSTYPE,SIZE,UUID,MOUNTPOINT
parts = [] parts = []
part_dict = list() part_dict = list()
keys = ['name', 'label', 'fs', 'size', 'uuid', 'mount'] keys = ['size', 'name', 'label', 'fs', 'uuid', 'mount']
device = "/dev/" + device device = "/dev/" + device
lsblk = subprocess.Popen( lsblk = subprocess.Popen(
["sudo lsblk " + device + " -l -b -o NAME,LABEL,FSTYPE,SIZE,UUID,MOUNTPOINT"], ["sudo lsblk " + device + " -l -b -o SIZE,NAME,LABEL,FSTYPE,UUID,MOUNTPOINT"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
universal_newlines=True) universal_newlines=True)
@ -83,26 +83,24 @@ def part_for_disk(device):
del parts[1] del parts[1]
element_length = list() element_length = list()
counter = 0 counter = 0
last_letter = 0
pre_value = " " pre_value = " "
for char in parts[0]: for char in parts[0]:
if char != " " and pre_value == " ": if char != " " and pre_value == " ":
element_length.append(counter) if len(element_length) == 0:
element_length.append(0)
else:
element_length.append(counter)
counter += 1 counter += 1
pre_value = char pre_value = char
# size ist rechtsbuendig. Extra Behandlung
# TODO: Besser machen
if char == "S" and parts[0][last_letter] == "E":
del element_length[-1]
element_length.append((last_letter + 2))
if char != " ":
last_letter = counter - 1
element_length.append(len(parts[0])) element_length.append(len(parts[0]))
del parts[0] del parts[0]
for part in parts: for part in parts:
values = list() values = list()
for start, end in zip(element_length, element_length[1:]): for start, next_start in zip(element_length, element_length[1:]):
values.append(part[start:(end - 1)].strip()) if next_start == element_length[-1:][0]:
values.append(part[start:len(part)].strip())
else:
values.append(part[start:(next_start - 1)].strip())
part_dict.append(dict(zip(keys, values))) part_dict.append(dict(zip(keys, values)))
return part_dict return part_dict

View file

@ -2,13 +2,10 @@
import subprocess import subprocess
# This file should read btrfs pools def get_free_space(mount_point):
# Storage: sudo btrfs fi usage -b -T /media/data-raid
def get_free_space(name):
lines = list() lines = list()
df = subprocess.Popen( df = subprocess.Popen(
["df -B K /dev/" + name], ["df -B K " + mount_point],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
universal_newlines=True) universal_newlines=True)
@ -20,7 +17,7 @@ def get_free_space(name):
break break
df.stdout.close() df.stdout.close()
for line in lines: for line in lines:
newLine = ' '.join(line.split()) new_line = ' '.join(line.split())
newLine = newLine.split(" ") new_line = new_line.split(" ")
if name in newLine[0]: if mount_point in new_line:
return int(newLine[3][:-1]) * 1024 return int(new_line[3][:-1]) * 1024

View file

@ -80,6 +80,7 @@ def get_drives():
def pool_gen(): def pool_gen():
part_dict = dict() part_dict = dict()
Pool.query.delete()
# creates map uuid is key, partitions are values # creates map uuid is key, partitions are values
for part in Partitions.query.all(): for part in Partitions.query.all():
if part.uuid in part_dict: if part.uuid in part_dict:
@ -97,7 +98,9 @@ def pool_gen():
drives = drives + str(Drive.query.get(part.drive_id)) + "," drives = drives + str(Drive.query.get(part.drive_id)) + ","
drives = drives[:-1] drives = drives[:-1]
value = value[0] value = value[0]
Pool.query.delete() missing = absent_drive(drives)
if missing is not None:
missing = ",".join(str(x.name) for x in missing)
if value.fs == "btrfs": if value.fs == "btrfs":
if value.mountpoint: if value.mountpoint:
memory_map = btrfsTools.get_space(value.mountpoint) memory_map = btrfsTools.get_space(value.mountpoint)
@ -108,16 +111,16 @@ def pool_gen():
['unbekannt', '1.00', 'unbekannt', '1.00']))) ['unbekannt', '1.00', 'unbekannt', '1.00'])))
pool_obj = Pool(value.label, memory_map.get("total"), memory_map.get("free"), raid_map.get("data_raid"), pool_obj = Pool(value.label, memory_map.get("total"), memory_map.get("free"), raid_map.get("data_raid"),
raid_map.get("data_ratio"), raid_map.get("meta_raid"), raid_map.get("meta_ratio"), value.fs, raid_map.get("data_ratio"), raid_map.get("meta_raid"), raid_map.get("meta_ratio"), value.fs,
value.mountpoint, "not implemented", drives, get_pool_health(drives)) value.mountpoint, "not implemented", drives, get_pool_health(drives), missing)
db.session.add(pool_obj) db.session.add(pool_obj)
elif value.fs == "ext4": elif value.fs == "ext4":
if value.mountpoint: if value.mountpoint:
free_space = ext4Tools.get_free_space(value.name) free_space = ext4Tools.get_free_space(value.mountpoint)
else: else:
free_space = 2 free_space = 2
pool_obj = Pool(value.label, value.size, free_space, raid, 1.00, raid, 1.00, value.fs, value.mountpoint, pool_obj = Pool(value.label, value.size, free_space, raid, 1.00, raid, 1.00, value.fs, value.mountpoint,
"not implemented", drives) "not implemented", drives, get_pool_health(drives), missing)
db.session.add(pool_obj) db.session.add(pool_obj)
db.session.commit() db.session.commit()
@ -137,6 +140,23 @@ def get_pool_health(drive_list):
return True return True
def absent_drive(drive_list):
"""
:param drive_list: contains drives which belongs to pool
:return: List of absent drives or None
"""
missing = list()
drive_split = drive_list.split(",")
for drive in drive_split:
db_drive = db.session.query(Drive).filter(Drive.name == drive).scalar()
if db_drive.missing:
missing.append(db_drive)
if not missing:
return None
else:
return missing
def delete_drive(drive): def delete_drive(drive):
""" """
removes a given drive object (including cascades) from db removes a given drive object (including cascades) from db

View file

@ -78,9 +78,10 @@ class Pool(db.Model):
mountopt = db.Column(db.String) mountopt = db.Column(db.String)
drives = db.Column(db.String) drives = db.Column(db.String)
healthy = db.Column(db.Boolean) healthy = db.Column(db.Boolean)
missing = db.Column(db.String)
def __init__(self, label, size, free, data_raid, data_ratio, meta_raid, meta_ratio, fs, mountpoint, mountopt, def __init__(self, label, size, free, data_raid, data_ratio, meta_raid, meta_ratio, fs, mountpoint, mountopt,
drives, healthy): drives, healthy, missing):
self.label = label self.label = label
self.size = size self.size = size
self.free = free self.free = free
@ -93,6 +94,7 @@ class Pool(db.Model):
self.mountopt = mountopt self.mountopt = mountopt
self.drives = drives self.drives = drives
self.healthy = healthy self.healthy = healthy
self.missing = missing
class Time(db.Model): class Time(db.Model):
@ -118,24 +120,3 @@ class Cleaning(db.Model):
self.path = path self.path = path
self.state = state self.state = state
class SambaShare(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
writeable = db.Column(db.Boolean)
recycling = db.Column(db.Boolean)
btrfs = db.Column(db.Boolean)
options = db.relationship('SambaOptions', order_by="SambaOptions.id", backref="samba_share", lazy="select")
def __init__(self, name, writeable=False, recycling=False, btrfs=False):
self.name = name
self.writeable = writeable
self.recycling = recycling
self.btrfs = btrfs
class SambaOptions(db.Model):
id = db.Column(db.Integer, primary_key=True)
option = db.Column(db.String, nullable=False)
value = db.Column(db.String, nullable=False)
sambashare_id = db.Column(db.Integer, db.ForeignKey('samba_share.id'), nullable=False)

View file

@ -0,0 +1,4 @@
from flask import Blueprint
bp_samba = Blueprint('samba', __name__, template_folder='templates')
from dirkules.samba import views

32
dirkules/samba/manager.py Normal file
View file

@ -0,0 +1,32 @@
from dirkules.config import staticDir
from dirkules import db, app_version
from dirkules.samba.models import SambaGlobal
def set_samba_global(workgroup, name):
SambaGlobal.query.delete()
workgroup = SambaGlobal("workgroup", workgroup)
name = SambaGlobal("server string", "%h {}".format(name))
db.session.add(workgroup)
db.session.add(name)
db.session.commit()
def generate_smb():
if SambaGlobal.query.first() is None:
workgroup = 'WORKGROUP'
server_string = '%h dirkules'
else:
workgroup = SambaGlobal.query.get(1)
server_string = SambaGlobal.query.get(2)
f = open("smb.conf.txt", "w")
samba_global = open(staticDir + "/conf/samba_global.conf", "r")
f.write("# This file was generated by dirkules v{}".format(app_version))
f.write()
f.write("# Global Config")
f.write("server string = {}".format(server_string))
f.write("workgroup = {}".format(workgroup))
f.write(samba_global.read())
f.close()

34
dirkules/samba/models.py Normal file
View file

@ -0,0 +1,34 @@
from dirkules import db
class SambaGlobal(db.Model):
id = db.Column(db.Integer, primary_key=True)
element = db.Column(db.String)
value = db.Column(db.String)
def __init__(self, element, value):
self.element = element
self.value = value
class SambaShare(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
writeable = db.Column(db.Boolean)
recycling = db.Column(db.Boolean)
btrfs = db.Column(db.Boolean)
options = db.relationship('SambaOptions', order_by="SambaOptions.id", backref="samba_share", lazy="select",
cascade="all, delete-orphan")
def __init__(self, name, writeable=False, recycling=False, btrfs=False):
self.name = name
self.writeable = writeable
self.recycling = recycling
self.btrfs = btrfs
class SambaOptions(db.Model):
id = db.Column(db.Integer, primary_key=True)
option = db.Column(db.String, nullable=False)
value = db.Column(db.String, nullable=False)
sambashare_id = db.Column(db.Integer, db.ForeignKey('samba_share.id'), nullable=False)

View file

@ -5,18 +5,19 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div class="ui container"> <div class="ui container">
<t2>Feste Bestandteile der<i> Samba global conf</i></t2> <t2>Feste Bestandteile der<i> Samba global conf</i></t2>
<div class="ui segment"> <div class="ui segment">
{% for line in conf %} {% for line in conf %}
{{ line }}<br> {{ line }}<br>
{% endfor %} {% endfor %}
</div> </div>
<t2>Veränderbare Bestandteile der<i> Samba global conf</i></t2> <t2>Veränderbare Bestandteile der<i> Samba global conf</i></t2>
{% from "_formhelpers.html" import render_field %} {% from "_formhelpers.html" import render_field %}
<form method=post class="ui form error"> <form method=post class="ui form error">
{{ form.hidden_tag() }}
{{ render_field(form.workgroup) }} {{ render_field(form.workgroup) }}
{{ render_field(form.server_string) }} {{ render_field(form.server_string) }}
<button class="ui button" type="submit"><i class="save icon"></i> Ändern</button> {{ render_field(form.submit) }}
</form> </form>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -0,0 +1,47 @@
{% extends "base.html" %}
{% block title %}Samba{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<div class="topspacer"></div>
<div class="ui container">
<a href="{{ url_for('.config') }}">
<div class="ui primary labeled icon button">
<i class="edit icon"></i> Konfigurieren
</div>
</a>
<a href="{{ url_for('.add') }}">
<div class="ui primary labeled icon button">
<i class="plus icon"></i> Freigabe hinzufügen
</div>
</a>
<a href="{{ url_for('.generate') }}">
<div class="ui primary labeled icon button">
<i class="magic icon"></i> Generieren
</div>
</a>
<table class="ui celled fixed table">
<thead>
<tr>
<th>Name</th>
<th>Schreibzugriff</th>
<th>Papierkorb</th>
<th>BtrFS Optimierungen</th>
</tr>
</thead>
<tbody>
{% for share in shares %}
<tr>
<td>{{ share.name }}</td>
<td>{{ share.writeable }}</td>
<td>{{ share.recycling }}</td>
<td>{{ share.btrfs }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View file

@ -0,0 +1,38 @@
from flask_wtf import FlaskForm
from wtforms import StringField, BooleanField, SelectField, IntegerField, RadioField, validators, SubmitField
class SambaConfigForm(FlaskForm):
workgroup = StringField("workgroup", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Regexp('^[a-z]+$', message="Bitte nur Kleinbuchstaben eingeben."),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Nichts..."})
server_string = StringField("server string", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Regexp('^[a-z]+$',
message="Bitte nur Kleinbuchstaben eingeben."),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Nichts..."})
submit = SubmitField("Speichern")
class SambaAddForm(FlaskForm):
name = StringField("Name der Freigabe", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Bilder"})
writeable = BooleanField("Schreibzugriff")
recycling = BooleanField("Papierkorb")
btrfs = BooleanField("BtrFS Optimierungen (Vorsicht!)")
# additional
path = SelectField("Pfad", choices=[("Value1", "Label1"), ("Value2", "Label2")])
user = StringField("Berechtigte Nutzer", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "sambadaniel"})
create_mask = IntegerField("Dateimaske", [validators.Optional(),
validators.NumberRange(min=4, max=4,
message="Bitte 4 Zahlen eingeben!")],
render_kw={"placeholder": "0600"})
dir_mask = IntegerField("Ordnermaske", [validators.Optional(),
validators.NumberRange(min=4, max=4,
message="Bitte 4 Zahlen eingeben!")],
render_kw={"placeholder": "0700"})
submit = SubmitField("Speichern")

44
dirkules/samba/views.py Normal file
View file

@ -0,0 +1,44 @@
from dirkules import db
from dirkules.config import staticDir
from flask import render_template, url_for, request, redirect
from dirkules.samba import bp_samba
from dirkules.samba.manager import set_samba_global
from dirkules.samba.models import SambaShare
from dirkules.samba.validation import SambaConfigForm, SambaAddForm
@bp_samba.route('/', methods=['GET'])
def index():
shares = SambaShare.query.order_by(db.asc(db.collate(SambaShare.name, 'NOCASE'))).all()
return render_template('samba/index.html', shares=shares)
@bp_samba.route('/config', methods=['GET', 'POST'])
def config():
form = SambaConfigForm(request.form)
if request.method == 'POST' and form.validate():
set_samba_global(form.workgroup.data, form.server_string.data)
return redirect(url_for('.index'))
file = open(staticDir + "/conf/samba_global.conf", "r")
conf = list()
while True:
line = file.readline()
if line != '':
conf.append(line.rstrip())
else:
break
return render_template('samba/config.html', form=form, conf=conf)
@bp_samba.route('/add', methods=['GET', 'POST'])
def add():
form = SambaAddForm(request.form)
if request.method == 'POST' and form.validate():
return redirect(url_for('.index'))
return render_template('samba/add.html', form=form)
@bp_samba.route('/generate')
def generate():
return redirect(url_for('.index'))

View file

@ -23,7 +23,7 @@
<a class="item" href="{{ url_for('drives') }}"><i class="hdd icon"></i> Festplatten</a> <a class="item" href="{{ url_for('drives') }}"><i class="hdd icon"></i> Festplatten</a>
<a class="item" href="{{ url_for('pools') }}"><i class="server icon"></i> Pools</a> <a class="item" href="{{ url_for('pools') }}"><i class="server icon"></i> Pools</a>
<a class="item" href="{{ url_for('cleaning') }}"><i class="trash icon"></i> Cleaning</a> <a class="item" href="{{ url_for('cleaning') }}"><i class="trash icon"></i> Cleaning</a>
<a class="item" href="{{ url_for('samba') }}"><i class="share alternate icon"></i> Samba</a> <a class="item" href="{{ url_for('samba.index') }}"><i class="share alternate icon"></i> Samba</a>
<div class="right menu"> <div class="right menu">
<a class="ui item" href="{{ url_for('about') }}">über Dirkules</a> <a class="ui item" href="{{ url_for('about') }}">über Dirkules</a>
</div> </div>

View file

@ -81,7 +81,7 @@
</tr> </tr>
<tr> <tr>
<td>Gesundheit</td> <td>Gesundheit</td>
{% if pool.healthy %} {% if pool.healthy and pool.missing is none %}
<td class="positive"><i class="icon checkmark"></i>Gesund</td> <td class="positive"><i class="icon checkmark"></i>Gesund</td>
{% else %} {% else %}
<td class="negative"><i class="attention icon"></i>Kritisch</td> <td class="negative"><i class="attention icon"></i>Kritisch</td>
@ -99,13 +99,14 @@
</div> </div>
<p> <p>
Die RAID Level von Data und Metadata unterscheiden sich. Normalerweise sollten beide gleich Die RAID Level von Data und Metadata unterscheiden sich. Normalerweise sollten beide gleich
konfiguriert werden, da es sonst unter Umständen zu <b>Datenverlust</b> kommen kann, wenn ein konfiguriert werden, da es sonst unter Umständen zu <b>Datenverlust</b> kommen kann, wenn
ein
Laufwerk ausfällt.<br> Laufwerk ausfällt.<br>
Solltest du einen guten Grund dafür haben, ignoriere einfach diese Meldung. Solltest du einen guten Grund dafür haben, ignoriere einfach diese Meldung.
</p> </p>
</div> </div>
{% endif %} {% endif %}
{% if pool.healthy %} {% if pool.healthy and pool.missing is none %}
<div class="ui positive message"> <div class="ui positive message">
<i class="close icon"></i> <i class="close icon"></i>
<div class="header"> <div class="header">
@ -116,16 +117,28 @@
</p> </p>
</div> </div>
{% else %} {% else %}
<div class="ui negative message"> {% if not pool.healthy %}
<i class="close icon"></i> <div class="ui negative message">
<div class="header"> <i class="close icon"></i>
Kritischer Zustand <div class="header">
Kritischer Zustand
</div>
<p>
Mindetstens ein Laufwerk befindet sich in einem schlechten Zustand! Du solltest
dieses schnellstmöglich tauschen.
</p>
</div> </div>
<p> {% else %}
Mindetstens ein Laufwerk befindet sich in einem schlechten Zustand! Du solltest <div class="ui negative message">
dieses schnellstmöglich tauschen. <i class="close icon"></i>
</p> <div class="header">
</div> Kritischer Zustand
</div>
<p>
Folgende Laufwerke wurden nicht gefunden: {{ pool.missing }}
</p>
</div>
{% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

View file

@ -1,39 +0,0 @@
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<a href="{{ url_for('samba_global') }}">
<div class="ui primary labeled icon button">
<i class="plus icon"></i> Samba Global conf
</div>
</a>
<a href="{{ url_for('samba_add') }}">
<div class="ui primary labeled icon button">
<i class="plus icon"></i> Samba add
</div>
</a>
<table class="ui celled fixed table">
<thead>
<tr>
<th>Name</th>
<th>Schreibzugriff</th>
<th>Papierkorb</th>
<th>BtrFS Optimierungen</th>
</tr>
</thead>
<tbody>
{% for share in shares %}
<tr>
<td>{{ share.name }}</td>
<td>{{ share.writeable }}</td>
<td>{{ share.recycling }}</td>
<td>{{ share.btrfs }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -17,42 +17,6 @@ class CleaningForm(FlaskForm):
submit = SubmitField("Job speichern") submit = SubmitField("Job speichern")
class SambaCleaningForm(FlaskForm):
workgroup = StringField("workgroup", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Regexp('^[a-z]+$', message="Bitte nur Kleinbuchstaben eingeben."),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Nichts..."})
server_string = StringField("server string", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Regexp('^[a-z]+$',
message="Bitte nur Kleinbuchstaben eingeben."),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Nichts..."})
class SambaAddForm(FlaskForm):
name = StringField("Name der Freigabe", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "Bilder"})
writeable = BooleanField("Schreibzugriff")
recycling = BooleanField("Papierkorb")
btrfs = BooleanField("BtrFS Optimierungen (Vorsicht!)")
# additional
path = SelectField("Pfad", choices=[("Value1", "Label1"), ("Value2", "Label2")])
user = StringField("Berechtigte Nutzer", [validators.required(message="Bitte Feld ausfüllen!"),
validators.Length(max=255, message="Eingabe zu lang")],
render_kw={"placeholder": "sambadaniel"})
create_mask = IntegerField("Dateimaske", [validators.Optional(),
validators.NumberRange(min=4, max=4,
message="Bitte 4 Zahlen eingeben!")],
render_kw={"placeholder": "0600"})
dir_mask = IntegerField("Ordnermaske", [validators.Optional(),
validators.NumberRange(min=4, max=4,
message="Bitte 4 Zahlen eingeben!")],
render_kw={"placeholder": "0700"})
class SemanticMultiSelectField(SelectField): class SemanticMultiSelectField(SelectField):
def pre_validate(self, form): def pre_validate(self, form):
if self.choices is not None: if self.choices is not None:

View file

@ -6,10 +6,9 @@ from dirkules import app, db, scheduler, app_version
import dirkules.manager.serviceManager as servMan import dirkules.manager.serviceManager as servMan
import dirkules.manager.driveManager as driveMan import dirkules.manager.driveManager as driveMan
import dirkules.manager.cleaning as cleaningMan import dirkules.manager.cleaning as cleaningMan
from dirkules.models import Drive, Cleaning, SambaShare, Pool from dirkules.models import Drive, Cleaning, Pool
import dirkules.manager.viewManager as viewManager import dirkules.manager.viewManager as viewManager
from dirkules.validation.validators import CleaningForm, SambaCleaningForm, SambaAddForm, PoolAddForm from dirkules.validation.validators import CleaningForm, PoolAddForm
from dirkules.config import staticDir
@app.errorhandler(404) @app.errorhandler(404)
@ -146,36 +145,3 @@ def add_cleaning():
viewManager.create_cleaning_obj(form.jobname.data, form.path.data, form.active.data) viewManager.create_cleaning_obj(form.jobname.data, form.path.data, form.active.data)
return redirect(url_for('cleaning')) return redirect(url_for('cleaning'))
return render_template('add_cleaning.html', form=form) return render_template('add_cleaning.html', form=form)
@app.route('/samba', methods=['GET'])
def samba():
shares = SambaShare.query.order_by(db.asc(db.collate(SambaShare.name, 'NOCASE'))).all()
return render_template('samba.html', shares=shares)
@app.route('/samba/global', methods=['GET', 'POST'])
def samba_global():
form = SambaCleaningForm(request.form)
if request.method == 'POST' and form.validate():
print("Input:")
print(form.workgroup.data)
print(form.server_string.data)
return redirect(url_for('samba_global'))
file = open(staticDir + "/conf/samba_global.conf")
conf = list()
while True:
line = file.readline()
if line != '':
conf.append(line.rstrip())
else:
break
return render_template('samba_global.html', form=form, conf=conf)
@app.route('/samba/add', methods=['GET', 'POST'])
def samba_add():
form = SambaAddForm(request.form)
if request.method == 'POST' and form.validate():
return redirect(url_for('samba'))
return render_template('samba_add.html', form=form)