2021-03-09 08:18:43 +01:00
//
// A P I S e r v i c e + R e b l o g . s w i f t
// M a s t o d o n
//
// C r e a t e d b y M a i n a s u K C i r n o o n 2 0 2 1 - 3 - 9 .
//
import Foundation
import Combine
import MastodonSDK
import CoreData
import CoreDataStack
import CommonOSLog
extension APIService {
// m a k e l o c a l s t a t e c h a n g e o n l y
func boost (
tootObjectID : NSManagedObjectID ,
mastodonUserObjectID : NSManagedObjectID ,
2021-03-09 12:39:44 +01:00
boostKind : Mastodon . API . Reblog . BoostKind
2021-03-09 08:18:43 +01:00
) -> AnyPublisher < Toot . ID , Error > {
var _targetTootID : Toot . ID ?
let managedObjectContext = backgroundManagedObjectContext
return managedObjectContext . performChanges {
let toot = managedObjectContext . object ( with : tootObjectID ) as ! Toot
let mastodonUser = managedObjectContext . object ( with : mastodonUserObjectID ) as ! MastodonUser
let targetToot = toot . reblog ? ? toot
let targetTootID = targetToot . id
_targetTootID = targetTootID
targetToot . update ( reblogged : boostKind = = . boost , mastodonUser : mastodonUser )
}
. tryMap { result in
switch result {
case . success :
guard let targetTootID = _targetTootID else {
throw APIError . implicit ( . badRequest )
}
return targetTootID
case . failure ( let error ) :
assertionFailure ( error . localizedDescription )
throw error
}
}
. eraseToAnyPublisher ( )
}
// s e n d b o o s t r e q u e s t t o r e m o t e
func boost (
statusID : Mastodon . Entity . Status . ID ,
2021-03-09 12:39:44 +01:00
boostKind : Mastodon . API . Reblog . BoostKind ,
2021-03-09 08:18:43 +01:00
mastodonAuthenticationBox : AuthenticationService . MastodonAuthenticationBox
) -> AnyPublisher < Mastodon . Response . Content < Mastodon . Entity . Status > , Error > {
let domain = mastodonAuthenticationBox . domain
let authorization = mastodonAuthenticationBox . userAuthorization
let requestMastodonUserID = mastodonAuthenticationBox . userID
2021-03-09 12:39:44 +01:00
return Mastodon . API . Reblog . boost (
2021-03-09 08:18:43 +01:00
session : session ,
domain : domain ,
statusID : statusID ,
boostKind : boostKind ,
authorization : authorization
)
. map { response -> AnyPublisher < Mastodon . Response . Content < Mastodon . Entity . Status > , Error > in
let log = OSLog . api
let entity = response . value
let managedObjectContext = self . backgroundManagedObjectContext
return managedObjectContext . performChanges {
let _requestMastodonUser : MastodonUser ? = {
let request = MastodonUser . sortedFetchRequest
request . predicate = MastodonUser . predicate ( domain : mastodonAuthenticationBox . domain , id : requestMastodonUserID )
request . fetchLimit = 1
request . returnsObjectsAsFaults = false
do {
return try managedObjectContext . fetch ( request ) . first
} catch {
assertionFailure ( error . localizedDescription )
return nil
}
} ( )
let _oldToot : Toot ? = {
let request = Toot . sortedFetchRequest
request . predicate = Toot . predicate ( domain : domain , id : statusID )
request . returnsObjectsAsFaults = false
request . relationshipKeyPathsForPrefetching = [ # keyPath ( Toot . reblog ) ]
do {
return try managedObjectContext . fetch ( request ) . first
} catch {
assertionFailure ( error . localizedDescription )
return nil
}
} ( )
guard let requestMastodonUser = _requestMastodonUser ,
let oldToot = _oldToot else {
assertionFailure ( )
return
}
APIService . CoreData . merge ( toot : oldToot , entity : entity . reblog ? ? entity , requestMastodonUser : requestMastodonUser , domain : mastodonAuthenticationBox . domain , networkDate : response . networkDate )
os_log ( . info , log : log , " %{public}s[%{public}ld], %{public}s: did update toot %{public}s reblog status to: %{public}s. now %ld boosts " , ( ( #file as NSString ) . lastPathComponent ) , #line , #function , entity . id , entity . reblogged . flatMap { $0 ? " boost " : " unboost " } ? ? " <nil> " , entity . reblogsCount )
}
. setFailureType ( to : Error . self )
. tryMap { result -> Mastodon . Response . Content < Mastodon . Entity . Status > in
switch result {
case . success :
return response
case . failure ( let error ) :
throw error
}
}
. eraseToAnyPublisher ( )
}
. switchToLatest ( )
. handleEvents ( receiveCompletion : { completion in
switch completion {
case . failure ( let error ) :
os_log ( . info , log : . debug , " %{public}s[%{public}ld], %{public}s: error: " , ( ( #file as NSString ) . lastPathComponent ) , #line , #function )
debugPrint ( error )
case . finished :
break
}
} )
. eraseToAnyPublisher ( )
}
}
extension APIService {
// f u n c l i k e L i s t (
// l i m i t : I n t = o n c e R e q u e s t T o o t M a x C o u n t ,
// u s e r I D : S t r i n g ,
// m a x I D : S t r i n g ? = n i l ,
// m a s t o d o n A u t h e n t i c a t i o n B o x : A u t h e n t i c a t i o n S e r v i c e . M a s t o d o n A u t h e n t i c a t i o n B o x
// ) - > A n y P u b l i s h e r < M a s t o d o n . R e s p o n s e . C o n t e n t < [ M a s t o d o n . E n t i t y . S t a t u s ] > , E r r o r > {
//
// l e t r e q u e s t M a s t o d o n U s e r I D = m a s t o d o n A u t h e n t i c a t i o n B o x . u s e r I D
// l e t q u e r y = M a s t o d o n . A P I . F a v o r i t e s . L i s t Q u e r y ( l i m i t : l i m i t , m i n I D : n i l , m a x I D : m a x I D )
// r e t u r n M a s t o d o n . A P I . F a v o r i t e s . f a v o r i t e d S t a t u s ( d o m a i n : m a s t o d o n A u t h e n t i c a t i o n B o x . d o m a i n , s e s s i o n : s e s s i o n , a u t h o r i z a t i o n : m a s t o d o n A u t h e n t i c a t i o n B o x . u s e r A u t h o r i z a t i o n , q u e r y : q u e r y )
// . m a p { r e s p o n s e - > A n y P u b l i s h e r < M a s t o d o n . R e s p o n s e . C o n t e n t < [ M a s t o d o n . E n t i t y . S t a t u s ] > , E r r o r > i n
// l e t l o g = O S L o g . a p i
//
// r e t u r n A P I S e r v i c e . P e r s i s t . p e r s i s t T i m e l i n e (
// m a n a g e d O b j e c t C o n t e x t : s e l f . b a c k g r o u n d M a n a g e d O b j e c t C o n t e x t ,
// d o m a i n : m a s t o d o n A u t h e n t i c a t i o n B o x . d o m a i n ,
// q u e r y : q u e r y ,
// r e s p o n s e : r e s p o n s e ,
// p e r s i s t T y p e : . l i k e L i s t ,
// r e q u e s t M a s t o d o n U s e r I D : r e q u e s t M a s t o d o n U s e r I D ,
// l o g : l o g
// )
// . s e t F a i l u r e T y p e ( t o : E r r o r . s e l f )
// . t r y M a p { r e s u l t - > M a s t o d o n . R e s p o n s e . C o n t e n t < [ M a s t o d o n . E n t i t y . S t a t u s ] > i n
// s w i t c h r e s u l t {
// c a s e . s u c c e s s :
// r e t u r n r e s p o n s e
// c a s e . f a i l u r e ( l e t e r r o r ) :
// t h r o w e r r o r
// }
// }
// . e r a s e T o A n y P u b l i s h e r ( )
// }
// . s w i t c h T o L a t e s t ( )
// . e r a s e T o A n y P u b l i s h e r ( )
// }
}