Merge pull request #255033 from AleXoundOS/castopod
castopod: init at 1.6.4
This commit is contained in:
commit
299e0b9560
10 changed files with 550 additions and 0 deletions
|
@ -759,6 +759,12 @@
|
|||
github = "Alexnortung";
|
||||
githubId = 1552267;
|
||||
};
|
||||
alexoundos = {
|
||||
email = "alexoundos@gmail.com";
|
||||
github = "AleXoundOS";
|
||||
githubId = 464913;
|
||||
name = "Alexander Tomokhov";
|
||||
};
|
||||
alexshpilkin = {
|
||||
email = "ashpilkin@gmail.com";
|
||||
github = "alexshpilkin";
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
- [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable).
|
||||
|
||||
- [Castopod](https://castopod.org/), an open-source hosting platform made for podcasters who want to engage and interact with their audience. Available as [services.castopod](#opt-services.castopod.enable).
|
||||
|
||||
- [Typesense](https://github.com/typesense/typesense), a fast, typo-tolerant search engine for building delightful search experiences. Available as [services.typesense](#opt-services.typesense.enable).
|
||||
|
||||
* [NS-USBLoader](https://github.com/developersu/ns-usbloader/), an all-in-one tool for managing Nintendo Switch homebrew. Available as [programs.ns-usbloader](#opt-programs.ns-usbloader.enable).
|
||||
|
|
|
@ -324,6 +324,7 @@
|
|||
./services/amqp/rabbitmq.nix
|
||||
./services/audio/alsa.nix
|
||||
./services/audio/botamusique.nix
|
||||
./services/audio/castopod.nix
|
||||
./services/audio/gmediarender.nix
|
||||
./services/audio/gonic.nix
|
||||
./services/audio/goxlr-utility.nix
|
||||
|
|
22
nixos/modules/services/audio/castopod.md
Normal file
22
nixos/modules/services/audio/castopod.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Castopod {#module-services-castopod}
|
||||
|
||||
Castopod is an open-source hosting platform made for podcasters who want to engage and interact with their audience.
|
||||
|
||||
## Quickstart {#module-services-castopod-quickstart}
|
||||
|
||||
Use the following configuration to start a public instance of Castopod on `castopod.example.com` domain:
|
||||
|
||||
```nix
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
services.castopod = {
|
||||
enable = true;
|
||||
database.createLocally = true;
|
||||
nginx.virtualHost = {
|
||||
serverName = "castopod.example.com";
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Go to `https://castopod.example.com/cp-install` to create superadmin account after applying the above configuration.
|
287
nixos/modules/services/audio/castopod.nix
Normal file
287
nixos/modules/services/audio/castopod.nix
Normal file
|
@ -0,0 +1,287 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.castopod;
|
||||
fpm = config.services.phpfpm.pools.castopod;
|
||||
|
||||
user = "castopod";
|
||||
stateDirectory = "/var/lib/castopod";
|
||||
|
||||
# https://docs.castopod.org/getting-started/install.html#requirements
|
||||
phpPackage = pkgs.php.withExtensions ({ enabled, all }: with all; [
|
||||
intl
|
||||
curl
|
||||
mbstring
|
||||
gd
|
||||
exif
|
||||
mysqlnd
|
||||
] ++ enabled);
|
||||
in
|
||||
{
|
||||
meta.doc = ./castopod.md;
|
||||
meta.maintainers = with lib.maintainers; [ alexoundos misuzu ];
|
||||
|
||||
options.services = {
|
||||
castopod = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Castopod");
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.castopod;
|
||||
defaultText = lib.literalMD "pkgs.castopod";
|
||||
description = lib.mdDoc "Which Castopod package to use.";
|
||||
};
|
||||
database = {
|
||||
createLocally = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Create the database and database user locally.
|
||||
'';
|
||||
};
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = lib.mdDoc "Database hostname.";
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "castopod";
|
||||
description = lib.mdDoc "Database name.";
|
||||
};
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = user;
|
||||
description = lib.mdDoc "Database user.";
|
||||
};
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = "/run/keys/castopod-dbpassword";
|
||||
description = lib.mdDoc ''
|
||||
A file containing the password corresponding to
|
||||
[](#opt-services.castopod.database.user).
|
||||
'';
|
||||
};
|
||||
};
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ str int bool ]);
|
||||
default = { };
|
||||
example = {
|
||||
"email.protocol" = "smtp";
|
||||
"email.SMTPHost" = "localhost";
|
||||
"email.SMTPUser" = "myuser";
|
||||
"email.fromEmail" = "castopod@example.com";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Environment variables used for Castopod.
|
||||
See [](https://code.castopod.org/adaures/castopod/-/blob/main/.env.example)
|
||||
for available environment variables.
|
||||
'';
|
||||
};
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = "/run/keys/castopod-env";
|
||||
description = lib.mdDoc ''
|
||||
Environment file to inject e.g. secrets into the configuration.
|
||||
See [](https://code.castopod.org/adaures/castopod/-/blob/main/.env.example)
|
||||
for available environment variables.
|
||||
'';
|
||||
};
|
||||
configureNginx = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc "Configure nginx as a reverse proxy for CastoPod.";
|
||||
};
|
||||
localDomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "castopod.example.org";
|
||||
description = lib.mdDoc "The domain serving your CastoPod instance.";
|
||||
};
|
||||
poolSettings = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ str int bool ]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = "32";
|
||||
"pm.start_servers" = "2";
|
||||
"pm.min_spare_servers" = "2";
|
||||
"pm.max_spare_servers" = "4";
|
||||
"pm.max_requests" = "500";
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Options for Castopod's PHP pool. See the documentation on `php-fpm.conf` for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.castopod.settings =
|
||||
let
|
||||
sslEnabled = with config.services.nginx.virtualHosts.${cfg.localDomain}; addSSL || forceSSL || onlySSL || enableACME || useACMEHost != null;
|
||||
baseURL = "http${lib.optionalString sslEnabled "s"}://${cfg.localDomain}";
|
||||
in
|
||||
lib.mapAttrs (name: lib.mkDefault) {
|
||||
"app.forceGlobalSecureRequests" = sslEnabled;
|
||||
"app.baseURL" = baseURL;
|
||||
|
||||
"media.baseURL" = "/";
|
||||
"media.root" = "media";
|
||||
"media.storage" = stateDirectory;
|
||||
|
||||
"admin.gateway" = "admin";
|
||||
"auth.gateway" = "auth";
|
||||
|
||||
"database.default.hostname" = cfg.database.hostname;
|
||||
"database.default.database" = cfg.database.name;
|
||||
"database.default.username" = cfg.database.user;
|
||||
"database.default.DBPrefix" = "cp_";
|
||||
|
||||
"cache.handler" = "file";
|
||||
};
|
||||
|
||||
services.phpfpm.pools.castopod = {
|
||||
inherit user;
|
||||
group = config.services.nginx.group;
|
||||
phpPackage = phpPackage;
|
||||
phpOptions = ''
|
||||
# https://code.castopod.org/adaures/castopod/-/blob/main/docker/production/app/uploads.ini
|
||||
file_uploads = On
|
||||
memory_limit = 512M
|
||||
upload_max_filesize = 500M
|
||||
post_max_size = 512M
|
||||
max_execution_time = 300
|
||||
max_input_time = 300
|
||||
'';
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"listen.group" = config.services.nginx.group;
|
||||
} // cfg.poolSettings;
|
||||
};
|
||||
|
||||
systemd.services.castopod-setup = {
|
||||
after = lib.optional config.services.mysql.enable "mysql.service";
|
||||
requires = lib.optional config.services.mysql.enable "mysql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.openssl phpPackage ];
|
||||
script =
|
||||
let
|
||||
envFile = "${stateDirectory}/.env";
|
||||
media = "${cfg.settings."media.storage"}/${cfg.settings."media.root"}";
|
||||
in
|
||||
''
|
||||
mkdir -p ${stateDirectory}/writable/{cache,logs,session,temp,uploads}
|
||||
|
||||
if [ ! -d ${lib.escapeShellArg media} ]; then
|
||||
cp --no-preserve=mode,ownership -r ${cfg.package}/share/castopod/public/media ${lib.escapeShellArg media}
|
||||
fi
|
||||
|
||||
if [ ! -f ${stateDirectory}/salt ]; then
|
||||
openssl rand -base64 33 > ${stateDirectory}/salt
|
||||
fi
|
||||
|
||||
cat <<'EOF' > ${envFile}
|
||||
${lib.generators.toKeyValue { } cfg.settings}
|
||||
EOF
|
||||
|
||||
echo "analytics.salt=$(cat ${stateDirectory}/salt)" >> ${envFile}
|
||||
|
||||
${if (cfg.database.passwordFile != null) then ''
|
||||
echo "database.default.password=$(cat ${lib.escapeShellArg cfg.database.passwordFile})" >> ${envFile}
|
||||
'' else ''
|
||||
echo "database.default.password=" >> ${envFile}
|
||||
''}
|
||||
|
||||
${lib.optionalString (cfg.environmentFile != null) ''
|
||||
cat ${lib.escapeShellArg cfg.environmentFile}) >> ${envFile}
|
||||
''}
|
||||
|
||||
php spark castopod:database-update
|
||||
'';
|
||||
serviceConfig = {
|
||||
StateDirectory = "castopod";
|
||||
WorkingDirectory = "${cfg.package}/share/castopod";
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = user;
|
||||
Group = config.services.nginx.group;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.castopod-scheduled = {
|
||||
after = [ "castopod-setup.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ phpPackage ];
|
||||
script = ''
|
||||
php public/index.php scheduled-activities
|
||||
php public/index.php scheduled-websub-publish
|
||||
php public/index.php scheduled-video-clips
|
||||
'';
|
||||
serviceConfig = {
|
||||
StateDirectory = "castopod";
|
||||
WorkingDirectory = "${cfg.package}/share/castopod";
|
||||
Type = "oneshot";
|
||||
User = user;
|
||||
Group = config.services.nginx.group;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers.castopod-scheduled = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* *:*:00";
|
||||
Unit = "castopod-scheduled.service";
|
||||
};
|
||||
};
|
||||
|
||||
services.mysql = lib.mkIf cfg.database.createLocally {
|
||||
enable = true;
|
||||
package = lib.mkDefault pkgs.mariadb;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [{
|
||||
name = cfg.database.user;
|
||||
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
}];
|
||||
};
|
||||
|
||||
services.nginx = lib.mkIf cfg.configureNginx {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.localDomain}" = {
|
||||
root = lib.mkForce "${cfg.package}/share/castopod/public";
|
||||
|
||||
extraConfig = ''
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
index index.php index.html;
|
||||
'';
|
||||
|
||||
locations."^~ /${cfg.settings."media.root"}/" = {
|
||||
root = cfg.settings."media.storage";
|
||||
extraConfig = ''
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
expires max;
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."~ \.php$" = {
|
||||
fastcgiParams = {
|
||||
SERVER_NAME = "$host";
|
||||
};
|
||||
extraConfig = ''
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass unix:${fpm.socket};
|
||||
try_files $uri =404;
|
||||
fastcgi_read_timeout 3600;
|
||||
fastcgi_send_timeout 3600;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${user} = lib.mapAttrs (name: lib.mkDefault) {
|
||||
description = "Castopod user";
|
||||
isSystemUser = true;
|
||||
group = config.services.nginx.group;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -158,6 +158,7 @@ in {
|
|||
cagebreak = handleTest ./cagebreak.nix {};
|
||||
calibre-web = handleTest ./calibre-web.nix {};
|
||||
calibre-server = handleTest ./calibre-server.nix {};
|
||||
castopod = handleTest ./castopod.nix {};
|
||||
cassandra_3_0 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_0; };
|
||||
cassandra_3_11 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_11; };
|
||||
cassandra_4 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_4; };
|
||||
|
|
87
nixos/tests/castopod.nix
Normal file
87
nixos/tests/castopod.nix
Normal file
|
@ -0,0 +1,87 @@
|
|||
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||
{
|
||||
name = "castopod";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ alexoundos misuzu ];
|
||||
};
|
||||
nodes.castopod = { nodes, ... }: {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
networking.extraHosts = ''
|
||||
127.0.0.1 castopod.example.com
|
||||
'';
|
||||
services.castopod = {
|
||||
enable = true;
|
||||
database.createLocally = true;
|
||||
localDomain = "castopod.example.com";
|
||||
};
|
||||
environment.systemPackages =
|
||||
let
|
||||
username = "admin";
|
||||
email = "admin@castood.example.com";
|
||||
password = "v82HmEp5";
|
||||
testRunner = pkgs.writers.writePython3Bin "test-runner"
|
||||
{
|
||||
libraries = [ pkgs.python3Packages.selenium ];
|
||||
flakeIgnore = [
|
||||
"E501"
|
||||
];
|
||||
} ''
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver import Firefox
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
options = Options()
|
||||
options.add_argument('--headless')
|
||||
driver = Firefox(options=options)
|
||||
try:
|
||||
driver.implicitly_wait(20)
|
||||
driver.get('http://castopod.example.com/cp-install')
|
||||
|
||||
wait = WebDriverWait(driver, 10)
|
||||
|
||||
wait.until(EC.title_contains("installer"))
|
||||
|
||||
driver.find_element(By.CSS_SELECTOR, '#username').send_keys(
|
||||
'${username}'
|
||||
)
|
||||
driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
|
||||
'${email}'
|
||||
)
|
||||
driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
|
||||
'${password}'
|
||||
)
|
||||
driver.find_element(By.XPATH, "//button[contains(., 'Finish install')]").click()
|
||||
|
||||
wait.until(EC.title_contains("Auth"))
|
||||
|
||||
driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
|
||||
'${email}'
|
||||
)
|
||||
driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
|
||||
'${password}'
|
||||
)
|
||||
driver.find_element(By.XPATH, "//button[contains(., 'Login')]").click()
|
||||
|
||||
wait.until(EC.title_contains("Admin dashboard"))
|
||||
finally:
|
||||
driver.close()
|
||||
driver.quit()
|
||||
'';
|
||||
in
|
||||
[ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ];
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
castopod.wait_for_unit("castopod-setup.service")
|
||||
castopod.wait_for_file("/run/phpfpm/castopod.sock")
|
||||
castopod.wait_for_unit("nginx.service")
|
||||
castopod.wait_for_open_port(80)
|
||||
castopod.wait_until_succeeds("curl -sS -f http://castopod.example.com")
|
||||
castopod.succeed("curl -s http://localhost/cp-install | grep 'Create your Super Admin account' > /dev/null")
|
||||
|
||||
with subtest("Create superadmin and log in"):
|
||||
castopod.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner")
|
||||
'';
|
||||
})
|
53
pkgs/applications/audio/castopod/default.nix
Normal file
53
pkgs/applications/audio/castopod/default.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ stdenv
|
||||
, fetchurl
|
||||
, ffmpeg-headless
|
||||
, lib
|
||||
, nixosTests
|
||||
, stateDirectory ? "/var/lib/castopod"
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "castopod";
|
||||
version = "1.6.4";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://code.castopod.org/adaures/castopod/uploads/ce56d4f149242f12bedd20f9a2b0916d/castopod-1.6.4.tar.gz";
|
||||
sha256 = "080jj91yxbn3xsbs0sywzwa2f5in9bp9qi2zwqcfqpaxlq9ga62v";
|
||||
};
|
||||
|
||||
dontBuild = true;
|
||||
dontFixup = true;
|
||||
|
||||
postPatch = ''
|
||||
# not configurable at runtime unfortunately:
|
||||
substituteInPlace app/Config/Paths.php \
|
||||
--replace "__DIR__ . '/../../writable'" "'${stateDirectory}/writable'"
|
||||
|
||||
# configuration file must be writable, place it to ${stateDirectory}
|
||||
substituteInPlace modules/Install/Controllers/InstallController.php \
|
||||
--replace "ROOTPATH" "'${stateDirectory}/'"
|
||||
substituteInPlace public/index.php spark \
|
||||
--replace "DotEnv(ROOTPATH)" "DotEnv('${stateDirectory}')"
|
||||
|
||||
# ffmpeg is required for Video Clips feature
|
||||
substituteInPlace modules/MediaClipper/VideoClipper.php \
|
||||
--replace "ffmpeg" "${ffmpeg-headless}/bin/ffmpeg"
|
||||
substituteInPlace modules/Admin/Controllers/VideoClipsController.php \
|
||||
--replace "which ffmpeg" "echo ${ffmpeg-headless}/bin/ffmpeg"
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/castopod
|
||||
cp -r . $out/share/castopod
|
||||
'';
|
||||
|
||||
passthru.tests.castopod = nixosTests.castopod;
|
||||
passthru.updateScript = ./update.sh;
|
||||
|
||||
meta = with lib; {
|
||||
description = "An open-source hosting platform made for podcasters who want to engage and interact with their audience";
|
||||
homepage = "https://castopod.org";
|
||||
license = licenses.agpl3Only;
|
||||
maintainers = with maintainers; [ alexoundos misuzu ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
89
pkgs/applications/audio/castopod/update.sh
Executable file
89
pkgs/applications/audio/castopod/update.sh
Executable file
|
@ -0,0 +1,89 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p curl jq
|
||||
set -euo pipefail
|
||||
|
||||
nixpkgs="$(git rev-parse --show-toplevel)"
|
||||
castopod_nix="$nixpkgs/pkgs/applications/audio/castopod/default.nix"
|
||||
|
||||
# https://www.meetup.com/api/guide/#p02-querying-section
|
||||
query='
|
||||
query allReleases($fullPath: ID!, $first: Int, $last: Int, $before: String, $after: String, $sort: ReleaseSort) {
|
||||
project(fullPath: $fullPath) {
|
||||
id
|
||||
releases(
|
||||
first: $first
|
||||
last: $last
|
||||
before: $before
|
||||
after: $after
|
||||
sort: $sort
|
||||
) {
|
||||
nodes {
|
||||
...Release
|
||||
__typename
|
||||
}
|
||||
__typename
|
||||
}
|
||||
__typename
|
||||
}
|
||||
}
|
||||
|
||||
fragment Release on Release {
|
||||
id
|
||||
name
|
||||
tagName
|
||||
releasedAt
|
||||
createdAt
|
||||
upcomingRelease
|
||||
historicalRelease
|
||||
assets {
|
||||
links {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
url
|
||||
directAssetUrl
|
||||
linkType
|
||||
__typename
|
||||
}
|
||||
__typename
|
||||
}
|
||||
__typename
|
||||
}
|
||||
__typename
|
||||
}
|
||||
'
|
||||
variables='{
|
||||
"fullPath": "adaures/castopod",
|
||||
"first": 1,
|
||||
"sort": "RELEASED_AT_DESC"
|
||||
}'
|
||||
|
||||
post=$(cat <<EOF
|
||||
{"query": "$(echo $query)", "variables": $(echo $variables)}
|
||||
EOF
|
||||
)
|
||||
|
||||
json="$(curl -s -X POST https://code.castopod.org/api/graphql \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "$post")"
|
||||
|
||||
echo "$json"
|
||||
TAG=$(echo $json | jq -r '.data.project.releases.nodes[].tagName')
|
||||
ASSET_URL=$(echo $json | jq -r '.data.project.releases.nodes[].assets.links.nodes[].url' | grep .tar.gz$)
|
||||
|
||||
CURRENT_VERSION=$(nix eval -f "$nixpkgs" --raw castopod.version)
|
||||
VERSION=${TAG:1}
|
||||
|
||||
if [[ "$CURRENT_VERSION" == "$VERSION" ]]; then
|
||||
echo "castopod is up-to-date: ${CURRENT_VERSION}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SHA256=$(nix-prefetch-url "$ASSET_URL")
|
||||
|
||||
URL=$(echo $ASSET_URL | sed -e 's/[\/&]/\\&/g')
|
||||
|
||||
sed -e "s/version =.*;/version = \"$VERSION\";/g" \
|
||||
-e "s/url =.*;/url = \"$URL\";/g" \
|
||||
-e "s/sha256 =.*;/sha256 = \"$SHA256\";/g" \
|
||||
-i "$castopod_nix"
|
|
@ -3583,6 +3583,8 @@ with pkgs;
|
|||
|
||||
callaudiod = callPackage ../applications/audio/callaudiod { };
|
||||
|
||||
castopod = callPackage ../applications/audio/castopod { };
|
||||
|
||||
calls = callPackage ../applications/networking/calls { };
|
||||
|
||||
castnow = callPackage ../tools/networking/castnow { };
|
||||
|
|
Loading…
Reference in a new issue