mirror of
https://github.com/vale981/dirkules
synced 2025-03-04 17:01:40 -05:00
commit
f4cc0bc354
19 changed files with 295 additions and 180 deletions
|
@ -1,4 +1,6 @@
|
|||
from flask_wtf import csrf, CSRFProtect
|
||||
import datetime
|
||||
|
||||
from flask_wtf import CSRFProtect
|
||||
import dirkules.config as config
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
@ -12,6 +14,7 @@ csrf.init_app(app)
|
|||
app_version = app.config["VERSION"]
|
||||
|
||||
import dirkules.models
|
||||
import dirkules.samba.models
|
||||
|
||||
# create db if not exists
|
||||
db.create_all()
|
||||
|
@ -21,3 +24,15 @@ scheduler.init_app(app)
|
|||
scheduler.start()
|
||||
# import 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())
|
||||
|
|
|
@ -5,7 +5,7 @@ from logging.config import dictConfig
|
|||
from apscheduler.jobstores.base import ConflictingIdError
|
||||
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
|
||||
|
||||
VERSION = "1.0"
|
||||
VERSION = "1.0.1"
|
||||
|
||||
baseDir = os.path.abspath(os.path.dirname(__file__))
|
||||
staticDir = os.path.join(baseDir, 'static')
|
||||
|
|
|
@ -66,10 +66,10 @@ def part_for_disk(device):
|
|||
# lsblk /dev/sdd -b -o NAME,LABEL,FSTYPE,SIZE,UUID,MOUNTPOINT
|
||||
parts = []
|
||||
part_dict = list()
|
||||
keys = ['name', 'label', 'fs', 'size', 'uuid', 'mount']
|
||||
keys = ['size', 'name', 'label', 'fs', 'uuid', 'mount']
|
||||
device = "/dev/" + device
|
||||
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,
|
||||
shell=True,
|
||||
universal_newlines=True)
|
||||
|
@ -83,26 +83,24 @@ def part_for_disk(device):
|
|||
del parts[1]
|
||||
element_length = list()
|
||||
counter = 0
|
||||
last_letter = 0
|
||||
pre_value = " "
|
||||
for char in parts[0]:
|
||||
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
|
||||
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]))
|
||||
del parts[0]
|
||||
for part in parts:
|
||||
values = list()
|
||||
for start, end in zip(element_length, element_length[1:]):
|
||||
values.append(part[start:(end - 1)].strip())
|
||||
for start, next_start in zip(element_length, element_length[1:]):
|
||||
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)))
|
||||
|
||||
return part_dict
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
import subprocess
|
||||
|
||||
|
||||
# This file should read btrfs pools
|
||||
# Storage: sudo btrfs fi usage -b -T /media/data-raid
|
||||
|
||||
def get_free_space(name):
|
||||
def get_free_space(mount_point):
|
||||
lines = list()
|
||||
df = subprocess.Popen(
|
||||
["df -B K /dev/" + name],
|
||||
["df -B K " + mount_point],
|
||||
stdout=subprocess.PIPE,
|
||||
shell=True,
|
||||
universal_newlines=True)
|
||||
|
@ -20,7 +17,7 @@ def get_free_space(name):
|
|||
break
|
||||
df.stdout.close()
|
||||
for line in lines:
|
||||
newLine = ' '.join(line.split())
|
||||
newLine = newLine.split(" ")
|
||||
if name in newLine[0]:
|
||||
return int(newLine[3][:-1]) * 1024
|
||||
new_line = ' '.join(line.split())
|
||||
new_line = new_line.split(" ")
|
||||
if mount_point in new_line:
|
||||
return int(new_line[3][:-1]) * 1024
|
||||
|
|
|
@ -80,6 +80,7 @@ def get_drives():
|
|||
|
||||
def pool_gen():
|
||||
part_dict = dict()
|
||||
Pool.query.delete()
|
||||
# creates map uuid is key, partitions are values
|
||||
for part in Partitions.query.all():
|
||||
if part.uuid in part_dict:
|
||||
|
@ -97,7 +98,9 @@ def pool_gen():
|
|||
drives = drives + str(Drive.query.get(part.drive_id)) + ","
|
||||
drives = drives[:-1]
|
||||
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.mountpoint:
|
||||
memory_map = btrfsTools.get_space(value.mountpoint)
|
||||
|
@ -108,16 +111,16 @@ def pool_gen():
|
|||
['unbekannt', '1.00', 'unbekannt', '1.00'])))
|
||||
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,
|
||||
value.mountpoint, "not implemented", drives, get_pool_health(drives))
|
||||
value.mountpoint, "not implemented", drives, get_pool_health(drives), missing)
|
||||
db.session.add(pool_obj)
|
||||
|
||||
elif value.fs == "ext4":
|
||||
if value.mountpoint:
|
||||
free_space = ext4Tools.get_free_space(value.name)
|
||||
free_space = ext4Tools.get_free_space(value.mountpoint)
|
||||
else:
|
||||
free_space = 2
|
||||
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.commit()
|
||||
|
||||
|
@ -137,6 +140,23 @@ def get_pool_health(drive_list):
|
|||
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):
|
||||
"""
|
||||
removes a given drive object (including cascades) from db
|
||||
|
|
|
@ -78,9 +78,10 @@ class Pool(db.Model):
|
|||
mountopt = db.Column(db.String)
|
||||
drives = db.Column(db.String)
|
||||
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,
|
||||
drives, healthy):
|
||||
drives, healthy, missing):
|
||||
self.label = label
|
||||
self.size = size
|
||||
self.free = free
|
||||
|
@ -93,6 +94,7 @@ class Pool(db.Model):
|
|||
self.mountopt = mountopt
|
||||
self.drives = drives
|
||||
self.healthy = healthy
|
||||
self.missing = missing
|
||||
|
||||
|
||||
class Time(db.Model):
|
||||
|
@ -118,24 +120,3 @@ class Cleaning(db.Model):
|
|||
self.path = path
|
||||
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)
|
||||
|
|
4
dirkules/samba/__init__.py
Normal file
4
dirkules/samba/__init__.py
Normal 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
32
dirkules/samba/manager.py
Normal 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
34
dirkules/samba/models.py
Normal 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)
|
|
@ -5,18 +5,19 @@
|
|||
{% endblock %}
|
||||
{% block body %}
|
||||
<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">
|
||||
{% for line in conf %}
|
||||
{{ line }}<br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<t2>Veränderbare Bestandteile der<i> Samba global conf</i></t2>
|
||||
{% from "_formhelpers.html" import render_field %}
|
||||
<form method=post class="ui form error">
|
||||
<t2>Veränderbare Bestandteile der<i> Samba global conf</i></t2>
|
||||
{% from "_formhelpers.html" import render_field %}
|
||||
<form method=post class="ui form error">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ render_field(form.workgroup) }}
|
||||
{{ render_field(form.server_string) }}
|
||||
<button class="ui button" type="submit"><i class="save icon"></i> Ändern</button>
|
||||
</form>
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
47
dirkules/samba/templates/samba/index.html
Normal file
47
dirkules/samba/templates/samba/index.html
Normal 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 %}
|
38
dirkules/samba/validation.py
Normal file
38
dirkules/samba/validation.py
Normal 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
44
dirkules/samba/views.py
Normal 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'))
|
|
@ -23,7 +23,7 @@
|
|||
<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('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">
|
||||
<a class="ui item" href="{{ url_for('about') }}">über Dirkules</a>
|
||||
</div>
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Gesundheit</td>
|
||||
{% if pool.healthy %}
|
||||
{% if pool.healthy and pool.missing is none %}
|
||||
<td class="positive"><i class="icon checkmark"></i>Gesund</td>
|
||||
{% else %}
|
||||
<td class="negative"><i class="attention icon"></i>Kritisch</td>
|
||||
|
@ -99,13 +99,14 @@
|
|||
</div>
|
||||
<p>
|
||||
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>
|
||||
Solltest du einen guten Grund dafür haben, ignoriere einfach diese Meldung.
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if pool.healthy %}
|
||||
{% if pool.healthy and pool.missing is none %}
|
||||
<div class="ui positive message">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
|
@ -116,16 +117,28 @@
|
|||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="ui negative message">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
Kritischer Zustand
|
||||
{% if not pool.healthy %}
|
||||
<div class="ui negative message">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
Kritischer Zustand
|
||||
</div>
|
||||
<p>
|
||||
Mindetstens ein Laufwerk befindet sich in einem schlechten Zustand! Du solltest
|
||||
dieses schnellstmöglich tauschen.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
Mindetstens ein Laufwerk befindet sich in einem schlechten Zustand! Du solltest
|
||||
dieses schnellstmöglich tauschen.
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="ui negative message">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
Kritischer Zustand
|
||||
</div>
|
||||
<p>
|
||||
Folgende Laufwerke wurden nicht gefunden: {{ pool.missing }}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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 %}
|
|
@ -17,42 +17,6 @@ class CleaningForm(FlaskForm):
|
|||
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):
|
||||
def pre_validate(self, form):
|
||||
if self.choices is not None:
|
||||
|
|
|
@ -6,10 +6,9 @@ from dirkules import app, db, scheduler, app_version
|
|||
import dirkules.manager.serviceManager as servMan
|
||||
import dirkules.manager.driveManager as driveMan
|
||||
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
|
||||
from dirkules.validation.validators import CleaningForm, SambaCleaningForm, SambaAddForm, PoolAddForm
|
||||
from dirkules.config import staticDir
|
||||
from dirkules.validation.validators import CleaningForm, PoolAddForm
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
|
@ -146,36 +145,3 @@ def add_cleaning():
|
|||
viewManager.create_cleaning_obj(form.jobname.data, form.path.data, form.active.data)
|
||||
return redirect(url_for('cleaning'))
|
||||
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)
|
||||
|
|
Loading…
Add table
Reference in a new issue