From bec7b7fa7acfffeaf5859c0be8bb53e88d6fc103 Mon Sep 17 00:00:00 2001 From: CreatureSurvive Date: Thu, 9 Nov 2023 12:03:35 -0600 Subject: [PATCH] initial commit --- .gitignore | 9 + Package.resolved | 32 ++ Package.swift | 34 ++ Sources/Swimmy/Extensions/APIExtensions.swift | 213 ++++++++++++ Sources/Swimmy/Extensions/Date.swift | 127 +++++++ Sources/Swimmy/Extensions/Encodable.swift | 17 + Sources/Swimmy/Extensions/Publisher.swift | 115 +++++++ Sources/Swimmy/Extensions/String.swift | 38 +++ Sources/Swimmy/Extensions/URL.swift | 34 ++ .../Lemmy API/Enums/CommentSortType.swift | 32 ++ .../Swimmy/Lemmy API/Enums/ListingType.swift | 23 ++ .../Lemmy API/Enums/ModlogActionType.swift | 67 ++++ .../Lemmy API/Enums/PostFeatureType.swift | 17 + .../Lemmy API/Enums/RegistrationMode.swift | 18 + .../Swimmy/Lemmy API/Enums/SearchType.swift | 21 ++ Sources/Swimmy/Lemmy API/Enums/SortType.swift | 93 ++++++ .../Lemmy API/Enums/SubscribedType.swift | 18 + .../Lemmy API/Requests/Admin/AddAdmin.swift | 29 ++ .../ApproveRegistrationApplication.swift | 24 ++ ...etUnreadRegistrationApplicationCount.swift | 25 ++ .../Admin/ListRegistrationApplications.swift | 32 ++ .../Requests/Admin/PurgeComment.swift | 29 ++ .../Requests/Admin/PurgeCommunity.swift | 26 ++ .../Requests/Admin/PurgePerson.swift | 26 ++ .../Lemmy API/Requests/Admin/PurgePost.swift | 26 ++ .../Requests/Comment/CreateComment.swift | 28 ++ .../Comment/CreateCommentReport.swift | 29 ++ .../Requests/Comment/DeleteComment.swift | 26 ++ .../Requests/Comment/DistinguishComment.swift | 23 ++ .../Requests/Comment/EditComment.swift | 33 ++ .../Requests/Comment/GetComment.swift | 27 ++ .../Requests/Comment/GetComments.swift | 45 +++ .../Requests/Comment/LikeComment.swift | 26 ++ .../Requests/Comment/ListCommentReports.swift | 35 ++ .../Comment/MarkCommentReplyAsRead.swift | 34 ++ .../Requests/Comment/RemoveComment.swift | 28 ++ .../Comment/ResolveCommentReport.swift | 27 ++ .../Requests/Comment/SaveComment.swift | 26 ++ .../Community/AddModToCommunity.swift | 31 ++ .../Requests/Community/BanFromCommunity.swift | 40 +++ .../Requests/Community/BlockCommunity.swift | 58 ++++ .../Requests/Community/CreateCommunity.swift | 42 +++ .../Requests/Community/DeleteCommunity.swift | 26 ++ .../Requests/Community/EditCommunity.swift | 38 +++ .../Requests/Community/FollowCommunity.swift | 26 ++ .../Requests/Community/GetCommunity.swift | 34 ++ .../Requests/Community/ListCommunities.swift | 33 ++ .../Requests/Community/RemoveCommunity.swift | 31 ++ .../Community/TransferCommunity.swift | 26 ++ .../GetFederatedInstances.swift | 25 ++ .../Lemmy API/Requests/Mod/GetModlog.swift | 51 +++ .../Requests/Pictrs/UploadImageRequest.swift | 33 ++ .../Requests/Post/\020GetSiteMetadata.swift" | 25 ++ .../Lemmy API/Requests/Post/CreatePost.swift | 39 +++ .../Requests/Post/CreatePostReport.swift | 29 ++ .../Lemmy API/Requests/Post/DeletePost.swift | 26 ++ .../Lemmy API/Requests/Post/EditPost.swift | 34 ++ .../Lemmy API/Requests/Post/FeaturePost.swift | 28 ++ .../Lemmy API/Requests/Post/GetPost.swift | 33 ++ .../Lemmy API/Requests/Post/GetPosts.swift | 45 +++ .../Lemmy API/Requests/Post/LikePost.swift | 27 ++ .../Requests/Post/ListPostReports.swift | 35 ++ .../Lemmy API/Requests/Post/LockPost.swift | 26 ++ .../Requests/Post/MarkPostAsRead.swift | 26 ++ .../Lemmy API/Requests/Post/RemovePost.swift | 28 ++ .../Requests/Post/ResolvePostReport.swift | 27 ++ .../Lemmy API/Requests/Post/SavePost.swift | 26 ++ .../CreatePrivateMessage.swift | 29 ++ .../CreatePrivateMessageReport.swift | 29 ++ .../DeletePrivateMessage.swift | 26 ++ .../Private Message/EditPrivateMessage.swift | 20 ++ .../Private Message/GetPrivateMessages.swift | 31 ++ .../ListPrivateMessageReports.swift | 31 ++ .../MarkPrivateMessageAsRead.swift | 26 ++ .../ResolvePrivateMessageReport.swift | 26 ++ .../ResolveObject/ResolveObject.swift | 30 ++ .../Lemmy API/Requests/Search/Search.swift | 47 +++ .../Requests/Site/BlockInstanceRequest.swift | 30 ++ .../Lemmy API/Requests/Site/CreateSite.swift | 107 ++++++ .../Lemmy API/Requests/Site/EditSite.swift | 104 ++++++ .../Lemmy API/Requests/Site/GetSite.swift | 33 ++ .../Lemmy API/Requests/User/BanPerson.swift | 29 ++ .../Lemmy API/Requests/User/BlockPerson.swift | 30 ++ .../Requests/User/ChangePassword.swift | 28 ++ .../Requests/User/DeleteAccount.swift | 26 ++ .../Requests/User/GetBannedPersons.swift | 25 ++ .../Lemmy API/Requests/User/GetCaptcha.swift | 22 ++ .../Requests/User/GetPersonDetails.swift | 43 +++ .../Requests/User/GetPersonMentions.swift | 34 ++ .../Lemmy API/Requests/User/GetReplies.swift | 33 ++ .../Requests/User/GetReportCount.swift | 31 ++ .../Requests/User/GetUnreadCount.swift | 27 ++ .../Lemmy API/Requests/User/LeaveAdmin.swift | 22 ++ .../Lemmy API/Requests/User/Login.swift | 38 +++ .../Requests/User/MarkAllAsRead.swift | 22 ++ .../User/MarkPersonMentionAsRead.swift | 29 ++ .../Requests/User/PasswordChange.swift | 26 ++ .../Requests/User/PasswordReset.swift | 24 ++ .../Lemmy API/Requests/User/Register.swift | 38 +++ .../Requests/User/SaveUserSettings.swift | 60 ++++ .../Lemmy API/Requests/User/VerifyEmail.swift | 24 ++ .../Lemmy API/Structs/AdminPurgeComment.swift | 24 ++ .../Structs/AdminPurgeCommentView.swift | 14 + .../Structs/AdminPurgeCommunity.swift | 15 + .../Structs/AdminPurgeCommunityView.swift | 13 + .../Lemmy API/Structs/AdminPurgePerson.swift | 15 + .../Structs/AdminPurgePersonView.swift | 13 + .../Lemmy API/Structs/AdminPurgePost.swift | 16 + .../Structs/AdminPurgePostView.swift | 14 + .../Lemmy API/Structs/CaptchaResponse.swift | 17 + .../Swimmy/Lemmy API/Structs/Comment.swift | 24 ++ .../Lemmy API/Structs/CommentAggregates.swift | 17 + .../Lemmy API/Structs/CommentReply.swift | 16 + .../Lemmy API/Structs/CommentReplyView.swift | 23 ++ .../Lemmy API/Structs/CommentReport.swift | 20 ++ .../Lemmy API/Structs/CommentReportView.swift | 21 ++ .../Lemmy API/Structs/CommentView.swift | 21 ++ .../Swimmy/Lemmy API/Structs/Community.swift | 28 ++ .../Structs/CommunityAggregates.swift | 20 ++ .../Structs/CommunityBlockView.swift | 13 + .../Structs/CommunityFollowerView.swift | 13 + .../Structs/CommunityModeratorView.swift | 13 + .../Lemmy API/Structs/CommunityView.swift | 15 + .../Structs/FederatedInstances.swift | 14 + .../Swimmy/Lemmy API/Structs/ImageFile.swift | 13 + .../Swimmy/Lemmy API/Structs/Instance.swift | 17 + .../Lemmy API/Structs/InstanceBlockView.swift | 14 + .../Swimmy/Lemmy API/Structs/Language.swift | 14 + .../Swimmy/Lemmy API/Structs/LocalSite.swift | 36 ++ .../Structs/LocalSiteRateLimit.swift | 27 ++ .../Lemmy API/Structs/LocalUserSettings.swift | 28 ++ .../Structs/LocalUserSettingsView.swift | 14 + Sources/Swimmy/Lemmy API/Structs/ModAdd.swift | 16 + .../Lemmy API/Structs/ModAddCommunity.swift | 17 + .../Structs/ModAddCommunityView.swift | 15 + .../Swimmy/Lemmy API/Structs/ModAddView.swift | 14 + Sources/Swimmy/Lemmy API/Structs/ModBan.swift | 18 + .../Structs/ModBanFromCommunity.swift | 19 ++ .../Structs/ModBanFromCommunityView.swift | 15 + .../Swimmy/Lemmy API/Structs/ModBanView.swift | 14 + .../Lemmy API/Structs/ModFeaturePost.swift | 17 + .../Structs/ModFeaturePostView.swift | 15 + .../Lemmy API/Structs/ModHideCommunity.swift | 26 ++ .../Structs/ModHideCommunityView.swift | 17 + .../Lemmy API/Structs/ModLockPost.swift | 16 + .../Lemmy API/Structs/ModLockPostView.swift | 15 + .../Lemmy API/Structs/ModRemoveComment.swift | 17 + .../Structs/ModRemoveCommentView.swift | 17 + .../Structs/ModRemoveCommunity.swift | 18 + .../Structs/ModRemoveCommunityView.swift | 14 + .../Lemmy API/Structs/ModRemovePost.swift | 17 + .../Lemmy API/Structs/ModRemovePostView.swift | 15 + .../Structs/ModTransferCommunity.swift | 17 + .../Structs/ModTransferCommunityView.swift | 15 + .../Swimmy/Lemmy API/Structs/MyUserInfo.swift | 18 + Sources/Swimmy/Lemmy API/Structs/Person.swift | 30 ++ .../Lemmy API/Structs/PersonAggregates.swift | 17 + .../Lemmy API/Structs/PersonBlockView.swift | 13 + .../Lemmy API/Structs/PersonMention.swift | 16 + .../Lemmy API/Structs/PersonMentionView.swift | 23 ++ .../Swimmy/Lemmy API/Structs/PersonView.swift | 13 + Sources/Swimmy/Lemmy API/Structs/Post.swift | 36 ++ .../Lemmy API/Structs/PostAggregates.swift | 22 ++ .../Swimmy/Lemmy API/Structs/PostReport.swift | 22 ++ .../Lemmy API/Structs/PostReportView.swift | 20 ++ .../Swimmy/Lemmy API/Structs/PostView.swift | 22 ++ .../Lemmy API/Structs/PrivateMessage.swift | 21 ++ .../Structs/PrivateMessageReport.swift | 20 ++ .../Structs/PrivateMessageReportView.swift | 16 + .../Structs/PrivateMessageView.swift | 14 + .../Structs/RegistrationApplication.swift | 17 + .../Structs/RegistrationApplicationView.swift | 15 + Sources/Swimmy/Lemmy API/Structs/Site.swift | 25 ++ .../Lemmy API/Structs/SiteAggregates.swift | 21 ++ .../Lemmy API/Structs/SiteMetadata.swift | 16 + .../Swimmy/Lemmy API/Structs/SiteView.swift | 16 + .../Swimmy/Lemmy API/Structs/Tagline.swift | 16 + Sources/Swimmy/LemmyApi.swift | 313 ++++++++++++++++++ Sources/Swimmy/MultipartFormDataRequest.swift | 75 +++++ Sources/Swimmy/Protocols/API.swift | 19 ++ Tests/SwimmyTests/SwimmyTests.swift | 67 ++++ 181 files changed, 5489 insertions(+) create mode 100644 .gitignore create mode 100644 Package.resolved create mode 100644 Package.swift create mode 100644 Sources/Swimmy/Extensions/APIExtensions.swift create mode 100644 Sources/Swimmy/Extensions/Date.swift create mode 100644 Sources/Swimmy/Extensions/Encodable.swift create mode 100644 Sources/Swimmy/Extensions/Publisher.swift create mode 100644 Sources/Swimmy/Extensions/String.swift create mode 100644 Sources/Swimmy/Extensions/URL.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/CommentSortType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/ListingType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/ModlogActionType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/PostFeatureType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/RegistrationMode.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/SearchType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/SortType.swift create mode 100644 Sources/Swimmy/Lemmy API/Enums/SubscribedType.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/AddAdmin.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/ApproveRegistrationApplication.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/GetUnreadRegistrationApplicationCount.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/ListRegistrationApplications.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/PurgeComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/PurgeCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/PurgePerson.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Admin/PurgePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/CreateComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/CreateCommentReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/DeleteComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/DistinguishComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/EditComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/GetComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/GetComments.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/LikeComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/ListCommentReports.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/MarkCommentReplyAsRead.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/RemoveComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/ResolveCommentReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Comment/SaveComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/AddModToCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/BanFromCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/BlockCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/CreateCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/DeleteCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/EditCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/FollowCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/GetCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/ListCommunities.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/RemoveCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Community/TransferCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Federated Instances/GetFederatedInstances.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Mod/GetModlog.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Pictrs/UploadImageRequest.swift create mode 100644 "Sources/Swimmy/Lemmy API/Requests/Post/\020GetSiteMetadata.swift" create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/CreatePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/CreatePostReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/DeletePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/EditPost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/FeaturePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/GetPost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/GetPosts.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/LikePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/ListPostReports.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/LockPost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/MarkPostAsRead.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/RemovePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/ResolvePostReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Post/SavePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessage.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessageReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/DeletePrivateMessage.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/EditPrivateMessage.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/GetPrivateMessages.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/ListPrivateMessageReports.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/MarkPrivateMessageAsRead.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Private Message/ResolvePrivateMessageReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/ResolveObject/ResolveObject.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Search/Search.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Site/BlockInstanceRequest.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Site/CreateSite.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Site/EditSite.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/Site/GetSite.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/BanPerson.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/BlockPerson.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/ChangePassword.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/DeleteAccount.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetBannedPersons.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetCaptcha.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetPersonDetails.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetPersonMentions.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetReplies.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetReportCount.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/GetUnreadCount.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/LeaveAdmin.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/Login.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/MarkAllAsRead.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/MarkPersonMentionAsRead.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/PasswordChange.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/PasswordReset.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/Register.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/SaveUserSettings.swift create mode 100644 Sources/Swimmy/Lemmy API/Requests/User/VerifyEmail.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgeComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommentView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgePerson.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgePersonView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/AdminPurgePostView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CaptchaResponse.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Comment.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentAggregates.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentReply.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentReplyView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentReportView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommentView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Community.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommunityAggregates.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommunityBlockView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommunityFollowerView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommunityModeratorView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/CommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/FederatedInstances.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ImageFile.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Instance.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/InstanceBlockView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Language.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/LocalSite.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/LocalSiteRateLimit.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/LocalUserSettings.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/LocalUserSettingsView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModAdd.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModAddCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModAddCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModAddView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModBan.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModBanView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModFeaturePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModFeaturePostView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModHideCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModHideCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModLockPost.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModLockPostView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemoveComment.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemoveCommentView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemovePost.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModRemovePostView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModTransferCommunity.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/ModTransferCommunityView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/MyUserInfo.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Person.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PersonAggregates.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PersonBlockView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PersonMention.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PersonMentionView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PersonView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Post.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PostAggregates.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PostReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PostReportView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PostView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PrivateMessage.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PrivateMessageReport.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PrivateMessageReportView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/PrivateMessageView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/RegistrationApplication.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/RegistrationApplicationView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Site.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/SiteAggregates.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/SiteMetadata.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/SiteView.swift create mode 100644 Sources/Swimmy/Lemmy API/Structs/Tagline.swift create mode 100644 Sources/Swimmy/LemmyApi.swift create mode 100644 Sources/Swimmy/MultipartFormDataRequest.swift create mode 100644 Sources/Swimmy/Protocols/API.swift create mode 100644 Tests/SwimmyTests/SwimmyTests.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b29812 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/config/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..dfa732b --- /dev/null +++ b/Package.resolved @@ -0,0 +1,32 @@ +{ + "pins" : [ + { + "identity" : "combinex", + "kind" : "remoteSourceControl", + "location" : "https://github.com/lavalleeale/CombineX", + "state" : { + "branch" : "master", + "revision" : "bb5ff98aff5db119c5a1075c63204fab3612a648" + } + }, + { + "identity" : "cxshim", + "kind" : "remoteSourceControl", + "location" : "https://github.com/cx-org/CXShim", + "state" : { + "revision" : "82fecc246c7ca9f0ac1656b8199b7956e64d68f3", + "version" : "0.4.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "6c89474e62719ddcc1e9614989fff2f68208fe10", + "version" : "1.1.0" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..517f735 --- /dev/null +++ b/Package.swift @@ -0,0 +1,34 @@ +// swift-tools-version: 5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "Swimmy", + platforms: [.iOS(.v15), .macOS(.v13)], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "Swimmy", + targets: ["Swimmy"]), + ], + dependencies: [ + .package(url: "https://github.com/cx-org/CXShim", .upToNextMinor(from: "0.4.0")), + .package(url: "https://github.com/lavalleeale/CombineX", branch: "master"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "Swimmy", + dependencies: [ + .product(name: "CXShim", package: "CXShim"), + .product(name: "CombineX", package: "CombineX"), + ], + swiftSettings: [.enableUpcomingFeature("BareSlashRegexLiterals")] + ), + .testTarget( + name: "SwimmyTests", + dependencies: ["Swimmy"]), + ] +) diff --git a/Sources/Swimmy/Extensions/APIExtensions.swift b/Sources/Swimmy/Extensions/APIExtensions.swift new file mode 100644 index 0000000..89c409f --- /dev/null +++ b/Sources/Swimmy/Extensions/APIExtensions.swift @@ -0,0 +1,213 @@ +// +// APIExtensions.swift +// +// +// Created by Dana Buehre on 11/9/23. +// + +import Foundation + +//extension URL { +// var isImageURL: Bool { +// return absoluteString.isImageURL +// } +// +// var isVideoURL: Bool { +// return absoluteString.isVideoURL +// } +//} + +//extension String { +// +// var nilOrValue: String? { +// guard !isEmpty else { +// return nil +// } +// +// return self +// } +// +// +// var isImageURL: Bool { +// return self.range(of: "(http[^\\s]+(jpg|jpeg|png|gif|gifv|webp|bmp|apng)\\b)", options: [.regularExpression, .caseInsensitive]) != nil +// } +// +// var isVideoURL: Bool { +// return self.range(of: "(http[^\\s]+(avi|m4a|m4b|m4p|m4r|m4v|mov|mp4|mpa|mqv|webvtt|xhe|m3u8)\\b)", options: [.regularExpression, .caseInsensitive]) != nil +// } +// +// func getURLs(filterBlock: @escaping (URL) -> Bool) -> (found: [URL], filtered: [URL]) { +// var urls: [URL] = [] +// var filtered: [URL] = [] +// let types: NSTextCheckingResult.CheckingType = [ .link] +// let detector = try? NSDataDetector(types: types.rawValue) +// detector?.enumerateMatches(in: self, options: [], range: NSMakeRange(0, (self as NSString).length)) { (result, flags, _) in +// if let url = result?.url, url.scheme != "mailto" { +// if filterBlock(url) { +// filtered.append(url) +// } else { +// urls.append(url) +// } +// } +// } +// return (urls, filtered) +// } +// +// func getURLs(filter: String? = nil) -> (found: [URL], filtered: [URL]) { +// var urls: [URL] = [] +// var filtered: [URL] = [] +// let types: NSTextCheckingResult.CheckingType = [ .link] +// let detector = try? NSDataDetector(types: types.rawValue) +// detector?.enumerateMatches(in: self, options: [], range: NSMakeRange(0, (self as NSString).length)) { (result, flags, _) in +// if let url = result?.url, url.scheme != "mailto" { +// if let filter = filter, url.absoluteString.contains(filter) { +// filtered.append(url) +// } else { +// urls.append(url) +// } +// } +// } +// return (urls, filtered) +// } +// +// func getUniqueURLs(filterBlock: @escaping (URL) -> Bool) -> (found: [URL], filtered: [URL]) { +// let results = getURLs(filterBlock: filterBlock) +// return (results.found.uniqued(), results.filtered.uniqued()) +// } +// +// func getUniqueURLs(filter: String? = nil) -> (found: [URL], filtered: [URL]) { +// let results = getURLs(filter: filter) +// return (results.found.uniqued(), results.filtered.uniqued()) +// } +//} + +//extension Sequence where Element: Hashable { +// func uniqued() -> [Element] { +// var set = Set() +// return filter { set.insert($0).inserted } +// } +//} + +//extension Post +// var content: String? { +// body ?? embed_description +// } +// +// var local_url: URL { +// AccountManager.shared.instanceURL.appending(path: "post/\(id)") +// } +// +// public var imageURL: URL? { +// let url = url?.asURL +// return (url?.isImageURL ?? false) ? url : nil +// } +// +// public var videoURL: URL? { +// let url = url?.asURL +// return (url?.isVideoURL ?? false) ? url : nil +// } +// +// public var imageURLs: [URL]? { +// var urls = body?.getUniqueURLs().found.compactMap{ $0.isImageURL ? $0 : nil } +// if let url = imageURL { +// urls?.append(url) +// } +// +// return urls +// } +// +// public var videoURLs: [URL]? { +// var urls = body?.getUniqueURLs().found.compactMap{ $0.isVideoURL ? $0 : nil } +// if let url = videoURL { +// urls?.append(url) +// } +// +// return urls +// } +//} +// + +//extension Site { +// var full_sidebar: String { +// if let description = description?.nilOrValue, let sidebar = sidebar?.nilOrValue { +// return "\(description)\n\n\(sidebar)" +// } +// if let description = description?.nilOrValue { +// return description +// } +// if let sidebar = sidebar?.nilOrValue { +// return sidebar +// } +// +// return "" +// } +//} + +//extension Comment { +// +// var local_url: URL { +// AccountManager.shared.instanceURL.appending(path: "comment/\(id)") +// } +// +// var display_content: String { +// deleted ? "*deleted by creator*" : +// removed ? "*removed by mod*" : +// content +// } +// +// var parentId: Int? { +// let components = path.components(separatedBy: ".") +// +// guard path != "0", components.count != 2 else { +// return nil +// } +// +// guard let id = components.dropLast(1).last else { +// return nil +// } +// +// return Int(id) +// } +// +// var pathIds: [Int]? { +// let components = path.components(separatedBy: ".").dropFirst() +// return components.compactMap({ Int($0) }) +// } +// +// var depth: Int { +// let count = path.components(separatedBy: ".").count - 1 +// return count >= 0 ? count : 0 +// } +// +// var isTopLevel: Bool { +// return depth < 2 +// } +//} + +//extension Community { +// var community_instance_name: String { +// return "\(name)@\(URL(string: actor_id)!.host!)" +// } +// +// var instance_host: String { +// return URL(string: actor_id)!.host! +// } +// +// var local_url: URL { +// AccountManager.shared.instanceURL.appending(path: "c/\(community_instance_name)") +// } +//} + +//extension Person { +// var instance: String { +// return "\(actor_id.asURL!.host!)" +// } +// +// var full_username: String { +// return "\(name)@\(actor_id.asURL!.host!)" +// } +// +// var safe_display_name: String { +// return (!(display_name?.isEmpty ?? true) ? display_name : nil) ?? name +// } +//} diff --git a/Sources/Swimmy/Extensions/Date.swift b/Sources/Swimmy/Extensions/Date.swift new file mode 100644 index 0000000..7de37f6 --- /dev/null +++ b/Sources/Swimmy/Extensions/Date.swift @@ -0,0 +1,127 @@ +// +// Date.swift +// +// +// Created by Dana Buehre on 11/9/23. +// + +import Foundation + +extension Date { + + /// returns a string in the format `5(s,m,h,d,w,mo,y)` eg: `5m` + func timeAgoDisplay() -> String { + let calendar = Calendar.current + + if calendar.date(byAdding: .minute, value: -1, to: .now)! < self { // less than minute ago + let diff = calendar.dateComponents([.second], from: self, to: .now).second ?? 0 + return "\(diff)s" + } else if calendar.date(byAdding: .hour, value: -1, to: .now)! < self { // less than hour ago + let diff = calendar.dateComponents([.minute], from: self, to: .now).minute ?? 0 + return "\(diff)m" + } else if calendar.date(byAdding: .day, value: -1, to: .now)! < self { // less than day ago + let diff = calendar.dateComponents([.hour], from: self, to: .now).hour ?? 0 + return "\(diff)h" + } else if calendar.date(byAdding: .day, value: -7, to: .now)! < self { // less than week ago + let diff = calendar.dateComponents([.day], from: self, to: .now).day ?? 0 + return "\(diff)d" + } else if calendar.date(byAdding: .month, value: -1, to: .now)! < self { // less than month ago + let diff = calendar.dateComponents([.weekOfYear], from: self, to: .now).weekOfYear ?? 0 + return "\(diff)w" + } else if calendar.date(byAdding: .year, value: -1, to: .now)! < self { // less than year ago + let diff = calendar.dateComponents([.month], from: self, to: .now).month ?? 0 + return "\(diff)mo" + } + let diff = calendar.dateComponents([.year], from: self, to: .now).year ?? 0 + return "\(diff)y" + } + + /// converts the date from one timezone to another + func convert(from timeZone: TimeZone, to destinationTimeZone: TimeZone) -> Date { + let calendar = Calendar.current + var components = calendar.dateComponents(in: timeZone, from: self) + components.timeZone = destinationTimeZone + return calendar.date(from: components)! + } + + static func date(string: String) -> Date? { + DateHelpers.dateForString(string) + } +} + +struct DateHelpers { + + /// possible formats used by Lemmy + static let dateFormats: [String] = [ + "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ", + "yyyy-MM-dd'T'HH:mm:ss.SSSSSS", + "yyyy-MM-dd'T'HH:mm:ssZ", + "yyyy-MM-dd'T'HH:mm:ss", + "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", + "yyyy-MM-dd HH:mm:ss.SSSSSS", + "yyyy-MM-dd HH:mm:ssZ", + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm" + ] + + /// the GMT timezone + static let GMT: TimeZone = TimeZone(identifier: "GMT")! + + /// the current time in the GMT timezone + static var nowGMT: Date { + return .now.convert(from: Calendar.current.timeZone, to: GMT) + } + + /// formatters for each format used by Lemmy + static let formatters: [DateFormatter] = dateFormats.map { format in + let formatter = DateFormatter() + formatter.timeZone = GMT + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.dateFormat = format + return formatter + } + + static let ISO8061Formatter: ISO8601DateFormatter = { + ISO8601DateFormatter() + }() + + static var formatter: DateFormatter = { + let formatter = DateFormatter() + formatter.timeZone = GMT + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + return formatter + }() + + /// formatter used to produce a time since string + static var timeSinceFormatter: RelativeDateTimeFormatter = { + let formatter = RelativeDateTimeFormatter() + formatter.dateTimeStyle = .numeric + formatter.unitsStyle = .full + formatter.formattingContext = .standalone + formatter.calendar = .autoupdatingCurrent + return formatter + }() + + static func timeSinceLong(timestamp: String) -> String? { + guard let date = dateForString(timestamp) else { return nil } + return timeSinceFormatter.localizedString(for: date, relativeTo: nowGMT) + } + + static func timeSinceLong(timestamp: Date) -> String? { + return timeSinceFormatter.localizedString(for: timestamp, relativeTo: nowGMT) + } + + static func dateForString(_ string: String) -> Date? { + + if let date = ISO8061Formatter.date(from: string) { + return date + } + + for formatter in formatters { + guard let date = formatter.date(from: string) else { continue } + return date + } + + return nil + } +} diff --git a/Sources/Swimmy/Extensions/Encodable.swift b/Sources/Swimmy/Extensions/Encodable.swift new file mode 100644 index 0000000..53fb6f7 --- /dev/null +++ b/Sources/Swimmy/Extensions/Encodable.swift @@ -0,0 +1,17 @@ +// +// Encodable.swift +// +// +// Created by Dana Buehre on 11/7/23. +// + +import Foundation + +extension Encodable { + var prettyPrintedJSONString: String? { + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + guard let data = try? encoder.encode(self) else { return nil } + return String(data: data, encoding: .utf8) ?? nil + } +} diff --git a/Sources/Swimmy/Extensions/Publisher.swift b/Sources/Swimmy/Extensions/Publisher.swift new file mode 100644 index 0000000..d84896b --- /dev/null +++ b/Sources/Swimmy/Extensions/Publisher.swift @@ -0,0 +1,115 @@ +// +// Publisher.swift +// +// +// Created by Dana Buehre on 11/9/23. +// + +#if canImport(Combine) +import Combine +#else +import CombineX +#endif + +public extension Publisher { + /** + Creates a new publisher which will upon failure retry the upstream publisher a provided number of times, with the provided delay between retry attempts. + If the upstream publisher succeeds the first time this is bypassed and proceeds as normal. + + - Parameters: + - retries: The number of times to retry the upstream publisher. + - delay: Delay in seconds between retry attempts. + - scheduler: The scheduler to dispatch the delayed events. + + - Returns: A new publisher which will retry the upstream publisher with a delay upon failure. + + let url = URL(string: "https://api.myService.com")! + + URLSession.shared.dataTaskPublisher(for: url) + .retryWithDelay(retries: 4, delay: 5, scheduler: DispatchQueue.global()) + .sink { completion in + switch completion { + case .finished: + print("Success 😊") + case .failure(let error): + print("The last and final failure after retry attempts: \(error)") + } + } receiveValue: { output in + print("Received value: \(output)") + } + .store(in: &cancellables) + */ + func retryWithDelay( + retries: Int, + delay: S.SchedulerTimeType.Stride, + scheduler: S + ) -> AnyPublisher where S: Scheduler { + delayIfFailure(for: delay, scheduler: scheduler) { error in + if let error = error as? LemmyAPIError { + switch error { + case .lemmyError(message: _, code: let code), .network(code: let code, description: _): + debugPrint(error) + return !(code <= 0 || (code >= 400 && code < 500)) + default: + return true + } + } + return true + } + .retry(times: retries) { error in + if let error = error as? LemmyAPIError { + switch error { + case .lemmyError(message: _, code: let code), .network(code: let code, description: _): + return !(code <= 0 || (code >= 400 && code < 500)) + default: + return true + } + } + return true + } + .eraseToAnyPublisher() + } + + private func delayIfFailure( + for delay: S.SchedulerTimeType.Stride, + scheduler: S, + condition: @escaping (Error) -> Bool + ) -> AnyPublisher where S: Scheduler { + return self.catch { error in + Future { completion in + scheduler.schedule(after: scheduler.now.advanced(by: condition(error) ? delay : 0)) { + completion(.failure(error)) + } + } + } + .eraseToAnyPublisher() + } + + internal func retry(times: Int, if condition: @escaping (Failure) -> Bool) -> Publishers.RetryIf { + Publishers.RetryIf(publisher: self, times: times, condition: condition) + } +} + +extension Publishers { + struct RetryIf: Publisher { + typealias Output = P.Output + typealias Failure = P.Failure + + let publisher: P + let times: Int + let condition: (P.Failure) -> Bool + + func receive(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input { + guard times > 0 else { return publisher.receive(subscriber: subscriber) } + + publisher.catch { (error: P.Failure) -> AnyPublisher in + if condition(error) { + return RetryIf(publisher: publisher, times: times - 1, condition: condition).eraseToAnyPublisher() + } else { + return Fail(error: error).eraseToAnyPublisher() + } + } + .receive(subscriber: subscriber) + } + } +} diff --git a/Sources/Swimmy/Extensions/String.swift b/Sources/Swimmy/Extensions/String.swift new file mode 100644 index 0000000..9c61d51 --- /dev/null +++ b/Sources/Swimmy/Extensions/String.swift @@ -0,0 +1,38 @@ +// +// String.swift +// +// +// Created by Dana Buehre on 11/7/23. +// + +import Foundation + +extension String { + init?(data: Data, textEncodingName: String? = nil, `default`: String.Encoding = .utf8) { + let encoding: String.Encoding = { + if let textEncodingName = textEncodingName { + let cfEncoding = CFStringConvertIANACharSetNameToEncoding(textEncodingName as CFString) + if cfEncoding != kCFStringEncodingInvalidId { + let nsEncoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding) + return String.Encoding(rawValue: nsEncoding) + } + } + + return data.stringEncoding ?? `default` + }() + + self.init(data: data, encoding: encoding) + } + + var asURL: URL? { + return URL(string: self) + } +} + +extension Data { + var stringEncoding: String.Encoding? { + var nsString: NSString? + guard case let rawValue = NSString.stringEncoding(for: self, encodingOptions: nil, convertedString: &nsString, usedLossyConversion: nil), rawValue != 0 else { return nil } + return String.Encoding(rawValue: rawValue) + } +} diff --git a/Sources/Swimmy/Extensions/URL.swift b/Sources/Swimmy/Extensions/URL.swift new file mode 100644 index 0000000..a4a5322 --- /dev/null +++ b/Sources/Swimmy/Extensions/URL.swift @@ -0,0 +1,34 @@ +// +// URL.swift +// +// +// Created by Dana Buehre on 11/7/23. +// + +import Foundation + +extension URL { + + /// Returns a new URL by adding the query items, or nil if the URL doesn't support it. + /// URL must conform to RFC 3986. + func appending(queryItems: [URLQueryItem]) -> URL? { + guard var urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: true) else { + // URL is not conforming to RFC 3986 (maybe it is only conforming to RFC 1808, RFC 1738, and RFC 2732) + return nil + } + // append the query items to the existing ones + urlComponents.queryItems = (urlComponents.queryItems ?? []) + queryItems + + // return the url from new url components + return urlComponents.url + } + + // no idea why appendingPathComponent is not dropping one of the / resulting in https://example.com/api/v3//path + func appending(path: String) -> URL { + + let base = absoluteString.hasSuffix("/") ? String(absoluteString.dropLast(1)) : absoluteString + let newPath = path.hasPrefix("/") ? String(path.dropFirst(1)) : path + + return URL(string: "\(base)/\(newPath)")! + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/CommentSortType.swift b/Sources/Swimmy/Lemmy API/Enums/CommentSortType.swift new file mode 100644 index 0000000..4baf739 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/CommentSortType.swift @@ -0,0 +1,32 @@ +// +// CommentSortType.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public enum CommentSortType: String, Codable, CustomStringConvertible, CaseIterable { + case hot = "Hot" + case new = "New" + case old = "Old" + case top = "Top" + + public var description: String { + return self.rawValue + } + + public var imageName: String { + return CommentSortType.imageName(type: self) + } + + public static func imageName(type: CommentSortType) -> String { + switch type { + case .hot: return "flame" + case .new: return "clock" + case .old: return "arrow.down" + case .top: return "arrow.up" + } + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/ListingType.swift b/Sources/Swimmy/Lemmy API/Enums/ListingType.swift new file mode 100644 index 0000000..a18721f --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/ListingType.swift @@ -0,0 +1,23 @@ +// +// ListingType.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public enum ListingType: String, Codable, CustomStringConvertible, CaseIterable { + case all = "All" + case community = "Community" // this is invalid + case local = "Local" + case subscribed = "Subscribed" + + public var description: String { + return self.rawValue + } + + public static var allTypes: [ListingType] { + return [.all, local, .subscribed] + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/ModlogActionType.swift b/Sources/Swimmy/Lemmy API/Enums/ModlogActionType.swift new file mode 100644 index 0000000..83e3d2a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/ModlogActionType.swift @@ -0,0 +1,67 @@ +// +// ModlogActionType.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public enum ModlogActionType: String, Codable, CustomStringConvertible, CaseIterable { + case adminPurgeComment = "AdminPurgeComment" + case adminPurgeCommunity = "AdminPurgeCommunity" + case adminPurgePerson = "AdminPurgePerson" + case adminPurgePost = "AdminPurgePost" + case all = "All" + case modAdd = "ModAdd" + case modAddCommunity = "ModAddCommunity" + case modBan = "ModBan" + case modBanFromCommunity = "ModBanFromCommunity" + case modFeaturePost = "ModFeaturePost" + case modHideCommunity = "ModHideCommunity" + case modLockPost = "ModLockPost" + case modRemoveComment = "ModRemoveComment" + case modRemoveCommunity = "ModRemoveCommunity" + case modRemovePost = "ModRemovePost" + case modTransferCommunity = "ModTransferCommunity" + + public var description: String { + return self.rawValue + } + + public var displayName: String { + switch self { + case .adminPurgeComment: return "Purge Comment" + case .adminPurgeCommunity: return "Purge Community" + case .adminPurgePerson: return "Purge Person" + case .adminPurgePost: return "Purge Post" + case .all: return "All" + case .modAdd: return "Add Mod" + case .modAddCommunity: return "Add Community" + case .modBan: return "Ban From Instance" + case .modBanFromCommunity: return "Ban From Community" + case .modFeaturePost: return "Feature Post" + case .modHideCommunity: return "Hide Community" + case .modLockPost: return "Lock Post" + case .modRemoveComment: return "Remove Comment" + case .modRemoveCommunity: return "Remove Community" + case .modRemovePost: return "Remove Post" + case .modTransferCommunity: return "Transfer Community" + } + } + + public static let listableTypes: [ModlogActionType] = [ + .all, + .modAdd, + .modAddCommunity, + .modBan, + .modBanFromCommunity, + .modFeaturePost, + .modHideCommunity, + .modLockPost, + .modRemoveComment, + .modRemoveCommunity, + .modRemovePost, + .modTransferCommunity, + ] +} diff --git a/Sources/Swimmy/Lemmy API/Enums/PostFeatureType.swift b/Sources/Swimmy/Lemmy API/Enums/PostFeatureType.swift new file mode 100644 index 0000000..f1e27b4 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/PostFeatureType.swift @@ -0,0 +1,17 @@ +// +// PostFeatureType.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public enum PostFeatureType: String, Codable, CustomStringConvertible, CaseIterable { + case community = "Community" + case local = "Local" + + public var description: String { + return self.rawValue + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/RegistrationMode.swift b/Sources/Swimmy/Lemmy API/Enums/RegistrationMode.swift new file mode 100644 index 0000000..8e7e5a7 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/RegistrationMode.swift @@ -0,0 +1,18 @@ +// +// RegistrationMode.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public enum RegistrationMode: String, Codable, CustomStringConvertible, CaseIterable { + case closed = "Closed" + case open = "Open" + case requireApplication = "RequireApplication" + + public var description: String { + return self.rawValue + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/SearchType.swift b/Sources/Swimmy/Lemmy API/Enums/SearchType.swift new file mode 100644 index 0000000..2331804 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/SearchType.swift @@ -0,0 +1,21 @@ +// +// SearchType.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public enum SearchType: String, Codable, CustomStringConvertible, CaseIterable { + case all = "All" + case comments = "Comments" + case communities = "Communities" + case posts = "Posts" + case url = "Url" + case users = "Users" + + public var description: String { + return self.rawValue + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/SortType.swift b/Sources/Swimmy/Lemmy API/Enums/SortType.swift new file mode 100644 index 0000000..b19a637 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/SortType.swift @@ -0,0 +1,93 @@ +// +// SortType.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +/// Different post sort types used in lemmy. +public enum SortType: String, Codable, CustomStringConvertible, CaseIterable { + case active = "Active" + case hot = "Hot" + case mostComments = "MostComments" + case new = "New" + case newComments = "NewComments" + case old = "Old" + case topAll = "TopAll" + case topDay = "TopDay" + case topMonth = "TopMonth" + case topWeek = "TopWeek" + case topYear = "TopYear" + case topHour = "TopHour" + case topSixHour = "TopSixHour" + case topTwelveHour = "TopTwelveHour" + case topThreeMonths = "TopThreeMonths" + case topSixMonths = "TopSixMonths" + case topNineMonths = "TopNineMonths" + + public var description: String { + return self.rawValue + } + + public var label: String { + switch self { + case .active: return "Active" + case .hot: return "Hot" + case .mostComments: return "Most Comments" + case .new: return "New" + case .newComments: return "New Comments" + case .old: return "Old" + case .topAll: return "Top All" + case .topDay: return "Top Day" + case .topMonth: return "Top Month" + case .topWeek: return "Top Week" + case .topYear: return "Top Year" + case .topHour: return "Top Hour" + case .topSixHour: return "Top 6 Hour" + case .topTwelveHour: return "Top 12 Hour" + case .topThreeMonths: return "Top 3 Month" + case .topSixMonths: return "Top 6 Month" + case .topNineMonths: return "Top 9 Month" + } + } + + public var imageName: String { + return SortType.imageName(type: self) + } + + public static var allTypes: [SortType] { + return [.hot, .new, .active, .newComments, .mostComments, .old, .topAll, .topHour, .topSixHour, .topTwelveHour, .topDay, .topWeek, .topMonth, .topThreeMonths, .topNineMonths, .topYear] + } + + public static var allNonTopTypes: [SortType] { + return [.hot, .new, .active, .newComments, .mostComments, .old] + } + + public static var allTopTypes: [SortType] { + return [.topAll, .topHour, .topSixHour, .topTwelveHour, .topDay, .topWeek, .topMonth, .topThreeMonths, .topNineMonths, .topYear] + } + + public static func imageName(type: SortType) -> String { + switch type { + case .active: return "hare" + case .hot: return "flame" + case .mostComments: return "list.bullet.indent" + case .new: return "clock" + case .newComments: return "text.badge.plus" + case .old: return "arrow.down" + case .topAll: return "arrow.up" + case .topDay: return "calendar" + case .topMonth: return "calendar" + case .topWeek: return "calendar" + case .topYear: return "calendar" + case .topHour: return "calendar" + case .topSixHour: return "calendar" + case .topTwelveHour: return "calendar" + case .topThreeMonths: return "calendar" + case .topSixMonths: return "calendar" + case .topNineMonths: return "calendar" + } + } +} diff --git a/Sources/Swimmy/Lemmy API/Enums/SubscribedType.swift b/Sources/Swimmy/Lemmy API/Enums/SubscribedType.swift new file mode 100644 index 0000000..80760ae --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Enums/SubscribedType.swift @@ -0,0 +1,18 @@ +// +// SubscribedType.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public enum SubscribedType: String, Codable, CustomStringConvertible, CaseIterable { + case notSubscribed = "NotSubscribed" + case pending = "Pending" + case subscribed = "Subscribed" + + public var description: String { + return self.rawValue + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/AddAdmin.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/AddAdmin.swift new file mode 100644 index 0000000..c5e4880 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/AddAdmin.swift @@ -0,0 +1,29 @@ +// +// AddAdmin.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AddAdminRequest: APIRequest { + public typealias Response = AddAdminResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/admin/add" + public var jwt: String? { return auth } + + public let added: Bool + public let auth: String + public let person_id: Int + + public init(added: Bool, auth: String, person_id: Int) { + self.added = added + self.auth = auth + self.person_id = person_id + } +} +public struct AddAdminResponse: APIResponse { + public let admins: [PersonView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/ApproveRegistrationApplication.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/ApproveRegistrationApplication.swift new file mode 100644 index 0000000..d1701e3 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/ApproveRegistrationApplication.swift @@ -0,0 +1,24 @@ +// +// ApproveRegistrationApplication.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ApproveRegistrationApplicationRequest: APIRequest { + public typealias Response = RegistrationApplicationResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/admin/registration_application/approve" + public var jwt: String? { return auth } + + public let approve: Bool + public let auth: String + public let deny_reason: String? + public let id: Int +} +public struct RegistrationApplicationResponse: APIResponse { + public let registration_application: RegistrationApplicationView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/GetUnreadRegistrationApplicationCount.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/GetUnreadRegistrationApplicationCount.swift new file mode 100644 index 0000000..35af6a7 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/GetUnreadRegistrationApplicationCount.swift @@ -0,0 +1,25 @@ +// +// GetUnreadRegistrationApplicationCount.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetUnreadRegistrationApplicationCountRequest: APIRequest { + public typealias Response = GetUnreadRegistrationApplicationCountResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/admin/registration_application/count" + public var jwt: String? { return auth } + + public let auth: String + + public init(auth: String) { + self.auth = auth + } +} +public struct GetUnreadRegistrationApplicationCountResponse: APIResponse { + public let registration_applications: Int +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/ListRegistrationApplications.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/ListRegistrationApplications.swift new file mode 100644 index 0000000..8d02cdd --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/ListRegistrationApplications.swift @@ -0,0 +1,32 @@ +// +// ListRegistrationApplications.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ListRegistrationApplicationsRequest: APIRequest { + public typealias Response = ListRegistrationApplicationsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/admin/registration_application/list" + public var jwt: String? { return auth } + + public let auth: String + public let limit: Int? + public let page: Int? + /// Only shows the unread applications (IE those without an admin actor). + public let unread_only: Bool? + + public init(auth: String, limit: Int? = nil, page: Int? = nil, unread_only: Bool? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.unread_only = unread_only + } +} +public struct ListRegistrationApplicationsResponse: APIResponse { + public let registration_applications: [RegistrationApplicationView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeComment.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeComment.swift new file mode 100644 index 0000000..75ef237 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeComment.swift @@ -0,0 +1,29 @@ +// +// PurgeComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PurgeCommentRequest: APIRequest { + public typealias Response = PurgeItemResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/admin/purge/comment" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let reason: String? + + public init(auth: String, comment_id: Int, reason: String? = nil) { + self.auth = auth + self.comment_id = comment_id + self.reason = reason + } +} +public struct PurgeItemResponse: APIResponse { + public let success: Bool +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeCommunity.swift new file mode 100644 index 0000000..483be88 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgeCommunity.swift @@ -0,0 +1,26 @@ +// +// PurgeCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PurgeCommunityRequest: APIRequest { + public typealias Response = PurgeItemResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/admin/purge/community" + public var jwt: String? { return auth } + + public let auth: String + public let community_id: Int + public let reason: String? + + public init(auth: String, community_id: Int, reason: String? = nil) { + self.auth = auth + self.community_id = community_id + self.reason = reason + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePerson.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePerson.swift new file mode 100644 index 0000000..c04fb49 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePerson.swift @@ -0,0 +1,26 @@ +// +// PurgePerson.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PurgePersonRequest: APIRequest { + public typealias Response = PurgeItemResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/admin/purge/person" + public var jwt: String? { return auth } + + public let auth: String + public let person_id: Int + public let reason: String? + + public init(auth: String, person_id: Int, reason: String? = nil) { + self.auth = auth + self.person_id = person_id + self.reason = reason + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePost.swift b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePost.swift new file mode 100644 index 0000000..2c6be29 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Admin/PurgePost.swift @@ -0,0 +1,26 @@ +// +// PurgePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PurgePostRequest: APIRequest { + public typealias Response = PurgeItemResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/admin/purge/post" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + public let reason: String? + + public init(auth: String, post_id: Int, reason: String? = nil) { + self.auth = auth + self.post_id = post_id + self.reason = reason + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/CreateComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/CreateComment.swift new file mode 100644 index 0000000..ffc09a0 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/CreateComment.swift @@ -0,0 +1,28 @@ +// +// CreateComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreateCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment" + public var jwt: String? { return auth } + + public let auth: String + public let content: String + public let form_id: String? + public let language_id: Int? + public let parent_id: Int? + public let post_id: Int +} +public struct CommentResponse: APIResponse { + public let comment_view: CommentView + public let form_id: String? + public let recipient_ids: [Int] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/CreateCommentReport.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/CreateCommentReport.swift new file mode 100644 index 0000000..9c5add6 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/CreateCommentReport.swift @@ -0,0 +1,29 @@ +// +// CreateCommentReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreateCommentReportRequest: APIRequest { + public typealias Response = CommentReportResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/report" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let reason: String + + public init(auth: String, comment_id: Int, reason: String) { + self.auth = auth + self.comment_id = comment_id + self.reason = reason + } +} +public struct CommentReportResponse: APIResponse { + public let comment_report_view: CommentReportView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/DeleteComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/DeleteComment.swift new file mode 100644 index 0000000..6117110 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/DeleteComment.swift @@ -0,0 +1,26 @@ +// +// DeleteComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct DeleteCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/delete" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let deleted: Bool + + public init(auth: String, comment_id: Int, deleted: Bool) { + self.auth = auth + self.comment_id = comment_id + self.deleted = deleted + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/DistinguishComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/DistinguishComment.swift new file mode 100644 index 0000000..3697b95 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/DistinguishComment.swift @@ -0,0 +1,23 @@ +import Foundation + +public struct DistinguishCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/distinguish" + public var jwt: String? { return auth } + + public let comment_id: Int + public let distinguished: Bool + public let auth: String + + public init( + comment_id: Int, + distinguished: Bool, + auth: String + ) { + self.comment_id = comment_id + self.distinguished = distinguished + self.auth = auth + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/EditComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/EditComment.swift new file mode 100644 index 0000000..98c14b8 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/EditComment.swift @@ -0,0 +1,33 @@ +// +// EditComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct EditCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/comment" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let content: String? + /// "Distinguishes" a comment, or speak officially. Only doable by community mods or admins. + public let distinguished: Bool? + public let form_id: String? + public let language_id: Int? + + public init(auth: String, comment_id: Int, content: String? = nil, distinguished: Bool? = nil, form_id: String? = nil, language_id: Int? = nil) { + self.auth = auth + self.comment_id = comment_id + self.content = content + self.distinguished = distinguished + self.form_id = form_id + self.language_id = language_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/GetComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/GetComment.swift new file mode 100644 index 0000000..47edc68 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/GetComment.swift @@ -0,0 +1,27 @@ +// +// GetComment.swift +// Arctic +// +// Created by Dana Buehre on 7/9/23. +// + +import Foundation + + public struct GetCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/comment" + public var jwt: String? { return auth } + + public let auth: String? + public let id: Int + + public init( + auth: String? = nil, + id: Int + ) { + self.auth = auth + self.id = id + } + } diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/GetComments.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/GetComments.swift new file mode 100644 index 0000000..3889eee --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/GetComments.swift @@ -0,0 +1,45 @@ +// +// GetComments.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetCommentsRequest: APIRequest { + public typealias Response = GetCommentsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/comment/list" + public var jwt: String? { return auth } + + public let auth: String? + public let community_id: Int? + public let community_name: String? + public let limit: Int? + public let max_depth: Int? + public let page: Int? + public let parent_id: Int? + public let post_id: Int? + public let saved_only: Bool? + public let sort: CommentSortType? + public let type_: ListingType? + + public init(auth: String? = nil, community_id: Int? = nil, community_name: String? = nil, limit: Int? = nil, max_depth: Int? = nil, page: Int? = nil, parent_id: Int? = nil, post_id: Int? = nil, saved_only: Bool? = nil, sort: CommentSortType? = nil, type_: ListingType? = nil) { + self.auth = auth + self.community_id = community_id + self.community_name = community_name + self.limit = limit + self.max_depth = max_depth + self.page = page + self.parent_id = parent_id + self.post_id = post_id + self.saved_only = saved_only + self.sort = sort + self.type_ = type_ + } +} +public struct GetCommentsResponse: APIResponse { + public let comments: [CommentView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/LikeComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/LikeComment.swift new file mode 100644 index 0000000..38069c3 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/LikeComment.swift @@ -0,0 +1,26 @@ +// +// LikeComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LikeCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/like" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let score: Int + + public init(auth: String, comment_id: Int, score: Int) { + self.auth = auth + self.comment_id = comment_id + self.score = score + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/ListCommentReports.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/ListCommentReports.swift new file mode 100644 index 0000000..2fa427d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/ListCommentReports.swift @@ -0,0 +1,35 @@ +// +// ListCommentReports.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ListCommentReportsRequest: APIRequest { + public typealias Response = ListCommentReportsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/comment/report/list" + public var jwt: String? { return auth } + + public let auth: String + /// If no community is given, it returns reports for all communities moderated by the auth user. + public let community_id: Int? + public let limit: Int? + public let page: Int? + /// Only shows the unresolved reports. + public let unresolved_only: Bool? + + public init(auth: String, community_id: Int? = nil, limit: Int? = nil, page: Int? = nil, unresolved_only: Bool? = nil) { + self.auth = auth + self.community_id = community_id + self.limit = limit + self.page = page + self.unresolved_only = unresolved_only + } +} +public struct ListCommentReportsResponse: APIResponse { + public let comment_reports: [CommentReportView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/MarkCommentReplyAsRead.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/MarkCommentReplyAsRead.swift new file mode 100644 index 0000000..9bd1ce2 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/MarkCommentReplyAsRead.swift @@ -0,0 +1,34 @@ +// +// MarkCommentReplyAsRead.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MarkCommentReplyAsReadRequest: APIRequest { + public typealias Response = CommentReplyResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/mark_as_read" + public var jwt: String? { return auth } + + public let auth: String + public let comment_reply_id: Int + public let read: Bool + + public init(auth: String, comment_reply_id: Int, read: Bool) { + self.auth = auth + self.comment_reply_id = comment_reply_id + self.read = read + } +} + +public struct CommentReplyResponse: APIResponse { + public let comment_reply_view: CommentReplyView + + public init(comment_reply_view: CommentReplyView) { + self.comment_reply_view = comment_reply_view + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/RemoveComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/RemoveComment.swift new file mode 100644 index 0000000..58e0f58 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/RemoveComment.swift @@ -0,0 +1,28 @@ +// +// RemoveComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RemoveCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/comment/remove" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let reason: String? + public let removed: Bool + + public init(auth: String, comment_id: Int, reason: String? = nil, removed: Bool) { + self.auth = auth + self.comment_id = comment_id + self.reason = reason + self.removed = removed + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/ResolveCommentReport.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/ResolveCommentReport.swift new file mode 100644 index 0000000..ce6a199 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/ResolveCommentReport.swift @@ -0,0 +1,27 @@ +// +// ResolveCommentReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ResolveCommentReportRequest: APIRequest { + public typealias Response = CommentReportResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/comment/report/resolve" + public var jwt: String? { return auth } + + public let auth: String + public let report_id: Int + /// Either resolve or unresolve a report. + public let resolved: Bool + + public init(auth: String, report_id: Int, resolved: Bool) { + self.auth = auth + self.report_id = report_id + self.resolved = resolved + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Comment/SaveComment.swift b/Sources/Swimmy/Lemmy API/Requests/Comment/SaveComment.swift new file mode 100644 index 0000000..ec31d99 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Comment/SaveComment.swift @@ -0,0 +1,26 @@ +// +// SaveComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SaveCommentRequest: APIRequest { + public typealias Response = CommentResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/comment/save" + public var jwt: String? { return auth } + + public let auth: String + public let comment_id: Int + public let save: Bool + + public init(auth: String, comment_id: Int, save: Bool) { + self.auth = auth + self.comment_id = comment_id + self.save = save + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/AddModToCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/AddModToCommunity.swift new file mode 100644 index 0000000..65efb27 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/AddModToCommunity.swift @@ -0,0 +1,31 @@ +// +// AddModToCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AddModToCommunityRequest: APIRequest { + public typealias Response = AddModToCommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/mod" + public var jwt: String? { return auth } + + public let added: Bool + public let auth: String + public let community_id: Int + public let person_id: Int + + public init(added: Bool, auth: String, community_id: Int, person_id: Int) { + self.added = added + self.auth = auth + self.community_id = community_id + self.person_id = person_id + } +} +public struct AddModToCommunityResponse: APIResponse { + public let moderators: [CommunityModeratorView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/BanFromCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/BanFromCommunity.swift new file mode 100644 index 0000000..7037327 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/BanFromCommunity.swift @@ -0,0 +1,40 @@ +// +// BanFromCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct BanFromCommunityRequest: APIRequest { + public typealias Response = BanFromCommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/ban_user" + public var jwt: String? { return auth } + + public let auth: String + public let ban: Bool + public let community_id: Int + /// The expire time in Unix seconds. + public let expires: Int? + public let person_id: Int + public let reason: String? + /// Removes/Restores their comments and posts for that community. + public let remove_data: Bool? + + public init(auth: String, ban: Bool, community_id: Int, expires: Int? = nil, person_id: Int, reason: String? = nil, remove_data: Bool? = nil) { + self.auth = auth + self.ban = ban + self.community_id = community_id + self.expires = expires + self.person_id = person_id + self.reason = reason + self.remove_data = remove_data + } +} +public struct BanFromCommunityResponse: APIResponse { + public let banned: Bool + public let person_view: PersonView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/BlockCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/BlockCommunity.swift new file mode 100644 index 0000000..1ad1b51 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/BlockCommunity.swift @@ -0,0 +1,58 @@ +// +// BlockCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct BlockCommunityRequest: APIRequest { + public typealias Response = BlockCommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/block" + public var jwt: String? { return auth } + + public let auth: String + public let block: Bool + public let community_id: Int + + public init(auth: String, block: Bool, community_id: Int) { + self.auth = auth + self.block = block + self.community_id = community_id + } +} +public struct BlockCommunityResponse: APIResponse { + public let blocked: Bool + public let community_view: CommunityView +} + +public struct HideCommunityRequest: APIRequest { + public typealias Response = HideCommunityResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/community/hide" + public var jwt: String? { return auth } + + let community_id: Int + + let hidden: Bool + let reason: String? + + let auth: String + + public init(auth: String, community_id: Int, hidden: Bool, reason: String?) { + + self.auth = auth + self.community_id = community_id + self.hidden = hidden + self.reason = reason + } +} + +public struct HideCommunityResponse: APIResponse { + let communityView: CommunityView + let discussionLanguages: [Int] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/CreateCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/CreateCommunity.swift new file mode 100644 index 0000000..07ba592 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/CreateCommunity.swift @@ -0,0 +1,42 @@ +// +// CreateCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreateCommunityRequest: APIRequest { + public typealias Response = CommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community" + public var jwt: String? { return auth } + + public let auth: String + public let banner: String? + public let description: String? + public let discussion_languages: [Int]? + public let icon: String? + public let name: String + public let nsfw: Bool? + public let posting_restricted_to_mods: Bool? + public let title: String + + public init(auth: String, banner: String? = nil, description: String? = nil, discussion_languages: [Int]? = nil, icon: String? = nil, name: String, nsfw: Bool? = nil, posting_restricted_to_mods: Bool? = nil, title: String) { + self.auth = auth + self.banner = banner + self.description = description + self.discussion_languages = discussion_languages + self.icon = icon + self.name = name + self.nsfw = nsfw + self.posting_restricted_to_mods = posting_restricted_to_mods + self.title = title + } +} +public struct CommunityResponse: APIResponse { + public let community_view: CommunityView + public let discussion_languages: [Int] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/DeleteCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/DeleteCommunity.swift new file mode 100644 index 0000000..7fff9e4 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/DeleteCommunity.swift @@ -0,0 +1,26 @@ +// +// DeleteCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct DeleteCommunityRequest: APIRequest { + public typealias Response = CommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/delete" + public var jwt: String? { return auth } + + public let auth: String + public let community_id: Int + public let deleted: Bool + + public init(auth: String, community_id: Int, deleted: Bool) { + self.auth = auth + self.community_id = community_id + self.deleted = deleted + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/EditCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/EditCommunity.swift new file mode 100644 index 0000000..afc3bb5 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/EditCommunity.swift @@ -0,0 +1,38 @@ +// +// EditCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct EditCommunityRequest: APIRequest { + public typealias Response = CommunityResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/community" + public var jwt: String? { return auth } + + public let auth: String + public let banner: String? + public let community_id: Int + public let description: String? + public let discussion_languages: [Int]? + public let icon: String? + public let nsfw: Bool? + public let posting_restricted_to_mods: Bool? + public let title: String? + + public init(auth: String, banner: String? = nil, community_id: Int, description: String? = nil, discussion_languages: [Int]? = nil, icon: String? = nil, nsfw: Bool? = nil, posting_restricted_to_mods: Bool? = nil, title: String? = nil) { + self.auth = auth + self.banner = banner + self.community_id = community_id + self.description = description + self.discussion_languages = discussion_languages + self.icon = icon + self.nsfw = nsfw + self.posting_restricted_to_mods = posting_restricted_to_mods + self.title = title + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/FollowCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/FollowCommunity.swift new file mode 100644 index 0000000..32227d4 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/FollowCommunity.swift @@ -0,0 +1,26 @@ +// +// FollowCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct FollowCommunityRequest: APIRequest { + public typealias Response = CommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/follow" + public var jwt: String? { return auth } + + public let auth: String + public let community_id: Int + public let follow: Bool + + public init(auth: String, community_id: Int, follow: Bool) { + self.auth = auth + self.community_id = community_id + self.follow = follow + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/GetCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/GetCommunity.swift new file mode 100644 index 0000000..8c147e3 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/GetCommunity.swift @@ -0,0 +1,34 @@ +// +// GetCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetCommunityRequest: APIRequest { + public typealias Response = GetCommunityResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/community" + public var jwt: String? { return auth } + + public let auth: String? + public let id: Int? + public let name: String? + + public init(auth: String? = nil, id: Int? = nil, name: String? = nil) { + self.auth = auth + self.id = id + self.name = name + } +} +public struct GetCommunityResponse: APIResponse { + public let community_view: CommunityView + public let default_post_language: Int? + public let discussion_languages: [Int] + public let moderators: [CommunityModeratorView] + public let online: Int? // v0.18 removed + public let site: Site? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/ListCommunities.swift b/Sources/Swimmy/Lemmy API/Requests/Community/ListCommunities.swift new file mode 100644 index 0000000..8e4e753 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/ListCommunities.swift @@ -0,0 +1,33 @@ +// +// ListCommunities.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ListCommunitiesRequest: APIRequest { + public typealias Response = ListCommunitiesResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/community/list" + public var jwt: String? { return auth } + + public let auth: String? + public let limit: Int? + public let page: Int? + public let sort: SortType? + public let type_: ListingType? + + public init(auth: String? = nil, limit: Int? = nil, page: Int? = nil, sort: SortType? = nil, type_: ListingType? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.sort = sort + self.type_ = type_ + } +} +public struct ListCommunitiesResponse: APIResponse { + public let communities: [CommunityView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/RemoveCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/RemoveCommunity.swift new file mode 100644 index 0000000..1dbe23d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/RemoveCommunity.swift @@ -0,0 +1,31 @@ +// +// RemoveCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RemoveCommunityRequest: APIRequest { + public typealias Response = CommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/remove" + public var jwt: String? { return auth } + + public let auth: String + public let community_id: Int + /// The expire time in Unix seconds. + public let expires: Int? + public let reason: String? + public let removed: Bool + + public init(auth: String, community_id: Int, expires: Int? = nil, reason: String? = nil, removed: Bool) { + self.auth = auth + self.community_id = community_id + self.expires = expires + self.reason = reason + self.removed = removed + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Community/TransferCommunity.swift b/Sources/Swimmy/Lemmy API/Requests/Community/TransferCommunity.swift new file mode 100644 index 0000000..0b13688 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Community/TransferCommunity.swift @@ -0,0 +1,26 @@ +// +// TransferCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct TransferCommunityRequest: APIRequest { + public typealias Response = GetCommunityResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/community/transfer" + public var jwt: String? { return auth } + + public let auth: String + public let community_id: Int + public let person_id: Int + + public init(auth: String, community_id: Int, person_id: Int) { + self.auth = auth + self.community_id = community_id + self.person_id = person_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Federated Instances/GetFederatedInstances.swift b/Sources/Swimmy/Lemmy API/Requests/Federated Instances/GetFederatedInstances.swift new file mode 100644 index 0000000..f9e9a6a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Federated Instances/GetFederatedInstances.swift @@ -0,0 +1,25 @@ +// +// GetFederatedInstances.swift +// Arctic +// +// Created by Dana Buehre on 8/31/23. +// + +import Foundation + +public struct GetFederatedInstances: APIRequest { + public typealias Response = GetFederatedInstancesResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/federated_instances" + public var jwt: String? { return auth } + + public let auth: String? + + public init(auth: String? = nil) { + self.auth = auth + } +} +public struct GetFederatedInstancesResponse: APIResponse { + public let federated_instances: FederatedInstances? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Mod/GetModlog.swift b/Sources/Swimmy/Lemmy API/Requests/Mod/GetModlog.swift new file mode 100644 index 0000000..ca04985 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Mod/GetModlog.swift @@ -0,0 +1,51 @@ +// +// GetModlog.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetModlogRequest: APIRequest { + public typealias Response = GetModlogResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/modlog" + public var jwt: String? { return auth } + + public let auth: String? + public let community_id: Int? + public let limit: Int? + public let mod_person_id: Int? + public let other_person_id: Int? + public let page: Int? + public let type_: ModlogActionType + + public init(auth: String? = nil, community_id: Int? = nil, limit: Int? = nil, mod_person_id: Int? = nil, other_person_id: Int? = nil, page: Int? = nil, type_: ModlogActionType) { + self.auth = auth + self.community_id = community_id + self.limit = limit + self.mod_person_id = mod_person_id + self.other_person_id = other_person_id + self.page = page + self.type_ = type_ + } +} +public struct GetModlogResponse: APIResponse { + public let added: [ModAddView] + public let added_to_community: [ModAddCommunityView] + public let admin_purged_comments: [AdminPurgeCommentView] + public let admin_purged_communities: [AdminPurgeCommunityView] + public let admin_purged_persons: [AdminPurgePersonView] + public let admin_purged_posts: [AdminPurgePostView] + public let banned: [ModBanView] + public let banned_from_community: [ModBanFromCommunityView] + public let featured_posts: [ModFeaturePostView] + public let locked_posts: [ModLockPostView] + public let removed_comments: [ModRemoveCommentView] + public let removed_communities: [ModRemoveCommunityView] + public let removed_posts: [ModRemovePostView] + public let transferred_to_community: [ModTransferCommunityView] + public let hidden_communities: [ModHideCommunityView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Pictrs/UploadImageRequest.swift b/Sources/Swimmy/Lemmy API/Requests/Pictrs/UploadImageRequest.swift new file mode 100644 index 0000000..1c18b83 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Pictrs/UploadImageRequest.swift @@ -0,0 +1,33 @@ +// +// UploadImageRequest.swift +// lemming +// +// Created by Dana Buehre on 7/3/23. +// + +import Foundation + +public struct UploadImageRequest: APIRequest { + public typealias Response = UploadImageResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/pictrs/image" + public var jwt: String? { return auth } + + public let auth: String? + public let image: Data + + public init(auth: String?, image: Data) { + self.auth = auth + self.image = image + } +} + +public struct UploadImageResponse: APIResponse { + public let delete_url: String? + public let files: [ImageFile]? + /// Is "ok" if the upload was successful; is something else otherwise. + public let msg: String + public let url: String? + +} diff --git "a/Sources/Swimmy/Lemmy API/Requests/Post/\020GetSiteMetadata.swift" "b/Sources/Swimmy/Lemmy API/Requests/Post/\020GetSiteMetadata.swift" new file mode 100644 index 0000000..f8df320 --- /dev/null +++ "b/Sources/Swimmy/Lemmy API/Requests/Post/\020GetSiteMetadata.swift" @@ -0,0 +1,25 @@ +// +// GetSiteMetadata.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetSiteMetadataRequest: APIRequest { + public typealias Response = GetSiteMetadataResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/post/site_metadata" + public var jwt: String? { return nil } + + public let url: String + + public init(url: String) { + self.url = url + } +} +public struct GetSiteMetadataResponse: APIResponse { + public let metadata: SiteMetadata +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/CreatePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/CreatePost.swift new file mode 100644 index 0000000..7ccad3c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/CreatePost.swift @@ -0,0 +1,39 @@ +// +// CreatePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreatePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post" + public var jwt: String? { return auth } + + public let auth: String + public let body: String? + public let community_id: Int + public let honeypot: String? + public let language_id: Int? + public let name: String + public let nsfw: Bool? + public let url: String? + + public init(auth: String, body: String? = nil, community_id: Int, honeypot: String? = nil, language_id: Int? = nil, name: String, nsfw: Bool? = nil, url: String? = nil) { + self.auth = auth + self.body = body + self.community_id = community_id + self.honeypot = honeypot + self.language_id = language_id + self.name = name + self.nsfw = nsfw + self.url = url + } +} +public struct PostResponse: APIResponse { + public let post_view: PostView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/CreatePostReport.swift b/Sources/Swimmy/Lemmy API/Requests/Post/CreatePostReport.swift new file mode 100644 index 0000000..1238283 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/CreatePostReport.swift @@ -0,0 +1,29 @@ +// +// CreatePostReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreatePostReportRequest: APIRequest { + public typealias Response = PostReportResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/report" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + public let reason: String + + public init(auth: String, post_id: Int, reason: String) { + self.auth = auth + self.post_id = post_id + self.reason = reason + } +} +public struct PostReportResponse: APIResponse { + public let post_report_view: PostReportView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/DeletePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/DeletePost.swift new file mode 100644 index 0000000..379b984 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/DeletePost.swift @@ -0,0 +1,26 @@ +// +// DeletePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct DeletePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/delete" + public var jwt: String? { return auth } + + public let auth: String + public let deleted: Bool + public let post_id: Int + + public init(auth: String, deleted: Bool, post_id: Int) { + self.auth = auth + self.deleted = deleted + self.post_id = post_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/EditPost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/EditPost.swift new file mode 100644 index 0000000..abfa968 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/EditPost.swift @@ -0,0 +1,34 @@ +// +// EditPost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct EditPostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/post" + public var jwt: String? { return auth } + + public let auth: String + public let body: String? + public let language_id: Int? + public let name: String? + public let nsfw: Bool? + public let post_id: Int + public let url: String? + + public init(auth: String, body: String? = nil, language_id: Int? = nil, name: String? = nil, nsfw: Bool? = nil, post_id: Int, url: String? = nil) { + self.auth = auth + self.body = body + self.language_id = language_id + self.name = name + self.nsfw = nsfw + self.post_id = post_id + self.url = url + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/FeaturePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/FeaturePost.swift new file mode 100644 index 0000000..d9a9fa7 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/FeaturePost.swift @@ -0,0 +1,28 @@ +// +// FeaturePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct FeaturePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/feature" + public var jwt: String? { return auth } + + public let auth: String + public let feature_type: PostFeatureType + public let featured: Bool + public let post_id: Int + + public init(auth: String, feature_type: PostFeatureType, featured: Bool, post_id: Int) { + self.auth = auth + self.feature_type = feature_type + self.featured = featured + self.post_id = post_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/GetPost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/GetPost.swift new file mode 100644 index 0000000..400e042 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/GetPost.swift @@ -0,0 +1,33 @@ +// +// GetPost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetPostRequest: APIRequest { + public typealias Response = GetPostResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/post" + public var jwt: String? { return auth } + + public let auth: String? + public let comment_id: Int? + public let id: Int? + + public init(auth: String? = nil, comment_id: Int? = nil, id: Int? = nil) { + self.auth = auth + self.comment_id = comment_id + self.id = id + } +} +public struct GetPostResponse: APIResponse { + public let community_view: CommunityView + public let moderators: [CommunityModeratorView] + public let online: Int? // removed in v0.18 + public let post_view: PostView + public let cross_posts: [PostView]? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/GetPosts.swift b/Sources/Swimmy/Lemmy API/Requests/Post/GetPosts.swift new file mode 100644 index 0000000..88ce721 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/GetPosts.swift @@ -0,0 +1,45 @@ +// +// GetPosts.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetPostsRequest: APIRequest { + public typealias Response = GetPostsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/post/list" + public var jwt: String? { return auth } + + public let auth: String? + public let community_id: Int? + /// To get posts for a federated community by name, use `name@instance.tld`. + public let community_name: String? + /// The maximum number of posts to retrieve. + /// + /// It is possible that less posts will be returned if the maximum is greater than the number of posts available. + /// + /// The server will throw a `couldnt_get_posts` error if you pass in a limit greater than 50. + public let limit: Int? + public let page: Int? + public let saved_only: Bool? + public let sort: SortType? + public let type_: ListingType? + + public init(auth: String? = nil, community_id: Int? = nil, community_name: String? = nil, limit: Int? = nil, page: Int? = nil, saved_only: Bool? = nil, sort: SortType? = nil, type_: ListingType? = nil) { + self.auth = auth + self.community_id = community_id + self.community_name = community_name + self.limit = limit + self.page = page + self.saved_only = saved_only + self.sort = sort + self.type_ = type_ + } +} +public struct GetPostsResponse: APIResponse { + public let posts: [PostView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/LikePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/LikePost.swift new file mode 100644 index 0000000..47a8a42 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/LikePost.swift @@ -0,0 +1,27 @@ +// +// LikePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LikePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/like" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + /// Must be 0, -1, or 1. Anything else will be rejected. + public let score: Int + + public init(auth: String, post_id: Int, score: Int) { + self.auth = auth + self.post_id = post_id + self.score = score + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/ListPostReports.swift b/Sources/Swimmy/Lemmy API/Requests/Post/ListPostReports.swift new file mode 100644 index 0000000..79c4b3b --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/ListPostReports.swift @@ -0,0 +1,35 @@ +// +// ListPostReports.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ListPostReportsRequest: APIRequest { + public typealias Response = ListPostReportsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/post/report/list" + public var jwt: String? { return auth } + + public let auth: String + /// If no community is given, it returns reports for all communities moderated by the auth user. + public let community_id: Int? + public let limit: Int? + public let page: Int? + /// Only shows the unresolved reports. + public let unresovled_only: Bool? + + public init(auth: String, community_id: Int? = nil, limit: Int? = nil, page: Int? = nil, unresovled_only: Bool? = nil) { + self.auth = auth + self.community_id = community_id + self.limit = limit + self.page = page + self.unresovled_only = unresovled_only + } +} +public struct ListPostReportsResponse: APIResponse { + public let post_reports: [PostReportView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/LockPost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/LockPost.swift new file mode 100644 index 0000000..9874f55 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/LockPost.swift @@ -0,0 +1,26 @@ +// +// LockPost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LockPostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/lock" + public var jwt: String? { return auth } + + public let auth: String + public let locked: Bool + public let post_id: Int + + public init(auth: String, locked: Bool, post_id: Int) { + self.auth = auth + self.locked = locked + self.post_id = post_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/MarkPostAsRead.swift b/Sources/Swimmy/Lemmy API/Requests/Post/MarkPostAsRead.swift new file mode 100644 index 0000000..36839c7 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/MarkPostAsRead.swift @@ -0,0 +1,26 @@ +// +// MarkPostAsRead.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MarkPostAsReadRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/mark_as_read" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + public let read: Bool + + public init(auth: String, post_id: Int, read: Bool) { + self.auth = auth + self.post_id = post_id + self.read = read + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/RemovePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/RemovePost.swift new file mode 100644 index 0000000..cd0320c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/RemovePost.swift @@ -0,0 +1,28 @@ +// +// RemovePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RemovePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/post/remove" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + public let reason: String? + public let removed: Bool + + public init(auth: String, post_id: Int, reason: String? = nil, removed: Bool) { + self.auth = auth + self.post_id = post_id + self.reason = reason + self.removed = removed + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/ResolvePostReport.swift b/Sources/Swimmy/Lemmy API/Requests/Post/ResolvePostReport.swift new file mode 100644 index 0000000..1606ef1 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/ResolvePostReport.swift @@ -0,0 +1,27 @@ +// +// ResolvePostReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ResolvePostReportRequest: APIRequest { + public typealias Response = PostReportResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/post/report/resolve" + public var jwt: String? { return auth } + + public let auth: String + public let report_id: Int + /// Either resolve or unresolve a report. + public let resolved: Bool + + public init(auth: String, report_id: Int, resolved: Bool) { + self.auth = auth + self.report_id = report_id + self.resolved = resolved + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Post/SavePost.swift b/Sources/Swimmy/Lemmy API/Requests/Post/SavePost.swift new file mode 100644 index 0000000..67bea5a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Post/SavePost.swift @@ -0,0 +1,26 @@ +// +// SavePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SavePostRequest: APIRequest { + public typealias Response = PostResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/post/save" + public var jwt: String? { return auth } + + public let auth: String + public let post_id: Int + public let save: Bool + + public init(auth: String, post_id: Int, save: Bool) { + self.auth = auth + self.post_id = post_id + self.save = save + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessage.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessage.swift new file mode 100644 index 0000000..0a327fa --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessage.swift @@ -0,0 +1,29 @@ +// +// CreatePrivateMessage.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreatePrivateMessageRequest: APIRequest { + public typealias Response = PrivateMessageResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/private_message" + public var jwt: String? { return auth } + + public let auth: String + public let content: String + public let recipient_id: Int + + public init(auth: String, content: String, recipient_id: Int) { + self.auth = auth + self.content = content + self.recipient_id = recipient_id + } +} +public struct PrivateMessageResponse: APIResponse { + public let private_message_view: PrivateMessageView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessageReport.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessageReport.swift new file mode 100644 index 0000000..2b69158 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/CreatePrivateMessageReport.swift @@ -0,0 +1,29 @@ +// +// CreatePrivateMessageReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreatePrivateMessageReportRequest: APIRequest { + public typealias Response = PrivateMessageReportResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/private_message/report" + public var jwt: String? { return auth } + + public let auth: String + public let private_message_id: Int + public let reason: String + + public init(auth: String, private_message_id: Int, reason: String) { + self.auth = auth + self.private_message_id = private_message_id + self.reason = reason + } +} +public struct PrivateMessageReportResponse: APIResponse { + public let private_message_report_view: PrivateMessageReportView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/DeletePrivateMessage.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/DeletePrivateMessage.swift new file mode 100644 index 0000000..2f15166 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/DeletePrivateMessage.swift @@ -0,0 +1,26 @@ +// +// DeletePrivateMessage.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct DeletePrivateMessageRequest: APIRequest { + public typealias Response = PrivateMessageResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/private_message/delete" + public var jwt: String? { return auth } + + public let auth: String + public let deleted: Bool + public let private_message_id: Int + + public init(auth: String, deleted: Bool, private_message_id: Int) { + self.auth = auth + self.deleted = deleted + self.private_message_id = private_message_id + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/EditPrivateMessage.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/EditPrivateMessage.swift new file mode 100644 index 0000000..b9f507e --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/EditPrivateMessage.swift @@ -0,0 +1,20 @@ +// +// EditPrivateMessage.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct EditPrivateMessageRequest: APIRequest { + public typealias Response = PrivateMessageResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/private_message" + public var jwt: String? { return auth } + + public let auth: String + public let content: String + public let private_message_id: Int +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/GetPrivateMessages.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/GetPrivateMessages.swift new file mode 100644 index 0000000..066fe30 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/GetPrivateMessages.swift @@ -0,0 +1,31 @@ +// +// GetPrivateMessages.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetPrivateMessagesRequest: APIRequest { + public typealias Response = PrivateMessagesResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/private_message/list" + public var jwt: String? { return auth } + + public let auth: String + public let limit: Int? + public let page: Int? + public let unread_only: Bool? + + public init(auth: String, limit: Int? = nil, page: Int? = nil, unread_only: Bool? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.unread_only = unread_only + } +} +public struct PrivateMessagesResponse: APIResponse { + public let private_messages: [PrivateMessageView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/ListPrivateMessageReports.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/ListPrivateMessageReports.swift new file mode 100644 index 0000000..218fc3b --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/ListPrivateMessageReports.swift @@ -0,0 +1,31 @@ +// +// ListPrivateMessageReports.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ListPrivateMessageReportsRequest: APIRequest { + public typealias Response = ListPrivateMessageReportsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/private_message/report/list" + public var jwt: String? { return auth } + + public let auth: String + public let limit: Int? + public let page: Int? + public let unresolved_only: Bool? + + public init(auth: String, limit: Int? = nil, page: Int? = nil, unresolved_only: Bool? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.unresolved_only = unresolved_only + } +} +public struct ListPrivateMessageReportsResponse: APIResponse { + public let private_message_reports: [PrivateMessageReportView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/MarkPrivateMessageAsRead.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/MarkPrivateMessageAsRead.swift new file mode 100644 index 0000000..b10e516 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/MarkPrivateMessageAsRead.swift @@ -0,0 +1,26 @@ +// +// MarkPrivateMessageAsRead.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MarkPrivateMessageAsReadRequest: APIRequest { + public typealias Response = PrivateMessageResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/private_message/mark_as_read" + public var jwt: String? { return auth } + + public let auth: String + public let private_message_id: Int + public let read: Bool + + public init(auth: String, private_message_id: Int, read: Bool) { + self.auth = auth + self.private_message_id = private_message_id + self.read = read + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Private Message/ResolvePrivateMessageReport.swift b/Sources/Swimmy/Lemmy API/Requests/Private Message/ResolvePrivateMessageReport.swift new file mode 100644 index 0000000..d71c136 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Private Message/ResolvePrivateMessageReport.swift @@ -0,0 +1,26 @@ +// +// ResolvePrivateMessageReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ResolvePrivateMessageReportRequest: APIRequest { + public typealias Response = PrivateMessageReportResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/private_message/report/resolve" + public var jwt: String? { return auth } + + public let auth: String + public let report_id: Int + public let resolved: Bool + + public init(auth: String, report_id: Int, resolved: Bool) { + self.auth = auth + self.report_id = report_id + self.resolved = resolved + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/ResolveObject/ResolveObject.swift b/Sources/Swimmy/Lemmy API/Requests/ResolveObject/ResolveObject.swift new file mode 100644 index 0000000..d5b1cba --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/ResolveObject/ResolveObject.swift @@ -0,0 +1,30 @@ +// +// ResolveObject.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ResolveObjectRequest: APIRequest { + public typealias Response = ResolveObjectResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/resolve_object" + public var jwt: String? { return auth } + + public let auth: String? + public let q: String + + public init(auth: String? = nil, q: String) { + self.auth = auth + self.q = q + } +} +public struct ResolveObjectResponse: APIResponse { + public let comment: CommentView? + public let community: CommunityView? + public let person: PersonView? + public let post: PostView? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Search/Search.swift b/Sources/Swimmy/Lemmy API/Requests/Search/Search.swift new file mode 100644 index 0000000..da4c03e --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Search/Search.swift @@ -0,0 +1,47 @@ +// +// Search.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct SearchRequest: APIRequest { + public typealias Response = SearchResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/search" + public var jwt: String? { return auth } + + public let auth: String? + public let community_id: Int? + public let community_name: String? + public let creator_id: Int? + public let limit: Int? + public let listing_type: ListingType? + public let page: Int? + public let q: String + public let sort: SortType? + public let type_: SearchType? + + public init(auth: String? = nil, community_id: Int? = nil, community_name: String? = nil, creator_id: Int? = nil, limit: Int? = nil, listing_type: ListingType? = nil, page: Int? = nil, q: String, sort: SortType? = nil, type_: SearchType? = nil) { + self.auth = auth + self.community_id = community_id + self.community_name = community_name + self.creator_id = creator_id + self.limit = limit + self.listing_type = listing_type + self.page = page + self.q = q + self.sort = sort + self.type_ = type_ + } +} +public struct SearchResponse: APIResponse { + public let comments: [CommentView] + public let communities: [CommunityView] + public let posts: [PostView] + public let type_: String + public let users: [PersonView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Site/BlockInstanceRequest.swift b/Sources/Swimmy/Lemmy API/Requests/Site/BlockInstanceRequest.swift new file mode 100644 index 0000000..8315ffb --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Site/BlockInstanceRequest.swift @@ -0,0 +1,30 @@ +// +// BlockInstanceRequest.swift +// Arctic +// +// Created by Dana Buehre on 10/3/23. +// + +import Foundation + +public struct BlockInstance: APIRequest { + public typealias Response = BlockInstanceResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/site/block" + public var jwt: String? { return auth } + + public let auth: String + public let instance_id: Int + public let block: Bool + + init(auth: String, instance_id: Int, block: Bool) { + self.auth = auth + self.instance_id = instance_id + self.block = block + } +} + +public struct BlockInstanceResponse: APIResponse { + let blocked: Bool +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Site/CreateSite.swift b/Sources/Swimmy/Lemmy API/Requests/Site/CreateSite.swift new file mode 100644 index 0000000..b499b45 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Site/CreateSite.swift @@ -0,0 +1,107 @@ +// +// CreateSite.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CreateSiteRequest: APIRequest { + public typealias Response = SiteResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/site" + public var jwt: String? { return auth } + + public let actor_name_max_length: Int? + public let allowed_instances: [String]? + public let application_email_admins: Bool? + public let application_question: String? + public let auth: String + public let banner: String? + public let blocked_instances: [String]? + public let captcha_difficulty: String? + public let captcha_enabled: Bool? + public let community_creation_admin_only: Bool? + public let default_post_listing_type: String? + public let default_theme: String? + public let description: String? + public let discussion_languages: [Int]? + public let enable_downvotes: Bool? + public let enable_nsfw: Bool? + public let federation_debug: Bool? + public let federation_enabled: Bool? + public let federation_worker_count: Int? + public let hide_modlog_mod_names: Bool? + public let icon: String? + public let legal_information: String? + public let name: String + public let private_instance: Bool? + public let rate_limit_comment: Int? + public let rate_limit_comment_per_second: Int? + public let rate_limit_image: Int? + public let rate_limit_image_per_second: Int? + public let rate_limit_message: Int? + public let rate_limit_message_per_second: Int? + public let rate_limit_post: Int? + public let rate_limit_post_per_second: Int? + public let rate_limit_register: Int? + public let rate_limit_register_per_second: Int? + public let rate_limit_search: Int? + public let rate_limit_search_per_second: Int? + public let registration_mode: RegistrationMode? + public let reports_email_admins: Bool? + public let require_email_verification: Bool? + public let sidebar: String? + public let slur_filter_regex: String? + public let taglines: [String]? + + public init(actor_name_max_length: Int? = nil, allowed_instances: [String]? = nil, application_email_admins: Bool? = nil, application_question: String? = nil, auth: String, banner: String? = nil, blocked_instances: [String]? = nil, captcha_difficulty: String? = nil, captcha_enabled: Bool? = nil, community_creation_admin_only: Bool? = nil, default_post_listing_type: String? = nil, default_theme: String? = nil, description: String? = nil, discussion_languages: [Int]? = nil, enable_downvotes: Bool? = nil, enable_nsfw: Bool? = nil, federation_debug: Bool? = nil, federation_enabled: Bool? = nil, federation_worker_count: Int? = nil, hide_modlog_mod_names: Bool? = nil, icon: String? = nil, legal_information: String? = nil, name: String, private_instance: Bool? = nil, rate_limit_comment: Int? = nil, rate_limit_comment_per_second: Int? = nil, rate_limit_image: Int? = nil, rate_limit_image_per_second: Int? = nil, rate_limit_message: Int? = nil, rate_limit_message_per_second: Int? = nil, rate_limit_post: Int? = nil, rate_limit_post_per_second: Int? = nil, rate_limit_register: Int? = nil, rate_limit_register_per_second: Int? = nil, rate_limit_search: Int? = nil, rate_limit_search_per_second: Int? = nil, registration_mode: RegistrationMode? = nil, reports_email_admins: Bool? = nil, require_email_verification: Bool? = nil, sidebar: String? = nil, slur_filter_regex: String? = nil, taglines: [String]? = nil) { + self.actor_name_max_length = actor_name_max_length + self.allowed_instances = allowed_instances + self.application_email_admins = application_email_admins + self.application_question = application_question + self.auth = auth + self.banner = banner + self.blocked_instances = blocked_instances + self.captcha_difficulty = captcha_difficulty + self.captcha_enabled = captcha_enabled + self.community_creation_admin_only = community_creation_admin_only + self.default_post_listing_type = default_post_listing_type + self.default_theme = default_theme + self.description = description + self.discussion_languages = discussion_languages + self.enable_downvotes = enable_downvotes + self.enable_nsfw = enable_nsfw + self.federation_debug = federation_debug + self.federation_enabled = federation_enabled + self.federation_worker_count = federation_worker_count + self.hide_modlog_mod_names = hide_modlog_mod_names + self.icon = icon + self.legal_information = legal_information + self.name = name + self.private_instance = private_instance + self.rate_limit_comment = rate_limit_comment + self.rate_limit_comment_per_second = rate_limit_comment_per_second + self.rate_limit_image = rate_limit_image + self.rate_limit_image_per_second = rate_limit_image_per_second + self.rate_limit_message = rate_limit_message + self.rate_limit_message_per_second = rate_limit_message_per_second + self.rate_limit_post = rate_limit_post + self.rate_limit_post_per_second = rate_limit_post_per_second + self.rate_limit_register = rate_limit_register + self.rate_limit_register_per_second = rate_limit_register_per_second + self.rate_limit_search = rate_limit_search + self.rate_limit_search_per_second = rate_limit_search_per_second + self.registration_mode = registration_mode + self.reports_email_admins = reports_email_admins + self.require_email_verification = require_email_verification + self.sidebar = sidebar + self.slur_filter_regex = slur_filter_regex + self.taglines = taglines + } +} +public struct SiteResponse: APIResponse { + public let site_view: SiteView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Site/EditSite.swift b/Sources/Swimmy/Lemmy API/Requests/Site/EditSite.swift new file mode 100644 index 0000000..b9b6cb2 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Site/EditSite.swift @@ -0,0 +1,104 @@ +// +// EditSite.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct EditSiteRequest: APIRequest { + public typealias Response = SiteResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/site" + public var jwt: String? { return auth } + + public let actor_name_max_length: Int? + public let allowed_instances: [String]? + public let application_email_admins: Bool? + public let application_question: String? + public let auth: String + public let banner: String? + public let blocked_instances: [String]? + public let captcha_difficulty: String? + public let captcha_enabled: Bool? + public let community_creation_admin_only: Bool? + public let default_post_listing_type: String? + public let default_theme: String? + public let description: String? + public let discussion_languages: [Int]? + public let enable_downvotes: Bool? + public let enable_nsfw: Bool? + public let federation_debug: Bool? + public let federation_enabled: Bool? + public let federation_worker_count: Int? + public let hide_modlog_mod_names: Bool? + public let icon: String? + public let legal_information: String? + public let name: String? + public let private_instance: Bool? + public let rate_limit_comment: Int? + public let rate_limit_comment_per_second: Int? + public let rate_limit_image: Int? + public let rate_limit_image_per_second: Int? + public let rate_limit_message: Int? + public let rate_limit_message_per_second: Int? + public let rate_limit_post: Int? + public let rate_limit_post_per_second: Int? + public let rate_limit_register: Int? + public let rate_limit_register_per_second: Int? + public let rate_limit_search: Int? + public let rate_limit_search_per_second: Int? + public let registration_mode: RegistrationMode? + public let reports_email_admins: Bool? + public let require_email_verification: Bool? + public let sidebar: String? + public let slur_filter_regex: String? + public let taglines: [String]? + + public init(actor_name_max_length: Int? = nil, allowed_instances: [String]? = nil, application_email_admins: Bool? = nil, application_question: String? = nil, auth: String, banner: String? = nil, blocked_instances: [String]? = nil, captcha_difficulty: String? = nil, captcha_enabled: Bool? = nil, community_creation_admin_only: Bool? = nil, default_post_listing_type: String? = nil, default_theme: String? = nil, description: String? = nil, discussion_languages: [Int]? = nil, enable_downvotes: Bool? = nil, enable_nsfw: Bool? = nil, federation_debug: Bool? = nil, federation_enabled: Bool? = nil, federation_worker_count: Int? = nil, hide_modlog_mod_names: Bool? = nil, icon: String? = nil, legal_information: String? = nil, name: String? = nil, private_instance: Bool? = nil, rate_limit_comment: Int? = nil, rate_limit_comment_per_second: Int? = nil, rate_limit_image: Int? = nil, rate_limit_image_per_second: Int? = nil, rate_limit_message: Int? = nil, rate_limit_message_per_second: Int? = nil, rate_limit_post: Int? = nil, rate_limit_post_per_second: Int? = nil, rate_limit_register: Int? = nil, rate_limit_register_per_second: Int? = nil, rate_limit_search: Int? = nil, rate_limit_search_per_second: Int? = nil, registration_mode: RegistrationMode? = nil, reports_email_admins: Bool? = nil, require_email_verification: Bool? = nil, sidebar: String? = nil, slur_filter_regex: String? = nil, taglines: [String]? = nil) { + self.actor_name_max_length = actor_name_max_length + self.allowed_instances = allowed_instances + self.application_email_admins = application_email_admins + self.application_question = application_question + self.auth = auth + self.banner = banner + self.blocked_instances = blocked_instances + self.captcha_difficulty = captcha_difficulty + self.captcha_enabled = captcha_enabled + self.community_creation_admin_only = community_creation_admin_only + self.default_post_listing_type = default_post_listing_type + self.default_theme = default_theme + self.description = description + self.discussion_languages = discussion_languages + self.enable_downvotes = enable_downvotes + self.enable_nsfw = enable_nsfw + self.federation_debug = federation_debug + self.federation_enabled = federation_enabled + self.federation_worker_count = federation_worker_count + self.hide_modlog_mod_names = hide_modlog_mod_names + self.icon = icon + self.legal_information = legal_information + self.name = name + self.private_instance = private_instance + self.rate_limit_comment = rate_limit_comment + self.rate_limit_comment_per_second = rate_limit_comment_per_second + self.rate_limit_image = rate_limit_image + self.rate_limit_image_per_second = rate_limit_image_per_second + self.rate_limit_message = rate_limit_message + self.rate_limit_message_per_second = rate_limit_message_per_second + self.rate_limit_post = rate_limit_post + self.rate_limit_post_per_second = rate_limit_post_per_second + self.rate_limit_register = rate_limit_register + self.rate_limit_register_per_second = rate_limit_register_per_second + self.rate_limit_search = rate_limit_search + self.rate_limit_search_per_second = rate_limit_search_per_second + self.registration_mode = registration_mode + self.reports_email_admins = reports_email_admins + self.require_email_verification = require_email_verification + self.sidebar = sidebar + self.slur_filter_regex = slur_filter_regex + self.taglines = taglines + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/Site/GetSite.swift b/Sources/Swimmy/Lemmy API/Requests/Site/GetSite.swift new file mode 100644 index 0000000..481f346 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/Site/GetSite.swift @@ -0,0 +1,33 @@ +// +// GetSite.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetSiteRequest: APIRequest { + public typealias Response = GetSiteResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/site" + public var jwt: String? { return auth } + + public let auth: String? + + public init(auth: String? = nil) { + self.auth = auth + } +} +public struct GetSiteResponse: APIResponse { + public let admins: [PersonView] + public let all_languages: [Language] + public let discussion_languages: [Int] + public let federated_instances: FederatedInstances? + public let my_user: MyUserInfo? + public let online: Int? // removed v0.18 + public let site_view: SiteView + public let taglines: [Tagline]? + public let version: String +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/BanPerson.swift b/Sources/Swimmy/Lemmy API/Requests/User/BanPerson.swift new file mode 100644 index 0000000..ab881f9 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/BanPerson.swift @@ -0,0 +1,29 @@ +// +// BanPerson.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct BanPersonRequest: APIRequest { + public typealias Response = BanPersonResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/ban" + public var jwt: String? { return auth } + + public let auth: String + public let ban: Bool + /// The expire time in Unix seconds. + public let expires: Int? + public let person_id: Int + public let reason: String? + /// Removes/Restores their comments, posts, and communities. + public let remove_data: Bool? +} +public struct BanPersonResponse: APIResponse { + public let banned: Bool + public let person_view: PersonView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/BlockPerson.swift b/Sources/Swimmy/Lemmy API/Requests/User/BlockPerson.swift new file mode 100644 index 0000000..dae332d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/BlockPerson.swift @@ -0,0 +1,30 @@ +// +// BlockPerson.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct BlockPersonRequest: APIRequest { + public typealias Response = BlockPersonResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/block" + public var jwt: String? { return auth } + + public let auth: String + public let block: Bool + public let person_id: Int + + public init(auth: String, block: Bool, person_id: Int) { + self.auth = auth + self.block = block + self.person_id = person_id + } +} +public struct BlockPersonResponse: APIResponse { + public let blocked: Bool + public let person_view: PersonView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/ChangePassword.swift b/Sources/Swimmy/Lemmy API/Requests/User/ChangePassword.swift new file mode 100644 index 0000000..19e89ee --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/ChangePassword.swift @@ -0,0 +1,28 @@ +// +// ChangePassword.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ChangePasswordRequest: APIRequest { + public typealias Response = LoginResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/user/change_password" + public var jwt: String? { return auth } + + public let auth: String + public let new_password: String + public let new_password_verify: String + public let old_password: String + + public init(auth: String, new_password: String, new_password_verify: String, old_password: String) { + self.auth = auth + self.new_password = new_password + self.new_password_verify = new_password_verify + self.old_password = old_password + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/DeleteAccount.swift b/Sources/Swimmy/Lemmy API/Requests/User/DeleteAccount.swift new file mode 100644 index 0000000..3e62e14 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/DeleteAccount.swift @@ -0,0 +1,26 @@ +// +// DeleteAccount.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct DeleteAccountRequest: APIRequest { + public typealias Response = DeleteAccountResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/delete_account" + public var jwt: String? { return auth } + + public let auth: String + public let password: String + + public init(auth: String, password: String) { + self.auth = auth + self.password = password + } +} +public struct DeleteAccountResponse: APIResponse { +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetBannedPersons.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetBannedPersons.swift new file mode 100644 index 0000000..ce0311c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetBannedPersons.swift @@ -0,0 +1,25 @@ +// +// GetBannedPersons.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetBannedPersonsRequest: APIRequest { + public typealias Response = BannedPersonsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/banned" + public var jwt: String? { return auth } + + public let auth: String + + public init(auth: String) { + self.auth = auth + } +} +public struct BannedPersonsResponse: APIResponse { + public let banned: [PersonView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetCaptcha.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetCaptcha.swift new file mode 100644 index 0000000..1af9d0d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetCaptcha.swift @@ -0,0 +1,22 @@ +// +// GetCaptcha.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetCaptchaRequest: APIRequest { + public typealias Response = GetCaptchaResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/get_captcha" + public var jwt: String? { return nil } + + public init() {} +} +public struct GetCaptchaResponse: APIResponse { + /// Will be nil if captchas are disabled. + public let ok: CaptchaResponse? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetPersonDetails.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetPersonDetails.swift new file mode 100644 index 0000000..5957823 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetPersonDetails.swift @@ -0,0 +1,43 @@ +// +// GetPersonDetails.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetPersonDetailsRequest: APIRequest { + public typealias Response = GetPersonDetailsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user" + public var jwt: String? { return auth } + + public let auth: String? + public let community_id: Int? + public let limit: Int? + public let page: Int? + public let person_id: Int? + public let saved_only: Bool? + public let sort: SortType? + /// To get details for a federated user, use `person@instance.tld`. + public let username: String? + + public init(auth: String? = nil, community_id: Int? = nil, limit: Int? = nil, page: Int? = nil, person_id: Int? = nil, saved_only: Bool? = nil, sort: SortType? = nil, username: String? = nil) { + self.auth = auth + self.community_id = community_id + self.limit = limit + self.page = page + self.person_id = person_id + self.saved_only = saved_only + self.sort = sort + self.username = username + } +} +public struct GetPersonDetailsResponse: APIResponse { + public var comments: [CommentView] + public var moderates: [CommunityModeratorView] + public var person_view: PersonView + public var posts: [PostView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetPersonMentions.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetPersonMentions.swift new file mode 100644 index 0000000..25dcbcb --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetPersonMentions.swift @@ -0,0 +1,34 @@ +// +// GetPersonMentions.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetPersonMentionsRequest: APIRequest { + public typealias Response = GetPersonMentionsResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/mention" + public var jwt: String? { return auth } + + public let auth: String + public let limit: Int? + public let page: Int? + public let sort: CommentSortType? + public let unread_only: Bool? + + public init(auth: String, limit: Int? = nil, page: Int? = nil, sort: CommentSortType? = nil, unread_only: Bool? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.sort = sort + self.unread_only = unread_only + } +} +public struct GetPersonMentionsResponse: APIResponse { + public let mentions: [PersonMentionView] +} + diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetReplies.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetReplies.swift new file mode 100644 index 0000000..2a9c8d5 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetReplies.swift @@ -0,0 +1,33 @@ +// +// GetReplies.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetRepliesRequest: APIRequest { + public typealias Response = GetRepliesResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/replies" + public var jwt: String? { return auth } + + public let auth: String + public let limit: Int? + public let page: Int? + public let sort: CommentSortType? + public let unread_only: Bool? + + public init(auth: String, limit: Int? = nil, page: Int? = nil, sort: CommentSortType? = nil, unread_only: Bool? = nil) { + self.auth = auth + self.limit = limit + self.page = page + self.sort = sort + self.unread_only = unread_only + } +} +public struct GetRepliesResponse: APIResponse { + public let replies: [CommentReplyView] +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetReportCount.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetReportCount.swift new file mode 100644 index 0000000..473c850 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetReportCount.swift @@ -0,0 +1,31 @@ +// +// GetReportCount.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetReportCountRequest: APIRequest { + public typealias Response = GetReportCountResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/report_count" + public var jwt: String? { return auth } + + public let auth: String + /// If a community is supplied, returns the report count for only that community, otherwise returns the report count for all communities the user moderates. + public let community_id: Int? + + public init(auth: String, community_id: Int? = nil) { + self.auth = auth + self.community_id = community_id + } +} +public struct GetReportCountResponse: APIResponse { + public let comment_reports: Int + public let community_id: Int? + public let post_reports: Int + public let private_message_reports: Int? +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/GetUnreadCount.swift b/Sources/Swimmy/Lemmy API/Requests/User/GetUnreadCount.swift new file mode 100644 index 0000000..1af9e12 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/GetUnreadCount.swift @@ -0,0 +1,27 @@ +// +// GetUnreadCount.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct GetUnreadCountRequest: APIRequest { + public typealias Response = GetUnreadCountResponse + + public static let httpMethod: HTTPMethod = .get + public static let path: String = "/user/unread_count" + public var jwt: String? { return auth } + + public let auth: String + + public init(auth: String) { + self.auth = auth + } +} +public struct GetUnreadCountResponse: APIResponse, Equatable { + public let mentions: Int + public let private_messages: Int + public let replies: Int +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/LeaveAdmin.swift b/Sources/Swimmy/Lemmy API/Requests/User/LeaveAdmin.swift new file mode 100644 index 0000000..3510651 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/LeaveAdmin.swift @@ -0,0 +1,22 @@ +// +// LeaveAdmin.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LeaveAdminRequest: APIRequest { + public typealias Response = GetSiteResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/leave_admin" + public var jwt: String? { return auth } + + public let auth: String + + public init(auth: String) { + self.auth = auth + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/Login.swift b/Sources/Swimmy/Lemmy API/Requests/User/Login.swift new file mode 100644 index 0000000..143b7a6 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/Login.swift @@ -0,0 +1,38 @@ +// +// Login.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct LoginRequest: APIRequest { + public typealias Response = LoginResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/login" + public var jwt: String? { return nil } + + public let username_or_email: String + public let password: String + public let totp_2fa_token: String? + + public init(username_or_email: String, password: String, totp_2fa_token: String?) { + self.username_or_email = username_or_email + self.password = password + self.totp_2fa_token = totp_2fa_token + } +} +public struct LoginResponse: APIResponse { + /// The JSON Web Token for the user. + /// + /// This token can be passed into `auth` parameters of other requests to make authorized requests. + /// + /// If you are registering a new account, this property will be `nil` if email verification is enabled, or if the server requires registration applications. + /// + /// It will also be `nil` if the login is wrong. + public let jwt: String? + public let registration_created: Bool + public let verify_email_sent: Bool +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/MarkAllAsRead.swift b/Sources/Swimmy/Lemmy API/Requests/User/MarkAllAsRead.swift new file mode 100644 index 0000000..6b6ccfa --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/MarkAllAsRead.swift @@ -0,0 +1,22 @@ +// +// MarkAllAsRead.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MarkAllAsReadRequest: APIRequest { + public typealias Response = GetRepliesResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/mark_all_as_read" + public var jwt: String? { return auth } + + public let auth: String + + public init(auth: String) { + self.auth = auth + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/MarkPersonMentionAsRead.swift b/Sources/Swimmy/Lemmy API/Requests/User/MarkPersonMentionAsRead.swift new file mode 100644 index 0000000..36929ba --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/MarkPersonMentionAsRead.swift @@ -0,0 +1,29 @@ +// +// MarkPersonMentionAsRead.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MarkPersonMentionAsReadRequest: APIRequest { + public typealias Response = PersonMentionResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/mention/mark_as_read" + public var jwt: String? { return auth } + + public let auth: String + public let person_mention_id: Int + public let read: Bool + + public init(auth: String, person_mention_id: Int, read: Bool) { + self.auth = auth + self.person_mention_id = person_mention_id + self.read = read + } +} +public struct PersonMentionResponse: APIResponse { + public let person_mention_view: PersonMentionView +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/PasswordChange.swift b/Sources/Swimmy/Lemmy API/Requests/User/PasswordChange.swift new file mode 100644 index 0000000..c22ad22 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/PasswordChange.swift @@ -0,0 +1,26 @@ +// +// PasswordChange.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PasswordChangeRequest: APIRequest { + public typealias Response = LoginResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/password_change" + public var jwt: String? { return nil } + + public let password: String + public let password_verify: String + public let token: String + + public init(password: String, password_verify: String, token: String) { + self.password = password + self.password_verify = password_verify + self.token = token + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/PasswordReset.swift b/Sources/Swimmy/Lemmy API/Requests/User/PasswordReset.swift new file mode 100644 index 0000000..98f8f46 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/PasswordReset.swift @@ -0,0 +1,24 @@ +// +// PasswordReset.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PasswordResetRequest: APIRequest { + public typealias Response = PasswordResetResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/password_reset" + public var jwt: String? { return nil } + + public let email: String + + public init(email: String) { + self.email = email + } +} +public struct PasswordResetResponse: APIResponse { +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/Register.swift b/Sources/Swimmy/Lemmy API/Requests/User/Register.swift new file mode 100644 index 0000000..f6e4f49 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/Register.swift @@ -0,0 +1,38 @@ +// +// Register.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RegisterRequest: APIRequest { + public typealias Response = LoginResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/register" + public var jwt: String? { return nil } + + public let answer: String? + public let captcha_answer: String? + public let captcha_uuid: String? + public let email: String? + public let honeypot: String? + public let password: String + public let password_verify: String + public let show_nsfw: Bool + public let username: String + + public init(answer: String? = nil, captcha_answer: String? = nil, captcha_uuid: String? = nil, email: String? = nil, honeypot: String? = nil, password: String, password_verify: String, show_nsfw: Bool, username: String) { + self.answer = answer + self.captcha_answer = captcha_answer + self.captcha_uuid = captcha_uuid + self.email = email + self.honeypot = honeypot + self.password = password + self.password_verify = password_verify + self.show_nsfw = show_nsfw + self.username = username + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/SaveUserSettings.swift b/Sources/Swimmy/Lemmy API/Requests/User/SaveUserSettings.swift new file mode 100644 index 0000000..cebe905 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/SaveUserSettings.swift @@ -0,0 +1,60 @@ +// +// SaveUserSettings.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SaveUserSettingsRequest: APIRequest { + public typealias Response = LoginResponse + + public static let httpMethod: HTTPMethod = .put + public static let path: String = "/user/save_user_settings" + public var jwt: String? { return auth } + + public let auth: String + public let avatar: String? + public let banner: String? + public let bio: String? + public let bot_account: Bool? + public let default_listing_type: ListingType? + public let default_sort_type: SortType? + public let discussion_languages: [Int]? + public let display_name: String? + public let email: String? + public let interface_language: String? + public let matrix_user_id: String? + public let send_notifications_to_email: Bool? + public let show_avatars: Bool? + public let show_bot_accounts: Bool? + public let show_new_post_notifs: Bool? + public let show_nsfw: Bool? + public let show_read_posts: Bool? + public let show_scores: Bool? + public let theme: String? + + public init(auth: String, avatar: String? = nil, banner: String? = nil, bio: String? = nil, bot_account: Bool? = nil, default_listing_type: ListingType? = nil, default_sort_type: SortType? = nil, discussion_languages: [Int]? = nil, display_name: String? = nil, email: String? = nil, interface_language: String? = nil, matrix_user_id: String? = nil, send_notifications_to_email: Bool? = nil, show_avatars: Bool? = nil, show_bot_accounts: Bool? = nil, show_new_post_notifs: Bool? = nil, show_nsfw: Bool? = nil, show_read_posts: Bool? = nil, show_scores: Bool? = nil, theme: String? = nil) { + self.auth = auth + self.avatar = avatar + self.banner = banner + self.bio = bio + self.bot_account = bot_account + self.default_listing_type = default_listing_type + self.default_sort_type = default_sort_type + self.discussion_languages = discussion_languages + self.display_name = display_name + self.email = email + self.interface_language = interface_language + self.matrix_user_id = matrix_user_id + self.send_notifications_to_email = send_notifications_to_email + self.show_avatars = show_avatars + self.show_bot_accounts = show_bot_accounts + self.show_new_post_notifs = show_new_post_notifs + self.show_nsfw = show_nsfw + self.show_read_posts = show_read_posts + self.show_scores = show_scores + self.theme = theme + } +} diff --git a/Sources/Swimmy/Lemmy API/Requests/User/VerifyEmail.swift b/Sources/Swimmy/Lemmy API/Requests/User/VerifyEmail.swift new file mode 100644 index 0000000..456521b --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Requests/User/VerifyEmail.swift @@ -0,0 +1,24 @@ +// +// VerifyEmail.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct VerifyEmailRequest: APIRequest { + public typealias Response = VerifyEmailResponse + + public static let httpMethod: HTTPMethod = .post + public static let path: String = "/user/verify_email" + public var jwt: String? { return nil } + + public let token: String + + public init(token: String) { + self.token = token + } +} +public struct VerifyEmailResponse: APIResponse { +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgeComment.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeComment.swift new file mode 100644 index 0000000..442a1bb --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeComment.swift @@ -0,0 +1,24 @@ +// +// AdminPurgeComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgeComment: Codable, Identifiable, Hashable { + internal init(admin_person_id: Int, id: Int, post_id: Int, reason: String? = nil, when_: String) { + self.admin_person_id = admin_person_id + self.id = id + self.post_id = post_id + self.reason = reason + self.when_ = when_ + } + + public let admin_person_id: Int + public let id: Int + public let post_id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommentView.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommentView.swift new file mode 100644 index 0000000..7441f0b --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommentView.swift @@ -0,0 +1,14 @@ +// +// AdminPurgeCommentView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgeCommentView: Codable, Hashable { + public let admin: Person? + public let admin_purge_comment: AdminPurgeComment + public let post: Post +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunity.swift new file mode 100644 index 0000000..0908be2 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunity.swift @@ -0,0 +1,15 @@ +// +// AdminPurgeCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgeCommunity: Codable, Identifiable, Hashable { + public let admin_person_id: Int + public let id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunityView.swift new file mode 100644 index 0000000..2f62964 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgeCommunityView.swift @@ -0,0 +1,13 @@ +// +// AdminPurgeCommunityView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgeCommunityView: Codable, Hashable { + public let admin: Person? + public let admin_purge_community: AdminPurgeCommunity +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgePerson.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePerson.swift new file mode 100644 index 0000000..ce88288 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePerson.swift @@ -0,0 +1,15 @@ +// +// AdminPurgePerson.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgePerson: Codable, Identifiable, Hashable { + public let admin_person_id: Int + public let id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgePersonView.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePersonView.swift new file mode 100644 index 0000000..dbc6c0c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePersonView.swift @@ -0,0 +1,13 @@ +// +// AdminPurgePersonView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgePersonView: Codable, Hashable { + public let admin: Person? + public let admin_purge_person: AdminPurgePerson +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgePost.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePost.swift new file mode 100644 index 0000000..b859265 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePost.swift @@ -0,0 +1,16 @@ +// +// AdminPurgePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgePost: Codable, Identifiable, Hashable { + public let admin_person_id: Int + public let community_id: Int + public let id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/AdminPurgePostView.swift b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePostView.swift new file mode 100644 index 0000000..86d98c9 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/AdminPurgePostView.swift @@ -0,0 +1,14 @@ +// +// AdminPurgePostView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct AdminPurgePostView: Codable, Hashable { + public let admin: Person? + public let admin_purge_post: AdminPurgePost + public let community: Community +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CaptchaResponse.swift b/Sources/Swimmy/Lemmy API/Structs/CaptchaResponse.swift new file mode 100644 index 0000000..143dcac --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CaptchaResponse.swift @@ -0,0 +1,17 @@ +// +// CaptchaResponse.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CaptchaResponse: Codable, Hashable { + /// A Base64 encoded png. + public let png: String + /// A UUID to match the one given on request. + public let uuid: String + /// A Base64 encoded wav file. + public let wav: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Comment.swift b/Sources/Swimmy/Lemmy API/Structs/Comment.swift new file mode 100644 index 0000000..ad00768 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Comment.swift @@ -0,0 +1,24 @@ +// +// Comment.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct Comment: Codable, Identifiable, Hashable { + public let ap_id: String + public let content: String + public let creator_id: Int + public let deleted: Bool + public let distinguished: Bool + public let id: Int + public let language_id: Int + public let local: Bool + public let path: String + public let post_id: Int + public let published: String + public let removed: Bool + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentAggregates.swift b/Sources/Swimmy/Lemmy API/Structs/CommentAggregates.swift new file mode 100644 index 0000000..4d03b3a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentAggregates.swift @@ -0,0 +1,17 @@ +// +// CommentAggregates.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct CommentAggregates: Codable, Identifiable, Hashable { + public let child_count: Int + public let comment_id: Int + public let downvotes: Int + public let id: Int + public let score: Int + public let upvotes: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentReply.swift b/Sources/Swimmy/Lemmy API/Structs/CommentReply.swift new file mode 100644 index 0000000..0827f46 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentReply.swift @@ -0,0 +1,16 @@ +// +// CommentReply.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommentReply: Codable, Identifiable, Hashable { + public let comment_id: Int + public let id: Int + public let published: String + public var read: Bool + public let recipient_id: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentReplyView.swift b/Sources/Swimmy/Lemmy API/Structs/CommentReplyView.swift new file mode 100644 index 0000000..8cc13f1 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentReplyView.swift @@ -0,0 +1,23 @@ +// +// CommentReplyView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommentReplyView: Codable, Hashable { + public let comment: Comment + public var comment_reply: CommentReply + public let community: Community + public let counts: CommentAggregates + public let creator: Person + public let creator_banned_from_community: Bool + public let creator_blocked: Bool + public var my_vote: Int? + public let post: Post + public let recipient: Person + public let saved: Bool + public let subscribed: SubscribedType +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentReport.swift b/Sources/Swimmy/Lemmy API/Structs/CommentReport.swift new file mode 100644 index 0000000..476dec3 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentReport.swift @@ -0,0 +1,20 @@ +// +// CommentReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommentReport: Codable, Identifiable, Hashable { + public let comment_id: Int + public let creator_id: Int + public let id: Int + public let original_comment_text: String + public let published: String + public let reason: String + public let resolved: Bool + public let resolver_id: Int? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentReportView.swift b/Sources/Swimmy/Lemmy API/Structs/CommentReportView.swift new file mode 100644 index 0000000..6e5a10f --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentReportView.swift @@ -0,0 +1,21 @@ +// +// CommentReportView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommentReportView: Codable, Hashable { + public var comment: Comment + public var comment_creator: Person + public let comment_report: CommentReport + public let community: Community + public let counts: CommentAggregates + public let creator: Person + public var creator_banned_from_community: Bool + public let my_vote: Int? + public let post: Post + public let resolver: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommentView.swift b/Sources/Swimmy/Lemmy API/Structs/CommentView.swift new file mode 100644 index 0000000..e27aaad --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommentView.swift @@ -0,0 +1,21 @@ +// +// CommentView.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct CommentView: Codable, Hashable { + public let comment: Comment + public let community: Community + public let counts: CommentAggregates + public var creator: Person + public var creator_banned_from_community: Bool + public let creator_blocked: Bool + public let my_vote: Int? + public let post: Post + public let saved: Bool + public let subscribed: SubscribedType +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Community.swift b/Sources/Swimmy/Lemmy API/Structs/Community.swift new file mode 100644 index 0000000..f61a262 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Community.swift @@ -0,0 +1,28 @@ +// +// Community.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct Community: Codable, Identifiable, Hashable { + + public let actor_id: String + public let banner: String? + public let deleted: Bool + public let description: String? + public let hidden: Bool + public let icon: URL? + public let id: Int + public let instance_id: Int + public let local: Bool + public let name: String + public let nsfw: Bool + public let posting_restricted_to_mods: Bool + public let published: String + public let removed: Bool + public let title: String + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommunityAggregates.swift b/Sources/Swimmy/Lemmy API/Structs/CommunityAggregates.swift new file mode 100644 index 0000000..571f934 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommunityAggregates.swift @@ -0,0 +1,20 @@ +// +// CommunityAggregates.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct CommunityAggregates: Codable, Identifiable, Hashable { + public let comments: Int + public let community_id: Int + public let id: Int + public let posts: Int + public let subscribers: Int + public let users_active_day: Int + public let users_active_half_year: Int + public let users_active_month: Int + public let users_active_week: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommunityBlockView.swift b/Sources/Swimmy/Lemmy API/Structs/CommunityBlockView.swift new file mode 100644 index 0000000..d0a8dcd --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommunityBlockView.swift @@ -0,0 +1,13 @@ +// +// CommunityBlockView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommunityBlockView: Codable, Hashable { + public let community: Community + public let person: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommunityFollowerView.swift b/Sources/Swimmy/Lemmy API/Structs/CommunityFollowerView.swift new file mode 100644 index 0000000..bb45c25 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommunityFollowerView.swift @@ -0,0 +1,13 @@ +// +// CommunityFollowerView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommunityFollowerView: Codable, Hashable { + public let community: Community + public let follower: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommunityModeratorView.swift b/Sources/Swimmy/Lemmy API/Structs/CommunityModeratorView.swift new file mode 100644 index 0000000..67b2793 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommunityModeratorView.swift @@ -0,0 +1,13 @@ +// +// CommunityModeratorView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct CommunityModeratorView: Codable, Hashable { + public let community: Community + public let moderator: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/CommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/CommunityView.swift new file mode 100644 index 0000000..d5415c4 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/CommunityView.swift @@ -0,0 +1,15 @@ +// +// CommunityView.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct CommunityView: Codable, Hashable { + public let blocked: Bool + public let community: Community + public let counts: CommunityAggregates + public let subscribed: SubscribedType +} diff --git a/Sources/Swimmy/Lemmy API/Structs/FederatedInstances.swift b/Sources/Swimmy/Lemmy API/Structs/FederatedInstances.swift new file mode 100644 index 0000000..c5f9932 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/FederatedInstances.swift @@ -0,0 +1,14 @@ +// +// FederatedInstances.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct FederatedInstances: Codable, Hashable { + public let allowed: [Instance]? + public let blocked: [Instance]? + public let linked: [Instance] +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ImageFile.swift b/Sources/Swimmy/Lemmy API/Structs/ImageFile.swift new file mode 100644 index 0000000..e3c55cd --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ImageFile.swift @@ -0,0 +1,13 @@ +// +// ImageFile.swift +// lemming +// +// Created by Dana Buehre on 7/3/23. +// + +import Foundation + +public struct ImageFile: Codable, Hashable { + public let delete_token: String + public let file: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Instance.swift b/Sources/Swimmy/Lemmy API/Structs/Instance.swift new file mode 100644 index 0000000..dca3564 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Instance.swift @@ -0,0 +1,17 @@ +// +// Instance.swift +// Arctic +// +// Created by Dana Buehre on 9/4/23. +// + +import Foundation + +public struct Instance: Codable, Identifiable, Hashable { + public let id: Int + public let domain: String + public let published: String + public let updated: String? + public let software: String? + public let version: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/InstanceBlockView.swift b/Sources/Swimmy/Lemmy API/Structs/InstanceBlockView.swift new file mode 100644 index 0000000..e19312c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/InstanceBlockView.swift @@ -0,0 +1,14 @@ +// +// InstanceBlockView.swift +// Arctic +// +// Created by Dana Buehre on 10/3/23. +// + +import Foundation + +public struct InstanceBlockView: Codable, Hashable { + public let person: Person + public let instance: Instance + public let site: Site? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Language.swift b/Sources/Swimmy/Lemmy API/Structs/Language.swift new file mode 100644 index 0000000..4c12fb4 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Language.swift @@ -0,0 +1,14 @@ +// +// Language.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct Language: Codable, Identifiable, Hashable { + public let code: String + public let id: Int + public let name: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/LocalSite.swift b/Sources/Swimmy/Lemmy API/Structs/LocalSite.swift new file mode 100644 index 0000000..102c544 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/LocalSite.swift @@ -0,0 +1,36 @@ +// +// LocalSite.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LocalSite: Codable, Identifiable, Hashable { + public let actor_name_max_length: Int + public let application_email_admins: Bool + public let application_question: String? + public let captcha_difficulty: String + public let captcha_enabled: Bool + public let community_creation_admin_only: Bool + public let default_post_listing_type: String + public let default_theme: String + public let enable_downvotes: Bool + public let enable_nsfw: Bool + public let federation_debug: Bool? // removed in v0.18 + public let federation_enabled: Bool + public let federation_worker_count: Int? + public let hide_modlog_mod_names: Bool + public let id: Int + public let legal_information: String? + public let private_instance: Bool + public let published: String + public let registration_mode: RegistrationMode + public let reports_email_admins: Bool + public let require_email_verification: Bool + public let site_id: Int + public let site_setup: Bool + public let slur_filter_regex: String? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/LocalSiteRateLimit.swift b/Sources/Swimmy/Lemmy API/Structs/LocalSiteRateLimit.swift new file mode 100644 index 0000000..f6b2c06 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/LocalSiteRateLimit.swift @@ -0,0 +1,27 @@ +// +// LocalSiteRateLimit.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LocalSiteRateLimit: Codable, Identifiable, Hashable { + public let comment: Int + public let comment_per_second: Int + public let id: Int + public let image: Int + public let image_per_second: Int + public let local_site_id: Int + public let message: Int + public let message_per_second: Int + public let post: Int + public let post_per_second: Int + public let published: String + public let register: Int + public let register_per_second: Int + public let search: Int + public let search_per_second: Int + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/LocalUserSettings.swift b/Sources/Swimmy/Lemmy API/Structs/LocalUserSettings.swift new file mode 100644 index 0000000..d77b082 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/LocalUserSettings.swift @@ -0,0 +1,28 @@ +// +// LocalUserSettings.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LocalUserSettings: Codable, Identifiable, Hashable { + public let accepted_application: Bool + public let default_listing_type: ListingType // changed from int in v0.18 + public let default_sort_type: SortType // changed from int in v0.18 + public let email: String? + public let email_verified: Bool + public let id: Int + public let interface_language: String + public let person_id: Int + public let send_notifications_to_email: Bool + public let show_avatars: Bool + public let show_bot_accounts: Bool + public let show_new_post_notifs: Bool + public let show_nsfw: Bool + public let show_read_posts: Bool + public let show_scores: Bool + public let theme: String + public let validator_time: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/LocalUserSettingsView.swift b/Sources/Swimmy/Lemmy API/Structs/LocalUserSettingsView.swift new file mode 100644 index 0000000..c32d81e --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/LocalUserSettingsView.swift @@ -0,0 +1,14 @@ +// +// LocalUserSettingsView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct LocalUserSettingsView: Codable, Hashable { + public let counts: PersonAggregates + public let local_user: LocalUserSettings + public let person: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModAdd.swift b/Sources/Swimmy/Lemmy API/Structs/ModAdd.swift new file mode 100644 index 0000000..aea5d96 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModAdd.swift @@ -0,0 +1,16 @@ +// +// ModAdd.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModAdd: Codable, Identifiable, Hashable { + public let id: Int + public let mod_person_id: Int + public let other_person_id: Int + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModAddCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/ModAddCommunity.swift new file mode 100644 index 0000000..5886826 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModAddCommunity.swift @@ -0,0 +1,17 @@ +// +// ModAddCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModAddCommunity: Codable, Identifiable, Hashable { + public let community_id: Int + public let id: Int + public let mod_person_id: Int + public let other_person_id: Int + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModAddCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/ModAddCommunityView.swift new file mode 100644 index 0000000..b200cfc --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModAddCommunityView.swift @@ -0,0 +1,15 @@ +// +// ModAddCommunityView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModAddCommunityView: Codable, Hashable { + public let community: Community + public let mod_add_community: ModAddCommunity + public let modded_person: Person + public let moderator: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModAddView.swift b/Sources/Swimmy/Lemmy API/Structs/ModAddView.swift new file mode 100644 index 0000000..62faa61 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModAddView.swift @@ -0,0 +1,14 @@ +// +// ModAddView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModAddView: Codable, Hashable { + public let mod_add: ModAdd + public let modded_person: Person + public let moderator: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModBan.swift b/Sources/Swimmy/Lemmy API/Structs/ModBan.swift new file mode 100644 index 0000000..1a0c331 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModBan.swift @@ -0,0 +1,18 @@ +// +// ModBan.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModBan: Codable, Identifiable, Hashable { + public let banned: Bool + public let expires: String? + public let id: Int + public let mod_person_id: Int + public let other_person_id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunity.swift new file mode 100644 index 0000000..8e2162c --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunity.swift @@ -0,0 +1,19 @@ +// +// ModBanFromCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModBanFromCommunity: Codable, Identifiable, Hashable { + public let banned: Bool? + public let community_id: Int + public let expires: String? + public let id: Int + public let mod_person_id: Int + public let other_person_id: Int + public let reason: String? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunityView.swift new file mode 100644 index 0000000..41a3127 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModBanFromCommunityView.swift @@ -0,0 +1,15 @@ +// +// ModBanFromCommunityView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModBanFromCommunityView: Codable, Hashable { + public let banned_person: Person + public let community: Community + public let mod_ban_from_community: ModBanFromCommunity + public let moderator: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModBanView.swift b/Sources/Swimmy/Lemmy API/Structs/ModBanView.swift new file mode 100644 index 0000000..f5537d3 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModBanView.swift @@ -0,0 +1,14 @@ +// +// ModBanView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModBanView: Codable, Hashable { + public let banned_person: Person + public let mod_ban: ModBan + public let moderator: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModFeaturePost.swift b/Sources/Swimmy/Lemmy API/Structs/ModFeaturePost.swift new file mode 100644 index 0000000..43b8f3f --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModFeaturePost.swift @@ -0,0 +1,17 @@ +// +// ModFeaturePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModFeaturePost: Codable, Identifiable, Hashable { + public let featured: Bool + public let id: Int + public let is_featured_community: Bool + public let mod_person_id: Int + public let post_id: Int + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModFeaturePostView.swift b/Sources/Swimmy/Lemmy API/Structs/ModFeaturePostView.swift new file mode 100644 index 0000000..771906d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModFeaturePostView.swift @@ -0,0 +1,15 @@ +// +// ModFeaturePostView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModFeaturePostView: Codable, Hashable { + public let community: Community + public let mod_feature_post: ModFeaturePost + public let moderator: Person? + public let post: Post +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModHideCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/ModHideCommunity.swift new file mode 100644 index 0000000..cda909d --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModHideCommunity.swift @@ -0,0 +1,26 @@ +import Foundation + +public struct ModHideCommunity: Codable, Identifiable, Hashable { + public let id: Int + public let community_id: Int + public let mod_person_id: Int + public let when_: String + public let reason: String? + public let hidden: Bool + + public init( + id: Int, + community_id: Int, + mod_person_id: Int, + when_: String, + reason: String? = nil, + hidden: Bool + ) { + self.id = id + self.community_id = community_id + self.mod_person_id = mod_person_id + self.when_ = when_ + self.reason = reason + self.hidden = hidden + } +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModHideCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/ModHideCommunityView.swift new file mode 100644 index 0000000..0d1afe6 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModHideCommunityView.swift @@ -0,0 +1,17 @@ +import Foundation + +public struct ModHideCommunityView: Codable, Hashable { + public let mod_hide_community: ModHideCommunity + public let admin: Person? + public let community: Community + + public init( + mod_hide_community: ModHideCommunity, + admin: Person? = nil, + community: Community + ) { + self.mod_hide_community = mod_hide_community + self.admin = admin + self.community = community + } +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModLockPost.swift b/Sources/Swimmy/Lemmy API/Structs/ModLockPost.swift new file mode 100644 index 0000000..f9ece5a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModLockPost.swift @@ -0,0 +1,16 @@ +// +// ModLockPost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModLockPost: Codable, Identifiable, Hashable { + public let id: Int + public let locked: Bool? + public let mod_person_id: Int + public let post_id: Int + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModLockPostView.swift b/Sources/Swimmy/Lemmy API/Structs/ModLockPostView.swift new file mode 100644 index 0000000..1e6b372 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModLockPostView.swift @@ -0,0 +1,15 @@ +// +// ModLockPostView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModLockPostView: Codable, Hashable { + public let community: Community + public let mod_lock_post: ModLockPost + public let moderator: Person? + public let post: Post +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemoveComment.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemoveComment.swift new file mode 100644 index 0000000..de5169e --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemoveComment.swift @@ -0,0 +1,17 @@ +// +// ModRemoveComment.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemoveComment: Codable, Identifiable, Hashable { + public let comment_id: Int + public let id: Int + public let mod_person_id: Int + public let reason: String? + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommentView.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommentView.swift new file mode 100644 index 0000000..18c8beb --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommentView.swift @@ -0,0 +1,17 @@ +// +// ModRemoveCommentView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemoveCommentView: Codable, Hashable { + public let comment: Comment + public let commenter: Person + public let community: Community + public let mod_remove_comment: ModRemoveComment + public let moderator: Person? + public let post: Post +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunity.swift new file mode 100644 index 0000000..2f39b42 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunity.swift @@ -0,0 +1,18 @@ +// +// ModRemoveCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemoveCommunity: Codable, Identifiable, Hashable { + public let community_id: Int + public let expires: String? + public let id: Int + public let mod_person_id: Int + public let reason: String? + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunityView.swift new file mode 100644 index 0000000..4e0ba3a --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemoveCommunityView.swift @@ -0,0 +1,14 @@ +// +// ModRemoveCommunityView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemoveCommunityView: Codable, Hashable { + public let community: Community + public let mod_remove_community: ModRemoveCommunity + public let moderator: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemovePost.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemovePost.swift new file mode 100644 index 0000000..dc76aab --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemovePost.swift @@ -0,0 +1,17 @@ +// +// ModRemovePost.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemovePost: Codable, Identifiable, Hashable { + public let id: Int + public let mod_person_id: Int + public let post_id: Int + public let reason: String? + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModRemovePostView.swift b/Sources/Swimmy/Lemmy API/Structs/ModRemovePostView.swift new file mode 100644 index 0000000..2eff7e1 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModRemovePostView.swift @@ -0,0 +1,15 @@ +// +// ModRemovePostView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModRemovePostView: Codable, Hashable { + public let community: Community + public let mod_remove_post: ModRemovePost + public let moderator: Person? + public let post: Post +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunity.swift b/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunity.swift new file mode 100644 index 0000000..61fe7fa --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunity.swift @@ -0,0 +1,17 @@ +// +// ModTransferCommunity.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModTransferCommunity: Codable, Identifiable, Hashable { + public let community_id: Int + public let id: Int + public let mod_person_id: Int + public let other_person_id: Int + public let removed: Bool? + public let when_: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunityView.swift b/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunityView.swift new file mode 100644 index 0000000..7d7ab0f --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/ModTransferCommunityView.swift @@ -0,0 +1,15 @@ +// +// ModTransferCommunityView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct ModTransferCommunityView: Codable, Hashable { + public let community: Community + public let mod_transfer_community: ModTransferCommunity + public let modded_person: Person + public let moderator: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/MyUserInfo.swift b/Sources/Swimmy/Lemmy API/Structs/MyUserInfo.swift new file mode 100644 index 0000000..2d873c0 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/MyUserInfo.swift @@ -0,0 +1,18 @@ +// +// MyUserInfo.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct MyUserInfo: Codable, Hashable { + public let community_blocks: [CommunityBlockView] + public let discussion_languages: [Int] + public let follows: [CommunityFollowerView] + public let local_user_view: LocalUserSettingsView + public let moderates: [CommunityModeratorView] + public let instance_blocks: [InstanceBlockView]? // v0.1.9 + public let person_blocks: [PersonBlockView] +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Person.swift b/Sources/Swimmy/Lemmy API/Structs/Person.swift new file mode 100644 index 0000000..16a9387 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Person.swift @@ -0,0 +1,30 @@ +// +// Person.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct Person: Codable, Identifiable, Hashable { + public let actor_id: String + public let admin: Bool? // v0.19 change to optional + public let avatar: String? + public let ban_expires: String? + public var banned: Bool + public let banner: String? + public let bio: String? + public let bot_account: Bool + public let deleted: Bool + public let display_name: String? + public let id: Int + public let inbox_url: String? + public let instance_id: Int + public let local: Bool + public let matrix_user_id: String? + public let name: String + public let published: String + public let shared_inbox_url: String? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PersonAggregates.swift b/Sources/Swimmy/Lemmy API/Structs/PersonAggregates.swift new file mode 100644 index 0000000..1f365c9 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PersonAggregates.swift @@ -0,0 +1,17 @@ +// +// PersonAggregates.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct PersonAggregates: Codable, Identifiable, Hashable { + public let comment_count: Int + public let comment_score: Int + public let id: Int + public let person_id: Int + public let post_count: Int + public let post_score: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PersonBlockView.swift b/Sources/Swimmy/Lemmy API/Structs/PersonBlockView.swift new file mode 100644 index 0000000..4f02504 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PersonBlockView.swift @@ -0,0 +1,13 @@ +// +// PersonBlockView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PersonBlockView: Codable, Hashable { + public let person: Person + public let target: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PersonMention.swift b/Sources/Swimmy/Lemmy API/Structs/PersonMention.swift new file mode 100644 index 0000000..7c914f0 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PersonMention.swift @@ -0,0 +1,16 @@ +// +// PersonMention.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PersonMention: Codable, Identifiable, Hashable { + public let comment_id: Int + public let id: Int + public let published: String + public var read: Bool + public let recipient_id: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PersonMentionView.swift b/Sources/Swimmy/Lemmy API/Structs/PersonMentionView.swift new file mode 100644 index 0000000..869b850 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PersonMentionView.swift @@ -0,0 +1,23 @@ +// +// PersonMentionView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PersonMentionView: Codable, Hashable { + public let comment: Comment + public let community: Community + public let counts: CommentAggregates + public let creator: Person + public let creator_banned_from_community: Bool + public let creator_blocked: Bool + public let my_vote: Int? + public let person_mention: PersonMention + public let post: Post + public let recipient: Person + public let saved: Bool + public let subscribed: SubscribedType +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PersonView.swift b/Sources/Swimmy/Lemmy API/Structs/PersonView.swift new file mode 100644 index 0000000..3792b59 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PersonView.swift @@ -0,0 +1,13 @@ +// +// PersonView.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct PersonView: Codable, Hashable { + public let counts: PersonAggregates + public let person: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Post.swift b/Sources/Swimmy/Lemmy API/Structs/Post.swift new file mode 100644 index 0000000..a176bea --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Post.swift @@ -0,0 +1,36 @@ +// +// Post.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct Post: Codable, Identifiable, Hashable, Equatable { + public let ap_id: String + public let body: String? + public let community_id: Int + public let creator_id: Int + public let deleted: Bool + public let embed_description: String? + public let embed_title: String? + public let embed_video_url: URL? + public let featured_community: Bool + public let featured_local: Bool + public let id: Int + public let language_id: Int + public let local: Bool + public let locked: Bool + public let name: String + public let nsfw: Bool + public let published: String + public let removed: Bool + public let thumbnail_url: URL? + public let updated: String? + public let url: String? + + static public func ==(lhs: Post, rhs: Post) -> Bool { + return lhs.id == rhs.id + } +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PostAggregates.swift b/Sources/Swimmy/Lemmy API/Structs/PostAggregates.swift new file mode 100644 index 0000000..2ae39dc --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PostAggregates.swift @@ -0,0 +1,22 @@ +// +// PostAggregates.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct PostAggregates: Codable, Identifiable, Hashable { + public let comments: Int + public let downvotes: Int + public let featured_community: Bool + public let featured_local: Bool + public let id: Int + public let newest_comment_time: String + /// Newest comment time, limited to 2 days, to prevent necrobumping. + public let newest_comment_time_necro: String + public let post_id: Int + public let score: Int + public let upvotes: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PostReport.swift b/Sources/Swimmy/Lemmy API/Structs/PostReport.swift new file mode 100644 index 0000000..5282a46 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PostReport.swift @@ -0,0 +1,22 @@ +// +// PostReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PostReport: Codable, Identifiable, Hashable { + public let creator_id: Int + public let id: Int + public let original_post_body: String? + public let original_post_name: String + public let original_post_url: String? + public let post_id: Int + public let published: String + public let reason: String + public let resolved: Bool + public let resolved_id: Int? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PostReportView.swift b/Sources/Swimmy/Lemmy API/Structs/PostReportView.swift new file mode 100644 index 0000000..782e53b --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PostReportView.swift @@ -0,0 +1,20 @@ +// +// PostReportView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PostReportView: Codable, Hashable { + public let community: Community + public let counts: PostAggregates + public let creator: Person + public var creator_banned_from_community: Bool + public let my_vote: Int? + public var post: Post + public var post_creator: Person + public let post_report: PostReport + public let resolver: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PostView.swift b/Sources/Swimmy/Lemmy API/Structs/PostView.swift new file mode 100644 index 0000000..953b0e5 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PostView.swift @@ -0,0 +1,22 @@ +// +// PostView.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public struct PostView: Codable, Hashable { + public let community: Community + public let counts: PostAggregates + public var creator: Person + public var creator_banned_from_community: Bool + public let creator_blocked: Bool + public let my_vote: Int? + public let post: Post + public var read: Bool + public var saved: Bool + public var subscribed: SubscribedType + public let unread_comments: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PrivateMessage.swift b/Sources/Swimmy/Lemmy API/Structs/PrivateMessage.swift new file mode 100644 index 0000000..d439da7 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PrivateMessage.swift @@ -0,0 +1,21 @@ +// +// PrivateMessage.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PrivateMessage: Codable, Identifiable, Hashable { + public let ap_id: String + public let content: String + public let creator_id: Int + public let deleted: Bool + public let id: Int + public let local: Bool + public let published: String + public var read: Bool + public let recipient_id: Int + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReport.swift b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReport.swift new file mode 100644 index 0000000..8de0c75 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReport.swift @@ -0,0 +1,20 @@ +// +// PrivateMessageReport.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PrivateMessageReport: Codable, Identifiable, Hashable { + public let creator_id: Int + public let id: Int + public let original_pm_text: String + public let private_message_id: Int + public let published: String + public let reason: String + public let resolved: Bool + public let resolver_id: Int? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReportView.swift b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReportView.swift new file mode 100644 index 0000000..07eed79 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageReportView.swift @@ -0,0 +1,16 @@ +// +// PrivateMessageReportView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PrivateMessageReportView: Codable, Hashable { + public let creator: Person + public let private_message: PrivateMessage + public let private_message_creator: Person + public let private_message_report: PrivateMessageReport + public let resolver: Person? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/PrivateMessageView.swift b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageView.swift new file mode 100644 index 0000000..eb08224 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/PrivateMessageView.swift @@ -0,0 +1,14 @@ +// +// PrivateMessageView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct PrivateMessageView: Codable, Hashable { + public let creator: Person + public var private_message: PrivateMessage + public let recipient: Person +} diff --git a/Sources/Swimmy/Lemmy API/Structs/RegistrationApplication.swift b/Sources/Swimmy/Lemmy API/Structs/RegistrationApplication.swift new file mode 100644 index 0000000..2ee29bc --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/RegistrationApplication.swift @@ -0,0 +1,17 @@ +// +// RegistrationApplication.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RegistrationApplication: Codable, Identifiable, Hashable { + public let admin_id: Int? + public let answer: String + public let deny_reason: String + public let id: Int + public let local_user_id: Int + public let published: String +} diff --git a/Sources/Swimmy/Lemmy API/Structs/RegistrationApplicationView.swift b/Sources/Swimmy/Lemmy API/Structs/RegistrationApplicationView.swift new file mode 100644 index 0000000..0289257 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/RegistrationApplicationView.swift @@ -0,0 +1,15 @@ +// +// RegistrationApplicationView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct RegistrationApplicationView: Codable, Hashable { + public let admin: Person? + public let creator: Person + public let creator_local_user: LocalUserSettings + public let registration_application: RegistrationApplication +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Site.swift b/Sources/Swimmy/Lemmy API/Structs/Site.swift new file mode 100644 index 0000000..7fd4c43 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Site.swift @@ -0,0 +1,25 @@ +// +// Site.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct Site: Codable, Identifiable, Hashable { + public let actor_id: String + public let banner: String? + public let description: String? + public let icon: String? + public let id: Int + public let inbox_url: String + public let instance_id: Int + public let last_refreshed_at: String + public let name: String + public let private_key: String? + public let public_key: String + public let published: String + public let sidebar: String? + public let updated: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/SiteAggregates.swift b/Sources/Swimmy/Lemmy API/Structs/SiteAggregates.swift new file mode 100644 index 0000000..c37c8c5 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/SiteAggregates.swift @@ -0,0 +1,21 @@ +// +// SiteAggregates.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SiteAggregates: Codable, Identifiable, Hashable { + public let comments: Int + public let communities: Int + public let id: Int + public let posts: Int + public let site_id: Int + public let users: Int + public let users_active_day: Int + public let users_active_half_year: Int + public let users_active_month: Int + public let users_active_week: Int +} diff --git a/Sources/Swimmy/Lemmy API/Structs/SiteMetadata.swift b/Sources/Swimmy/Lemmy API/Structs/SiteMetadata.swift new file mode 100644 index 0000000..183a611 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/SiteMetadata.swift @@ -0,0 +1,16 @@ +// +// SiteMetadata.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SiteMetadata: Codable, Hashable { + public let description: String? + public let html: String? + public let image: String? + public let title: String? + public let embed_video_url: String? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/SiteView.swift b/Sources/Swimmy/Lemmy API/Structs/SiteView.swift new file mode 100644 index 0000000..d418362 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/SiteView.swift @@ -0,0 +1,16 @@ +// +// SiteView.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct SiteView: Codable, Hashable { + public let counts: SiteAggregates + public let local_site: LocalSite + public let local_site_rate_limit: LocalSiteRateLimit + public let site: Site + public let taglines: [Tagline]? +} diff --git a/Sources/Swimmy/Lemmy API/Structs/Tagline.swift b/Sources/Swimmy/Lemmy API/Structs/Tagline.swift new file mode 100644 index 0000000..71e25e1 --- /dev/null +++ b/Sources/Swimmy/Lemmy API/Structs/Tagline.swift @@ -0,0 +1,16 @@ +// +// Tagline.swift +// +// +// Created by Dana Buehre on 6/11/23. +// + +import Foundation + +public struct Tagline: Codable, Identifiable, Hashable { + public let content: String + public let id: Int + public let local_site_id: Int + public let published: String + public let updated: String? +} diff --git a/Sources/Swimmy/LemmyApi.swift b/Sources/Swimmy/LemmyApi.swift new file mode 100644 index 0000000..f8c7605 --- /dev/null +++ b/Sources/Swimmy/LemmyApi.swift @@ -0,0 +1,313 @@ +import Foundation +import UniformTypeIdentifiers +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif +#if canImport(Dispatch) +import Dispatch +#endif +import CXShim +#if canImport(Combine) +import Combine +#else +import CombineX +#endif + +let swimmyVersion: String = "1.0.0" + + +/// An instance of the Lemmy API. +public class LemmyAPI { + public var retries: Int = 0 + + /// the api endpoint eg https://instance.com/api/v3 + public let baseUrl: URL + /// the pictrs endpoint eg https://instance.com/pictrs/image + public let pictrsUrl: URL + /// the instance endpoint eg https://instance.com + public let instanceUrl: URL + + private let headers: [String: String]? + private let urlSession: URLSession + + public static let headers: [String:String] = [ + "User-Agent" : "Swimmy/\(swimmyVersion); (Lemmy Swift API))", + "Accept-Encoding" : "gzip", + "charset" : "UTF-8" + ] + + public static let dispatchQueue: DispatchQueue = { + return DispatchQueue.init(label: "Swimmy.api", qos: .userInitiated, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil) + }() + + public static let operationQueue: OperationQueue = { + let queue = OperationQueue.init() + queue.maxConcurrentOperationCount = 10 + queue.qualityOfService = .default + queue.underlyingQueue = dispatchQueue + return queue + }() + + public static let session: URLSession = { + let configuration = URLSessionConfiguration.ephemeral + return URLSession(configuration: configuration, delegate: nil, delegateQueue: operationQueue) + }() + + public init(baseUrl: URL, headers: [String: String]? = headers, urlSession: URLSession = session) throws { + self.baseUrl = baseUrl + guard + var components = URLComponents(url: baseUrl, resolvingAgainstBaseURL: false), + let instanceUrl = { + components.queryItems = nil + components.path = "" + return components.url + }() + else { + throw LemmyAPIError.invalidUrl + } + self.instanceUrl = instanceUrl + self.pictrsUrl = instanceUrl.appending(path: "/pictrs/image") + self.headers = headers + self.urlSession = urlSession + } + + public convenience init(baseUrl: String, version: String = "v3", headers: [String: String]? = headers, urlSession: URLSession = session) throws { + var baseUrl = baseUrl.lowercased() + let regex = "https?://" + if baseUrl.range(of: regex, options: .regularExpression) == nil { + baseUrl = "https://" + baseUrl + } + if baseUrl.last == "/" { + baseUrl = String(baseUrl.dropLast()) + } + guard let apiURL = URL(string: "\(baseUrl)/api/\(version)") else { + throw LemmyAPIError.invalidUrl + } + + try self.init(baseUrl: apiURL, headers: headers, urlSession: urlSession) + } + + public func urlRequest(_ apiRequest: T, timeout: TimeInterval = 10) throws -> URLRequest { + var request = URLRequest(url: baseUrl.appending(path: T.path)) + request.httpMethod = T.httpMethod.rawValue + request.timeoutInterval = timeout + + if let auth = apiRequest.jwt { + request.setValue( "Bearer \(auth)", forHTTPHeaderField: "Authorization") + } + + if T.httpMethod == .get { + let mirror = Mirror(reflecting: apiRequest) + request.url = request.url? + .appending(queryItems: mirror.children.compactMap { label, value in + guard let label = label, + let valueString = value as? CustomStringConvertible else { return nil } + + return URLQueryItem(name: label, value: String(describing: valueString)) + }) + } else { + let encoder = JSONEncoder() + request.httpBody = try encoder.encode(apiRequest) + } + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + return request + } + + public func baseRequest(_ apiRequest: T, timeout: TimeInterval = 10) async throws -> (T.Response, URLResponse, Data) { + let request = try urlRequest(apiRequest, timeout: timeout) + print("LemmyAPI request: \(request.debugDescription)") + let (data, response) = try await urlSession.data(for: request) + + let code = (response as! HTTPURLResponse).statusCode + if !(200..<300).contains(code) { + if let genericError = try? JSONDecoder().decode(GenericError.self, from: data), let reason = genericError.error { + switch reason { + case "not_logged_in": + throw LemmyAPIError.notLoggedIn + default: + throw LemmyAPIError.lemmyError(message: genericError.error, code: code) + } + } + throw LemmyAPIError.unexpectedStatusCodeDetails("Unexpected status code from LemmyAPI: (\(code)) \(HTTPURLResponse.localizedString(forStatusCode: code))") + } + + let decoder = JSONDecoder() + + do { + let decodedResult = try decoder.decode(T.Response.self, from: data) + return (decodedResult, response, data) + } catch { + let genericError = try? decoder.decode(GenericError.self, from: data) + print(genericError?.prettyPrintedJSONString ?? String(data: data, textEncodingName: nil, default: .utf8)!) + + + throw error + } + } + + public func request(_ apiRequest: T, timeout: TimeInterval = 10) async throws -> T.Response { + let (result, _, _) = try await baseRequest(apiRequest, timeout: timeout) + return result + } + + public func request(_ apiRequest: T, timeout: TimeInterval = 10, response: @escaping (T.Response?, Error?) -> Void) throws -> AnyCancellable { + let request = try urlRequest(apiRequest, timeout: timeout) + print("LemmyAPI request: \(request.debugDescription)") + +#if canImport(FoundationNetworking) + let session = urlSession.cx +#else + let session = urlSession +#endif + + return session.dataTaskPublisher(for: request).mapError { error in + return LemmyAPIError.network(code: error.code.rawValue, description: error.localizedDescription) + } + .tryMap { v in + let code = (v.response as! HTTPURLResponse).statusCode + if !(200..<300).contains(code) { + + print("unexpectedStatusCode: (\(code)) \(String(data: v.data, encoding: .utf8) ?? "")") + if let decoded = try? JSONDecoder().decode(GenericError.self, from: v.data) { + throw LemmyAPIError.lemmyError(message: decoded.error, code: code) + } + throw LemmyAPIError.network(code: code, description: String(data: v.data, encoding: .utf8) ?? "") + } + return v + } +// .retryWithDelay(retries: retries, delay: 2, scheduler: LemmyAPI.dispatchQueue.cx) + .flatMap { v in + Just(v.data) + .decode(type: T.Response.self, decoder: JSONDecoder()) + .mapError { error in + let decodingError = LemmyAPIError.decoding( + message: String(data: v.data, encoding: .utf8) ?? "", + error: error as! DecodingError + ) + print("\(error)") + return decodingError + } + .tryCatch { decodingError in + Just(v.data) + .decode(type: GenericError.self, decoder: JSONDecoder()) + .mapError { _ in decodingError } + .tryMap { throw LemmyAPIError.lemmyError(message: $0.error, code: 200) } + } + } + .mapError { $0 as! LemmyAPIError } + .receive(on: DispatchQueue.main.cx) + .sink(receiveCompletion: { completion in + switch completion { + case .finished: break + case let .failure(error): + response(nil, error) + } + }, receiveValue: { value in + response(value, nil) + }) + } + + public func uploadRequest(_ apiRequest: UploadImageRequest) async throws -> UploadImageRequest.Response { + let request = MultipartFormDataRequest(url: pictrsUrl) + request.addDataField(named: "images[]", data: apiRequest.image, mimeType: UTType.image.identifier) + var urlRequest = request.asURLRequest() + if let auth = apiRequest.auth { + urlRequest.setValue("jwt=\(auth)", forHTTPHeaderField: "Cookie") + urlRequest.setValue( "Bearer \(auth)", forHTTPHeaderField: "Authorization") + } + + print("LemmyAPI request: \(urlRequest.debugDescription)") + let (data, response) = try await urlSession.data(for: urlRequest) + + try checkResponse(response, data: data) + + let decoder = JSONDecoder() + + do { + let decodedResult = try decoder.decode(UploadImageRequest.Response.self, from: data) + return decodedResult + } catch { + let genericError = try? decoder.decode(GenericError.self, from: data) + print(genericError?.prettyPrintedJSONString ?? String(data: data, textEncodingName: nil, default: .utf8)!) + + if let genericError = genericError { + throw LemmyAPIError.genericError("lemmy returned an error: \(error). response: \(genericError)") + } + + throw error + } + } + + public func checkResponse(_ response: URLResponse, data: Data?) throws { + if let response = response as? HTTPURLResponse, + !(200..<300).contains(response.statusCode) { + let genericError = checkGenericError(data) + + if let genericError = genericError { + throw LemmyAPIError.genericError( + """ + lemmy returned an error: \(genericError) + with an unexpected status code from LemmyAPI: (\(response.statusCode)) + \(HTTPURLResponse.localizedString(forStatusCode: response.statusCode))") + """ + ) + } + + throw LemmyAPIError.unexpectedStatusCodeDetails("Unexpected status code from LemmyAPI: (\(response.statusCode)) \(HTTPURLResponse.localizedString(forStatusCode: response.statusCode))") + } + } + + func checkGenericError(_ data: Data?) -> GenericError? { + guard let data = data else { return nil } + return try? JSONDecoder().decode(GenericError.self, from: data) + } +} + +public enum HTTPMethod: String { + case get = "GET" + case post = "POST" + case put = "PUT" +} + +public enum LemmyAPIError: Error { + case network(code: Int, description: String) + case lemmyError(message: String?, code: Int) + case decoding(message: String, error: DecodingError) + case unexpectedStatusCode(Int) + case unexpectedStatusCodeDetails(String) + case genericError(String) + case notLoggedIn + case invalidUrl +} + +public struct GenericError: Codable { + public let error: String? +} + +extension LemmyAPIError: LocalizedError { + public var errorDescription: String? { + switch self { + case .unexpectedStatusCode(let status): + return "lemmy returned an unexpected status: \(status)" + case .unexpectedStatusCodeDetails(let details): + return "lemmy returned an unexpected status: \(details)" + case .genericError(let error): + return "lemmyAPI encountered an unexpected error: \(error)" + case .notLoggedIn: + return "user not logged in, or session expired" + case .network(let code, let description): + return "LemmyApi received a network error: code \(code), reason: \(description)" + case .lemmyError(let message, let code): + switch message { + case "not_logged_in": + return "user not logged in, or session expired" + default: + return "LemmyApi lemmy returned an error: code \(code), reason: \(message ?? "unknown")" + } + case .decoding(let message, let error): + return "LemmyApi could not decode response: \(message), reason: \(error.localizedDescription)" + case .invalidUrl: + return "lemmyAPI base url is invalid" + } + } +} diff --git a/Sources/Swimmy/MultipartFormDataRequest.swift b/Sources/Swimmy/MultipartFormDataRequest.swift new file mode 100644 index 0000000..bffc785 --- /dev/null +++ b/Sources/Swimmy/MultipartFormDataRequest.swift @@ -0,0 +1,75 @@ +// +// MultipartFormDataRequest.swift +// Arctic +// +// Created by Dana Buehre on 7/9/23. +// + +import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif + +struct MultipartFormDataRequest { + private let boundary: String = UUID().uuidString + private var httpBody = NSMutableData() + let url: URL + + init(url: URL) { + self.url = url + } + + func addTextField(named name: String, value: String) { + httpBody.append(textFormField(named: name, value: value)) + } + + private func textFormField(named name: String, value: String) -> String { + var fieldString = "--\(boundary)\r\n" + fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n" + fieldString += "Content-Type: text/plain; charset=ISO-8859-1\r\n" + fieldString += "Content-Transfer-Encoding: 8bit\r\n" + fieldString += "\r\n" + fieldString += "\(value)\r\n" + + return fieldString + } + + func addDataField(named name: String, data: Data, mimeType: String) { + httpBody.append(dataFormField(named: name, data: data, mimeType: mimeType)) + } + + private func dataFormField(named name: String, + data: Data, + mimeType: String) -> Data { + let fieldData = NSMutableData() + + fieldData.append("--\(boundary)\r\n") + fieldData.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"image.jpg\"\r\n") + fieldData.append("Content-Type: \(mimeType)\r\n") + fieldData.append("\r\n") + fieldData.append(data) + fieldData.append("\r\n") + + return fieldData as Data + } + + func asURLRequest() -> URLRequest { + var request = URLRequest(url: url) + + request.httpMethod = "POST" + request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") + + httpBody.append("--\(boundary)--") + request.httpBody = httpBody as Data + + return request + } +} + +extension NSMutableData { + func append(_ string: String) { + if let data = string.data(using: .utf8) { + self.append(data) + } + } +} diff --git a/Sources/Swimmy/Protocols/API.swift b/Sources/Swimmy/Protocols/API.swift new file mode 100644 index 0000000..7169c41 --- /dev/null +++ b/Sources/Swimmy/Protocols/API.swift @@ -0,0 +1,19 @@ +// +// API.swift +// +// +// Created by Dana Buehre on 6/10/23. +// + +import Foundation + +public protocol APIRequest: Codable, Hashable { + static var httpMethod: HTTPMethod { get } + static var path: String { get } + var jwt: String? { get } + + associatedtype Response: APIResponse +} + +public protocol APIResponse: Codable { +} diff --git a/Tests/SwimmyTests/SwimmyTests.swift b/Tests/SwimmyTests/SwimmyTests.swift new file mode 100644 index 0000000..be4b96e --- /dev/null +++ b/Tests/SwimmyTests/SwimmyTests.swift @@ -0,0 +1,67 @@ +import XCTest +import Combine +@testable import Swimmy + +final class SwimmyTests: XCTestCase { + + let endpoint = URL(string: "https://lemmy.world/api/v3")! + let requests: [any APIRequest] = [ + GetSiteRequest(), + GetPersonDetailsRequest(username: "CreatureSurvive"), + GetPostsRequest(), + GetCommentsRequest() + ] + + func testAPI() async throws { + let api = try LemmyAPI(baseUrl: endpoint) + + for request in requests { + do { + let response = try await api.request(request) + } catch { + XCTFail( + """ + Expected result \(String(describing: requests.self)) Response, + Error: \(error) + Description: \(error.localizedDescription) + """, + file: #file, + line: #line + ) + } + } + } + + func testCombineAPI() async throws { + let api = try LemmyAPI(baseUrl: endpoint) + var cancellables = Set() + + for request in requests { + do { + let (response, error) = try await withCheckedThrowingContinuation { continuation in + do { + try api.request(request) { response, error in + continuation.resume(returning: (response, error)) + }.store(in: &cancellables) + } catch { + continuation.resume(throwing: error) + } + } + if let error = error { + throw error + } + XCTAssert(response != nil, "Found nil for response: \(String(describing: requests.self))") + } catch { + XCTFail( + """ + Expected result \(String(describing: requests.self)) Response, + Error: \(error) + Description: \(error.localizedDescription) + """, + file: #file, + line: #line + ) + } + } + } +}