Commit 16765d55 authored by Lukas Fleischer's avatar Lukas Fleischer
Browse files

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's avatarLukas Fleischer <lfleischer@archlinux.org>
parent 4411a55e
...@@ -301,6 +301,16 @@ CREATE TABLE PackageBlacklist ( ...@@ -301,6 +301,16 @@ CREATE TABLE PackageBlacklist (
UNIQUE (Name) UNIQUE (Name)
) ENGINE = InnoDB; ) 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 -- Define package request types
-- --
CREATE TABLE RequestTypes ( CREATE TABLE RequestTypes (
......
...@@ -18,6 +18,7 @@ sync_dbs = config.get('aurblup', 'sync-dbs').split(' ') ...@@ -18,6 +18,7 @@ sync_dbs = config.get('aurblup', 'sync-dbs').split(' ')
servers = config.get('aurblup', 'servers').split(' ') servers = config.get('aurblup', 'servers').split(' ')
blacklist = set() blacklist = set()
providers = set()
h = pyalpm.Handle("/", db_path) h = pyalpm.Handle("/", db_path)
for sync_db in sync_dbs: for sync_db in sync_dbs:
...@@ -30,6 +31,8 @@ for sync_db in sync_dbs: ...@@ -30,6 +31,8 @@ for sync_db in sync_dbs:
for pkg in repo.pkgcache: for pkg in repo.pkgcache:
blacklist.add(pkg.name) blacklist.add(pkg.name)
[blacklist.add(x) for x in pkg.replaces] [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, db = mysql.connector.connect(host=aur_db_host, user=aur_db_user,
passwd=aur_db_pass, db=aur_db_name, passwd=aur_db_pass, db=aur_db_name,
...@@ -44,5 +47,15 @@ for pkg in blacklist.difference(oldblacklist): ...@@ -44,5 +47,15 @@ for pkg in blacklist.difference(oldblacklist):
for pkg in oldblacklist.difference(blacklist): for pkg in oldblacklist.difference(blacklist):
cur.execute("DELETE FROM PackageBlacklist WHERE Name = %s", [pkg]) 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.commit()
db.close() db.close()
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);
----
...@@ -168,6 +168,9 @@ function pkg_providers($name) { ...@@ -168,6 +168,9 @@ function pkg_providers($name) {
$q.= "INNER JOIN RelationTypes rt ON rt.ID = pr.RelTypeID "; $q.= "INNER JOIN RelationTypes rt ON rt.ID = pr.RelTypeID ";
$q.= "WHERE rt.Name = 'provides' "; $q.= "WHERE rt.Name = 'provides' ";
$q.= "AND pr.RelName = " . $dbh->quote($name); $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); $result = $dbh->query($q);
if (!$result) { if (!$result) {
...@@ -280,6 +283,29 @@ function pkg_deplink_annotation($type, $arch, $desc=false) { ...@@ -280,6 +283,29 @@ function pkg_deplink_annotation($type, $arch, $desc=false) {
return $link; 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 = '<a href="';
if ($official) {
$link .= 'https://www.archlinux.org/packages/?q=' .
urlencode($name);
} else {
$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
}
$link .= '" title="' . __('View packages details for') . ' ';
$link .= htmlspecialchars($name) . '">';
$link .= htmlspecialchars($name) . '</a>';
return $link;
}
/** /**
* Get the HTML code to display a package dependency 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) { ...@@ -312,31 +338,37 @@ function pkg_depend_link($name, $type, $cond, $arch, $pkg_id) {
$providers = pkg_providers($name); $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) { if (count($providers) > 0) {
$link = htmlspecialchars($name) . ' ';
$link .= '<span class="virtual-dep">('; $link .= '<span class="virtual-dep">(';
foreach ($providers as $provider) { foreach ($providers as $provider) {
$is_official = ($provider[0] == 0);
$name = $provider[1]; $name = $provider[1];
$link .= '<a href="'; $link .= pkg_provider_link($name, $is_official) . ', ';
$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
$link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
$link .= htmlspecialchars($name) . '</a>, ';
} }
$link = substr($link, 0, -2); $link = substr($link, 0, -2);
$link .= ')</span>'; $link .= ')</span>';
} else {
$link = '<a href="';
if (is_null($pkg_id)) {
$link .= 'https://www.archlinux.org/packages/?q=' . urlencode($name);
} else {
$link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
}
$link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
$link .= htmlspecialchars($name) . '</a>';
$link .= htmlspecialchars($cond);
} }
return $link . pkg_deplink_annotation($type, $arch, $desc); $link .= pkg_deplink_annotation($type, $arch, $desc);
return $link;
} }
/** /**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment