block item support attempt
This commit is contained in:
parent
9cee885966
commit
a8c472dfe8
6 changed files with 150 additions and 3 deletions
|
@ -13,7 +13,7 @@ from werkzeug.contrib.fixers import ProxyFix
|
||||||
from config import config
|
from config import config
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
sys.stderr.write("My uid={}, gid={}, euid={}, egid={}".format(os.getuid(), os.getgid(), os.geteuid(), os.getegid()))
|
sys.stderr.write("worker uid={} gid={}".format(os.getuid(), os.getgid()))
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
|
@ -88,6 +88,7 @@ class User(db.Model, UserMixin):
|
||||||
currency = db.Column(db.String, default='BGN')
|
currency = db.Column(db.String, default='BGN')
|
||||||
inv_transactions = db.relationship('Transaction', backref='owner', lazy='dynamic')
|
inv_transactions = db.relationship('Transaction', backref='owner', lazy='dynamic')
|
||||||
inv_orders = db.relationship('Order', 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_servers = db.relationship('Server', backref='owner', lazy='dynamic')
|
||||||
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
|
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
|
||||||
|
@ -428,3 +429,19 @@ class InvoiceItem(db.Model):
|
||||||
def total(self):
|
def total(self):
|
||||||
return self.item_quantity * self.item_price
|
return self.item_quantity * self.item_price
|
||||||
|
|
||||||
|
#SUPPORT
|
||||||
|
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')
|
||||||
|
|
||||||
|
class SupportLine(db.Model):
|
||||||
|
__tablename__ = 'support_line'
|
||||||
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
|
topic_id = db.Column(db.ForeignKey('support_topic.pid'))
|
||||||
|
line = db.Column(db.Unicode)
|
||||||
|
timestamp = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectField, DecimalField
|
from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectField, DecimalField
|
||||||
|
from flask_pagedown.fields import PageDownField
|
||||||
from wtforms import validators, ValidationError
|
from wtforms import validators, ValidationError
|
||||||
from wtforms.fields.html5 import EmailField, DecimalRangeField
|
from wtforms.fields.html5 import EmailField, DecimalRangeField
|
||||||
|
|
||||||
|
@ -20,3 +21,7 @@ class OrderForm(FlaskForm):
|
||||||
|
|
||||||
submit = SubmitField('DEPLOY')
|
submit = SubmitField('DEPLOY')
|
||||||
|
|
||||||
|
class MessageForm(FlaskForm):
|
||||||
|
line = PageDownField('Enter your message...', validators=[validators.DataRequired()])
|
||||||
|
submit = SubmitField('Submit')
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,14 @@ from flask_login import login_required, login_user, logout_user, current_user
|
||||||
from flask_sqlalchemy import get_debug_queries
|
from flask_sqlalchemy import get_debug_queries
|
||||||
|
|
||||||
from . import panel
|
from . import panel
|
||||||
from .forms import OrderForm
|
from .forms import OrderForm, MessageForm
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..email import send_email
|
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, contact_proxmaster
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
from datetime import date, time, datetime
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
@panel.after_app_request
|
@panel.after_app_request
|
||||||
def after_request(response):
|
def after_request(response):
|
||||||
|
@ -97,3 +99,62 @@ def dashboard(user_pid):
|
||||||
continue
|
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)
|
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("/support", methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def list_support():
|
||||||
|
""" general enquiry and list all open support tasks """
|
||||||
|
cuser = current_user
|
||||||
|
alltopics = cuser.inv_topics.all()
|
||||||
|
return render_template('panel/support_list.html', inv_topics=alltopics)
|
||||||
|
|
||||||
|
@panel.route("/support/<string: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)
|
||||||
|
|
||||||
|
support_topic = EmptySupport()
|
||||||
|
return render_template('panel/support_item.html', form=form, support=support_topic)
|
||||||
|
else:
|
||||||
|
if support_topic.user_id != cuser.user_id:
|
||||||
|
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 None
|
||||||
|
#create new topic
|
||||||
|
new_topic = SupportTopic(user_id=int(cuser.pid), hashtag=str(topic))
|
||||||
|
db.session.add(new_topic)
|
||||||
|
new_line = SupportLine(topic_id=int(new_topic.pid), line=str(form.line.data))
|
||||||
|
db.session.add(new_line)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if support_topic.user_id == cuser.user_id:
|
||||||
|
new_line = SupportLine(topic_id=int(support_topic.pid), line=str(form.line.data))
|
||||||
|
db.session.add(new_line)
|
||||||
|
else:
|
||||||
|
abort(403) #TODO: hidden 404
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
return None
|
||||||
|
|
24
app/templates/panel/support_item.html
Normal file
24
app/templates/panel/support_item.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{% block support_item %}
|
||||||
|
<div class="panel panel-danger" style="margin-top: 2px">
|
||||||
|
<div class="panel-heading" href="#support{{ support.pid }}" aria-expanded="true" aria-controls="support{{ support.pid }}" role="tab" id="support{{ support.pid }}">
|
||||||
|
<font color="green">{{ support.hashtag }} started at {{ support.timestamp }}</font></b></a>
|
||||||
|
i </div>
|
||||||
|
</div> <!-- end of heading -->
|
||||||
|
|
||||||
|
<br />
|
||||||
|
{% for line in inv_lines %}
|
||||||
|
{{ line.timestamp }}
|
||||||
|
{{ line.line }} <br />
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<form method="POST" action="{{ url_for('panel.support', topic=support.hashtag) }}">
|
||||||
|
{{ form.line | safe }}
|
||||||
|
{% for error in form.line.errors %}
|
||||||
|
{{ error }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{{ form.csrf_token() }}
|
||||||
|
{{ form.submit }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
40
app/templates/panel/support_list.html
Normal file
40
app/templates/panel/support_list.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{ super() }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$('a[data-toggle="tooltip"]').tooltip({
|
||||||
|
animated: 'fade',
|
||||||
|
placement: 'bottom',
|
||||||
|
html: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
{% if inv_topics != [] %}
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-info" id="deployments">
|
||||||
|
<div class="panel-heading">Support</div>
|
||||||
|
<div class="panel-body"><p>
|
||||||
|
<div class="panel-group" id="<s" role="tablist" aria-multiselectable="true">
|
||||||
|
{% for topic in inv_topics %}
|
||||||
|
{% include "panel/support_item.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in a new issue