forked from unias/docklet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbeansapplicationmgr.py
executable file
·148 lines (130 loc) · 5.75 KB
/
beansapplicationmgr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python3
'''
This module consists of three parts:
1.send_beans_email: a function to send email to remind users of their beans.
2.ApplicationMgr: a class that will deal with users' requests about beans application.
3.ApprovalRobot: a automatic robot to examine and approve users' applications.
'''
import threading,datetime,random,time
from model import db,User,ApplyMsg
from userManager import administration_required
import env
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from settings import settings
# send email to remind users of their beans
def send_beans_email(to_address, username, beans):
email_from_address = settings.get('EMAIL_FROM_ADDRESS')
if (email_from_address in ['\'\'', '\"\"', '']):
return
#text = 'Dear '+ username + ':\n' + ' Your beans in docklet are less than' + beans + '.'
text = '<html><h4>Dear '+ username + ':</h4>'
text += '''<p> Your beans in <a href='%s'>docklet</a> are %d now. </p>
<p> If your beans are less than or equal to 0, all your worksapces will be stopped.</p>
<p> Please apply for more beans to keep your workspaces running by following link:</p>
<p> <a href='%s/beans/application/'>%s/beans/application/</p>
<br>
<p> Note: DO NOT reply to this email!</p>
<br><br>
<p> <a href='http://docklet.unias.org'>Docklet Team</a>, SEI, PKU</p>
''' % (env.getenv("PORTAL_URL"), beans, env.getenv("PORTAL_URL"), env.getenv("PORTAL_URL"))
text += '<p>'+ str(datetime.datetime.now()) + '</p>'
text += '</html>'
subject = 'Docklet beans alert'
msg = MIMEMultipart()
textmsg = MIMEText(text,'html','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = email_from_address
msg['To'] = to_address
msg.attach(textmsg)
s = smtplib.SMTP()
s.connect()
s.sendmail(email_from_address, to_address, msg.as_string())
s.close()
# a class that will deal with users' requests about beans application.
class ApplicationMgr:
def __init__(self):
# create database
try:
ApplyMsg.query.all()
except:
db.create_all()
# user apply for beans
def apply(self,username,number,reason):
user = User.query.filter_by(username=username).first()
if user is not None and user.beans >= 1000:
return [False, "Your beans must be less than 1000."]
if int(number) < 100 or int(number) > 5000:
return [False, "Number field must be between 100 and 5000!"]
applymsgs = ApplyMsg.query.filter_by(username=username).all()
lasti = len(applymsgs) - 1 # the last index, the last application is also the latest application.
if lasti >= 0 and applymsgs[lasti].status == "Processing":
return [False, "You already have a processing application, please be patient."]
# store the application into the database
applymsg = ApplyMsg(username,number,reason)
db.session.add(applymsg)
db.session.commit()
return [True,""]
# get all applications of a user
def query(self,username):
applymsgs = ApplyMsg.query.filter_by(username=username).all()
ans = []
for msg in applymsgs:
ans.append(msg.ch2dict())
return ans
# get all unread applications
@administration_required
def queryUnRead(self,*,cur_user):
applymsgs = ApplyMsg.query.filter_by(status="Processing").all()
ans = []
for msg in applymsgs:
ans.append(msg.ch2dict())
return {"success":"true","applymsgs":ans}
# agree an application
@administration_required
def agree(self,msgid,*,cur_user):
applymsg = ApplyMsg.query.get(msgid)
if applymsg is None:
return {"success":"false","message":"Application doesn\'t exist."}
applymsg.status = "Agreed"
user = User.query.filter_by(username=applymsg.username).first()
if user is not None:
# update users' beans
user.beans += applymsg.number
db.session.commit()
return {"success":"true"}
# reject an application
@administration_required
def reject(self,msgid,*,cur_user):
applymsg = ApplyMsg.query.get(msgid)
if applymsg is None:
return {"success":"false","message":"Application doesn\'t exist."}
applymsg.status = "Rejected"
db.session.commit()
return {"success":"true"}
# a automatic robot to examine and approve users' applications.
class ApprovalRobot(threading.Thread):
def __init__(self,maxtime=3600):
threading.Thread.__init__(self)
self.stop = False
self.interval = 20
self.maxtime = maxtime # The max time that users may wait for from 'processing' to 'agreed'
def stop(self):
self.stop = True
def run(self):
while not self.stop:
# query all processing applications
applymsgs = ApplyMsg.query.filter_by(status="Processing").all()
for msg in applymsgs:
secs = (datetime.datetime.now() - msg.time).seconds
ranint = random.randint(self.interval,self.maxtime)
if secs >= ranint:
msg.status = "Agreed"
user = User.query.filter_by(username=msg.username).first()
if user is not None:
# update users'beans
user.beans += msg.number
db.session.commit()
time.sleep(self.interval)