2019-05-28 19:08:15 +02:00
//
// G o o g l e R e a d e r C o m p a t i b l e A r t i c l e . s w i f t
// A c c o u n t
//
// C r e a t e d b y B r e n t S i m m o n s o n 1 2 / 1 1 / 1 7 .
// C o p y r i g h t © 2 0 1 7 R a n c h e r o S o f t w a r e , L L C . A l l r i g h t s r e s e r v e d .
//
import Foundation
import RSParser
import RSCore
2019-06-10 22:53:35 +02:00
struct GoogleReaderCompatibleEntryWrapper : Codable {
let id : String
let updated : Int
let entries : [ GoogleReaderCompatibleEntry ]
enum CodingKeys : String , CodingKey {
case id = " id "
case updated = " updated "
case entries = " items "
}
}
/* {
" id " : " tag:google.com,2005:reader/item/00058a3b5197197b " ,
" crawlTimeMsec " : " 1559362260113 " ,
" timestampUsec " : " 1559362260113787 " ,
" published " : 1554845280 ,
" title " : " " ,
" summary " : {
" content " : " \n <p>Found an old screenshot of NetNewsWire 1.0 for iPhone!</p> \n \n <p><img src= \" https://nnw.ranchero.com/uploads/2019/c07c0574b1.jpg \" alt= \" Netnewswire 1.0 for iPhone screenshot showing the list of feeds. \" title= \" NewsGator got renamed to Sitrion, years later, and then renamed again as Limeade. \" border= \" 0 \" width= \" 260 \" height= \" 320 \" ></p> \n "
} ,
" alternate " : [
{
" href " : " https://nnw.ranchero.com/2019/04/09/found-an-old.html "
}
] ,
" categories " : [
" user/-/state/com.google/reading-list " ,
" user/-/label/Uncategorized "
] ,
" origin " : {
" streamId " : " feed/130 " ,
" title " : " NetNewsWire "
}
}
*/
2019-05-28 19:08:15 +02:00
struct GoogleReaderCompatibleEntry : Codable {
2019-06-10 22:53:35 +02:00
let articleID : String
2019-05-28 19:08:15 +02:00
let title : String ?
2019-06-10 22:53:35 +02:00
let publishedTimestamp : Double ?
let crawledTimestamp : String ?
let timestampUsec : String ?
let summary : GoogleReaderCompatibleArticleSummary
let alternates : [ GoogleReaderCompatibleAlternateLocation ]
let categories : [ String ]
let origin : GoogleReaderCompatibleEntryOrigin
2019-05-28 19:08:15 +02:00
enum CodingKeys : String , CodingKey {
case articleID = " id "
case title = " title "
case summary = " summary "
2019-06-10 22:53:35 +02:00
case alternates = " alternate "
case categories = " categories "
case publishedTimestamp = " published "
case crawledTimestamp = " crawlTimeMsec "
case origin = " origin "
case timestampUsec = " timestampUsec "
2019-05-28 19:08:15 +02:00
}
2019-06-10 22:53:35 +02:00
2019-05-28 19:08:15 +02:00
func parseDatePublished ( ) -> Date ? {
2019-06-10 22:53:35 +02:00
guard let unixTime = publishedTimestamp else {
2019-05-28 19:08:15 +02:00
return nil
}
2019-06-10 22:53:35 +02:00
return Date ( timeIntervalSince1970 : unixTime )
2019-05-28 19:08:15 +02:00
}
2019-06-11 21:37:21 +02:00
func uniqueID ( ) -> String {
// S h o u l d l o o k s o m e t h i n g l i k e " t a g : g o o g l e . c o m , 2 0 0 5 : r e a d e r / i t e m / 0 0 0 5 8 b 1 0 c e 3 3 8 9 0 9 "
// R E G E X f e e l s h e a v y , I s h o u l d b e a b l e t o j u s t s p l i t o n / a n d t a k e t h e l a s t e l e m e n t
guard let idPart = articleID . components ( separatedBy : " / " ) . last else {
return articleID
}
// C o n v e r t h e x r e p r e s e n t a t i o n b a c k t o i n t e g e r a n d t h e n a s t r i n g r e p r e s e n t a t i o n
guard let idNumber = Int ( idPart , radix : 16 ) else {
return articleID
}
return String ( idNumber , radix : 10 , uppercase : false )
}
2019-05-28 19:08:15 +02:00
}
2019-06-10 22:53:35 +02:00
struct GoogleReaderCompatibleArticleSummary : Codable {
let content : String ?
2019-05-28 19:08:15 +02:00
enum CodingKeys : String , CodingKey {
2019-06-10 22:53:35 +02:00
case content = " content "
2019-05-28 19:08:15 +02:00
}
}
2019-06-10 22:53:35 +02:00
struct GoogleReaderCompatibleAlternateLocation : Codable {
2019-05-28 19:08:15 +02:00
let url : String ?
2019-06-10 22:53:35 +02:00
2019-05-28 19:08:15 +02:00
enum CodingKeys : String , CodingKey {
2019-06-10 22:53:35 +02:00
case url = " href "
2019-05-28 19:08:15 +02:00
}
}
2019-06-10 22:53:35 +02:00
struct GoogleReaderCompatibleEntryOrigin : Codable {
let streamId : String ?
let title : String ?
enum CodingKeys : String , CodingKey {
case streamId = " streamId "
case title = " title "
}
}