Functions for publish website by ftp or sftp
This commit is contained in:
@@ -6,6 +6,8 @@ from PIL import Image
|
|||||||
from pathlib import Path, PurePath, PurePosixPath
|
from pathlib import Path, PurePath, PurePosixPath
|
||||||
from shutil import rmtree, copytree
|
from shutil import rmtree, copytree
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from flask import session
|
||||||
|
|
||||||
|
|
||||||
class DataSite:
|
class DataSite:
|
||||||
user_folder = None
|
user_folder = None
|
||||||
@@ -216,23 +218,42 @@ class DataSite:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def publish(self, serverInfos=dict(), password=str()):
|
def publish(self, serverInfos=dict(), password=str()):
|
||||||
userDir = Path(PurePosixPath(self.user_folder))
|
userDir = Path(PurePosixPath(self.user_folder))
|
||||||
|
|
||||||
|
|
||||||
command = "lftp -u \"{}\",\"{}\" -p {} {} -e ' mirror -R public {}; chmod -R o+rx ./; bye;'".format(serverInfos['username'],
|
upload = "lftp -u \"{}\",\"{}\" -p {} {} -e ' mirror -R public {}; chmod -R o+rx ./; bye;'".format(serverInfos['username'],
|
||||||
password,
|
password,
|
||||||
serverInfos['Port'],
|
serverInfos['Port'],
|
||||||
serverInfos['Address'],
|
serverInfos['Address'],
|
||||||
serverInfos['folder'])
|
serverInfos['folder'])
|
||||||
|
|
||||||
|
set_permissions = "lftp -u \"{}\",\"{}\" -p {} {} -e 'chmod -R o+rx ./; bye;'".format(serverInfos['username'],
|
||||||
|
password,
|
||||||
|
serverInfos['Port'],
|
||||||
|
serverInfos['Address'],
|
||||||
|
serverInfos['folder'])
|
||||||
try:
|
try:
|
||||||
subprocess.call(command, shell=True, cwd=str(userDir))
|
subprocess.call(upload, shell=True, cwd=str(userDir))
|
||||||
|
self.update_status_publish("Uploaded")
|
||||||
|
subprocess.call(set_permissions, shell=True, cwd=str(userDir))
|
||||||
|
|
||||||
except ChildProcessError:
|
except ChildProcessError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def update_status_publish (self, status: str):
|
||||||
|
self.datas['publication_status'] = status
|
||||||
|
self.filej.write_text(json.dumps(self.datas, indent=5))
|
||||||
|
|
||||||
|
def get_status_publish(self):
|
||||||
|
if 'publication_status' in self.datas.keys():
|
||||||
|
return self.datas['publication_status']
|
||||||
|
else:
|
||||||
|
return "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ from app.forms import Login
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from app.utils import login_required
|
from app.utils import login_required
|
||||||
from flask_wtf.csrf import CSRFProtect
|
from flask_wtf.csrf import CSRFProtect
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
csrf = CSRFProtect(app)
|
csrf = CSRFProtect(app)
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ bcrypt = Bcrypt(app)
|
|||||||
|
|
||||||
EXT_IMG = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
EXT_IMG = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
||||||
|
|
||||||
|
|
||||||
@app.route('/login', methods=['GET', 'POST'])
|
@app.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
form = Login()
|
form = Login()
|
||||||
@@ -44,6 +47,7 @@ def login():
|
|||||||
|
|
||||||
if bcrypt.check_password_hash(passwd_bcrypt, password) is True:
|
if bcrypt.check_password_hash(passwd_bcrypt, password) is True:
|
||||||
session['username'] = login
|
session['username'] = login
|
||||||
|
session['upload'] = None
|
||||||
resp = redirect(url_for('edit', _external=True))
|
resp = redirect(url_for('edit', _external=True))
|
||||||
else:
|
else:
|
||||||
flash(u'Mauvais mot de passe', 'error')
|
flash(u'Mauvais mot de passe', 'error')
|
||||||
@@ -68,19 +72,17 @@ def edit(page):
|
|||||||
user = '%s'% escape(session['username'])
|
user = '%s'% escape(session['username'])
|
||||||
page = '%s' % escape(page)
|
page = '%s' % escape(page)
|
||||||
db = DataSite(user, USERS_FOLDER)
|
db = DataSite(user, USERS_FOLDER)
|
||||||
mypages = db.get_pages()
|
|
||||||
theme = db.datas['config']['theme']
|
|
||||||
menu = db.datas['menu']
|
|
||||||
myblocs = db.get_blocs(page)['blocs']
|
myblocs = db.get_blocs(page)['blocs']
|
||||||
|
print(myblocs)
|
||||||
return render_template('/edit.html.tpl',
|
return render_template('/edit.html.tpl',
|
||||||
blocEdit="",
|
blocEdit="",
|
||||||
config=db.datas['config'],
|
config=db.datas['config'],
|
||||||
menu=menu,
|
menu=db.datas['menu'],
|
||||||
theme=theme,
|
theme=db.datas['config']['theme'],
|
||||||
pagesList=mypages,
|
pagesList=db.get_pages(),
|
||||||
page=page,
|
page=page,
|
||||||
myblocs=myblocs
|
myblocs=myblocs,
|
||||||
|
serverInfos=db.datas['publish']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ def edit_photo(page, image, bloc):
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
myblocs[bloc][image] = db.update_img(image, form)
|
myblocs[bloc][image] = db.update_img(image, form)
|
||||||
db.save_blocs(page, myblocs)
|
db.save_blocs(page, myblocs)
|
||||||
form = MyBlocs.makeForm(db.datas['blocs'][bloc])
|
form = MyBlocs.make_form(db.datas['blocs'][bloc])
|
||||||
if "hx-request" in request.headers:
|
if "hx-request" in request.headers:
|
||||||
return make_response(('Image modified', 200))
|
return make_response(('Image modified', 200))
|
||||||
else:
|
else:
|
||||||
@@ -149,7 +151,7 @@ def drop_upload(page, bloc):
|
|||||||
img.thumbnail((640,480))
|
img.thumbnail((640,480))
|
||||||
img.save(os.path.join(save_path, 'thumbnails', filename ) )
|
img.save(os.path.join(save_path, 'thumbnails', filename ) )
|
||||||
|
|
||||||
myblocs[bloc][filename] = db.addImg(filename)
|
myblocs[bloc][filename] = db.add_img(filename)
|
||||||
db.save_blocs(page, myblocs)
|
db.save_blocs(page, myblocs)
|
||||||
return make_response(('Chunk upload succesfull', 200))
|
return make_response(('Chunk upload succesfull', 200))
|
||||||
|
|
||||||
@@ -209,7 +211,7 @@ def edit_bloc(page, blocname):
|
|||||||
bg_custom = 'bg_custom_'+bloc['name']+filename
|
bg_custom = 'bg_custom_'+bloc['name']+filename
|
||||||
file.save(os.path.join(USERS_FOLDER, user, 'public', 'img', bg_custom ))
|
file.save(os.path.join(USERS_FOLDER, user, 'public', 'img', bg_custom ))
|
||||||
if 'bg_img' in bloc.keys():
|
if 'bg_img' in bloc.keys():
|
||||||
db.delImg(bloc, bloc['bg_img'])
|
db.del_img(bloc, bloc['bg_img'])
|
||||||
|
|
||||||
|
|
||||||
myblocs[blocname]['bg_img'] = bg_custom
|
myblocs[blocname]['bg_img'] = bg_custom
|
||||||
@@ -403,6 +405,39 @@ def favicon():
|
|||||||
return make_response(('Ok! ', 200))
|
return make_response(('Ok! ', 200))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/publish_progress/', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def publish_progress():
|
||||||
|
user = '%s' % escape(session['username'])
|
||||||
|
db = DataSite(user, USERS_FOLDER)
|
||||||
|
progress = 0
|
||||||
|
|
||||||
|
error = False
|
||||||
|
completed = False
|
||||||
|
status = db.get_status_publish()
|
||||||
|
|
||||||
|
match status:
|
||||||
|
case "Generated" :
|
||||||
|
progress = 30
|
||||||
|
case "Login Incorrect" | "Upload error" :
|
||||||
|
progress = 100
|
||||||
|
error = True
|
||||||
|
case "Identification verified":
|
||||||
|
progress = 50
|
||||||
|
status = "Upload ..."
|
||||||
|
case "Uploaded":
|
||||||
|
progress = 80
|
||||||
|
status = "Set permissions ..."
|
||||||
|
case str(x) if "Uploaded at:" in x:
|
||||||
|
progress = 100
|
||||||
|
completed = True
|
||||||
|
status = status.replace("Uploaded at:", "")
|
||||||
|
|
||||||
|
return render_template('admin/_publish-progress.html', progress=progress,
|
||||||
|
status=status,
|
||||||
|
error = error,
|
||||||
|
completed = completed)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/publish', methods=['POST'])
|
@app.route('/publish', methods=['POST'])
|
||||||
@@ -416,12 +451,13 @@ def publish():
|
|||||||
test_alphanum = "^[A-Za-z0-9/_-]*$"
|
test_alphanum = "^[A-Za-z0-9/_-]*$"
|
||||||
|
|
||||||
|
|
||||||
serverAddress = str(request.form['serverAddress'])
|
|
||||||
serverPort = str(request.form['serverPort'])
|
|
||||||
username = str(request.form['username'])
|
|
||||||
password = str(request.form['password'])
|
password = str(request.form['password'])
|
||||||
folder = str(request.form['folder'])
|
|
||||||
|
|
||||||
|
serverInfos = dict()
|
||||||
|
serverInfos['Address'] = str(request.form['serverAddress'])
|
||||||
|
serverInfos['Port'] = str(request.form['serverPort'])
|
||||||
|
serverInfos['username'] = str(request.form['username'])
|
||||||
|
serverInfos['folder'] = str(request.form['folder'])
|
||||||
|
|
||||||
for page in listPages:
|
for page in listPages:
|
||||||
myblocs = db.get_blocs(page)['blocs']
|
myblocs = db.get_blocs(page)['blocs']
|
||||||
@@ -433,6 +469,7 @@ def publish():
|
|||||||
myblocs=myblocs)
|
myblocs=myblocs)
|
||||||
db.writeHTML(theme, page, htmlExport)
|
db.writeHTML(theme, page, htmlExport)
|
||||||
|
|
||||||
|
|
||||||
# Export index.html landing page
|
# Export index.html landing page
|
||||||
myblocs = db.get_blocs('')['blocs']
|
myblocs = db.get_blocs('')['blocs']
|
||||||
htmlExport = render_template('/index.html.tpl',
|
htmlExport = render_template('/index.html.tpl',
|
||||||
@@ -444,21 +481,34 @@ def publish():
|
|||||||
|
|
||||||
db.writeHTML(theme, '/', htmlExport)
|
db.writeHTML(theme, '/', htmlExport)
|
||||||
db.copy_static_files()
|
db.copy_static_files()
|
||||||
|
db.update_status_publish("Generated")
|
||||||
|
|
||||||
if serverPort == '' or serverPort.isdigit() == False :
|
|
||||||
|
if serverInfos['Port'] == '' or serverInfos['Port'].isdigit() == False :
|
||||||
serverPort = '22'
|
serverPort = '22'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if folder == '' :
|
if serverInfos['folder'] == '' :
|
||||||
folder = '/'
|
|
||||||
elif(bool(re.match(test_alphanum, folder)) == False):
|
|
||||||
folder = '/'
|
folder = '/'
|
||||||
|
elif(bool(re.match(test_alphanum, serverInfos['folder'])) == False):
|
||||||
|
serverInfos['folder'] = '/'
|
||||||
|
|
||||||
|
|
||||||
if db.publish(username, password, serverAddress, serverPort, folder) == False:
|
if db.test_server_login(serverInfos, password ) == False:
|
||||||
return make_response(('Impossible de publier le site ', 500))
|
db.update_status_publish ("Identification Incorrect")
|
||||||
|
return make_response(('Login Incorrect', 500))
|
||||||
|
else:
|
||||||
|
db.update_status_publish("Identification verified")
|
||||||
|
if db.publish(serverInfos, password) == False:
|
||||||
|
db.update_status_publish ("Upload error")
|
||||||
|
return make_response('Upload Error !')
|
||||||
|
|
||||||
|
#Generate date of success upload
|
||||||
|
now = datetime.now()
|
||||||
|
date_upload = now.strftime("%d/%m/%Y, %H:%M:%S")
|
||||||
|
db.update_status_publish ("Uploaded at: "+date_upload)
|
||||||
|
db.save_server_info(serverInfos)
|
||||||
|
|
||||||
return redirect(url_for('edit'))
|
return redirect(url_for('edit'))
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#options"> Options </a>
|
<a class="nav-link" data-toggle="pill" href="#options"> Options </a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-toggle="pill" href="#publication"> Publication </a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
@@ -13,10 +10,9 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<h4> Mes réseaux sociaux </h4>
|
<h4> Mes réseaux sociaux </h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane container fade text-center" id="publication">
|
|
||||||
<br/>
|
|
||||||
<h4> Serveur(s) où publier mon site </h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
app/templates/admin/_publish-progress.html
Normal file
12
app/templates/admin/_publish-progress.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="progress" style="height: 30px;">
|
||||||
|
<div class="progress-bar {% if completed %} bg-success {% endif %} {% if error %} bg-danger {%endif%}"
|
||||||
|
style="width:{{progress}}%">
|
||||||
|
|
||||||
|
{% if completed %}
|
||||||
|
Dernière publication avec succès le : {{ status }}
|
||||||
|
{% else %}
|
||||||
|
{{ status }} {{progress}}%
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -10,10 +10,14 @@
|
|||||||
name="serverAddress"
|
name="serverAddress"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="serverAddress"
|
id="serverAddress"
|
||||||
|
{%if serverInfos.Address %}
|
||||||
|
value="{{ serverInfos.Address }}"
|
||||||
|
{%else%}
|
||||||
placeholder="sftp://mon_serveur.com, ou ftp://mon_serveur.com"
|
placeholder="sftp://mon_serveur.com, ou ftp://mon_serveur.com"
|
||||||
|
{%endif%}
|
||||||
required>
|
required>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
L'upload a rencontrer n'a pas pu se faire.
|
La publication du site n'a pas pu se faire correctement.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -25,7 +29,12 @@
|
|||||||
max="65536"
|
max="65536"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="serverPort"
|
id="serverPort"
|
||||||
placeholder="Si vous ne savez pas ne mettez rien">
|
{%if serverInfos.Port %}
|
||||||
|
value="{{ serverInfos.Port }}"
|
||||||
|
{%else%}
|
||||||
|
placeholder="1-65535"
|
||||||
|
{%endif%}>
|
||||||
|
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -35,7 +44,11 @@
|
|||||||
name="folder"
|
name="folder"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="folder"
|
id="folder"
|
||||||
placeholder="Spécifier un dossier sinon ne mettez rien">
|
{%if serverInfos.folder %}
|
||||||
|
value="{{ serverInfos.folder }}"
|
||||||
|
{%else%}
|
||||||
|
placeholder="Spécifier un dossier sinon ne mettez rien"
|
||||||
|
{%endif%}>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -45,6 +58,12 @@
|
|||||||
name="username"
|
name="username"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
|
{%if serverInfos.username %}
|
||||||
|
value="{{ serverInfos.username }}"
|
||||||
|
{%else%}
|
||||||
|
placeholder="Nom d'utilisateur fourni par votre hébergeur"
|
||||||
|
{%endif%}
|
||||||
|
|
||||||
placeholder="Nom d'utilisateur fourni par votre hébergeur"
|
placeholder="Nom d'utilisateur fourni par votre hébergeur"
|
||||||
required>
|
required>
|
||||||
|
|
||||||
@@ -61,8 +80,10 @@
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
<div hx-get="{{ url_for('publish_progress') }}" hx-trigger="load, every 1s">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
<button type="submit" class="btn btn-success"
|
<button type="submit" class="btn btn-success"
|
||||||
onclick="valid_nameBloc()"> Publier le site </button>
|
onclick="valid_nameBloc()"> Publier le site </button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user