diff --git a/CHANGES b/CHANGES index dae64b0..7e3a640 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +v0.2.8, Jul 28, 2016 +-------------------- + +**Bug Fix** + * [#119] version display error + +**Improvement** + * [#52] give user a total quota, let themselves decide how to use quota + * [#72] recording the user's historical resource usage + * [#85] Making workers's state consistent with master + * [#88] setting config file in admin panel + * [#96] Web notifications + * [#113] Recovery : after poweroff, just recover container, not recover service + v0.2.7, May 17, 2016 -------------------- diff --git a/VERSION b/VERSION index b003284..a45be46 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.7 +0.2.8 diff --git a/src/httprest.py b/src/httprest.py index 2d030ff..43de1b6 100755 --- a/src/httprest.py +++ b/src/httprest.py @@ -451,14 +451,22 @@ def vnodes_monitor(cur_user, user, form, con_id, issue): return json.dumps({'success':'true', 'monitor':res}) -@app.route("/monitor/user/quotainfo/", methods=['POST']) +@app.route("/monitor/user//", methods=['POST']) @login_required -def user_quotainfo_monitor(cur_user, user, form): +def user_quotainfo_monitor(cur_user, user, form,issue): global G_usermgr - logger.info("handle request: monitor/user/quotainfo/") - user_info = G_usermgr.selfQuery(cur_user = cur_user) - quotainfo = user_info['data']['groupinfo'] - return json.dumps({'success':'true', 'quotainfo':quotainfo}) + global G_historymgr + if issue == 'quotainfo': + logger.info("handle request: monitor/user/quotainfo/") + user_info = G_usermgr.selfQuery(cur_user = cur_user) + quotainfo = user_info['data']['groupinfo'] + return json.dumps({'success':'true', 'quotainfo':quotainfo}) + elif issue == 'createdvnodes': + logger.info("handle request: monitor/user/createdvnodes/") + res = G_historymgr.getCreatedVNodes(user) + return json.dumps({'success':'true', 'createdvnodes':res}) + else: + return json.dumps({'success':'false', 'message':"Unspported Method!"}) @app.route("/monitor/listphynodes/", methods=['POST']) @login_required diff --git a/src/model.py b/src/model.py index 89a72df..ca1af5c 100755 --- a/src/model.py +++ b/src/model.py @@ -96,7 +96,7 @@ class User(db.Model): if (date != None): self.register_date = date else: - self.register_date = datetime.utcnow() + self.register_date = datetime.now() self.user_group = usergroup self.auth_method = auth_method @@ -187,6 +187,20 @@ class NotificationGroups(db.Model): def __repr__(self): return '' % (self.notification_id, self.group_name) +class UserNotificationPair(db.Model): + id = db.Column(db.Integer, primary_key=True) + userName = db.Column(db.String(10)) + notifyId = db.Column(db.Integer) + isRead = db.Column(db.Integer) + + def __init__(self, username, notifyid): + self.userName = username + self.notifyId = notifyid + self.isRead = 0 + + def __repr__(self): + return '' % (self.userName, self.notifyId) + class VNode(db.Model): __bind_key__ = 'history' name = db.Column(db.String(100), primary_key=True) diff --git a/src/monitor.py b/src/monitor.py index 3891084..0e35f06 100755 --- a/src/monitor.py +++ b/src/monitor.py @@ -669,3 +669,10 @@ class History_Manager: else: res = History.query.filter_by(vnode=vnode_name).all() return list(eval(str(res))) + + def getCreatedVNodes(self,owner): + vnodes = VNode.query.filter(VNode.name.startswith(owner)).all() + res = [] + for vnode in vnodes: + res.append(vnode.name) + return res diff --git a/src/notificationmgr.py b/src/notificationmgr.py index 6713dea..c94826f 100644 --- a/src/notificationmgr.py +++ b/src/notificationmgr.py @@ -1,7 +1,7 @@ import json from log import logger -from model import db, Notification, NotificationGroups, User +from model import db, Notification, NotificationGroups, User, UserNotificationPair from userManager import administration_required, token_required import smtplib from email.mime.text import MIMEText @@ -21,6 +21,10 @@ class NotificationMgr: NotificationGroups.query.all() except: db.create_all() + try: + UserNotificationPair.query.all() + except: + db.create_all() logger.info("Notification Manager init done!") def query_user_notifications(self, user): @@ -102,6 +106,16 @@ class NotificationMgr: db.session.commit() if 'sendMail' in form: self.mail_notification(notify.id) + users = User.query.all() + for user in users: + user_group = user.user_group + for group_name in group_names: + if user_group == group_name: + tempPair = UserNotificationPair(user.username, notify.id) + db.session.add(tempPair) + break; + db.session.commit() + return {"success": 'true'} @administration_required @@ -158,36 +172,62 @@ class NotificationMgr: db.session.delete(notify_groups) db.session.delete(notify) db.session.commit() + temppairs = UserNotificationPair.query.filter_by(notifyId=notify_id).all() + for temppair in temppairs: + db.session.delete(temppair) + db.session.commit() return {"success": 'true'} @token_required def query_self_notification_simple_infos(self, *args, **kwargs): user = kwargs['cur_user'] + username = user.username notifies = self.query_user_notifications(user) notify_simple_infos = [] for notify in notifies: if notify is None or notify.status != 'open': continue + notifyid = notify.id + temppair = UserNotificationPair.query.filter_by(userName=username, notifyId=notifyid).first() + if temppair == None: + isRead = 0 + temppair = UserNotificationPair(username, notifyid) + db.session.add(temppair) + db.session.commit() + else: + isRead = temppair.isRead notify_simple_infos.append({ 'id': notify.id, 'title': notify.title, - 'create_date': notify.create_date + 'create_date': notify.create_date, + 'isRead': isRead }) return {'success': 'true', 'data': notify_simple_infos} @token_required def query_self_notifications_infos(self, *args, **kwargs): user = kwargs['cur_user'] + username = user.username notifies = self.query_user_notifications(user) notify_infos = [] for notify in notifies: if notify is None or notify.status != 'open': continue + notifyid = notify.id + temppair = UserNotificationPair.query.filter_by(userName=username, notifyId=notifyid).first() + if temppair == None: + temppair = UserNotificationPair(username, notifyid) + db.session.add(temppair) + isRead = 1 + temppair.isRead = 1 + db.session.add(temppair) + db.session.commit() notify_infos.append({ 'id': notify.id, 'title': notify.title, 'content': notify.content, - 'create_date': notify.create_date + 'create_date': notify.create_date, + 'isRead': isRead }) return {'success': 'true', 'data': notify_infos} @@ -208,6 +248,10 @@ class NotificationMgr: 'content': notify.content, 'create_date': notify.create_date } + usernotifypair = UserNotificationPair.query.filter_by(userName=user.username, notifyId=notify.id).first() + usernotifypair.isRead = 1 + db.session.add(usernotifypair) + db.session.commit() if notify.status != 'open': notify_info['title'] = 'This notification is not available' notify_info['content'] = 'Sorry, it seems that the administrator has closed this notification.' diff --git a/src/userManager.py b/src/userManager.py index d58a68b..d7d03dd 100755 --- a/src/userManager.py +++ b/src/userManager.py @@ -82,7 +82,7 @@ def send_activated_email(to_address, username):

Docklet Team, SEI, PKU

''' % (env.getenv("PORTAL_URL"), env.getenv("PORTAL_URL")) - text += '

'+ str(datetime.utcnow()) + '

' + text += '

'+ str(datetime.now()) + '

' text += '' subject = 'Docklet account activated' msg = MIMEMultipart() @@ -107,7 +107,7 @@ def send_remind_activating_email(username):

Docklet Team, SEI, PKU

''' % (username, env.getenv("PORTAL_URL"), env.getenv("PORTAL_URL")) - text += '

'+ str(datetime.utcnow()) + '

' + text += '

'+ str(datetime.now()) + '

' text += '' subject = 'An activating request in Docklet has been sent' msg = MIMEMultipart() @@ -324,14 +324,14 @@ class userManager: def set_nfs_quota_bygroup(self,groupname, quota): if not data_quota == "True": - return - users = User.query.filter_by(user_group = groupname).all() + return + users = User.query.filter_by(user_group = groupname).all() for user in users: self.set_nfs_quota(user.username, quota) def set_nfs_quota(self, username, quota): if not data_quota == "True": - return + return nfspath = "/users/%s/data" % username try: cmd = data_quota_cmd % (nfspath,quota+"GB") @@ -769,6 +769,13 @@ class userManager: will send an e-mail when status is changed from 'applying' to 'normal' Usage: modify(newValue = dict_from_form, cur_user = token_from_auth) ''' + if ( kwargs['newValue'].get('Instruction', '') == 'Activate'): + user_modify = User.query.filter_by(id = kwargs['newValue'].get('ID', None)).first() + user_modify.status = 'normal' + send_activated_email(user_modify.e_mail, user_modify.username) + db.session.commit() + return {"success": "true"} + user_modify = User.query.filter_by(username = kwargs['newValue'].get('username', None)).first() if (user_modify == None): @@ -786,11 +793,12 @@ class userManager: if (user_modify.status == 'applying' and form.get('status', '') == 'normal'): send_activated_email(user_modify.e_mail, user_modify.username) user_modify.status = form.get('status', '') - if (form.get('password', '') != ''): - new_password = form.get('password','') - new_password = hashlib.sha512(new_password.encode('utf-8')).hexdigest() - user_modify.password = new_password + #if (form.get('password', '') != ''): + #new_password = form.get('password','') + #new_password = hashlib.sha512(new_password.encode('utf-8')).hexdigest() + #user_modify.password = new_password #self.chpassword(cur_user = user_modify, password = form.get('password','no_password')) + #modify password in another function now db.session.commit() res = self.groupQuery(name=user_modify.user_group) diff --git a/web/templates/base_AdminLTE.html b/web/templates/base_AdminLTE.html index d1666be..f650734 100644 --- a/web/templates/base_AdminLTE.html +++ b/web/templates/base_AdminLTE.html @@ -149,6 +149,9 @@ + {% if mysession['usergroup'] == 'root' or mysession['usergroup'] == 'admin'%} @@ -242,6 +245,8 @@ $("#nav_Hosts").addClass("active"); else if(pathname[1] == 'config') $("#nav_Config").addClass("active"); + else if(pathname[1] == 'history') + $("#nav_History").addClass("active"); else if(pathname[1] == 'user') { if (pathname[2] == 'list') @@ -265,29 +270,35 @@ var notifies = data.data; var len = notifies.length; var cnt = 0; + var unread = 0; var now = new Date().getTime(); for(var t = 0; t < len; t++) { var notify = notifies[t]; var createDate = notify.create_date.substring(0, 19); + var isRead = notify.isRead; createDate = createDate.replace(/-/g,'/'); var from = new Date(createDate).getTime(); var delta = now - from; if(delta <= 604800000) { cnt ++; } + if(isRead == 0){ + unread ++; + } } $('#notificationIcon').find('span').remove(); $('#notificationList').empty(); - if(cnt != 0) { - $(""+cnt+"").appendTo($('#notificationIcon')); - } + if(unread != 0) + $(""+unread+"").appendTo($('#notificationIcon')); + $("#notificationHeader").html("You have " + len + " notifications, "+cnt+" in 1 week"); for(var i = 0; i < len; i++) { notify = notifies[i]; console.log(notify); + var isRead = notify.isRead; var a = $(" "+ notify.title +"") var item = $("
  • "); item.append(a); diff --git a/web/templates/monitor/history.html b/web/templates/monitor/history.html index 4f03ffe..7be1b25 100644 --- a/web/templates/monitor/history.html +++ b/web/templates/monitor/history.html @@ -2,16 +2,13 @@ {% block title %}Docklet | History{% endblock %} -{% block panel_title %}History for
    {{ vnode_name }}
    {% endblock %} +{% block panel_title %}History of All Created VNodes{% endblock %} {% block panel_list %}