mirror of https://github.com/jellyfin/jellyfin.git
Merge branch 'master' into fix-trailers_urls
This commit is contained in:
commit
e0cafe418c
|
@ -27,11 +27,11 @@ jobs:
|
||||||
dotnet-version: '8.0.x'
|
dotnet-version: '8.0.x'
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
|
uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: +security-extended
|
queries: +security-extended
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
|
uses: github/codeql-action/autobuild@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
|
uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||||
|
|
|
@ -176,6 +176,7 @@
|
||||||
- [Pithaya](https://github.com/Pithaya)
|
- [Pithaya](https://github.com/Pithaya)
|
||||||
- [Çağrı Sakaoğlu](https://github.com/ilovepilav)
|
- [Çağrı Sakaoğlu](https://github.com/ilovepilav)
|
||||||
_ [Barasingha](https://github.com/MaVdbussche)
|
_ [Barasingha](https://github.com/MaVdbussche)
|
||||||
|
- [Gauvino](https://github.com/Gauvino)
|
||||||
|
|
||||||
# Emby Contributors
|
# Emby Contributors
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<PackageVersion Include="BlurHashSharp" Version="1.3.0" />
|
<PackageVersion Include="BlurHashSharp" Version="1.3.0" />
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
|
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
|
||||||
<PackageVersion Include="Diacritics" Version="3.3.18" />
|
<PackageVersion Include="Diacritics" Version="3.3.27" />
|
||||||
<PackageVersion Include="DiscUtils.Udf" Version="0.16.13" />
|
<PackageVersion Include="DiscUtils.Udf" Version="0.16.13" />
|
||||||
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
|
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
|
||||||
<PackageVersion Include="EFCoreSecondLevelCacheInterceptor" Version="4.1.1" />
|
<PackageVersion Include="EFCoreSecondLevelCacheInterceptor" Version="4.1.1" />
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
||||||
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
||||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||||
<PackageVersion Include="Svg.Skia" Version="1.0.0.2" />
|
<PackageVersion Include="Svg.Skia" Version="1.0.0.10" />
|
||||||
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
|
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
|
||||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||||
<PackageVersion Include="System.Globalization" Version="4.3.0" />
|
<PackageVersion Include="System.Globalization" Version="4.3.0" />
|
||||||
|
@ -85,6 +85,6 @@
|
||||||
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
|
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
|
||||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
|
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
|
||||||
<PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" />
|
<PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" />
|
||||||
<PackageVersion Include="xunit" Version="2.6.5" />
|
<PackageVersion Include="xunit" Version="2.6.6" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
62
Dockerfile
62
Dockerfile
|
@ -8,72 +8,68 @@ FROM node:20-alpine as web-builder
|
||||||
ARG JELLYFIN_WEB_VERSION=master
|
ARG JELLYFIN_WEB_VERSION=master
|
||||||
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
||||||
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
||||||
|
&& apk del curl \
|
||||||
&& cd jellyfin-web-* \
|
&& cd jellyfin-web-* \
|
||||||
&& npm ci --no-audit --unsafe-perm \
|
&& npm ci --no-audit --unsafe-perm \
|
||||||
&& npm run build:production \
|
&& npm run build:production \
|
||||||
&& mv dist /dist
|
&& mv dist /dist
|
||||||
|
|
||||||
FROM debian:stable-slim as app
|
FROM debian:bookworm-slim as app
|
||||||
|
|
||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND="noninteractive"
|
ARG DEBIAN_FRONTEND="noninteractive"
|
||||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||||
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
||||||
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
||||||
|
ENV NVIDIA_VISIBLE_DEVICES="all"
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||||
|
|
||||||
# https://github.com/intel/compute-runtime/releases
|
ENV JELLYFIN_DATA_DIR=/config
|
||||||
ARG GMMLIB_VERSION=22.0.2
|
ENV JELLYFIN_CACHE_DIR=/cache
|
||||||
ARG IGC_VERSION=1.0.10395
|
|
||||||
ARG NEO_VERSION=22.08.22549
|
# https://github.com/intel/compute-runtime/releases
|
||||||
ARG LEVEL_ZERO_VERSION=1.3.22549
|
ARG GMMLIB_VERSION=22.3.11.ci17757293
|
||||||
|
ARG IGC_VERSION=1.0.15136.22
|
||||||
|
ARG NEO_VERSION=23.39.27427.23
|
||||||
|
ARG LEVEL_ZERO_VERSION=1.3.27427.23
|
||||||
|
|
||||||
# Install dependencies:
|
|
||||||
# mesa-va-drivers: needed for AMD VAAPI. Mesa >= 20.1 is required for HEVC transcoding.
|
|
||||||
# curl: healthcheck
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg wget curl \
|
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl \
|
||||||
&& wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | apt-key add - \
|
&& curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg \
|
||||||
&& echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | tee /etc/apt/sources.list.d/jellyfin.list \
|
&& echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | tee /etc/apt/sources.list.d/jellyfin.list \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y \
|
&& apt-get install --no-install-recommends --no-install-suggests -y mesa-va-drivers jellyfin-ffmpeg6 openssl locales \
|
||||||
mesa-va-drivers \
|
|
||||||
jellyfin-ffmpeg5 \
|
|
||||||
openssl \
|
|
||||||
locales \
|
|
||||||
# Intel VAAPI Tone mapping dependencies:
|
# Intel VAAPI Tone mapping dependencies:
|
||||||
# Prefer NEO to Beignet since the latter one doesn't support Comet Lake or newer for now.
|
# Prefer NEO to Beignet since the latter one doesn't support Comet Lake or newer for now.
|
||||||
# Do not use the intel-opencl-icd package from repo since they will not build with RELEASE_WITH_REGKEYS enabled.
|
# Do not use the intel-opencl-icd package from repo since they will not build with RELEASE_WITH_REGKEYS enabled.
|
||||||
&& mkdir intel-compute-runtime \
|
&& mkdir intel-compute-runtime \
|
||||||
&& cd intel-compute-runtime \
|
&& cd intel-compute-runtime \
|
||||||
&& wget https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/intel-gmmlib_${GMMLIB_VERSION}_amd64.deb \
|
&& curl -LO https://github.com/intel/intel-graphics-compiler/releases/download/igc-${IGC_VERSION}/intel-igc-core_${IGC_VERSION}_amd64.deb \
|
||||||
&& wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-${IGC_VERSION}/intel-igc-core_${IGC_VERSION}_amd64.deb \
|
-LO https://github.com/intel/intel-graphics-compiler/releases/download/igc-${IGC_VERSION}/intel-igc-opencl_${IGC_VERSION}_amd64.deb \
|
||||||
&& wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-${IGC_VERSION}/intel-igc-opencl_${IGC_VERSION}_amd64.deb \
|
-LO https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/intel-level-zero-gpu_${LEVEL_ZERO_VERSION}_amd64.deb \
|
||||||
&& wget https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/intel-opencl-icd_${NEO_VERSION}_amd64.deb \
|
-LO https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/intel-opencl-icd_${NEO_VERSION}_amd64.deb \
|
||||||
&& wget https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/intel-level-zero-gpu_${LEVEL_ZERO_VERSION}_amd64.deb \
|
-LO https://github.com/intel/compute-runtime/releases/download/${NEO_VERSION}/libigdgmm12_${GMMLIB_VERSION}_amd64.deb \
|
||||||
&& dpkg -i *.deb \
|
&& dpkg -i *.deb \
|
||||||
&& cd .. \
|
&& cd .. \
|
||||||
&& rm -rf intel-compute-runtime \
|
&& rm -rf intel-compute-runtime \
|
||||||
&& apt-get remove gnupg wget -y \
|
&& apt-get remove gnupg -y \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
&& apt-get autoremove -y \
|
&& apt-get autoremove -y \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /cache /config /media \
|
&& mkdir -p ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& chmod 777 /cache /config /media \
|
&& chmod 777 ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||||
|
|
||||||
# ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
ENV LC_ALL=en_US.UTF-8
|
||||||
ENV LC_ALL en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
ENV LANG en_US.UTF-8
|
ENV LANGUAGE=en_US:en
|
||||||
ENV LANGUAGE en_US:en
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||||
WORKDIR /repo
|
WORKDIR /repo
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
# because of changes in docker and systemd we need to not build in parallel at the moment
|
|
||||||
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none
|
||||||
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none
|
|
||||||
|
|
||||||
FROM app
|
FROM app
|
||||||
|
|
||||||
|
@ -83,10 +79,8 @@ COPY --from=builder /jellyfin /jellyfin
|
||||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||||
|
|
||||||
EXPOSE 8096
|
EXPOSE 8096
|
||||||
VOLUME /cache /config
|
VOLUME ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR}
|
||||||
ENTRYPOINT [ "./jellyfin/jellyfin", \
|
ENTRYPOINT [ "./jellyfin/jellyfin", \
|
||||||
"--datadir", "/config", \
|
|
||||||
"--cachedir", "/cache", \
|
|
||||||
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg" ]
|
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg" ]
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
||||||
|
|
|
@ -4,64 +4,58 @@
|
||||||
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
|
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
|
||||||
ARG DOTNET_VERSION=8.0
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
|
||||||
FROM node:20-alpine as web-builder
|
FROM node:20-alpine as web-builder
|
||||||
ARG JELLYFIN_WEB_VERSION=master
|
ARG JELLYFIN_WEB_VERSION=master
|
||||||
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
||||||
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
||||||
|
&& apk del curl \
|
||||||
&& cd jellyfin-web-* \
|
&& cd jellyfin-web-* \
|
||||||
&& npm ci --no-audit --unsafe-perm \
|
&& npm ci --no-audit --unsafe-perm \
|
||||||
&& npm run build:production \
|
&& npm run build:production \
|
||||||
&& mv dist /dist
|
&& mv dist /dist
|
||||||
|
|
||||||
FROM multiarch/qemu-user-static:x86_64-arm as qemu
|
FROM multiarch/qemu-user-static:x86_64-arm as qemu
|
||||||
FROM arm32v7/debian:stable-slim as app
|
FROM arm32v7/debian:bookworm-slim as app
|
||||||
|
|
||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND="noninteractive"
|
ARG DEBIAN_FRONTEND="noninteractive"
|
||||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||||
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
||||||
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
||||||
|
ENV NVIDIA_VISIBLE_DEVICES="all"
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||||
|
|
||||||
|
ENV JELLYFIN_DATA_DIR=/config
|
||||||
|
ENV JELLYFIN_CACHE_DIR=/cache
|
||||||
|
|
||||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
|
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
|
||||||
|
|
||||||
# curl: setup & healthcheck
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl && \
|
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl \
|
||||||
curl -ks https://repo.jellyfin.org/debian/jellyfin_team.gpg.key | apt-key add - && \
|
&& curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg \
|
||||||
curl -ks https://keyserver.ubuntu.com/pks/lookup?op=get\&search=0x6587ffd6536b8826e88a62547876ae518cbcf2f2 | apt-key add - && \
|
&& curl -fsSL https://keyserver.ubuntu.com/pks/lookup?op=get\&search=0x6587ffd6536b8826e88a62547876ae518cbcf2f2 | gpg --dearmor -o /etc/apt/trusted.gpg.d/ubuntu-jellyfin.gpg \
|
||||||
echo 'deb [arch=armhf] https://repo.jellyfin.org/debian buster main' > /etc/apt/sources.list.d/jellyfin.list && \
|
&& echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | tee /etc/apt/sources.list.d/jellyfin.list \
|
||||||
echo "deb http://ppa.launchpad.net/ubuntu-raspi2/ppa/ubuntu bionic main">> /etc/apt/sources.list.d/raspbins.list && \
|
&& apt-get update \
|
||||||
apt-get update && \
|
&& apt-get install --no-install-recommends --no-install-suggests -y \
|
||||||
apt-get install --no-install-recommends --no-install-suggests -y \
|
jellyfin-ffmpeg6 libssl-dev libfontconfig1 \
|
||||||
jellyfin-ffmpeg \
|
libfreetype6 vainfo libva2 locales \
|
||||||
libssl-dev \
|
|
||||||
libfontconfig1 \
|
|
||||||
libfreetype6 \
|
|
||||||
vainfo \
|
|
||||||
libva2 \
|
|
||||||
locales \
|
|
||||||
&& apt-get remove gnupg -y \
|
&& apt-get remove gnupg -y \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
&& apt-get autoremove -y \
|
&& apt-get autoremove -y \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /cache /config /media \
|
&& mkdir -p ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& chmod 777 /cache /config /media \
|
&& chmod 777 ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||||
|
|
||||||
# ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
ENV LC_ALL=en_US.UTF-8
|
||||||
ENV LC_ALL en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
ENV LANG en_US.UTF-8
|
ENV LANGUAGE=en_US:en
|
||||||
ENV LANGUAGE en_US:en
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||||
WORKDIR /repo
|
WORKDIR /repo
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
# Discard objs - may cause failures if exists
|
|
||||||
RUN find . -type d -name obj | xargs -r rm -r
|
|
||||||
# Build
|
|
||||||
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none
|
||||||
|
|
||||||
FROM app
|
FROM app
|
||||||
|
@ -72,10 +66,8 @@ COPY --from=builder /jellyfin /jellyfin
|
||||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||||
|
|
||||||
EXPOSE 8096
|
EXPOSE 8096
|
||||||
VOLUME /cache /config
|
VOLUME ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR}
|
||||||
ENTRYPOINT ["./jellyfin/jellyfin", \
|
ENTRYPOINT [ "/jellyfin/jellyfin", \
|
||||||
"--datadir", "/config", \
|
|
||||||
"--cachedir", "/cache", \
|
|
||||||
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg" ]
|
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg" ]
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
||||||
|
|
|
@ -4,58 +4,58 @@
|
||||||
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
|
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
|
||||||
ARG DOTNET_VERSION=8.0
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
|
||||||
FROM node:20-alpine as web-builder
|
FROM node:20-alpine as web-builder
|
||||||
ARG JELLYFIN_WEB_VERSION=master
|
ARG JELLYFIN_WEB_VERSION=master
|
||||||
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \
|
||||||
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
|
||||||
|
&& apk del curl \
|
||||||
&& cd jellyfin-web-* \
|
&& cd jellyfin-web-* \
|
||||||
&& npm ci --no-audit --unsafe-perm \
|
&& npm ci --no-audit --unsafe-perm \
|
||||||
&& npm run build:production \
|
&& npm run build:production \
|
||||||
&& mv dist /dist
|
&& mv dist /dist
|
||||||
|
|
||||||
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
|
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
|
||||||
FROM arm64v8/debian:stable-slim as app
|
FROM arm64v8/debian:bookworm-slim as app
|
||||||
|
|
||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND="noninteractive"
|
ARG DEBIAN_FRONTEND="noninteractive"
|
||||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||||
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
||||||
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
||||||
|
ENV NVIDIA_VISIBLE_DEVICES="all"
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||||
|
|
||||||
|
ENV JELLYFIN_DATA_DIR=/config
|
||||||
|
ENV JELLYFIN_CACHE_DIR=/cache
|
||||||
|
|
||||||
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
|
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin
|
||||||
|
|
||||||
# curl: healcheck
|
RUN apt-get update \
|
||||||
RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y \
|
&& apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg curl \
|
||||||
ffmpeg \
|
&& curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg \
|
||||||
libssl-dev \
|
&& curl -fsSL https://keyserver.ubuntu.com/pks/lookup?op=get\&search=0x6587ffd6536b8826e88a62547876ae518cbcf2f2 | gpg --dearmor -o /etc/apt/trusted.gpg.d/ubuntu-jellyfin.gpg \
|
||||||
ca-certificates \
|
&& echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | tee /etc/apt/sources.list.d/jellyfin.list \
|
||||||
libfontconfig1 \
|
&& apt-get update \
|
||||||
libfreetype6 \
|
&& apt-get install --no-install-recommends --no-install-suggests -y \
|
||||||
libomxil-bellagio0 \
|
jellyfin-ffmpeg6 locales libssl-dev libfontconfig1 \
|
||||||
libomxil-bellagio-bin \
|
libfreetype6 libomxil-bellagio0 libomxil-bellagio-bin \
|
||||||
locales \
|
&& apt-get remove gnupg -y \
|
||||||
curl \
|
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
&& apt-get autoremove -y \
|
&& apt-get autoremove -y \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /cache /config /media \
|
&& mkdir -p ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& chmod 777 /cache /config /media \
|
&& chmod 777 ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR} \
|
||||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||||
|
|
||||||
# ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
ENV LC_ALL=en_US.UTF-8
|
||||||
ENV LC_ALL en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
ENV LANG en_US.UTF-8
|
ENV LANGUAGE=en_US:en
|
||||||
ENV LANGUAGE en_US:en
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder
|
||||||
WORKDIR /repo
|
WORKDIR /repo
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
# Discard objs - may cause failures if exists
|
|
||||||
RUN find . -type d -name obj | xargs -r rm -r
|
|
||||||
# Build
|
|
||||||
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none
|
||||||
|
|
||||||
FROM app
|
FROM app
|
||||||
|
@ -66,11 +66,9 @@ COPY --from=builder /jellyfin /jellyfin
|
||||||
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
COPY --from=web-builder /dist /jellyfin/jellyfin-web
|
||||||
|
|
||||||
EXPOSE 8096
|
EXPOSE 8096
|
||||||
VOLUME /cache /config
|
VOLUME ${JELLYFIN_DATA_DIR} ${JELLYFIN_CACHE_DIR}
|
||||||
ENTRYPOINT ["./jellyfin/jellyfin", \
|
ENTRYPOINT [ "/jellyfin/jellyfin", \
|
||||||
"--datadir", "/config", \
|
"--ffmpeg", "/usr/lib/jellyfin-ffmpeg/ffmpeg" ]
|
||||||
"--cachedir", "/cache", \
|
|
||||||
"--ffmpeg", "/usr/bin/ffmpeg"]
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=3 \
|
||||||
CMD curl -Lk -fsS "${HEALTHCHECK_URL}" || exit 1
|
CMD curl -Lk -fsS "${HEALTHCHECK_URL}" || exit 1
|
||||||
|
|
|
@ -695,7 +695,7 @@ namespace Emby.Server.Implementations
|
||||||
GetExports<IMetadataSaver>(),
|
GetExports<IMetadataSaver>(),
|
||||||
GetExports<IExternalId>());
|
GetExports<IExternalId>());
|
||||||
|
|
||||||
Resolve<ILiveTvManager>().AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
|
Resolve<ILiveTvManager>().AddParts(GetExports<ILiveTvService>(), GetExports<IListingsProvider>());
|
||||||
|
|
||||||
Resolve<IMediaSourceManager>().AddParts(GetExports<IMediaSourceProvider>());
|
Resolve<IMediaSourceManager>().AddParts(GetExports<IMediaSourceProvider>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,7 +699,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
saveItemStatement.TryBindNull("@EndDate");
|
saveItemStatement.TryBindNull("@EndDate");
|
||||||
}
|
}
|
||||||
|
|
||||||
saveItemStatement.TryBind("@ChannelId", item.ChannelId.Equals(default) ? null : item.ChannelId.ToString("N", CultureInfo.InvariantCulture));
|
saveItemStatement.TryBind("@ChannelId", item.ChannelId.IsEmpty() ? null : item.ChannelId.ToString("N", CultureInfo.InvariantCulture));
|
||||||
|
|
||||||
if (item is IHasProgramAttributes hasProgramAttributes)
|
if (item is IHasProgramAttributes hasProgramAttributes)
|
||||||
{
|
{
|
||||||
|
@ -729,7 +729,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
saveItemStatement.TryBind("@ProductionYear", item.ProductionYear);
|
saveItemStatement.TryBind("@ProductionYear", item.ProductionYear);
|
||||||
|
|
||||||
var parentId = item.ParentId;
|
var parentId = item.ParentId;
|
||||||
if (parentId.Equals(default))
|
if (parentId.IsEmpty())
|
||||||
{
|
{
|
||||||
saveItemStatement.TryBindNull("@ParentId");
|
saveItemStatement.TryBindNull("@ParentId");
|
||||||
}
|
}
|
||||||
|
@ -925,7 +925,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
saveItemStatement.TryBind("@SeasonName", episode.SeasonName);
|
saveItemStatement.TryBind("@SeasonName", episode.SeasonName);
|
||||||
|
|
||||||
var nullableSeasonId = episode.SeasonId.Equals(default) ? (Guid?)null : episode.SeasonId;
|
var nullableSeasonId = episode.SeasonId.IsEmpty() ? (Guid?)null : episode.SeasonId;
|
||||||
|
|
||||||
saveItemStatement.TryBind("@SeasonId", nullableSeasonId);
|
saveItemStatement.TryBind("@SeasonId", nullableSeasonId);
|
||||||
}
|
}
|
||||||
|
@ -937,7 +937,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
if (item is IHasSeries hasSeries)
|
if (item is IHasSeries hasSeries)
|
||||||
{
|
{
|
||||||
var nullableSeriesId = hasSeries.SeriesId.Equals(default) ? (Guid?)null : hasSeries.SeriesId;
|
var nullableSeriesId = hasSeries.SeriesId.IsEmpty() ? (Guid?)null : hasSeries.SeriesId;
|
||||||
|
|
||||||
saveItemStatement.TryBind("@SeriesId", nullableSeriesId);
|
saveItemStatement.TryBind("@SeriesId", nullableSeriesId);
|
||||||
saveItemStatement.TryBind("@SeriesPresentationUniqueKey", hasSeries.SeriesPresentationUniqueKey);
|
saveItemStatement.TryBind("@SeriesPresentationUniqueKey", hasSeries.SeriesPresentationUniqueKey);
|
||||||
|
@ -1010,7 +1010,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
Guid ownerId = item.OwnerId;
|
Guid ownerId = item.OwnerId;
|
||||||
if (ownerId.Equals(default))
|
if (ownerId.IsEmpty())
|
||||||
{
|
{
|
||||||
saveItemStatement.TryBindNull("@OwnerId");
|
saveItemStatement.TryBindNull("@OwnerId");
|
||||||
}
|
}
|
||||||
|
@ -1266,7 +1266,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
/// <exception cref="ArgumentException"><paramr name="id"/> is <seealso cref="Guid.Empty"/>.</exception>
|
/// <exception cref="ArgumentException"><paramr name="id"/> is <seealso cref="Guid.Empty"/>.</exception>
|
||||||
public BaseItem RetrieveItem(Guid id)
|
public BaseItem RetrieveItem(Guid id)
|
||||||
{
|
{
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||||
}
|
}
|
||||||
|
@ -1970,7 +1970,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
@ -3230,7 +3230,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
whereClauses.Add($"ChannelId in ({inClause})");
|
whereClauses.Add($"ChannelId in ({inClause})");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.ParentId.Equals(default))
|
if (!query.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
whereClauses.Add("ParentId=@ParentId");
|
whereClauses.Add("ParentId=@ParentId");
|
||||||
statement?.TryBind("@ParentId", query.ParentId);
|
statement?.TryBind("@ParentId", query.ParentId);
|
||||||
|
@ -4452,7 +4452,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
||||||
|
|
||||||
public void DeleteItem(Guid id)
|
public void DeleteItem(Guid id)
|
||||||
{
|
{
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
@ -4583,13 +4583,13 @@ AND Type = @InternalPersonType)");
|
||||||
statement?.TryBind("@UserId", query.User.InternalId);
|
statement?.TryBind("@UserId", query.User.InternalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.ItemId.Equals(default))
|
if (!query.ItemId.IsEmpty())
|
||||||
{
|
{
|
||||||
whereClauses.Add("ItemId=@ItemId");
|
whereClauses.Add("ItemId=@ItemId");
|
||||||
statement?.TryBind("@ItemId", query.ItemId);
|
statement?.TryBind("@ItemId", query.ItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.AppearsInItemId.Equals(default))
|
if (!query.AppearsInItemId.IsEmpty())
|
||||||
{
|
{
|
||||||
whereClauses.Add("p.Name in (Select Name from People where ItemId=@AppearsInItemId)");
|
whereClauses.Add("p.Name in (Select Name from People where ItemId=@AppearsInItemId)");
|
||||||
statement?.TryBind("@AppearsInItemId", query.AppearsInItemId);
|
statement?.TryBind("@AppearsInItemId", query.AppearsInItemId);
|
||||||
|
@ -4640,7 +4640,7 @@ AND Type = @InternalPersonType)");
|
||||||
|
|
||||||
private void UpdateAncestors(Guid itemId, List<Guid> ancestorIds, SqliteConnection db, SqliteCommand deleteAncestorsStatement)
|
private void UpdateAncestors(Guid itemId, List<Guid> ancestorIds, SqliteConnection db, SqliteCommand deleteAncestorsStatement)
|
||||||
{
|
{
|
||||||
if (itemId.Equals(default))
|
if (itemId.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
@ -5156,7 +5156,7 @@ AND Type = @InternalPersonType)");
|
||||||
|
|
||||||
private void UpdateItemValues(Guid itemId, List<(int MagicNumber, string Value)> values, SqliteConnection db)
|
private void UpdateItemValues(Guid itemId, List<(int MagicNumber, string Value)> values, SqliteConnection db)
|
||||||
{
|
{
|
||||||
if (itemId.Equals(default))
|
if (itemId.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
@ -5228,7 +5228,7 @@ AND Type = @InternalPersonType)");
|
||||||
|
|
||||||
public void UpdatePeople(Guid itemId, List<PersonInfo> people)
|
public void UpdatePeople(Guid itemId, List<PersonInfo> people)
|
||||||
{
|
{
|
||||||
if (itemId.Equals(default))
|
if (itemId.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
@ -5378,7 +5378,7 @@ AND Type = @InternalPersonType)");
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
@ -5758,7 +5758,7 @@ AND Type = @InternalPersonType)");
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Guid can't be empty.", nameof(id));
|
throw new ArgumentException("Guid can't be empty.", nameof(id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Events;
|
using Jellyfin.Data.Events;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -241,7 +242,7 @@ public sealed class LibraryChangedNotifier : IServerEntryPoint
|
||||||
{
|
{
|
||||||
var userIds = _sessionManager.Sessions
|
var userIds = _sessionManager.Sessions
|
||||||
.Select(i => i.UserId)
|
.Select(i => i.UserId)
|
||||||
.Where(i => !i.Equals(default))
|
.Where(i => !i.IsEmpty())
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|
|
@ -732,7 +732,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
Path = path
|
Path = path
|
||||||
};
|
};
|
||||||
|
|
||||||
if (folder.Id.Equals(default))
|
if (folder.Id.IsEmpty())
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(folder.Path))
|
if (string.IsNullOrEmpty(folder.Path))
|
||||||
{
|
{
|
||||||
|
@ -1219,7 +1219,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="id"/> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="id"/> is <c>null</c>.</exception>
|
||||||
public BaseItem GetItemById(Guid id)
|
public BaseItem GetItemById(Guid id)
|
||||||
{
|
{
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||||
}
|
}
|
||||||
|
@ -1241,7 +1241,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
||||||
{
|
{
|
||||||
if (query.Recursive && !query.ParentId.Equals(default))
|
if (query.Recursive && !query.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var parent = GetItemById(query.ParentId);
|
var parent = GetItemById(query.ParentId);
|
||||||
if (parent is not null)
|
if (parent is not null)
|
||||||
|
@ -1272,7 +1272,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public int GetCount(InternalItemsQuery query)
|
public int GetCount(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.Recursive && !query.ParentId.Equals(default))
|
if (query.Recursive && !query.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var parent = GetItemById(query.ParentId);
|
var parent = GetItemById(query.ParentId);
|
||||||
if (parent is not null)
|
if (parent is not null)
|
||||||
|
@ -1430,7 +1430,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
|
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.Recursive && !query.ParentId.Equals(default))
|
if (query.Recursive && !query.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var parent = GetItemById(query.ParentId);
|
var parent = GetItemById(query.ParentId);
|
||||||
if (parent is not null)
|
if (parent is not null)
|
||||||
|
@ -1486,7 +1486,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
private void AddUserToQuery(InternalItemsQuery query, User user, bool allowExternalContent = true)
|
private void AddUserToQuery(InternalItemsQuery query, User user, bool allowExternalContent = true)
|
||||||
{
|
{
|
||||||
if (query.AncestorIds.Length == 0 &&
|
if (query.AncestorIds.Length == 0 &&
|
||||||
query.ParentId.Equals(default) &&
|
query.ParentId.IsEmpty() &&
|
||||||
query.ChannelIds.Count == 0 &&
|
query.ChannelIds.Count == 0 &&
|
||||||
query.TopParentIds.Length == 0 &&
|
query.TopParentIds.Length == 0 &&
|
||||||
string.IsNullOrEmpty(query.AncestorWithPresentationUniqueKey) &&
|
string.IsNullOrEmpty(query.AncestorWithPresentationUniqueKey) &&
|
||||||
|
@ -1520,7 +1520,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate view into folders
|
// Translate view into folders
|
||||||
if (!view.DisplayParentId.Equals(default))
|
if (!view.DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var displayParent = GetItemById(view.DisplayParentId);
|
var displayParent = GetItemById(view.DisplayParentId);
|
||||||
if (displayParent is not null)
|
if (displayParent is not null)
|
||||||
|
@ -1531,7 +1531,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
return Array.Empty<Guid>();
|
return Array.Empty<Guid>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!view.ParentId.Equals(default))
|
if (!view.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var displayParent = GetItemById(view.ParentId);
|
var displayParent = GetItemById(view.ParentId);
|
||||||
if (displayParent is not null)
|
if (displayParent is not null)
|
||||||
|
@ -2137,7 +2137,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!item.ParentId.Equals(default))
|
while (!item.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var parent = item.GetParent();
|
var parent = item.GetParent();
|
||||||
if (parent is null || parent is AggregateFolder)
|
if (parent is null || parent is AggregateFolder)
|
||||||
|
@ -2215,7 +2215,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
CollectionType? viewType,
|
CollectionType? viewType,
|
||||||
string sortName)
|
string sortName)
|
||||||
{
|
{
|
||||||
var parentIdString = parentId.Equals(default)
|
var parentIdString = parentId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: parentId.ToString("N", CultureInfo.InvariantCulture);
|
: parentId.ToString("N", CultureInfo.InvariantCulture);
|
||||||
var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
|
var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
|
||||||
|
@ -2251,7 +2251,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
||||||
|
|
||||||
if (!refresh && !item.DisplayParentId.Equals(default))
|
if (!refresh && !item.DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var displayParent = GetItemById(item.DisplayParentId);
|
var displayParent = GetItemById(item.DisplayParentId);
|
||||||
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
||||||
|
@ -2315,7 +2315,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
||||||
|
|
||||||
if (!refresh && !item.DisplayParentId.Equals(default))
|
if (!refresh && !item.DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var displayParent = GetItemById(item.DisplayParentId);
|
var displayParent = GetItemById(item.DisplayParentId);
|
||||||
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
||||||
|
@ -2345,7 +2345,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
ArgumentException.ThrowIfNullOrEmpty(name);
|
ArgumentException.ThrowIfNullOrEmpty(name);
|
||||||
|
|
||||||
var parentIdString = parentId.Equals(default)
|
var parentIdString = parentId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: parentId.ToString("N", CultureInfo.InvariantCulture);
|
: parentId.ToString("N", CultureInfo.InvariantCulture);
|
||||||
var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
|
var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
|
||||||
|
@ -2391,7 +2391,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
|
||||||
|
|
||||||
if (!refresh && !item.DisplayParentId.Equals(default))
|
if (!refresh && !item.DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var displayParent = GetItemById(item.DisplayParentId);
|
var displayParent = GetItemById(item.DisplayParentId);
|
||||||
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
refresh = displayParent is not null && displayParent.DateLastSaved > item.DateLastRefreshed;
|
||||||
|
@ -2419,7 +2419,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
return GetItemById(parentId.Value);
|
return GetItemById(parentId.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId.HasValue && !userId.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return GetUserRootFolder();
|
return GetUserRootFolder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using Jellyfin.Extensions.Json;
|
using Jellyfin.Extensions.Json;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
|
@ -524,10 +525,10 @@ namespace Emby.Server.Implementations.Library
|
||||||
_logger.LogInformation("Live stream opened: {@MediaSource}", mediaSource);
|
_logger.LogInformation("Live stream opened: {@MediaSource}", mediaSource);
|
||||||
var clone = JsonSerializer.Deserialize<MediaSourceInfo>(json, _jsonOptions);
|
var clone = JsonSerializer.Deserialize<MediaSourceInfo>(json, _jsonOptions);
|
||||||
|
|
||||||
if (!request.UserId.Equals(default))
|
if (!request.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(request.UserId);
|
var user = _userManager.GetUserById(request.UserId);
|
||||||
var item = request.ItemId.Equals(default)
|
var item = request.ItemId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: _libraryManager.GetItemById(request.ItemId);
|
: _libraryManager.GetItemById(request.ItemId);
|
||||||
SetDefaultAudioAndSubtitleStreamIndexes(item, clone, user);
|
SetDefaultAudioAndSubtitleStreamIndexes(item, clone, user);
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
@ -80,7 +81,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
return Guid.Empty;
|
return Guid.Empty;
|
||||||
}
|
}
|
||||||
}).Where(i => !i.Equals(default)).ToArray();
|
}).Where(i => !i.IsEmpty()).ToArray();
|
||||||
|
|
||||||
return GetInstantMixFromGenreIds(genreIds, user, dtoOptions);
|
return GetInstantMixFromGenreIds(genreIds, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
public QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query)
|
public QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query)
|
||||||
{
|
{
|
||||||
User user = null;
|
User user = null;
|
||||||
if (!query.UserId.Equals(default))
|
if (!query.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
user = _userManager.GetUserById(query.UserId);
|
user = _userManager.GetUserById(query.UserId);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
if (searchQuery.IncludeItemTypes.Length == 1 && searchQuery.IncludeItemTypes[0] == BaseItemKind.MusicArtist)
|
if (searchQuery.IncludeItemTypes.Length == 1 && searchQuery.IncludeItemTypes[0] == BaseItemKind.MusicArtist)
|
||||||
{
|
{
|
||||||
if (!searchQuery.ParentId.Equals(default))
|
if (!searchQuery.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
searchQuery.AncestorIds = new[] { searchQuery.ParentId };
|
searchQuery.AncestorIds = new[] { searchQuery.ParentId };
|
||||||
searchQuery.ParentId = Guid.Empty;
|
searchQuery.ParentId = Guid.Empty;
|
||||||
|
|
|
@ -8,6 +8,7 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
|
@ -151,7 +152,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
var index = Array.IndexOf(orders, i.Id);
|
var index = Array.IndexOf(orders, i.Id);
|
||||||
if (index == -1
|
if (index == -1
|
||||||
&& i is UserView view
|
&& i is UserView view
|
||||||
&& !view.DisplayParentId.Equals(default))
|
&& !view.DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
index = Array.IndexOf(orders, view.DisplayParentId);
|
index = Array.IndexOf(orders, view.DisplayParentId);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +254,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
var parents = new List<BaseItem>();
|
var parents = new List<BaseItem>();
|
||||||
|
|
||||||
if (!parentId.Equals(default))
|
if (!parentId.IsEmpty())
|
||||||
{
|
{
|
||||||
var parentItem = _libraryManager.GetItemById(parentId);
|
var parentItem = _libraryManager.GetItemById(parentId);
|
||||||
if (parentItem is Channel)
|
if (parentItem is Channel)
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
"HeaderFavoriteAlbums": "რჩეული ალბომები",
|
"HeaderFavoriteAlbums": "რჩეული ალბომები",
|
||||||
"TasksApplicationCategory": "აპლიკაცია",
|
"TasksApplicationCategory": "აპლიკაცია",
|
||||||
"Albums": "ალბომები",
|
"Albums": "ალბომები",
|
||||||
"AppDeviceValues": "აპი: {0}, მოწყობილობა: {1}",
|
"AppDeviceValues": "აპლიკაცია: {0}, მოწყობილობა: {1}",
|
||||||
"Application": "აპლიკაცია",
|
"Application": "აპლიკაცია",
|
||||||
"Artists": "შემსრულებლები",
|
"Artists": "არტისტი",
|
||||||
"AuthenticationSucceededWithUserName": "{0} -ის ავთენტიკაცია წარმატებულია",
|
"AuthenticationSucceededWithUserName": "{0} -ის ავთენტიკაცია წარმატებულია",
|
||||||
"Books": "წიგნები",
|
"Books": "წიგნები",
|
||||||
"Forced": "ძალით",
|
"Forced": "ძალით",
|
||||||
|
|
|
@ -83,13 +83,13 @@
|
||||||
"UserDeletedWithName": "用戶 {0} 已被移除",
|
"UserDeletedWithName": "用戶 {0} 已被移除",
|
||||||
"UserDownloadingItemWithValues": "{0} 正在下載 {1}",
|
"UserDownloadingItemWithValues": "{0} 正在下載 {1}",
|
||||||
"UserLockedOutWithName": "用戶 {0} 已被封鎖",
|
"UserLockedOutWithName": "用戶 {0} 已被封鎖",
|
||||||
"UserOfflineFromDevice": "{0} 從 {1} 斷開連接",
|
"UserOfflineFromDevice": "{0} 終止了 {1} 的連接",
|
||||||
"UserOnlineFromDevice": "{0} 從 {1} 連線",
|
"UserOnlineFromDevice": "{0} 從 {1} 連線",
|
||||||
"UserPasswordChangedWithName": "{0} 的密碼已被變改",
|
"UserPasswordChangedWithName": "{0} 的密碼已被更改",
|
||||||
"UserPolicyUpdatedWithName": "使用條款已更新為 {0}",
|
"UserPolicyUpdatedWithName": "使用條款已更新為 {0}",
|
||||||
"UserStartedPlayingItemWithValues": "{0} 在 {2} 上播放 {1}",
|
"UserStartedPlayingItemWithValues": "{0} 在 {2} 上播放 {1}",
|
||||||
"UserStoppedPlayingItemWithValues": "{0} 已停止在 {2} 上播放 {1}",
|
"UserStoppedPlayingItemWithValues": "{0} 停止在 {2} 上播放 {1}",
|
||||||
"ValueHasBeenAddedToLibrary": "已添加 {0} 到你的媒體庫",
|
"ValueHasBeenAddedToLibrary": "{0} 已被加入至你的媒體庫",
|
||||||
"ValueSpecialEpisodeName": "特典 - {0}",
|
"ValueSpecialEpisodeName": "特典 - {0}",
|
||||||
"VersionNumber": "版本 {0}",
|
"VersionNumber": "版本 {0}",
|
||||||
"TaskDownloadMissingSubtitles": "下載欠缺字幕",
|
"TaskDownloadMissingSubtitles": "下載欠缺字幕",
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
@ -178,7 +179,7 @@ namespace Emby.Server.Implementations.Playlists
|
||||||
|
|
||||||
public Task AddToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId)
|
public Task AddToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId)
|
||||||
{
|
{
|
||||||
var user = userId.Equals(default) ? null : _userManager.GetUserById(userId);
|
var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId);
|
||||||
|
|
||||||
return AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false)
|
return AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,9 +115,10 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask
|
||||||
List<LinkedChild>? itemsToRemove = null;
|
List<LinkedChild>? itemsToRemove = null;
|
||||||
foreach (var linkedChild in folder.LinkedChildren)
|
foreach (var linkedChild in folder.LinkedChildren)
|
||||||
{
|
{
|
||||||
if (!File.Exists(folder.Path))
|
var path = linkedChild.Path;
|
||||||
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Item in {FolderName} cannot be found at {ItemPath}", folder.Name, linkedChild.Path);
|
_logger.LogInformation("Item in {FolderName} cannot be found at {ItemPath}", folder.Name, path);
|
||||||
(itemsToRemove ??= new List<LinkedChild>()).Add(linkedChild);
|
(itemsToRemove ??= new List<LinkedChild>()).Add(linkedChild);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,7 +337,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture);
|
info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.ItemId.Equals(default) && info.Item is null && libraryItem is not null)
|
if (!info.ItemId.IsEmpty() && info.Item is null && libraryItem is not null)
|
||||||
{
|
{
|
||||||
var current = session.NowPlayingItem;
|
var current = session.NowPlayingItem;
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
var users = new List<User>();
|
var users = new List<User>();
|
||||||
|
|
||||||
if (session.UserId.Equals(default))
|
if (session.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +690,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
var session = GetSession(info.SessionId);
|
var session = GetSession(info.SessionId);
|
||||||
|
|
||||||
var libraryItem = info.ItemId.Equals(default)
|
var libraryItem = info.ItemId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: GetNowPlayingItem(session, info.ItemId);
|
: GetNowPlayingItem(session, info.ItemId);
|
||||||
|
|
||||||
|
@ -784,7 +784,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
var session = GetSession(info.SessionId);
|
var session = GetSession(info.SessionId);
|
||||||
|
|
||||||
var libraryItem = info.ItemId.Equals(default)
|
var libraryItem = info.ItemId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: GetNowPlayingItem(session, info.ItemId);
|
: GetNowPlayingItem(session, info.ItemId);
|
||||||
|
|
||||||
|
@ -923,7 +923,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
session.StopAutomaticProgress();
|
session.StopAutomaticProgress();
|
||||||
|
|
||||||
var libraryItem = info.ItemId.Equals(default)
|
var libraryItem = info.ItemId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: GetNowPlayingItem(session, info.ItemId);
|
: GetNowPlayingItem(session, info.ItemId);
|
||||||
|
|
||||||
|
@ -933,7 +933,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture);
|
info.MediaSourceId = info.ItemId.ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.ItemId.Equals(default) && info.Item is null && libraryItem is not null)
|
if (!info.ItemId.IsEmpty() && info.Item is null && libraryItem is not null)
|
||||||
{
|
{
|
||||||
var current = session.NowPlayingItem;
|
var current = session.NowPlayingItem;
|
||||||
|
|
||||||
|
@ -1154,7 +1154,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
var session = GetSessionToRemoteControl(sessionId);
|
var session = GetSessionToRemoteControl(sessionId);
|
||||||
|
|
||||||
var user = session.UserId.Equals(default) ? null : _userManager.GetUserById(session.UserId);
|
var user = session.UserId.IsEmpty() ? null : _userManager.GetUserById(session.UserId);
|
||||||
|
|
||||||
List<BaseItem> items;
|
List<BaseItem> items;
|
||||||
|
|
||||||
|
@ -1223,7 +1223,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
var controllingSession = GetSession(controllingSessionId);
|
var controllingSession = GetSession(controllingSessionId);
|
||||||
AssertCanControl(session, controllingSession);
|
AssertCanControl(session, controllingSession);
|
||||||
if (!controllingSession.UserId.Equals(default))
|
if (!controllingSession.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
command.ControllingUserId = controllingSession.UserId;
|
command.ControllingUserId = controllingSession.UserId;
|
||||||
}
|
}
|
||||||
|
@ -1342,7 +1342,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
var controllingSession = GetSession(controllingSessionId);
|
var controllingSession = GetSession(controllingSessionId);
|
||||||
AssertCanControl(session, controllingSession);
|
AssertCanControl(session, controllingSession);
|
||||||
if (!controllingSession.UserId.Equals(default))
|
if (!controllingSession.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
command.ControllingUserId = controllingSession.UserId.ToString("N", CultureInfo.InvariantCulture);
|
command.ControllingUserId = controllingSession.UserId.ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
@ -1463,7 +1463,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
ArgumentException.ThrowIfNullOrEmpty(request.AppVersion);
|
ArgumentException.ThrowIfNullOrEmpty(request.AppVersion);
|
||||||
|
|
||||||
User user = null;
|
User user = null;
|
||||||
if (!request.UserId.Equals(default))
|
if (!request.UserId.IsEmpty())
|
||||||
{
|
{
|
||||||
user = _userManager.GetUserById(request.UserId);
|
user = _userManager.GetUserById(request.UserId);
|
||||||
}
|
}
|
||||||
|
@ -1766,7 +1766,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
|
|
||||||
var user = info.UserId.Equals(default)
|
var user = info.UserId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(info.UserId);
|
: _userManager.GetUserById(info.UserId);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Controller.SyncPlay;
|
using MediaBrowser.Controller.SyncPlay;
|
||||||
|
@ -553,7 +554,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
||||||
if (playingItemRemoved)
|
if (playingItemRemoved)
|
||||||
{
|
{
|
||||||
var itemId = PlayQueue.GetPlayingItemId();
|
var itemId = PlayQueue.GetPlayingItemId();
|
||||||
if (!itemId.Equals(default))
|
if (!itemId.IsEmpty())
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(itemId);
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
RunTimeTicks = item.RunTimeTicks ?? 0;
|
RunTimeTicks = item.RunTimeTicks ?? 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -41,7 +42,7 @@ namespace Emby.Server.Implementations.TV
|
||||||
}
|
}
|
||||||
|
|
||||||
string? presentationUniqueKey = null;
|
string? presentationUniqueKey = null;
|
||||||
if (query.SeriesId.HasValue && !query.SeriesId.Value.Equals(default))
|
if (!query.SeriesId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
if (_libraryManager.GetItemById(query.SeriesId.Value) is Series series)
|
if (_libraryManager.GetItemById(query.SeriesId.Value) is Series series)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.TV
|
||||||
|
|
||||||
string? presentationUniqueKey = null;
|
string? presentationUniqueKey = null;
|
||||||
int? limit = null;
|
int? limit = null;
|
||||||
if (request.SeriesId.HasValue && !request.SeriesId.Value.Equals(default))
|
if (!request.SeriesId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
if (_libraryManager.GetItemById(request.SeriesId.Value) is Series series)
|
if (_libraryManager.GetItemById(request.SeriesId.Value) is Series series)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +147,7 @@ namespace Emby.Server.Implementations.TV
|
||||||
|
|
||||||
// If viewing all next up for all series, remove first episodes
|
// If viewing all next up for all series, remove first episodes
|
||||||
// But if that returns empty, keep those first episodes (avoid completely empty view)
|
// But if that returns empty, keep those first episodes (avoid completely empty view)
|
||||||
var alwaysEnableFirstEpisode = request.SeriesId.HasValue && !request.SeriesId.Value.Equals(default);
|
var alwaysEnableFirstEpisode = !request.SeriesId.IsNullOrEmpty();
|
||||||
var anyFound = false;
|
var anyFound = false;
|
||||||
|
|
||||||
return allNextUp
|
return allNextUp
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Events;
|
using Jellyfin.Data.Events;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using Jellyfin.Extensions.Json;
|
using Jellyfin.Extensions.Json;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -227,7 +228,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
availablePackages = availablePackages.Where(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
availablePackages = availablePackages.Where(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!id.Equals(default))
|
if (!id.IsEmpty())
|
||||||
{
|
{
|
||||||
availablePackages = availablePackages.Where(x => x.Id.Equals(id));
|
availablePackages = availablePackages.Where(x => x.Id.Equals(id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -41,7 +42,7 @@ namespace Jellyfin.Api.Auth.DefaultAuthorizationPolicy
|
||||||
var isApiKey = context.User.GetIsApiKey();
|
var isApiKey = context.User.GetIsApiKey();
|
||||||
var userId = context.User.GetUserId();
|
var userId = context.User.GetUserId();
|
||||||
// This likely only happens during the wizard, so skip the default checks and let any other handlers do it
|
// This likely only happens during the wizard, so skip the default checks and let any other handlers do it
|
||||||
if (!isApiKey && userId.Equals(default))
|
if (!isApiKey && userId.IsEmpty())
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -46,7 +47,7 @@ namespace Jellyfin.Api.Auth.FirstTimeSetupPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
var userId = contextUser.GetUserId();
|
var userId = contextUser.GetUserId();
|
||||||
if (userId.Equals(default))
|
if (userId.IsEmpty())
|
||||||
{
|
{
|
||||||
context.Fail();
|
context.Fail();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -126,7 +127,7 @@ public class ArtistsController : BaseJellyfinApiController
|
||||||
User? user = null;
|
User? user = null;
|
||||||
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
user = _userManager.GetUserById(userId.Value);
|
user = _userManager.GetUserById(userId.Value);
|
||||||
}
|
}
|
||||||
|
@ -330,7 +331,7 @@ public class ArtistsController : BaseJellyfinApiController
|
||||||
User? user = null;
|
User? user = null;
|
||||||
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
user = _userManager.GetUserById(userId.Value);
|
user = _userManager.GetUserById(userId.Value);
|
||||||
}
|
}
|
||||||
|
@ -469,7 +470,7 @@ public class ArtistsController : BaseJellyfinApiController
|
||||||
|
|
||||||
var item = _libraryManager.GetArtist(name, dtoOptions);
|
var item = _libraryManager.GetArtist(name, dtoOptions);
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -126,7 +127,7 @@ public class ChannelsController : BaseJellyfinApiController
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -201,7 +202,7 @@ public class ChannelsController : BaseJellyfinApiController
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] channelIds)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] channelIds)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -53,7 +54,7 @@ public class FilterController : BaseJellyfinApiController
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] MediaType[] mediaTypes)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] MediaType[] mediaTypes)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ public class FilterController : BaseJellyfinApiController
|
||||||
[FromQuery] bool? recursive)
|
[FromQuery] bool? recursive)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -95,7 +96,7 @@ public class GenresController : BaseJellyfinApiController
|
||||||
.AddClientFields(User)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId.Value.Equals(default)
|
User? user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -172,7 +173,7 @@ public class GenresController : BaseJellyfinApiController
|
||||||
|
|
||||||
item ??= new Genre();
|
item ??= new Genre();
|
||||||
|
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -76,7 +77,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -113,7 +114,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var album = _libraryManager.GetItemById(id);
|
var album = _libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -150,7 +151,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var playlist = (Playlist)_libraryManager.GetItemById(id);
|
var playlist = (Playlist)_libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -186,7 +187,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -223,7 +224,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -260,7 +261,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
@ -334,7 +335,7 @@ public class InstantMixController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -245,7 +246,7 @@ public class ItemsController : BaseJellyfinApiController
|
||||||
var isApiKey = User.GetIsApiKey();
|
var isApiKey = User.GetIsApiKey();
|
||||||
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
|
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = !isApiKey && !userId.Value.Equals(default)
|
var user = !isApiKey && !userId.IsNullOrEmpty()
|
||||||
? _userManager.GetUserById(userId.Value) ?? throw new ResourceNotFoundException()
|
? _userManager.GetUserById(userId.Value) ?? throw new ResourceNotFoundException()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
@ -840,7 +841,7 @@ public class ItemsController : BaseJellyfinApiController
|
||||||
var ancestorIds = Array.Empty<Guid>();
|
var ancestorIds = Array.Empty<Guid>();
|
||||||
|
|
||||||
var excludeFolderIds = user.GetPreferenceValues<Guid>(PreferenceKind.LatestItemExcludes);
|
var excludeFolderIds = user.GetPreferenceValues<Guid>(PreferenceKind.LatestItemExcludes);
|
||||||
if (parentIdGuid.Equals(default) && excludeFolderIds.Length > 0)
|
if (parentIdGuid.IsEmpty() && excludeFolderIds.Length > 0)
|
||||||
{
|
{
|
||||||
ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true)
|
ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true)
|
||||||
.Where(i => i is Folder)
|
.Where(i => i is Folder)
|
||||||
|
|
|
@ -146,12 +146,12 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
[FromQuery] bool inheritFromParent = false)
|
[FromQuery] bool inheritFromParent = false)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? (userId.Value.Equals(default)
|
? (userId.IsNullOrEmpty()
|
||||||
? _libraryManager.RootFolder
|
? _libraryManager.RootFolder
|
||||||
: _libraryManager.GetUserRootFolder())
|
: _libraryManager.GetUserRootFolder())
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
@ -213,12 +213,12 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
[FromQuery] bool inheritFromParent = false)
|
[FromQuery] bool inheritFromParent = false)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? (userId.Value.Equals(default)
|
? (userId.IsNullOrEmpty()
|
||||||
? _libraryManager.RootFolder
|
? _libraryManager.RootFolder
|
||||||
: _libraryManager.GetUserRootFolder())
|
: _libraryManager.GetUserRootFolder())
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
@ -339,7 +339,7 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var isApiKey = User.GetIsApiKey();
|
var isApiKey = User.GetIsApiKey();
|
||||||
var userId = User.GetUserId();
|
var userId = User.GetUserId();
|
||||||
var user = !isApiKey && !userId.Equals(default)
|
var user = !isApiKey && !userId.IsEmpty()
|
||||||
? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
|
? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
|
||||||
: null;
|
: null;
|
||||||
if (!isApiKey && user is null)
|
if (!isApiKey && user is null)
|
||||||
|
@ -382,7 +382,7 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var isApiKey = User.GetIsApiKey();
|
var isApiKey = User.GetIsApiKey();
|
||||||
var userId = User.GetUserId();
|
var userId = User.GetUserId();
|
||||||
var user = !isApiKey && !userId.Equals(default)
|
var user = !isApiKey && !userId.IsEmpty()
|
||||||
? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
|
? _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
[FromQuery] bool? isFavorite)
|
[FromQuery] bool? isFavorite)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
|
|
||||||
var baseItemDtos = new List<BaseItemDto>();
|
var baseItemDtos = new List<BaseItemDto>();
|
||||||
|
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -702,8 +702,8 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? (userId.Value.Equals(default)
|
? (userId.IsNullOrEmpty()
|
||||||
? _libraryManager.RootFolder
|
? _libraryManager.RootFolder
|
||||||
: _libraryManager.GetUserRootFolder())
|
: _libraryManager.GetUserRootFolder())
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
@ -718,7 +718,7 @@ public class LibraryController : BaseJellyfinApiController
|
||||||
return new QueryResult<BaseItemDto>();
|
return new QueryResult<BaseItemDto>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
|
|
@ -10,12 +10,12 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Attributes;
|
using Jellyfin.Api.Attributes;
|
||||||
using Jellyfin.Api.Constants;
|
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.LiveTvDtos;
|
using Jellyfin.Api.Models.LiveTvDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Api;
|
using MediaBrowser.Common.Api;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -43,6 +43,7 @@ namespace Jellyfin.Api.Controllers;
|
||||||
public class LiveTvController : BaseJellyfinApiController
|
public class LiveTvController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
private readonly ILiveTvManager _liveTvManager;
|
private readonly ILiveTvManager _liveTvManager;
|
||||||
|
private readonly ITunerHostManager _tunerHostManager;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
@ -55,6 +56,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
/// Initializes a new instance of the <see cref="LiveTvController"/> class.
|
/// Initializes a new instance of the <see cref="LiveTvController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="liveTvManager">Instance of the <see cref="ILiveTvManager"/> interface.</param>
|
/// <param name="liveTvManager">Instance of the <see cref="ILiveTvManager"/> interface.</param>
|
||||||
|
/// <param name="tunerHostManager">Instance of the <see cref="ITunerHostManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
|
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
|
@ -64,6 +66,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
/// <param name="transcodeManager">Instance of the <see cref="ITranscodeManager"/> interface.</param>
|
/// <param name="transcodeManager">Instance of the <see cref="ITranscodeManager"/> interface.</param>
|
||||||
public LiveTvController(
|
public LiveTvController(
|
||||||
ILiveTvManager liveTvManager,
|
ILiveTvManager liveTvManager,
|
||||||
|
ITunerHostManager tunerHostManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
|
@ -73,6 +76,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
ITranscodeManager transcodeManager)
|
ITranscodeManager transcodeManager)
|
||||||
{
|
{
|
||||||
_liveTvManager = liveTvManager;
|
_liveTvManager = liveTvManager;
|
||||||
|
_tunerHostManager = tunerHostManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
@ -179,7 +183,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
dtoOptions,
|
dtoOptions,
|
||||||
CancellationToken.None);
|
CancellationToken.None);
|
||||||
|
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -211,10 +215,10 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
public ActionResult<BaseItemDto> GetChannel([FromRoute, Required] Guid channelId, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetChannel([FromRoute, Required] Guid channelId, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var item = channelId.Equals(default)
|
var item = channelId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(channelId);
|
: _libraryManager.GetItemById(channelId);
|
||||||
|
|
||||||
|
@ -384,7 +388,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
public async Task<ActionResult<QueryResult<BaseItemDto>>> GetRecordingFolders([FromQuery] Guid? userId)
|
public async Task<ActionResult<QueryResult<BaseItemDto>>> GetRecordingFolders([FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var folders = await _liveTvManager.GetRecordingFoldersAsync(user).ConfigureAwait(false);
|
var folders = await _liveTvManager.GetRecordingFoldersAsync(user).ConfigureAwait(false);
|
||||||
|
@ -407,10 +411,10 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
public ActionResult<BaseItemDto> GetRecording([FromRoute, Required] Guid recordingId, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetRecording([FromRoute, Required] Guid recordingId, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var item = recordingId.Equals(default) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
|
var item = recordingId.IsEmpty() ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(User);
|
.AddClientFields(User);
|
||||||
|
@ -564,7 +568,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -591,7 +595,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
GenreIds = genreIds
|
GenreIds = genreIds
|
||||||
};
|
};
|
||||||
|
|
||||||
if (librarySeriesId.HasValue && !librarySeriesId.Equals(default))
|
if (!librarySeriesId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
query.IsSeries = true;
|
query.IsSeries = true;
|
||||||
|
|
||||||
|
@ -620,7 +624,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[Authorize(Policy = Policies.LiveTvAccess)]
|
[Authorize(Policy = Policies.LiveTvAccess)]
|
||||||
public async Task<ActionResult<QueryResult<BaseItemDto>>> GetPrograms([FromBody] GetProgramsDto body)
|
public async Task<ActionResult<QueryResult<BaseItemDto>>> GetPrograms([FromBody] GetProgramsDto body)
|
||||||
{
|
{
|
||||||
var user = body.UserId.Equals(default) ? null : _userManager.GetUserById(body.UserId);
|
var user = body.UserId.IsEmpty() ? null : _userManager.GetUserById(body.UserId);
|
||||||
|
|
||||||
var query = new InternalItemsQuery(user)
|
var query = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
|
@ -645,7 +649,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
GenreIds = body.GenreIds
|
GenreIds = body.GenreIds
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!body.LibrarySeriesId.Equals(default))
|
if (!body.LibrarySeriesId.IsEmpty())
|
||||||
{
|
{
|
||||||
query.IsSeries = true;
|
query.IsSeries = true;
|
||||||
|
|
||||||
|
@ -704,7 +708,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -743,7 +747,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[FromQuery] Guid? userId)
|
[FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -951,9 +955,7 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[Authorize(Policy = Policies.LiveTvManagement)]
|
[Authorize(Policy = Policies.LiveTvManagement)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<TunerHostInfo>> AddTunerHost([FromBody] TunerHostInfo tunerHostInfo)
|
public async Task<ActionResult<TunerHostInfo>> AddTunerHost([FromBody] TunerHostInfo tunerHostInfo)
|
||||||
{
|
=> await _tunerHostManager.SaveTunerHost(tunerHostInfo).ConfigureAwait(false);
|
||||||
return await _liveTvManager.SaveTunerHost(tunerHostInfo).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a tuner host.
|
/// Deletes a tuner host.
|
||||||
|
@ -1130,10 +1132,8 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[HttpGet("TunerHosts/Types")]
|
[HttpGet("TunerHosts/Types")]
|
||||||
[Authorize(Policy = Policies.LiveTvAccess)]
|
[Authorize(Policy = Policies.LiveTvAccess)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult<IEnumerable<NameIdPair>> GetTunerHostTypes()
|
public IEnumerable<NameIdPair> GetTunerHostTypes()
|
||||||
{
|
=> _tunerHostManager.GetTunerHostTypes();
|
||||||
return _liveTvManager.GetTunerHostTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Discover tuners.
|
/// Discover tuners.
|
||||||
|
@ -1145,10 +1145,8 @@ public class LiveTvController : BaseJellyfinApiController
|
||||||
[HttpGet("Tuners/Discover")]
|
[HttpGet("Tuners/Discover")]
|
||||||
[Authorize(Policy = Policies.LiveTvManagement)]
|
[Authorize(Policy = Policies.LiveTvManagement)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<IEnumerable<TunerHostInfo>>> DiscoverTuners([FromQuery] bool newDevicesOnly = false)
|
public IAsyncEnumerable<TunerHostInfo> DiscoverTuners([FromQuery] bool newDevicesOnly = false)
|
||||||
{
|
=> _tunerHostManager.DiscoverTuners(newDevicesOnly);
|
||||||
return await _liveTvManager.DiscoverTuners(newDevicesOnly, CancellationToken.None).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a live tv recording stream.
|
/// Gets a live tv recording stream.
|
||||||
|
|
|
@ -7,6 +7,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
|
@ -69,7 +70,7 @@ public class MoviesController : BaseJellyfinApiController
|
||||||
[FromQuery] int itemLimit = 8)
|
[FromQuery] int itemLimit = 8)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
@ -95,7 +96,7 @@ public class MusicGenresController : BaseJellyfinApiController
|
||||||
.AddClientFields(User)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId.Value.Equals(default)
|
User? user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -164,7 +165,7 @@ public class MusicGenresController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -83,7 +84,7 @@ public class PersonsController : BaseJellyfinApiController
|
||||||
.AddClientFields(User)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId.Value.Equals(default)
|
User? user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ public class PersonsController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId.Value);
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
|
|
|
@ -9,6 +9,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.PlaylistDtos;
|
using Jellyfin.Api.Models.PlaylistDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
|
@ -188,7 +189,7 @@ public class PlaylistsController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = userId.Equals(default)
|
var user = userId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId);
|
: _userManager.GetUserById(userId);
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ public class SearchController : BaseJellyfinApiController
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.ChannelId.Equals(default))
|
if (!item.ChannelId.IsEmpty())
|
||||||
{
|
{
|
||||||
var channel = _libraryManager.GetItemById(item.ChannelId);
|
var channel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
result.ChannelName = channel?.Name;
|
result.ChannelName = channel?.Name;
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.SessionDtos;
|
using Jellyfin.Api.Models.SessionDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Api;
|
using MediaBrowser.Common.Api;
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -71,7 +72,7 @@ public class SessionController : BaseJellyfinApiController
|
||||||
result = result.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase));
|
result = result.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controllableByUserId.HasValue && !controllableByUserId.Equals(default))
|
if (!controllableByUserId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
result = result.Where(i => i.SupportsRemoteControl);
|
result = result.Where(i => i.SupportsRemoteControl);
|
||||||
|
|
||||||
|
@ -83,12 +84,12 @@ public class SessionController : BaseJellyfinApiController
|
||||||
|
|
||||||
if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers))
|
if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers))
|
||||||
{
|
{
|
||||||
result = result.Where(i => i.UserId.Equals(default) || i.ContainsUser(controllableByUserId.Value));
|
result = result.Where(i => i.UserId.IsEmpty() || i.ContainsUser(controllableByUserId.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl))
|
if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl))
|
||||||
{
|
{
|
||||||
result = result.Where(i => !i.UserId.Equals(default));
|
result = result.Where(i => !i.UserId.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
result = result.Where(i =>
|
result = result.Where(i =>
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -91,7 +92,7 @@ public class StudiosController : BaseJellyfinApiController
|
||||||
.AddClientFields(User)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId.Value.Equals(default)
|
User? user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -144,7 +145,7 @@ public class StudiosController : BaseJellyfinApiController
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(User);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
var item = _libraryManager.GetStudio(name);
|
var item = _libraryManager.GetStudio(name);
|
||||||
if (!userId.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -62,7 +63,7 @@ public class SuggestionsController : BaseJellyfinApiController
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] bool enableTotalRecordCount = false)
|
[FromQuery] bool enableTotalRecordCount = false)
|
||||||
{
|
{
|
||||||
var user = userId.Equals(default)
|
var user = userId.IsEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId);
|
: _userManager.GetUserById(userId);
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class TvShowsController : BaseJellyfinApiController
|
||||||
},
|
},
|
||||||
options);
|
options);
|
||||||
|
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ public class TvShowsController : BaseJellyfinApiController
|
||||||
[FromQuery] bool? enableUserData)
|
[FromQuery] bool? enableUserData)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ public class TvShowsController : BaseJellyfinApiController
|
||||||
[FromQuery] ItemSortBy? sortBy)
|
[FromQuery] ItemSortBy? sortBy)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ public class TvShowsController : BaseJellyfinApiController
|
||||||
}
|
}
|
||||||
|
|
||||||
// This must be the last filter
|
// This must be the last filter
|
||||||
if (adjacentTo.HasValue && !adjacentTo.Value.Equals(default))
|
if (!adjacentTo.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
episodes = UserViewBuilder.FilterForAdjacency(episodes, adjacentTo.Value).ToList();
|
episodes = UserViewBuilder.FilterForAdjacency(episodes, adjacentTo.Value).ToList();
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ public class TvShowsController : BaseJellyfinApiController
|
||||||
[FromQuery] bool? enableUserData)
|
[FromQuery] bool? enableUserData)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.Models.UserDtos;
|
using Jellyfin.Api.Models.UserDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Api;
|
using MediaBrowser.Common.Api;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -532,7 +533,7 @@ public class UserController : BaseJellyfinApiController
|
||||||
public ActionResult<UserDto> GetCurrentUser()
|
public ActionResult<UserDto> GetCurrentUser()
|
||||||
{
|
{
|
||||||
var userId = User.GetUserId();
|
var userId = User.GetUserId();
|
||||||
if (userId.Equals(default))
|
if (userId.IsEmpty())
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
@ -84,7 +85,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -185,7 +186,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -221,7 +222,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -257,7 +258,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -330,7 +331,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -375,7 +376,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
@ -558,7 +559,7 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Api;
|
using MediaBrowser.Common.Api;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -96,12 +97,12 @@ public class VideosController : BaseJellyfinApiController
|
||||||
public ActionResult<QueryResult<BaseItemDto>> GetAdditionalPart([FromRoute, Required] Guid itemId, [FromQuery] Guid? userId)
|
public ActionResult<QueryResult<BaseItemDto>> GetAdditionalPart([FromRoute, Required] Guid itemId, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
userId = RequestHelpers.GetUserId(User, userId);
|
userId = RequestHelpers.GetUserId(User, userId);
|
||||||
var user = userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
var item = itemId.Equals(default)
|
var item = itemId.IsEmpty()
|
||||||
? (userId.Value.Equals(default)
|
? (userId.IsNullOrEmpty()
|
||||||
? _libraryManager.RootFolder
|
? _libraryManager.RootFolder
|
||||||
: _libraryManager.GetUserRootFolder())
|
: _libraryManager.GetUserRootFolder())
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class YearsController : BaseJellyfinApiController
|
||||||
.AddClientFields(User)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId.Value.Equals(default)
|
User? user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId);
|
||||||
|
@ -110,7 +110,7 @@ public class YearsController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
var folder = (Folder)parentItem;
|
var folder = (Folder)parentItem;
|
||||||
|
|
||||||
if (userId.Equals(default))
|
if (userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
items = recursive ? folder.GetRecursiveChildren(Filter) : folder.Children.Where(Filter).ToList();
|
items = recursive ? folder.GetRecursiveChildren(Filter) : folder.Children.Where(Filter).ToList();
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ public class YearsController : BaseJellyfinApiController
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(User);
|
.AddClientFields(User);
|
||||||
|
|
||||||
if (!userId.Value.Equals(default))
|
if (!userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId.Value);
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
@ -86,7 +87,7 @@ public class MediaInfoHelper
|
||||||
string? mediaSourceId = null,
|
string? mediaSourceId = null,
|
||||||
string? liveStreamId = null)
|
string? liveStreamId = null)
|
||||||
{
|
{
|
||||||
var user = userId is null || userId.Value.Equals(default)
|
var user = userId.IsNullOrEmpty()
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var item = _libraryManager.GetItemById(id);
|
var item = _libraryManager.GetItemById(id);
|
||||||
|
|
|
@ -7,6 +7,7 @@ using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Extensions;
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -67,7 +68,7 @@ public static class RequestHelpers
|
||||||
var authenticatedUserId = claimsPrincipal.GetUserId();
|
var authenticatedUserId = claimsPrincipal.GetUserId();
|
||||||
|
|
||||||
// UserId not provided, fall back to authenticated user id.
|
// UserId not provided, fall back to authenticated user id.
|
||||||
if (userId is null || userId.Value.Equals(default))
|
if (userId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return authenticatedUserId;
|
return authenticatedUserId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public static class StreamingHelpers
|
||||||
};
|
};
|
||||||
|
|
||||||
var userId = httpContext.User.GetUserId();
|
var userId = httpContext.User.GetUserId();
|
||||||
if (!userId.Equals(default))
|
if (!userId.IsEmpty())
|
||||||
{
|
{
|
||||||
state.User = userManager.GetUserById(userId);
|
state.User = userManager.GetUserById(userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using Jellyfin.Data.Events;
|
using Jellyfin.Data.Events;
|
||||||
using Jellyfin.Data.Events.Users;
|
using Jellyfin.Data.Events.Users;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -117,7 +118,7 @@ namespace Jellyfin.Server.Implementations.Users
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public User? GetUserById(Guid id)
|
public User? GetUserById(Guid id)
|
||||||
{
|
{
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ using Jellyfin.Api.WebSocketListeners;
|
||||||
using Jellyfin.Drawing;
|
using Jellyfin.Drawing;
|
||||||
using Jellyfin.Drawing.Skia;
|
using Jellyfin.Drawing.Skia;
|
||||||
using Jellyfin.LiveTv;
|
using Jellyfin.LiveTv;
|
||||||
using Jellyfin.LiveTv.Channels;
|
|
||||||
using Jellyfin.Server.Implementations;
|
using Jellyfin.Server.Implementations;
|
||||||
using Jellyfin.Server.Implementations.Activity;
|
using Jellyfin.Server.Implementations.Activity;
|
||||||
using Jellyfin.Server.Implementations.Devices;
|
using Jellyfin.Server.Implementations.Devices;
|
||||||
|
@ -18,18 +17,15 @@ using Jellyfin.Server.Implementations.Users;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Authentication;
|
using MediaBrowser.Controller.Authentication;
|
||||||
using MediaBrowser.Controller.BaseItemManager;
|
using MediaBrowser.Controller.BaseItemManager;
|
||||||
using MediaBrowser.Controller.Channels;
|
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
|
||||||
using MediaBrowser.Controller.Lyrics;
|
using MediaBrowser.Controller.Lyrics;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Security;
|
using MediaBrowser.Controller.Security;
|
||||||
using MediaBrowser.Controller.Trickplay;
|
using MediaBrowser.Controller.Trickplay;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Providers.Lyric;
|
using MediaBrowser.Providers.Lyric;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
@ -101,11 +97,6 @@ namespace Jellyfin.Server
|
||||||
|
|
||||||
serviceCollection.AddScoped<IAuthenticationManager, AuthenticationManager>();
|
serviceCollection.AddScoped<IAuthenticationManager, AuthenticationManager>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<LiveTvDtoService>();
|
|
||||||
serviceCollection.AddSingleton<ILiveTvManager, LiveTvManager>();
|
|
||||||
serviceCollection.AddSingleton<IChannelManager, ChannelManager>();
|
|
||||||
serviceCollection.AddSingleton<IStreamHelper, StreamHelper>();
|
|
||||||
|
|
||||||
foreach (var type in GetExportTypes<ILyricProvider>())
|
foreach (var type in GetExportTypes<ILyricProvider>())
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton(typeof(ILyricProvider), type);
|
serviceCollection.AddSingleton(typeof(ILyricProvider), type);
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Net.Http.Headers;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Jellyfin.Api.Middleware;
|
using Jellyfin.Api.Middleware;
|
||||||
|
using Jellyfin.LiveTv.Extensions;
|
||||||
using Jellyfin.MediaEncoding.Hls.Extensions;
|
using Jellyfin.MediaEncoding.Hls.Extensions;
|
||||||
using Jellyfin.Networking;
|
using Jellyfin.Networking;
|
||||||
using Jellyfin.Networking.HappyEyeballs;
|
using Jellyfin.Networking.HappyEyeballs;
|
||||||
|
@ -121,6 +122,7 @@ namespace Jellyfin.Server
|
||||||
.AddCheck<DbContextFactoryHealthCheck<JellyfinDbContext>>(nameof(JellyfinDbContext));
|
.AddCheck<DbContextFactoryHealthCheck<JellyfinDbContext>>(nameof(JellyfinDbContext));
|
||||||
|
|
||||||
services.AddHlsPlaylistGenerator();
|
services.AddHlsPlaylistGenerator();
|
||||||
|
services.AddLiveTvServices();
|
||||||
|
|
||||||
services.AddHostedService<AutoDiscoveryHost>();
|
services.AddHostedService<AutoDiscoveryHost>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,12 +95,5 @@ namespace MediaBrowser.Controller.Channels
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The item media sources.</returns>
|
/// <returns>The item media sources.</returns>
|
||||||
IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken);
|
IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the item supports media probe.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <returns>Whether media probe should be enabled.</returns>
|
|
||||||
bool EnableMediaProbe(BaseItem item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
|
@ -184,7 +185,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <exception cref="ArgumentNullException">The id is empty.</exception>
|
/// <exception cref="ArgumentNullException">The id is empty.</exception>
|
||||||
public BaseItem FindVirtualChild(Guid id)
|
public BaseItem FindVirtualChild(Guid id)
|
||||||
{
|
{
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||||
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
|
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsAccessedByName => ParentId.Equals(default);
|
public bool IsAccessedByName => ParentId.IsEmpty();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public override bool IsFolder => !IsAccessedByName;
|
public override bool IsFolder => !IsAccessedByName;
|
||||||
|
|
|
@ -240,7 +240,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!ChannelId.Equals(default))
|
if (!ChannelId.IsEmpty())
|
||||||
{
|
{
|
||||||
return SourceType.Channel;
|
return SourceType.Channel;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +530,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var id = DisplayParentId;
|
var id = DisplayParentId;
|
||||||
if (id.Equals(default))
|
if (id.IsEmpty())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -746,7 +746,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public virtual bool StopRefreshIfLocalMetadataFound => true;
|
public virtual bool StopRefreshIfLocalMetadataFound => true;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
protected virtual bool SupportsOwnedItems => !ParentId.Equals(default) && IsFileProtocol;
|
protected virtual bool SupportsOwnedItems => !ParentId.IsEmpty() && IsFileProtocol;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual bool SupportsPeople => false;
|
public virtual bool SupportsPeople => false;
|
||||||
|
@ -823,7 +823,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public BaseItem GetOwner()
|
public BaseItem GetOwner()
|
||||||
{
|
{
|
||||||
var ownerId = OwnerId;
|
var ownerId = OwnerId;
|
||||||
return ownerId.Equals(default) ? null : LibraryManager.GetItemById(ownerId);
|
return ownerId.IsEmpty() ? null : LibraryManager.GetItemById(ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanDelete(User user, List<Folder> allCollectionFolders)
|
public bool CanDelete(User user, List<Folder> allCollectionFolders)
|
||||||
|
@ -968,7 +968,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public BaseItem GetParent()
|
public BaseItem GetParent()
|
||||||
{
|
{
|
||||||
var parentId = ParentId;
|
var parentId = ParentId;
|
||||||
if (parentId.Equals(default))
|
if (parentId.IsEmpty())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1361,7 +1361,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
var tasks = extras.Select(i =>
|
var tasks = extras.Select(i =>
|
||||||
{
|
{
|
||||||
var subOptions = new MetadataRefreshOptions(options);
|
var subOptions = new MetadataRefreshOptions(options);
|
||||||
if (!i.OwnerId.Equals(ownerId) || !i.ParentId.Equals(default))
|
if (!i.OwnerId.Equals(ownerId) || !i.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
i.OwnerId = ownerId;
|
i.OwnerId = ownerId;
|
||||||
i.ParentId = Guid.Empty;
|
i.ParentId = Guid.Empty;
|
||||||
|
@ -1673,7 +1673,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
// First get using the cached Id
|
// First get using the cached Id
|
||||||
if (info.ItemId.HasValue)
|
if (info.ItemId.HasValue)
|
||||||
{
|
{
|
||||||
if (info.ItemId.Value.Equals(default))
|
if (info.ItemId.Value.IsEmpty())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2439,7 +2439,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (video.OwnerId.Equals(default))
|
if (video.OwnerId.IsEmpty())
|
||||||
{
|
{
|
||||||
video.OwnerId = this.Id;
|
video.OwnerId = this.Id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
||||||
using System.Threading.Tasks.Dataflow;
|
using System.Threading.Tasks.Dataflow;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Collections;
|
using MediaBrowser.Controller.Collections;
|
||||||
|
@ -198,7 +199,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
item.SetParent(this);
|
item.SetParent(this);
|
||||||
|
|
||||||
if (item.Id.Equals(default))
|
if (item.Id.IsEmpty())
|
||||||
{
|
{
|
||||||
item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType());
|
item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType());
|
||||||
}
|
}
|
||||||
|
@ -697,7 +698,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
if (this is not UserRootFolder
|
if (this is not UserRootFolder
|
||||||
&& this is not AggregateFolder
|
&& this is not AggregateFolder
|
||||||
&& query.ParentId.Equals(default))
|
&& query.ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
query.Parent = this;
|
query.Parent = this;
|
||||||
}
|
}
|
||||||
|
@ -840,7 +841,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default))
|
if (!query.AdjacentTo.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Logger.LogDebug("Query requires post-filtering due to AdjacentTo");
|
Logger.LogDebug("Query requires post-filtering due to AdjacentTo");
|
||||||
return true;
|
return true;
|
||||||
|
@ -987,7 +988,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
#pragma warning restore CA1309
|
#pragma warning restore CA1309
|
||||||
|
|
||||||
// This must be the last filter
|
// This must be the last filter
|
||||||
if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default))
|
if (!query.AdjacentTo.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
items = UserViewBuilder.FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
|
items = UserViewBuilder.FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
@ -74,12 +75,12 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var seriesId = SeriesId;
|
var seriesId = SeriesId;
|
||||||
if (seriesId.Equals(default))
|
if (seriesId.IsEmpty())
|
||||||
{
|
{
|
||||||
seriesId = FindSeriesId();
|
seriesId = FindSeriesId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return seriesId.Equals(default) ? null : (LibraryManager.GetItemById(seriesId) as Series);
|
return seriesId.IsEmpty() ? null : (LibraryManager.GetItemById(seriesId) as Series);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +90,12 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var seasonId = SeasonId;
|
var seasonId = SeasonId;
|
||||||
if (seasonId.Equals(default))
|
if (seasonId.IsEmpty())
|
||||||
{
|
{
|
||||||
seasonId = FindSeasonId();
|
seasonId = FindSeasonId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return seasonId.Equals(default) ? null : (LibraryManager.GetItemById(seasonId) as Season);
|
return seasonId.IsEmpty() ? null : (LibraryManager.GetItemById(seasonId) as Season);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
|
||||||
var seasonId = SeasonId;
|
var seasonId = SeasonId;
|
||||||
|
|
||||||
if (!seasonId.Equals(default) && !list.Contains(seasonId))
|
if (!seasonId.IsEmpty() && !list.Contains(seasonId))
|
||||||
{
|
{
|
||||||
list.Add(seasonId);
|
list.Add(seasonId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
@ -48,12 +49,12 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var seriesId = SeriesId;
|
var seriesId = SeriesId;
|
||||||
if (seriesId.Equals(default))
|
if (seriesId.IsEmpty())
|
||||||
{
|
{
|
||||||
seriesId = FindSeriesId();
|
seriesId = FindSeriesId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return seriesId.Equals(default) ? null : (LibraryManager.GetItemById(seriesId) as Series);
|
return seriesId.IsEmpty() ? null : (LibraryManager.GetItemById(seriesId) as Series);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,11 +70,11 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override IEnumerable<Guid> GetIdsForAncestorQuery()
|
public override IEnumerable<Guid> GetIdsForAncestorQuery()
|
||||||
{
|
{
|
||||||
if (!DisplayParentId.Equals(default))
|
if (!DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
yield return DisplayParentId;
|
yield return DisplayParentId;
|
||||||
}
|
}
|
||||||
else if (!ParentId.Equals(default))
|
else if (!ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
yield return ParentId;
|
yield return ParentId;
|
||||||
}
|
}
|
||||||
|
@ -95,11 +95,11 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var parent = this as Folder;
|
var parent = this as Folder;
|
||||||
|
|
||||||
if (!DisplayParentId.Equals(default))
|
if (!DisplayParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
parent = LibraryManager.GetItemById(DisplayParentId) as Folder ?? parent;
|
parent = LibraryManager.GetItemById(DisplayParentId) as Folder ?? parent;
|
||||||
}
|
}
|
||||||
else if (!ParentId.Equals(default))
|
else if (!ParentId.IsEmpty())
|
||||||
{
|
{
|
||||||
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
|
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
var user = query.User;
|
var user = query.User;
|
||||||
|
|
||||||
// This must be the last filter
|
// This must be the last filter
|
||||||
if (query.AdjacentTo.HasValue && !query.AdjacentTo.Value.Equals(default))
|
if (!query.AdjacentTo.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
items = FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
|
items = FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,7 +456,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
foreach (var child in LinkedAlternateVersions)
|
foreach (var child in LinkedAlternateVersions)
|
||||||
{
|
{
|
||||||
// Reset the cached value
|
// Reset the cached value
|
||||||
if (child.ItemId.HasValue && child.ItemId.Value.Equals(default))
|
if (child.ItemId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
child.ItemId = null;
|
child.ItemId = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,9 +71,8 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// Adds the parts.
|
/// Adds the parts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="services">The services.</param>
|
/// <param name="services">The services.</param>
|
||||||
/// <param name="tunerHosts">The tuner hosts.</param>
|
|
||||||
/// <param name="listingProviders">The listing providers.</param>
|
/// <param name="listingProviders">The listing providers.</param>
|
||||||
void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders);
|
void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<IListingsProvider> listingProviders);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the timer.
|
/// Gets the timer.
|
||||||
|
@ -253,14 +252,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem Item, BaseItemDto ItemDto)> programs, IReadOnlyList<ItemFields> fields, User user = null);
|
Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem Item, BaseItemDto ItemDto)> programs, IReadOnlyList<ItemFields> fields, User user = null);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the tuner host.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="info">Turner host to save.</param>
|
|
||||||
/// <param name="dataSourceChanged">Option to specify that data source has changed.</param>
|
|
||||||
/// <returns>Tuner host information wrapped in a task.</returns>
|
|
||||||
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the listing provider.
|
/// Saves the listing provider.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -298,10 +289,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
|
|
||||||
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
|
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
|
||||||
|
|
||||||
List<NameIdPair> GetTunerHostTypes();
|
|
||||||
|
|
||||||
Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
string GetEmbyTvActiveRecordingPath(string id);
|
string GetEmbyTvActiveRecordingPath(string id);
|
||||||
|
|
||||||
ActiveRecordingInfo GetActiveRecordingInfo(string path);
|
ActiveRecordingInfo GetActiveRecordingInfo(string path);
|
||||||
|
|
|
@ -140,14 +140,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task CloseLiveStream(string id, CancellationToken cancellationToken);
|
Task CloseLiveStream(string id, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Records the live stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The identifier.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task RecordLiveStream(string id, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the tuner.
|
/// Resets the tuner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -180,9 +172,4 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
{
|
{
|
||||||
Task<ILiveStream> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
Task<ILiveStream> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ISupportsUpdatingDefaults
|
|
||||||
{
|
|
||||||
Task UpdateTimerDefaults(SeriesTimerInfo info, CancellationToken cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task<IEnumerable<ChannelInfo>>.</returns>
|
/// <returns>Task<IEnumerable<ChannelInfo>>.</returns>
|
||||||
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
|
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the tuner infos.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task<List<LiveTvTunerInfo>>.</returns>
|
|
||||||
Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the channel stream.
|
/// Gets the channel stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Model.Dto;
|
||||||
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.LiveTv;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Service responsible for managing the <see cref="ITunerHost"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITunerHostManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the available <see cref="ITunerHost"/>s.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyList<ITunerHost> TunerHosts { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="NameIdPair"/>s for the available <see cref="ITunerHost"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The <see cref="NameIdPair"/>s.</returns>
|
||||||
|
IEnumerable<NameIdPair> GetTunerHostTypes();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the tuner host.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">Turner host to save.</param>
|
||||||
|
/// <param name="dataSourceChanged">Option to specify that data source has changed.</param>
|
||||||
|
/// <returns>Tuner host information wrapped in a task.</returns>
|
||||||
|
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Discovers the available tuners.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newDevicesOnly">A value indicating whether to only return new devices.</param>
|
||||||
|
/// <returns>The <see cref="TunerHostInfo"/>s.</returns>
|
||||||
|
IAsyncEnumerable<TunerHostInfo> DiscoverTuners(bool newDevicesOnly);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scans for tuner devices that have changed URLs.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
|
||||||
|
/// <returns>A task that represents the scanning operation.</returns>
|
||||||
|
Task ScanForTunerDeviceChanges(CancellationToken cancellationToken);
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class LiveTvServiceStatusInfo
|
|
||||||
{
|
|
||||||
public LiveTvServiceStatusInfo()
|
|
||||||
{
|
|
||||||
Tuners = new List<LiveTvTunerInfo>();
|
|
||||||
IsVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public LiveTvServiceStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status message.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status message.</value>
|
|
||||||
public string StatusMessage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the version.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The version.</value>
|
|
||||||
public string Version { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has update available.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value>
|
|
||||||
public bool HasUpdateAvailable { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the tuners.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The tuners.</value>
|
|
||||||
public List<LiveTvTunerInfo> Tuners { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is visible.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is visible; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsVisible { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class LiveTvTunerInfo
|
|
||||||
{
|
|
||||||
public LiveTvTunerInfo()
|
|
||||||
{
|
|
||||||
Clients = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type of the source.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type of the source.</value>
|
|
||||||
public string SourceType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name.</value>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The identifier.</value>
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The URL.</value>
|
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public LiveTvTunerStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the channel identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The channel identifier.</value>
|
|
||||||
public string ChannelId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the recording identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The recording identifier.</value>
|
|
||||||
public string RecordingId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the program.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name of the program.</value>
|
|
||||||
public string ProgramName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the clients.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The clients.</value>
|
|
||||||
public List<string> Clients { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance can reset.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
|
|
||||||
public bool CanReset { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class RecordingInfo
|
|
||||||
{
|
|
||||||
public RecordingInfo()
|
|
||||||
{
|
|
||||||
Genres = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the id of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the series timer identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The series timer identifier.</value>
|
|
||||||
public string SeriesTimerId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the timer identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The timer identifier.</value>
|
|
||||||
public string TimerId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the channelId of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string ChannelId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type of the channel.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type of the channel.</value>
|
|
||||||
public ChannelType ChannelType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the path.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The path.</value>
|
|
||||||
public string Path { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The URL.</value>
|
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the overview.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The overview.</value>
|
|
||||||
public string Overview { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the start date of the recording, in UTC.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime StartDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the end date of the recording, in UTC.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime EndDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the program identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The program identifier.</value>
|
|
||||||
public string ProgramId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public RecordingStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the genre of the program.
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Genres { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is repeat.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsRepeat { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the episode title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The episode title.</value>
|
|
||||||
public string EpisodeTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is hd.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
|
|
||||||
public bool? IsHD { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the audio.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The audio.</value>
|
|
||||||
public ProgramAudio? Audio { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the original air date.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The original air date.</value>
|
|
||||||
public DateTime? OriginalAirDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is movie.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsMovie { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is sports.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsSports { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is series.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsSeries { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is live.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsLive { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is news.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsNews { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is kids.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsKids { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is premiere.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsPremiere { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the official rating.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The official rating.</value>
|
|
||||||
public string OfficialRating { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the community rating.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The community rating.</value>
|
|
||||||
public float? CommunityRating { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the image path if it can be accessed directly from the file system.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The image path.</value>
|
|
||||||
public string ImagePath { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the image url if it can be downloaded.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The image URL.</value>
|
|
||||||
public string ImageUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has image.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value>
|
|
||||||
public bool? HasImage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the show identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The show identifier.</value>
|
|
||||||
public string ShowId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the date last updated.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The date last updated.</value>
|
|
||||||
public DateTime DateLastUpdated { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class RecordingStatusChangedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public string RecordingId { get; set; }
|
|
||||||
|
|
||||||
public RecordingStatus NewStatus { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,6 +9,7 @@ using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
|
@ -400,7 +401,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
||||||
|
|
||||||
if (state.VideoRequest is not null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
|
if (state.VideoRequest is not null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
|
||||||
{
|
{
|
||||||
var user = userId.Equals(default) ? null : _userManager.GetUserById(userId);
|
var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId);
|
||||||
if (user is not null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
if (user is not null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
||||||
{
|
{
|
||||||
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
|
@ -1536,7 +1537,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
private static void ValidateMediaOptions(MediaOptions options, bool isMediaSource)
|
private static void ValidateMediaOptions(MediaOptions options, bool isMediaSource)
|
||||||
{
|
{
|
||||||
if (options.ItemId.Equals(default))
|
if (options.ItemId.IsEmpty())
|
||||||
{
|
{
|
||||||
ArgumentException.ThrowIfNullOrEmpty(options.DeviceId);
|
ArgumentException.ThrowIfNullOrEmpty(options.DeviceId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ namespace MediaBrowser.Model.IO
|
||||||
|
|
||||||
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
|
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken);
|
Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.LiveTv
|
|
||||||
{
|
|
||||||
public enum LiveTvTunerStatus
|
|
||||||
{
|
|
||||||
Available = 0,
|
|
||||||
Disabled = 1,
|
|
||||||
RecordingTv = 2,
|
|
||||||
LiveTv = 3
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -706,7 +706,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
{
|
{
|
||||||
BaseItem? referenceItem = null;
|
BaseItem? referenceItem = null;
|
||||||
|
|
||||||
if (!searchInfo.ItemId.Equals(default))
|
if (!searchInfo.ItemId.IsEmpty())
|
||||||
{
|
{
|
||||||
referenceItem = _libraryManager.GetItemById(searchInfo.ItemId);
|
referenceItem = _libraryManager.GetItemById(searchInfo.ItemId);
|
||||||
}
|
}
|
||||||
|
@ -944,7 +944,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
public void QueueRefresh(Guid itemId, MetadataRefreshOptions options, RefreshPriority priority)
|
public void QueueRefresh(Guid itemId, MetadataRefreshOptions options, RefreshPriority priority)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(itemId);
|
ArgumentNullException.ThrowIfNull(itemId);
|
||||||
if (itemId.Equals(default))
|
if (itemId.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Guid can't be empty", nameof(itemId));
|
throw new ArgumentException("Guid can't be empty", nameof(itemId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ cat ${debian_changelog_file} >> ${debian_changelog_temp}
|
||||||
# Move into place
|
# Move into place
|
||||||
mv ${debian_changelog_temp} ${debian_changelog_file}
|
mv ${debian_changelog_temp} ${debian_changelog_file}
|
||||||
|
|
||||||
# Write out a temporary Yum changelog with our new stuff prepended and some templated formatting
|
# Write out a temporary Dnf changelog with our new stuff prepended and some templated formatting
|
||||||
fedora_spec_file="fedora/jellyfin.spec"
|
fedora_spec_file="fedora/jellyfin.spec"
|
||||||
fedora_changelog_temp="$( mktemp )"
|
fedora_changelog_temp="$( mktemp )"
|
||||||
fedora_spec_temp_dir="$( mktemp -d )"
|
fedora_spec_temp_dir="$( mktemp -d )"
|
||||||
|
|
|
@ -7,27 +7,27 @@ HOST_ARCH := $(shell arch)
|
||||||
BUILD_ARCH := ${DEB_HOST_MULTIARCH}
|
BUILD_ARCH := ${DEB_HOST_MULTIARCH}
|
||||||
ifeq ($(HOST_ARCH),x86_64)
|
ifeq ($(HOST_ARCH),x86_64)
|
||||||
# Building AMD64
|
# Building AMD64
|
||||||
DOTNETRUNTIME := debian-x64
|
DOTNETRUNTIME := linux-x64
|
||||||
ifeq ($(BUILD_ARCH),arm-linux-gnueabihf)
|
ifeq ($(BUILD_ARCH),arm-linux-gnueabihf)
|
||||||
# Cross-building ARM on AMD64
|
# Cross-building ARM on AMD64
|
||||||
DOTNETRUNTIME := debian-arm
|
DOTNETRUNTIME := linux-arm
|
||||||
endif
|
endif
|
||||||
ifeq ($(BUILD_ARCH),aarch64-linux-gnu)
|
ifeq ($(BUILD_ARCH),aarch64-linux-gnu)
|
||||||
# Cross-building ARM on AMD64
|
# Cross-building ARM on AMD64
|
||||||
DOTNETRUNTIME := debian-arm64
|
DOTNETRUNTIME := linux-arm64
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(HOST_ARCH),armv7l)
|
ifeq ($(HOST_ARCH),armv7l)
|
||||||
# Building ARM
|
# Building ARM
|
||||||
DOTNETRUNTIME := debian-arm
|
DOTNETRUNTIME := linux-arm
|
||||||
endif
|
endif
|
||||||
ifeq ($(HOST_ARCH),arm64)
|
ifeq ($(HOST_ARCH),arm64)
|
||||||
# Building ARM
|
# Building ARM
|
||||||
DOTNETRUNTIME := debian-arm64
|
DOTNETRUNTIME := linux-arm64
|
||||||
endif
|
endif
|
||||||
ifeq ($(HOST_ARCH),aarch64)
|
ifeq ($(HOST_ARCH),aarch64)
|
||||||
# Building ARM
|
# Building ARM
|
||||||
DOTNETRUNTIME := debian-arm64
|
DOTNETRUNTIME := linux-arm64
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export DH_VERBOSE=1
|
export DH_VERBOSE=1
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
FROM centos:7
|
FROM quay.io/centos/centos:stream9
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
ENV IS_DOCKER=YES
|
ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare CentOS environment
|
# Prepare CentOS environment
|
||||||
RUN yum update -yq \
|
RUN dnf update -yq \
|
||||||
&& yum install -yq epel-release \
|
&& dnf install -yq epel-release \
|
||||||
&& yum install -yq @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git wget
|
&& dnf install -yq \
|
||||||
|
rpmdevtools libcurl-devel fontconfig-devel \
|
||||||
|
freetype-devel openssl-devel glibc-devel \
|
||||||
|
libicu-devel git wget dnf-plugins-core \
|
||||||
|
&& dnf clean all \
|
||||||
|
&& rm -rf /var/cache/dnf
|
||||||
|
|
||||||
# Install DotNET SDK
|
# Install DotNET SDK
|
||||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -10,11 +14,14 @@ ENV ARCH=amd64
|
||||||
ENV IS_DOCKER=YES
|
ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yq \
|
||||||
debhelper gnupg devscripts build-essential mmv \
|
debhelper gnupg devscripts build-essential mmv \
|
||||||
libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev \
|
libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev \
|
||||||
libssl1.1 liblttng-ust0
|
libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yq \
|
||||||
|
&& apt-get autoremove -yq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.amd64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.amd64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,23 +15,26 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts build-essential mmv
|
debhelper gnupg devscripts build-essential mmv
|
||||||
|
|
||||||
# Prepare the cross-toolchain
|
# Prepare the cross-toolchain
|
||||||
RUN dpkg --add-architecture arm64 \
|
RUN dpkg --add-architecture arm64 \
|
||||||
&& apt-get update -yqq \
|
&& apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends cross-gcc-dev \
|
&& apt-get install --no-install-recommends -yqq cross-gcc-dev \
|
||||||
&& TARGET_LIST="arm64" cross-gcc-gensource 9 \
|
&& TARGET_LIST="arm64" cross-gcc-gensource 12 \
|
||||||
&& cd cross-gcc-packages-amd64/cross-gcc-9-arm64 \
|
&& cd cross-gcc-packages-amd64/cross-gcc-12-arm64 \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
gcc-9-source libstdc++-9-dev-arm64-cross \
|
gcc-12-source libstdc++-12-dev-arm64-cross \
|
||||||
binutils-aarch64-linux-gnu bison flex libtool \
|
binutils-aarch64-linux-gnu bison flex libtool \
|
||||||
gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev \
|
gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev \
|
||||||
systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip \
|
systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip \
|
||||||
libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 \
|
libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 \
|
||||||
libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 \
|
libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 \
|
||||||
libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust0:arm64 libstdc++-9-dev:arm64
|
libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust1:arm64 libstdc++-12-dev:arm64 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.arm64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.arm64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,24 +15,27 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts build-essential mmv
|
debhelper gnupg devscripts build-essential mmv
|
||||||
|
|
||||||
# Prepare the cross-toolchain
|
# Prepare the cross-toolchain
|
||||||
RUN dpkg --add-architecture armhf \
|
RUN dpkg --add-architecture armhf \
|
||||||
&& apt-get update -yqq \
|
&& apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends cross-gcc-dev \
|
&& apt-get install --no-install-recommends -yqq cross-gcc-dev \
|
||||||
&& TARGET_LIST="armhf" cross-gcc-gensource 9 \
|
&& TARGET_LIST="armhf" cross-gcc-gensource 12 \
|
||||||
&& cd cross-gcc-packages-amd64/cross-gcc-9-armhf \
|
&& cd cross-gcc-packages-amd64/cross-gcc-12-armhf \
|
||||||
&& apt-get install -yqq --no-install-recommends\
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
gcc-9-source libstdc++-9-dev-armhf-cross \
|
gcc-12-source libstdc++-12-dev-armhf-cross \
|
||||||
binutils-aarch64-linux-gnu bison flex libtool gdb \
|
binutils-aarch64-linux-gnu bison flex libtool gdb \
|
||||||
sharutils netbase libmpc-dev libmpfr-dev libgmp-dev \
|
sharutils netbase libmpc-dev libmpfr-dev libgmp-dev \
|
||||||
systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
||||||
zip binutils-arm-linux-gnueabihf libc6-dev:armhf \
|
zip binutils-arm-linux-gnueabihf libc6-dev:armhf \
|
||||||
linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf \
|
linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf \
|
||||||
libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf \
|
libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf \
|
||||||
liblttng-ust0:armhf libstdc++-9-dev:armhf
|
liblttng-ust1:armhf libstdc++-12-dev:armhf \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
ARG SOURCE_DIR=/src
|
ARG SOURCE_DIR=/src
|
||||||
ARG ARTIFACT_DIR=/jellyfin
|
ARG ARTIFACT_DIR=/jellyfin
|
||||||
|
|
||||||
WORKDIR ${SOURCE_DIR}
|
WORKDIR ${SOURCE_DIR}
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
|
||||||
# because of changes in docker and systemd we need to not build in parallel at the moment
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none
|
||||||
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
|
|
||||||
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 -p:DebugSymbols=false -p:DebugType=none
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
ARG SOURCE_DIR=/src
|
ARG SOURCE_DIR=/src
|
||||||
ARG ARTIFACT_DIR=/jellyfin
|
ARG ARTIFACT_DIR=/jellyfin
|
||||||
|
|
||||||
WORKDIR ${SOURCE_DIR}
|
WORKDIR ${SOURCE_DIR}
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
|
||||||
# because of changes in docker and systemd we need to not build in parallel at the moment
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none
|
||||||
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
|
|
||||||
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 -p:DebugSymbols=false -p:DebugType=none
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
ARG SOURCE_DIR=/src
|
ARG SOURCE_DIR=/src
|
||||||
ARG ARTIFACT_DIR=/jellyfin
|
ARG ARTIFACT_DIR=/jellyfin
|
||||||
|
|
||||||
WORKDIR ${SOURCE_DIR}
|
WORKDIR ${SOURCE_DIR}
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
|
||||||
# because of changes in docker and systemd we need to not build in parallel at the moment
|
RUN dotnet publish Jellyfin.Server --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none
|
||||||
# see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting
|
|
||||||
RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm -p:DebugSymbols=false -p:DebugType=none
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
FROM fedora:39
|
FROM fedora:39
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -9,7 +11,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Fedora environment
|
# Prepare Fedora environment
|
||||||
RUN dnf update -yq \
|
RUN dnf update -yq \
|
||||||
&& dnf install -yq @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel systemd wget make
|
&& dnf install -yq \
|
||||||
|
@buildsys-build rpmdevtools git \
|
||||||
|
dnf-plugins-core libcurl-devel fontconfig-devel \
|
||||||
|
freetype-devel openssl-devel glibc-devel \
|
||||||
|
libicu-devel systemd wget make \
|
||||||
|
&& dnf clean all \
|
||||||
|
&& rm -rf /var/cache/dnf
|
||||||
|
|
||||||
# Install DotNET SDK
|
# Install DotNET SDK
|
||||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
|
@ -17,7 +25,6 @@ RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
||||||
|
|
||||||
# Create symlinks and directories
|
# Create symlinks and directories
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora.amd64 /build.sh \
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora.amd64 /build.sh \
|
||||||
&& mkdir -p ${SOURCE_DIR}/SPECS \
|
&& mkdir -p ${SOURCE_DIR}/SPECS \
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.amd64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.amd64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.amd64-musl /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.amd64-musl /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.arm64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.arm64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.armhf /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.armhf /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
apt-transport-https debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.musl-linux-arm64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.musl-linux-arm64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts \
|
debhelper gnupg devscripts \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.amd64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.amd64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,10 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts \
|
debhelper gnupg devscripts \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.arm64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.arm64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -10,10 +14,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts \
|
debhelper gnupg devscripts \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM ubuntu:bionic
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-jammy
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,16 +15,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg wget ca-certificates devscripts \
|
debhelper gnupg wget ca-certificates devscripts \
|
||||||
mmv build-essential libcurl4-openssl-dev libfontconfig1-dev \
|
mmv build-essential libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
# Install dotnet repository
|
&& apt-get autoremove -yqq \
|
||||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
&& mkdir -p dotnet-sdk \
|
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.amd64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.amd64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM ubuntu:bionic
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-jammy
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,16 +15,10 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg wget ca-certificates devscripts \
|
debhelper gnupg wget ca-certificates devscripts \
|
||||||
mmv build-essential lsb-release
|
mmv build-essential lsb-release
|
||||||
|
|
||||||
# Install dotnet repository
|
|
||||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
|
||||||
&& mkdir -p dotnet-sdk \
|
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
|
||||||
|
|
||||||
# Prepare the cross-toolchain
|
# Prepare the cross-toolchain
|
||||||
RUN rm /etc/apt/sources.list \
|
RUN rm /etc/apt/sources.list \
|
||||||
&& export CODENAME="$( lsb_release -c -s )" \
|
&& export CODENAME="$( lsb_release -c -s )" \
|
||||||
|
@ -34,16 +32,19 @@ RUN rm /etc/apt/sources.list \
|
||||||
&& echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \
|
&& echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \
|
||||||
&& dpkg --add-architecture arm64 \
|
&& dpkg --add-architecture arm64 \
|
||||||
&& apt-get update -yqq \
|
&& apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends cross-gcc-dev \
|
&& apt-get install --no-install-recommends -yqq cross-gcc-dev \
|
||||||
&& TARGET_LIST="arm64" cross-gcc-gensource 6 \
|
&& TARGET_LIST="arm64" cross-gcc-gensource 12 \
|
||||||
&& cd cross-gcc-packages-amd64/cross-gcc-6-arm64 \
|
&& cd cross-gcc-packages-amd64/cross-gcc-12-arm64 \
|
||||||
&& ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \
|
&& ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
gcc-6-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu \
|
gcc-12-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu \
|
||||||
bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev \
|
bison flex libtool gdb sharutils netbase libmpc-dev \
|
||||||
libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
||||||
zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 \
|
zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 \
|
||||||
libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust0:arm64 libstdc++6:arm64 libssl-dev:arm64
|
libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust1:arm64 libstdc++6:arm64 libssl-dev:arm64 \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.arm64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.arm64 /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM ubuntu:bionic
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-jammy
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -11,16 +15,10 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg wget ca-certificates devscripts \
|
debhelper gnupg wget ca-certificates devscripts \
|
||||||
mmv build-essential lsb-release
|
mmv build-essential lsb-release
|
||||||
|
|
||||||
# Install dotnet repository
|
|
||||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/5226a5fa-8c0b-474f-b79a-8984ad7c5beb/3113ccbf789c9fd29972835f0f334b7a/dotnet-sdk-8.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
|
||||||
&& mkdir -p dotnet-sdk \
|
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
|
||||||
|
|
||||||
# Prepare the cross-toolchain
|
# Prepare the cross-toolchain
|
||||||
RUN rm /etc/apt/sources.list \
|
RUN rm /etc/apt/sources.list \
|
||||||
&& export CODENAME="$( lsb_release -c -s )" \
|
&& export CODENAME="$( lsb_release -c -s )" \
|
||||||
|
@ -34,16 +32,19 @@ RUN rm /etc/apt/sources.list \
|
||||||
&& echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \
|
&& echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \
|
||||||
&& dpkg --add-architecture armhf \
|
&& dpkg --add-architecture armhf \
|
||||||
&& apt-get update -yqq \
|
&& apt-get update -yqq \
|
||||||
&& apt-get install -yqq cross-gcc-dev \
|
&& apt-get install --no-install-recommends -yqq cross-gcc-dev \
|
||||||
&& TARGET_LIST="armhf" cross-gcc-gensource 6 \
|
&& TARGET_LIST="armhf" cross-gcc-gensource 12 \
|
||||||
&& cd cross-gcc-packages-amd64/cross-gcc-6-armhf \
|
&& cd cross-gcc-packages-amd64/cross-gcc-12-armhf \
|
||||||
&& ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \
|
&& ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
gcc-6-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf \
|
gcc-12-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf \
|
||||||
bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev \
|
bison flex libtool gdb sharutils netbase libmpc-dev \
|
||||||
libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev \
|
||||||
zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf \
|
zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf \
|
||||||
libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust0:armhf libstdc++6:armhf libssl-dev:armhf
|
libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust1:armhf libstdc++6:armhf libssl-dev:armhf \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to build script
|
# Link to build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim
|
ARG DOTNET_VERSION=8.0
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
|
||||||
|
|
||||||
# Docker build arguments
|
# Docker build arguments
|
||||||
ARG SOURCE_DIR=/jellyfin
|
ARG SOURCE_DIR=/jellyfin
|
||||||
ARG ARTIFACT_DIR=/dist
|
ARG ARTIFACT_DIR=/dist
|
||||||
|
|
||||||
# Docker run environment
|
# Docker run environment
|
||||||
ENV SOURCE_DIR=/jellyfin
|
ENV SOURCE_DIR=/jellyfin
|
||||||
ENV ARTIFACT_DIR=/dist
|
ENV ARTIFACT_DIR=/dist
|
||||||
|
@ -10,10 +14,13 @@ ENV IS_DOCKER=YES
|
||||||
|
|
||||||
# Prepare Debian build environment
|
# Prepare Debian build environment
|
||||||
RUN apt-get update -yqq \
|
RUN apt-get update -yqq \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install --no-install-recommends -yqq \
|
||||||
debhelper gnupg devscripts unzip \
|
debhelper gnupg devscripts unzip \
|
||||||
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
mmv libcurl4-openssl-dev libfontconfig1-dev \
|
||||||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip
|
libfreetype6-dev libssl-dev libssl3 liblttng-ust1 zip \
|
||||||
|
&& apt-get clean autoclean -yqq \
|
||||||
|
&& apt-get autoremove -yqq \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Link to docker-build script
|
# Link to docker-build script
|
||||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.windows.amd64 /build.sh
|
RUN ln -sf ${SOURCE_DIR}/deployment/build.windows.amd64 /build.sh
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#= CentOS/RHEL 7+ amd64 .rpm
|
#= CentOS/RHEL 8+ amd64 .rpm
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o xtrace
|
set -o xtrace
|
||||||
|
@ -42,7 +42,7 @@ rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm
|
||||||
mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm "${ARTIFACT_DIR}/"
|
mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm "${ARTIFACT_DIR}/"
|
||||||
|
|
||||||
if [[ ${IS_DOCKER} == YES ]]; then
|
if [[ ${IS_DOCKER} == YES ]]; then
|
||||||
chown -Rc $(stat -c %u:%g "${ARTIFACT_DIR}") "${ARTIFACT_DIR}"
|
chown -Rc "$(stat -c %u:%g "${ARTIFACT_DIR}")" "${ARTIFACT_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f fedora/jellyfin*.tar.gz
|
rm -f fedora/jellyfin*.tar.gz
|
||||||
|
@ -51,7 +51,7 @@ if [[ ${IS_DOCKER} == YES ]]; then
|
||||||
pushd fedora
|
pushd fedora
|
||||||
|
|
||||||
cp -a /tmp/spec.orig jellyfin.spec
|
cp -a /tmp/spec.orig jellyfin.spec
|
||||||
chown -Rc $(stat -c %u:%g "${ARTIFACT_DIR}") "${ARTIFACT_DIR}"
|
chown -Rc "$(stat -c %u:%g "${ARTIFACT_DIR}")" "${ARTIFACT_DIR}"
|
||||||
|
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -37,7 +37,7 @@ mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} "${ARTIFACT_DIR}/"
|
||||||
|
|
||||||
if [[ ${IS_DOCKER} == YES ]]; then
|
if [[ ${IS_DOCKER} == YES ]]; then
|
||||||
cp -a /tmp/control.orig debian/control
|
cp -a /tmp/control.orig debian/control
|
||||||
chown -Rc $(stat -c %u:%g "${ARTIFACT_DIR}") "${ARTIFACT_DIR}"
|
chown -Rc "$(stat -c %u:%g "${ARTIFACT_DIR}")" "${ARTIFACT_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -38,7 +38,7 @@ mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} "${ARTIFACT_DIR}/"
|
||||||
|
|
||||||
if [[ ${IS_DOCKER} == YES ]]; then
|
if [[ ${IS_DOCKER} == YES ]]; then
|
||||||
cp -a /tmp/control.orig debian/control
|
cp -a /tmp/control.orig debian/control
|
||||||
chown -Rc $(stat -c %u:%g "${ARTIFACT_DIR}") "${ARTIFACT_DIR}"
|
chown -Rc "$(stat -c %u:%g "${ARTIFACT_DIR}")" "${ARTIFACT_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -38,7 +38,7 @@ mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} "${ARTIFACT_DIR}/"
|
||||||
|
|
||||||
if [[ ${IS_DOCKER} == YES ]]; then
|
if [[ ${IS_DOCKER} == YES ]]; then
|
||||||
cp -a /tmp/control.orig debian/control
|
cp -a /tmp/control.orig debian/control
|
||||||
chown -Rc $(stat -c %u:%g "${ARTIFACT_DIR}") "${ARTIFACT_DIR}"
|
chown -Rc "$(stat -c %u:%g "${ARTIFACT_DIR}")" "${ARTIFACT_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue