From 16765d553233e50b326456393108729b1f3828bf Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Wed, 21 Oct 2015 18:41:43 +0200 Subject: Track providers in the official repositories Maintain a list of virtual provisions of packages from the official binary package repositories. The list can be updated using the aurblup script, e.g. via a cronjob. This allows for adding proper links to package dependencies: If an AUR package depends on a package from the official repositories (or on a name provided by a package from the official repositories), add a link to the corresponding archweb package details page. If an AUR package depends on another AUR package (or on a name provided by another AUR package), add a link to the corresponding aurweb package details page. Otherwise, just display the name and do not add a link at all. Fixes FS#46549. Signed-off-by: Lukas Fleischer --- schema/aur-schema.sql | 10 ++++++++ scripts/aurblup.py | 13 ++++++++++ upgrading/4.2.0.txt | 11 +++++++++ web/lib/pkgfuncs.inc.php | 64 ++++++++++++++++++++++++++++++++++++------------ 4 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 upgrading/4.2.0.txt diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index 53dc468..0a0c806 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -301,6 +301,16 @@ CREATE TABLE PackageBlacklist ( UNIQUE (Name) ) ENGINE = InnoDB; +-- Providers in the official repositories +-- +CREATE TABLE OfficialProviders ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + Provides VARCHAR(64) NOT NULL, + PRIMARY KEY (ID) +) ENGINE = InnoDB; +CREATE UNIQUE INDEX ProviderNameProvides ON OfficialProviders (Name, Provides); + -- Define package request types -- CREATE TABLE RequestTypes ( diff --git a/scripts/aurblup.py b/scripts/aurblup.py index d6d0c3c..5397528 100755 --- a/scripts/aurblup.py +++ b/scripts/aurblup.py @@ -18,6 +18,7 @@ sync_dbs = config.get('aurblup', 'sync-dbs').split(' ') servers = config.get('aurblup', 'servers').split(' ') blacklist = set() +providers = set() h = pyalpm.Handle("/", db_path) for sync_db in sync_dbs: @@ -30,6 +31,8 @@ for sync_db in sync_dbs: for pkg in repo.pkgcache: blacklist.add(pkg.name) [blacklist.add(x) for x in pkg.replaces] + providers.add((pkg.name, pkg.name)) + [providers.add((pkg.name, x)) for x in pkg.provides] db = mysql.connector.connect(host=aur_db_host, user=aur_db_user, passwd=aur_db_pass, db=aur_db_name, @@ -44,5 +47,15 @@ for pkg in blacklist.difference(oldblacklist): for pkg in oldblacklist.difference(blacklist): cur.execute("DELETE FROM PackageBlacklist WHERE Name = %s", [pkg]) +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]) +for pkg, provides in oldproviders.difference(providers): + cur.execute("DELETE FROM OfficialProviders " + "WHERE Name = %s AND Provides = %s", [pkg, provides]) + db.commit() db.close() diff --git a/upgrading/4.2.0.txt b/upgrading/4.2.0.txt new file mode 100644 index 0000000..37cbeae --- /dev/null +++ b/upgrading/4.2.0.txt @@ -0,0 +1,11 @@ +1. Add a new table to store providers from official packages: + +---- +CREATE TABLE OfficialProviders ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + Provides VARCHAR(64) NOT NULL, + PRIMARY KEY (ID) +) ENGINE = InnoDB; +CREATE UNIQUE INDEX ProviderNameProvides ON OfficialProviders (Name, Provides); +---- diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 66bc249..717085d 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -168,6 +168,9 @@ function pkg_providers($name) { $q.= "INNER JOIN RelationTypes rt ON rt.ID = pr.RelTypeID "; $q.= "WHERE rt.Name = 'provides' "; $q.= "AND pr.RelName = " . $dbh->quote($name); + $q.= "UNION "; + $q.= "SELECT 0, Name FROM OfficialProviders "; + $q.= "WHERE Provides = " . $dbh->quote($name); $result = $dbh->query($q); if (!$result) { @@ -280,6 +283,29 @@ function pkg_deplink_annotation($type, $arch, $desc=false) { return $link; } +/** + * Get the HTML code to display a package provider link + * + * @param string $name The name of the provider + * @param bool $official True if the package is in the official repositories + * + * @return string The HTML code of the link to display + */ +function pkg_provider_link($name, $official) { + $link = ''; + $link .= htmlspecialchars($name) . ''; + + return $link; +} + /** * Get the HTML code to display a package dependency link * @@ -312,31 +338,37 @@ function pkg_depend_link($name, $type, $cond, $arch, $pkg_id) { $providers = pkg_providers($name); } + $link = htmlspecialchars($name); + foreach ($providers as $provider) { + if ($provider[1] == $name) { + $is_official = ($provider[0] == 0); + $name = $provider[1]; + $link = pkg_provider_link($name, $is_official); + break; + } + } + $link .= ' ' . htmlspecialchars($cond); + + foreach ($providers as $key => $provider) { + if ($provider[1] == $name) { + unset($providers[$key]); + } + } + if (count($providers) > 0) { - $link = htmlspecialchars($name) . ' '; $link .= '('; foreach ($providers as $provider) { + $is_official = ($provider[0] == 0); $name = $provider[1]; - $link .= ''; - $link .= htmlspecialchars($name) . ', '; + $link .= pkg_provider_link($name, $is_official) . ', '; } $link = substr($link, 0, -2); $link .= ')'; - } else { - $link = ''; - $link .= htmlspecialchars($name) . ''; - $link .= htmlspecialchars($cond); } - return $link . pkg_deplink_annotation($type, $arch, $desc); + $link .= pkg_deplink_annotation($type, $arch, $desc); + + return $link; } /** -- cgit v1.2.3-70-g09d2