mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-04 21:07:40 +01:00
Merge branch 'mac-release'
This commit is contained in:
commit
6b2ecdaca0
@ -16,7 +16,6 @@
|
||||
5133230A2281082F00C30F19 /* subscriptions_initial.json in Resources */ = {isa = PBXBuildFile; fileRef = 513323092281082F00C30F19 /* subscriptions_initial.json */; };
|
||||
5133230C2281088A00C30F19 /* subscriptions_add.json in Resources */ = {isa = PBXBuildFile; fileRef = 5133230B2281088A00C30F19 /* subscriptions_add.json */; };
|
||||
5133230E2281089500C30F19 /* icons.json in Resources */ = {isa = PBXBuildFile; fileRef = 5133230D2281089500C30F19 /* icons.json */; };
|
||||
5133231122810EB200C30F19 /* FeedbinIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5133230F22810E5700C30F19 /* FeedbinIcon.swift */; };
|
||||
5144EA49227B497600D19003 /* FeedbinAPICaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA48227B497600D19003 /* FeedbinAPICaller.swift */; };
|
||||
5144EA4E227B829A00D19003 /* FeedbinAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */; };
|
||||
5154367B228EEB28005E1CDF /* FeedbinImportResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5154367A228EEB28005E1CDF /* FeedbinImportResult.swift */; };
|
||||
@ -214,7 +213,6 @@
|
||||
513323092281082F00C30F19 /* subscriptions_initial.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscriptions_initial.json; sourceTree = "<group>"; };
|
||||
5133230B2281088A00C30F19 /* subscriptions_add.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscriptions_add.json; sourceTree = "<group>"; };
|
||||
5133230D2281089500C30F19 /* icons.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = icons.json; sourceTree = "<group>"; };
|
||||
5133230F22810E5700C30F19 /* FeedbinIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinIcon.swift; sourceTree = "<group>"; };
|
||||
5144EA48227B497600D19003 /* FeedbinAPICaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAPICaller.swift; sourceTree = "<group>"; };
|
||||
5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAccountDelegate.swift; sourceTree = "<group>"; };
|
||||
5154367A228EEB28005E1CDF /* FeedbinImportResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinImportResult.swift; sourceTree = "<group>"; };
|
||||
@ -492,7 +490,6 @@
|
||||
5144EA48227B497600D19003 /* FeedbinAPICaller.swift */,
|
||||
51E490352288C37100C791F0 /* FeedbinDate.swift */,
|
||||
84CAD7151FDF2E22000F0755 /* FeedbinEntry.swift */,
|
||||
5133230F22810E5700C30F19 /* FeedbinIcon.swift */,
|
||||
5154367A228EEB28005E1CDF /* FeedbinImportResult.swift */,
|
||||
51E5959A228C781500FCC42B /* FeedbinStarredEntry.swift */,
|
||||
84245C841FDDD8CB0074AFBB /* FeedbinSubscription.swift */,
|
||||
@ -956,7 +953,6 @@
|
||||
5144EA49227B497600D19003 /* FeedbinAPICaller.swift in Sources */,
|
||||
84B99C9F1FAE8D3200ECDEDB /* ContainerPath.swift in Sources */,
|
||||
9E510D6E234F16A8002E6F1A /* FeedlyAddFeedRequest.swift in Sources */,
|
||||
5133231122810EB200C30F19 /* FeedbinIcon.swift in Sources */,
|
||||
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */,
|
||||
55203300229D5D5A009559E0 /* ReaderAPICaller.swift in Sources */,
|
||||
9E1D154F233371DD00F4944C /* FeedlyGetCollectionsOperation.swift in Sources */,
|
||||
|
@ -26,7 +26,6 @@ final class FeedbinAPICaller: NSObject {
|
||||
static let subscriptions = "subscriptions"
|
||||
static let tags = "tags"
|
||||
static let taggings = "taggings"
|
||||
static let icons = "icons"
|
||||
static let unreadEntries = "unreadEntries"
|
||||
static let starredEntries = "starredEntries"
|
||||
}
|
||||
@ -149,9 +148,11 @@ final class FeedbinAPICaller: NSObject {
|
||||
|
||||
func retrieveSubscriptions(completion: @escaping (Result<[FeedbinSubscription]?, Error>) -> Void) {
|
||||
|
||||
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions.json")
|
||||
var callComponents = URLComponents(url: feedbinBaseURL.appendingPathComponent("subscriptions.json"), resolvingAgainstBaseURL: false)!
|
||||
callComponents.queryItems = [URLQueryItem(name: "mode", value: "extended")]
|
||||
|
||||
let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.subscriptions]
|
||||
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
||||
let request = URLRequest(url: callComponents.url!, credentials: credentials, conditionalGet: conditionalGet)
|
||||
|
||||
transport.send(request: request, resultType: [FeedbinSubscription].self) { result in
|
||||
|
||||
@ -169,8 +170,10 @@ final class FeedbinAPICaller: NSObject {
|
||||
|
||||
func createSubscription(url: String, completion: @escaping (Result<CreateSubscriptionResult, Error>) -> Void) {
|
||||
|
||||
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions.json")
|
||||
var request = URLRequest(url: callURL, credentials: credentials)
|
||||
var callComponents = URLComponents(url: feedbinBaseURL.appendingPathComponent("subscriptions.json"), resolvingAgainstBaseURL: false)!
|
||||
callComponents.queryItems = [URLQueryItem(name: "mode", value: "extended")]
|
||||
|
||||
var request = URLRequest(url: callComponents.url!, credentials: credentials)
|
||||
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
||||
|
||||
let payload: Data
|
||||
@ -313,26 +316,6 @@ final class FeedbinAPICaller: NSObject {
|
||||
transport.send(request: request, method: HTTPMethod.delete, completion: completion)
|
||||
}
|
||||
|
||||
func retrieveIcons(completion: @escaping (Result<[FeedbinIcon]?, Error>) -> Void) {
|
||||
|
||||
let callURL = feedbinBaseURL.appendingPathComponent("icons.json")
|
||||
let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.icons]
|
||||
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
||||
|
||||
transport.send(request: request, resultType: [FeedbinIcon].self) { result in
|
||||
|
||||
switch result {
|
||||
case .success(let (response, icons)):
|
||||
self.storeConditionalGet(key: ConditionalGetKeys.icons, headers: response.allHeaderFields)
|
||||
completion(.success(icons))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([FeedbinEntry]?), Error>) -> Void) {
|
||||
|
||||
guard !articleIDs.isEmpty else {
|
||||
|
@ -80,7 +80,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
retrieveCredentialsIfNecessary(account)
|
||||
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(6)
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(5)
|
||||
|
||||
refreshAccount(account) { result in
|
||||
switch result {
|
||||
@ -627,26 +627,14 @@ private extension FeedbinAccountDelegate {
|
||||
switch result {
|
||||
case .success(let taggings):
|
||||
|
||||
self.refreshProgress.completeTask()
|
||||
self.caller.retrieveIcons { result in
|
||||
switch result {
|
||||
case .success(let icons):
|
||||
|
||||
BatchUpdate.shared.perform {
|
||||
self.syncFolders(account, tags)
|
||||
self.syncFeeds(account, subscriptions)
|
||||
self.syncFeedFolderRelationship(account, taggings)
|
||||
self.syncFavicons(account, icons)
|
||||
}
|
||||
|
||||
self.refreshProgress.completeTask()
|
||||
completion(.success(()))
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
BatchUpdate.shared.perform {
|
||||
self.syncFolders(account, tags)
|
||||
self.syncFeeds(account, subscriptions)
|
||||
self.syncFeedFolderRelationship(account, taggings)
|
||||
}
|
||||
|
||||
self.refreshProgress.completeTask()
|
||||
completion(.success(()))
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
@ -811,6 +799,8 @@ private extension FeedbinAccountDelegate {
|
||||
feed.editedName = nil
|
||||
feed.homePageURL = subscription.homePageURL
|
||||
feed.subscriptionID = String(subscription.subscriptionID)
|
||||
feed.faviconURL = subscription.jsonFeed?.favicon
|
||||
feed.iconURL = subscription.jsonFeed?.icon
|
||||
}
|
||||
else {
|
||||
subscriptionsToAdd.insert(subscription)
|
||||
@ -894,25 +884,6 @@ private extension FeedbinAccountDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func syncFavicons(_ account: Account, _ icons: [FeedbinIcon]?) {
|
||||
|
||||
guard let icons = icons else { return }
|
||||
|
||||
os_log(.debug, log: log, "Syncing favicons with %ld icons.", icons.count)
|
||||
|
||||
let iconDict = Dictionary(uniqueKeysWithValues: icons.map { ($0.host, $0.url) } )
|
||||
|
||||
for feed in account.flattenedFeeds() {
|
||||
for (key, value) in iconDict {
|
||||
if feed.homePageURL?.contains(key) ?? false {
|
||||
feed.faviconURL = value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func sendArticleStatuses(_ statuses: [SyncStatus],
|
||||
apiCall: ([Int], @escaping (Result<Void, Error>) -> Void) -> Void,
|
||||
completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||
@ -1008,11 +979,12 @@ private extension FeedbinAccountDelegate {
|
||||
|
||||
func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) {
|
||||
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL)
|
||||
feed.subscriptionID = String(sub.subscriptionID)
|
||||
feed.iconURL = sub.jsonFeed?.icon
|
||||
feed.faviconURL = sub.jsonFeed?.favicon
|
||||
|
||||
account.addFeed(feed, to: container) { result in
|
||||
switch result {
|
||||
|
@ -1,21 +0,0 @@
|
||||
//
|
||||
// FeedbinIcon.swift
|
||||
// Account
|
||||
//
|
||||
// Created by Maurice Parker on 5/6/19.
|
||||
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct FeedbinIcon: Codable {
|
||||
|
||||
let host: String
|
||||
let url: String
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case host
|
||||
case url
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,7 @@ struct FeedbinSubscription: Hashable, Codable {
|
||||
let name: String?
|
||||
let url: String
|
||||
let homePageURL: String?
|
||||
let jsonFeed: FeedbinSubscriptionJSONFeed?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case subscriptionID = "id"
|
||||
@ -24,11 +25,26 @@ struct FeedbinSubscription: Hashable, Codable {
|
||||
case name = "title"
|
||||
case url = "feed_url"
|
||||
case homePageURL = "site_url"
|
||||
case jsonFeed = "json_feed"
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(subscriptionID)
|
||||
}
|
||||
|
||||
static func == (lhs: FeedbinSubscription, rhs: FeedbinSubscription) -> Bool {
|
||||
return lhs.subscriptionID == rhs.subscriptionID
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct FeedbinSubscriptionJSONFeed: Codable {
|
||||
let favicon: String?
|
||||
let icon: String?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case favicon = "favicon"
|
||||
case icon = "icon"
|
||||
}
|
||||
}
|
||||
|
||||
struct FeedbinCreateSubscription: Codable {
|
||||
|
Loading…
x
Reference in New Issue
Block a user