mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
Merge branch 'master' into old-engine
This commit is contained in:
12
.github/workflows/github-actions-docker.yml
vendored
12
.github/workflows/github-actions-docker.yml
vendored
@@ -13,16 +13,16 @@ jobs:
|
||||
run : echo ${{ github.event.release.tag_name }}
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3.3.0
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2.2.1
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -39,10 +39,10 @@ jobs:
|
||||
echo ${{ env.REG_REPO }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v3.3.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ env.REG_REPO }}:${{ github.event.release.tag_name }}
|
||||
|
||||
@@ -6,8 +6,9 @@ WORKDIR /app
|
||||
RUN yarn install && yarn run build
|
||||
### FRONT BUILD END ###
|
||||
|
||||
|
||||
### BUILD TORRSERVER MULTIARCH START ###
|
||||
FROM --platform=$BUILDPLATFORM golang:1.18-alpine as builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.19-alpine as builder
|
||||
|
||||
COPY . /opt/src
|
||||
COPY --from=front /app/build /opt/src/web/build
|
||||
@@ -42,6 +43,7 @@ RUN apt-get update && apt-get install -y upx-ucl && upx --best --lzma ./torrserv
|
||||
# && if [[ "$compress" -eq 1 ]]; then ./upx --best --lzma ./torrserver; fi
|
||||
### UPX COMPRESSING END ###
|
||||
|
||||
|
||||
### BUILD MAIN IMAGE START ###
|
||||
FROM alpine
|
||||
|
||||
|
||||
@@ -5,9 +5,15 @@ TorrServer, stream torrent to http
|
||||
Just download server from releases and exec file\
|
||||
https://github.com/YouROK/TorrServer/releases \
|
||||
After open browser link http://127.0.0.1:8090 \
|
||||
On linux systems you need to set the environment variable before run \
|
||||
On linux systems you may need to set the environment variable before run \
|
||||
***export GODEBUG=madvdontneed=1***
|
||||
|
||||
#### macOS install / configure / uninstall script
|
||||
Just run in Terminal: `curl -s https://raw.githubusercontent.com/YouROK/TorrServer/master/installTorrServerMac.sh | sudo bash`
|
||||
|
||||
#### Linux on VPS install / configure / uninstall script
|
||||
Just run in console: `curl -s https://raw.githubusercontent.com/YouROK/TorrServer/master/installTorrServerLinux.sh | sudo bash`
|
||||
|
||||
#### Unofficial TorrServer iocage plugin
|
||||
On FreeBSD (TrueNAS/FreeNAS) you can use this plugin
|
||||
|
||||
|
||||
520
installTorrServerLinux.sh
Normal file
520
installTorrServerLinux.sh
Normal file
@@ -0,0 +1,520 @@
|
||||
#!/usr/bin/env bash
|
||||
username="torrserver" # system user to add || root
|
||||
dirInstall="/opt/torrserver" # путь установки torrserver
|
||||
serviceName="torrserver" # имя службы: systemctl status torrserver.service
|
||||
scriptname=$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")
|
||||
|
||||
#################################
|
||||
# F U N C T I O N S #
|
||||
#################################
|
||||
|
||||
function isRoot() {
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function addUser() {
|
||||
if isRoot; then
|
||||
[[ $username == "root" ]] && return 0
|
||||
egrep "^$username" /etc/passwd >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
[[ $lang == "en" ]] && echo " - $username user exists!" || echo " - пользователь $username найден!"
|
||||
return 0
|
||||
else
|
||||
useradd --home-dir "$dirInstall" --create-home --shell /bin/false -c "TorrServer" "$username"
|
||||
[ $? -eq 0 ] && {
|
||||
chmod 755 "$dirInstall"
|
||||
[[ $lang == "en" ]] && echo " - User $username has been added to system!" || echo " - пользователь $username добавлен!"
|
||||
} || {
|
||||
[[ $lang == "en" ]] && echo " - Failed to add $username user!" || echo " - не удалось добавить пользователя $username!"
|
||||
}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function delUser() {
|
||||
if isRoot; then
|
||||
[[ $username == "root" ]] && return 0
|
||||
egrep "^$username" /etc/passwd >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
userdel --remove "$username" 2>/dev/null # --force
|
||||
[ $? -eq 0 ] && {
|
||||
[[ $lang == "en" ]] && echo " - User $username has been removed from system!" || echo " - Пользователь $username удален!"
|
||||
} || {
|
||||
[[ $lang == "en" ]] && echo " - Failed to remove $username user!" || echo " - не удалось удалить пользователя $username!"
|
||||
}
|
||||
else
|
||||
[[ $lang == "en" ]] && echo " - $username - no such user!" || echo " - пользователь $username не найден!"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function checkRunning() {
|
||||
runningPid=$(ps -ax|grep -i torrserver|grep -v grep|grep -v "$scriptname"|awk '{print $1}')
|
||||
echo $runningPid
|
||||
}
|
||||
|
||||
function getLang() {
|
||||
lang=$(locale | grep LANG | cut -d= -f2 | tr -d '"' | cut -d_ -f1)
|
||||
[[ $lang != "ru" ]] && lang="en"
|
||||
}
|
||||
|
||||
function getIP() {
|
||||
[ -z "`which dig`" ] && serverIP=$(host myip.opendns.com resolver1.opendns.com | tail -n1 | cut -d' ' -f4-) || serverIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
|
||||
# echo $serverIP
|
||||
}
|
||||
|
||||
function uninstall() {
|
||||
checkArch
|
||||
checkInstalled
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " TorrServer install dir - ${dirInstall}"
|
||||
echo ""
|
||||
echo " This action will delete TorrServer including all it's torrents, settings and files on path above!"
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " Директория c TorrServer - ${dirInstall}"
|
||||
echo ""
|
||||
echo " Это действие удалит все данные TorrServer включая базу данных торрентов и настройки по указанному выше пути!"
|
||||
echo ""
|
||||
}
|
||||
[[ $lang == "en" ]] && read -p ' Are you shure you want to delete TorrServer? (Yes/No) ' answer_del </dev/tty || read -p ' Вы уверены что хотите удалить программу? (Да/Нет) ' answer_del </dev/tty
|
||||
if [ "$answer_del" != "${answer_del#[YyДд]}" ]; then
|
||||
cleanup
|
||||
cleanAll
|
||||
[[ $lang == "en" ]] && echo " - TorrServer uninstalled!" || echo " - TorrServer удален из системы!"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
systemctl stop $serviceName 2>/dev/null
|
||||
systemctl disable $serviceName 2>/dev/null
|
||||
rm -rf /usr/local/lib/systemd/system/$serviceName.service $dirInstall 2>/dev/null
|
||||
delUser
|
||||
}
|
||||
|
||||
function cleanAll() { # guess other installs
|
||||
systemctl stop torr torrserver 2>/dev/null
|
||||
systemctl disable torr torrserver 2>/dev/null
|
||||
rm -rf /home/torrserver 2>/dev/null
|
||||
rm -rf /usr/local/torr 2>/dev/null
|
||||
rm -rf /opt/torr{,*} 2>/dev/null
|
||||
rm -f /{,etc,usr/local/lib}/systemd/system/tor{,r,rserver}.service 2>/dev/null
|
||||
}
|
||||
|
||||
function helpUsage() {
|
||||
[[ $lang == "en" ]] && echo -e "$scriptname
|
||||
-i | --install | install - install latest release version
|
||||
-u | --update | update - install latest update (if any)
|
||||
-c | --check | check - check update (show only version info)
|
||||
-d | --down | down - version downgrade, need version number as argument
|
||||
-r | --remove | remove - uninstall TorrServer
|
||||
-h | --help | help - this help screen
|
||||
" || echo -e "$scriptname
|
||||
-i | --install | install - установка последней версии
|
||||
-u | --update | update - установка последнего обновления, если имеется
|
||||
-c | --check | check - проверка обновления (выводит только информацию о версиях)
|
||||
-d | --down | down - понизить версию, после опции указывается версия для понижения
|
||||
-r | --remove | remove - удаление TorrServer
|
||||
-h | --help | help - эта справка
|
||||
"
|
||||
}
|
||||
|
||||
function checkOS() {
|
||||
if [[ -e /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
source /etc/os-release
|
||||
|
||||
if [[ $ID == "debian" || $ID == "raspbian" ]]; then
|
||||
if [[ $VERSION_ID -lt 6 ]]; then
|
||||
echo "⚠️ Ваша версия Debian не поддерживается."
|
||||
echo ""
|
||||
echo " Скрипт поддерживает только Debian >=6"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
elif [[ $ID == "ubuntu" ]]; then
|
||||
OS="ubuntu"
|
||||
MAJOR_UBUNTU_VERSION=$(echo "$VERSION_ID" | cut -d '.' -f1)
|
||||
if [[ $MAJOR_UBUNTU_VERSION -lt 10 ]]; then
|
||||
echo "⚠️ Ваша версия Ubuntu не поддерживается."
|
||||
echo ""
|
||||
echo " Скрипт поддерживает только Ubuntu >=10"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
elif [[ -e /etc/system-release ]]; then
|
||||
source /etc/os-release
|
||||
if [[ $ID == "fedora" || $ID_LIKE == "fedora" ]]; then
|
||||
OS="fedora"
|
||||
# [ -z "$(rpm -qa wget)" ] && yum -y install wget
|
||||
fi
|
||||
if [[ $ID == "centos" || $ID == "rocky" || $ID == "redhat" ]]; then
|
||||
OS="centos"
|
||||
if [[ ! $VERSION_ID =~ (6|7|8) ]]; then
|
||||
echo "⚠️ Ваша версия CentOS/RockyLinux/RedHat не поддерживается."
|
||||
echo ""
|
||||
echo " Скрипт поддерживает только CentOS/RockyLinux/RedHat версии 6,7 и 8."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
# [ -z "$(rpm -qa wget)" ] && yum -y install wget
|
||||
fi
|
||||
if [[ $ID == "ol" ]]; then
|
||||
OS="oracle"
|
||||
if [[ ! $VERSION_ID =~ (6|7|8) ]]; then
|
||||
echo "⚠️ Ваша версия Oracle Linux не поддерживается."
|
||||
echo ""
|
||||
echo " Скрипт поддерживает только Oracle Linux версии 6,7 и 8."
|
||||
exit 1
|
||||
fi
|
||||
# [ -z "$(rpm -qa wget)" ] && yum -y install wget
|
||||
fi
|
||||
if [[ $ID == "amzn" ]]; then
|
||||
OS="amzn"
|
||||
if [[ $VERSION_ID != "2" ]]; then
|
||||
echo "⚠️ Ваша версия Amazon Linux не поддерживается."
|
||||
echo ""
|
||||
echo " Скрипт поддерживает только Amazon Linux 2."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
# [ -z "$(rpm -qa wget)" ] && yum -y install wget
|
||||
fi
|
||||
elif [[ -e /etc/arch-release ]]; then
|
||||
OS=arch
|
||||
# [ -z $(pacman -Qqe wget 2>/dev/null) ] && pacman -Sy --noconfirm wget
|
||||
else
|
||||
echo " Похоже, что вы запускаете этот установщик в системе отличной от Debian, Ubuntu, Fedora, CentOS, Amazon Linux, Oracle Linux или Arch Linux."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function checkArch() {
|
||||
case $(uname -m) in
|
||||
i386) architecture="386" ;;
|
||||
i686) architecture="386" ;;
|
||||
x86_64) architecture="amd64" ;;
|
||||
aarch64) architecture="arm64" ;;
|
||||
armv7|armv7l) architecture="arm7" ;;
|
||||
armv6|armv6l) architecture="arm5" ;;
|
||||
*) [[ $lang == "en" ]] && { echo " Unsupported Arch. Can't continue."; exit 1; } || { echo " Не поддерживаемая архитектура. Продолжение невозможно."; exit 1; } ;;
|
||||
esac
|
||||
}
|
||||
|
||||
function checkInternet() {
|
||||
[ -z "`which ping`" ] && echo " Сначала установите iputils-ping" && exit 1
|
||||
[[ $lang == "en" ]] && echo " Check Internet access…" || echo " Проверяем соединение с Интернетом…"
|
||||
if ! ping -c 2 google.com &> /dev/null; then
|
||||
[[ $lang == "en" ]] && echo " - No Internet. Check your network and DNS settings." || echo " - Нет Интернета. Проверьте ваше соединение, а также разрешение имен DNS."
|
||||
exit 1
|
||||
fi
|
||||
[[ $lang == "en" ]] && echo " - Have Internet Access" || echo " - соединение с Интернетом успешно"
|
||||
}
|
||||
|
||||
function initialCheck() {
|
||||
if ! isRoot; then
|
||||
[[ $lang == "en" ]] && echo " Script must run as root or user with sudo privileges. Example: sudo $scriptname" || echo " Вам нужно запустить скрипт от root или пользователя с правами sudo. Пример: sudo $scriptname"
|
||||
exit 1
|
||||
fi
|
||||
[ -z "`which curl`" ] && echo " Сначала установите curl" && exit 1
|
||||
checkOS
|
||||
checkArch
|
||||
checkInternet
|
||||
}
|
||||
|
||||
function getLatestRelease() {
|
||||
curl -s "https://api.github.com/repos/YouROK/TorrServer/releases" |
|
||||
grep -iE '"tag_name":|"version":' |
|
||||
sed -E 's/.*"([^"]+)".*/\1/' |
|
||||
head -1
|
||||
}
|
||||
|
||||
function installTorrServer() {
|
||||
[[ $lang == "en" ]] && echo " Install and configure TorrServer…" || echo " Устанавливаем и настраиваем TorrServer…"
|
||||
if checkInstalled; then
|
||||
if ! checkInstalledVersion; then
|
||||
[[ $lang == "en" ]] && read -p ' Want to update TorrServer? (Yes/No) ' answer_up </dev/tty || read -p ' Хотите обновить TorrServer? (Да/Нет) ' answer_up </dev/tty
|
||||
if [ "$answer_up" != "${answer_up#[YyДд]}" ]; then
|
||||
UpdateVersion
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
binName="TorrServer-linux-${architecture}"
|
||||
[[ ! -d "$dirInstall" ]] && mkdir -p ${dirInstall}
|
||||
[[ ! -d "/usr/local/lib/systemd/system" ]] && mkdir -p "/usr/local/lib/systemd/system"
|
||||
urlBin="https://github.com/YouROK/TorrServer/releases/download/$(getLatestRelease)/${binName}"
|
||||
if [[ ! -f "$dirInstall/$binName" ]] | [[ ! -x "$dirInstall/$binName" ]] || [[ $(stat -c%s "$dirInstall/$binName" 2>/dev/null) -eq 0 ]]; then
|
||||
curl -L --progress-bar -# -o "$dirInstall/$binName" "$urlBin"
|
||||
chmod +x "$dirInstall/$binName"
|
||||
fi
|
||||
cat << EOF > $dirInstall/$serviceName.service
|
||||
[Unit]
|
||||
Description = TorrServer - stream torrent to http
|
||||
Wants = network-online.target
|
||||
After = network.target
|
||||
|
||||
[Service]
|
||||
User = $username
|
||||
Group = $username
|
||||
Type = simple
|
||||
NonBlocking = true
|
||||
EnvironmentFile = $dirInstall/$serviceName.config
|
||||
ExecStart = ${dirInstall}/${binName} \$DAEMON_OPTIONS
|
||||
ExecReload = /bin/kill -HUP \${MAINPID}
|
||||
ExecStop = /bin/kill -INT \${MAINPID}
|
||||
TimeoutSec = 30
|
||||
#WorkingDirectory = ${dirInstall}
|
||||
Restart = on-failure
|
||||
RestartSec = 5s
|
||||
#LimitNOFILE = 4096
|
||||
|
||||
[Install]
|
||||
WantedBy = multi-user.target
|
||||
EOF
|
||||
[ -z $servicePort ] && {
|
||||
[[ $lang == "en" ]] && read -p ' Change TorrServer web-port? (Yes/No) ' answer_cp </dev/tty || read -p ' Хотите изменить порт для TorrServer? (Да/Нет) ' answer_cp </dev/tty
|
||||
if [ "$answer_cp" != "${answer_cp#[YyДд]}" ]; then
|
||||
[[ $lang == "en" ]] && read -p ' Enter port number: ' answer_port </dev/tty || read -p ' Введите номер порта: ' answer_port </dev/tty
|
||||
servicePort=$answer_port
|
||||
else
|
||||
servicePort="8090"
|
||||
fi
|
||||
}
|
||||
[ -z $isAuth ] && {
|
||||
[[ $lang == "en" ]] && read -p ' Enable server authorization? (Yes/No) ' answer_auth </dev/tty || read -p ' Включить авторизацию на сервере? (Да/Нет) ' answer_auth </dev/tty
|
||||
if [ "$answer_auth" != "${answer_auth#[YyДд]}" ]; then
|
||||
isAuth=1
|
||||
else
|
||||
isAuth=0
|
||||
fi
|
||||
}
|
||||
if [[ "$isAuth" == 1 ]]; then
|
||||
[[ ! -f "$dirInstall/accs.db" ]] && {
|
||||
[[ $lang == "en" ]] && read -p ' User: ' answer_user </dev/tty || read -p ' Пользователь: ' answer_user </dev/tty
|
||||
isAuthUser=$answer_user
|
||||
[[ $lang == "en" ]] && read -p ' Password: ' answer_pass </dev/tty || read -p ' Пароль: ' answer_pass </dev/tty
|
||||
isAuthPass=$answer_pass
|
||||
[[ $lang == "en" ]] && echo " Apply user and password - $isAuthUser:$isAuthPass" || echo " Устанавливаем логин и пароль - $isAuthUser:$isAuthPass"
|
||||
echo -e "{\n \"$isAuthUser\": \"$isAuthPass\"\n}" > $dirInstall/accs.db
|
||||
} || {
|
||||
[[ $lang == "en" ]] && echo " Use existing auth from ${dirInstall}/accs.db" || echo " Используйте реквизиты из ${dirInstall}/accs.db для входа"
|
||||
}
|
||||
cat << EOF > $dirInstall/$serviceName.config
|
||||
DAEMON_OPTIONS="--port $servicePort --path $dirInstall --httpauth"
|
||||
EOF
|
||||
else
|
||||
cat << EOF > $dirInstall/$serviceName.config
|
||||
DAEMON_OPTIONS="--port $servicePort --path $dirInstall"
|
||||
EOF
|
||||
fi
|
||||
[ -z $isRdb ] && {
|
||||
[[ $lang == "en" ]] && read -p ' Start TorrServer in public read-only mode? (Yes/No) ' answer_rdb </dev/tty || read -p ' Запускать TorrServer в публичном режиме без возможности изменения настроек через веб сервера? (Да/Нет) ' answer_rdb </dev/tty
|
||||
if [ "$answer_rdb" != "${answer_rdb#[YyДд]}" ]; then
|
||||
isRdb=1
|
||||
else
|
||||
isRdb=0
|
||||
fi
|
||||
}
|
||||
if [[ "$isRdb" == 1 ]]; then
|
||||
[[ $lang == "en" ]] && {
|
||||
echo " Set database to read-only mode…"
|
||||
echo " To change remove --rdb option from $dirInstall/$serviceName.config"
|
||||
echo " or rerun install script without parameters"
|
||||
} || {
|
||||
echo " База данных устанавливается в режим «только для чтения»…"
|
||||
echo " Для изменения отредактируйте $dirInstall/$serviceName.config, убрав опцию --rdb"
|
||||
echo " или запустите интерактивную установку без параметров повторно"
|
||||
}
|
||||
sed -i 's|DAEMON_OPTIONS="--port|DAEMON_OPTIONS="--rdb --port|' $dirInstall/$serviceName.config
|
||||
fi
|
||||
[ -z $isLog ] && {
|
||||
[[ $lang == "en" ]] && read -p ' Enable TorrServer log output to file? (Yes/No) ' answer_log </dev/tty || read -p ' Включить запись журнала работы TorrServer в файл? (Да/Нет) ' answer_log </dev/tty
|
||||
if [ "$answer_log" != "${answer_log#[YyДд]}" ]; then
|
||||
sed -i "s|--path|--logpath $dirInstall/$serviceName.log --path|" "$dirInstall/$serviceName.config"
|
||||
[[ $lang == "en" ]] && echo " - TorrServer log stored at $dirInstall/$serviceName.log" || echo " - лог TorrServer располагается по пути $dirInstall/$serviceName.log"
|
||||
fi
|
||||
}
|
||||
|
||||
ln -sf $dirInstall/$serviceName.service /usr/local/lib/systemd/system/
|
||||
sed -i 's/^[ \t]*//' $dirInstall/$serviceName.service
|
||||
sed -i 's/^[ \t]*//' $dirInstall/$serviceName.config
|
||||
|
||||
[[ $lang == "en" ]] && echo " Starting TorrServer…" || echo " Запускаем службу TorrServer…"
|
||||
systemctl daemon-reload 2>/dev/null
|
||||
systemctl enable $serviceName.service 2>/dev/null # enable --now
|
||||
systemctl restart $serviceName.service 2>/dev/null
|
||||
getIP
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " TorrServer $(getLatestRelease) installed to ${dirInstall}"
|
||||
echo ""
|
||||
echo " You can now open your browser at http://${serverIP}:${servicePort} to access TorrServer web GUI."
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " TorrServer $(getLatestRelease) установлен в директории ${dirInstall}"
|
||||
echo ""
|
||||
echo " Теперь вы можете открыть браузер по адресу http://${serverIP}:${servicePort} для доступа к вебу TorrServer"
|
||||
echo ""
|
||||
}
|
||||
if [[ "$isAuth" == 1 && $isAuthUser > 0 ]]; then
|
||||
[[ $lang == "en" ]] && echo " Use user \"$isAuthUser\" with password \"$isAuthPass\" for authentication" || echo " Для авторизации введите пользователя $isAuthUser с паролем $isAuthPass"
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
function checkInstalled() {
|
||||
if ! addUser; then
|
||||
username="root"
|
||||
fi
|
||||
binName="TorrServer-linux-${architecture}"
|
||||
if [[ -f "$dirInstall/$binName" ]] || [[ $(stat -c%s "$dirInstall/$binName" 2>/dev/null) -ne 0 ]]; then
|
||||
[[ $lang == "en" ]] && echo " - TorrServer found in $dirInstall" || echo " - TorrServer найден в директории $dirInstall"
|
||||
else
|
||||
[[ $lang == "en" ]] && echo " - TorrServer not found. It's not installed or have zero size." || echo " - TorrServer не найден, возможно он не установлен или размер бинарника равен 0."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function checkInstalledVersion() {
|
||||
binName="TorrServer-linux-${architecture}"
|
||||
if [[ -z "$(getLatestRelease)" ]]; then
|
||||
[[ $lang == "en" ]] && echo " - No update. Can be server issue." || echo " - Не найдено обновление. Возможно сервер не доступен."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$(getLatestRelease)" == "$($dirInstall/$binName --version 2>/dev/null | awk '{print $2}')" ]]; then
|
||||
[[ $lang == "en" ]] && echo " - You have latest TorrServer $(getLatestRelease)" || echo " - Установлен TorrServer последней версии $(getLatestRelease)"
|
||||
else
|
||||
[[ $lang == "en" ]] && {
|
||||
echo " - TorrServer update found!"
|
||||
echo " installed: \"$($dirInstall/$binName --version 2>/dev/null | awk '{print $2}')\""
|
||||
echo " available: \"$(getLatestRelease)\""
|
||||
} || {
|
||||
echo " - Доступно обновление сервера"
|
||||
echo " установлен: \"$($dirInstall/$binName --version 2>/dev/null | awk '{print $2}')\""
|
||||
echo " обновление: \"$(getLatestRelease)\""
|
||||
}
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function UpdateVersion() {
|
||||
systemctl stop $serviceName.service
|
||||
binName="TorrServer-linux-${architecture}"
|
||||
urlBin="https://github.com/YouROK/TorrServer/releases/download/$(getLatestRelease)/${binName}"
|
||||
curl -L --progress-bar -# -o "$dirInstall/$binName" "$urlBin"
|
||||
chmod +x "$dirInstall/$binName"
|
||||
systemctl start $serviceName.service
|
||||
}
|
||||
|
||||
function DowngradeVersion() {
|
||||
systemctl stop $serviceName.service
|
||||
binName="TorrServer-linux-${architecture}"
|
||||
urlBin="https://github.com/YouROK/TorrServer/releases/download/MatriX.$downgradeRelease/${binName}"
|
||||
curl -L --progress-bar -# -o "$dirInstall/$binName" "$urlBin"
|
||||
chmod +x "$dirInstall/$binName"
|
||||
systemctl start $serviceName.service
|
||||
}
|
||||
#####################################
|
||||
# E N D F U N C T I O N S #
|
||||
#####################################
|
||||
getLang
|
||||
case $1 in
|
||||
-i|--install|install)
|
||||
initialCheck
|
||||
if ! checkInstalled; then
|
||||
servicePort="8090"
|
||||
isAuth=0
|
||||
isRdb=0
|
||||
isLog=0
|
||||
installTorrServer
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
-u|--update|update)
|
||||
initialCheck
|
||||
if checkInstalled; then
|
||||
if ! checkInstalledVersion; then
|
||||
UpdateVersion
|
||||
fi
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
-c|--check|check)
|
||||
initialCheck
|
||||
if checkInstalled; then
|
||||
checkInstalledVersion
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
-d|--down|down)
|
||||
initialCheck
|
||||
downgradeRelease="$2"
|
||||
[ -z "$downgradeRelease" ] &&
|
||||
echo " Вы не указали номер версии" &&
|
||||
echo " Наберите $scriptname -d|-down|down <версия>, например $scriptname -d 101" &&
|
||||
exit 1
|
||||
if checkInstalled; then
|
||||
DowngradeVersion
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
-r|--remove|remove)
|
||||
uninstall
|
||||
exit
|
||||
;;
|
||||
-h|--help|help)
|
||||
helpUsage
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
echo " Choose Language:"
|
||||
echo " [1] English"
|
||||
echo " [2] Русский"
|
||||
read -p ' Your language (Ваш язык): ' answer_lang </dev/tty
|
||||
if [ "$answer_lang" != "${answer_lang#[2]}" ]; then
|
||||
lang="ru"
|
||||
fi
|
||||
echo ""
|
||||
echo "============================================================="
|
||||
[[ $lang == "en" ]] && echo " TorrServer install and configuration script for Linux " || echo " Скрипт установки, удаления и настройки TorrServer для Linux "
|
||||
echo "============================================================="
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && echo " Enter $scriptname -h or --help or help for all available commands" || echo " Наберите $scriptname -h или --help или help для вызова справки всех доступных команд"
|
||||
;;
|
||||
esac
|
||||
|
||||
while true; do
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && read -p " Want to install or configure TorrServer? (Yes|No) Type Delete to uninstall. " ydn </dev/tty || read -p " Хотите установить, обновить или настроить TorrServer? (Да|Нет) Для удаления введите «Удалить» " ydn </dev/tty
|
||||
case $ydn in
|
||||
[YyДд]*)
|
||||
initialCheck
|
||||
installTorrServer
|
||||
break
|
||||
;;
|
||||
[DdУу]*)
|
||||
uninstall
|
||||
break
|
||||
;;
|
||||
[NnНн]*)
|
||||
break
|
||||
;;
|
||||
*) [[ $lang == "en" ]] && echo " Enter Yes, No or Delete" || echo " Ввведите Да, Нет или Удалить"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo " Have Fun!"
|
||||
echo ""
|
||||
sleep 3
|
||||
234
installTorrServerMac.sh
Executable file
234
installTorrServerMac.sh
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/bin/bash
|
||||
dirInstall="/Users/Shared/TorrServer"
|
||||
serviceName="torrserver"
|
||||
|
||||
function getLang() {
|
||||
lang=$(locale | grep LANG | cut -d= -f2 | tr -d '"' | cut -d_ -f1)
|
||||
[[ $lang != "ru" ]] && lang="en"
|
||||
}
|
||||
|
||||
function checkArch() {
|
||||
case $(uname -m) in
|
||||
i386) architecture="386" ;;
|
||||
i686) architecture="386" ;;
|
||||
x86_64) architecture="amd64" ;;
|
||||
aarch64) architecture="arm64" ;;
|
||||
*) [[ $lang == "en" ]] && { echo ""; echo " Unsupported Arch. Can't continue."; exit 1; } || { echo ""; echo " Не поддерживаемая архитектура. Продолжение невозможно."; exit 1; } ;;
|
||||
esac
|
||||
}
|
||||
|
||||
function getLatestRelease() {
|
||||
curl -s "https://api.github.com/repos/YouROK/TorrServer/releases" |
|
||||
grep -iE '"tag_name":|"version":' |
|
||||
sed -E 's/.*"([^"]+)".*/\1/' |
|
||||
head -1
|
||||
}
|
||||
|
||||
function killRunning() {
|
||||
self="$(basename "$0")"
|
||||
runningPid=$(ps -ax|grep -i torrserver|grep -v grep|grep -v "$self"|awk '{print $1}')
|
||||
# echo $runningPid
|
||||
[ -z $runningPid ] || sudo kill -9 $runningPid
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -f /Library/LaunchAgents/*torrserver* 1>/dev/null 2>&1
|
||||
sudo rm -f /Library/LaunchDaemons/*torrserver* 1>/dev/null 2>&1
|
||||
sudo rm -f $HOME/Library/LaunchAgents/*torrserver* 1>/dev/null 2>&1
|
||||
sudo rm -f $HOME/Library/LaunchDaemons/*torrserver* 1>/dev/null 2>&1
|
||||
killRunning
|
||||
}
|
||||
|
||||
function uninstall() {
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " TorrServer install dir - ${dirInstall}"
|
||||
echo ""
|
||||
echo " This action will delete TorrServer including all it's torrents, settings and files on path above."
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " Директория c TorrServer - ${dirInstall}"
|
||||
echo ""
|
||||
echo " Это действие удалит все данные TorrServer включая базу данных торрентов и настройки по указанному выше пути."
|
||||
echo ""
|
||||
}
|
||||
[[ $lang == "en" ]] && read -p ' Are you shure you want to delete TorrServer? (Yes/No) ' answer_del </dev/tty || read -p ' Вы уверены что хотите удалить программу? (Да/Нет) ' answer_del </dev/tty
|
||||
read answer_del
|
||||
if [ "$answer_del" != "${answer_del#[YyДд]}" ]; then
|
||||
cleanup
|
||||
sudo rm -rf $dirInstall
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && echo " TorrServer deleted from Mac" || echo " TorrServer удален c вашего Mac"
|
||||
echo ""
|
||||
sleep 5
|
||||
else
|
||||
echo ""
|
||||
echo "OK"
|
||||
echo ""
|
||||
sleep 5
|
||||
fi
|
||||
}
|
||||
|
||||
function installTorrServer() {
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " Install TorrServer $(getLatestRelease)…"
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " Устанавливаем TorrServer $(getLatestRelease)…"
|
||||
echo ""
|
||||
}
|
||||
binName="TorrServer-darwin-${architecture}"
|
||||
[[ ! -d "$dirInstall" ]] && mkdir -p ${dirInstall}
|
||||
urlBin="https://github.com/YouROK/TorrServer/releases/download/$(getLatestRelease)/${binName}"
|
||||
if [[ ! -f "$dirInstall/$binName" ]] | [[ ! -x "$dirInstall/$binName" ]] || [[ $(stat -c%s "$dirInstall/$binName" 2>/dev/null) -eq 0 ]]; then
|
||||
curl -L --progress-bar -# -o "$dirInstall/$binName" "$urlBin"
|
||||
chmod a+rx "$dirInstall/$binName"
|
||||
xattr -r -d com.apple.quarantine "$dirInstall/$binName"
|
||||
fi
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " Add autostart service for TorrServer $(getLatestRelease)…"
|
||||
echo ""
|
||||
echo " System can ask your admin account password"
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " Создаем сервис автозагрузки TorrServer $(getLatestRelease)…"
|
||||
echo ""
|
||||
echo " Система может запросить ваш пароль администратора"
|
||||
echo ""
|
||||
}
|
||||
###
|
||||
cleanup
|
||||
###
|
||||
[[ $lang == "en" ]] && read -p ' Change TorrServer web port? (Yes/No) ' answer_cp </dev/tty || read -p ' Хотите изменить веб-порт для TorrServer? (Да/Нет) ' answer_cp </dev/tty
|
||||
if [ "$answer_cp" != "${answer_cp#[YyДд]}" ]; then
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && read -p ' Enter port number: ' answer_port </dev/tty || read -p ' Введите номер порта: ' answer_port </dev/tty
|
||||
servicePort=$answer_port
|
||||
echo ""
|
||||
else
|
||||
servicePort="8090"
|
||||
echo ""
|
||||
fi
|
||||
cat << EOF > $dirInstall/$serviceName.plist
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>${serviceName}</string>
|
||||
<key>ServiceDescription</key>
|
||||
<string>TorrServer service for MacOS</string>
|
||||
<key>LaunchOnlyOnce</key>
|
||||
<true/>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>${dirInstall}/TorrServer-darwin-${architecture}</string>
|
||||
<string>--port</string>
|
||||
<string>${servicePort}</string>
|
||||
<string>--path</string>
|
||||
<string>${dirInstall}</string>
|
||||
<string>--logpath</string>
|
||||
<string>${dirInstall}/torrserver.log</string>
|
||||
<string>--httpauth</string>
|
||||
</array>
|
||||
<key>StandardOutPath</key>
|
||||
<string>${dirInstall}/torrserver.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>${dirInstall}/torrserver.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
[[ $lang == "en" ]] && read -p ' Enable HTTP Authorization? (Yes/No) ' answer_auth </dev/tty || read -p ' Включить авторизацию на сервере? (Да/Нет) ' answer_auth </dev/tty
|
||||
if [ "$answer_auth" != "${answer_auth#[YyДд]}" ]; then
|
||||
isAuth=1
|
||||
else
|
||||
isAuth=0
|
||||
fi
|
||||
echo ""
|
||||
if [[ "$isAuth" == 1 ]]; then
|
||||
[[ $lang == "en" ]] && echo " HTTP Auth Install choosen" || echo " Вы выбрали установку с авторизацией"
|
||||
[[ ! -f "$dirInstall/accs.db" ]] && {
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && read -p ' User: ' answer_user </dev/tty || read -p ' Пользователь: ' answer_user </dev/tty
|
||||
isAuthUser=$answer_user
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && read -p ' Password: ' answer_pass </dev/tty || read -p ' Пароль: ' answer_pass </dev/tty
|
||||
isAuthPass=$answer_pass
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && echo " Added credentials: $isAuthUser:$isAuthPass" || echo " Устанавливаем логин и пароль: $isAuthUser:$isAuthPass"
|
||||
echo ""
|
||||
echo -e "{\n \"$isAuthUser\": \"$isAuthPass\"\n}" > $dirInstall/accs.db
|
||||
} || {
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && echo " Use ${dirInstall}/accs.db credentials for access" || echo " Используйте реквизиты из ${dirInstall}/accs.db для входа"
|
||||
echo ""
|
||||
}
|
||||
else
|
||||
sed -i '' -e '/httpauth/d' $dirInstall/$serviceName.plist
|
||||
fi
|
||||
[[ $lang == "en" ]] && read -p ' Add autostart for current user (1) or all users (2)? ' answer_cu </dev/tty || read -p ' Добавить автозагрузку для текушего пользователя (1) или всех (2)? ' answer_cu </dev/tty
|
||||
if [ "$answer_cu" != "${answer_cu#[1]}" ]; then
|
||||
# user
|
||||
sysPath="${HOME}/Library/LaunchAgents"
|
||||
[[ ! -d "$sysPath" ]] && mkdir -p ${sysPath}
|
||||
cp "$dirInstall/$serviceName.plist" $sysPath
|
||||
chmod 0644 "$sysPath/$serviceName.plist"
|
||||
launchctl load -w "$sysPath/$serviceName.plist" 1>/dev/null 2>&1
|
||||
else
|
||||
# root
|
||||
sysPath="/Library/LaunchDaemons"
|
||||
[[ ! -d "$sysPath" ]] && sudo mkdir -p ${sysPath}
|
||||
sudo cp "$dirInstall/$serviceName.plist" $sysPath
|
||||
sudo chown root:wheel "$sysPath/$serviceName.plist"
|
||||
sudo chmod 0644 "$sysPath/$serviceName.plist"
|
||||
sudo launchctl load -w "$sysPath/$serviceName.plist" 1>/dev/null 2>&1
|
||||
fi
|
||||
[[ $lang == "en" ]] && {
|
||||
echo ""
|
||||
echo " Autostart service added to ${sysPath}"
|
||||
echo ""
|
||||
echo " TorrServer $(getLatestRelease) for ${architecture} Mac installed to ${dirInstall}"
|
||||
echo ""
|
||||
echo " You can now open browser URL http://localhost:$servicePort to access TorrServer GUI"
|
||||
echo ""
|
||||
} || {
|
||||
echo ""
|
||||
echo " Сервис автозагрузки записан в ${sysPath}"
|
||||
echo ""
|
||||
echo " TorrServer $(getLatestRelease) для ${architecture} Mac установлен в ${dirInstall}"
|
||||
echo ""
|
||||
echo " Теперь вы можете открыть браузер по адресу http://localhost:$servicePort для доступа к вебу TorrServer"
|
||||
echo ""
|
||||
}
|
||||
if [[ "$isAuth" == 1 && $isAuthUser > 0 ]]; then
|
||||
[[ $lang == "en" ]] && echo " Use user \"$isAuthUser\" with password \"$isAuthPass\" for web auth" || echo " Для авторизации введите пользователя $isAuthUser с паролем $isAuthPass"
|
||||
echo ""
|
||||
fi
|
||||
sleep 60
|
||||
}
|
||||
|
||||
while true; do
|
||||
getLang
|
||||
echo ""
|
||||
echo "=============================================================="
|
||||
[[ $lang == "en" ]] && echo " TorrServer install, update and uninstall script for MacOS " || echo " Скрипт установки, обновления и удаления TorrServer для MacOS "
|
||||
echo "=============================================================="
|
||||
echo ""
|
||||
[[ $lang == "en" ]] && read -p " Do You want to install or update TorrServer? (Yes or No). Enter \"Delete\" to Uninstall TorrServer. " ydn </dev/tty || read -p " Хотите установить или обновить TorrServer? (Да|Нет). Для удаления введите «Удалить». " ydn </dev/tty
|
||||
case $ydn in
|
||||
[YyДд]*) checkArch; installTorrServer; break ;;
|
||||
[DdУу]*) uninstall; break ;;
|
||||
[NnНн]*) exit ;;
|
||||
*) [[ $lang == "en" ]] && { echo ""; echo " Enter \"Yes\", \"No\" or \"Delete\"."; } || { echo ""; echo " Ввведите «Да», «Нет» или «Удалить»."; } ;;
|
||||
esac
|
||||
done
|
||||
echo " Have Fun!"
|
||||
echo ""
|
||||
sleep 5
|
||||
@@ -2,66 +2,69 @@ module server
|
||||
|
||||
go 1.18
|
||||
|
||||
replace github.com/anacrolix/torrent v1.46.1-0.20220831010947-648acc0120a4 => github.com/tsynik/torrent v1.2.8
|
||||
replace github.com/anacrolix/torrent v1.48.0 => github.com/tsynik/torrent v1.2.8
|
||||
|
||||
require (
|
||||
github.com/agnivade/levenshtein v1.1.1
|
||||
github.com/alexflint/go-arg v1.4.3
|
||||
github.com/anacrolix/dms v1.5.0
|
||||
github.com/anacrolix/log v0.13.2-0.20220711050817-613cb738ef30
|
||||
github.com/anacrolix/log v0.13.2-0.20221123232138-02e2764801c3
|
||||
github.com/anacrolix/missinggo v1.3.0
|
||||
github.com/anacrolix/publicip v0.3.0
|
||||
github.com/anacrolix/torrent v1.46.1-0.20220831010947-648acc0120a4
|
||||
github.com/anacrolix/torrent v1.48.0
|
||||
github.com/gin-contrib/cors v1.4.0
|
||||
github.com/gin-contrib/location v0.0.2
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/gin-gonic/gin v1.8.2
|
||||
github.com/kljensen/snowball v0.6.0
|
||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4
|
||||
github.com/pkg/errors v0.9.1
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
golang.org/x/time v0.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/RoaringBitmap/roaring v1.2.1 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.2.3 // indirect
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
|
||||
github.com/alexflint/go-scalar v1.1.0 // indirect
|
||||
github.com/anacrolix/chansync v0.3.0 // indirect
|
||||
github.com/anacrolix/dht/v2 v2.18.1 // indirect
|
||||
github.com/anacrolix/ffprobe v1.0.0 // indirect
|
||||
github.com/anacrolix/ffprobe v1.0.1 // indirect
|
||||
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
|
||||
github.com/anacrolix/missinggo/v2 v2.7.0 // indirect
|
||||
github.com/anacrolix/missinggo/v2 v2.7.1 // indirect
|
||||
github.com/anacrolix/multiless v0.3.0 // indirect
|
||||
github.com/anacrolix/stm v0.4.0 // indirect
|
||||
github.com/anacrolix/stm v0.5.0 // indirect
|
||||
github.com/anacrolix/sync v0.4.0 // indirect
|
||||
github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96 // indirect
|
||||
github.com/anacrolix/utp v0.1.0 // indirect
|
||||
github.com/benbjohnson/immutable v0.3.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.3.3 // indirect
|
||||
github.com/benbjohnson/immutable v0.4.2 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.5.0 // indirect
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.1.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.0 // indirect
|
||||
github.com/goccy/go-json v0.9.11 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 // indirect
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
|
||||
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 // indirect
|
||||
golang.org/x/sys v0.0.0-20220913175220-63ea55921009 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
github.com/ugorji/go/codec v1.2.8 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230202163644-54bba9f4231b // indirect
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
121
server/go.sum
121
server/go.sum
@@ -7,10 +7,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
|
||||
github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A=
|
||||
github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY=
|
||||
github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk=
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8=
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2/go.mod h1:zD6QGEyw49HIq19caJDc2NMXAy8rNi9ROrxtMXATfyI=
|
||||
@@ -33,14 +35,15 @@ github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhU
|
||||
github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.1.0/go.mod h1:My7T5oSqVfEn4MD4Meczkw/f5lSIndGAKu/0SM/rkf4=
|
||||
github.com/anacrolix/envpprof v1.1.1 h1:sHQCyj7HtiSfaZAzL2rJrQdyS7odLqlwO6nhk/tG/j8=
|
||||
github.com/anacrolix/ffprobe v1.0.0 h1:j8fGLBsXejwdXd0pkA9iR3Dt1XwMFv5wjeYWObcue8A=
|
||||
github.com/anacrolix/ffprobe v1.0.0/go.mod h1:BIw+Bjol6CWjm/CRWrVLk2Vy+UYlkgmBZ05vpSYqZPw=
|
||||
github.com/anacrolix/ffprobe v1.0.1 h1:S/MfCrUNZvbkkykX/1mmLVRf8//M7mvlY3BcwHaK3bQ=
|
||||
github.com/anacrolix/ffprobe v1.0.1/go.mod h1:MXe+zG/RRa5OdIf5+VYYfS/CfsSqOH7RrvGIqJBzqhI=
|
||||
github.com/anacrolix/log v0.3.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU=
|
||||
github.com/anacrolix/log v0.6.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU=
|
||||
github.com/anacrolix/log v0.10.1-0.20220123034749-3920702c17f8/go.mod h1:GmnE2c0nvz8pOIPUSC9Rawgefy1sDXqposC2wgtBZE4=
|
||||
github.com/anacrolix/log v0.13.1/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68=
|
||||
github.com/anacrolix/log v0.13.2-0.20220711050817-613cb738ef30 h1:bAgFzUxN1K3U8KwOzqCOhiygOr5NqYO3kNlV9tvp2Rc=
|
||||
github.com/anacrolix/log v0.13.2-0.20220711050817-613cb738ef30/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68=
|
||||
github.com/anacrolix/log v0.13.2-0.20221123232138-02e2764801c3 h1:qDcPnH18SanNZMeMuEjzKpB3NQGR1ahytV08KOhZhNo=
|
||||
github.com/anacrolix/log v0.13.2-0.20221123232138-02e2764801c3/go.mod h1:MD4fn2pYcyhUAQg9SxoGOpTnV/VIdiKVYKZdCbDC97k=
|
||||
github.com/anacrolix/missinggo v1.1.0/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo=
|
||||
github.com/anacrolix/missinggo v1.1.2-0.20190815015349-b888af804467/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo=
|
||||
github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y=
|
||||
@@ -51,15 +54,15 @@ github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5ur
|
||||
github.com/anacrolix/missinggo/v2 v2.2.0/go.mod h1:o0jgJoYOyaoYQ4E2ZMISVa9c88BbUBVQQW4QeRkNCGY=
|
||||
github.com/anacrolix/missinggo/v2 v2.5.1/go.mod h1:WEjqh2rmKECd0t1VhQkLGTdIWXO6f6NLjp5GlMZ+6FA=
|
||||
github.com/anacrolix/missinggo/v2 v2.5.2/go.mod h1:yNvsLrtZYRYCOI+KRH/JM8TodHjtIE/bjOGhQaLOWIE=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.0 h1:4fzOAAn/VCvfWGviLmh64MPMttrlYew81JdPO7nSHvI=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.0/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.1 h1:Y+wL0JC6D2icpwhDpcrRM4THQB/uFcPNYUtZMbYvQgI=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.1/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI=
|
||||
github.com/anacrolix/multiless v0.3.0 h1:5Bu0DZncjE4e06b9r1Ap2tUY4Au0NToBP5RpuEngSis=
|
||||
github.com/anacrolix/multiless v0.3.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4=
|
||||
github.com/anacrolix/publicip v0.3.0 h1:QK+lvqNzZDznqWMe5lbnjdXsKb7Mvhqy6osV3J+HwPY=
|
||||
github.com/anacrolix/publicip v0.3.0/go.mod h1:tF1kAG96Ao3t9Q8zyfA7Lso1wOEfHHEcZQTRI+PMm4k=
|
||||
github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
|
||||
github.com/anacrolix/stm v0.4.0 h1:tOGvuFwaBjeu1u9X1eIh9TX8OEedEiEQ1se1FjhFnXY=
|
||||
github.com/anacrolix/stm v0.4.0/go.mod h1:GCkwqWoAsP7RfLW+jw+Z0ovrt2OO7wRzcTtFYMYY5t8=
|
||||
github.com/anacrolix/stm v0.5.0 h1:9df1KBpttF0TzLgDq51Z+TEabZKMythqgx89f1FQJt8=
|
||||
github.com/anacrolix/stm v0.5.0/go.mod h1:MOwrSy+jCm8Y7HYfMAwPj7qWVu7XoVvjOiYwJmpeB/M=
|
||||
github.com/anacrolix/sync v0.3.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
|
||||
github.com/anacrolix/sync v0.4.0 h1:T+MdO/u87ir/ijWsTFsPYw5jVm0SMm4kVpg8t4KF38o=
|
||||
github.com/anacrolix/sync v0.4.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
|
||||
@@ -71,15 +74,17 @@ github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96/go.mod h1:Wa6n8cY
|
||||
github.com/anacrolix/utp v0.1.0 h1:FOpQOmIwYsnENnz7tAGohA+r6iXpRjrq8ssKSre2Cp4=
|
||||
github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNaBJ2Dk=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/benbjohnson/immutable v0.2.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
||||
github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCgWHZEIw=
|
||||
github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
||||
github.com/benbjohnson/immutable v0.4.2 h1:0KBS7FYBWAlu9Xw/i1MS3gvJIwLR8RBeUqFFNn97JMU=
|
||||
github.com/benbjohnson/immutable v0.4.2/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
|
||||
github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8=
|
||||
github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 h1:GKTyiRCL6zVf5wWaqKnf+7Qs6GbEPfd4iMOitWzXJx8=
|
||||
@@ -90,16 +95,20 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
||||
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
|
||||
github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
|
||||
@@ -108,8 +117,9 @@ github.com/gin-contrib/location v0.0.2/go.mod h1:NGoidiRlf0BlA/VKSVp+g3cuSMeTmip
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY=
|
||||
github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8nfB398=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
@@ -120,22 +130,24 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
|
||||
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -163,7 +175,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -177,8 +190,9 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
|
||||
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -187,12 +201,15 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kljensen/snowball v0.6.0 h1:6DZLCcZeL0cLfodx+Md4/OLC6b/bfurWUOUGs1ydfOU=
|
||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -202,8 +219,8 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
@@ -222,8 +239,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
|
||||
@@ -253,8 +270,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs=
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
|
||||
@@ -268,6 +286,7 @@ github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:K
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@@ -275,8 +294,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
@@ -285,22 +305,24 @@ github.com/tsynik/torrent v1.2.8/go.mod h1:wtEVRmXUffDKwa1YpwP6EbWfuuzPZ7Q+FiBuh
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.8 h1:sgBJS6COt0b/P40VouWKdseidkDgHxYGm0SAglUHfP0=
|
||||
github.com/ugorji/go/codec v1.2.8/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20230202163644-54bba9f4231b h1:EqBVA+nNsObCwQoBEHy4wLU0pi7i8a4AL3pbItPdPkE=
|
||||
golang.org/x/exp v0.0.0-20230202163644-54bba9f4231b/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -316,10 +338,9 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220524220425-1d687d428aca/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -328,8 +349,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 h1:0SH2R3f1b1VmIMG7BXbEZCBUu2dKmHschSmjqGUrW8A=
|
||||
golang.org/x/sync v0.0.0-20220907140024-f12130a52804/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -342,27 +363,26 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220913175220-63ea55921009 h1:PuvuRMeLWqsf/ZdT1UUZz0syhioyv1mzuFZsXs4fvhw=
|
||||
golang.org/x/sys v0.0.0-20220913175220-63ea55921009/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -370,7 +390,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
76
server/rutor/models/torrentDetails.go
Normal file
76
server/rutor/models/torrentDetails.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
CatMovie = "Movie"
|
||||
CatSeries = "Series"
|
||||
CatDocMovie = "DocMovie"
|
||||
CatDocSeries = "DocSeries"
|
||||
CatCartoonMovie = "CartoonMovie"
|
||||
CatCartoonSeries = "CartoonSeries"
|
||||
CatTVShow = "TVShow"
|
||||
CatAnime = "Anime"
|
||||
|
||||
Q_LOWER = 0
|
||||
Q_WEBDL_720 = 100
|
||||
Q_BDRIP_720 = 101
|
||||
Q_BDRIP_HEVC_720 = 102
|
||||
Q_WEBDL_1080 = 200
|
||||
Q_BDRIP_1080 = 201
|
||||
Q_BDRIP_HEVC_1080 = 202
|
||||
Q_BDREMUX_1080 = 203
|
||||
Q_WEBDL_SDR_2160 = 300
|
||||
Q_WEBDL_HDR_2160 = 301
|
||||
Q_WEBDL_DV_2160 = 302
|
||||
Q_BDRIP_SDR_2160 = 303
|
||||
Q_BDRIP_HDR_2160 = 304
|
||||
Q_BDRIP_DV_2160 = 305
|
||||
Q_UHD_BDREMUX_SDR = 306
|
||||
Q_UHD_BDREMUX_HDR = 307
|
||||
Q_UHD_BDREMUX_DV = 308
|
||||
|
||||
Q_UNKNOWN = 0
|
||||
Q_A = 1 // Авторский, по типу Гоблина или старых переводчиков
|
||||
Q_L1 = 100 // Любительский одноголосый закадровый
|
||||
Q_L2 = 101 // Любительский двухголосый закадровый
|
||||
Q_L = 102 // Любительский 3-5 человек закадровый
|
||||
Q_LS = 103 // Любительский студия
|
||||
Q_P1 = 200 // Професиональный одноголосый закадровый
|
||||
Q_P2 = 201 // Профессиональный двухголосый закадровый
|
||||
Q_P = 202 // Профессиональный 3-5 человек закадровый
|
||||
Q_PS = 203 // Профессиональный студия
|
||||
Q_D = 300 // Официальное профессиональное многоголосое озвучивание
|
||||
Q_LICENSE = 301 // Лицензия
|
||||
)
|
||||
|
||||
type TorrentDetails struct {
|
||||
Title string
|
||||
Name string
|
||||
Names []string
|
||||
Categories string
|
||||
Size string
|
||||
CreateDate time.Time
|
||||
Tracker string
|
||||
Link string
|
||||
Year int
|
||||
Peer int
|
||||
Seed int
|
||||
Magnet string
|
||||
Hash string
|
||||
IMDBID string
|
||||
VideoQuality int
|
||||
AudioQuality int
|
||||
}
|
||||
|
||||
type TorrentFile struct {
|
||||
Name string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func (d TorrentDetails) GetNames() string {
|
||||
return strings.Join(d.Names, " ")
|
||||
}
|
||||
153
server/rutor/rutor.go
Normal file
153
server/rutor/rutor.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package rutor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"encoding/json"
|
||||
"github.com/agnivade/levenshtein"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"server/log"
|
||||
"server/rutor/models"
|
||||
"server/rutor/torrsearch"
|
||||
"server/rutor/utils"
|
||||
"server/settings"
|
||||
utils2 "server/torr/utils"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
torrs []*models.TorrentDetails
|
||||
isStop bool
|
||||
)
|
||||
|
||||
func Start() {
|
||||
go func() {
|
||||
if settings.BTsets.EnableRutorSearch {
|
||||
loadDB()
|
||||
updateDB()
|
||||
isStop = false
|
||||
for !isStop {
|
||||
for i := 0; i < 3*60*60; i++ {
|
||||
time.Sleep(time.Second)
|
||||
if isStop {
|
||||
return
|
||||
}
|
||||
}
|
||||
updateDB()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func Stop() {
|
||||
isStop = true
|
||||
torrs = nil
|
||||
torrsearch.NewIndex(nil)
|
||||
utils2.FreeOSMemGC()
|
||||
time.Sleep(time.Millisecond * 1500)
|
||||
}
|
||||
|
||||
// https://github.com/yourok-0001/releases/raw/master/torr/rutor.ls
|
||||
func updateDB() {
|
||||
log.TLogln("Update rutor db")
|
||||
fnTmp := filepath.Join(settings.Path, "rutor.tmp")
|
||||
out, err := os.Create(fnTmp)
|
||||
if err != nil {
|
||||
log.TLogln("Error create file rutor.tmp:", err)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := http.Get("https://github.com/yourok-0001/releases/raw/master/torr/rutor.ls")
|
||||
if err != nil {
|
||||
log.TLogln("Error connect to rutor db:", err)
|
||||
out.Close()
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
out.Close()
|
||||
if err != nil {
|
||||
log.TLogln("Error download rutor db:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fnOrig := filepath.Join(settings.Path, "rutor.ls")
|
||||
|
||||
md5Tmp := utils.MD5File(fnTmp)
|
||||
md5Orig := utils.MD5File(fnOrig)
|
||||
if md5Tmp != md5Orig {
|
||||
err = os.Remove(fnOrig)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
log.TLogln("Error remove old rutor db:", err)
|
||||
return
|
||||
}
|
||||
err = os.Rename(fnTmp, fnOrig)
|
||||
if err != nil {
|
||||
log.TLogln("Error rename rutor db:", err)
|
||||
return
|
||||
}
|
||||
loadDB()
|
||||
} else {
|
||||
os.Remove(fnTmp)
|
||||
}
|
||||
}
|
||||
|
||||
func loadDB() {
|
||||
log.TLogln("Load rutor db")
|
||||
buf, err := os.ReadFile(filepath.Join(settings.Path, "rutor.ls"))
|
||||
if err == nil {
|
||||
r := flate.NewReader(bytes.NewReader(buf))
|
||||
buf, err = io.ReadAll(r)
|
||||
r.Close()
|
||||
if err == nil {
|
||||
var ftors []*models.TorrentDetails
|
||||
err = json.Unmarshal(buf, &ftors)
|
||||
if err == nil {
|
||||
torrs = ftors
|
||||
log.TLogln("Index rutor db")
|
||||
torrsearch.NewIndex(torrs)
|
||||
} else {
|
||||
log.TLogln("Error read rutor db:", err)
|
||||
}
|
||||
} else {
|
||||
log.TLogln("Error read rutor db:", err)
|
||||
}
|
||||
} else {
|
||||
log.TLogln("Error load rutor db:", err)
|
||||
}
|
||||
utils2.FreeOSMemGC()
|
||||
}
|
||||
|
||||
func Search(query string) []*models.TorrentDetails {
|
||||
if !settings.BTsets.EnableRutorSearch {
|
||||
return nil
|
||||
}
|
||||
matchedIDs := torrsearch.Search(query)
|
||||
if len(matchedIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
var list []*models.TorrentDetails
|
||||
for _, id := range matchedIDs {
|
||||
list = append(list, torrs[id])
|
||||
}
|
||||
|
||||
hash := utils.ClearStr(query)
|
||||
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
lhash := utils.ClearStr(strings.ToLower(list[i].Name+list[i].GetNames())) + strconv.Itoa(list[i].Year)
|
||||
lev1 := levenshtein.ComputeDistance(hash, lhash)
|
||||
lhash = utils.ClearStr(strings.ToLower(list[j].Name+list[j].GetNames())) + strconv.Itoa(list[j].Year)
|
||||
lev2 := levenshtein.ComputeDistance(hash, lhash)
|
||||
if lev1 == lev2 {
|
||||
return list[j].CreateDate.Before(list[i].CreateDate)
|
||||
}
|
||||
return lev1 < lev2
|
||||
})
|
||||
return list
|
||||
}
|
||||
99
server/rutor/torrsearch/filter.go
Normal file
99
server/rutor/torrsearch/filter.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package torrsearch
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
snowballeng "github.com/kljensen/snowball/english"
|
||||
snowballru "github.com/kljensen/snowball/russian"
|
||||
)
|
||||
|
||||
// lowercaseFilter returns a slice of tokens normalized to lower case.
|
||||
func lowercaseFilter(tokens []string) []string {
|
||||
r := make([]string, len(tokens))
|
||||
for i, token := range tokens {
|
||||
r[i] = replaceChars(strings.ToLower(token))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// stopwordFilter returns a slice of tokens with stop words removed.
|
||||
func stopwordFilter(tokens []string) []string {
|
||||
r := make([]string, 0, len(tokens))
|
||||
for _, token := range tokens {
|
||||
if !isStopWord(token) {
|
||||
r = append(r, token)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// stemmerFilter returns a slice of stemmed tokens.
|
||||
func stemmerFilter(tokens []string) []string {
|
||||
r := make([]string, len(tokens))
|
||||
for i, token := range tokens {
|
||||
worden := snowballeng.Stem(token, false)
|
||||
wordru := snowballru.Stem(token, false)
|
||||
if wordru == "" || worden == "" {
|
||||
continue
|
||||
}
|
||||
if wordru != token {
|
||||
r[i] = wordru
|
||||
} else {
|
||||
r[i] = worden
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func replaceChars(word string) string {
|
||||
out := []rune(word)
|
||||
for i, r := range out {
|
||||
if r == 'ё' {
|
||||
out[i] = 'е'
|
||||
}
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
|
||||
func isStopWord(word string) bool {
|
||||
switch word {
|
||||
case "a", "about", "above", "after", "again", "against", "all", "am", "an",
|
||||
"and", "any", "are", "as", "at", "be", "because", "been", "before",
|
||||
"being", "below", "between", "both", "but", "by", "can", "did", "do",
|
||||
"does", "doing", "don", "down", "during", "each", "few", "for", "from",
|
||||
"further", "had", "has", "have", "having", "he", "her", "here", "hers",
|
||||
"herself", "him", "himself", "his", "how", "i", "if", "in", "into", "is",
|
||||
"it", "its", "itself", "just", "me", "more", "most", "my", "myself",
|
||||
"no", "nor", "not", "now", "of", "off", "on", "once", "only", "or",
|
||||
"other", "our", "ours", "ourselves", "out", "over", "own", "s", "same",
|
||||
"she", "should", "so", "some", "such", "t", "than", "that", "the", "their",
|
||||
"theirs", "them", "themselves", "then", "there", "these", "they",
|
||||
"this", "those", "through", "to", "too", "under", "until", "up",
|
||||
"very", "was", "we", "were", "what", "when", "where", "which", "while",
|
||||
"who", "whom", "why", "will", "with", "you", "your", "yours", "yourself",
|
||||
"yourselves", "и", "в", "во", "не", "что", "он", "на", "я", "с",
|
||||
"со", "как", "а", "то", "все", "она", "так", "его",
|
||||
"но", "да", "ты", "к", "у", "же", "вы", "за", "бы",
|
||||
"по", "только", "ее", "мне", "было", "вот", "от",
|
||||
"меня", "еще", "нет", "о", "из", "ему", "теперь",
|
||||
"когда", "даже", "ну", "вдруг", "ли", "если", "уже",
|
||||
"или", "ни", "быть", "был", "него", "до", "вас",
|
||||
"нибудь", "опять", "уж", "вам", "ведь", "там", "потом",
|
||||
"себя", "ничего", "ей", "может", "они", "тут", "где",
|
||||
"есть", "надо", "ней", "для", "мы", "тебя", "их",
|
||||
"чем", "была", "сам", "чтоб", "без", "будто", "чего",
|
||||
"раз", "тоже", "себе", "под", "будет", "ж", "тогда",
|
||||
"кто", "этот", "того", "потому", "этого", "какой",
|
||||
"совсем", "ним", "здесь", "этом", "один", "почти",
|
||||
"мой", "тем", "чтобы", "нее", "сейчас", "были", "куда",
|
||||
"зачем", "всех", "никогда", "можно", "при", "наконец",
|
||||
"два", "об", "другой", "хоть", "после", "над", "больше",
|
||||
"тот", "через", "эти", "нас", "про", "всего", "них",
|
||||
"какая", "много", "разве", "три", "эту", "моя",
|
||||
"впрочем", "хорошо", "свою", "этой", "перед", "иногда",
|
||||
"лучше", "чуть", "том", "нельзя", "такой", "им", "более",
|
||||
"всегда", "конечно", "всю", "между":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
74
server/rutor/torrsearch/index.go
Normal file
74
server/rutor/torrsearch/index.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package torrsearch
|
||||
|
||||
import (
|
||||
"server/rutor/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Index is an inverted Index. It maps tokens to document IDs.
|
||||
type Index map[string][]int
|
||||
|
||||
var idx Index
|
||||
|
||||
func NewIndex(torrs []*models.TorrentDetails) {
|
||||
idx = make(Index)
|
||||
idx.add(torrs)
|
||||
}
|
||||
|
||||
func Search(text string) []int {
|
||||
return idx.search(text)
|
||||
}
|
||||
|
||||
func (idx Index) add(torrs []*models.TorrentDetails) {
|
||||
for ID, torr := range torrs {
|
||||
for _, token := range analyze(torr.Name + " " + torr.GetNames() + " " + strconv.Itoa(torr.Year)) {
|
||||
ids := idx[token]
|
||||
if ids != nil && ids[len(ids)-1] == ID {
|
||||
// Don't add same ID twice.
|
||||
continue
|
||||
}
|
||||
idx[token] = append(ids, ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// intersection returns the set intersection between a and b.
|
||||
// a and b have to be sorted in ascending order and contain no duplicates.
|
||||
func intersection(a []int, b []int) []int {
|
||||
maxLen := len(a)
|
||||
if len(b) > maxLen {
|
||||
maxLen = len(b)
|
||||
}
|
||||
r := make([]int, 0, maxLen)
|
||||
var i, j int
|
||||
for i < len(a) && j < len(b) {
|
||||
if a[i] < b[j] {
|
||||
i++
|
||||
} else if a[i] > b[j] {
|
||||
j++
|
||||
} else {
|
||||
r = append(r, a[i])
|
||||
i++
|
||||
j++
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Search queries the Index for the given text.
|
||||
func (idx Index) search(text string) []int {
|
||||
var r []int
|
||||
for _, token := range analyze(text) {
|
||||
if ids, ok := idx[token]; ok {
|
||||
if r == nil {
|
||||
r = ids
|
||||
} else {
|
||||
r = intersection(r, ids)
|
||||
}
|
||||
} else {
|
||||
// Token doesn't exist.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
23
server/rutor/torrsearch/tokenizer.go
Normal file
23
server/rutor/torrsearch/tokenizer.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package torrsearch
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// tokenize returns a slice of tokens for the given text.
|
||||
func tokenize(text string) []string {
|
||||
return strings.FieldsFunc(text, func(r rune) bool {
|
||||
// Split on any character that is not a letter or a number.
|
||||
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
|
||||
})
|
||||
}
|
||||
|
||||
// analyze analyzes the text and returns a slice of tokens.
|
||||
func analyze(text string) []string {
|
||||
tokens := tokenize(text)
|
||||
tokens = lowercaseFilter(tokens)
|
||||
tokens = stopwordFilter(tokens)
|
||||
tokens = stemmerFilter(tokens)
|
||||
return tokens
|
||||
}
|
||||
42
server/rutor/utils/utils.go
Normal file
42
server/rutor/utils/utils.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ClearStr(str string) string {
|
||||
ret := ""
|
||||
str = strings.ToLower(str)
|
||||
for _, r := range str {
|
||||
if (r >= '0' && r <= '9') || (r >= 'a' && r <= 'z') || (r >= 'а' && r <= 'я') || r == 'ё' {
|
||||
ret = ret + string(r)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func MD5File(fname string) string {
|
||||
f, err := os.Open(fname)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
buf := make([]byte, 1024*1024)
|
||||
h := sha256.New()
|
||||
|
||||
for {
|
||||
bytesRead, err := f.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
h.Write(buf[:bytesRead])
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
@@ -31,6 +31,9 @@ type BTSets struct {
|
||||
EnableDLNA bool
|
||||
FriendlyName string
|
||||
|
||||
// Rutor
|
||||
EnableRutorSearch bool
|
||||
|
||||
// BT Config
|
||||
EnableIPv6 bool
|
||||
DisableTCP bool
|
||||
|
||||
@@ -26,6 +26,8 @@ var defTrackers = []string{
|
||||
"udp://tracker.opentrackr.org:1337/announce",
|
||||
"http://bt.svao-ix.ru/announce",
|
||||
"udp://explodie.org:6969/announce",
|
||||
"wss://tracker.btorrent.xyz",
|
||||
"wss://tracker.openwebtorrent.com",
|
||||
}
|
||||
|
||||
var loadedTrackers []string
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package version
|
||||
|
||||
const Version = "MatriX.118.OE"
|
||||
const Version = "MatriX.120.OE"
|
||||
|
||||
@@ -39,6 +39,7 @@ func SetupRoute(route *gin.RouterGroup) {
|
||||
route.GET("/playlist/*fname", playList)
|
||||
|
||||
route.GET("/download/:size", download)
|
||||
route.GET("/search/*query", rutorSearch)
|
||||
}
|
||||
|
||||
func shutdown(c *gin.Context) {
|
||||
|
||||
16
server/web/api/rutor.go
Normal file
16
server/web/api/rutor.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"server/rutor"
|
||||
"server/rutor/models"
|
||||
)
|
||||
|
||||
func rutorSearch(c *gin.Context) {
|
||||
query := c.Query("query")
|
||||
list := rutor.Search(query)
|
||||
if list == nil {
|
||||
list = []*models.TorrentDetails{}
|
||||
}
|
||||
c.JSON(200, list)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"server/rutor"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
@@ -34,11 +35,14 @@ func settings(c *gin.Context) {
|
||||
if req.Sets.EnableDLNA {
|
||||
dlna.Start()
|
||||
}
|
||||
rutor.Stop()
|
||||
rutor.Start()
|
||||
c.Status(200)
|
||||
return
|
||||
} else if req.Action == "def" {
|
||||
torr.SetDefSettings()
|
||||
dlna.Stop()
|
||||
rutor.Stop()
|
||||
c.Status(200)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -118,20 +118,20 @@ var Manifesticon512maskablepng []byte
|
||||
//go:embed pages/site.webmanifest
|
||||
var Sitewebmanifest []byte
|
||||
|
||||
//go:embed pages/static/js/2.0f998e59.chunk.js
|
||||
var Staticjs20f998e59chunkjs []byte
|
||||
//go:embed pages/static/js/2.a86a4d53.chunk.js
|
||||
var Staticjs2a86a4d53chunkjs []byte
|
||||
|
||||
//go:embed pages/static/js/2.0f998e59.chunk.js.LICENSE.txt
|
||||
var Staticjs20f998e59chunkjsLICENSEtxt []byte
|
||||
//go:embed pages/static/js/2.a86a4d53.chunk.js.LICENSE.txt
|
||||
var Staticjs2a86a4d53chunkjsLICENSEtxt []byte
|
||||
|
||||
//go:embed pages/static/js/2.0f998e59.chunk.js.map
|
||||
var Staticjs20f998e59chunkjsmap []byte
|
||||
//go:embed pages/static/js/2.a86a4d53.chunk.js.map
|
||||
var Staticjs2a86a4d53chunkjsmap []byte
|
||||
|
||||
//go:embed pages/static/js/main.604c45f6.chunk.js
|
||||
var Staticjsmain604c45f6chunkjs []byte
|
||||
//go:embed pages/static/js/main.f534b9a4.chunk.js
|
||||
var Staticjsmainf534b9a4chunkjs []byte
|
||||
|
||||
//go:embed pages/static/js/main.604c45f6.chunk.js.map
|
||||
var Staticjsmain604c45f6chunkjsmap []byte
|
||||
//go:embed pages/static/js/main.f534b9a4.chunk.js.map
|
||||
var Staticjsmainf534b9a4chunkjsmap []byte
|
||||
|
||||
//go:embed pages/static/js/runtime-main.64d07802.js
|
||||
var Staticjsruntimemain64d07802js []byte
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/main.604c45f6.chunk.js",
|
||||
"main.js.map": "/static/js/main.604c45f6.chunk.js.map",
|
||||
"main.js": "/static/js/main.f534b9a4.chunk.js",
|
||||
"main.js.map": "/static/js/main.f534b9a4.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.64d07802.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.64d07802.js.map",
|
||||
"static/js/2.0f998e59.chunk.js": "/static/js/2.0f998e59.chunk.js",
|
||||
"static/js/2.0f998e59.chunk.js.map": "/static/js/2.0f998e59.chunk.js.map",
|
||||
"static/js/2.a86a4d53.chunk.js": "/static/js/2.a86a4d53.chunk.js",
|
||||
"static/js/2.a86a4d53.chunk.js.map": "/static/js/2.a86a4d53.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/js/2.0f998e59.chunk.js.LICENSE.txt": "/static/js/2.0f998e59.chunk.js.LICENSE.txt"
|
||||
"static/js/2.a86a4d53.chunk.js.LICENSE.txt": "/static/js/2.a86a4d53.chunk.js.LICENSE.txt"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.64d07802.js",
|
||||
"static/js/2.0f998e59.chunk.js",
|
||||
"static/js/main.604c45f6.chunk.js"
|
||||
"static/js/2.a86a4d53.chunk.js",
|
||||
"static/js/main.f534b9a4.chunk.js"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -161,24 +161,24 @@ func RouteWebPages(route *gin.RouterGroup) {
|
||||
c.Data(200, "application/manifest+json", Sitewebmanifest)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.0f998e59.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjs20f998e59chunkjs)
|
||||
route.GET("/static/js/2.a86a4d53.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjs2a86a4d53chunkjs)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.0f998e59.chunk.js.LICENSE.txt", func(c *gin.Context) {
|
||||
c.Data(200, "text/plain; charset=utf-8", Staticjs20f998e59chunkjsLICENSEtxt)
|
||||
route.GET("/static/js/2.a86a4d53.chunk.js.LICENSE.txt", func(c *gin.Context) {
|
||||
c.Data(200, "text/plain; charset=utf-8", Staticjs2a86a4d53chunkjsLICENSEtxt)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.0f998e59.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjs20f998e59chunkjsmap)
|
||||
route.GET("/static/js/2.a86a4d53.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjs2a86a4d53chunkjsmap)
|
||||
})
|
||||
|
||||
route.GET("/static/js/main.604c45f6.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjsmain604c45f6chunkjs)
|
||||
route.GET("/static/js/main.f534b9a4.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjsmainf534b9a4chunkjs)
|
||||
})
|
||||
|
||||
route.GET("/static/js/main.604c45f6.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjsmain604c45f6chunkjsmap)
|
||||
route.GET("/static/js/main.f534b9a4.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjsmainf534b9a4chunkjsmap)
|
||||
})
|
||||
|
||||
route.GET("/static/js/runtime-main.64d07802.js", func(c *gin.Context) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package web
|
||||
|
||||
import (
|
||||
"net"
|
||||
"server/rutor"
|
||||
"sort"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
@@ -37,6 +38,8 @@ func Start(port string) {
|
||||
waitChan <- err
|
||||
return
|
||||
}
|
||||
rutor.Start()
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
//corsCfg := cors.DefaultConfig()
|
||||
|
||||
@@ -34,7 +34,6 @@ const Table = memo(
|
||||
'No playable files in this torrent'
|
||||
) : (
|
||||
<>
|
||||
<div>{isVlcUsed.toString()}</div>
|
||||
<TableStyle>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import { FormControlLabel, InputAdornment, InputLabel, Select, Switch } from '@material-ui/core'
|
||||
import {
|
||||
FormControlLabel,
|
||||
FormGroup,
|
||||
FormHelperText,
|
||||
InputAdornment,
|
||||
InputLabel,
|
||||
Select,
|
||||
Switch,
|
||||
} from '@material-ui/core'
|
||||
|
||||
import { SecondarySettingsContent, SettingSectionLabel } from './style'
|
||||
|
||||
@@ -14,6 +22,7 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
|
||||
EnableDLNA,
|
||||
EnableIPv6,
|
||||
FriendlyName,
|
||||
EnableRutorSearch,
|
||||
ForceEncrypt,
|
||||
DisableTCP,
|
||||
DisableUTP,
|
||||
@@ -157,6 +166,14 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
|
||||
label={t('SettingsDialog.EnableDebug')}
|
||||
labelPlacement='start'
|
||||
/>
|
||||
<FormGroup>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={EnableRutorSearch} onChange={inputForm} id='EnableRutorSearch' color='secondary' />}
|
||||
label={t('SettingsDialog.EnableRutorSearch')}
|
||||
labelPlacement='start'
|
||||
/>
|
||||
<FormHelperText>{t('SettingsDialog.EnableRutorSearchHint')}</FormHelperText>
|
||||
</FormGroup>
|
||||
<br />
|
||||
<InputLabel htmlFor='RetrackersMode'>{t('SettingsDialog.RetrackersMode')}</InputLabel>
|
||||
<Select
|
||||
|
||||
@@ -15,6 +15,7 @@ export default {
|
||||
EnableDebug: false,
|
||||
EnableIPv6: false,
|
||||
FriendlyName: '',
|
||||
EnableRutorSearch: false,
|
||||
ForceEncrypt: false,
|
||||
PeersListenPort: 0,
|
||||
PreloadCache: 50,
|
||||
|
||||
@@ -115,6 +115,8 @@
|
||||
"ForceEncrypt": "Force Encrypt Headers",
|
||||
"FriendlyName": "DLNA Server Name",
|
||||
"FriendlyNameHint": "Leave blank to use default",
|
||||
"EnableRutorSearch": "Turn on the search by RuTor",
|
||||
"EnableRutorSearchHint": "You can search torrents by RuTor, even if the RuTor is not available. The database in memory takes about 500 MB.",
|
||||
"PeersListenPort": "Peers Listen Port",
|
||||
"PeersListenPortHint": "1024 - 65535, 0 - auto",
|
||||
"PreloadCache": "Preload Cache Before Play",
|
||||
|
||||
@@ -115,6 +115,8 @@
|
||||
"ForceEncrypt": "Принудительное шифрование заголовков",
|
||||
"FriendlyName": "Имя сервера DLNA",
|
||||
"FriendlyNameHint": "Оставьте пустым, чтобы использовать значение по умолчанию.",
|
||||
"EnableRutorSearch": "Включить поиск по RuTor",
|
||||
"EnableRutorSearchHint": "Можно искать торренты от RuTor, даже если RuTor не доступен. База в памяти занимает около 500 МБ.",
|
||||
"PeersListenPort": "Порт для входящих подключений",
|
||||
"PeersListenPortHint": "1024 - 65535, 0 - авто",
|
||||
"PreloadCache": "Буфер предзагрузки",
|
||||
|
||||
@@ -115,6 +115,8 @@
|
||||
"ForceEncrypt": "Примусово шифрувати заголовки",
|
||||
"FriendlyName": "Ім'я сервера DLNA",
|
||||
"FriendlyNameHint": "Залиште порожнім, щоб використовувати значення за промовчанням.",
|
||||
"EnableRutorSearch": "Увімкніть пошук RuTor",
|
||||
"EnableRutorSearchHint": "Ви можете шукати торренти от RuTor, навіть якщо RuTor недоступний. Основа в пам'яті займає близько 500 МБ.",
|
||||
"PeersListenPort": "Порт для вхідних з'єднань",
|
||||
"PeersListenPortHint": "1024 - 65535, 0 - авто",
|
||||
"PreloadCache": "Буфер попер. завантаження",
|
||||
|
||||
@@ -4549,9 +4549,9 @@ decimal.js@^10.2.1:
|
||||
integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==
|
||||
|
||||
decode-uri-component@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||
integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
|
||||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
|
||||
|
||||
decompress-response@^6.0.0:
|
||||
version "6.0.0"
|
||||
@@ -7874,9 +7874,9 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
||||
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
|
||||
|
||||
json5@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
|
||||
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
@@ -8525,9 +8525,9 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
|
||||
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
|
||||
|
||||
minipass-collect@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
||||
Reference in New Issue
Block a user