From c230ddcfc8801e4198799da91b139e4a8bab1c32 Mon Sep 17 00:00:00 2001
From: deflax
Date: Mon, 23 Apr 2018 01:00:05 +0300
Subject: [PATCH] ingegrate support back to the panel
---
app/__init__.py | 3 -
app/livesupport/__init__.py | 3 -
app/livesupport/forms.py | 27 ------
app/livesupport/routes.py | 83 -------------------
app/models.py | 17 +++-
app/panel/forms.py | 3 +
app/panel/routes.py | 67 ++++++++++++++-
app/templates/nav.html | 2 +-
.../{livesupport => panel}/support_item.html | 15 +---
.../{livesupport => panel}/support_list.html | 2 +-
app/templates/panel/vdc_pool.html | 16 +++-
11 files changed, 102 insertions(+), 136 deletions(-)
delete mode 100644 app/livesupport/__init__.py
delete mode 100644 app/livesupport/forms.py
delete mode 100644 app/livesupport/routes.py
rename app/templates/{livesupport => panel}/support_item.html (61%)
rename app/templates/{livesupport => panel}/support_list.html (94%)
diff --git a/app/__init__.py b/app/__init__.py
index d8c7e6d..f8a56ee 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -68,9 +68,6 @@ app.register_blueprint(smanager_blueprint, url_prefix='/smanager')
from .dmanager import dmanager as dmanager_blueprint
app.register_blueprint(dmanager_blueprint, url_prefix='/dmanager')
-from .livesupport import livesupport as livesupport_blueprint
-app.register_blueprint(livesupport_blueprint, url_prefix='/support')
-
from .uinvoice import uinvoice as uinvoice_blueprint
app.register_blueprint(uinvoice_blueprint, url_prefix='/uinvoice')
diff --git a/app/livesupport/__init__.py b/app/livesupport/__init__.py
deleted file mode 100644
index e991060..0000000
--- a/app/livesupport/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from flask import Blueprint
-livesupport = Blueprint('livesupport', __name__)
-from . import routes
diff --git a/app/livesupport/forms.py b/app/livesupport/forms.py
deleted file mode 100644
index ee6f96f..0000000
--- a/app/livesupport/forms.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from flask_wtf import FlaskForm
-from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectField, DecimalField
-from flask_pagedown.fields import PageDownField
-from wtforms import validators, ValidationError
-from wtforms.fields.html5 import EmailField, DecimalRangeField
-
-from .. import db
-
-class OrderForm(FlaskForm):
- region_choices = [(1, 'Plovdiv, Bulgaria'), (2, 'International Space Station')]
- region = SelectField('Region:', choices=region_choices, coerce=int)
-
- recipe_choices = [(1, 'RootVPS')]
- recipe = SelectField('Type:', choices=recipe_choices, coerce=int)
-
- cpu = DecimalRangeField('Processor Cores', default=2)
- memory = DecimalRangeField('Memory', default=2048)
- storage = DecimalRangeField('Storage', default=20)
-
- alias = StringField('Name:', [validators.Regexp(message='ex.: myservice1.com, myservice2.local', regex='^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$'), validators.Length(6,64)])
-
- submit = SubmitField('DEPLOY')
-
-class MessageForm(FlaskForm):
- line = PageDownField('Enter your message...', validators=[validators.DataRequired()])
- submit = SubmitField('Submit')
-
diff --git a/app/livesupport/routes.py b/app/livesupport/routes.py
deleted file mode 100644
index 5f5c0e2..0000000
--- a/app/livesupport/routes.py
+++ /dev/null
@@ -1,83 +0,0 @@
-from flask import render_template, abort, redirect, url_for, abort, flash, request, current_app, make_response, g
-from flask_login import login_required, login_user, logout_user, current_user
-from flask_sqlalchemy import get_debug_queries
-
-from . import livesupport
-from .forms import MessageForm
-from .. import db
-from ..email import send_email
-from ..models import User, Permission, SupportTopic, SupportLine, contact_proxmaster
-
-import base64
-from datetime import date, time, datetime
-from dateutil.relativedelta import relativedelta
-
-@livesupport.after_app_request
-def after_request(response):
- for query in get_debug_queries():
- if query.duration >= current_app.config['SLOW_DB_QUERY_TIME']:
- current_app.logger.warning('Slow query: %s\nParameters: %s\nDuration: %fs\nContext: %s\n' % (query.statement, query.parameters, query.duration, query.context))
- return response
-
-#SUPPORT
-@livesupport.route("/support", methods=['GET'])
-@login_required
-def support_list():
- """ general enquiry and list all open support tasks """
- cuser = current_user
- form = MessageForm()
-
- alltopics = cuser.inv_topics.all()
- return render_template('livesupport/support_list.html', form=form, inv_topics=alltopics)
-
-@livesupport.route("/support//", methods=['GET', 'POST'])
-@login_required
-def support(topic):
- """ block item for support chatbox. invoked from vdc_pool or supportlist """
- cuser = current_user
- form = MessageForm()
-
- if request.method == "GET":
- support_topic = SupportTopic.query.filter_by(hashtag=str(topic)).first()
- if support_topic == None:
- class EmptySupport():
- hashtag=str(topic)
- timestamp=datetime.utcnow()
- support_topic = EmptySupport()
- return render_template('livesupport/support_item.html', form=form, support=support_topic)
- else:
- if support_topic.user_id != cuser.pid:
- abort(403) #TODO: hidden 403. there is a topic like that but its not yours!
- else:
- #topic is yours. show it.
- return render_template('livesupport/support_item.html', form=form, support=support_topic)
-
- if request.method == "POST" and form.validate_on_submit():
- support_topic = SupportTopic.query.filter_by(hashtag=str(topic)).first()
- if support_topic == None:
- #no topic. create one?
- if cuser.inv_topics.all() != []:
- #check if other topics exist, and ratelimit
- last_topic = cuser.inv_topics.order_by(SupportTopic.timestamp.desc()).first()
- now = datetime.utcnow()
- time_last_topic = last_topic.timestamp
- expiry = time_last_topic + relativedelta(time_last_topic, minutes=+5)
- if now < expiry:
- flash('ratelimit. try again later')
- return redirect(url_for('livesupport.support_list'))
- #create new topic
- new_topic = SupportTopic(user_id=cuser.pid, hashtag=str(topic))
- db.session.add(new_topic)
- new_line = SupportLine(topic_id=new_topic.pid, line=str(form.line.data))
- db.session.add(new_line)
-
- else:
- if support_topic.user_id == cuser.pid:
- new_line = SupportLine(topic_id=support_topic.pid, line=form.line.data)
- db.session.add(new_line)
- else:
- abort(403) #TODO: hidden 404
-
- db.session.commit()
- return redirect(url_for('livesupport.support_list'))
-
diff --git a/app/models.py b/app/models.py
index d731759..ce37d63 100644
--- a/app/models.py
+++ b/app/models.py
@@ -88,7 +88,6 @@ class User(db.Model, UserMixin):
currency = db.Column(db.String, default='BGN')
inv_transactions = db.relationship('Transaction', backref='owner', lazy='dynamic')
inv_orders = db.relationship('Order', backref='owner', lazy='dynamic')
- inv_topics = db.relationship('SupportTopic', backref='owner', lazy='dynamic')
inv_servers = db.relationship('Server', backref='owner', lazy='dynamic')
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
@@ -99,6 +98,7 @@ class User(db.Model, UserMixin):
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
+
if self.role is None:
if self.email == current_app.config['ADMIN_EMAIL']:
#if email match config admin name create admin user
@@ -110,6 +110,7 @@ class User(db.Model, UserMixin):
if self.avatar_hash is None and self.email is not None:
self.avatar_hash = hashlib.md5(self.email.encode('utf-8')).hexdigest()
+
if self.otp_secret is None:
# generate a random secret
self.otp_secret = base64.b32encode(os.urandom(10)).decode('utf-8')
@@ -283,6 +284,7 @@ class Deployment(db.Model):
pid = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.ForeignKey('users.pid')) #FK
server_id = db.Column(db.ForeignKey('servers.pid')) #FK
+ topic_id = db.Column(db.ForeignKey('support_topic.pid')) #FK
date_created = db.Column(db.DateTime, default=datetime.utcnow)
deleted = db.Column(db.Boolean, default=False)
@@ -302,6 +304,16 @@ class Deployment(db.Model):
inv_pubvlans = db.relationship('PubVLAN', backref='deploy', lazy='dynamic')
+ def __init__(self, **kwargs):
+ super(Deployment, self).__init__(**kwargs)
+
+ if self.topic_id is None:
+ #create new topic
+ new_topic = SupportTopic(hashtag='deploy-' + query['unit_id'])
+ db.session.add(new_topic)
+ db.session.commit()
+ self.topic_id = new_topic.pid
+
class PubVLAN(db.Model):
__tablename__ = 'pubvlans'
pid = db.Column(db.Integer, primary_key=True)
@@ -433,14 +445,15 @@ class InvoiceItem(db.Model):
class SupportTopic(db.Model):
__tablename__ = 'support_topic'
pid = db.Column(db.Integer, primary_key=True)
- user_id = db.Column(db.ForeignKey('users.pid')) #fk
hashtag = db.Column(db.String) #topic
timestamp = db.Column(db.DateTime(), default=datetime.utcnow)
inv_lines = db.relationship('SupportLine', backref='topic', lazy='dynamic')
+ inv_deployments = db.relationship('Deployment', backref='topic', lazy='dynamic')
class SupportLine(db.Model):
__tablename__ = 'support_line'
pid = db.Column(db.Integer, primary_key=True)
+ user_id = db.Column(db.ForeignKey('users.pid')) #FK
topic_id = db.Column(db.ForeignKey('support_topic.pid')) #FK
line = db.Column(db.Unicode)
timestamp = db.Column(db.DateTime(), default=datetime.utcnow)
diff --git a/app/panel/forms.py b/app/panel/forms.py
index 56ab715..ee6f96f 100644
--- a/app/panel/forms.py
+++ b/app/panel/forms.py
@@ -21,4 +21,7 @@ class OrderForm(FlaskForm):
submit = SubmitField('DEPLOY')
+class MessageForm(FlaskForm):
+ line = PageDownField('Enter your message...', validators=[validators.DataRequired()])
+ submit = SubmitField('Submit')
diff --git a/app/panel/routes.py b/app/panel/routes.py
index d8d2f57..8b5f738 100644
--- a/app/panel/routes.py
+++ b/app/panel/routes.py
@@ -3,10 +3,10 @@ from flask_login import login_required, login_user, logout_user, current_user
from flask_sqlalchemy import get_debug_queries
from . import panel
-from .forms import OrderForm
+from .forms import OrderForm, MessageForm
from .. import db
from ..email import send_email
-from ..models import User, Permission, Recipe, Order, Server, Deployment, Service, Region, Address, Domain, contact_proxmaster
+from ..models import User, Permission, Recipe, Order, Server, Deployment, Service, Region, Address, Domain, SupportTopic, SupportLine, contact_proxmaster
import base64
from datetime import date, time, datetime
@@ -99,3 +99,66 @@ def dashboard(user_pid):
continue
return render_template('panel/dashboard.html', sys_regions=sys_regions, inv_deployments=inv_deployments, inv_services=inv_services, inv_domains=inv_domains, inv_addresses=inv_addresses, rrd=rrd, status=statuses, warnflag=warnflag, regions=regions)
+
+#SUPPORT
+@panel.route("/list", methods=['GET'])
+@login_required
+def support_list():
+ """ general enquiry and list all open support tasks """
+ cuser = current_user
+ form = MessageForm()
+
+ alltopics = cuser.inv_topics.all()
+ return render_template('panel/support_list.html', form=form, inv_topics=alltopics)
+
+@panel.route("/topic//", methods=['GET', 'POST'])
+@login_required
+def support(topic):
+ """ block item for support chatbox. invoked from vdc_pool or supportlist """
+ cuser = current_user
+ form = MessageForm()
+
+ if request.method == "GET":
+ support_topic = SupportTopic.query.filter_by(hashtag=str(topic)).first()
+ if support_topic == None:
+ class EmptySupport():
+ hashtag=str(topic)
+ timestamp=datetime.utcnow()
+ support_topic = EmptySupport()
+ return render_template('panel/support_item.html', form=form, support=support_topic)
+ else:
+ if support_topic.user_id != cuser.pid:
+ abort(403) #TODO: hidden 403. there is a topic like that but its not yours!
+ else:
+ #topic is yours. show it.
+ return render_template('panel/support_item.html', form=form, support=support_topic)
+
+ if request.method == "POST" and form.validate_on_submit():
+ support_topic = SupportTopic.query.filter_by(hashtag=str(topic)).first()
+ if support_topic == None:
+ #no topic. create one?
+ if cuser.inv_topics.all() != []:
+ #check if other topics exist, and ratelimit
+ last_topic = cuser.inv_topics.order_by(SupportTopic.timestamp.desc()).first()
+ now = datetime.utcnow()
+ time_last_topic = last_topic.timestamp
+ expiry = time_last_topic + relativedelta(time_last_topic, minutes=+5)
+ if now < expiry:
+ flash('ratelimit. try again later')
+ return redirect(url_for('panel.support_list'))
+ #create new topic
+ new_topic = SupportTopic(user_id=cuser.pid, hashtag=str(topic))
+ db.session.add(new_topic)
+ new_line = SupportLine(topic_id=new_topic.pid, line=str(form.line.data))
+ db.session.add(new_line)
+
+ else:
+ if support_topic.user_id == cuser.pid:
+ new_line = SupportLine(topic_id=support_topic.pid, line=form.line.data)
+ db.session.add(new_line)
+ else:
+ abort(403) #TODO: hidden 404
+
+ db.session.commit()
+ return redirect(url_for('panel.support_list'))
+
diff --git a/app/templates/nav.html b/app/templates/nav.html
index 93c137c..a2c2d61 100644
--- a/app/templates/nav.html
+++ b/app/templates/nav.html
@@ -52,7 +52,7 @@
Transactions
Profile
- Support
+ Support
Logout
diff --git a/app/templates/livesupport/support_item.html b/app/templates/panel/support_item.html
similarity index 61%
rename from app/templates/livesupport/support_item.html
rename to app/templates/panel/support_item.html
index 391df26..e3a94f7 100644
--- a/app/templates/livesupport/support_item.html
+++ b/app/templates/panel/support_item.html
@@ -1,16 +1,5 @@
{% block support_item %}
-{% if support.inv_lines != [] %}
-
+{% if support != None %}
@@ -25,7 +14,7 @@
{% endfor %}
{% endif %}
-
diff --git a/app/templates/panel/vdc_pool.html b/app/templates/panel/vdc_pool.html
index 1bd19a2..9539bf0 100644
--- a/app/templates/panel/vdc_pool.html
+++ b/app/templates/panel/vdc_pool.html
@@ -22,6 +22,7 @@
@@ -92,7 +93,20 @@
-
+
+
+
+
+
+
+ {% with support=deploy.discussion %}
+ {% include "panel/support_item.html" %}
+ {% endwith %}
+
+
+
+
+