Skip to content

Instantly share code, notes, and snippets.

@JPVenson
Last active July 19, 2023 13:03
Show Gist options
  • Save JPVenson/e765d97c3c1eb92fb11f0856c6034e6a to your computer and use it in GitHub Desktop.
Save JPVenson/e765d97c3c1eb92fb11f0856c6034e6a to your computer and use it in GitHub Desktop.

Revisions

  1. JPVenson revised this gist Mar 4, 2023. 1 changed file with 33 additions and 19 deletions.
    52 changes: 33 additions & 19 deletions docs.md
    Original file line number Diff line number Diff line change
    @@ -5,25 +5,35 @@ to cleanup the collection.xml for missing link entires.

    ## Linux Host

    To run this on linus, ensure you have a dotnet version installed.
    `https://learn.microsoft.com/en-us/dotnet/core/install/linux`
    or for the most part, this oneliner will install dotnet on your system:
    `curl -sL "https://dot.net/v1/dotnet-install.sh" | bash`
    To run this on linus, ensure you have a dotnet version installed.
    `https://learn.microsoft.com/en-us/dotnet/core/install/linux`
    or for the most part, this oneliner will install dotnet on your system:
    ```bash
    curl -sL "https://dot.net/v1/dotnet-install.sh" | bash
    ```

    ## Windows Host
    Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
    Visit the mirosoft page `https://dotnet.microsoft.com/en-us/download/dotnet` and download it or verifiy that you have the latest dotnet version installed
    by opening a new commandline and running:
    `dotnet --info`
    this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    You can also just use this command to ensure dotnet7 is installed
    `winget install Microsoft.DotNet.SDK.7`
    Visit the mirosoft page `https://dotnet.microsoft.com/en-us/download/dotnet` and download it or verifiy that you have the latest dotnet version installed
    by opening a new commandline and running:
    ```bash
    dotnet --info
    ```
    this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    You can also just use this command to ensure dotnet7 is installed
    ```bash
    winget install Microsoft.DotNet.SDK.7
    ```

    # Setup the Script
    After the install has been completed, navigate to a new folder and create a new c# project via:
    `dotnet new console`
    then download this script and download it in the same directory you just created the new project in like this:
    `curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/5200079b939c7be8e5b2da274d7229a0c4dd5bed/program.cs" -o Program.cs`
    After the install has been completed, navigate to a new folder and create a new c# project via:
    ```bash
    dotnet new console
    ```
    then download this script and download it in the same directory you just created the new project in like this:
    ```bash
    curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/5200079b939c7be8e5b2da274d7229a0c4dd5bed/program.cs" -o Program.cs
    ```

    # Build and Run
    The script can be run Interactivly or controlled via commandline arguments or enviorment variables.
    @@ -49,10 +59,14 @@ Syntax: `mediaRoot=PATH`
    [Interactive] [EnviormentVariable] [arguments]

    # Run the Script
    after that, compile and run this file with:
    `dotnet run`
    To add arguments, use a blank `--` to seperate arguments to the dotnet call and the app.
    For example, this sets the RunDry flag and substitutes the root path `\mnt\media` with `X:\videos\store` in a case where you run the script on a windows host and want to modify the collections in the linux path format.
    `dotnet run -- whatif=y "targetPathSubsitution=\mnt\media\:X:\videos\store"`
    after that, compile and run this file with:
    ```bash
    dotnet run
    ```
    To add arguments, use a blank `--` to seperate arguments to the dotnet call and the app.
    For example, this sets the RunDry flag and substitutes the root path `\mnt\media` with `X:\videos\store` in a case where you run the script on a windows host and want to modify the collections in the linux path format.
    ```bash
    dotnet run -- whatif=y "targetPathSubsitution=\mnt\media\:X:\videos\store"
    ```


  2. JPVenson revised this gist Mar 4, 2023. 1 changed file with 13 additions and 9 deletions.
    22 changes: 13 additions & 9 deletions docs.md
    Original file line number Diff line number Diff line change
    @@ -26,23 +26,27 @@ then download this script and download it in the same directory you just created
    `curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/5200079b939c7be8e5b2da274d7229a0c4dd5bed/program.cs" -o Program.cs`

    # Build and Run
    The script can be run Interactivly or controlled via commandline arguments or enviorment variables.
    The script can be run Interactivly or controlled via commandline arguments or enviorment variables.

    ### Whatif
    The script can dryrun without applying modifications.
    Syntax: `whatif=y` [EnviormentVariable] [arguments]
    The script can dryrun without applying modifications.
    Syntax: `whatif=y`
    [EnviormentVariable] [arguments]

    ### targetPathSubsitution
    Replaces the root of the media path as read from the collection with a fixed other. Helpfull when you _BACKUP_ your collection folder and move it to another system
    Syntax: `targetPathSubsitution=ORIGINAL:NEW` [EnviormentVariable] [arguments]
    Replaces the root of the media path as read from the collection with a fixed other. Helpfull when you _BACKUP_ your collection folder and move it to another system
    Syntax: `targetPathSubsitution=ORIGINAL:NEW`
    [EnviormentVariable] [arguments]

    ### input
    Path to the directory where the `collection.xml` files are located in. Usually under you config directory `\data\collections`.
    Syntax: `input=PATH` [Interactive] [EnviormentVariable] [arguments]
    Path to the directory where the `collection.xml` files are located in. Usually under you config directory `\data\collections`.
    Syntax: `input=PATH`
    [Interactive] [EnviormentVariable] [arguments]

    ### mediaRoot
    The path to the root of your media.
    Syntax: `mediaRoot=PATH` [Interactive] [EnviormentVariable] [arguments]
    The path to the root of your media.
    Syntax: `mediaRoot=PATH`
    [Interactive] [EnviormentVariable] [arguments]

    # Run the Script
    after that, compile and run this file with:
  3. JPVenson revised this gist Mar 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion docs.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ You can also just use this command to ensure dotnet7 is installed
    After the install has been completed, navigate to a new folder and create a new c# project via:
    `dotnet new console`
    then download this script and download it in the same directory you just created the new project in like this:
    `curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/315739fdba9c03dceb12b6fba6ce1532c878cc36/program.cs" -o Program.cs`
    `curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/5200079b939c7be8e5b2da274d7229a0c4dd5bed/program.cs" -o Program.cs`

    # Build and Run
    The script can be run Interactivly or controlled via commandline arguments or enviorment variables.
  4. JPVenson revised this gist Mar 4, 2023. 2 changed files with 57 additions and 28 deletions.
    54 changes: 54 additions & 0 deletions docs.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    # BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!

    This is the Cs version of the script posted by michaelkrieger at https://github.com/jellyfin/jellyfin/issues/1907#issuecomment-1122821083
    to cleanup the collection.xml for missing link entires.

    ## Linux Host

    To run this on linus, ensure you have a dotnet version installed.
    `https://learn.microsoft.com/en-us/dotnet/core/install/linux`
    or for the most part, this oneliner will install dotnet on your system:
    `curl -sL "https://dot.net/v1/dotnet-install.sh" | bash`

    ## Windows Host
    Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
    Visit the mirosoft page `https://dotnet.microsoft.com/en-us/download/dotnet` and download it or verifiy that you have the latest dotnet version installed
    by opening a new commandline and running:
    `dotnet --info`
    this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    You can also just use this command to ensure dotnet7 is installed
    `winget install Microsoft.DotNet.SDK.7`

    # Setup the Script
    After the install has been completed, navigate to a new folder and create a new c# project via:
    `dotnet new console`
    then download this script and download it in the same directory you just created the new project in like this:
    `curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/315739fdba9c03dceb12b6fba6ce1532c878cc36/program.cs" -o Program.cs`

    # Build and Run
    The script can be run Interactivly or controlled via commandline arguments or enviorment variables.

    ### Whatif
    The script can dryrun without applying modifications.
    Syntax: `whatif=y` [EnviormentVariable] [arguments]

    ### targetPathSubsitution
    Replaces the root of the media path as read from the collection with a fixed other. Helpfull when you _BACKUP_ your collection folder and move it to another system
    Syntax: `targetPathSubsitution=ORIGINAL:NEW` [EnviormentVariable] [arguments]

    ### input
    Path to the directory where the `collection.xml` files are located in. Usually under you config directory `\data\collections`.
    Syntax: `input=PATH` [Interactive] [EnviormentVariable] [arguments]

    ### mediaRoot
    The path to the root of your media.
    Syntax: `mediaRoot=PATH` [Interactive] [EnviormentVariable] [arguments]

    # Run the Script
    after that, compile and run this file with:
    `dotnet run`
    To add arguments, use a blank `--` to seperate arguments to the dotnet call and the app.
    For example, this sets the RunDry flag and substitutes the root path `\mnt\media` with `X:\videos\store` in a case where you run the script on a windows host and want to modify the collections in the linux path format.
    `dotnet run -- whatif=y "targetPathSubsitution=\mnt\media\:X:\videos\store"`


    31 changes: 3 additions & 28 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -3,34 +3,9 @@
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * This is the Cs version of the script posted by michaelkrieger at https://github.com/jellyfin/jellyfin/issues/1907#issuecomment-1122821083
    * to cleanup the collection.xml for missing link entires
    * <linux>
    * To run this on linus, ensure you have a dotnet version installed.
    * https://learn.microsoft.com/en-us/dotnet/core/install/linux
    * or for the most part, this oneliner will install dotnet on your system:
    * curl -sL "https://dot.net/v1/dotnet-install.sh" | bash
    * </linux>
    * <windows>
    * Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
    * Visit the mirosoft page (https://dotnet.microsoft.com/en-us/download/dotnet) and download it or verifiy that you have the latest dotnet version installed
    * by opening a new commandline and running:
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * You can also just use this command to ensure dotnet7 is installed
    * winget install Microsoft.DotNet.SDK.7
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it in the same directory you just created the new project in like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/315739fdba9c03dceb12b6fba6ce1532c878cc36/program.cs" -o Program.cs
    * after that, compile and run this file with:
    * dotnet run
    * <Build-And-Run>
    */
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * READ.THE.MANUAL
    */

    using System.Xml.Linq;
    using System.Xml.XPath;
  5. JPVenson revised this gist Feb 28, 2023. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,9 @@
    /*
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * BEFORE YOU START: BACKUP YOUR CONFIGURATION. YOU. HAVE. BEEN. WARNED!
    * This is the Cs version of the script posted by michaelkrieger at https://github.com/jellyfin/jellyfin/issues/1907#issuecomment-1122821083
    * to cleanup the collection.xml for missing link entires
    * <linux>
  6. JPVenson revised this gist Feb 28, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it in the same directory you just created the new project in like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/90c697d14ca32b6304784861a3a9419526de358c/program.cs" -o Program.cs
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/315739fdba9c03dceb12b6fba6ce1532c878cc36/program.cs" -o Program.cs
    * after that, compile and run this file with:
    * dotnet run
    * <Build-And-Run>
  7. JPVenson revised this gist Feb 28, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * You can also just use this command to ensure dotnet7 is installed
    * winget install Microsoft.DotNet.DesktopRuntime.7
    * winget install Microsoft.DotNet.SDK.7
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
  8. JPVenson revised this gist Feb 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it in the same directory you just created the new project in like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs" -o Program.cs
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/90c697d14ca32b6304784861a3a9419526de358c/program.cs" -o Program.cs
    * after that, compile and run this file with:
    * dotnet run
    * <Build-And-Run>
  9. JPVenson revised this gist Feb 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@
    * This section is the same for both linux and windows.
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it anywhere like this:
    * then download this script and download it in the same directory you just created the new project in like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs" -o Program.cs
    * after that, compile and run this file with:
    * dotnet run
  10. JPVenson revised this gist Feb 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@
    var targetPathSubsitution = GetVariableValue("targetPathSubsitution=")
    ?? Environment.GetEnvironmentVariable("targetPathSubsitution");

    Console.WriteLine("Path to the 'collection.xml' file");
    Console.WriteLine("Path to the directory the 'collection.xml' files are located in.");
    var collectionDirectory = GetVariableValue("input") ?? Console.ReadLine();
    if (!Directory.Exists(collectionDirectory))
    {
  11. JPVenson revised this gist Feb 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@
    * To run this on linus, ensure you have a dotnet version installed.
    * https://learn.microsoft.com/en-us/dotnet/core/install/linux
    * or for the most part, this oneliner will install dotnet on your system:
    * bash < (curl -sL "https://dot.net/v1/dotnet-install.sh")
    * curl -sL "https://dot.net/v1/dotnet-install.sh" | bash
    * </linux>
    * <windows>
    * Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
  12. JPVenson revised this gist Feb 4, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * You can also just use this command to ensure dotnet7 is installed
    * winget install Microsoft.DotNet.SDK.7
    * winget install Microsoft.DotNet.DesktopRuntime.7
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
  13. JPVenson revised this gist Feb 4, 2023. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion program.cs
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,9 @@
    * Visit the mirosoft page (https://dotnet.microsoft.com/en-us/download/dotnet) and download it or verifiy that you have the latest dotnet version installed
    * by opening a new commandline and running:
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * You can also just use this command to ensure dotnet7 is installed
    * winget install Microsoft.DotNet.SDK.7
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
  14. JPVenson revised this gist Feb 4, 2023. 1 changed file with 4 additions and 8 deletions.
    12 changes: 4 additions & 8 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -6,24 +6,20 @@
    * https://learn.microsoft.com/en-us/dotnet/core/install/linux
    * or for the most part, this oneliner will install dotnet on your system:
    * bash < (curl -sL "https://dot.net/v1/dotnet-install.sh")
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it anywhere like this:
    * Program.cs < curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs"
    * </linux>
    * <windows>
    * Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
    * Visit the mirosoft page (https://dotnet.microsoft.com/en-us/download/dotnet) and download it or verifiy that you have the latest dotnet version installed
    * by opening a new commandline and running:
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * after that, download this script and download it anywhere like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs" -o Program.cs
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it anywhere like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs" -o Program.cs
    * after that, compile and run this file with:
    * dotnet run
    * <Build-And-Run>
  15. JPVenson revised this gist Feb 4, 2023. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,32 @@
    /*
    * This is the Cs version of the script posted by michaelkrieger at https://github.com/jellyfin/jellyfin/issues/1907#issuecomment-1122821083
    * to cleanup the collection.xml for missing link entires
    * <linux>
    * To run this on linus, ensure you have a dotnet version installed.
    * https://learn.microsoft.com/en-us/dotnet/core/install/linux
    * or for the most part, this oneliner will install dotnet on your system:
    * bash < (curl -sL "https://dot.net/v1/dotnet-install.sh")
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * then download this script and download it anywhere like this:
    * Program.cs < curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs"
    * </linux>
    * <windows>
    * Most should have any one dotnet version installed on the system. However i recommand using the latest version (Net7) or at least Net6.
    * Visit the mirosoft page (https://dotnet.microsoft.com/en-us/download/dotnet) and download it or verifiy that you have the latest dotnet version installed
    * by opening a new commandline and running:
    * dotnet --info
    * this should list under ".NET SDKs installed" at least some versions starting with "6.0.000" or higher.
    * after the install has been completed, we must create a new c# project via:
    * dotnet new console
    * after that, download this script and download it anywhere like this:
    * curl "https://gist.github.com/JPVenson/e765d97c3c1eb92fb11f0856c6034e6a/raw/8540ee9bcdb8a1c22cf1cf251f44bc58f8adead6/program.cs" -o Program.cs
    * </windows>
    * <Build-And-Run>
    * This section is the same for both linux and windows.
    * after that, compile and run this file with:
    * dotnet run
    * <Build-And-Run>
    */

    using System.Xml.Linq;
  16. JPVenson revised this gist Jan 31, 2023. 1 changed file with 37 additions and 34 deletions.
    71 changes: 37 additions & 34 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -22,8 +22,8 @@
    ?? Environment.GetEnvironmentVariable("targetPathSubsitution");

    Console.WriteLine("Path to the 'collection.xml' file");
    var collectionFile = GetVariableValue("input") ?? Console.ReadLine();
    if (!File.Exists(collectionFile))
    var collectionDirectory = GetVariableValue("input") ?? Console.ReadLine();
    if (!Directory.Exists(collectionDirectory))
    {
    Console.WriteLine("File does not exist. Exit.");
    return;
    @@ -37,46 +37,49 @@
    return;
    }

    using var documentStream = File.Open(collectionFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    var document = await XDocument.LoadAsync(documentStream, LoadOptions.PreserveWhitespace, CancellationToken.None);
    var paths = document.XPathSelectElements("//CollectionItem/Path");
    foreach (var path in paths)
    foreach (var collectionFile in Directory.EnumerateFiles(collectionDirectory, "collection.xml", SearchOption.AllDirectories))
    {
    var sourcePath = path.Value;

    if (!string.IsNullOrWhiteSpace(targetPathSubsitution))
    await using var documentStream = File.Open(collectionFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    var document = await XDocument.LoadAsync(documentStream, LoadOptions.PreserveWhitespace, CancellationToken.None);
    var paths = document.XPathSelectElements("//CollectionItem/Path");
    foreach (var path in paths)
    {
    var subsitutionParts = targetPathSubsitution.Split(':');
    sourcePath = sourcePath.Replace(subsitutionParts[0], subsitutionParts[1]);
    }
    var sourcePath = path.Value;

    sourcePath = sourcePath.TrimStart('/', '\\');
    if (!string.IsNullOrWhiteSpace(targetPathSubsitution))
    {
    var subsitutionParts = targetPathSubsitution.Split(':');
    sourcePath = sourcePath.Replace(subsitutionParts[0], subsitutionParts[1]);
    }

    var targetPath = Path.Combine(mediaRoot, sourcePath);
    Console.Write($"Check '{targetPath}': ");
    if (File.Exists(targetPath))
    {
    Console.WriteLine("Exists.");
    }
    else
    {
    Console.Write("Does not exist.");
    if (whatif)
    sourcePath = sourcePath.TrimStart('/', '\\');

    var targetPath = Path.Combine(mediaRoot, sourcePath);
    Console.Write($"Check '{targetPath}': ");
    if (File.Exists(targetPath))
    {
    Console.WriteLine();
    Console.WriteLine("Exists.");
    }
    else
    {
    Console.WriteLine("Delete entry.");
    path.Parent.Remove();
    Console.Write("Does not exist.");
    if (whatif)
    {
    Console.WriteLine();
    }
    else
    {
    Console.WriteLine("Delete entry.");
    path.Parent.Remove();
    }
    }
    }
    }

    if (!whatif)
    {
    documentStream.Seek(0, SeekOrigin.Begin);
    documentStream.SetLength(0);
    await document.SaveAsync(documentStream, SaveOptions.None, CancellationToken.None);
    await documentStream.FlushAsync();
    }
    if (!whatif)
    {
    documentStream.Seek(0, SeekOrigin.Begin);
    documentStream.SetLength(0);
    await document.SaveAsync(documentStream, SaveOptions.None, CancellationToken.None);
    await documentStream.FlushAsync();
    }
    }
  17. JPVenson created this gist Jan 31, 2023.
    82 changes: 82 additions & 0 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    /*
    * This is the Cs version of the script posted by michaelkrieger at https://github.com/jellyfin/jellyfin/issues/1907#issuecomment-1122821083
    * to cleanup the collection.xml for missing link entires
    */

    using System.Xml.Linq;
    using System.Xml.XPath;

    string? GetVariableValue(string variableName)
    {
    var variableValue = Environment.GetEnvironmentVariable(variableName);
    if (variableValue != null)
    {
    return variableValue;
    }

    return args.FirstOrDefault(e => e.StartsWith(variableName + "="))?.Remove(0, variableName.Length + 1);
    }

    var whatif = GetVariableValue("whatif") == "y";
    var targetPathSubsitution = GetVariableValue("targetPathSubsitution=")
    ?? Environment.GetEnvironmentVariable("targetPathSubsitution");

    Console.WriteLine("Path to the 'collection.xml' file");
    var collectionFile = GetVariableValue("input") ?? Console.ReadLine();
    if (!File.Exists(collectionFile))
    {
    Console.WriteLine("File does not exist. Exit.");
    return;
    }

    Console.WriteLine("Media Root:");
    var mediaRoot = GetVariableValue("mediaRoot") ?? Console.ReadLine();
    if (!Directory.Exists(mediaRoot))
    {
    Console.WriteLine("Media Directory does not exist. Exit.");
    return;
    }

    using var documentStream = File.Open(collectionFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    var document = await XDocument.LoadAsync(documentStream, LoadOptions.PreserveWhitespace, CancellationToken.None);
    var paths = document.XPathSelectElements("//CollectionItem/Path");
    foreach (var path in paths)
    {
    var sourcePath = path.Value;

    if (!string.IsNullOrWhiteSpace(targetPathSubsitution))
    {
    var subsitutionParts = targetPathSubsitution.Split(':');
    sourcePath = sourcePath.Replace(subsitutionParts[0], subsitutionParts[1]);
    }

    sourcePath = sourcePath.TrimStart('/', '\\');

    var targetPath = Path.Combine(mediaRoot, sourcePath);
    Console.Write($"Check '{targetPath}': ");
    if (File.Exists(targetPath))
    {
    Console.WriteLine("Exists.");
    }
    else
    {
    Console.Write("Does not exist.");
    if (whatif)
    {
    Console.WriteLine();
    }
    else
    {
    Console.WriteLine("Delete entry.");
    path.Parent.Remove();
    }
    }
    }

    if (!whatif)
    {
    documentStream.Seek(0, SeekOrigin.Begin);
    documentStream.SetLength(0);
    await document.SaveAsync(documentStream, SaveOptions.None, CancellationToken.None);
    await documentStream.FlushAsync();
    }