diff --git a/app/__init__.py b/app/__init__.py index 1c5f55d..f8a56ee 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -13,7 +13,7 @@ from werkzeug.contrib.fixers import ProxyFix from config import config 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() app = Flask(__name__) diff --git a/app/models.py b/app/models.py index 8a38999..947b2b5 100644 --- a/app/models.py +++ b/app/models.py @@ -88,6 +88,7 @@ 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') @@ -428,3 +429,19 @@ class InvoiceItem(db.Model): def total(self): 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) + diff --git a/app/panel/forms.py b/app/panel/forms.py index a46d3a1..ee6f96f 100644 --- a/app/panel/forms.py +++ b/app/panel/forms.py @@ -1,5 +1,6 @@ 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 @@ -20,3 +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 e550589..8e2c2ed 100644 --- a/app/panel/routes.py +++ b/app/panel/routes.py @@ -3,12 +3,14 @@ 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, contact_proxmaster import base64 +from datetime import date, time, datetime +from dateutil.relativedelta import relativedelta @panel.after_app_request def after_request(response): @@ -97,3 +99,62 @@ 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("/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//", 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 diff --git a/app/templates/panel/support_item.html b/app/templates/panel/support_item.html new file mode 100644 index 0000000..0f37073 --- /dev/null +++ b/app/templates/panel/support_item.html @@ -0,0 +1,24 @@ +{% block support_item %} +
+ +
+ +
+ {% for line in inv_lines %} + {{ line.timestamp }} + {{ line.line }}
+ {% endfor %} + +
+ {{ form.line | safe }} + {% for error in form.line.errors %} + {{ error }}
+ {% endfor %} + + {{ form.csrf_token() }} + {{ form.submit }} +
+ +{% endblock %} diff --git a/app/templates/panel/support_list.html b/app/templates/panel/support_list.html new file mode 100644 index 0000000..af2b9e8 --- /dev/null +++ b/app/templates/panel/support_list.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} + +{% block styles %} +{{ super() }} +{% endblock %} + +{% block scripts %} +{{ super() }} + +{% endblock %} + +{% block page_content %} +
+ + {% if inv_topics != [] %} +
+
+
Support
+

+

+ {% for topic in inv_topics %} + {% include "panel/support_item.html" %} + {% endfor %} +
+
+
+
+ {% endif %} + +
+
+ +{% endblock %} +