From cff7585c8aac2e09aacb66ccbfe306ba5f71bf03 Mon Sep 17 00:00:00 2001 From: Marian Zagoruiko Date: Wed, 15 Jan 2025 13:50:27 +0200 Subject: [PATCH 1/4] feat: include time option for dates --- .../Models/PropertyValue/DatePropertyValue.cs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs b/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs index 7467936b..7d785212 100644 --- a/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs +++ b/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs @@ -21,6 +21,7 @@ public class DatePropertyValue : PropertyValue /// /// Date value object. /// + [JsonConverter(typeof(DateCustomConverter))] public class Date { /// @@ -43,5 +44,94 @@ public class Date /// [JsonProperty("time_zone")] public string TimeZone { get; set; } + + /// + /// Whether to include time + /// + public bool IncludeTime { get; set; } = true; + } + + public class DateJsonObject + { + [JsonProperty("start")] + public string Start { get; set; } + + [JsonProperty("end")] + public string End { get; set; } + + [JsonProperty("time_zone")] + public string TimeZone { get; set; } + } + + public class DateCustomConverter : JsonConverter + { + public override Date ReadJson(JsonReader reader, Type objectType, Date existingValue, bool hasExistingValue, + JsonSerializer serializer) + { + var jsonObject = serializer.Deserialize(reader); + + if (jsonObject == null) + { + return null; + } + + var date = new Date + { + Start = ParseDateTime(jsonObject.Start, out bool includeTime), + End = ParseDateTime(jsonObject.End, out _), + TimeZone = jsonObject.TimeZone, + IncludeTime = includeTime, + }; + + return date; + } + + public override void WriteJson(JsonWriter writer, Date value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + + return; + } + + writer.WriteStartObject(); + + if (value.Start.HasValue) + { + string startFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; + writer.WritePropertyName("start"); + writer.WriteValue(value.Start.Value.ToString(startFormat)); + } + + if (value.End.HasValue) + { + string endFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; + writer.WritePropertyName("end"); + writer.WriteValue(value.End.Value.ToString(endFormat)); + } + + if (!string.IsNullOrEmpty(value.TimeZone)) + { + writer.WritePropertyName("time_zone"); + writer.WriteValue(value.TimeZone); + } + + writer.WriteEndObject(); + } + + private static DateTime? ParseDateTime(string dateTimeString, out bool includeTime) + { + includeTime = false; + + if (string.IsNullOrEmpty(dateTimeString)) + { + return null; + } + + includeTime = dateTimeString.Contains("T") || dateTimeString.Contains(" "); + + return DateTimeOffset.Parse(dateTimeString).UtcDateTime; + } } } From f41327e34abf0529a18006581580ec7005738f03 Mon Sep 17 00:00:00 2001 From: Marian Zagoruiko Date: Fri, 17 Jan 2025 18:10:12 +0200 Subject: [PATCH 2/4] feat: rollup date parsing --- Src/Notion.Client/Models/PropertyValue/RollupPropertyValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Notion.Client/Models/PropertyValue/RollupPropertyValue.cs b/Src/Notion.Client/Models/PropertyValue/RollupPropertyValue.cs index 2eb104fb..92020c61 100644 --- a/Src/Notion.Client/Models/PropertyValue/RollupPropertyValue.cs +++ b/Src/Notion.Client/Models/PropertyValue/RollupPropertyValue.cs @@ -35,7 +35,7 @@ public class RollupValue /// Date rollup property values contain a date property value. /// [JsonProperty("date")] - public DatePropertyValue Date { get; set; } + public Date Date { get; set; } /// /// Array rollup property values contain an array of element objects. From 954c042c057a0c6fc5b3a2debad938fb40424f37 Mon Sep 17 00:00:00 2001 From: Marian Zagoruiko Date: Fri, 28 Mar 2025 10:06:16 +0200 Subject: [PATCH 3/4] fix: custom emoji support --- Src/Notion.Client/Models/CustomEmoji.cs | 16 ++++++++++++++++ Src/Notion.Client/Models/CustomEmojiObject.cs | 13 +++++++++++++ Src/Notion.Client/Models/Page/IPageIcon.cs | 1 + 3 files changed, 30 insertions(+) create mode 100644 Src/Notion.Client/Models/CustomEmoji.cs create mode 100644 Src/Notion.Client/Models/CustomEmojiObject.cs diff --git a/Src/Notion.Client/Models/CustomEmoji.cs b/Src/Notion.Client/Models/CustomEmoji.cs new file mode 100644 index 00000000..0f7a4c48 --- /dev/null +++ b/Src/Notion.Client/Models/CustomEmoji.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmoji + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("url")] + public string Url { get; set; } + } +} diff --git a/Src/Notion.Client/Models/CustomEmojiObject.cs b/Src/Notion.Client/Models/CustomEmojiObject.cs new file mode 100644 index 00000000..1faa4d74 --- /dev/null +++ b/Src/Notion.Client/Models/CustomEmojiObject.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiObject : IPageIcon + { + [JsonProperty("custom_emoji")] + public CustomEmoji CustomEmoji { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/IPageIcon.cs b/Src/Notion.Client/Models/Page/IPageIcon.cs index b9ebea56..5d692185 100644 --- a/Src/Notion.Client/Models/Page/IPageIcon.cs +++ b/Src/Notion.Client/Models/Page/IPageIcon.cs @@ -5,6 +5,7 @@ namespace Notion.Client { [JsonConverter(typeof(JsonSubtypes), "type")] [JsonSubtypes.KnownSubTypeAttribute(typeof(EmojiObject), "emoji")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CustomEmojiObject), "custom_emoji")] [JsonSubtypes.KnownSubTypeAttribute(typeof(FileObject), "file")] [JsonSubtypes.KnownSubTypeAttribute(typeof(FileObject), "external")] public interface IPageIcon From 8ee7f0fd923e55406aa88a12bdd94409c8bf2c3e Mon Sep 17 00:00:00 2001 From: Marian Zagoruiko Date: Fri, 28 Mar 2025 10:28:28 +0200 Subject: [PATCH 4/4] fix: linter --- .../PropertyValue/DateCustomConverter.cs | 77 +++++++++++++++++ .../Models/PropertyValue/DateJsonObject.cs | 16 ++++ .../Models/PropertyValue/DatePropertyValue.cs | 84 ------------------- 3 files changed, 93 insertions(+), 84 deletions(-) create mode 100644 Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs create mode 100644 Src/Notion.Client/Models/PropertyValue/DateJsonObject.cs diff --git a/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs b/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs new file mode 100644 index 00000000..6823c303 --- /dev/null +++ b/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs @@ -0,0 +1,77 @@ +using System; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DateCustomConverter : JsonConverter + { + public override Date ReadJson(JsonReader reader, Type objectType, Date existingValue, bool hasExistingValue, + JsonSerializer serializer) + { + var jsonObject = serializer.Deserialize(reader); + + if (jsonObject == null) + { + return null; + } + + var date = new Date + { + Start = ParseDateTime(jsonObject.Start, out bool includeTime), + End = ParseDateTime(jsonObject.End, out _), + TimeZone = jsonObject.TimeZone, + IncludeTime = includeTime, + }; + + return date; + } + + public override void WriteJson(JsonWriter writer, Date value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + + return; + } + + writer.WriteStartObject(); + + if (value.Start.HasValue) + { + string startFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; + writer.WritePropertyName("start"); + writer.WriteValue(value.Start.Value.ToString(startFormat)); + } + + if (value.End.HasValue) + { + string endFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; + writer.WritePropertyName("end"); + writer.WriteValue(value.End.Value.ToString(endFormat)); + } + + if (!string.IsNullOrEmpty(value.TimeZone)) + { + writer.WritePropertyName("time_zone"); + writer.WriteValue(value.TimeZone); + } + + writer.WriteEndObject(); + } + + private static DateTime? ParseDateTime(string dateTimeString, out bool includeTime) + { + includeTime = false; + + if (string.IsNullOrEmpty(dateTimeString)) + { + return null; + } + + includeTime = dateTimeString.Contains("T") || dateTimeString.Contains(" "); + + return DateTimeOffset.Parse(dateTimeString).UtcDateTime; + } + } +} diff --git a/Src/Notion.Client/Models/PropertyValue/DateJsonObject.cs b/Src/Notion.Client/Models/PropertyValue/DateJsonObject.cs new file mode 100644 index 00000000..b33b58c7 --- /dev/null +++ b/Src/Notion.Client/Models/PropertyValue/DateJsonObject.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + internal class DateJsonObject + { + [JsonProperty("start")] + public string Start { get; set; } + + [JsonProperty("end")] + public string End { get; set; } + + [JsonProperty("time_zone")] + public string TimeZone { get; set; } + } +} diff --git a/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs b/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs index 7d785212..b79707db 100644 --- a/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs +++ b/Src/Notion.Client/Models/PropertyValue/DatePropertyValue.cs @@ -50,88 +50,4 @@ public class Date /// public bool IncludeTime { get; set; } = true; } - - public class DateJsonObject - { - [JsonProperty("start")] - public string Start { get; set; } - - [JsonProperty("end")] - public string End { get; set; } - - [JsonProperty("time_zone")] - public string TimeZone { get; set; } - } - - public class DateCustomConverter : JsonConverter - { - public override Date ReadJson(JsonReader reader, Type objectType, Date existingValue, bool hasExistingValue, - JsonSerializer serializer) - { - var jsonObject = serializer.Deserialize(reader); - - if (jsonObject == null) - { - return null; - } - - var date = new Date - { - Start = ParseDateTime(jsonObject.Start, out bool includeTime), - End = ParseDateTime(jsonObject.End, out _), - TimeZone = jsonObject.TimeZone, - IncludeTime = includeTime, - }; - - return date; - } - - public override void WriteJson(JsonWriter writer, Date value, JsonSerializer serializer) - { - if (value is null) - { - writer.WriteNull(); - - return; - } - - writer.WriteStartObject(); - - if (value.Start.HasValue) - { - string startFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; - writer.WritePropertyName("start"); - writer.WriteValue(value.Start.Value.ToString(startFormat)); - } - - if (value.End.HasValue) - { - string endFormat = value.IncludeTime ? "yyyy-MM-ddTHH:mm:ss" : "yyyy-MM-dd"; - writer.WritePropertyName("end"); - writer.WriteValue(value.End.Value.ToString(endFormat)); - } - - if (!string.IsNullOrEmpty(value.TimeZone)) - { - writer.WritePropertyName("time_zone"); - writer.WriteValue(value.TimeZone); - } - - writer.WriteEndObject(); - } - - private static DateTime? ParseDateTime(string dateTimeString, out bool includeTime) - { - includeTime = false; - - if (string.IsNullOrEmpty(dateTimeString)) - { - return null; - } - - includeTime = dateTimeString.Contains("T") || dateTimeString.Contains(" "); - - return DateTimeOffset.Parse(dateTimeString).UtcDateTime; - } - } }