diff --git a/src/ImmichToSlideshow/Controllers/BandController.cs b/src/ImmichToSlideshow/Controllers/BandController.cs new file mode 100644 index 0000000..06dea21 --- /dev/null +++ b/src/ImmichToSlideshow/Controllers/BandController.cs @@ -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 tokens) : ControllerBase { + + private readonly BandService _BandService = pushPostService; + private readonly Dictionary _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"); + } + +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/DependencyInjection/ServiceCollectionExtensions.cs b/src/ImmichToSlideshow/DependencyInjection/ServiceCollectionExtensions.cs index 89bcdb9..c368619 100644 --- a/src/ImmichToSlideshow/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/ImmichToSlideshow/DependencyInjection/ServiceCollectionExtensions.cs @@ -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 tokens) { + _ = services.AddControllers(); _ = services.AddScoped(); + _ = services.AddScoped(); + _ = 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; } diff --git a/src/ImmichToSlideshow/Models/AppSettings.cs b/src/ImmichToSlideshow/Models/AppSettings.cs index e316a2f..2407780 100644 --- a/src/ImmichToSlideshow/Models/AppSettings.cs +++ b/src/ImmichToSlideshow/Models/AppSettings.cs @@ -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 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())}"); diff --git a/src/ImmichToSlideshow/Models/Band.cs b/src/ImmichToSlideshow/Models/Band.cs new file mode 100644 index 0000000..1fb9c8a --- /dev/null +++ b/src/ImmichToSlideshow/Models/Band.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/0-get_authorization_code_from_user.cs b/src/ImmichToSlideshow/Models/Open/Api/0-get_authorization_code_from_user.cs new file mode 100644 index 0000000..3e3282b --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/0-get_authorization_code_from_user.cs @@ -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 doesn’t 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 doesn’t 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 \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/1-get_bands.cs b/src/ImmichToSlideshow/Models/Open/Api/1-get_bands.cs new file mode 100644 index 0000000..d41e457 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/1-get_bands.cs @@ -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 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" +// } +// ] +// } +// } \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/10-write_comment.cs b/src/ImmichToSlideshow/Models/Open/Api/10-write_comment.cs new file mode 100644 index 0000000..c28249a --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/10-write_comment.cs @@ -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 +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/11-get_post_permission.cs b/src/ImmichToSlideshow/Models/Open/Api/11-get_post_permission.cs new file mode 100644 index 0000000..eadd86b --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/11-get_post_permission.cs @@ -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 Permission +// ); + +// public record Root( +// [property: JsonPropertyName("result_code")] int ResultCode, +// [property: JsonPropertyName("result_data")] ResultData ResultData +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/2-Profile.cs b/src/ImmichToSlideshow/Models/Open/Api/2-Profile.cs new file mode 100644 index 0000000..5bae213 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/2-Profile.cs @@ -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" +// } +// } \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/3-get_posts.cs b/src/ImmichToSlideshow/Models/Open/Api/3-get_posts.cs new file mode 100644 index 0000000..2c07fe7 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/3-get_posts.cs @@ -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 : user name +// 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 Jordan #food", +// "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 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 Items, +// [property: JsonPropertyName("paging")] Paging Paging +// ); + +// public record Root( +// [property: JsonPropertyName("result_code")] int ResultCode, +// [property: JsonPropertyName("result_data")] ResultData ResultData +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/4-get_post.cs b/src/ImmichToSlideshow/Models/Open/Api/4-get_post.cs new file mode 100644 index 0000000..149d22e --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/4-get_post.cs @@ -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 : user name +// 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... ", +// "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 +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/5-get_comments.cs b/src/ImmichToSlideshow/Models/Open/Api/5-get_comments.cs new file mode 100644 index 0000000..8ca3d33 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/5-get_comments.cs @@ -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 : user name +// 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... Sujan", +// "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 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( + +// ); diff --git a/src/ImmichToSlideshow/Models/Open/Api/6-get_albums.cs b/src/ImmichToSlideshow/Models/Open/Api/6-get_albums.cs new file mode 100644 index 0000000..d26fd4f --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/6-get_albums.cs @@ -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 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 +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/7-get_photos.cs b/src/ImmichToSlideshow/Models/Open/Api/7-get_photos.cs new file mode 100644 index 0000000..1298ef2 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/7-get_photos.cs @@ -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 Items, +// [property: JsonPropertyName("paging")] Paging Paging +// ); + +// public record Root( +// [property: JsonPropertyName("result_code")] int ResultCode, +// [property: JsonPropertyName("result_data")] ResultData ResultData +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/8-handle_errors.cs b/src/ImmichToSlideshow/Models/Open/Api/8-handle_errors.cs new file mode 100644 index 0000000..aefc5db --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/8-handle_errors.cs @@ -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 \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/9-write_post.cs b/src/ImmichToSlideshow/Models/Open/Api/9-write_post.cs new file mode 100644 index 0000000..a161670 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/9-write_post.cs @@ -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 +// ); \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Item.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Item.cs new file mode 100644 index 0000000..a247e91 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Item.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/NextParams.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/NextParams.cs new file mode 100644 index 0000000..a8e413f --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/NextParams.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Paging.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Paging.cs new file mode 100644 index 0000000..0cf0b32 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Paging.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Photo.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Photo.cs new file mode 100644 index 0000000..57cbd9e --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Photo.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/ResultData.cs new file mode 100644 index 0000000..cb17f13 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/ResultData.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Albums; + +public record ResultData( + [property: JsonPropertyName("items")] IReadOnlyList Items, + [property: JsonPropertyName("paging")] Paging Paging, + [property: JsonPropertyName("total_photo_count")] int TotalPhotoCount +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class AlbumsResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Root.cs new file mode 100644 index 0000000..40d0c29 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Albums/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Band.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Band.cs new file mode 100644 index 0000000..ba882bb --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Band.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/ResultData.cs new file mode 100644 index 0000000..bd36b71 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/ResultData.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Bands; + +public record ResultData( + [property: JsonPropertyName("bands")] IReadOnlyList Bands +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class BandsResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Root.cs new file mode 100644 index 0000000..e4855b4 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Bands/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Author.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Author.cs new file mode 100644 index 0000000..35e1ff0 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Author.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Item.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Item.cs new file mode 100644 index 0000000..1d8958f --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Item.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/NextParams.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/NextParams.cs new file mode 100644 index 0000000..49f6ef5 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/NextParams.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Paging.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Paging.cs new file mode 100644 index 0000000..51dc9c0 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Paging.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Photo.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Photo.cs new file mode 100644 index 0000000..79bbec3 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Photo.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/ResultData.cs new file mode 100644 index 0000000..a2bb5d9 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/ResultData.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Comments; + +public record ResultData( + [property: JsonPropertyName("items")] IReadOnlyList Items, + [property: JsonPropertyName("paging")] Paging Paging, + [property: JsonPropertyName("update_param")] UpdateParam UpdateParam +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class CommentsResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Root.cs new file mode 100644 index 0000000..8e9be32 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/UpdateParam.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/UpdateParam.cs new file mode 100644 index 0000000..e92ab84 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Comments/UpdateParam.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/ResultData.cs new file mode 100644 index 0000000..dbfa793 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/ResultData.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Permissions; + +public record ResultData( + [property: JsonPropertyName("permission")] IReadOnlyList Permissions +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class PermissionsResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/Root.cs new file mode 100644 index 0000000..151e7aa --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Permissions/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Author.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Author.cs new file mode 100644 index 0000000..052cd19 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Author.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Item.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Item.cs new file mode 100644 index 0000000..9498bb9 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Item.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/NextParams.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/NextParams.cs new file mode 100644 index 0000000..b3851ae --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/NextParams.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Paging.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Paging.cs new file mode 100644 index 0000000..7f17393 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Paging.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Photo.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Photo.cs new file mode 100644 index 0000000..bed3313 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Photo.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/ResultData.cs new file mode 100644 index 0000000..a38f615 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/ResultData.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Photos; + +public record ResultData( + [property: JsonPropertyName("items")] IReadOnlyList Items, + [property: JsonPropertyName("paging")] Paging Paging +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class PhotosResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Root.cs new file mode 100644 index 0000000..004453d --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Photos/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Author.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Author.cs new file mode 100644 index 0000000..02feea7 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Author.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P175284037.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P175284037.cs new file mode 100644 index 0000000..438cb0e --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P175284037.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P5110026620.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P5110026620.cs new file mode 100644 index 0000000..1277624 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/P5110026620.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Photo.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Photo.cs new file mode 100644 index 0000000..16fc11d --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Photo.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Post.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Post.cs new file mode 100644 index 0000000..e997c5b --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Post.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/ResultData.cs new file mode 100644 index 0000000..a60a646 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/ResultData.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Root.cs new file mode 100644 index 0000000..bfcba77 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Video.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Video.cs new file mode 100644 index 0000000..acc7b1f --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Post/Video.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Author.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Author.cs new file mode 100644 index 0000000..5b6e995 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Author.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Item.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Item.cs new file mode 100644 index 0000000..e81d3da --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Item.cs @@ -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 Photos, + [property: JsonPropertyName("post_key")] string PostKey +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Item))] +public partial class PostsItemSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/NextParams.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/NextParams.cs new file mode 100644 index 0000000..a1d2404 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/NextParams.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Paging.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Paging.cs new file mode 100644 index 0000000..19536dd --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Paging.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Photo.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Photo.cs new file mode 100644 index 0000000..8b71204 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Photo.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/ResultData.cs new file mode 100644 index 0000000..f052cef --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/ResultData.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace ImmichToSlideshow.Models.Open.Api.Band.Posts; + +public record ResultData( + [property: JsonPropertyName("items")] IReadOnlyList Items, + [property: JsonPropertyName("paging")] Paging Paging +); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ResultData))] +public partial class PostsResultDataSourceGenerationContext : JsonSerializerContext { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Root.cs new file mode 100644 index 0000000..1c68619 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Posts/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/ResultData.cs new file mode 100644 index 0000000..a51ec04 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/ResultData.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/Root.cs new file mode 100644 index 0000000..e14f6ec --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Profile/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/ResultData.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/ResultData.cs new file mode 100644 index 0000000..b5680b7 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/ResultData.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Root.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Root.cs new file mode 100644 index 0000000..56f8a9d --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Root.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Open/Api/Band/Token.cs b/src/ImmichToSlideshow/Models/Open/Api/Band/Token.cs new file mode 100644 index 0000000..7da66d1 --- /dev/null +++ b/src/ImmichToSlideshow/Models/Open/Api/Band/Token.cs @@ -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 { +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Models/Settings.cs b/src/ImmichToSlideshow/Models/Settings.cs index 9333ed5..c3245ae 100644 --- a/src/ImmichToSlideshow/Models/Settings.cs +++ b/src/ImmichToSlideshow/Models/Settings.cs @@ -5,6 +5,7 @@ namespace ImmichToSlideshow.Models; public record Settings(int AddDays, string ArchivedTag, + Band? Band, string ConnectionString, DigiKam4? DigiKam4, string[] FilterTags, diff --git a/src/ImmichToSlideshow/Program.cs b/src/ImmichToSlideshow/Program.cs index 52358ca..b8e25de 100644 --- a/src/ImmichToSlideshow/Program.cs +++ b/src/ImmichToSlideshow/Program.cs @@ -7,11 +7,11 @@ namespace ImmichToSlideshow; public class Program { public static void Main(string[] args) { + Dictionary tokens = []; WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args); _ = webApplicationBuilder.Configuration.AddUserSecrets(); AppSettings appSettings = AppSettings.Get(webApplicationBuilder.Configuration); - _ = webApplicationBuilder.Services.AddControllers(); - _ = webApplicationBuilder.Services.AddServices(appSettings); + _ = webApplicationBuilder.Services.AddServices(appSettings, tokens); WebApplication webApplication = webApplicationBuilder.Build(); ILogger? logger = webApplication.Services.GetRequiredService>(); logger.LogInformation("Starting Web Application"); diff --git a/src/ImmichToSlideshow/Services/BandService.cs b/src/ImmichToSlideshow/Services/BandService.cs new file mode 100644 index 0000000..3c37a77 --- /dev/null +++ b/src/ImmichToSlideshow/Services/BandService.cs @@ -0,0 +1,314 @@ +using ImmichToSlideshow.Models; +using ImmichToSlideshow.Models.Open.API.Band; +using System.Text.Json; + +namespace ImmichToSlideshow.Services; + +public class BandService(ILogger logger, AppSettings appSettings, IHttpClientFactory httpClientFactory) { + +#pragma warning disable CS9124 + private readonly ILogger _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 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 = 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 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 = 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? 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? tokens) => + tokens is null || tokens.Count == 0 ? null : tokens.ElementAt(0).Value; + + private static string? GetString(ILogger logger, Uri requestUri, Task 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 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 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 = 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? 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 logger, HttpClient httpClient, Token token, string bandKey, string message) { + Models.Open.Api.Band.Root? result; + List> formData = [ + new KeyValuePair("access_token", token.AccessToken), + new KeyValuePair("band_key", string.Concat(bandKey)), + new KeyValuePair("content", message), + new KeyValuePair("do_push", "true") + ]; + FormUrlEncodedContent formContent = new(formData); + Uri requestUri = new($"{httpClient.BaseAddress}v2.2/band/post/create"); + Task 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? 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 logger, HttpClient httpClient, Token token, string bandKey, string postKey, string message) { + Models.Open.Api.Band.Root? result; + List> formData = [ + new KeyValuePair("access_token", token.AccessToken), + new KeyValuePair("band_key", string.Concat(bandKey)), + new KeyValuePair("post_key", postKey), + new KeyValuePair("body", message) + ]; + FormUrlEncodedContent formContent = new(formData); + Uri requestUri = new($"{httpClient.BaseAddress}v2/band/post/comment/create"); + Task 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; + } + +} \ No newline at end of file diff --git a/src/ImmichToSlideshow/Services/CommandText.cs b/src/ImmichToSlideshow/Services/CommandText.cs index af84293..b7afd7c 100644 --- a/src/ImmichToSlideshow/Services/CommandText.cs +++ b/src/ImmichToSlideshow/Services/CommandText.cs @@ -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 {