mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
Add support for package update notifications
Introduce a new notification option to receive notifications when a new commit is pushed to a package repository. Implements FS#30109. Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
This commit is contained in:
parent
aa5e58db81
commit
64072461df
8 changed files with 68 additions and 12 deletions
|
@ -5,6 +5,7 @@ import mysql.connector
|
||||||
import os
|
import os
|
||||||
import pygit2
|
import pygit2
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import srcinfo.parse
|
import srcinfo.parse
|
||||||
|
@ -19,6 +20,8 @@ aur_db_user = config.get('database', 'user')
|
||||||
aur_db_pass = config.get('database', 'password')
|
aur_db_pass = config.get('database', 'password')
|
||||||
aur_db_socket = config.get('database', 'socket')
|
aur_db_socket = config.get('database', 'socket')
|
||||||
|
|
||||||
|
notify_cmd = config.get('notifications', 'notify-cmd')
|
||||||
|
|
||||||
repo_path = config.get('serve', 'repo-path')
|
repo_path = config.get('serve', 'repo-path')
|
||||||
repo_regex = config.get('serve', 'repo-regex')
|
repo_regex = config.get('serve', 'repo-regex')
|
||||||
|
|
||||||
|
@ -169,6 +172,13 @@ def save_metadata(metadata, db, cur, user):
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
def update_notify(db, cur, user, pkgbase_id):
|
||||||
|
# Obtain the user ID of the new maintainer.
|
||||||
|
cur.execute("SELECT ID FROM Users WHERE Username = %s", [user])
|
||||||
|
user_id = int(cur.fetchone()[0])
|
||||||
|
|
||||||
|
# Execute the notification script.
|
||||||
|
subprocess.Popen((notify_cmd, 'update', str(user_id), str(pkgbase_id)))
|
||||||
|
|
||||||
def die(msg):
|
def die(msg):
|
||||||
sys.stderr.write("error: {:s}\n".format(msg))
|
sys.stderr.write("error: {:s}\n".format(msg))
|
||||||
|
@ -336,8 +346,6 @@ for pkgname in srcinfo.utils.get_package_names(metadata):
|
||||||
# Store package base details in the database.
|
# Store package base details in the database.
|
||||||
save_metadata(metadata, db, cur, user)
|
save_metadata(metadata, db, cur, user)
|
||||||
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
# Create (or update) a branch with the name of the package base for better
|
# Create (or update) a branch with the name of the package base for better
|
||||||
# accessibility.
|
# accessibility.
|
||||||
repo.create_reference('refs/heads/' + pkgbase, sha1_new, True)
|
repo.create_reference('refs/heads/' + pkgbase, sha1_new, True)
|
||||||
|
@ -347,3 +355,9 @@ repo.create_reference('refs/heads/' + pkgbase, sha1_new, True)
|
||||||
# http://git.661346.n2.nabble.com/PATCH-receive-pack-Create-a-HEAD-ref-for-ref-namespace-td7632149.html
|
# http://git.661346.n2.nabble.com/PATCH-receive-pack-Create-a-HEAD-ref-for-ref-namespace-td7632149.html
|
||||||
# for details.
|
# for details.
|
||||||
repo.create_reference('refs/namespaces/' + pkgbase + '/HEAD', sha1_new, True)
|
repo.create_reference('refs/namespaces/' + pkgbase + '/HEAD', sha1_new, True)
|
||||||
|
|
||||||
|
# Send package update notifications.
|
||||||
|
update_notify(db, cur, user, pkgbase_id)
|
||||||
|
|
||||||
|
# Close the database.
|
||||||
|
db.close()
|
||||||
|
|
|
@ -39,6 +39,7 @@ CREATE TABLE Users (
|
||||||
InactivityTS BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
InactivityTS BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
RegistrationTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
RegistrationTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
CommentNotify TINYINT(1) NOT NULL DEFAULT 1,
|
CommentNotify TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
|
UpdateNotify TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (ID),
|
PRIMARY KEY (ID),
|
||||||
UNIQUE (Username),
|
UNIQUE (Username),
|
||||||
UNIQUE (Email),
|
UNIQUE (Email),
|
||||||
|
|
|
@ -105,6 +105,16 @@ def get_comment_recipients(cur, pkgbase_id, uid):
|
||||||
return [row[0] for row in cur.fetchall()]
|
return [row[0] for row in cur.fetchall()]
|
||||||
|
|
||||||
|
|
||||||
|
def get_update_recipients(cur, pkgbase_id, uid):
|
||||||
|
cur.execute('SELECT DISTINCT Users.Email FROM Users ' +
|
||||||
|
'INNER JOIN PackageNotifications ' +
|
||||||
|
'ON PackageNotifications.UserID = Users.ID WHERE ' +
|
||||||
|
'Users.UpdateNotify = 1 AND ' +
|
||||||
|
'PackageNotifications.UserID != %s AND ' +
|
||||||
|
'PackageNotifications.PackageBaseID = %s', [uid, pkgbase_id])
|
||||||
|
return [row[0] for row in cur.fetchall()]
|
||||||
|
|
||||||
|
|
||||||
def get_request_recipients(cur, pkgbase_id, uid):
|
def get_request_recipients(cur, pkgbase_id, uid):
|
||||||
cur.execute('SELECT DISTINCT Users.Email FROM Users ' +
|
cur.execute('SELECT DISTINCT Users.Email FROM Users ' +
|
||||||
'INNER JOIN PackageBases ' +
|
'INNER JOIN PackageBases ' +
|
||||||
|
@ -189,6 +199,28 @@ def comment(cur, uid, pkgbase_id, comment_id):
|
||||||
send_notification(to, subject, body, refs, headers)
|
send_notification(to, subject, body, refs, headers)
|
||||||
|
|
||||||
|
|
||||||
|
def update(cur, uid, pkgbase_id):
|
||||||
|
user = username_from_id(cur, uid)
|
||||||
|
pkgbase = pkgbase_from_id(cur, pkgbase_id)
|
||||||
|
to = get_update_recipients(cur, pkgbase_id, uid)
|
||||||
|
|
||||||
|
user_uri = aur_location + '/account/' + user + '/'
|
||||||
|
pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/'
|
||||||
|
|
||||||
|
subject = 'AUR Package Update: %s' % (pkgbase)
|
||||||
|
body = '%s [1] pushed a new commit to %s [2].' % (user, pkgbase)
|
||||||
|
body += '\n\n'
|
||||||
|
body += 'If you no longer wish to receive notifications about this ' \
|
||||||
|
'package, please go to the package page [2] and select "%s".' % \
|
||||||
|
('Disable notifications')
|
||||||
|
refs = '[1] ' + user_uri + '\n'
|
||||||
|
refs += '[2] ' + pkgbase_uri
|
||||||
|
thread_id = '<pkg-notifications-' + pkgbase + '@aur.archlinux.org>'
|
||||||
|
headers = headers_reply(thread_id)
|
||||||
|
|
||||||
|
send_notification(to, subject, body, refs, headers)
|
||||||
|
|
||||||
|
|
||||||
def flag(cur, uid, pkgbase_id):
|
def flag(cur, uid, pkgbase_id):
|
||||||
user = username_from_id(cur, uid)
|
user = username_from_id(cur, uid)
|
||||||
pkgbase = pkgbase_from_id(cur, pkgbase_id)
|
pkgbase = pkgbase_from_id(cur, pkgbase_id)
|
||||||
|
@ -327,6 +359,7 @@ if __name__ == '__main__':
|
||||||
'send-resetkey': send_resetkey,
|
'send-resetkey': send_resetkey,
|
||||||
'welcome': welcome,
|
'welcome': welcome,
|
||||||
'comment': comment,
|
'comment': comment,
|
||||||
|
'update': update,
|
||||||
'flag': flag,
|
'flag': flag,
|
||||||
'comaintainer-add': comaintainer_add,
|
'comaintainer-add': comaintainer_add,
|
||||||
'comaintainer-remove': comaintainer_remove,
|
'comaintainer-remove': comaintainer_remove,
|
||||||
|
|
|
@ -52,5 +52,6 @@ ALTER TABLE CommentNotify RENAME TO PackageNotifications;
|
||||||
|
|
||||||
----
|
----
|
||||||
ALTER TABLE Users
|
ALTER TABLE Users
|
||||||
ADD COLUMN CommentNotify TINYINT(1) NOT NULL DEFAULT 1;
|
ADD COLUMN CommentNotify TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
|
ADD COLUMN UpdateNotify TINYINT(1) NOT NULL DEFAULT 0;
|
||||||
----
|
----
|
||||||
|
|
|
@ -35,8 +35,8 @@ if ($action == "UpdateAccount") {
|
||||||
in_request("E"), in_request("H"), in_request("P"),
|
in_request("E"), in_request("H"), in_request("P"),
|
||||||
in_request("C"), in_request("R"), in_request("L"),
|
in_request("C"), in_request("R"), in_request("L"),
|
||||||
in_request("I"), in_request("K"), in_request("PK"),
|
in_request("I"), in_request("K"), in_request("PK"),
|
||||||
in_request("J"), in_request("CN"), in_request("ID"),
|
in_request("J"), in_request("CN"), in_request("UN"),
|
||||||
$row["Username"]);
|
in_request("ID"), $row["Username"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ if (isset($_COOKIE["AURSID"])) {
|
||||||
$row["HideEmail"], "", "", $row["RealName"],
|
$row["HideEmail"], "", "", $row["RealName"],
|
||||||
$row["LangPreference"], $row["IRCNick"], $row["PGPKey"], $PK,
|
$row["LangPreference"], $row["IRCNick"], $row["PGPKey"], $PK,
|
||||||
$row["InactivityTS"] ? 1 : 0, $row["CommentNotify"],
|
$row["InactivityTS"] ? 1 : 0, $row["CommentNotify"],
|
||||||
$row["ID"], $row["Username"]);
|
$row["UpdateNotify"], $row["ID"], $row["Username"]);
|
||||||
} else {
|
} else {
|
||||||
print __("You do not have permission to edit this account.");
|
print __("You do not have permission to edit this account.");
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,8 @@ if (isset($_COOKIE["AURSID"])) {
|
||||||
in_request("R"), in_request("L"),
|
in_request("R"), in_request("L"),
|
||||||
in_request("I"), in_request("K"),
|
in_request("I"), in_request("K"),
|
||||||
in_request("PK"), in_request("J"),
|
in_request("PK"), in_request("J"),
|
||||||
in_request("CN"), in_request("ID"),
|
in_request("CN"), in_request("UN"),
|
||||||
$row["Username"]);
|
in_request("ID"), $row["Username"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,7 +23,7 @@ if (in_request("Action") == "NewAccount") {
|
||||||
"new", "NewAccount", in_request("U"), 1, 0,
|
"new", "NewAccount", in_request("U"), 1, 0,
|
||||||
in_request("E"), in_request("H"), '', '', in_request("R"),
|
in_request("E"), in_request("H"), '', '', in_request("R"),
|
||||||
in_request("L"), in_request("I"), in_request("K"),
|
in_request("L"), in_request("I"), in_request("K"),
|
||||||
in_request("PK"), 0, in_request("CN"));
|
in_request("PK"), 0, in_request("CN"), in_request("UN"));
|
||||||
|
|
||||||
print $message;
|
print $message;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ if (in_request("Action") == "NewAccount") {
|
||||||
display_account_form("NewAccount", in_request("U"), 1, 0,
|
display_account_form("NewAccount", in_request("U"), 1, 0,
|
||||||
in_request("E"), in_request("H"), '', '', in_request("R"),
|
in_request("E"), in_request("H"), '', '', in_request("R"),
|
||||||
in_request("L"), in_request("I"), in_request("K"),
|
in_request("L"), in_request("I"), in_request("K"),
|
||||||
in_request("PK"), 0, in_request("CN"));
|
in_request("PK"), 0, in_request("CN"), in_request("UN"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print '<p>' . __("Use this form to create an account.") . '</p>';
|
print '<p>' . __("Use this form to create an account.") . '</p>';
|
||||||
|
|
|
@ -57,13 +57,14 @@ function html_format_pgp_fingerprint($fingerprint) {
|
||||||
* @param string $PK The list of SSH public keys
|
* @param string $PK The list of SSH public keys
|
||||||
* @param string $J The inactivity status of the displayed user
|
* @param string $J The inactivity status of the displayed user
|
||||||
* @param string $CN Whether to notify of new comments
|
* @param string $CN Whether to notify of new comments
|
||||||
|
* @param string $UN Whether to notify of package updates
|
||||||
* @param string $UID The user ID of the displayed user
|
* @param string $UID The user ID of the displayed user
|
||||||
* @param string $N The username as present in the database
|
* @param string $N The username as present in the database
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="",
|
function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="",
|
||||||
$L="",$I="",$K="",$PK="",$J="",$CN="",$UID=0,$N="") {
|
$L="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$UID=0,$N="") {
|
||||||
global $SUPPORTED_LANGS;
|
global $SUPPORTED_LANGS;
|
||||||
|
|
||||||
include("account_edit_form.php");
|
include("account_edit_form.php");
|
||||||
|
@ -90,13 +91,14 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R=""
|
||||||
* @param string $PK The list of public SSH keys
|
* @param string $PK The list of public SSH keys
|
||||||
* @param string $J The inactivity status of the user
|
* @param string $J The inactivity status of the user
|
||||||
* @param string $CN Whether to notify of new comments
|
* @param string $CN Whether to notify of new comments
|
||||||
|
* @param string $UN Whether to notify of package updates
|
||||||
* @param string $UID The user ID of the modified account
|
* @param string $UID The user ID of the modified account
|
||||||
* @param string $N The username as present in the database
|
* @param string $N The username as present in the database
|
||||||
*
|
*
|
||||||
* @return array Boolean indicating success and message to be printed
|
* @return array Boolean indicating success and message to be printed
|
||||||
*/
|
*/
|
||||||
function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",
|
function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",
|
||||||
$R="",$L="",$I="",$K="",$PK="",$J="",$CN="",$UID=0,$N="") {
|
$R="",$L="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$UID=0,$N="") {
|
||||||
global $SUPPORTED_LANGS;
|
global $SUPPORTED_LANGS;
|
||||||
|
|
||||||
$error = '';
|
$error = '';
|
||||||
|
@ -344,6 +346,7 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
|
||||||
$q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K));
|
$q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K));
|
||||||
$q.= ", InactivityTS = " . $inactivity_ts;
|
$q.= ", InactivityTS = " . $inactivity_ts;
|
||||||
$q.= ", CommentNotify = " . ($CN ? "1" : "0");
|
$q.= ", CommentNotify = " . ($CN ? "1" : "0");
|
||||||
|
$q.= ", UpdateNotify = " . ($UN ? "1" : "0");
|
||||||
$q.= " WHERE ID = ".intval($UID);
|
$q.= " WHERE ID = ".intval($UID);
|
||||||
$result = $dbh->exec($q);
|
$result = $dbh->exec($q);
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,10 @@
|
||||||
<label for="id_commentnotify"><?= __("Notify of new comments") ?>:</label>
|
<label for="id_commentnotify"><?= __("Notify of new comments") ?>:</label>
|
||||||
<input type="checkbox" name="CN" id="id_commentnotify" <?= $CN ? 'checked="checked"' : '' ?> />
|
<input type="checkbox" name="CN" id="id_commentnotify" <?= $CN ? 'checked="checked"' : '' ?> />
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="id_updatenotify"><?= __("Notify of package updates") ?>:</label>
|
||||||
|
<input type="checkbox" name="UN" id="id_updatenotify" <?= $UN ? 'checked="checked"' : '' ?> />
|
||||||
|
</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
Loading…
Add table
Reference in a new issue