add ability to download package from external links (e.g. HTTP)

This commit is contained in:
2021-10-20 03:09:58 +03:00
parent 9d4f85624d
commit ff24188ca1
5 changed files with 66 additions and 17 deletions

View File

@ -144,11 +144,12 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
"from another repository source); "
"3) it is also possible to add package from local PKGBUILD, but in this case it "
"will be ignored during the next automatic updates; "
"4) and finally you can add package from AUR.",
"4) ahriman supports downloading archives from remote (e.g. HTTP) sources; "
"5) and finally you can add package from AUR.",
formatter_class=_formatter)
parser.add_argument("package", help="package base/name or path to local files", nargs="+")
parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+")
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
parser.add_argument("-s", "--source", help="package source",
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
type=PackageSource, choices=PackageSource, default=PackageSource.Auto)
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
parser.set_defaults(handler=handlers.Add)

View File

@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import logging
import requests
import shutil
from pathlib import Path
@ -111,6 +112,12 @@ class Application:
dst = self.repository.paths.packages / src.name
shutil.copy(src, dst)
def add_aur(src: str) -> Path:
package = Package.load(src, self.repository.pacman, aur_url)
Sources.load(self.repository.paths.manual_for(package.base), package.git_url,
self.repository.paths.patches_for(package.base))
return self.repository.paths.manual_for(package.base)
def add_directory(path: Path) -> None:
for full_path in filter(package_like, path.iterdir()):
add_archive(full_path)
@ -123,11 +130,13 @@ class Application:
shutil.copytree(cache_dir, self.repository.paths.manual_for(package.base)) # copy package for the build
return self.repository.paths.manual_for(package.base)
def add_remote(src: str) -> Path:
package = Package.load(src, self.repository.pacman, aur_url)
Sources.load(self.repository.paths.manual_for(package.base), package.git_url,
self.repository.paths.patches_for(package.base))
return self.repository.paths.manual_for(package.base)
def add_remote(src: str) -> None:
dst = self.repository.paths.packages / Path(src).name # URL is path, is not it?
response = requests.get(src, stream=True)
response.raise_for_status()
with dst.open("wb") as local_file:
for chunk in response.iter_content(chunk_size=1024):
local_file.write(chunk)
def process_dependencies(path: Path) -> None:
if without_dependencies:
@ -140,13 +149,15 @@ class Application:
if resolved_source == PackageSource.Archive:
add_archive(Path(src))
elif resolved_source == PackageSource.AUR:
path = add_remote(src)
path = add_aur(src)
process_dependencies(path)
elif resolved_source == PackageSource.Directory:
add_directory(Path(src))
elif resolved_source == PackageSource.Local:
path = add_local(Path(src))
process_dependencies(path)
elif resolved_source == PackageSource.Remote:
add_remote(src)
for name in names:
process_single(name)

View File

@ -21,6 +21,7 @@ from __future__ import annotations
from enum import Enum
from pathlib import Path
from urllib.parse import urlparse
from ahriman.core.util import package_like
@ -33,6 +34,7 @@ class PackageSource(Enum):
:cvar AUR: source is an AUR package for which it should search
:cvar Directory: source is a directory which contains packages
:cvar Local: source is locally stored PKGBUILD
:cvar Remote: source is remote (http, ftp etc) link
"""
Auto = "auto"
@ -40,6 +42,7 @@ class PackageSource(Enum):
AUR = "aur"
Directory = "directory"
Local = "local"
Remote = "remote"
def resolve(self, source: str) -> PackageSource:
"""
@ -50,11 +53,16 @@ class PackageSource(Enum):
if self != PackageSource.Auto:
return self
maybe_path = Path(source)
maybe_url = urlparse(source) # handle file:// like paths
maybe_path = Path(maybe_url.path)
if maybe_url.scheme and maybe_url.scheme not in ("data", "file") and package_like(maybe_path):
return PackageSource.Remote
if (maybe_path / "PKGBUILD").is_file():
return PackageSource.Local
if maybe_path.is_dir():
return PackageSource.Directory
if maybe_path.is_file() and package_like(maybe_path):
return PackageSource.Archive
return PackageSource.AUR