mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2025-05-13 14:44:29 -04:00
448 lines
12 KiB
Python
448 lines
12 KiB
Python
# __package__ = 'archivebox.plugins.system'
|
|
|
|
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import inspect
|
|
import django
|
|
from sqlite3 import dbapi2 as sqlite3
|
|
|
|
from pathlib import Path
|
|
from typing import List, Dict, Any
|
|
|
|
from django.db import models
|
|
from django.utils.functional import cached_property
|
|
|
|
from solo.models import SingletonModel
|
|
|
|
from config import bin_path, bin_version, VERSION
|
|
|
|
from plugins.defaults.models import ArchiveBoxBaseDependency
|
|
|
|
ConfigDict = Dict[str, Any]
|
|
|
|
|
|
class BashEnvironmentDependency(ArchiveBoxBaseDependency):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'BASH'
|
|
LABEL = "Bash"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = []
|
|
|
|
BIN_DEPENDENCIES: List[str] = ['bash']
|
|
APT_DEPENDENCIES: List[str] = []
|
|
BREW_DEPENDENCIES: List[str] = []
|
|
PIP_DEPENDENCIES: List[str] = []
|
|
NPM_DEPENDENCIES: List[str] = []
|
|
|
|
DEFAULT_BINARY = 'bash'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = '-c'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=not REQUIRED)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
VERSION_CMD = models.CharField(max_length=255, default='{BINARY} --version')
|
|
|
|
# START_CMD = models.CharField(max_length=255, default=DEFAULT_START_CMD)
|
|
# WORKERS = models.IntegerField(default=1)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Shell Environment: bash"
|
|
verbose_name_plural = "Shell Environments: bash"
|
|
|
|
# @task
|
|
def install_pkgs(self, os_pkgs=()):
|
|
assert self.is_valid, 'Bash environment is not available on this host'
|
|
|
|
for os_dependency in os_pkgs:
|
|
assert bin_path(os_dependency)
|
|
|
|
return True
|
|
|
|
class PythonEnvironmentDependency(ArchiveBoxBaseDependency):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'PYTHON'
|
|
LABEL = "Python"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = []
|
|
|
|
BIN_DEPENDENCIES = ['python3']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_DEPENDENCIES = []
|
|
NPM_DEPENDENCIES = []
|
|
|
|
DEFAULT_BINARY = 'python3'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = '-c'
|
|
VERSION_CMD = '{BINARY} --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=not REQUIRED)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
# START_CMD = models.CharField(max_length=255, default=DEFAULT_START_CMD)
|
|
# WORKERS = models.IntegerField(default=1)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Shell Environment: python3"
|
|
|
|
class NodeJSEnvironmentDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'NODEJS'
|
|
LABEL = "NodeJS"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = []
|
|
|
|
BIN_DEPENDENCIES = ['node']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_DEPENDENCIES = []
|
|
NPM_DEPENDENCIES = []
|
|
|
|
DEFAULT_BINARY = 'node'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = '-c'
|
|
VERSION_CMD = '{BINARY} --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=True)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
# START_CMD = models.CharField(max_length=255, default=DEFAULT_START_CMD)
|
|
# WORKERS = models.IntegerField(default=1)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Shell Environment: node"
|
|
|
|
|
|
class AptEnvironmentDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'APT'
|
|
LABEL = "apt"
|
|
REQUIRED = False
|
|
|
|
PARENT_DEPENDENCIES = ['BashEnvironmentDependency']
|
|
|
|
BIN_DEPENDENCIES = ['apt-get']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_PACKAGES = []
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'apt-get'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = '-qq'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=not REQUIRED)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Package Manager: apt"
|
|
|
|
# @task
|
|
def install_pkgs(self, apt_pkgs=()):
|
|
assert self.is_valid, 'Apt environment is not available on this host'
|
|
|
|
# with huey.lock_task('apt-install'):
|
|
|
|
run(cmd=[self.DEFAULT_BINARY, '-qq', 'update'])
|
|
for apt_package in apt_pkgs:
|
|
run(cmd=[self.DEFAULT_BINARY, 'install', '-y', apt_package])
|
|
|
|
return True
|
|
|
|
class BrewEnvironmentDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'BREW'
|
|
LABEL = "homebrew"
|
|
REQUIRED = False
|
|
|
|
PARENT_DEPENDENCIES = ['BashEnvironmentDependency']
|
|
|
|
BIN_DEPENDENCIES = ['brew']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_PACKAGES = []
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'brew'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = ''
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=True)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Package Manager: brew"
|
|
|
|
# @task
|
|
def install_pkgs(self, brew_pkgs=()):
|
|
assert self.is_valid, 'Brw environment is not available on this host'
|
|
|
|
run(cmd=[self.DEFAULT_BINARY, 'update'])
|
|
|
|
for brew_pkg in brew_pkgs:
|
|
run(cmd=[self.DEFAULT_BINARY, 'install', brew_pkg])
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class PipEnvironmentDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'PIP'
|
|
LABEL = "pip"
|
|
REQUIRED = False
|
|
|
|
PARENT_DEPENDENCIES = ['BashEnvironmentDependency']
|
|
|
|
BIN_DEPENDENCIES = ['python3', 'pip3']
|
|
APT_DEPENDENCIES = ['python3.11', 'pip3', 'pipx']
|
|
BREW_DEPENDENCIES = ['python@3.11', 'pipx']
|
|
PIP_PACKAGES = ['setuptools', 'pipx']
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'pip3'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = ''
|
|
VERSION_CMD = '{BINARY} --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=True)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Package Manager: pip"
|
|
|
|
# @task
|
|
def install_pkgs(self, pip_pkgs=()):
|
|
assert self.is_valid, 'Pip environment is not available on this host'
|
|
|
|
for pip_pkg in pip_pkgs:
|
|
run(cmd=[self.DEFAULT_BINARY, 'install', '--update', '--ignore-installed', pip_pkg])
|
|
|
|
return True
|
|
|
|
|
|
class NPMEnvironmentDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'NODEJS'
|
|
LABEL = "NodeJS"
|
|
REQUIRED = False
|
|
|
|
PARENT_DEPENDENCIES = ['BashEnvironmentDependency']
|
|
|
|
BIN_DEPENDENCIES = ['node', 'npm']
|
|
APT_DEPENDENCIES = ['node', 'npm']
|
|
BREW_DEPENDENCIES = ['node', 'npm']
|
|
PIP_PACKAGES = []
|
|
NPM_PACKAGES = ['npm']
|
|
|
|
DEFAULT_BINARY = 'node'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = ''
|
|
VERSION_CMD = '{BINARY} --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=True)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Package Manager: npm"
|
|
|
|
# @task
|
|
def install_pkgs(self, npm_pkgs=()):
|
|
assert self.is_valid, 'NPM environment is not available on this host'
|
|
|
|
for npm_pkg in npm_pkgs:
|
|
run(cmd=[self.DEFAULT_BINARY, 'install', npm_pkg])
|
|
|
|
return True
|
|
|
|
|
|
class DjangoDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'DJANGO'
|
|
LABEL = "Django"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = []
|
|
|
|
BIN_DEPENDENCIES = ['django-admin.py']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_PACKAGES = ['django==3.1.14']
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'django-admin.py'
|
|
DEFAULT_START_CMD = 'archivebox server 0.0.0.0:8000'
|
|
DEFAULT_PID_FILE = 'logs/{NAME}_WORKER.pid'
|
|
DEFAULT_STOP_CMD = 'kill "$(<{PID_FILE})"'
|
|
DEFAULT_ARGS = []
|
|
VERSION_CMD = '{BINARY} --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=False)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY, editable=False)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS, editable=False)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Internal Dependency: django"
|
|
|
|
@cached_property
|
|
def bin_path(self):
|
|
return inspect.getfile(django)
|
|
|
|
@cached_property
|
|
def bin_version(self):
|
|
return '.'.join(str(v) for v in django.VERSION[:3])
|
|
|
|
|
|
class SQLiteDependency(ArchiveBoxBaseDependency, SingletonModel):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'SQLITE'
|
|
LABEL = "SQLite"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = []
|
|
|
|
BIN_DEPENDENCIES = []
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_PACKAGES = []
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'sqlite3'
|
|
DEFAULT_START_CMD = None
|
|
DEFAULT_STOP_CMD = None
|
|
DEFAULT_PID_FILE = None
|
|
DEFAULT_ARGS = []
|
|
VERSION_CMD = 'python3 -c ""'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=False)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY, editable=False)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS, editable=False)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Internal Dependency: sqlite3"
|
|
|
|
@cached_property
|
|
def bin_path(self):
|
|
return inspect.getfile(sqlite3)
|
|
|
|
@cached_property
|
|
def bin_version(self):
|
|
return sqlite3.version
|
|
|
|
class ArchiveBoxDependency(ArchiveBoxBaseDependency):
|
|
singleton_instance_id = 1
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
NAME = 'ARCHIVEBOX'
|
|
LABEL = "ArchiveBox"
|
|
REQUIRED = True
|
|
|
|
PARENT_DEPENDENCIES = [
|
|
'PipEnvironmentDependency',
|
|
'DjangoDependency',
|
|
'SQLiteDependency',
|
|
]
|
|
|
|
BIN_DEPENDENCIES = ['archivebox']
|
|
APT_DEPENDENCIES = []
|
|
BREW_DEPENDENCIES = []
|
|
PIP_PACKAGES = ['archivebox']
|
|
NPM_PACKAGES = []
|
|
|
|
DEFAULT_BINARY = 'archivebox'
|
|
DEFAULT_START_CMD = '{BINARY} server 0.0.0.0:8000'
|
|
DEFAULT_ARGS = []
|
|
VERSION_CMD = 'archivebox --version'
|
|
|
|
ENABLED = models.BooleanField(default=True, editable=False)
|
|
BINARY = models.CharField(max_length=255, default=DEFAULT_BINARY, editable=False)
|
|
ARGS = models.CharField(max_length=255, default=DEFAULT_ARGS, editable=False)
|
|
|
|
class Meta:
|
|
abstract = False
|
|
app_label = 'system'
|
|
verbose_name = "Internal Dependency: archivebox"
|
|
|
|
@cached_property
|
|
def bin_path(self):
|
|
return sys.argv[0] or bin_path('archivebox')
|
|
|
|
@cached_property
|
|
def bin_version(self):
|
|
# return config['VERSION']
|
|
return VERSION
|
|
|