12 config
= configparser
.RawConfigParser()
13 config
.read(os
.path
.dirname(os
.path
.realpath(__file__
)) + '/../conf/config')
15 aur_db_host
= config
.get('database', 'host')
16 aur_db_name
= config
.get('database', 'name')
17 aur_db_user
= config
.get('database', 'user')
18 aur_db_pass
= config
.get('database', 'password')
19 aur_db_socket
= config
.get('database', 'socket')
21 aur_location
= config
.get('options', 'aur_location')
22 aur_request_ml
= config
.get('options', 'aur_request_ml')
24 sendmail
= config
.get('notifications', 'sendmail')
25 sender
= config
.get('notifications', 'sender')
26 reply_to
= config
.get('notifications', 'reply-to')
29 def headers_cc(cclist
):
30 return {'Cc': str.join(', ', cclist
)}
32 def headers_msgid(thread_id
):
33 return {'Message-ID': thread_id
}
35 def headers_reply(thread_id
):
36 return {'In-Reply-To': thread_id
, 'References': thread_id
}
38 def send_notification(to
, subject
, body
, refs
, headers
={}):
39 body
= '\n'.join([textwrap
.fill(line
) for line
in body
.splitlines()])
43 msg
= email
.mime
.text
.MIMEText(body
, 'plain', 'utf-8')
44 msg
['Subject'] = subject
46 msg
['Reply-to'] = reply_to
49 for key
, value
in headers
.items():
52 p
= subprocess
.Popen([sendmail
, '-t', '-oi'], stdin
=subprocess
.PIPE
)
53 p
.communicate(msg
.as_bytes())
55 def username_from_id(cur
, uid
):
56 cur
.execute('SELECT UserName FROM Users WHERE ID = %s', [uid
])
57 return cur
.fetchone()[0]
59 def pkgbase_from_id(cur
, pkgbase_id
):
60 cur
.execute('SELECT Name FROM PackageBases WHERE ID = %s', [pkgbase_id
])
61 return cur
.fetchone()[0]
63 def pkgbase_from_pkgreq(cur
, reqid
):
64 cur
.execute('SELECT PackageBaseID FROM PackageRequests WHERE ID = %s',
66 return cur
.fetchone()[0]
68 def get_maintainer_email(cur
, pkgbase_id
):
69 cur
.execute('SELECT Users.Email FROM Users ' +
70 'INNER JOIN PackageBases ' +
71 'ON PackageBases.MaintainerUID = Users.ID WHERE ' +
72 'PackageBases.ID = %s', [pkgbase_id
])
73 return cur
.fetchone()[0]
75 def get_recipients(cur
, pkgbase_id
, uid
):
76 cur
.execute('SELECT DISTINCT Users.Email FROM Users ' +
77 'INNER JOIN CommentNotify ' +
78 'ON CommentNotify.UserID = Users.ID WHERE ' +
79 'CommentNotify.UserID != %s AND ' +
80 'CommentNotify.PackageBaseID = %s', [uid
, pkgbase_id
])
81 return [row
[0] for row
in cur
.fetchall()]
83 def get_request_recipients(cur
, pkgbase_id
, uid
):
84 cur
.execute('SELECT DISTINCT Users.Email FROM Users ' +
85 'INNER JOIN PackageBases ' +
86 'ON PackageBases.MaintainerUID = Users.ID WHERE ' +
87 'Users.ID = %s OR PackageBases.ID = %s', [uid
, pkgbase_id
])
88 return [row
[0] for row
in cur
.fetchall()]
90 def send_resetkey(cur
, uid
):
91 cur
.execute('SELECT UserName, Email, ResetKey FROM Users WHERE ID = %s',
93 username
, to
, resetkey
= cur
.fetchone()
95 subject
= 'AUR Password Reset'
96 body
= 'A password reset request was submitted for the account %s ' \
97 'associated with your email address. If you wish to reset your ' \
98 'password follow the link [1] below, otherwise ignore this ' \
99 'message and nothing will happen.' % (username
)
100 refs
= '[1] ' + aur_location
+ '/passreset/?resetkey=' + resetkey
102 send_notification([to
], subject
, body
, refs
)
104 def welcome(cur
, uid
):
105 cur
.execute('SELECT UserName, Email, ResetKey FROM Users WHERE ID = %s',
107 username
, to
, resetkey
= cur
.fetchone()
109 subject
= 'Welcome to the Arch User Repository'
110 body
= 'Welcome to the Arch User Repository! In order to set an initial ' \
111 'password for your new account, please click the link [1] below. ' \
112 'If the link does not work, try copying and pasting it into your ' \
114 refs
= '[1] ' + aur_location
+ '/passreset/?resetkey=' + resetkey
116 send_notification([to
], subject
, body
, refs
)
118 def comment(cur
, uid
, pkgbase_id
):
119 user
= username_from_id(cur
, uid
)
120 pkgbase
= pkgbase_from_id(cur
, pkgbase_id
)
121 to
= get_recipients(cur
, pkgbase_id
, uid
)
122 text
= sys
.stdin
.read()
124 uri
= aur_location
+ '/pkgbase/' + pkgbase
+ '/'
126 user_uri
= aur_location
+ '/account/' + user
+ '/'
127 pkgbase_uri
= aur_location
+ '/pkgbase/' + pkgbase
+ '/'
129 subject
= 'AUR Comment for %s' % (pkgbase
)
130 body
= '%s [1] added the following comment to %s [2]:' % (user
, pkgbase
)
131 body
+= '\n\n' + text
+ '\n\n'
132 body
+= 'If you no longer wish to receive notifications about this ' \
133 'package, please go to the package page [2] and select "%s".' % \
134 ('Disable notifications')
135 refs
= '[1] ' + user_uri
+ '\n'
136 refs
+= '[2] ' + pkgbase_uri
137 thread_id
= '<pkg-notifications-' + pkgbase
+ '@aur.archlinux.org>'
138 headers
= headers_reply(thread_id
)
140 send_notification(to
, subject
, body
, refs
, headers
)
142 def flag(cur
, uid
, pkgbase_id
):
143 user
= username_from_id(cur
, uid
)
144 pkgbase
= pkgbase_from_id(cur
, pkgbase_id
)
145 to
= [get_maintainer_email(cur
, pkgbase_id
)]
146 text
= sys
.stdin
.read()
148 user_uri
= aur_location
+ '/account/' + user
+ '/'
149 pkgbase_uri
= aur_location
+ '/pkgbase/' + pkgbase
+ '/'
151 subject
= 'AUR Out-of-date Notification for %s' % (pkgbase
)
152 body
= 'Your package %s [1] has been flagged out-of-date by %s [2]:' % \
154 body
+= '\n\n' + text
155 refs
= '[1] ' + pkgbase_uri
+ '\n'
156 refs
+= '[2] ' + user_uri
158 send_notification(to
, subject
, body
, refs
)
160 def delete(cur
, uid
, old_pkgbase_id
, new_pkgbase_id
=None):
161 user
= username_from_id(cur
, uid
)
162 old_pkgbase
= pkgbase_from_id(cur
, old_pkgbase_id
)
164 new_pkgbase
= pkgbase_from_id(cur
, new_pkgbase_id
)
165 to
= get_recipients(cur
, old_pkgbase_id
, uid
)
167 user_uri
= aur_location
+ '/account/' + user
+ '/'
168 pkgbase_uri
= aur_location
+ '/pkgbase/' + pkgbase
+ '/'
170 subject
= 'AUR Package deleted: %s' % (old_pkgbase
)
172 new_pkgbase_uri
= aur_location
+ '/pkgbase/' + new_pkgbase
+ '/'
173 body
= '%s [1] merged %s [2] into %s [3].\n\n' \
174 'If you no longer wish receive notifications about the new ' \
175 'package, please go to [3] and click "%s".' %\
176 (user
, old_pkgbase
, new_pkgbase
, 'Disable notifications')
177 refs
= '[1] ' + user_uri
+ '\n'
178 refs
+= '[2] ' + pkgbase_uri
+ '\n'
179 refs
+= '[3] ' + new_pkgbase_uri
181 body
= '%s [1] deleted %s [2].\n\n' \
182 'You will no longer receive notifications about this ' \
183 'package.' % (user
, old_pkgbase
)
184 refs
= '[1] ' + user_uri
+ '\n'
185 refs
+= '[2] ' + pkgbase_uri
187 send_notification(to
, subject
, body
, refs
)
189 def request_open(cur
, uid
, reqid
, reqtype
, pkgbase_id
, merge_into
=None):
190 user
= username_from_id(cur
, uid
)
191 pkgbase
= pkgbase_from_id(cur
, pkgbase_id
)
192 to
= [aur_request_ml
]
193 cc
= get_request_recipients(cur
, pkgbase_id
, uid
)
194 text
= sys
.stdin
.read()
196 user_uri
= aur_location
+ '/account/' + user
+ '/'
197 pkgbase_uri
= aur_location
+ '/pkgbase/' + pkgbase
+ '/'
199 subject
= '[PRQ#%d] %s Request for %s' % \
200 (int(reqid
), reqtype
.title(), pkgbase
)
202 merge_into_uri
= aur_location
+ '/pkgbase/' + merge_into
+ '/'
203 body
= '%s [1] filed a request to merge %s [2] into %s [3]:' % \
204 (user
, pkgbase
, merge_into
)
205 body
+= '\n\n' + text
206 refs
= '[1] ' + user_uri
+ '\n'
207 refs
+= '[2] ' + pkgbase_uri
+ '\n'
208 refs
+= '[3] ' + merge_into_uri
210 body
= '%s [1] filed a %s request for %s [2]:' % \
211 (user
, reqtype
, pkgbase
)
212 body
+= '\n\n' + text
213 refs
= '[1] ' + user_uri
+ '\n'
214 refs
+= '[2] ' + pkgbase_uri
+ '\n'
215 thread_id
= '<pkg-request-' + reqid
+ '@aur.archlinux.org>'
216 headers
= headers_msgid(thread_id
) + headers_cc(cc
)
218 send_notification(to
, subject
, body
, refs
, headers
)
220 def request_close(cur
, uid
, reqid
, reason
):
221 user
= username_from_id(cur
, uid
)
222 pkgbase_id
= pkgbase_from_pkgreq(cur
, reqid
)
223 to
= [aur_request_ml
]
224 cc
= get_request_recipients(cur
, pkgbase_id
, uid
)
225 text
= sys
.stdin
.read()
227 user_uri
= aur_location
+ '/account/' + user
+ '/'
229 subject
= '[PRQ#%d] Request %s' % (int(reqid
), reason
.title())
230 body
= 'Request #%d has been %s by %s [1]' % (int(reqid
), reason
, user
)
231 if text
.strip() == '':
234 body
+= ':\n\n' + text
235 refs
= '[1] ' + user_uri
236 thread_id
= '<pkg-request-' + reqid
+ '@aur.archlinux.org>'
237 headers
= headers_reply(thread_id
) + headers_cc(cc
)
239 send_notification(to
, subject
, body
, refs
, headers
)
242 if __name__
== '__main__':
245 'send-resetkey': send_resetkey
,
250 'request-open': request_open
,
251 'request-close': request_close
,
254 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
255 passwd
=aur_db_pass
, db
=aur_db_name
,
256 unix_socket
=aur_db_socket
, buffered
=True)
259 action_map
[action
](cur
, *sys
.argv
[2:])