Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion ImmichFrame.WebApi.Tests/Helpers/Config/ConfigLoaderTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Json;
using System.Collections;
using System.Reflection;
using ImmichFrame.Core.Interfaces;
Expand Down Expand Up @@ -68,6 +69,56 @@ public void TestLoadConfigV2Yaml()
VerifyConfig(config, true, false);
}

[Test]
public void TestLoadConfigV2Json_WeatherApiKeyFile()
{
var configDir = Path.Combine(Path.GetTempPath(), $"immichframe-weather-{Guid.NewGuid():N}");
Directory.CreateDirectory(configDir);
var keyFile = Path.Combine(configDir, "weather-api-key");

try
{
File.WriteAllText(keyFile, " weather-api-key \n");
var settings = new
{
General = new { WeatherApiKey = "", WeatherApiKeyFile = keyFile },
Accounts = new[]
{
new { ImmichServerUrl = "https://immich.example", ApiKey = "account-api-key" }
}
};
File.WriteAllText(
Path.Combine(configDir, "Settings.json"),
JsonSerializer.Serialize(settings));

var config = _configLoader.LoadConfig(configDir);

Assert.That(config.GeneralSettings.WeatherApiKey, Is.EqualTo("weather-api-key"));
}
finally
{
Directory.Delete(configDir, recursive: true);
}
}

[Test]
public void TestLoadConfigV2Json_WeatherApiKeyFile_ConflictsWithInlineKey()
{
var settings = new GeneralSettings
{
WeatherApiKey = "inline-weather-api-key",
WeatherApiKeyFile = "weather-api-key-file"
};

var exception = Assert.Throws<Exception>(() => settings.Validate());

Assert.That(
exception!.Message,
Is.EqualTo("Cannot specify both WeatherApiKey and WeatherApiKeyFile. Please provide only one."));
}



private void VerifyConfig(IServerSettings serverSettings, bool usePrefix, bool expectNullApiKeyFile)
{
VerifyProperties(serverSettings.GeneralSettings);
Expand Down Expand Up @@ -107,7 +158,8 @@ private void VerifyProperties(object o, string? prefix = "", bool expectNullApiK
switch (type)
{
case var t when t == typeof(string):
if (prop.Name.Equals("ApiKeyFile") && expectNullApiKeyFile)
if (prop.Name.Equals("ApiKeyFile") && expectNullApiKeyFile ||
prop.Name.Equals("WeatherApiKeyFile") && value is null)
{
Assert.That(value, Is.EqualTo(null), prop.Name);
}
Expand Down
14 changes: 13 additions & 1 deletion ImmichFrame.WebApi/Models/ServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,24 @@ public class GeneralSettings : IGeneralSettings, IConfigSettable
public List<string> Webcalendars { get; set; } = new();
public int RefreshAlbumPeopleInterval { get; set; } = 12;
public string? WeatherApiKey { get; set; } = string.Empty;
public string? WeatherApiKeyFile { get; set; } = null;
public string? UnitSystem { get; set; } = "imperial";
public string? WeatherLatLong { get; set; } = "40.7128,74.0060";
public string? Webhook { get; set; }
public string? AuthenticationSecret { get; set; }

public void Validate() { }
public void Validate()
{
if (!string.IsNullOrWhiteSpace(WeatherApiKeyFile))
{
if (!string.IsNullOrWhiteSpace(WeatherApiKey))
{
throw new Exception("Cannot specify both WeatherApiKey and WeatherApiKeyFile. Please provide only one.");
}

WeatherApiKey = File.ReadAllText(WeatherApiKeyFile).Trim();
}
}
}

public class ServerAccountSettings : IAccountSettings, IConfigSettable
Expand Down
1 change: 1 addition & 0 deletions docker/Settings.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"PhotoDateFormat": "MM/dd/yyyy",
"ImageLocationFormat": "City,State,Country",
"WeatherApiKey": "",
"WeatherApiKeyFile": null,
"UnitSystem": "imperial",
"WeatherLatLong": "40.730610,-73.935242",
"Webhook": null,
Expand Down
2 changes: 2 additions & 0 deletions docker/Settings.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ General:
RefreshAlbumPeopleInterval: 12
PhotoDateFormat: MM/dd/yyyy
ImageLocationFormat: 'City,State,Country'
# Set either WeatherApiKey or WeatherApiKeyFile; leave both empty to disable weather.
WeatherApiKey: ''
# WeatherApiKeyFile: '/path/to/weather-api.key'
UnitSystem: imperial
WeatherLatLong: '40.730610,-73.935242'
Webhook: null
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ General:
PhotoDateFormat: 'MM/dd/yyyy' # string
ImageLocationFormat: 'City,State,Country'
# Get an API key from OpenWeatherMap: https://openweathermap.org/appid
# Set either WeatherApiKey or WeatherApiKeyFile; leave both empty to disable weather.
WeatherApiKey: '' # string
# WeatherApiKeyFile: '/path/to/weather-api.key'
# Imperial or metric system (Fahrenheit or Celsius)
UnitSystem: 'imperial' # 'imperial' | 'metric'
# Set the weather location with lat/lon.
Expand Down