Use NSXMLDocument to export opml file
This commit is contained in:
@@ -1 +1 @@
|
|||||||
github "relikd/RSXML" "7fa835427e61d2745c02d8d779e0223d0ec2effa"
|
github "relikd/RSXML" "8c3ca8bfc34a227588b41f07896a39fdff0f2e58"
|
||||||
|
|||||||
@@ -55,9 +55,11 @@
|
|||||||
[sp beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) {
|
[sp beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) {
|
||||||
if (result == NSModalResponseOK) {
|
if (result == NSModalResponseOK) {
|
||||||
BOOL flattened = ([self radioGroupSelection:radioView] == 1);
|
BOOL flattened = ([self radioGroupSelection:radioView] == 1);
|
||||||
NSString *exportString = [self exportFeedsHierarchical:!flattened inContext:moc];
|
NSArray<FeedGroup*> *list = [StoreCoordinator sortedListOfRootObjectsInContext:moc];
|
||||||
|
NSXMLDocument *doc = [self xmlDocumentForFeeds:list hierarchical:!flattened];
|
||||||
|
NSData *xml = [doc XMLDataWithOptions:NSXMLNodePreserveAttributeOrder | NSXMLNodePrettyPrint];
|
||||||
NSError *error;
|
NSError *error;
|
||||||
[exportString writeToURL:sp.URL atomically:YES encoding:NSUTF8StringEncoding error:&error];
|
[xml writeToURL:sp.URL options:NSDataWritingAtomic error:&error];
|
||||||
if (error) {
|
if (error) {
|
||||||
[NSApp presentError:error];
|
[NSApp presentError:error];
|
||||||
}
|
}
|
||||||
@@ -198,50 +200,59 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initiate export of current core data state. Write opml header and all root items.
|
Create NSXMLNode structure with application header nodes and body node containing feed items.
|
||||||
|
|
||||||
@param flag If @c YES keep parent-child structure intact. If @c NO ignore all parents and add @c Feed items only.
|
@param flag If @c YES keep parent-child structure intact. If @c NO ignore all parents and add @c Feed items only.
|
||||||
@param moc Managed object context.
|
|
||||||
@return Save this string to file.
|
|
||||||
*/
|
*/
|
||||||
+ (NSString*)exportFeedsHierarchical:(BOOL)flag inContext:(NSManagedObjectContext*)moc {
|
+ (NSXMLDocument*)xmlDocumentForFeeds:(NSArray<FeedGroup*>*)list hierarchical:(BOOL)flag {
|
||||||
NSDictionary *info = @{OPMLTitleKey : @"baRSS feeds",
|
NSXMLElement *head = [NSXMLElement elementWithName:@"head"];
|
||||||
@"ownerName" : @"baRSS",
|
[head addChild:[NSXMLElement elementWithName:@"title" stringValue:@"baRSS feeds"]];
|
||||||
@"dateCreated" : [self currentDayAsStringISO8601:YES]};
|
[head addChild:[NSXMLElement elementWithName:@"ownerName" stringValue:@"baRSS"]];
|
||||||
RSOPMLItem *doc = [RSOPMLItem itemWithAttributes:info];
|
[head addChild:[NSXMLElement elementWithName:@"dateCreated" stringValue:[self currentDayAsStringISO8601:YES]]];
|
||||||
@autoreleasepool {
|
|
||||||
NSArray<FeedGroup*> *arr = [StoreCoordinator sortedListOfRootObjectsInContext:moc];
|
NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
|
||||||
for (FeedGroup *item in arr) {
|
for (FeedGroup *item in list) {
|
||||||
[self addChild:item toParent:doc hierarchical:flag];
|
[self appendChild:item toNode:body hierarchical:flag];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return [doc exportOPMLAsString];
|
|
||||||
|
NSXMLElement *opml = [NSXMLElement elementWithName:@"opml"];
|
||||||
|
[opml addAttribute:[NSXMLNode attributeWithName:@"version" stringValue:@"1.0"]];
|
||||||
|
[opml addChild:head];
|
||||||
|
[opml addChild:body];
|
||||||
|
|
||||||
|
NSXMLDocument *xml = [NSXMLDocument documentWithRootElement:opml];
|
||||||
|
xml.version = @"1.0";
|
||||||
|
xml.characterEncoding = @"UTF-8";
|
||||||
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Build up @c RSOPMLItem structure recursively. Essentially, re-create same structure as in core data storage.
|
Build up @c NSXMLNode structure recursively. Essentially, re-create same structure as in core data storage.
|
||||||
|
|
||||||
@param flag If @c NO don't add groups to export file but continue evaluation of child items.
|
@param flag If @c NO don't add groups to export file but continue evaluation of child items.
|
||||||
*/
|
*/
|
||||||
+ (void)addChild:(FeedGroup*)item toParent:(RSOPMLItem*)parent hierarchical:(BOOL)flag {
|
+ (void)appendChild:(FeedGroup*)item toNode:(NSXMLElement *)parent hierarchical:(BOOL)flag {
|
||||||
RSOPMLItem *child = [RSOPMLItem new];
|
if (flag || item.type != GROUP) {
|
||||||
[child setAttribute:item.name forKey:OPMLTitleKey];
|
// dont add group node if hierarchical == NO
|
||||||
if (flag || item.type == SEPARATOR || item.feed) {
|
NSXMLElement *outline = [NSXMLElement elementWithName:@"outline"];
|
||||||
[parent addChild:child]; // dont add item if item is group and hierarchical == NO
|
[parent addChild:outline];
|
||||||
}
|
[outline addAttribute:[NSXMLNode attributeWithName:OPMLTitleKey stringValue:item.name]];
|
||||||
|
[outline addAttribute:[NSXMLNode attributeWithName:OPMLTextKey stringValue:item.name]];
|
||||||
if (item.type == SEPARATOR) {
|
|
||||||
[child setAttribute:@"true" forKey:@"separator"]; // baRSS specific
|
if (item.type == SEPARATOR) {
|
||||||
} else if (item.feed) {
|
[outline addAttribute:[NSXMLNode attributeWithName:@"separator" stringValue:@"true"]]; // baRSS specific
|
||||||
[child setAttribute:@"rss" forKey:OPMLTypeKey];
|
} else if (item.feed) {
|
||||||
[child setAttribute:item.feed.link forKey:OPMLHMTLURLKey];
|
[outline addAttribute:[NSXMLNode attributeWithName:OPMLHMTLURLKey stringValue:item.feed.link]];
|
||||||
[child setAttribute:item.feed.meta.url forKey:OPMLXMLURLKey];
|
[outline addAttribute:[NSXMLNode attributeWithName:OPMLXMLURLKey stringValue:item.feed.meta.url]];
|
||||||
NSNumber *refreshNum = [NSNumber numberWithInteger:item.feed.meta.refreshInterval];
|
[outline addAttribute:[NSXMLNode attributeWithName:OPMLTypeKey stringValue:@"rss"]];
|
||||||
[child setAttribute:refreshNum forKey:@"refreshInterval"]; // baRSS specific
|
NSString *intervalStr = [NSString stringWithFormat:@"%d", item.feed.meta.refreshInterval];
|
||||||
} else {
|
[outline addAttribute:[NSXMLNode attributeWithName:@"refreshInterval" stringValue:intervalStr]]; // baRSS specific
|
||||||
for (FeedGroup *subItem in [item sortedChildren]) {
|
// TODO: option to export unread state?
|
||||||
[self addChild:subItem toParent:(flag ? child : parent) hierarchical:flag];
|
|
||||||
}
|
}
|
||||||
|
parent = outline;
|
||||||
|
}
|
||||||
|
for (FeedGroup *subItem in [item sortedChildren]) {
|
||||||
|
[self appendChild:subItem toNode:parent hierarchical:flag];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user