home page for App
This commit is contained in:
@ -1,19 +1,76 @@
|
||||
using SQLite;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SQLite;
|
||||
|
||||
namespace Blahblah.FlowerApp.Data;
|
||||
|
||||
public sealed class Constants
|
||||
internal sealed class Constants
|
||||
{
|
||||
public const string CategoryOther = "other";
|
||||
public const string EventUnknown = "unknown";
|
||||
|
||||
public const string BaseUrl = "https://flower.tsanie.org";
|
||||
public const string ApiVersionName = "api_version";
|
||||
public const string LastTokenName = "last_token";
|
||||
|
||||
public const string BaseUrl = "https://app.blahblaho.com";
|
||||
|
||||
public const SQLiteOpenFlags SQLiteFlags =
|
||||
SQLiteOpenFlags.ReadWrite |
|
||||
SQLiteOpenFlags.Create |
|
||||
SQLiteOpenFlags.SharedCache;
|
||||
|
||||
private const string dbFilename = "flowerstory.db3";
|
||||
const string dbFilename = "flowerstory.db3";
|
||||
public static string DatabasePath => Path.Combine(FileSystem.AppDataDirectory, dbFilename);
|
||||
|
||||
static string? apiVersion;
|
||||
public static string? ApiVersion => apiVersion;
|
||||
|
||||
static string? authorization;
|
||||
public static string? Authorization => authorization;
|
||||
|
||||
public static void SetAuthorization(string auth)
|
||||
{
|
||||
authorization = auth;
|
||||
}
|
||||
|
||||
public static async Task<Definitions?> Initialize(ILogger logger, string? version, CancellationToken cancellation = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var v = await Extensions.FetchAsync<string>("api/version", cancellation);
|
||||
apiVersion = v;
|
||||
|
||||
if (v != version)
|
||||
{
|
||||
var definition = await Extensions.FetchAsync<Definitions>($"api/consts?{v}", cancellation);
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError("error occurs on fetching version and definitions, {error}", ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal record Definitions
|
||||
{
|
||||
public required string ApiVersion { get; init; }
|
||||
|
||||
public required Dictionary<int, NamedItem> Categories { get; init; }
|
||||
|
||||
public required Dictionary<int, EventItem> Events { get; init; }
|
||||
}
|
||||
|
||||
internal record NamedItem(string Name, string? Description)
|
||||
{
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
public string? Description { get; init; } = Description;
|
||||
}
|
||||
|
||||
internal record EventItem(string Name, string? Description, bool Unique) : NamedItem(Name, Description)
|
||||
{
|
||||
public bool Unique { get; init; } = Unique;
|
||||
}
|
@ -13,6 +13,130 @@ public class FlowerDatabase
|
||||
public FlowerDatabase(ILogger<FlowerDatabase> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await Setup();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError("error occurs on setup, {error}", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Dictionary<int, NamedItem>? categories;
|
||||
|
||||
private Dictionary<int, EventItem>? events;
|
||||
|
||||
public string Category(int categoryId)
|
||||
{
|
||||
if (categories?.TryGetValue(categoryId, out var category) == true)
|
||||
{
|
||||
return category.Name;
|
||||
}
|
||||
return Constants.CategoryOther;
|
||||
}
|
||||
|
||||
public string Event(int eventId)
|
||||
{
|
||||
if (events?.TryGetValue(eventId, out var @event) == true)
|
||||
{
|
||||
return @event.Name;
|
||||
}
|
||||
return Constants.EventUnknown;
|
||||
}
|
||||
|
||||
private async Task Setup()
|
||||
{
|
||||
await Init();
|
||||
|
||||
#if DEBUG
|
||||
Constants.SetAuthorization("RF4mfoUur0vHtWzHwD42ka0FhIfGaPnBxoQgrXOYEDg=");
|
||||
#else
|
||||
var token = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.LastTokenName);
|
||||
if (token != null)
|
||||
{
|
||||
Constants.SetAuthorization(token.Value);
|
||||
}
|
||||
#endif
|
||||
|
||||
var version = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.ApiVersionName);
|
||||
var definition = await Constants.Initialize(logger, version?.Value);
|
||||
|
||||
if (definition != null)
|
||||
{
|
||||
categories = definition.Categories;
|
||||
events = definition.Events;
|
||||
|
||||
logger.LogInformation("new version founded, from ({from}) to ({to})", version?.Value, definition.ApiVersion);
|
||||
|
||||
if (version == null)
|
||||
{
|
||||
version = new ParamItem
|
||||
{
|
||||
Code = Constants.ApiVersionName,
|
||||
Value = definition.ApiVersion
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
version.Value = definition.ApiVersion;
|
||||
}
|
||||
await database.InsertOrReplaceAsync(version);
|
||||
|
||||
// replace local definitions
|
||||
await database.DeleteAllAsync<DefinitionItem>();
|
||||
|
||||
var defs = new List<DefinitionItem>();
|
||||
foreach (var category in definition.Categories)
|
||||
{
|
||||
defs.Add(new DefinitionItem
|
||||
{
|
||||
DefinitionType = 0,
|
||||
DefinitionId = category.Key,
|
||||
Name = category.Value.Name,
|
||||
Description = category.Value.Description
|
||||
});
|
||||
}
|
||||
foreach (var @event in definition.Events)
|
||||
{
|
||||
defs.Add(new DefinitionItem
|
||||
{
|
||||
DefinitionType = 1,
|
||||
DefinitionId = @event.Key,
|
||||
Name = @event.Value.Name,
|
||||
Description = @event.Value.Description,
|
||||
Unique = @event.Value.Unique
|
||||
});
|
||||
}
|
||||
var rows = await database.InsertAllAsync(defs);
|
||||
logger.LogInformation("{count} definitions, {rows} rows inserted", defs.Count, rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use local definitions
|
||||
var defs = await database.Table<DefinitionItem>().ToListAsync();
|
||||
var cates = new Dictionary<int, NamedItem>();
|
||||
var evts = new Dictionary<int, EventItem>();
|
||||
foreach (var d in defs)
|
||||
{
|
||||
if (d.DefinitionType == 0)
|
||||
{
|
||||
// category
|
||||
cates[d.DefinitionId] = new NamedItem(d.Name, d.Description);
|
||||
}
|
||||
else if (d.DefinitionType == 1)
|
||||
{
|
||||
// event
|
||||
evts[d.DefinitionId] = new EventItem(d.Name, d.Description, d.Unique ?? false);
|
||||
}
|
||||
}
|
||||
categories = cates;
|
||||
events = evts;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Init()
|
||||
@ -27,7 +151,13 @@ public class FlowerDatabase
|
||||
#if DEBUG
|
||||
var result =
|
||||
#endif
|
||||
await database.CreateTablesAsync<FlowerItem, RecordItem, PhotoItem, UserItem>();
|
||||
await database.CreateTablesAsync(CreateFlags.None,
|
||||
typeof(FlowerItem),
|
||||
typeof(RecordItem),
|
||||
typeof(PhotoItem),
|
||||
typeof(UserItem),
|
||||
typeof(DefinitionItem),
|
||||
typeof(ParamItem));
|
||||
|
||||
#if DEBUG
|
||||
foreach (var item in result.Results)
|
||||
|
29
FlowerApp/Data/Model/DefinitionItem.cs
Normal file
29
FlowerApp/Data/Model/DefinitionItem.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using SQLite;
|
||||
|
||||
namespace Blahblah.FlowerApp.Data.Model;
|
||||
|
||||
[Table("definitions")]
|
||||
public class DefinitionItem
|
||||
{
|
||||
[Column("did"), PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// - 0: category
|
||||
/// - 1: event
|
||||
/// </summary>
|
||||
[Column("type"), NotNull]
|
||||
public int DefinitionType { get; set; }
|
||||
|
||||
[Column("id"), NotNull]
|
||||
public int DefinitionId { get; set; }
|
||||
|
||||
[Column("name"), NotNull]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
[Column("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Column("unique")]
|
||||
public bool? Unique { get; set; }
|
||||
}
|
@ -20,8 +20,6 @@ public class FlowerItem
|
||||
[Column("datebuy"), NotNull]
|
||||
public long DateBuyUnixTime { get; set; }
|
||||
|
||||
public DateTimeOffset DateBuy => DateTimeOffset.FromUnixTimeMilliseconds(DateBuyUnixTime);
|
||||
|
||||
[Column("cost")]
|
||||
public decimal? Cost { get; set; }
|
||||
|
||||
@ -37,5 +35,9 @@ public class FlowerItem
|
||||
[Column("longitude")]
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public PhotoItem[]? Photos { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public int? Distance { get; set; }
|
||||
}
|
||||
|
22
FlowerApp/Data/Model/ParamItem.cs
Normal file
22
FlowerApp/Data/Model/ParamItem.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using SQLite;
|
||||
|
||||
namespace Blahblah.FlowerApp.Data.Model;
|
||||
|
||||
[Table("params")]
|
||||
public class ParamItem
|
||||
{
|
||||
[Column("pid"), PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("uid")]
|
||||
public int? OwnerId { get; set; }
|
||||
|
||||
[Column("code"), NotNull]
|
||||
public string Code { get; set; } = null!;
|
||||
|
||||
[Column("value"), NotNull]
|
||||
public string Value { get; set; } = null!;
|
||||
|
||||
[Column("description")]
|
||||
public string? Description { get; set; }
|
||||
}
|
@ -29,8 +29,12 @@ public class PhotoItem
|
||||
[Column("dateupload"), NotNull]
|
||||
public long DateUploadUnixTime { get; set; }
|
||||
|
||||
public DateTimeOffset DateUpload => DateTimeOffset.FromUnixTimeMilliseconds(DateUploadUnixTime);
|
||||
|
||||
[Column("url")]
|
||||
public string Url { get; set; } = null!;
|
||||
|
||||
[Column("width")]
|
||||
public int? Width { get; set; }
|
||||
|
||||
[Column("height")]
|
||||
public int? Height { get; set; }
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ public class RecordItem
|
||||
[Column("date"), NotNull]
|
||||
public long DateUnixTime { get; set; }
|
||||
|
||||
public DateTimeOffset Date => DateTimeOffset.FromUnixTimeMilliseconds(DateUnixTime);
|
||||
|
||||
[Column("byuid")]
|
||||
public int? ByUserId { get; set; }
|
||||
|
||||
|
@ -4,15 +4,15 @@ namespace Blahblah.FlowerApp.Data.Model;
|
||||
|
||||
public class UserItem
|
||||
{
|
||||
[Column("uid"), PrimaryKey, AutoIncrement]
|
||||
[Column("uid"), PrimaryKey, NotNull]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("token"), Indexed, NotNull]
|
||||
public string Token { get; set; } = null!;
|
||||
|
||||
[Column("id"), NotNull]
|
||||
public string UserId { get; set; } = null!;
|
||||
|
||||
[Column("token"), NotNull]
|
||||
public string Token { get; set; } = null!;
|
||||
|
||||
[Column("name"), NotNull]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
@ -22,8 +22,6 @@ public class UserItem
|
||||
[Column("regdate"), NotNull]
|
||||
public long RegisterDateUnixTime { get; set; }
|
||||
|
||||
public DateTimeOffset RegisterDate => DateTimeOffset.FromUnixTimeMilliseconds(RegisterDateUnixTime);
|
||||
|
||||
//[Column("activedate")]
|
||||
//public long? ActiveDateUnixTime { get; set; }
|
||||
|
||||
|
Reference in New Issue
Block a user