Just json to c#

This commit is contained in:
2025-08-22 13:00:01 -07:00
parent 895dab9413
commit 47fc079e0a
66 changed files with 2246 additions and 17 deletions

View File

@ -0,0 +1,88 @@
using ImmichToSlideshow.Models.Open.API.Band;
using ImmichToSlideshow.Services;
using Microsoft.AspNetCore.Mvc;
namespace ImmichToSlideshow.Controllers;
[ApiController]
[Route("api/v1/[controller]")]
public class BandController(BandService pushPostService, Dictionary<string, Token> tokens) : ControllerBase {
private readonly BandService _BandService = pushPostService;
private readonly Dictionary<string, Token> _Tokens = tokens;
[HttpGet("display")]
public IActionResult Get(string code) {
Token? token = _BandService.GetToken(code);
if (token is null) {
if (_Tokens is not null) {
_BandService.GetAuthorizationCode();
}
return BadRequest("Unable to get token");
}
_Tokens.Add(code, token);
return Content(code, "text/plain");
}
[HttpGet("bands")]
public IActionResult Bands() {
Models.Open.Api.Band.Bands.Root? result = _BandService.GetBands(_Tokens);
return result is null ? BadRequest("Unable to get bands") : Ok(result);
}
[HttpGet("{band_key}/profile")]
public IActionResult Profile(string band_key) {
Models.Open.Api.Band.Profile.Root? result = _BandService.GetProfile(_Tokens, band_key);
return result is null ? BadRequest("Unable to get profile") : Ok(result);
}
[HttpGet("{band_key}/post/post_key")]
public IActionResult Posts(string band_key, string post_key) {
Models.Open.Api.Band.Post.Root? result = _BandService.GetPost(_Tokens, band_key, post_key);
return result is null ? BadRequest("Unable to get posts") : Ok(result);
}
[HttpGet("{band_key}/comments/post_key")]
public IActionResult comments(string band_key, string post_key, string sort = "recent") {
Models.Open.Api.Band.Comments.Root? result = _BandService.GetComments(_Tokens, band_key, post_key, sort);
return result is null ? BadRequest("Unable to get comments") : Ok(result);
}
[HttpGet("{band_key}/albums")]
public IActionResult albums(string band_key) {
Models.Open.Api.Band.Albums.Root? result = _BandService.GetAlbums(_Tokens, band_key);
return result is null ? BadRequest("Unable to get albums") : Ok(result);
}
[HttpGet("{band_key}/photos/{photo_album_key}")]
public IActionResult Photos(string band_key, string photo_album_key) {
Models.Open.Api.Band.Photos.Root? result = _BandService.GetPhotos(_Tokens, band_key, photo_album_key);
return result is null ? BadRequest("Unable to get photos") : Ok(result);
}
[HttpGet("{band_key}/permissions/{permissions}")]
public IActionResult Permissions(string band_key, string permissions) {
Models.Open.Api.Band.Permissions.Root? result = _BandService.GetPermissions(_Tokens, band_key, permissions);
return result is null ? BadRequest("Unable to get permissions") : Ok(result);
}
[HttpGet("{band_key}/post")]
public IActionResult Post(string band_key, string message) {
Models.Open.Api.Band.Root? result = _BandService.WritePost(_Tokens, band_key, message);
if (result is null) {
return BadRequest("Unable to post message");
}
return Content("", "text/plain");
}
[HttpGet("{band_key}/post-comment/{post_key}")]
public IActionResult WritePostComment(string band_key, string post_key, string message) {
Models.Open.Api.Band.Root? result = _BandService.WritePostComment(_Tokens, band_key, post_key, message);
if (result is null) {
return BadRequest("Unable to post message");
}
return Content("", "text/plain");
}
}

View File

@ -5,9 +5,18 @@ namespace ImmichToSlideshow.DependencyInjection;
public static class ServiceCollectionExtensions {
public static IServiceCollection AddServices(this IServiceCollection services, AppSettings appSettings) {
public static IServiceCollection AddServices(this IServiceCollection services, AppSettings appSettings, Dictionary<string, Models.Open.API.Band.Token> tokens) {
_ = services.AddControllers();
_ = services.AddScoped<AssetService>();
_ = services.AddScoped<BandService>();
_ = services.AddSingleton(_ => tokens);
_ = services.AddSingleton(_ => appSettings);
if (appSettings.Settings.Band is not null && !string.IsNullOrEmpty(appSettings.Settings.Band.BasicAuthorization)) {
_ = services.AddHttpClient(nameof(AppSettings.Settings.Band), client => {
client.BaseAddress = new Uri("https://openapi.band.us/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
}
return services;
}

View File

@ -11,28 +11,42 @@ public record AppSettings(string Company, Settings Settings, string URLs, string
}
private static void Verify(AppSettings appSettings) {
if (appSettings?.Company is null)
if (appSettings?.Company is null) {
throw new NullReferenceException(nameof(Company));
if (appSettings?.URLs is null)
}
if (appSettings?.URLs is null) {
throw new NullReferenceException(nameof(URLs));
if (appSettings?.WithOrigins is null)
}
if (appSettings?.WithOrigins is null) {
throw new NullReferenceException(nameof(WithOrigins));
if (appSettings?.Settings?.AddDays is null)
}
if (appSettings?.Settings?.AddDays is null) {
throw new NullReferenceException(nameof(Settings.AddDays));
if (appSettings?.Settings?.ArchivedTag is null)
}
if (appSettings?.Settings?.ArchivedTag is null) {
throw new NullReferenceException(nameof(Settings.ArchivedTag));
if (appSettings?.Settings?.ConnectionString is null)
}
if (appSettings?.Settings?.ConnectionString is null) {
throw new NullReferenceException(nameof(Settings.ConnectionString));
if (appSettings?.Settings?.DigiKam4 is null)
}
if (appSettings?.Settings?.Band is null) {
throw new NullReferenceException(nameof(Settings.Band));
}
if (appSettings?.Settings?.DigiKam4 is null) {
throw new NullReferenceException(nameof(Settings.DigiKam4));
if (appSettings?.Settings?.FilterTags is null)
}
if (appSettings?.Settings?.FilterTags is null) {
throw new NullReferenceException(nameof(Settings.FilterTags));
if (appSettings?.Settings?.ImmichUploadDirectory is null)
}
if (appSettings?.Settings?.ImmichUploadDirectory is null) {
throw new NullReferenceException(nameof(Settings.ImmichUploadDirectory));
if (appSettings?.Settings?.RandomResultsDirectory is null)
}
if (appSettings?.Settings?.RandomResultsDirectory is null) {
throw new NullReferenceException(nameof(Settings.RandomResultsDirectory));
if (appSettings?.Settings?.SyncDirectory is null)
}
if (appSettings?.Settings?.SyncDirectory is null) {
throw new NullReferenceException(nameof(Settings.SyncDirectory));
}
}
public static AppSettings Get(IConfigurationRoot configurationRoot) {
@ -46,10 +60,12 @@ public record AppSettings(string Company, Settings Settings, string URLs, string
if (company is null || settings is null || urls is null || withOrigins is null) {
List<string> paths = [];
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) {
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) {
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
}
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) {
continue;
}
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");

View File

@ -0,0 +1,21 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models;
public record Band(string? BasicAuthorization,
int? ClientId,
string? Redirect,
string? Token) {
public override string ToString() {
string result = JsonSerializer.Serialize(this, BandSourceGenerationContext.Default.Band);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Band))]
public partial class BandSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,99 @@
// public record Root(
// [property: JsonPropertyName("access_token")] string AccessToken,
// [property: JsonPropertyName("expires_in")] int ExpiresIn,
// [property: JsonPropertyName("refresh_token")] string RefreshToken,
// [property: JsonPropertyName("scope")] string Scope,
// [property: JsonPropertyName("token_type")] string TokenType,
// [property: JsonPropertyName("user_key")] string UserKey
// );
// https://developers.band.us/develop/guide/api/get_authorization_code_from_user
// https://auth.band.us/oauth2/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri urlencoded}
// Request
// GET /oauth2/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri urlencoded} HTTP/1.1
// Host: auth.band.us
// A user authorization process takes place within a popup window offered by BAND. The authorization code is sent to redirect_uri which has been passed as a parameter after a successful authorization.
// Response
// HTTP/1.1 302 Found
// Location: {redirect_uri}?code={authorization_code}
// Content-Length: 0
// Content-Type: text/plain; charset=UTF-8
// Request
// GET /oauth2/token?grant_type=authorization_code&code={authorization_code} HTTP/1.1
// Host: auth.band.us
// Authorization: Basic {base64 encoded '{client_id:client_secret}'}
// Response
// HTTP/1.1 200 OK
// Content-Type: application/json;charset=UTF-8
// {
// "access_token": "{access_token}",
// "expires_in": 315359999,
// "refresh_token": "{refresh_token}",
// "scope": "READ_PHOTO READ_ALBUM DELETE_POST READ_BAND_AND_USERS_LIST READ_BAND_PERMISSION CREATE_COMMENT READ_POST WRITE_POST READ_MY_PROFILE READ_COMMENT",
// "token_type": "bearer",
// "user_key": "{user_key}"
// }
// Reference: Interface Specification
// 1) Getting an authorization code
// Request
// URL
// [GET] https://auth.band.us/oauth2/authorize
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// response_type|string|Y|Must input code to get a proper response.
// client_id|Integer|Y|Client ID for your app. Issued when registering your service/app.
// redirect_uri|string|Y|Redirect path you wish to receive your authorization code.
// Response
// redirect uri
// {redirect_uri} received as a request parameter
// redirect parameter
// Parameters
// Name|Type|Description
// code|string|Authorization code issued
// 2) Issuing an access token
// Request
// URL
// [GET] https://auth.band.us/oauth2/token
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// code|string|Y|The authorization code passed
// grant_type|string|Y|Must input authorization_code to get a proper response.
// Header
// Header
// Name|Type|Mandatory|Description
// Authorization|string|Y|Use basic authentication scheme. Basic {perform base64 encoding after combining client_id and client_secret with a colon (:) in between}
// Response
// Content-Type
// : application/json;charset=UTF-8
// Response body
// Response body
// Name|Type|Description
// access_token|string|Access token
// user_key|string|User ID
// expires_in|Integer|Valid period of an access tokens
// token_type|string|Access token type
// Error Code
// Error Code
// http status|Error Code|Description
// 401|invalid_client|Cannot identify the client (client_id error)
// 401|invalid_token|Token does not exist or has been expired
// 400|invalid_request|Undefined error
// 400|invalid_grant|Token cannot be obtained. (wrong authorization_code or login info)
// 400|redirect_uri_mismatch|redirect_uri doesnt match the info given in service/app registration
// 400|unsupported_grant_type|The value for the grant_type is invalid
// 400|unsupported_response_type|The value for the response_type is invalid
// 400|access_denied|User doesnt allow your service/app to access his/her data
// 403|insufficient_scope|Resource server response. Access token does not have the scope of the requested API
// https://auth.band.us/oauth2/authorize?response_type=code&client_id=465368400&redirect_uri=https%3A%2F%2Fband.phares.duckdns.org%2Fapi%2Fv1%2Fband%2Fdisplay

View File

@ -0,0 +1,40 @@
// using System.Text.Json.Serialization;
// namespace ImmichToSlideshow.Models.Open.Api.Band.Band;
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );
// public record ResultData(
// [property: JsonPropertyName("bands")] IReadOnlyList<Band> Bands
// );
// public record Band(
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("cover")] string Cover,
// [property: JsonPropertyName("member_count")] int MemberCount,
// [property: JsonPropertyName("name")] string Name
// );
// https://developers.band.us/develop/guide/api/get_bands
// {
// "result_code": 1,
// "result_data": {
// "bands": [
// {
// "band_key": "AzIEz54gxWeSAB_nwygZ84",
// "cover": "http://img.band.us/111.jpg",
// "member_count": 100,
// "name": "Golf Club"
// },
// {
// "band_key": "AzIEz54gxWeSAB_nwygZ95",
// "cover": "http://img.band.us/222.jpg",
// "member_count": 32,
// "name": "Baseball team"
// }
// ]
// }
// }

View File

@ -0,0 +1,32 @@
// https://developers.band.us/develop/guide/api/write_comment
// Request
// URL
// [POST] https://openapi.band.us/v2/band/post/comment/create
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// post_key|string|Y|Post ID
// body|string|Y|Comment content
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.message|string|Result message
// {
// "result_code": 1,
// "result_data": {
// "message": "success"
// }
// }
// public record ResultData(
// [property: JsonPropertyName("message")] string Message
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,37 @@
// https://developers.band.us/develop/guide/api/get_post_permission
// Request
// URL
// [GET] https://openapi.band.us/v2/band/permissions
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// permissions|list|Y|Permission list to check. Use a comma (,) to separate permissions. (ex, permissions=posting,commenting)
// posting: Post write permission
// commenting: Comment write permission
// contents_deletion: Post/Comment delete permission (Does not check the person who published it.)
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.permissions|list|List of filtered permissions
// {
// "result_code": 1,
// "result_data": {
// "permission": [
// "posting",
// "commenting"
// ]
// }
// }
// public record ResultData(
// [property: JsonPropertyName("permission")] IReadOnlyList<string> Permission
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,47 @@
// using System.Text.Json.Serialization;
// namespace ImmichToSlideshow.Models.Open.Api.Band.Profile;
// public record ResultData(
// [property: JsonPropertyName("is_app_member")] bool IsAppMember,
// [property: JsonPropertyName("message_allowed")] bool MessageAllowed,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl,
// [property: JsonPropertyName("user_key")] string UserKey
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );
// https://developers.band.us/develop/guide/api/get_user_information
// Request
// URL
// [GET] https://openapi.band.us/v2/profile
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|N|Band ID to get the user's profile from a specific band.
// If not provided, the default profile of the user will be returned.
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.user_key|string|User ID
// result_data.profile_image_url|string|URL of a profile image
// result_data.name|string|User name
// result_data.is_app_member|bool|Boolean value indicating whether the user account is connected to your app or not.
// result_data.message_allowed|bool|Boolean value indicating whether the user allowed to receive messages or not.
// {
// "result_code": 1,
// "result_data": {
// "is_app_member": true,
// "message_allowed": true,
// "name": "Jordan Lee",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxxx/test.jpg",
// "user_key": "1egy84j58_testkey"
// }
// }

View File

@ -0,0 +1,181 @@
// https://developers.band.us/develop/guide/api/get_posts
// Request
// URL
// [GET] https://openapi.band.us/v2/band/posts
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// locale|string|Y|Region and language (ex. en_US)
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.paging|object|Paging parameters
// result_data.items|list|Post list
// result_data > paging
// result_data > paging
// Name|Type|Description
// previous_params|object|Parameter information to get the previous page (currently not available)
// next_params|object|Parameter information to get the next page
// important
// next_params
// To request the pagination, use the next_params value as a parameter, which is returned as paging. For example, if "next_params" : { "after": "aaa", "limit": "20", "band_key" : "bbb", "access_token": "xxx" } is returned in the next_params field, call https://openapi.band.us/v2/band/posts?after=aaa&limit=20&band_key=bbb&access_token=xxx&locale=en_US to get the next page.
// Note that previous_params is not currently supported.
// result_data > items[i]
// result_data > items[i]
// Name|Type|Description
// content|string|Body of a post. Note that HTML tags are escaped (if applicable).
// ex) tag : <band:refer user_key="abcde">user name</band:refer>
// author|object|Author information
// post_key|string|Post ID
// comment_count|int|Band ID
// created_at|long|Published date and time
// photos|list|Information on photos and videos. Videos are shown first.
// emotion_count|int|The number of emotions
// latest_comments|list|Content of the latest comments in the post
// band_key|string|Band ID
// result_data > items[i] > author
// result_data > items[i] > author
// Name|Type|Description
// name|string|Author name
// description|string|Description about the author
// role|string|Author's role
// profile_image_url|string|URL of an author's profile image
// user_key|string|User ID of an author
// result_data > items[i] > photos
// result_data > items[i] > photos
// Name|Type|Description
// height|int|Height of an image
// width|int|Width of an image
// created_at|long|Created date and time
// url|string|URL of an image
// author|object|Information on the user who uploaded the photo/video. Same format as post author.
// photo_album_key|string|Album ID
// photo_key|string|Photo ID
// comment_count|int|The number of comments
// emotion_count|int|The number of emotions
// is_video_thumbnail|boolean|Indicates whether the image is a video thumbnail or not.
// result_data > items[i] > latest_comments
// result_data > items[i] > latest_comments
// Name|Type|Description
// body|string|Comment content
// author|object|Information on the user who commented. Same format as post author.
// created_at|long|Created date and time
// {
// "result_code": 1,
// "result_data": {
// "items": [
// {
// "author": {
// "description": "This is a description",
// "name": "Charley Lee",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/zzzzzz/zzzzz.jpg"
// },
// "comment_count": 7,
// "content": "Cotents <band:refer user_no=\"\">Jordan</band:refer> <band:hashtag>#food</band:hashtag>",
// "created_at": 1444288237000,
// "photos": [
// {
// "author": {
// "description": "This is desc.",
// "name": "Sujan",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/yyyyyy/yyyyy.jpg"
// },
// "comment_count": 1,
// "created_at": 1444295780000,
// "emotion_count": 1,
// "height": 480,
// "is_video_thumbnail": true,
// "photo_album_key": null,
// "photo_key": "AAACTLxEYqMx09qji9nzAv1V",
// "url": "http://beta.coresos.phinf.naver.net/a/2g8728_c/28aUd015g6pesvlf89uq_ggxdbs.jpg",
// "width": 640
// },
// {
// "author": {
// "description": "This contents is so...",
// "name": "Eddy",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxxxxx/xxxxxx.jpg"
// },
// "comment_count": 1,
// "created_at": 1444288237000,
// "emotion_count": 1,
// "height": 720,
// "is_video_thumbnail": false,
// "photo_album_key": null,
// "photo_key": "AADtBkdo52blVIcH-4y_AotK",
// "url": "http://beta.coresos.phinf.naver.net/a/2g8701_9/ac2Ud01515ftew9215e27_ggxdbs.jpg",
// "width": 1280
// }
// ],
// "post_key": "AABhEEQG08e1Fc227z2fRCwv"
// }
// ],
// "paging": {
// "next_params": {
// "access_token": "accsstokenxxxx",
// "after": "AABsFASmeIbSAib8KSzihCBC",
// "band_key": "bandkeyxxxx",
// "limit": "20"
// },
// "previous_params": null
// }
// }
// }
// public record Author(
// [property: JsonPropertyName("description")] string Description,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
// );
// public record Item(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("content")] string Content,
// [property: JsonPropertyName("created_at")] long CreatedAt,
// [property: JsonPropertyName("photos")] IReadOnlyList<Photo> Photos,
// [property: JsonPropertyName("post_key")] string PostKey
// );
// public record NextParams(
// [property: JsonPropertyName("access_token")] string AccessToken,
// [property: JsonPropertyName("after")] string After,
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("limit")] string Limit
// );
// public record Paging(
// [property: JsonPropertyName("next_params")] NextParams NextParams,
// [property: JsonPropertyName("previous_params")] object PreviousParams
// );
// public record Photo(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("created_at")] object CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("height")] int Height,
// [property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
// [property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
// [property: JsonPropertyName("photo_key")] string PhotoKey,
// [property: JsonPropertyName("url")] string Url,
// [property: JsonPropertyName("width")] int Width
// );
// public record ResultData(
// [property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
// [property: JsonPropertyName("paging")] Paging Paging
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,182 @@
// https://developers.band.us/develop/guide/api/get_post
// Request
// URL
// [GET] https://openapi.band.us/v2.1/band/post
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// post_key|string|Y|Post ID
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.post|object|Post details
// result_data > post
// result_data > post
// Name|Type|Description
// content|string|Body of a post. Note that HTML tags are escaped (if applicable).
// ex) tag : <band:refer user_key="abcde">user name</band:refer>
// author|object|Author information
// post_key|string|Post ID
// comment_count|int|The number of comments
// created_at|long|Published date and time
// photo|object|Information on photos and videos. Videos are shown first.
// emotion_count|int|The number of emotions
// band_key|string|Band ID
// post_read_count|int|Read count
// result_data > post > author
// result_data > post > author
// Name|Type|Description
// name|string|Author name
// description|string|Description about the author
// role|string|Author's role
// profile_image_url|string|URL of an author's profile image
// user_key|string|User ID of an author
// result_data > post > photo
// result_data > post > photo
// Name|Type|Description
// height|int|Height of an image
// width|int|Width of an image
// created_at|long|Created date and time
// url|string|URL of an image
// author|object|Information on the user who uploaded the photo/video. Same format as post author.
// photo_album_key|string|Album ID
// photo_key|string|Photo ID
// comment_count|int|The number of comments
// emotion_count|int|The number of emotions
// is_video_thumbnail|boolean|Indicates whether the image is a video thumbnail or not.
// {
// "result_code": 1,
// "result_data": {
// "post": {
// "author": {
// "description": "",
// "name": "Jordan",
// "profile_image_url": "http://coresos.phinf.naver.net/a/yyy/xxx.png",
// "role": "member",
// "user_key": "AACv2efNJhMjHOgGWhfhXg25"
// },
// "band_key": "AAAbBbMeQHBLh3-y8xxogqBg",
// "comment_count": 0,
// "content": "This is Cotents.\n To be continue... <band:attachment type=\"photo\" id=\"3452\" /><band:attachment type=\"video\" id=\"675\" />",
// "created_at": 1484303791000,
// "emotion_count": 0,
// "is_multilingual": false,
// "photo": {
// "5110026620": {
// "author": {
// "description": "",
// "name": "Charley",
// "profile_image_url": "http://coresos.phinf.naver.net/a/2hj6eg_i/yyyyy.png",
// "role": "member",
// "user_key": "AACv2efNJhMjHOgGWhfhXg25"
// },
// "comment_count": 0,
// "created_at": 1484303791000,
// "emotion_count": 0,
// "height": 1920,
// "is_video_thumbnail": false,
// "photo_album_key": null,
// "photo_key": "AACVbWOG62mcbDJjaYOkSO2c",
// "url": "http://coresos.phinf.naver.net/a/2hjc4i_d/zzzzz.jpg",
// "width": 1440
// }
// },
// "post_key": "AAAFJEEalAmkhLXGh0rQCy3h",
// "post_read_count": 0,
// "shared_count": 0,
// "video": {
// "175284037": {
// "author": {
// "description": "",
// "name": "미니0",
// "profile_image_url": "http://coresos.phinf.naver.net/a/xxxx/xxxxx.png",
// "role": "member",
// "user_key": "AACv2efNJhMjHOgGWhfhXg25"
// },
// "comment_count": 0,
// "created_at": 1484303791000,
// "emotion_count": 0,
// "height": 360,
// "is_video_thumbnail": true,
// "photo_album_key": null,
// "photo_key": "AAD7LTDVWfB5GE80Usi_0Y_H",
// "url": "http://coresos.phinf.naver.net/a/yyyy/yyyy.jpg",
// "width": 640
// }
// }
// }
// }
// }
// public record _175284037(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("created_at")] long CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("height")] int Height,
// [property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
// [property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
// [property: JsonPropertyName("photo_key")] string PhotoKey,
// [property: JsonPropertyName("url")] string Url,
// [property: JsonPropertyName("width")] int Width
// );
// public record _5110026620(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("created_at")] long CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("height")] int Height,
// [property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
// [property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
// [property: JsonPropertyName("photo_key")] string PhotoKey,
// [property: JsonPropertyName("url")] string Url,
// [property: JsonPropertyName("width")] int Width
// );
// public record Author(
// [property: JsonPropertyName("description")] string Description,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl,
// [property: JsonPropertyName("role")] string Role,
// [property: JsonPropertyName("user_key")] string UserKey
// );
// public record Photo(
// [property: JsonPropertyName("5110026620")] _5110026620 _5110026620
// );
// public record Post(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("content")] string Content,
// [property: JsonPropertyName("created_at")] long CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("is_multilingual")] bool IsMultilingual,
// [property: JsonPropertyName("photo")] Photo Photo,
// [property: JsonPropertyName("post_key")] string PostKey,
// [property: JsonPropertyName("post_read_count")] int PostReadCount,
// [property: JsonPropertyName("shared_count")] int SharedCount,
// [property: JsonPropertyName("video")] Video Video
// );
// public record ResultData(
// [property: JsonPropertyName("post")] Post Post
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );
// public record Video(
// [property: JsonPropertyName("175284037")] _175284037 _175284037
// );

View File

@ -0,0 +1,159 @@
// https://developers.band.us/develop/guide/api/get_comments
// This API lets you get comments of a specific post.
// [GET] https://openapi.band.us/v2/band/post/comments
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// post_key|string|Y|Post ID
// sort|string|N|Sorting types. The default order is sorted by created date.
// +created_at: Sorted by created date
// -created_at: Sorted by last modified date
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.paging|object|Paging parameters
// result_data.items|list|Post list
// result_data > paging
// result_data > paging
// Name|Type|Description
// previous_params|object|Parameter information to get the previous page (currently not available)
// next_params|object|Parameter information to get the next page
// important
// next_params
// To request the pagination, use the next_params value as a parameter, which is returned as paging. For example, if "next_params" : { "after": "aaa", "limit": "20", "band_key" : "bbb", "access_token": "xxx" } is returned in the next_params field, call https://openapi.band.us/v2/band/posts?after=aaa&limit=20&band_key=bbb&access_token=xxx&locale=en_US to get the next page.
// Note that previous_params is not currently supported.
// result_data > items[i]
// result_data > items[i]
// Name|Type|Description
// band_key|string|Body of a post. Note that HTML tags are escaped (if applicable).
// ex) tag : <band:refer user_key="abcde">user name</band:refer>
// author|object|Band ID
// post_key|string|Post ID
// comment_key|string|Comment ID
// content|string|Comment content
// emotion_count|integer|The number of emotions
// is_audio_included|bool|Indicates whether the comment is audible or not.
// created_at|long|Comment date and time
// author|object|Author information
// photo|object|Photo information
// result_data > items[i] > author
// result_data > items[i] > author
// Name|Type|Description
// name|string|Author name
// description|string|Description about the author
// role|string|Author's role
// profile_image_url|string|URL of an author's profile image
// user_key|string|User ID of an author
// result_data > items[i] > photo
// result_data > items[i] > photo
// Name|Type|Description
// url|string|URL of an image
// height|int|Height of an image
// width|int|Width of an image
// Note
// Time is shown in epoch value.
// {
// "result_code": 1,
// "result_data": {
// "items": [
// {
// "author": {
// "description": "ㅋㅋ",
// "name": "Jordan Lee ",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/yyyy/xxxxx.jpg"
// },
// "comment_key": "AADGZXHAFeWdd1NaGsc5hN07",
// "content": "This is content... <band:refer user_no=\"122\">Sujan</band:refer>",
// "created_at": 1444110980000,
// "emotion_count": 1,
// "is_audio_comment": false,
// "photo": {
// "height": 720,
// "url": "http://beta.coresos.phinf.naver.net/a/2g85c8_c/173Ud015tfd2ude1umx7_ggxdbs.jpg",
// "width": 1280
// },
// "sticker": null
// },
// {
// "author": {
// "description": "I'm ... ",
// "name": "Jordan Lee ",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxx/yyyyyy.jpg"
// },
// "comment_key": "AABsFASmeIbSAib8KSzihCBC",
// "content": "This is Content...",
// "created_at": 1444199762000,
// "emotion_count": 0,
// "is_audio_comment": false,
// "photo": null,
// "sticker": null
// }
// ],
// "paging": {
// "next_params": {
// "access_token": "xxxx",
// "after": "AABsFASmeIbSAib8KSzihCBC",
// "band_key": "bxx",
// "post_key": "pxx"
// },
// "previous_params": null
// },
// "update_param": {}
// }
// }
// public record Author(
// [property: JsonPropertyName("description")] string Description,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
// );
// public record Item(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_key")] string CommentKey,
// [property: JsonPropertyName("content")] string Content,
// [property: JsonPropertyName("created_at")] object CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("is_audio_comment")] bool IsAudioComment,
// [property: JsonPropertyName("photo")] Photo Photo,
// [property: JsonPropertyName("sticker")] object Sticker
// );
// public record NextParams(
// [property: JsonPropertyName("access_token")] string AccessToken,
// [property: JsonPropertyName("after")] string After,
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("post_key")] string PostKey
// );
// public record Paging(
// [property: JsonPropertyName("next_params")] NextParams NextParams,
// [property: JsonPropertyName("previous_params")] object PreviousParams
// );
// public record Photo(
// [property: JsonPropertyName("height")] int Height,
// [property: JsonPropertyName("url")] string Url,
// [property: JsonPropertyName("width")] int Width
// );
// public record ResultData(
// [property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
// [property: JsonPropertyName("paging")] Paging Paging,
// [property: JsonPropertyName("update_param")] UpdateParam UpdateParam
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );
// public record UpdateParam(
// );

View File

@ -0,0 +1,116 @@
// https://developers.band.us/develop/guide/api/get_albums
// Request
// URL
// [GET] https://openapi.band.us/v2/band/albums
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.paging|object|Paging parameters
// result_data.items|list|Album list
// result_data > paging
// result_data > paging
// Name|Type|Description
// previous_params|object|Parameter information to get the previous page (currently not available)
// next_params|object|Parameter information to get the next page
// important
// next_params
// To request the pagination, use the next_params value as a parameter, which is returned as paging. For example, if "next_params" : { "after": "aaa", "limit": "20", "band_key" : "bbb", "access_token": "xxx" } is returned in the next_params field, call https://openapi.band.us/v2/band/posts?after=aaa&limit=20&band_key=bbb&access_token=xxx&locale=en_US to get the next page.
// Note that previous_params is not currently supported.
// result_data > items[i]
// result_data > items[i]
// Name|Type|Description
// photo_album_key|string|Album ID
// name|string|Album name
// photo_count|int|The number of photos in an album
// created_at|long|Created date and time
// author|object|Album creator information
// result_data > items[i] > author
// result_data > items[i] > author
// Name|Type|Description
// name|string|Author name
// description|string|Description about the author
// role|string|Author's role
// profile_image_url|string|URL of an author's profile image
// user_key|string|User ID of an author
// Note
// Time is shown in epoch value.
// {
// "result_code": 1,
// "result_data": {
// "items": [
// {
// "created_at": 1443778960000,
// "name": "Flower Album",
// "owner": {
// "description": "ㅋㅋ",
// "name": "Charley",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxx/test.jpg"
// },
// "photo_album_key": "AAA4EPU-k8RKboHPybmZaUw5",
// "photo_count": 1
// },
// {
// "created_at": 1443691414000,
// "name": "Europe Tour",
// "owner": {
// "description": "This is description.",
// "name": "Jordan Lee",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxxx/test.jpg"
// },
// "photo_album_key": "AABWu8gnqZaHTsKDa4zVn7hK",
// "photo_count": 3
// }
// ],
// "paging": {
// "next_params": {
// "after": "AABWu8gnqZaHTsKDa4zVn7hK",
// "band_key": "xxxx"
// },
// "previous_params": null
// },
// "total_photo_count": 10
// }
// }
// public record Item(
// [property: JsonPropertyName("created_at")] object CreatedAt,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("owner")] Owner Owner,
// [property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey,
// [property: JsonPropertyName("photo_count")] int PhotoCount
// );
// public record NextParams(
// [property: JsonPropertyName("after")] string After,
// [property: JsonPropertyName("band_key")] string BandKey
// );
// public record Owner(
// [property: JsonPropertyName("description")] string Description,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
// );
// public record Paging(
// [property: JsonPropertyName("next_params")] NextParams NextParams,
// [property: JsonPropertyName("previous_params")] object PreviousParams
// );
// public record ResultData(
// [property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
// [property: JsonPropertyName("paging")] Paging Paging,
// [property: JsonPropertyName("total_photo_count")] int TotalPhotoCount
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,129 @@
// https://developers.band.us/develop/guide/api/get_photos
// Request
// URL
// [GET] https://openapi.band.us/v2/band/album/photos
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// photo_album_key|string|N|Album ID
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.paging|object|Paging parameters
// result_data.items|list|Image list
// result_data > paging
// result_data > paging
// Name|Type|Description
// previous_params|object|Parameter information to get the previous page (currently not available)
// next_params|object|Parameter information to get the next page
// result_data > items[i]
// result_data > items[i]
// Name|Type|Description
// photo_key|string|Photo ID
// url|string|URL of an image
// width|int|Width of an image
// height|int|Height of an image
// photo_album_key|string|Album ID
// created_at|long|Created date and time
// author|object|Author information
// comment_count|int|The number of comments
// emotion_count|int|The number of emotions
// result_data > items[i] > author
// result_data > items[i] > author
// Name|Type|Description
// name|string|Author name
// description|string|Description about the author
// role|string|Author's role
// profile_image_url|string|URL of an author's profile image
// user_key|string|User ID of an author
// {
// "result_code": 1,
// "result_data": {
// "items": [
// {
// "author": {
// "description": "This is description.",
// "name": "Jordan Lee",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxx/test.jpg"
// },
// "comment_count": 1,
// "created_at": 1443691385000,
// "emotion_count": 1,
// "height": 720,
// "is_video_thumbnail": false,
// "photo_album_key": "AADgiaZXYFi1lV-JpylzUvwO",
// "photo_key": "AACEdJ3oAh0ICHh98X5so5aI",
// "url": "http://beta.coresos.phinf.naver.net/a/xxxx/test.jpg",
// "width": 1280
// },
// {
// "author": {
// "description": "This is description.",
// "name": "Robert J. Lee",
// "profile_image_url": "http://band.phinf.campmobile.net/20130719_224/xxx/test.jpg"
// },
// "comment_count": 1,
// "created_at": 1443690955000,
// "emotion_count": 1,
// "height": 480,
// "is_video_thumbnail": true,
// "photo_album_key": "AADgiaZXYFi1lV-JpylzUvwO",
// "photo_key": "AAAVIQRg6e8ld2yf7eQZwWtf",
// "url": "http://beta.coresos.phinf.naver.net/a/xxxx/test.jpg",
// "width": 640
// }
// ],
// "paging": {
// "next_params": {
// "after": "294038803",
// "band_key": "dhjd8djd7",
// "photo_album_key": "wdfdf929"
// },
// "previous_params": null
// }
// }
// }
// public record Author(
// [property: JsonPropertyName("description")] string Description,
// [property: JsonPropertyName("name")] string Name,
// [property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
// );
// public record Item(
// [property: JsonPropertyName("author")] Author Author,
// [property: JsonPropertyName("comment_count")] int CommentCount,
// [property: JsonPropertyName("created_at")] object CreatedAt,
// [property: JsonPropertyName("emotion_count")] int EmotionCount,
// [property: JsonPropertyName("height")] int Height,
// [property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
// [property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey,
// [property: JsonPropertyName("photo_key")] string PhotoKey,
// [property: JsonPropertyName("url")] string Url,
// [property: JsonPropertyName("width")] int Width
// );
// public record NextParams(
// [property: JsonPropertyName("after")] string After,
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey
// );
// public record Paging(
// [property: JsonPropertyName("next_params")] NextParams NextParams,
// [property: JsonPropertyName("previous_params")] object PreviousParams
// );
// public record ResultData(
// [property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
// [property: JsonPropertyName("paging")] Paging Paging
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,45 @@
// https://developers.band.us/develop/guide/api/handle_errors
// Handle Errors
// result_code when it fails
// result_code when it fails
// result_code|message|description|resolution
// 211|Invalid Parameters||
// 212|Insufficient Parameters||Check for required parameters and add it (if applicable).
// 1001|App quota has been exceeded|API quota exceeds the limit|
// 1002|User quota has been exceeded|User quota exceeds the limit|
// 1003|Cool down time restriction|Continuous API calls for a short period of time is not available|Try again after timeout interval has expire.
// 2142|Only Band Leaders are allowed to do this|Only Band owners are allowed|
// 2300|Invalid response|Error in server response|Undefined error. Send us your client ID, request URL, and parameter info.
// 3000|Invalid request|Invalid call|Check the path and parameters and try again.
// 3001|Exceeded chareacter limit|Content length exceeds the limit|Shorten the length and try again.
// 3002|Image file size has been exceeded|Image file size exceeds the limit|Reduce the image file size and try again.
// 3003|Number of image files has been exceeded|The number of attachments exceeds the limit|Reduce the number of attachments and try again.
// 10401|Unauthorized|Authentication failure; no access token exists or it has expired|Get a new access token after login and try again.|
// 10403|Forbidden|Access is denied; no permissions|Check your permissions and contact Customer Center to request permission.
// 60000|Invalid Parameter|Invalid parameter is used|Check for required parameters and parameter types and try again.
// 60100|Invalid member|User does not exist|
// 60101|Not my friend|User is not found in the friend list|
// 60102|Not Band member|The API called is only valid for Bands that a user has joined|
// 60103|This user is not connected|The API called is only valid for users whose BAND account is connected with the app|
// 60104|This user has already been connected|The API called is only valid for users whose BAND account is not connected with the app|
// 60105|You are Band Leader. Band has members.|Band owner tries to leave a Band|
// 60106|This function is granted to the specified member.|Only specific members are given permission to use this function|
// 60200|This Band is invalid or not connected.|Band does not exist or is invalid|
// 60201|You have already joined Band|The API called is only valid for Bands that a user has not joined|
// 60202|Exceeded Band Max.|Exceeded the maximum number of Bands a user is allowed to join|
// 60203|The API called is valid for either guild Bands or official Bands||
// 60204|This Band did not allow access by the user.|Try to access a Band that is not accessible|
// 60300|Receiving message is blocked|Message is not accepted by the recipient|
// 60301|Invalid message format||
// 60302|Message service failure||
// 60400|Only designated member(s) can write post|No write permission|
// 60401|Post is not connected with the app||
// 60402|Post is not editable; images or its sub posts may be deleted.||
// 60700|This invitation is invalid|Invalid invitation|
// 60800|Image URL is invalid or the format is not supported|Invalid image URL format|
// 60801|Album not exists|Album ID does not exist|
// result_data when it fails
// result_data when it fails
// name|type|nullable|description
// message|string|N|Error message
// message|string|Y|Error details

View File

@ -0,0 +1,35 @@
// https://developers.band.us/develop/guide/api/write_post
// Request
// URL
// [POST] https://openapi.band.us/v2.2/band/post/create
// Parameters
// Parameters
// Name|Type|Mandatory|Description
// access_token|string|Y|Access token of the user
// band_key|string|Y|Band ID
// content|string|Y|Body content
// do_push|boolean|N|Sends a push notifications to all members who have subscribed to it
// Response
// response body (json)
// response body (json)
// Name|Type|Description
// result_code|integer|Result code (success: 1)
// result_data.band_key|string|Band ID
// result_data.post_key|string|Post ID
// {
// "result_code": 1,
// "result_data": {
// "band_key": "4u4i3333",
// "post_key": "34512"
// }
// }
// public record ResultData(
// [property: JsonPropertyName("band_key")] string BandKey,
// [property: JsonPropertyName("post_key")] string PostKey
// );
// public record Root(
// [property: JsonPropertyName("result_code")] int ResultCode,
// [property: JsonPropertyName("result_data")] ResultData ResultData
// );

View File

@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record Item(
[property: JsonPropertyName("created_at")] object CreatedAt,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("owner")] Owner Owner,
[property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey,
[property: JsonPropertyName("photo_count")] int PhotoCount
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Item))]
public partial class AlbumsItemSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record NextParams(
[property: JsonPropertyName("after")] string After,
[property: JsonPropertyName("band_key")] string BandKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(NextParams))]
public partial class AlbumsNextParamsSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record Paging(
[property: JsonPropertyName("next_params")] NextParams NextParams,
[property: JsonPropertyName("previous_params")] object PreviousParams
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Paging))]
public partial class AlbumsPagingSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record Owner(
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Owner))]
public partial class AlbumsOwnerSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record ResultData(
[property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
[property: JsonPropertyName("paging")] Paging Paging,
[property: JsonPropertyName("total_photo_count")] int TotalPhotoCount
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class AlbumsResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Albums;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class AlbumsRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Bands;
public record Band(
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("cover")] string Cover,
[property: JsonPropertyName("member_count")] int MemberCount,
[property: JsonPropertyName("name")] string Name
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Band))]
public partial class BandsBandSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Bands;
public record ResultData(
[property: JsonPropertyName("bands")] IReadOnlyList<Band> Bands
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class BandsResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Bands;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class BandsRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record Author(
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Author))]
public partial class CommentsAuthorSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record Item(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comments_key")] string CommentsKey,
[property: JsonPropertyName("content")] string Content,
[property: JsonPropertyName("created_at")] object CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("is_audio_comments")] bool IsAudioComments,
[property: JsonPropertyName("photo")] Photo Photo,
[property: JsonPropertyName("sticker")] object Sticker
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Item))]
public partial class CommentsItemSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record NextParams(
[property: JsonPropertyName("access_token")] string AccessToken,
[property: JsonPropertyName("after")] string After,
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("post_key")] string PostKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(NextParams))]
public partial class CommentsNextParamsSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record Paging(
[property: JsonPropertyName("next_params")] NextParams NextParams,
[property: JsonPropertyName("previous_params")] object PreviousParams
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Paging))]
public partial class CommentsPagingSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record Photo(
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Photo))]
public partial class CommentsPhotoSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record ResultData(
[property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
[property: JsonPropertyName("paging")] Paging Paging,
[property: JsonPropertyName("update_param")] UpdateParam UpdateParam
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class CommentsResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class CommentsRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,11 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Comments;
public record UpdateParam(
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(UpdateParam))]
public partial class CommentsUpdateParamSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Permissions;
public record ResultData(
[property: JsonPropertyName("permission")] IReadOnlyList<string> Permissions
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class PermissionsResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Permissions;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class PermissionsRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record Author(
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Author))]
public partial class PhotosAuthorSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record Item(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("created_at")] object CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
[property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey,
[property: JsonPropertyName("photo_key")] string PhotoKey,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Item))]
public partial class PhotosItemSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record NextParams(
[property: JsonPropertyName("after")] string After,
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("photo_album_key")] string PhotoAlbumKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(NextParams))]
public partial class PhotosNextParamsSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record Paging(
[property: JsonPropertyName("next_params")] NextParams NextParams,
[property: JsonPropertyName("previous_params")] object PreviousParams
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Paging))]
public partial class PhotosPagingSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record Photo(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("created_at")] object CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
[property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
[property: JsonPropertyName("photo_key")] string PhotoKey,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Photo))]
public partial class PhotosPhotoSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record ResultData(
[property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
[property: JsonPropertyName("paging")] Paging Paging
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class PhotosResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Photos;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class PhotosRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record Author(
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl,
[property: JsonPropertyName("role")] string Role,
[property: JsonPropertyName("user_key")] string UserKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Author))]
public partial class PostAuthorSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record P175284037(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("created_at")] long CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
[property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
[property: JsonPropertyName("photo_key")] string PhotoKey,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(P175284037))]
public partial class PostP175284037SourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record P5110026620(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("created_at")] long CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
[property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
[property: JsonPropertyName("photo_key")] string PhotoKey,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(P5110026620))]
public partial class PostP5110026620SourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record Photo(
[property: JsonPropertyName("5110026620")] P5110026620 P5110026620
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Photo))]
public partial class PostPhotoSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,23 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record Post(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("content")] string Content,
[property: JsonPropertyName("created_at")] long CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("is_multilingual")] bool IsMultilingual,
[property: JsonPropertyName("photo")] Photo Photo,
[property: JsonPropertyName("post_key")] string PostKey,
[property: JsonPropertyName("post_read_count")] int PostReadCount,
[property: JsonPropertyName("shared_count")] int SharedCount,
[property: JsonPropertyName("video")] Video Video
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Post))]
public partial class PostPostSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record ResultData(
[property: JsonPropertyName("post")] Post Post
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class PostResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class PostRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Post;
public record Video(
[property: JsonPropertyName("175284037")] P175284037 P175284037
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Video))]
public partial class PostVideoSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record Author(
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Author))]
public partial class PostsAuthorSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record Item(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("content")] string Content,
[property: JsonPropertyName("created_at")] long CreatedAt,
[property: JsonPropertyName("photos")] IReadOnlyList<Photo> Photos,
[property: JsonPropertyName("post_key")] string PostKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Item))]
public partial class PostsItemSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record NextParams(
[property: JsonPropertyName("access_token")] string AccessToken,
[property: JsonPropertyName("after")] string After,
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("limit")] string Limit
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(NextParams))]
public partial class PostsNextParamsSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record Paging(
[property: JsonPropertyName("next_params")] NextParams NextParams,
[property: JsonPropertyName("previous_params")] object PreviousParams
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Paging))]
public partial class PostsPagingSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record Photo(
[property: JsonPropertyName("author")] Author Author,
[property: JsonPropertyName("comment_count")] int CommentCount,
[property: JsonPropertyName("created_at")] object CreatedAt,
[property: JsonPropertyName("emotion_count")] int EmotionCount,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("is_video_thumbnail")] bool IsVideoThumbnail,
[property: JsonPropertyName("photo_album_key")] object PhotoAlbumKey,
[property: JsonPropertyName("photo_key")] string PhotoKey,
[property: JsonPropertyName("url")] string Url,
[property: JsonPropertyName("width")] int Width
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Photo))]
public partial class PostsPhotoSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record ResultData(
[property: JsonPropertyName("items")] IReadOnlyList<Item> Items,
[property: JsonPropertyName("paging")] Paging Paging
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class PostsResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Posts;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class PostsRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Profile;
public record ResultData(
[property: JsonPropertyName("is_app_member")] bool IsAppMember,
[property: JsonPropertyName("message_allowed")] bool MessageAllowed,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("profile_image_url")] string ProfileImageUrl,
[property: JsonPropertyName("user_key")] string UserKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class ProfileResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band.Profile;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class ProfileRootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band;
public record ResultData(
[property: JsonPropertyName("band_key")] string BandKey,
[property: JsonPropertyName("post_key")] string PostKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ResultData))]
public partial class ResultDataSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.Api.Band;
public record Root(
[property: JsonPropertyName("result_code")] int ResultCode,
[property: JsonPropertyName("result_data")] ResultData ResultData
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
public partial class RootSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
namespace ImmichToSlideshow.Models.Open.API.Band;
public record Token(
[property: JsonPropertyName("access_token")] string AccessToken,
[property: JsonPropertyName("expires_in")] int ExpiresIn,
[property: JsonPropertyName("refresh_token")] string RefreshToken,
[property: JsonPropertyName("scope")] string Scope,
[property: JsonPropertyName("token_type")] string TokenType,
[property: JsonPropertyName("user_key")] string UserKey
);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Token))]
public partial class TokenSourceGenerationContext : JsonSerializerContext {
}

View File

@ -5,6 +5,7 @@ namespace ImmichToSlideshow.Models;
public record Settings(int AddDays,
string ArchivedTag,
Band? Band,
string ConnectionString,
DigiKam4? DigiKam4,
string[] FilterTags,

View File

@ -7,11 +7,11 @@ namespace ImmichToSlideshow;
public class Program {
public static void Main(string[] args) {
Dictionary<string, Models.Open.API.Band.Token> tokens = [];
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
AppSettings appSettings = AppSettings.Get(webApplicationBuilder.Configuration);
_ = webApplicationBuilder.Services.AddControllers();
_ = webApplicationBuilder.Services.AddServices(appSettings);
_ = webApplicationBuilder.Services.AddServices(appSettings, tokens);
WebApplication webApplication = webApplicationBuilder.Build();
ILogger<Program>? logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Starting Web Application");

View File

@ -0,0 +1,314 @@
using ImmichToSlideshow.Models;
using ImmichToSlideshow.Models.Open.API.Band;
using System.Text.Json;
namespace ImmichToSlideshow.Services;
public class BandService(ILogger<Program> logger, AppSettings appSettings, IHttpClientFactory httpClientFactory) {
#pragma warning disable CS9124
private readonly ILogger<Program> _Logger = logger;
private readonly Band _Band = appSettings.Settings.Band ?? throw new Exception();
private readonly IHttpClientFactory _HttpClientFactory = httpClientFactory;
#pragma warning restore CS9124
public string? GetAuthorizationCode() {
string? result;
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetAuthorizationCode(_Logger, _Band, httpClient);
httpClient.Dispose();
return result;
}
private static string? GetAuthorizationCode(ILogger<Program> logger, Band band, HttpClient httpClient) {
string? result;
Uri requestUri = new($"https://auth.band.us/oauth2/authorize?response_type=code&client_id={band.ClientId}&redirect_uri={band.Redirect}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
result = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.Redirect);
return result;
}
public Token? GetToken(string code) {
Token? result;
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetToken(_Logger, _Band, code, httpClient);
httpClient.Dispose();
return result;
}
private static Token? GetToken(ILogger<Program> logger, Band band, string code, HttpClient httpClient) {
Token? result;
Uri requestUri = new($"https://auth.band.us/oauth2/token?grant_type=authorization_code&code={code}");
HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, requestUri);
httpRequestMessage.Headers.Add("Authorization", $"Basic {band.BasicAuthorization}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.SendAsync(httpRequestMessage);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, TokenSourceGenerationContext.Default.Token);
return result;
}
public Models.Open.Api.Band.Bands.Root? GetBands(Dictionary<string, Token>? tokens) {
Models.Open.Api.Band.Bands.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetBands(_Logger, httpClient, token);
httpClient.Dispose();
}
return result;
}
private static Token? GetToken(Dictionary<string, Token>? tokens) =>
tokens is null || tokens.Count == 0 ? null : tokens.ElementAt(0).Value;
private static string? GetString(ILogger<Program> logger, Uri requestUri, Task<HttpResponseMessage> httpResponseMessage, System.Net.HttpStatusCode httpStatusCode) {
string? result;
httpResponseMessage.Wait();
if (httpResponseMessage.Result.StatusCode != httpStatusCode) {
result = null;
logger.LogWarning("{StatusCode}: {requestUri}", httpResponseMessage.Result.StatusCode, requestUri.OriginalString);
} else {
Task<string> content = httpResponseMessage.Result.Content.ReadAsStringAsync();
content.Wait();
result = content.Result;
logger.LogDebug("{content}", result);
httpResponseMessage.Dispose();
content.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Bands.Root? GetBands(ILogger<Program> logger, HttpClient httpClient, Token token) {
Models.Open.Api.Band.Bands.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2.1/bands?access_token={token.AccessToken}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Bands.BandsRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Profile.Root? GetProfile(Dictionary<string, Token>? tokens, string bandKey) {
Models.Open.Api.Band.Profile.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetProfile(_Logger, httpClient, token, bandKey);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Profile.Root? GetProfile(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey) {
Models.Open.Api.Band.Profile.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/profile?access_token={token.AccessToken}&band_key={bandKey}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Profile.ProfileRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Posts.Root? GetPosts(Dictionary<string, Token>? tokens, string bandKey) {
Models.Open.Api.Band.Posts.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPosts(_Logger, httpClient, token, bandKey);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Posts.Root? GetPosts(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey) {
Models.Open.Api.Band.Posts.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/posts?access_token={token.AccessToken}&band_key={bandKey}&locale=en_US");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Posts.PostsRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Post.Root? GetPost(Dictionary<string, Token>? tokens, string bandKey, string postKey) {
Models.Open.Api.Band.Post.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPost(_Logger, httpClient, token, bandKey, postKey);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Post.Root? GetPost(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string postKey) {
Models.Open.Api.Band.Post.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/post?access_token={token.AccessToken}&band_key={bandKey}&post_key={postKey}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Post.PostRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Comments.Root? GetComments(Dictionary<string, Token>? tokens, string bandKey, string postKey, string sort) {
Models.Open.Api.Band.Comments.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetComments(_Logger, httpClient, token, bandKey, postKey, sort);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Comments.Root? GetComments(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string postKey, string sort) {
Models.Open.Api.Band.Comments.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/post/comments?access_token={token.AccessToken}&band_key={bandKey}&post_key={postKey}&sort={sort}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Comments.CommentsRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Albums.Root? GetAlbums(Dictionary<string, Token>? tokens, string bandKey) {
Models.Open.Api.Band.Albums.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetAlbums(_Logger, httpClient, token, bandKey);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Albums.Root? GetAlbums(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey) {
Models.Open.Api.Band.Albums.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/albums?access_token={token.AccessToken}&band_key={bandKey}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Albums.AlbumsRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Photos.Root? GetPhotos(Dictionary<string, Token>? tokens, string bandKey, string photoAlbumKey) {
Models.Open.Api.Band.Photos.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPhotos(_Logger, httpClient, token, bandKey, photoAlbumKey);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Photos.Root? GetPhotos(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string photoAlbumKey) {
Models.Open.Api.Band.Photos.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/album/photos?access_token={token.AccessToken}&band_key={bandKey}&photo_album_key={photoAlbumKey}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Photos.PhotosRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Permissions.Root? GetPermissions(Dictionary<string, Token>? tokens, string bandKey, string permissions) {
Models.Open.Api.Band.Permissions.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPermissions(_Logger, httpClient, token, bandKey, permissions);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Permissions.Root? GetPermissions(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string permissions) {
Models.Open.Api.Band.Permissions.Root? result;
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/permissions?access_token={token.AccessToken}&band_key={bandKey}&permissions={permissions}");
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(requestUri);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.Permissions.PermissionsRootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Root? WritePost(Dictionary<string, Token>? tokens, string bandKey, string message) {
Models.Open.Api.Band.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPostCreate(_Logger, httpClient, token, bandKey, message);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Root? GetPostCreate(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string message) {
Models.Open.Api.Band.Root? result;
List<KeyValuePair<string, string>> formData = [
new KeyValuePair<string, string>("access_token", token.AccessToken),
new KeyValuePair<string, string>("band_key", string.Concat(bandKey)),
new KeyValuePair<string, string>("content", message),
new KeyValuePair<string, string>("do_push", "true")
];
FormUrlEncodedContent formContent = new(formData);
Uri requestUri = new($"{httpClient.BaseAddress}v2.2/band/post/create");
Task<HttpResponseMessage> httpResponseMessage = httpClient.PostAsync(requestUri, formContent);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.RootSourceGenerationContext.Default.Root);
return result;
}
public Models.Open.Api.Band.Root? WritePostComment(Dictionary<string, Token>? tokens, string bandKey, string postKey, string message) {
Models.Open.Api.Band.Root? result;
Token? token = GetToken(tokens);
if (token is null) {
_Logger.LogWarning("Unable to get token");
result = null;
} else {
HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(AppSettings.Settings.Band));
result = GetPostCommentCreate(_Logger, httpClient, token, bandKey, postKey, message);
httpClient.Dispose();
}
return result;
}
private static Models.Open.Api.Band.Root? GetPostCommentCreate(ILogger<Program> logger, HttpClient httpClient, Token token, string bandKey, string postKey, string message) {
Models.Open.Api.Band.Root? result;
List<KeyValuePair<string, string>> formData = [
new KeyValuePair<string, string>("access_token", token.AccessToken),
new KeyValuePair<string, string>("band_key", string.Concat(bandKey)),
new KeyValuePair<string, string>("post_key", postKey),
new KeyValuePair<string, string>("body", message)
];
FormUrlEncodedContent formContent = new(formData);
Uri requestUri = new($"{httpClient.BaseAddress}v2/band/post/comment/create");
Task<HttpResponseMessage> httpResponseMessage = httpClient.PostAsync(requestUri, formContent);
string? content = GetString(logger, requestUri, httpResponseMessage, System.Net.HttpStatusCode.OK);
result = content is null ? null : JsonSerializer.Deserialize(content, Models.Open.Api.Band.RootSourceGenerationContext.Default.Root);
return result;
}
}

View File

@ -79,7 +79,7 @@ internal static class CommandText {
} else {
results.Add(" FROM public.asset a ");
}
results.AddRange(" INNER ");
results.Add(" INNER ");
if (lowestVersionHistory <= 1.129) {
results.Add(" JOIN asset_files f ");
} else {