From 6ec4a3589e327ded693ab0c741828fc5ec66b840 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 21 Feb 2016 19:44:38 +0100 Subject: Send notifications when changing ownership Add a new option that makes it possible to subscribe to package ownership changes (adoption/disownment). Fixes FS#15412. Signed-off-by: Lukas Fleischer --- upgrading/4.3.0.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 upgrading/4.3.0.txt (limited to 'upgrading') diff --git a/upgrading/4.3.0.txt b/upgrading/4.3.0.txt new file mode 100644 index 0000000..0d3a9b7 --- /dev/null +++ b/upgrading/4.3.0.txt @@ -0,0 +1,5 @@ +1. Add a column to store ownership notification settings: + +---- +ALTER TABLE Users ADD COLUMN OwnershipNotify TINYINT(1) NOT NULL DEFAULT 1; +---- -- cgit v1.2.3-54-g00ecf From 0108c64541d2cd9684ce0b75acfc541bf479ae71 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Tue, 15 Mar 2016 18:01:15 +0100 Subject: Resize the LastLoginIPAddress column Make sure that all valid IPv6 addresses fit into the LastLoginIPAddress field. Signed-off-by: Lukas Fleischer --- schema/aur-schema.sql | 2 +- upgrading/4.3.0.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'upgrading') diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index aa5ed9d..0804ac3 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -35,7 +35,7 @@ CREATE TABLE Users ( IRCNick VARCHAR(32) NOT NULL DEFAULT '', PGPKey VARCHAR(40) NULL DEFAULT NULL, LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0, - LastLoginIPAddress VARCHAR(40) NULL DEFAULT NULL, + LastLoginIPAddress VARCHAR(45) NULL DEFAULT NULL, InactivityTS BIGINT UNSIGNED NOT NULL DEFAULT 0, RegistrationTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, CommentNotify TINYINT(1) NOT NULL DEFAULT 1, diff --git a/upgrading/4.3.0.txt b/upgrading/4.3.0.txt index 0d3a9b7..34b19a2 100644 --- a/upgrading/4.3.0.txt +++ b/upgrading/4.3.0.txt @@ -3,3 +3,9 @@ ---- ALTER TABLE Users ADD COLUMN OwnershipNotify TINYINT(1) NOT NULL DEFAULT 1; ---- + +2. Resize the LastLoginIPAddress column: + +---- +ALTER TABLE Users MODIFY LastLoginIPAddress VARCHAR(45) NULL DEFAULT NULL; +---- -- cgit v1.2.3-54-g00ecf From b2e97cdd1ee804468b2dd601eafda9574c05a3a7 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Tue, 17 May 2016 19:03:39 +0200 Subject: Add repository information to official providers When updating the list of packages provided by the official repositories, also save the repository names. --- schema/aur-schema.sql | 1 + scripts/aurblup.py | 8 ++++++-- upgrading/4.3.0.txt | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'upgrading') diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index 0804ac3..ea19d46 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -310,6 +310,7 @@ CREATE TABLE PackageBlacklist ( CREATE TABLE OfficialProviders ( ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name VARCHAR(64) NOT NULL, + Repo VARCHAR(64) NOT NULL, Provides VARCHAR(64) NOT NULL, PRIMARY KEY (ID) ) ENGINE = InnoDB; diff --git a/scripts/aurblup.py b/scripts/aurblup.py index 325ef3d..9e11e43 100755 --- a/scripts/aurblup.py +++ b/scripts/aurblup.py @@ -20,6 +20,7 @@ servers = config.get('aurblup', 'servers').split(' ') blacklist = set() providers = set() +repomap = dict() h = pyalpm.Handle("/", db_path) for sync_db in sync_dbs: @@ -33,9 +34,11 @@ for sync_db in sync_dbs: blacklist.add(pkg.name) [blacklist.add(x) for x in pkg.replaces] providers.add((pkg.name, pkg.name)) + repomap[(pkg.name, pkg.name)] = repo.name for provision in pkg.provides: provisionname = re.sub(r'(<|=|>).*', '', provision) providers.add((pkg.name, provisionname)) + repomap[(pkg.name, provisionname)] = repo.name db = mysql.connector.connect(host=aur_db_host, user=aur_db_user, passwd=aur_db_pass, db=aur_db_name, @@ -54,8 +57,9 @@ cur.execute("SELECT Name, Provides FROM OfficialProviders") oldproviders = set(cur.fetchall()) for pkg, provides in providers.difference(oldproviders): - cur.execute("INSERT INTO OfficialProviders (Name, Provides) " - "VALUES (%s, %s)", [pkg, provides]) + repo = repomap[(pkg, provides)] + cur.execute("INSERT INTO OfficialProviders (Name, Repo, Provides) " + "VALUES (%s, %s, %s)", [pkg, repo, provides]) for pkg, provides in oldproviders.difference(providers): cur.execute("DELETE FROM OfficialProviders " "WHERE Name = %s AND Provides = %s", [pkg, provides]) diff --git a/upgrading/4.3.0.txt b/upgrading/4.3.0.txt index 34b19a2..f7f3e08 100644 --- a/upgrading/4.3.0.txt +++ b/upgrading/4.3.0.txt @@ -9,3 +9,9 @@ ALTER TABLE Users ADD COLUMN OwnershipNotify TINYINT(1) NOT NULL DEFAULT 1; ---- ALTER TABLE Users MODIFY LastLoginIPAddress VARCHAR(45) NULL DEFAULT NULL; ---- + +3. Add a new column to store repository information of official providers: + +---- +ALTER TABLE OfficialProviders ADD COLUMN Repo VARCHAR(64) NOT NULL; +---- -- cgit v1.2.3-54-g00ecf From e3670ef1888a3f030452b229e8d48b83bb83b240 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Thu, 2 Jun 2016 08:51:29 +0200 Subject: Add a homepage field to accounts Allow users to add a link to their homepage to their profile. Implements FS#22774. Signed-off-by: Lukas Fleischer --- schema/aur-schema.sql | 1 + upgrading/4.3.0.txt | 6 +++++ web/html/account.php | 53 +++++++++++++++++++++++++++----------- web/lib/acctfuncs.inc.php | 12 ++++++--- web/template/account_details.php | 4 +++ web/template/account_edit_form.php | 5 ++++ 6 files changed, 62 insertions(+), 19 deletions(-) (limited to 'upgrading') diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index ea19d46..7edf94c 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -32,6 +32,7 @@ CREATE TABLE Users ( ResetKey CHAR(32) NOT NULL DEFAULT '', RealName VARCHAR(64) NOT NULL DEFAULT '', LangPreference VARCHAR(5) NOT NULL DEFAULT 'en', + Homepage TEXT NULL DEFAULT NULL, IRCNick VARCHAR(32) NOT NULL DEFAULT '', PGPKey VARCHAR(40) NULL DEFAULT NULL, LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0, diff --git a/upgrading/4.3.0.txt b/upgrading/4.3.0.txt index f7f3e08..6c1753d 100644 --- a/upgrading/4.3.0.txt +++ b/upgrading/4.3.0.txt @@ -15,3 +15,9 @@ ALTER TABLE Users MODIFY LastLoginIPAddress VARCHAR(45) NULL DEFAULT NULL; ---- ALTER TABLE OfficialProviders ADD COLUMN Repo VARCHAR(64) NOT NULL; ---- + +4. Add a column to store users' homepages: + +---- +ALTER TABLE Users ADD COLUMN Homepage TEXT NULL DEFAULT NULL; +---- diff --git a/web/html/account.php b/web/html/account.php index 9007ace..8d92b2c 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -78,12 +78,25 @@ if (isset($_COOKIE["AURSID"])) { } else { /* Verify user has permission to edit the account */ if (can_edit_account($row)) { - display_account_form("UpdateAccount", $row["Username"], - $row["AccountTypeID"], $row["Suspended"], $row["Email"], - $row["HideEmail"], "", "", $row["RealName"], - $row["LangPreference"], $row["IRCNick"], $row["PGPKey"], $PK, - $row["InactivityTS"] ? 1 : 0, $row["CommentNotify"], - $row["UpdateNotify"], $row["ID"], $row["Username"]); + display_account_form("UpdateAccount", + $row["Username"], + $row["AccountTypeID"], + $row["Suspended"], + $row["Email"], + $row["HideEmail"], + "", + "", + $row["RealName"], + $row["LangPreference"], + $row["Homepage"], + $row["IRCNick"], + $row["PGPKey"], + $PK, + $row["InactivityTS"] ? 1 : 0, + $row["CommentNotify"], + $row["UpdateNotify"], + $row["ID"], + $row["Username"]); } else { print __("You do not have permission to edit this account."); } @@ -116,15 +129,25 @@ if (isset($_COOKIE["AURSID"])) { print $update_account_message; if (!$success) { - display_account_form("UpdateAccount", in_request("U"), - in_request("T"), in_request("S"), - in_request("E"), in_request("H"), - in_request("P"), in_request("C"), - in_request("R"), in_request("L"), - in_request("I"), in_request("K"), - in_request("PK"), in_request("J"), - in_request("CN"), in_request("UN"), - in_request("ID"), $row["Username"]); + display_account_form("UpdateAccount", + in_request("U"), + in_request("T"), + in_request("S"), + in_request("E"), + in_request("H"), + in_request("P"), + in_request("C"), + in_request("R"), + in_request("L"), + in_request("HP"), + in_request("I"), + in_request("K"), + in_request("PK"), + in_request("J"), + in_request("CN"), + in_request("UN"), + in_request("ID"), + $row["Username"]); } } else { diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index 0eb021e..172b962 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -52,6 +52,7 @@ function html_format_pgp_fingerprint($fingerprint) { * @param string $C The confirmed password value of the displayed user * @param string $R The real name of the displayed user * @param string $L The language preference of the displayed user + * @param string $HP The homepage of the displayed user * @param string $I The IRC nickname of the displayed user * @param string $K The PGP key fingerprint of the displayed user * @param string $PK The list of SSH public keys @@ -65,7 +66,7 @@ function html_format_pgp_fingerprint($fingerprint) { * @return void */ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="", - $L="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { + $L="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { global $SUPPORTED_LANGS; include("account_edit_form.php"); @@ -87,6 +88,7 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="" * @param string $C The confirmed password for the user * @param string $R The real name of the user * @param string $L The language preference of the user + * @param string $HP The homepage of the displayed user * @param string $I The IRC nickname of the user * @param string $K The PGP fingerprint of the user * @param string $PK The list of public SSH keys @@ -100,7 +102,7 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="" * @return array Boolean indicating success and message to be printed */ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="", - $R="",$L="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { + $R="",$L="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { global $SUPPORTED_LANGS; $error = ''; @@ -276,13 +278,14 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="" $salt = $dbh->quote($salt); $R = $dbh->quote($R); $L = $dbh->quote($L); + $HP = $dbh->quote($HP); $I = $dbh->quote($I); $K = $dbh->quote(str_replace(" ", "", $K)); $q = "INSERT INTO Users (AccountTypeID, Suspended, "; $q.= "InactivityTS, Username, Email, Passwd, Salt, "; - $q.= "RealName, LangPreference, IRCNick, PGPKey) "; + $q.= "RealName, LangPreference, Homepage, IRCNick, PGPKey) "; $q.= "VALUES (1, 0, 0, $U, $E, $P, $salt, $R, $L, "; - $q.= "$I, $K)"; + $q.= "$HP, $I, $K)"; $result = $dbh->exec($q); if (!$result) { $message = __("Error trying to create account, %s%s%s.", @@ -344,6 +347,7 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="" } $q.= ", RealName = " . $dbh->quote($R); $q.= ", LangPreference = " . $dbh->quote($L); + $q.= ", Homepage = " . $dbh->quote($HP); $q.= ", IRCNick = " . $dbh->quote($I); $q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K)); $q.= ", InactivityTS = " . $inactivity_ts; diff --git a/web/template/account_details.php b/web/template/account_details.php index 59a6a63..0ac85a5 100644 --- a/web/template/account_details.php +++ b/web/template/account_details.php @@ -41,6 +41,10 @@ + + + + diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index b4f0192..6c2b8fb 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -98,6 +98,11 @@

+

+ + +

+

-- cgit v1.2.3-54-g00ecf From e55b529813feb806fd139ccbf47be87970d95b74 Mon Sep 17 00:00:00 2001 From: Johannes Löthberg Date: Wed, 20 Jul 2016 20:16:25 +0200 Subject: Make LangPreference DB field wide enough to fit es_419 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The language code for Latin American Spanish is es_419, which is longer than the 5 characters previously allowed. Signed-off-by: Johannes Löthberg Signed-off-by: Lukas Fleischer --- schema/aur-schema.sql | 2 +- upgrading/4.3.0.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'upgrading') diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index 1affc25..9991129 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -31,7 +31,7 @@ CREATE TABLE Users ( Salt CHAR(32) NOT NULL DEFAULT '', ResetKey CHAR(32) NOT NULL DEFAULT '', RealName VARCHAR(64) NOT NULL DEFAULT '', - LangPreference VARCHAR(5) NOT NULL DEFAULT 'en', + LangPreference VARCHAR(6) NOT NULL DEFAULT 'en', Homepage TEXT NULL DEFAULT NULL, IRCNick VARCHAR(32) NOT NULL DEFAULT '', PGPKey VARCHAR(40) NULL DEFAULT NULL, diff --git a/upgrading/4.3.0.txt b/upgrading/4.3.0.txt index 6c1753d..78f9455 100644 --- a/upgrading/4.3.0.txt +++ b/upgrading/4.3.0.txt @@ -21,3 +21,9 @@ ALTER TABLE OfficialProviders ADD COLUMN Repo VARCHAR(64) NOT NULL; ---- ALTER TABLE Users ADD COLUMN Homepage TEXT NULL DEFAULT NULL; ---- + +5. Resize LangPreference to fit Latin American Spanish language code: + +-- +ALTER TABLE Users MODIFY LangPreference VARCHAR(6); +-- -- cgit v1.2.3-54-g00ecf From 1492444ecbe68e4498a6f7ae0258c39ebbd47138 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Tue, 11 Oct 2016 08:09:21 +0200 Subject: Make URL columns 8000 characters wide According to RFC 7230, URLs can be up too 8000 characters long. Resize all URL fields accordingly. Also, add a test to verify that URLs with more than 8000 characters are rejected by the update hook. Reported-by: Andreas Linz Signed-off-by: Lukas Fleischer --- aurweb/git/update.py | 5 +++-- schema/aur-schema.sql | 4 ++-- test/t1300-git-update.sh | 16 ++++++++++++++++ upgrading/4.4.0.txt | 12 ++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 upgrading/4.4.0.txt (limited to 'upgrading') diff --git a/aurweb/git/update.py b/aurweb/git/update.py index 7337341..af2dfed 100755 --- a/aurweb/git/update.py +++ b/aurweb/git/update.py @@ -324,8 +324,9 @@ def main(): die_commit('invalid package name: {:s}'.format( pkginfo['pkgname']), str(commit.id)) - for field in ('pkgname', 'pkgdesc', 'url'): - if field in pkginfo and len(pkginfo[field]) > 255: + max_len = {'pkgname': 255, 'pkgdesc': 255, 'url': 8000} + for field in max_len.keys(): + if field in pkginfo and len(pkginfo[field]) > max_len[field]: die_commit('{:s} field too long: {:s}'.format(field, pkginfo[field]), str(commit.id)) diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index 030370b..30209bd 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -119,7 +119,7 @@ CREATE TABLE Packages ( Name VARCHAR(255) NOT NULL, Version VARCHAR(255) NOT NULL DEFAULT '', Description VARCHAR(255) NULL DEFAULT NULL, - URL VARCHAR(255) NULL DEFAULT NULL, + URL VARCHAR(8000) NULL DEFAULT NULL, PRIMARY KEY (ID), UNIQUE (Name), FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE @@ -227,7 +227,7 @@ CREATE INDEX RelationsRelName ON PackageRelations (RelName); -- CREATE TABLE PackageSources ( PackageID INTEGER UNSIGNED NOT NULL, - Source VARCHAR(255) NOT NULL DEFAULT "/dev/null", + Source VARCHAR(8000) NOT NULL DEFAULT "/dev/null", SourceArch VARCHAR(255) NULL DEFAULT NULL, FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE ) ENGINE = InnoDB; diff --git a/test/t1300-git-update.sh b/test/t1300-git-update.sh index b642089..abab7ea 100755 --- a/test/t1300-git-update.sh +++ b/test/t1300-git-update.sh @@ -309,6 +309,22 @@ test_expect_success 'Pushing .SRCINFO with invalid epoch.' ' grep -q "^error: invalid epoch: !$" actual ' +test_expect_success 'Pushing .SRCINFO with too long URL.' ' + old=$(git -C aur.git rev-parse HEAD) && + url="http://$(printf "%7993s" x | sed "s/ /x/g")/" && + test_when_finished "git -C aur.git reset --hard $old" && + ( + cd aur.git && + sed "s#.*url.*#\\0\\nurl = $url#" .SRCINFO >.SRCINFO.new + mv .SRCINFO.new .SRCINFO + git commit -q -am "Change URL" + ) && + new=$(git -C aur.git rev-parse HEAD) && + AUR_USER=user AUR_PKGBASE=foobar AUR_PRIVILEGED=0 \ + test_must_fail "$GIT_UPDATE" refs/heads/master "$old" "$new" >actual 2>&1 && + grep -q "^error: url field too long: $url\$" actual +' + test_expect_success 'Missing install file.' ' old=$(git -C aur.git rev-parse HEAD) && test_when_finished "git -C aur.git reset --hard $old" && diff --git a/upgrading/4.4.0.txt b/upgrading/4.4.0.txt new file mode 100644 index 0000000..1cc55b3 --- /dev/null +++ b/upgrading/4.4.0.txt @@ -0,0 +1,12 @@ +1. Resize the URL column of the Packages table: + +---- +ALTER TABLE Packages MODIFY URL VARCHAR(8000) NULL DEFAULT NULL; +---- + +2. Resize the Source column of the PackageSources table: + +---- +ALTER TABLE PackageSources + MODIFY Source VARCHAR(8000) NOT NULL DEFAULT "/dev/null"; +---- -- cgit v1.2.3-54-g00ecf From 51101d21b972b6afcef299795430cb5aea81e373 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Tue, 11 Oct 2016 08:40:28 +0200 Subject: upgrading/4.4.0.txt: Warn about new scripts The location of the Git interface wrapper scripts was changed by commit d4fe77a (Reorganize Git interface scripts, 2016-10-08). Add a note to the upgrade instructions to remind users to update their configuration files. Signed-off-by: Lukas Fleischer --- upgrading/4.4.0.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'upgrading') diff --git a/upgrading/4.4.0.txt b/upgrading/4.4.0.txt index 1cc55b3..afe01be 100644 --- a/upgrading/4.4.0.txt +++ b/upgrading/4.4.0.txt @@ -10,3 +10,8 @@ ALTER TABLE Packages MODIFY URL VARCHAR(8000) NULL DEFAULT NULL; ALTER TABLE PackageSources MODIFY Source VARCHAR(8000) NOT NULL DEFAULT "/dev/null"; ---- + +3. The location of the Git interface scripts was changed. Make sure you update + your aurweb configuration, as well as the SSH daemon and AUR Git repository + configurations to point to the new wrapper scripts which are located in + /usr/local/bin/ by default. -- cgit v1.2.3-54-g00ecf From 85866796a40923708f6b868c32ddc2f2f4417d1d Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Mon, 17 Oct 2016 15:01:45 +0200 Subject: Move configuration to /etc/aurweb/config Since d4fe77a (Reorganize Git interface scripts, 2016-10-08), the key components of the aurweb SSH interface are installed system-wide. Update the default configuration path to point to a central location. Signed-off-by: Lukas Fleischer --- .gitignore | 1 - INSTALL | 4 ++-- aurweb/config.py | 3 +-- upgrading/4.4.1.txt | 3 +++ web/lib/confparser.inc.php | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 upgrading/4.4.1.txt (limited to 'upgrading') diff --git a/.gitignore b/.gitignore index 2cb5bdc..f0e462d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -conf/config dummy-data.sql* po/*.mo po/*.po~ diff --git a/INSTALL b/INSTALL index 395915a..95cac4c 100644 --- a/INSTALL +++ b/INSTALL @@ -30,8 +30,8 @@ Setup on Arch Linux } } -3) Copy conf/config.proto to conf/config and adjust the configuration (pay - attention to disable_http_login, enable_maintenance and aur_location). +3) Copy conf/config.proto to /etc/aurweb/config and adjust the configuration + (pay attention to disable_http_login, enable_maintenance and aur_location). 4) Create a new MySQL database and a user and import the AUR SQL schema: diff --git a/aurweb/config.py b/aurweb/config.py index aac188b..a52d942 100644 --- a/aurweb/config.py +++ b/aurweb/config.py @@ -12,8 +12,7 @@ def _get_parser(): if 'AUR_CONFIG' in os.environ: path = os.environ.get('AUR_CONFIG') else: - relpath = "/../conf/config" - path = os.path.dirname(os.path.realpath(__file__)) + relpath + path = "/etc/aurweb/config" _parser.read(path) return _parser diff --git a/upgrading/4.4.1.txt b/upgrading/4.4.1.txt new file mode 100644 index 0000000..b06696e --- /dev/null +++ b/upgrading/4.4.1.txt @@ -0,0 +1,3 @@ +1. The default configuration file search path now points to /etc/aurweb/config. + Make sure you copy your aurweb configuration to the new location before + upgrading. diff --git a/web/lib/confparser.inc.php b/web/lib/confparser.inc.php index 6368b86..789300e 100644 --- a/web/lib/confparser.inc.php +++ b/web/lib/confparser.inc.php @@ -4,7 +4,7 @@ function config_load() { global $AUR_CONFIG; if (!isset($AUR_CONFIG)) { - $AUR_CONFIG = parse_ini_file("../../conf/config", true, INI_SCANNER_RAW); + $AUR_CONFIG = parse_ini_file("/etc/aurweb/config", true, INI_SCANNER_RAW); } } -- cgit v1.2.3-54-g00ecf From 37188603b52a3dac23df229ada82c7da0c3d9c00 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Mon, 17 Oct 2016 15:20:29 +0200 Subject: Make maintenance scripts installable Add wrappers for the maintenance scripts to the setuptools configuration. Signed-off-by: Lukas Fleischer --- aurweb/scripts/__init__.py | 0 aurweb/scripts/aurblup.py | 55 +++++ aurweb/scripts/mkpkglists.py | 38 ++++ aurweb/scripts/notify.py | 455 +++++++++++++++++++++++++++++++++++++++ aurweb/scripts/pkgmaint.py | 20 ++ aurweb/scripts/popupdate.py | 26 +++ aurweb/scripts/tuvotereminder.py | 28 +++ scripts/__init__.py | 0 scripts/aurblup.py | 55 ----- scripts/mkpkglists.py | 38 ---- scripts/notify.py | 455 --------------------------------------- scripts/pkgmaint.py | 20 -- scripts/popupdate.py | 26 --- scripts/tuvotereminder.py | 28 --- setup.py | 6 + upgrading/4.4.1.txt | 3 + 16 files changed, 631 insertions(+), 622 deletions(-) create mode 100644 aurweb/scripts/__init__.py create mode 100755 aurweb/scripts/aurblup.py create mode 100755 aurweb/scripts/mkpkglists.py create mode 100755 aurweb/scripts/notify.py create mode 100755 aurweb/scripts/pkgmaint.py create mode 100755 aurweb/scripts/popupdate.py create mode 100755 aurweb/scripts/tuvotereminder.py delete mode 100644 scripts/__init__.py delete mode 100755 scripts/aurblup.py delete mode 100755 scripts/mkpkglists.py delete mode 100755 scripts/notify.py delete mode 100755 scripts/pkgmaint.py delete mode 100755 scripts/popupdate.py delete mode 100755 scripts/tuvotereminder.py (limited to 'upgrading') diff --git a/aurweb/scripts/__init__.py b/aurweb/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aurweb/scripts/aurblup.py b/aurweb/scripts/aurblup.py new file mode 100755 index 0000000..1b6de2f --- /dev/null +++ b/aurweb/scripts/aurblup.py @@ -0,0 +1,55 @@ +#!/usr/bin/python3 + +import pyalpm +import re + +import aurweb.config +import aurweb.db + +db_path = aurweb.config.get('aurblup', 'db-path') +sync_dbs = aurweb.config.get('aurblup', 'sync-dbs').split(' ') +server = aurweb.config.get('aurblup', 'server') + + +def main(): + blacklist = set() + providers = set() + repomap = dict() + + h = pyalpm.Handle("/", db_path) + for sync_db in sync_dbs: + repo = h.register_syncdb(sync_db, pyalpm.SIG_DATABASE_OPTIONAL) + repo.servers = [server.replace("%s", sync_db)] + t = h.init_transaction() + repo.update(False) + t.release() + + for pkg in repo.pkgcache: + blacklist.add(pkg.name) + [blacklist.add(x) for x in pkg.replaces] + providers.add((pkg.name, pkg.name)) + repomap[(pkg.name, pkg.name)] = repo.name + for provision in pkg.provides: + provisionname = re.sub(r'(<|=|>).*', '', provision) + providers.add((pkg.name, provisionname)) + repomap[(pkg.name, provisionname)] = repo.name + + conn = aurweb.db.Connection() + + cur = conn.execute("SELECT Name, Provides FROM OfficialProviders") + oldproviders = set(cur.fetchall()) + + for pkg, provides in providers.difference(oldproviders): + repo = repomap[(pkg, provides)] + conn.execute("INSERT INTO OfficialProviders (Name, Repo, Provides) " + "VALUES (?, ?, ?)", [pkg, repo, provides]) + for pkg, provides in oldproviders.difference(providers): + conn.execute("DELETE FROM OfficialProviders " + "WHERE Name = ? AND Provides = ?", [pkg, provides]) + + conn.commit() + conn.close() + + +if __name__ == '__main__': + main() diff --git a/aurweb/scripts/mkpkglists.py b/aurweb/scripts/mkpkglists.py new file mode 100755 index 0000000..8a0f2e9 --- /dev/null +++ b/aurweb/scripts/mkpkglists.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 + +import datetime +import gzip + +import aurweb.config +import aurweb.db + +packagesfile = aurweb.config.get('mkpkglists', 'packagesfile') +pkgbasefile = aurweb.config.get('mkpkglists', 'pkgbasefile') + + +def main(): + conn = aurweb.db.Connection() + + datestr = datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT") + pkglist_header = "# AUR package list, generated on " + datestr + pkgbaselist_header = "# AUR package base list, generated on " + datestr + + with gzip.open(packagesfile, "w") as f: + f.write(bytes(pkglist_header + "\n", "UTF-8")) + cur = conn.execute("SELECT Packages.Name FROM Packages " + + "INNER JOIN PackageBases " + + "ON PackageBases.ID = Packages.PackageBaseID " + + "WHERE PackageBases.PackagerUID IS NOT NULL") + f.writelines([bytes(x[0] + "\n", "UTF-8") for x in cur.fetchall()]) + + with gzip.open(pkgbasefile, "w") as f: + f.write(bytes(pkgbaselist_header + "\n", "UTF-8")) + cur = conn.execute("SELECT Name FROM PackageBases " + + "WHERE PackagerUID IS NOT NULL") + f.writelines([bytes(x[0] + "\n", "UTF-8") for x in cur.fetchall()]) + + conn.close() + + +if __name__ == '__main__': + main() diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py new file mode 100755 index 0000000..ddd6e49 --- /dev/null +++ b/aurweb/scripts/notify.py @@ -0,0 +1,455 @@ +#!/usr/bin/python3 + +import email.mime.text +import subprocess +import sys +import textwrap + +import aurweb.config +import aurweb.db + +aur_location = aurweb.config.get('options', 'aur_location') +aur_request_ml = aurweb.config.get('options', 'aur_request_ml') + +sendmail = aurweb.config.get('notifications', 'sendmail') +sender = aurweb.config.get('notifications', 'sender') +reply_to = aurweb.config.get('notifications', 'reply-to') + + +def headers_cc(cclist): + return {'Cc': str.join(', ', cclist)} + + +def headers_msgid(thread_id): + return {'Message-ID': thread_id} + + +def headers_reply(thread_id): + return {'In-Reply-To': thread_id, 'References': thread_id} + + +def send_notification(to, subject, body, refs, headers={}): + wrapped = '' + for line in body.splitlines(): + wrapped += textwrap.fill(line, break_long_words=False) + '\n' + if refs: + body = wrapped + '\n' + refs + else: + body = wrapped + + for recipient in to: + msg = email.mime.text.MIMEText(body, 'plain', 'utf-8') + msg['Subject'] = subject + msg['From'] = sender + msg['Reply-to'] = reply_to + msg['To'] = recipient + + for key, value in headers.items(): + msg[key] = value + + p = subprocess.Popen([sendmail, '-t', '-oi'], stdin=subprocess.PIPE) + p.communicate(msg.as_bytes()) + + +def username_from_id(conn, uid): + cur = conn.execute('SELECT UserName FROM Users WHERE ID = ?', [uid]) + return cur.fetchone()[0] + + +def pkgbase_from_id(conn, pkgbase_id): + cur = conn.execute('SELECT Name FROM PackageBases WHERE ID = ?', + [pkgbase_id]) + return cur.fetchone()[0] + + +def pkgbase_from_pkgreq(conn, reqid): + cur = conn.execute('SELECT PackageBaseID FROM PackageRequests ' + + 'WHERE ID = ?', [reqid]) + return cur.fetchone()[0] + + +def get_user_email(conn, uid): + cur = conn.execute('SELECT Email FROM Users WHERE ID = ?', [uid]) + return cur.fetchone()[0] + + +def get_maintainer_email(conn, pkgbase_id): + cur = conn.execute('SELECT Users.Email FROM Users ' + + 'INNER JOIN PackageBases ' + + 'ON PackageBases.MaintainerUID = Users.ID WHERE ' + + 'PackageBases.ID = ?', [pkgbase_id]) + return cur.fetchone()[0] + + +def get_recipients(conn, pkgbase_id, uid): + cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + + 'INNER JOIN PackageNotifications ' + + 'ON PackageNotifications.UserID = Users.ID WHERE ' + + 'PackageNotifications.UserID != ? AND ' + + 'PackageNotifications.PackageBaseID = ?', + [uid, pkgbase_id]) + return [row[0] for row in cur.fetchall()] + + +def get_comment_recipients(conn, pkgbase_id, uid): + cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + + 'INNER JOIN PackageNotifications ' + + 'ON PackageNotifications.UserID = Users.ID WHERE ' + + 'Users.CommentNotify = 1 AND ' + + 'PackageNotifications.UserID != ? AND ' + + 'PackageNotifications.PackageBaseID = ?', + [uid, pkgbase_id]) + return [row[0] for row in cur.fetchall()] + + +def get_update_recipients(conn, pkgbase_id, uid): + cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + + 'INNER JOIN PackageNotifications ' + + 'ON PackageNotifications.UserID = Users.ID WHERE ' + + 'Users.UpdateNotify = 1 AND ' + + 'PackageNotifications.UserID != ? AND ' + + 'PackageNotifications.PackageBaseID = ?', + [uid, pkgbase_id]) + return [row[0] for row in cur.fetchall()] + + +def get_ownership_recipients(conn, pkgbase_id, uid): + cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + + 'INNER JOIN PackageNotifications ' + + 'ON PackageNotifications.UserID = Users.ID WHERE ' + + 'Users.OwnershipNotify = 1 AND ' + + 'PackageNotifications.UserID != ? AND ' + + 'PackageNotifications.PackageBaseID = ?', + [uid, pkgbase_id]) + return [row[0] for row in cur.fetchall()] + + +def get_request_recipients(conn, reqid): + cur = conn.execute('SELECT DISTINCT Users.Email FROM PackageRequests ' + + 'INNER JOIN PackageBases ' + + 'ON PackageBases.ID = PackageRequests.PackageBaseID ' + + 'INNER JOIN Users ' + + 'ON Users.ID = PackageRequests.UsersID ' + + 'OR Users.ID = PackageBases.MaintainerUID ' + + 'WHERE PackageRequests.ID = ?', [reqid]) + return [row[0] for row in cur.fetchall()] + + +def get_tu_vote_reminder_recipients(conn, vote_id): + cur = conn.execute('SELECT Users.Email FROM Users ' + + 'WHERE AccountTypeID = 2 ' + + 'EXCEPT SELECT Users.Email FROM Users ' + + 'INNER JOIN TU_Votes ' + + 'ON TU_Votes.UserID = Users.ID ' + + 'WHERE TU_Votes.VoteID = ?', [vote_id]) + return [row[0] for row in cur.fetchall()] + + +def get_comment(conn, comment_id): + cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID = ?', + [comment_id]) + return cur.fetchone()[0] + + +def get_flagger_comment(conn, pkgbase_id): + cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ID = ?', + [pkgbase_id]) + return cur.fetchone()[0] + + +def get_request_comment(conn, reqid): + cur = conn.execute('SELECT Comments FROM PackageRequests WHERE ID = ?', + [reqid]) + return cur.fetchone()[0] + + +def get_request_closure_comment(conn, reqid): + cur = conn.execute('SELECT ClosureComment FROM PackageRequests ' + + 'WHERE ID = ?', [reqid]) + return cur.fetchone()[0] + + +def send_resetkey(conn, uid): + cur = conn.execute('SELECT UserName, Email, ResetKey FROM Users ' + + 'WHERE ID = ?', [uid]) + username, to, resetkey = cur.fetchone() + + subject = 'AUR Password Reset' + body = 'A password reset request was submitted for the account %s ' \ + 'associated with your email address. If you wish to reset your ' \ + 'password follow the link [1] below, otherwise ignore this ' \ + 'message and nothing will happen.' % (username) + refs = '[1] ' + aur_location + '/passreset/?resetkey=' + resetkey + + send_notification([to], subject, body, refs) + + +def welcome(conn, uid): + cur = conn.execute('SELECT UserName, Email, ResetKey FROM Users ' + + 'WHERE ID = ?', [uid]) + username, to, resetkey = cur.fetchone() + + subject = 'Welcome to the Arch User Repository' + body = 'Welcome to the Arch User Repository! In order to set an initial ' \ + 'password for your new account, please click the link [1] below. ' \ + 'If the link does not work, try copying and pasting it into your ' \ + 'browser.' + refs = '[1] ' + aur_location + '/passreset/?resetkey=' + resetkey + + send_notification([to], subject, body, refs) + + +def comment(conn, uid, pkgbase_id, comment_id): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = get_comment_recipients(conn, pkgbase_id, uid) + text = get_comment(conn, comment_id) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Comment for %s' % (pkgbase) + body = '%s [1] added the following comment to %s [2]:' % (user, pkgbase) + body += '\n\n' + text + '\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 = '' + headers = headers_reply(thread_id) + + send_notification(to, subject, body, refs, headers) + + +def update(conn, uid, pkgbase_id): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = get_update_recipients(conn, 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 = '' + headers = headers_reply(thread_id) + + send_notification(to, subject, body, refs, headers) + + +def flag(conn, uid, pkgbase_id): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = [get_maintainer_email(conn, pkgbase_id)] + text = get_flagger_comment(conn, pkgbase_id) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Out-of-date Notification for %s' % (pkgbase) + body = 'Your package %s [1] has been flagged out-of-date by %s [2]:' % \ + (pkgbase, user) + body += '\n\n' + text + refs = '[1] ' + pkgbase_uri + '\n' + refs += '[2] ' + user_uri + + send_notification(to, subject, body, refs) + + +def adopt(conn, pkgbase_id, uid): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = get_ownership_recipients(conn, pkgbase_id, uid) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Ownership Notification for %s' % (pkgbase) + body = 'The package %s [1] was adopted by %s [2].' % (pkgbase, user) + refs = '[1] ' + pkgbase_uri + '\n' + refs += '[2] ' + user_uri + + send_notification(to, subject, body, refs) + + +def disown(conn, pkgbase_id, uid): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = get_ownership_recipients(conn, pkgbase_id, uid) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Ownership Notification for %s' % (pkgbase) + body = 'The package %s [1] was disowned by %s [2].' % (pkgbase, user) + refs = '[1] ' + pkgbase_uri + '\n' + refs += '[2] ' + user_uri + + send_notification(to, subject, body, refs) + + +def comaintainer_add(conn, pkgbase_id, uid): + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = [get_user_email(conn, uid)] + + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Co-Maintainer Notification for %s' % (pkgbase) + body = 'You were added to the co-maintainer list of %s [1].' % (pkgbase) + refs = '[1] ' + pkgbase_uri + '\n' + + send_notification(to, subject, body, refs) + + +def comaintainer_remove(conn, pkgbase_id, uid): + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = [get_user_email(conn, uid)] + + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = 'AUR Co-Maintainer Notification for %s' % (pkgbase) + body = ('You were removed from the co-maintainer list of %s [1].' % + (pkgbase)) + refs = '[1] ' + pkgbase_uri + '\n' + + send_notification(to, subject, body, refs) + + +def delete(conn, uid, old_pkgbase_id, new_pkgbase_id=None): + user = username_from_id(conn, uid) + old_pkgbase = pkgbase_from_id(conn, old_pkgbase_id) + if new_pkgbase_id: + new_pkgbase = pkgbase_from_id(conn, new_pkgbase_id) + to = get_recipients(conn, old_pkgbase_id, uid) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + old_pkgbase + '/' + + subject = 'AUR Package deleted: %s' % (old_pkgbase) + if new_pkgbase_id: + new_pkgbase_uri = aur_location + '/pkgbase/' + new_pkgbase + '/' + body = '%s [1] merged %s [2] into %s [3].\n\n' \ + 'If you no longer wish receive notifications about the new ' \ + 'package, please go to [3] and click "%s".' %\ + (user, old_pkgbase, new_pkgbase, 'Disable notifications') + refs = '[1] ' + user_uri + '\n' + refs += '[2] ' + pkgbase_uri + '\n' + refs += '[3] ' + new_pkgbase_uri + else: + body = '%s [1] deleted %s [2].\n\n' \ + 'You will no longer receive notifications about this ' \ + 'package.' % (user, old_pkgbase) + refs = '[1] ' + user_uri + '\n' + refs += '[2] ' + pkgbase_uri + + send_notification(to, subject, body, refs) + + +def request_open(conn, uid, reqid, reqtype, pkgbase_id, merge_into=None): + user = username_from_id(conn, uid) + pkgbase = pkgbase_from_id(conn, pkgbase_id) + to = [aur_request_ml] + cc = get_request_recipients(conn, reqid) + text = get_request_comment(conn, reqid) + + user_uri = aur_location + '/account/' + user + '/' + pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' + + subject = '[PRQ#%d] %s Request for %s' % \ + (int(reqid), reqtype.title(), pkgbase) + if merge_into: + merge_into_uri = aur_location + '/pkgbase/' + merge_into + '/' + body = '%s [1] filed a request to merge %s [2] into %s [3]:' % \ + (user, pkgbase, merge_into) + body += '\n\n' + text + refs = '[1] ' + user_uri + '\n' + refs += '[2] ' + pkgbase_uri + '\n' + refs += '[3] ' + merge_into_uri + else: + body = '%s [1] filed a %s request for %s [2]:' % \ + (user, reqtype, pkgbase) + body += '\n\n' + text + refs = '[1] ' + user_uri + '\n' + refs += '[2] ' + pkgbase_uri + '\n' + thread_id = '' + # Use a deterministic Message-ID for the first email referencing a request. + headers = headers_msgid(thread_id) + headers.update(headers_cc(cc)) + + send_notification(to, subject, body, refs, headers) + + +def request_close(conn, uid, reqid, reason): + to = [aur_request_ml] + cc = get_request_recipients(conn, reqid) + text = get_request_closure_comment(conn, reqid) + + subject = '[PRQ#%d] Request %s' % (int(reqid), reason.title()) + if int(uid): + user = username_from_id(conn, uid) + user_uri = aur_location + '/account/' + user + '/' + body = 'Request #%d has been %s by %s [1]' % (int(reqid), reason, user) + refs = '[1] ' + user_uri + else: + body = 'Request #%d has been %s automatically by the Arch User ' \ + 'Repository package request system' % (int(reqid), reason) + refs = None + if text.strip() == '': + body += '.' + else: + body += ':\n\n' + text + thread_id = '' + headers = headers_reply(thread_id) + headers.update(headers_cc(cc)) + + send_notification(to, subject, body, refs, headers) + + +def tu_vote_reminder(conn, vote_id): + to = get_tu_vote_reminder_recipients(conn, vote_id) + + vote_uri = aur_location + '/tu/?id=' + vote_id + + subject = 'TU Vote Reminder: Proposal %d' % (int(vote_id)) + body = 'Please remember to cast your vote on proposal %d [1]. ' \ + 'The voting period ends in less than 48 hours.' % (int(vote_id)) + refs = '[1] ' + vote_uri + + send_notification(to, subject, body, refs) + + +def main(): + action = sys.argv[1] + action_map = { + 'send-resetkey': send_resetkey, + 'welcome': welcome, + 'comment': comment, + 'update': update, + 'flag': flag, + 'adopt': adopt, + 'disown': disown, + 'comaintainer-add': comaintainer_add, + 'comaintainer-remove': comaintainer_remove, + 'delete': delete, + 'request-open': request_open, + 'request-close': request_close, + 'tu-vote-reminder': tu_vote_reminder, + } + + conn = aurweb.db.Connection() + + action_map[action](conn, *sys.argv[2:]) + + conn.commit() + conn.close() + + +if __name__ == '__main__': + main() diff --git a/aurweb/scripts/pkgmaint.py b/aurweb/scripts/pkgmaint.py new file mode 100755 index 0000000..3ad9ed8 --- /dev/null +++ b/aurweb/scripts/pkgmaint.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +import time + +import aurweb.db + + +def main(): + conn = aurweb.db.Connection() + + limit_to = int(time.time()) - 86400 + conn.execute("DELETE FROM PackageBases WHERE " + + "SubmittedTS < ? AND PackagerUID IS NULL", [limit_to]) + + conn.commit() + conn.close() + + +if __name__ == '__main__': + main() diff --git a/aurweb/scripts/popupdate.py b/aurweb/scripts/popupdate.py new file mode 100755 index 0000000..58cd018 --- /dev/null +++ b/aurweb/scripts/popupdate.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import time + +import aurweb.db + + +def main(): + conn = aurweb.db.Connection() + + conn.execute("UPDATE PackageBases SET NumVotes = (" + + "SELECT COUNT(*) FROM PackageVotes " + + "WHERE PackageVotes.PackageBaseID = PackageBases.ID)") + + now = int(time.time()) + conn.execute("UPDATE PackageBases SET Popularity = (" + + "SELECT COALESCE(SUM(POWER(0.98, (? - VoteTS) / 86400)), 0.0) " + + "FROM PackageVotes WHERE PackageVotes.PackageBaseID = " + + "PackageBases.ID AND NOT VoteTS IS NULL)", [now]) + + conn.commit() + conn.close() + + +if __name__ == '__main__': + main() diff --git a/aurweb/scripts/tuvotereminder.py b/aurweb/scripts/tuvotereminder.py new file mode 100755 index 0000000..97b1d12 --- /dev/null +++ b/aurweb/scripts/tuvotereminder.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 + +import subprocess +import time + +import aurweb.config +import aurweb.db + +notify_cmd = aurweb.config.get('notifications', 'notify-cmd') + + +def main(): + conn = aurweb.db.Connection() + + now = int(time.time()) + filter_from = now + 500 + filter_to = now + 172800 + + cur = conn.execute("SELECT ID FROM TU_VoteInfo " + + "WHERE End >= ? AND End <= ?", + [filter_from, filter_to]) + + for vote_id in [row[0] for row in cur.fetchall()]: + subprocess.Popen((notify_cmd, 'tu-vote-reminder', str(vote_id))).wait() + + +if __name__ == '__main__': + main() diff --git a/scripts/__init__.py b/scripts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/aurblup.py b/scripts/aurblup.py deleted file mode 100755 index 1b6de2f..0000000 --- a/scripts/aurblup.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python3 - -import pyalpm -import re - -import aurweb.config -import aurweb.db - -db_path = aurweb.config.get('aurblup', 'db-path') -sync_dbs = aurweb.config.get('aurblup', 'sync-dbs').split(' ') -server = aurweb.config.get('aurblup', 'server') - - -def main(): - blacklist = set() - providers = set() - repomap = dict() - - h = pyalpm.Handle("/", db_path) - for sync_db in sync_dbs: - repo = h.register_syncdb(sync_db, pyalpm.SIG_DATABASE_OPTIONAL) - repo.servers = [server.replace("%s", sync_db)] - t = h.init_transaction() - repo.update(False) - t.release() - - for pkg in repo.pkgcache: - blacklist.add(pkg.name) - [blacklist.add(x) for x in pkg.replaces] - providers.add((pkg.name, pkg.name)) - repomap[(pkg.name, pkg.name)] = repo.name - for provision in pkg.provides: - provisionname = re.sub(r'(<|=|>).*', '', provision) - providers.add((pkg.name, provisionname)) - repomap[(pkg.name, provisionname)] = repo.name - - conn = aurweb.db.Connection() - - cur = conn.execute("SELECT Name, Provides FROM OfficialProviders") - oldproviders = set(cur.fetchall()) - - for pkg, provides in providers.difference(oldproviders): - repo = repomap[(pkg, provides)] - conn.execute("INSERT INTO OfficialProviders (Name, Repo, Provides) " - "VALUES (?, ?, ?)", [pkg, repo, provides]) - for pkg, provides in oldproviders.difference(providers): - conn.execute("DELETE FROM OfficialProviders " - "WHERE Name = ? AND Provides = ?", [pkg, provides]) - - conn.commit() - conn.close() - - -if __name__ == '__main__': - main() diff --git a/scripts/mkpkglists.py b/scripts/mkpkglists.py deleted file mode 100755 index 8a0f2e9..0000000 --- a/scripts/mkpkglists.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/python3 - -import datetime -import gzip - -import aurweb.config -import aurweb.db - -packagesfile = aurweb.config.get('mkpkglists', 'packagesfile') -pkgbasefile = aurweb.config.get('mkpkglists', 'pkgbasefile') - - -def main(): - conn = aurweb.db.Connection() - - datestr = datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT") - pkglist_header = "# AUR package list, generated on " + datestr - pkgbaselist_header = "# AUR package base list, generated on " + datestr - - with gzip.open(packagesfile, "w") as f: - f.write(bytes(pkglist_header + "\n", "UTF-8")) - cur = conn.execute("SELECT Packages.Name FROM Packages " + - "INNER JOIN PackageBases " + - "ON PackageBases.ID = Packages.PackageBaseID " + - "WHERE PackageBases.PackagerUID IS NOT NULL") - f.writelines([bytes(x[0] + "\n", "UTF-8") for x in cur.fetchall()]) - - with gzip.open(pkgbasefile, "w") as f: - f.write(bytes(pkgbaselist_header + "\n", "UTF-8")) - cur = conn.execute("SELECT Name FROM PackageBases " + - "WHERE PackagerUID IS NOT NULL") - f.writelines([bytes(x[0] + "\n", "UTF-8") for x in cur.fetchall()]) - - conn.close() - - -if __name__ == '__main__': - main() diff --git a/scripts/notify.py b/scripts/notify.py deleted file mode 100755 index ddd6e49..0000000 --- a/scripts/notify.py +++ /dev/null @@ -1,455 +0,0 @@ -#!/usr/bin/python3 - -import email.mime.text -import subprocess -import sys -import textwrap - -import aurweb.config -import aurweb.db - -aur_location = aurweb.config.get('options', 'aur_location') -aur_request_ml = aurweb.config.get('options', 'aur_request_ml') - -sendmail = aurweb.config.get('notifications', 'sendmail') -sender = aurweb.config.get('notifications', 'sender') -reply_to = aurweb.config.get('notifications', 'reply-to') - - -def headers_cc(cclist): - return {'Cc': str.join(', ', cclist)} - - -def headers_msgid(thread_id): - return {'Message-ID': thread_id} - - -def headers_reply(thread_id): - return {'In-Reply-To': thread_id, 'References': thread_id} - - -def send_notification(to, subject, body, refs, headers={}): - wrapped = '' - for line in body.splitlines(): - wrapped += textwrap.fill(line, break_long_words=False) + '\n' - if refs: - body = wrapped + '\n' + refs - else: - body = wrapped - - for recipient in to: - msg = email.mime.text.MIMEText(body, 'plain', 'utf-8') - msg['Subject'] = subject - msg['From'] = sender - msg['Reply-to'] = reply_to - msg['To'] = recipient - - for key, value in headers.items(): - msg[key] = value - - p = subprocess.Popen([sendmail, '-t', '-oi'], stdin=subprocess.PIPE) - p.communicate(msg.as_bytes()) - - -def username_from_id(conn, uid): - cur = conn.execute('SELECT UserName FROM Users WHERE ID = ?', [uid]) - return cur.fetchone()[0] - - -def pkgbase_from_id(conn, pkgbase_id): - cur = conn.execute('SELECT Name FROM PackageBases WHERE ID = ?', - [pkgbase_id]) - return cur.fetchone()[0] - - -def pkgbase_from_pkgreq(conn, reqid): - cur = conn.execute('SELECT PackageBaseID FROM PackageRequests ' + - 'WHERE ID = ?', [reqid]) - return cur.fetchone()[0] - - -def get_user_email(conn, uid): - cur = conn.execute('SELECT Email FROM Users WHERE ID = ?', [uid]) - return cur.fetchone()[0] - - -def get_maintainer_email(conn, pkgbase_id): - cur = conn.execute('SELECT Users.Email FROM Users ' + - 'INNER JOIN PackageBases ' + - 'ON PackageBases.MaintainerUID = Users.ID WHERE ' + - 'PackageBases.ID = ?', [pkgbase_id]) - return cur.fetchone()[0] - - -def get_recipients(conn, pkgbase_id, uid): - cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + - 'INNER JOIN PackageNotifications ' + - 'ON PackageNotifications.UserID = Users.ID WHERE ' + - 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', - [uid, pkgbase_id]) - return [row[0] for row in cur.fetchall()] - - -def get_comment_recipients(conn, pkgbase_id, uid): - cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + - 'INNER JOIN PackageNotifications ' + - 'ON PackageNotifications.UserID = Users.ID WHERE ' + - 'Users.CommentNotify = 1 AND ' + - 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', - [uid, pkgbase_id]) - return [row[0] for row in cur.fetchall()] - - -def get_update_recipients(conn, pkgbase_id, uid): - cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + - 'INNER JOIN PackageNotifications ' + - 'ON PackageNotifications.UserID = Users.ID WHERE ' + - 'Users.UpdateNotify = 1 AND ' + - 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', - [uid, pkgbase_id]) - return [row[0] for row in cur.fetchall()] - - -def get_ownership_recipients(conn, pkgbase_id, uid): - cur = conn.execute('SELECT DISTINCT Users.Email FROM Users ' + - 'INNER JOIN PackageNotifications ' + - 'ON PackageNotifications.UserID = Users.ID WHERE ' + - 'Users.OwnershipNotify = 1 AND ' + - 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', - [uid, pkgbase_id]) - return [row[0] for row in cur.fetchall()] - - -def get_request_recipients(conn, reqid): - cur = conn.execute('SELECT DISTINCT Users.Email FROM PackageRequests ' + - 'INNER JOIN PackageBases ' + - 'ON PackageBases.ID = PackageRequests.PackageBaseID ' + - 'INNER JOIN Users ' + - 'ON Users.ID = PackageRequests.UsersID ' + - 'OR Users.ID = PackageBases.MaintainerUID ' + - 'WHERE PackageRequests.ID = ?', [reqid]) - return [row[0] for row in cur.fetchall()] - - -def get_tu_vote_reminder_recipients(conn, vote_id): - cur = conn.execute('SELECT Users.Email FROM Users ' + - 'WHERE AccountTypeID = 2 ' + - 'EXCEPT SELECT Users.Email FROM Users ' + - 'INNER JOIN TU_Votes ' + - 'ON TU_Votes.UserID = Users.ID ' + - 'WHERE TU_Votes.VoteID = ?', [vote_id]) - return [row[0] for row in cur.fetchall()] - - -def get_comment(conn, comment_id): - cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID = ?', - [comment_id]) - return cur.fetchone()[0] - - -def get_flagger_comment(conn, pkgbase_id): - cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ID = ?', - [pkgbase_id]) - return cur.fetchone()[0] - - -def get_request_comment(conn, reqid): - cur = conn.execute('SELECT Comments FROM PackageRequests WHERE ID = ?', - [reqid]) - return cur.fetchone()[0] - - -def get_request_closure_comment(conn, reqid): - cur = conn.execute('SELECT ClosureComment FROM PackageRequests ' + - 'WHERE ID = ?', [reqid]) - return cur.fetchone()[0] - - -def send_resetkey(conn, uid): - cur = conn.execute('SELECT UserName, Email, ResetKey FROM Users ' + - 'WHERE ID = ?', [uid]) - username, to, resetkey = cur.fetchone() - - subject = 'AUR Password Reset' - body = 'A password reset request was submitted for the account %s ' \ - 'associated with your email address. If you wish to reset your ' \ - 'password follow the link [1] below, otherwise ignore this ' \ - 'message and nothing will happen.' % (username) - refs = '[1] ' + aur_location + '/passreset/?resetkey=' + resetkey - - send_notification([to], subject, body, refs) - - -def welcome(conn, uid): - cur = conn.execute('SELECT UserName, Email, ResetKey FROM Users ' + - 'WHERE ID = ?', [uid]) - username, to, resetkey = cur.fetchone() - - subject = 'Welcome to the Arch User Repository' - body = 'Welcome to the Arch User Repository! In order to set an initial ' \ - 'password for your new account, please click the link [1] below. ' \ - 'If the link does not work, try copying and pasting it into your ' \ - 'browser.' - refs = '[1] ' + aur_location + '/passreset/?resetkey=' + resetkey - - send_notification([to], subject, body, refs) - - -def comment(conn, uid, pkgbase_id, comment_id): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = get_comment_recipients(conn, pkgbase_id, uid) - text = get_comment(conn, comment_id) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Comment for %s' % (pkgbase) - body = '%s [1] added the following comment to %s [2]:' % (user, pkgbase) - body += '\n\n' + text + '\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 = '' - headers = headers_reply(thread_id) - - send_notification(to, subject, body, refs, headers) - - -def update(conn, uid, pkgbase_id): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = get_update_recipients(conn, 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 = '' - headers = headers_reply(thread_id) - - send_notification(to, subject, body, refs, headers) - - -def flag(conn, uid, pkgbase_id): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = [get_maintainer_email(conn, pkgbase_id)] - text = get_flagger_comment(conn, pkgbase_id) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Out-of-date Notification for %s' % (pkgbase) - body = 'Your package %s [1] has been flagged out-of-date by %s [2]:' % \ - (pkgbase, user) - body += '\n\n' + text - refs = '[1] ' + pkgbase_uri + '\n' - refs += '[2] ' + user_uri - - send_notification(to, subject, body, refs) - - -def adopt(conn, pkgbase_id, uid): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = get_ownership_recipients(conn, pkgbase_id, uid) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Ownership Notification for %s' % (pkgbase) - body = 'The package %s [1] was adopted by %s [2].' % (pkgbase, user) - refs = '[1] ' + pkgbase_uri + '\n' - refs += '[2] ' + user_uri - - send_notification(to, subject, body, refs) - - -def disown(conn, pkgbase_id, uid): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = get_ownership_recipients(conn, pkgbase_id, uid) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Ownership Notification for %s' % (pkgbase) - body = 'The package %s [1] was disowned by %s [2].' % (pkgbase, user) - refs = '[1] ' + pkgbase_uri + '\n' - refs += '[2] ' + user_uri - - send_notification(to, subject, body, refs) - - -def comaintainer_add(conn, pkgbase_id, uid): - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = [get_user_email(conn, uid)] - - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Co-Maintainer Notification for %s' % (pkgbase) - body = 'You were added to the co-maintainer list of %s [1].' % (pkgbase) - refs = '[1] ' + pkgbase_uri + '\n' - - send_notification(to, subject, body, refs) - - -def comaintainer_remove(conn, pkgbase_id, uid): - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = [get_user_email(conn, uid)] - - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = 'AUR Co-Maintainer Notification for %s' % (pkgbase) - body = ('You were removed from the co-maintainer list of %s [1].' % - (pkgbase)) - refs = '[1] ' + pkgbase_uri + '\n' - - send_notification(to, subject, body, refs) - - -def delete(conn, uid, old_pkgbase_id, new_pkgbase_id=None): - user = username_from_id(conn, uid) - old_pkgbase = pkgbase_from_id(conn, old_pkgbase_id) - if new_pkgbase_id: - new_pkgbase = pkgbase_from_id(conn, new_pkgbase_id) - to = get_recipients(conn, old_pkgbase_id, uid) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + old_pkgbase + '/' - - subject = 'AUR Package deleted: %s' % (old_pkgbase) - if new_pkgbase_id: - new_pkgbase_uri = aur_location + '/pkgbase/' + new_pkgbase + '/' - body = '%s [1] merged %s [2] into %s [3].\n\n' \ - 'If you no longer wish receive notifications about the new ' \ - 'package, please go to [3] and click "%s".' %\ - (user, old_pkgbase, new_pkgbase, 'Disable notifications') - refs = '[1] ' + user_uri + '\n' - refs += '[2] ' + pkgbase_uri + '\n' - refs += '[3] ' + new_pkgbase_uri - else: - body = '%s [1] deleted %s [2].\n\n' \ - 'You will no longer receive notifications about this ' \ - 'package.' % (user, old_pkgbase) - refs = '[1] ' + user_uri + '\n' - refs += '[2] ' + pkgbase_uri - - send_notification(to, subject, body, refs) - - -def request_open(conn, uid, reqid, reqtype, pkgbase_id, merge_into=None): - user = username_from_id(conn, uid) - pkgbase = pkgbase_from_id(conn, pkgbase_id) - to = [aur_request_ml] - cc = get_request_recipients(conn, reqid) - text = get_request_comment(conn, reqid) - - user_uri = aur_location + '/account/' + user + '/' - pkgbase_uri = aur_location + '/pkgbase/' + pkgbase + '/' - - subject = '[PRQ#%d] %s Request for %s' % \ - (int(reqid), reqtype.title(), pkgbase) - if merge_into: - merge_into_uri = aur_location + '/pkgbase/' + merge_into + '/' - body = '%s [1] filed a request to merge %s [2] into %s [3]:' % \ - (user, pkgbase, merge_into) - body += '\n\n' + text - refs = '[1] ' + user_uri + '\n' - refs += '[2] ' + pkgbase_uri + '\n' - refs += '[3] ' + merge_into_uri - else: - body = '%s [1] filed a %s request for %s [2]:' % \ - (user, reqtype, pkgbase) - body += '\n\n' + text - refs = '[1] ' + user_uri + '\n' - refs += '[2] ' + pkgbase_uri + '\n' - thread_id = '' - # Use a deterministic Message-ID for the first email referencing a request. - headers = headers_msgid(thread_id) - headers.update(headers_cc(cc)) - - send_notification(to, subject, body, refs, headers) - - -def request_close(conn, uid, reqid, reason): - to = [aur_request_ml] - cc = get_request_recipients(conn, reqid) - text = get_request_closure_comment(conn, reqid) - - subject = '[PRQ#%d] Request %s' % (int(reqid), reason.title()) - if int(uid): - user = username_from_id(conn, uid) - user_uri = aur_location + '/account/' + user + '/' - body = 'Request #%d has been %s by %s [1]' % (int(reqid), reason, user) - refs = '[1] ' + user_uri - else: - body = 'Request #%d has been %s automatically by the Arch User ' \ - 'Repository package request system' % (int(reqid), reason) - refs = None - if text.strip() == '': - body += '.' - else: - body += ':\n\n' + text - thread_id = '' - headers = headers_reply(thread_id) - headers.update(headers_cc(cc)) - - send_notification(to, subject, body, refs, headers) - - -def tu_vote_reminder(conn, vote_id): - to = get_tu_vote_reminder_recipients(conn, vote_id) - - vote_uri = aur_location + '/tu/?id=' + vote_id - - subject = 'TU Vote Reminder: Proposal %d' % (int(vote_id)) - body = 'Please remember to cast your vote on proposal %d [1]. ' \ - 'The voting period ends in less than 48 hours.' % (int(vote_id)) - refs = '[1] ' + vote_uri - - send_notification(to, subject, body, refs) - - -def main(): - action = sys.argv[1] - action_map = { - 'send-resetkey': send_resetkey, - 'welcome': welcome, - 'comment': comment, - 'update': update, - 'flag': flag, - 'adopt': adopt, - 'disown': disown, - 'comaintainer-add': comaintainer_add, - 'comaintainer-remove': comaintainer_remove, - 'delete': delete, - 'request-open': request_open, - 'request-close': request_close, - 'tu-vote-reminder': tu_vote_reminder, - } - - conn = aurweb.db.Connection() - - action_map[action](conn, *sys.argv[2:]) - - conn.commit() - conn.close() - - -if __name__ == '__main__': - main() diff --git a/scripts/pkgmaint.py b/scripts/pkgmaint.py deleted file mode 100755 index 3ad9ed8..0000000 --- a/scripts/pkgmaint.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/python3 - -import time - -import aurweb.db - - -def main(): - conn = aurweb.db.Connection() - - limit_to = int(time.time()) - 86400 - conn.execute("DELETE FROM PackageBases WHERE " + - "SubmittedTS < ? AND PackagerUID IS NULL", [limit_to]) - - conn.commit() - conn.close() - - -if __name__ == '__main__': - main() diff --git a/scripts/popupdate.py b/scripts/popupdate.py deleted file mode 100755 index 58cd018..0000000 --- a/scripts/popupdate.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python3 - -import time - -import aurweb.db - - -def main(): - conn = aurweb.db.Connection() - - conn.execute("UPDATE PackageBases SET NumVotes = (" + - "SELECT COUNT(*) FROM PackageVotes " + - "WHERE PackageVotes.PackageBaseID = PackageBases.ID)") - - now = int(time.time()) - conn.execute("UPDATE PackageBases SET Popularity = (" + - "SELECT COALESCE(SUM(POWER(0.98, (? - VoteTS) / 86400)), 0.0) " + - "FROM PackageVotes WHERE PackageVotes.PackageBaseID = " + - "PackageBases.ID AND NOT VoteTS IS NULL)", [now]) - - conn.commit() - conn.close() - - -if __name__ == '__main__': - main() diff --git a/scripts/tuvotereminder.py b/scripts/tuvotereminder.py deleted file mode 100755 index 97b1d12..0000000 --- a/scripts/tuvotereminder.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python3 - -import subprocess -import time - -import aurweb.config -import aurweb.db - -notify_cmd = aurweb.config.get('notifications', 'notify-cmd') - - -def main(): - conn = aurweb.db.Connection() - - now = int(time.time()) - filter_from = now + 500 - filter_to = now + 172800 - - cur = conn.execute("SELECT ID FROM TU_VoteInfo " + - "WHERE End >= ? AND End <= ?", - [filter_from, filter_to]) - - for vote_id in [row[0] for row in cur.fetchall()]: - subprocess.Popen((notify_cmd, 'tu-vote-reminder', str(vote_id))).wait() - - -if __name__ == '__main__': - main() diff --git a/setup.py b/setup.py index b64e71c..99dbfed 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,12 @@ setup( 'aurweb-git-auth = aurweb.git.auth:main', 'aurweb-git-serve = aurweb.git.serve:main', 'aurweb-git-update = aurweb.git.update:main', + 'aurweb-aurblup = aurweb.scripts.aurblup:main', + 'aurweb-mkpkglists = aurweb.scripts.mkpkglists:main', + 'aurweb-notify = aurweb.scripts.notify:main', + 'aurweb-pkgmaint = aurweb.scripts.pkgmaint:main', + 'aurweb-popupdate = aurweb.scripts.popupdate:main', + 'aurweb-tuvotereminder = aurweb.scripts.tuvotereminder:main', ], }, ) diff --git a/upgrading/4.4.1.txt b/upgrading/4.4.1.txt index b06696e..726f9e2 100644 --- a/upgrading/4.4.1.txt +++ b/upgrading/4.4.1.txt @@ -1,3 +1,6 @@ 1. The default configuration file search path now points to /etc/aurweb/config. Make sure you copy your aurweb configuration to the new location before upgrading. + +2. The maintenance scripts have been prefixed by "aurweb-" and can now be + installed using `python3 setup.py install`. -- cgit v1.2.3-54-g00ecf