support user to report a bug in dashboard
This commit is contained in:
parent
e765225d62
commit
f84661bb69
|
@ -0,0 +1,53 @@
|
||||||
|
from master.settings import settings
|
||||||
|
import smtplib
|
||||||
|
from utils.log import logger
|
||||||
|
from utils import env
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.header import Header
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
def send_bug_mail(username, bugmessage):
|
||||||
|
#admin_email_address = env.getenv('ADMIN_EMAIL_ADDRESS')
|
||||||
|
nulladdr = ['\'\'', '\"\"', '']
|
||||||
|
email_from_address = settings.get('EMAIL_FROM_ADDRESS')
|
||||||
|
admin_email_address = settings.get('ADMIN_EMAIL_ADDRESS')
|
||||||
|
logger.info("receive bug from %s: %s" % (username, bugmessage))
|
||||||
|
if (email_from_address in nulladdr or admin_email_address in nulladdr):
|
||||||
|
return {'success': 'false'}
|
||||||
|
#text = 'Dear '+ username + ':\n' + ' Your account in docklet has been activated'
|
||||||
|
text = '<html><h4>Dear '+ 'admin' + ':</h4>'
|
||||||
|
text += '''<p> A bug has been report by %s.</p>
|
||||||
|
<br/>
|
||||||
|
<strong> %s </strong>
|
||||||
|
<br/>
|
||||||
|
<p> Please check it !</p>
|
||||||
|
<br/><br/>
|
||||||
|
<p> Docklet Team, SEI, PKU</p>
|
||||||
|
''' % (username, bugmessage)
|
||||||
|
text += '<p>'+ str(datetime.utcnow()) + '</p>'
|
||||||
|
text += '</html>'
|
||||||
|
subject = 'A bug of Docklet has been reported'
|
||||||
|
if admin_email_address[0] == '"':
|
||||||
|
admins_addr = admin_email_address[1:-1].split(" ")
|
||||||
|
else:
|
||||||
|
admins_addr = admin_email_address.split(" ")
|
||||||
|
alladdr=""
|
||||||
|
for addr in admins_addr:
|
||||||
|
alladdr = alladdr+addr+", "
|
||||||
|
alladdr=alladdr[:-2]
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
textmsg = MIMEText(text,'html','utf-8')
|
||||||
|
msg['Subject'] = Header(subject, 'utf-8')
|
||||||
|
msg['From'] = email_from_address
|
||||||
|
msg['To'] = alladdr
|
||||||
|
msg.attach(textmsg)
|
||||||
|
s = smtplib.SMTP()
|
||||||
|
s.connect()
|
||||||
|
try:
|
||||||
|
s.sendmail(email_from_address, admins_addr, msg.as_string())
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
s.close()
|
||||||
|
return {'success':'true'}
|
|
@ -34,6 +34,7 @@ from utils.model import User,db
|
||||||
from httplib2 import Http
|
from httplib2 import Http
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
from master.settings import settings
|
from master.settings import settings
|
||||||
|
from master.bugreporter import send_bug_mail
|
||||||
|
|
||||||
external_login = env.getenv('EXTERNAL_LOGIN')
|
external_login = env.getenv('EXTERNAL_LOGIN')
|
||||||
if(external_login == 'TRUE'):
|
if(external_login == 'TRUE'):
|
||||||
|
@ -472,6 +473,13 @@ def query_self_notifications_infos(cur_user, user, form):
|
||||||
result = G_notificationmgr.query_self_notifications_infos(cur_user=cur_user, form=form)
|
result = G_notificationmgr.query_self_notifications_infos(cur_user=cur_user, form=form)
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
@app.route("/bug/report/", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def report_bug(cur_user, user, form):
|
||||||
|
logger.info("handle request: bug/report")
|
||||||
|
result = send_bug_mail(user, form.get("bugmessage", None))
|
||||||
|
return json.dumps(result)
|
||||||
|
|
||||||
@app.route("/billing/beans/", methods=['POST'])
|
@app.route("/billing/beans/", methods=['POST'])
|
||||||
@auth_key_required
|
@auth_key_required
|
||||||
def billing_beans():
|
def billing_beans():
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
<td>{{image['name']}}</td>
|
<td>{{image['name']}}</td>
|
||||||
<td>private</td>
|
<td>private</td>
|
||||||
<td>{{user}}</td>
|
<td>{{user}}</td>
|
||||||
<td><a href="/image/{{masterips[0].split("@")[1]}}/description/{{image['name']}}_{{user}}_private/" target="_blank">{{image['description']}}</a></td>
|
<td><a href="/image/{{masterips[0].split("@")[0]}}/description/{{image['name']}}_{{user}}_private/" target="_blank">{{image['description']}}</a></td>
|
||||||
<td><div class="i-checks"><label><input type="radio" name="image" value="{{image['name']}}_{{user}}_private"></label></div></td>
|
<td><div class="i-checks"><label><input type="radio" name="image" value="{{image['name']}}_{{user}}_private"></label></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
<td>{{image['name']}}</td>
|
<td>{{image['name']}}</td>
|
||||||
<td>public</td>
|
<td>public</td>
|
||||||
<td>{{p_user}}</td>
|
<td>{{p_user}}</td>
|
||||||
<td><a href="/image/{{masterips[0].split("@")[1]}}/description/{{image['name']}}_{{p_user}}_public/" target="_blank">{{image['description']}}</a></td>
|
<td><a href="/image/{{masterips[0].split("@")[0]}}/description/{{image['name']}}_{{p_user}}_public/" target="_blank">{{image['description']}}</a></td>
|
||||||
<td><div class="i-checks"><label><input type="radio" name="image" value="{{image['name']}}_{{p_user}}_public"></label></div></td>
|
<td><div class="i-checks"><label><input type="radio" name="image" value="{{image['name']}}_{{p_user}}_public"></label></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -109,6 +109,23 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<!-- Control Sidebar Toggle Button -->
|
<!-- Control Sidebar Toggle Button -->
|
||||||
|
<li class="dropdown user user-menu">
|
||||||
|
<!-- Menu Toggle Button -->
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<strong>Bug Report</strong>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<!-- The user image in the menu -->
|
||||||
|
<form action="/bug/report/" method="POST">
|
||||||
|
<textarea id="bugmessage" name="bugmessage" style="width:250px; height:200px"></textarea>
|
||||||
|
<li class="user-footer" style="background-color:#e6e6e6">
|
||||||
|
<div class="pull-right">
|
||||||
|
<button type="submit" class="btn btn-default btn-flat">Submit</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</form>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/document/" target="_blank"><strong>Help</strong></a>
|
<a href="/document/" target="_blank"><strong>Help</strong></a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -220,10 +237,10 @@
|
||||||
<footer class="main-footer">
|
<footer class="main-footer">
|
||||||
<!-- To the right -->
|
<!-- To the right -->
|
||||||
<div class="pull-right hidden-xs">
|
<div class="pull-right hidden-xs">
|
||||||
<i><a href="http://github.com/unias/docklet">Docklet {{ version }}</a></i>
|
<i><a href="https://github.com/unias/docklet">Docklet {{ version }}</a></i>
|
||||||
</div>
|
</div>
|
||||||
<!-- Default to the left -->
|
<!-- Default to the left -->
|
||||||
<strong>Copyright</strong>© 2017 <a href="http://unias.github.io/docklet">UniAS</a>@<a href="http://www.sei.pku.edu.cn"> SEI, PKU</a>
|
<strong>Copyright</strong>© 2017 <a href="https://unias.github.io/docklet">UniAS</a>@<a href="http://www.sei.pku.edu.cn"> SEI, PKU</a>
|
||||||
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,12 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row" style="font-size:16px; color:white; padding:16px">
|
<div class="row" style="font-size:16px; color:white; padding:16px">
|
||||||
<div class="pull-right" >
|
<div class="pull-right" >
|
||||||
<a class="linkbtn" href="http://docklet.unias.org/docklet-book/userguide/_book/">Document</a>
|
<a class="linkbtn" href="https://unias.github.io/docklet/userguide/">Document</a>
|
||||||
·
|
·
|
||||||
<a class="linkbtn" href="/login/" >Sign In</a>
|
<a class="linkbtn" href="/login/" >Sign In</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="linkbtn" href="http://docklet.unias.org"><strong>Docklet Cloud OS</strong></a>
|
<a class="linkbtn" href="https://docklet.unias.org"><strong>Docklet Cloud OS</strong></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
<h1>SUCCESS</h1>
|
<h1>SUCCESS</h1>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
<pre>{{message}}</pre>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
<a href="/dashboard/"><span class="btn btn-w-m btn-success">Click Here Back To The Workspace</span></a>
|
<a href="/dashboard/"><span class="btn btn-w-m btn-success">Click Here Back To The Workspace</span></a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -36,6 +36,7 @@ from webViews.admin import *
|
||||||
from webViews.monitor import *
|
from webViews.monitor import *
|
||||||
from webViews.beansapplication import *
|
from webViews.beansapplication import *
|
||||||
from webViews.cloud import *
|
from webViews.cloud import *
|
||||||
|
from webViews.reportbug import *
|
||||||
from webViews.authenticate.auth import login_required, administration_required,activated_required
|
from webViews.authenticate.auth import login_required, administration_required,activated_required
|
||||||
from webViews.authenticate.register import registerView
|
from webViews.authenticate.register import registerView
|
||||||
from webViews.authenticate.login import loginView, logoutView
|
from webViews.authenticate.login import loginView, logoutView
|
||||||
|
@ -112,13 +113,18 @@ def dashboard():
|
||||||
|
|
||||||
@app.route("/document/", methods=['GET'])
|
@app.route("/document/", methods=['GET'])
|
||||||
def redirect_dochome():
|
def redirect_dochome():
|
||||||
return redirect("http://unias.github.io/docklet/userguide")
|
return redirect("https://unias.github.io/docklet/userguide/")
|
||||||
|
|
||||||
@app.route("/config/", methods=['GET'])
|
@app.route("/config/", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def config():
|
def config():
|
||||||
return configView.as_view()
|
return configView.as_view()
|
||||||
|
|
||||||
|
@app.route("/bug/report/", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def reportBug():
|
||||||
|
reportBugView.bugmessage = request.form['bugmessage']
|
||||||
|
return reportBugView.as_view()
|
||||||
|
|
||||||
@app.route("/workspace/create/", methods=['GET'])
|
@app.route("/workspace/create/", methods=['GET'])
|
||||||
#@activated_required
|
#@activated_required
|
||||||
|
@ -601,7 +607,6 @@ def adminpage():
|
||||||
def updatesettings():
|
def updatesettings():
|
||||||
return updatesettingsView.as_view()
|
return updatesettingsView.as_view()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/index/', methods=['GET'])
|
@app.route('/index/', methods=['GET'])
|
||||||
def jupyter_control():
|
def jupyter_control():
|
||||||
return redirect('/dashboard/')
|
return redirect('/dashboard/')
|
||||||
|
|
|
@ -38,7 +38,8 @@ class dockletRequest():
|
||||||
'user',
|
'user',
|
||||||
'beans',
|
'beans',
|
||||||
'notification',
|
'notification',
|
||||||
'settings'
|
'settings',
|
||||||
|
'bug'
|
||||||
}
|
}
|
||||||
if ":" not in endpoint:
|
if ":" not in endpoint:
|
||||||
endpoint = "http://"+endpoint+":"+master_port
|
endpoint = "http://"+endpoint+":"+master_port
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
from flask import session,render_template,request,redirect
|
||||||
|
from webViews.view import normalView
|
||||||
|
from webViews.dockletrequest import dockletRequest
|
||||||
|
|
||||||
|
|
||||||
|
class reportBugView(normalView):
|
||||||
|
template_path = "opsuccess.html"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get(self):
|
||||||
|
dockletRequest.post("/bug/report/", {'bugmessage': self.bugmessage})
|
||||||
|
return self.render(self.template_path, message="Thank You!")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def post(self):
|
||||||
|
return self.get()
|
Loading…
Reference in New Issue