From e43a019cca95b7990f9605b9f0ad1cdc37a65dfb Mon Sep 17 00:00:00 2001 From: Olof Hellman Date: Wed, 25 Apr 2018 21:40:50 -0700 Subject: [PATCH 1/2] add testFeedExists script; remove redundant uniqueId functions; add CFBundleURLTypes info.plist key --- Evergreen.xcodeproj/project.pbxproj | 6 ++++++ Evergreen/Info.plist | 13 +++++++++++++ Evergreen/Scriptability/Account+Scriptability.swift | 2 +- Evergreen/Scriptability/Article+Scriptability.swift | 6 +----- Evergreen/Scriptability/Author+Scriptability.swift | 6 +----- Evergreen/Scriptability/Feed+Scriptability.swift | 7 +------ Evergreen/Scriptability/Folder+Scriptability.swift | 6 +----- EvergreenTests/ScriptingTests/ScriptingTests.swift | 4 ++++ .../scripts/testFeedExists.applescript | 10 ++++++++++ 9 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 EvergreenTests/ScriptingTests/scripts/testFeedExists.applescript diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 8b6611303..f0131b965 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -162,6 +162,8 @@ D5558FD5200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */; }; D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD7200228B80066386B /* AppleEventUtils.swift */; }; D57BE6E0204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57BE6DF204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift */; }; + D57BE7642051025E00D11AAC /* testFeedExists.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D57BE7562051025E00D11AAC /* testFeedExists.applescript */; }; + D57BE7652051027D00D11AAC /* testFeedExists.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D57BE7562051025E00D11AAC /* testFeedExists.applescript */; }; D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; }; D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; }; D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; }; @@ -483,6 +485,7 @@ dstPath = TestScripts; dstSubfolderSpec = 7; files = ( + D57BE7652051027D00D11AAC /* testFeedExists.applescript in CopyFiles */, D5D07B19204B423C0093F739 /* testIterativeCreateAndDeleteFeed.applescript in CopyFiles */, D5E4CCDE20303A66009B4FFC /* testCurrentArticleIsNil.applescript in CopyFiles */, D5E4CCDF20303A66009B4FFC /* testURLsOfCurrentArticle.applescript in CopyFiles */, @@ -665,6 +668,7 @@ D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "NSAppleEventDescriptor+UserRecordFields.swift"; path = "AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift"; sourceTree = SOURCE_ROOT; }; D5558FD7200228B80066386B /* AppleEventUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleEventUtils.swift; sourceTree = ""; }; D57BE6DF204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSScriptCommand+Evergreen.swift"; sourceTree = ""; }; + D57BE7562051025E00D11AAC /* testFeedExists.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testFeedExists.applescript; sourceTree = ""; }; D5907C9D20023249005947E5 /* testGenericScript.applescript */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.applescript; path = testGenericScript.applescript; sourceTree = ""; }; D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_release.xcconfig; sourceTree = ""; }; D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_debug.xcconfig; sourceTree = ""; }; @@ -1325,6 +1329,7 @@ D5E4CCD620303823009B4FFC /* selectAFeed.applescript */, D5E4CCD520303823009B4FFC /* selectAnArticle.applescript */, D5907C9D20023249005947E5 /* testGenericScript.applescript */, + D57BE7562051025E00D11AAC /* testFeedExists.applescript */, D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */, D5558FD1200223F60066386B /* testGetURL.applescript */, D5F4EDE720075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript */, @@ -1993,6 +1998,7 @@ D5F4EDE620075C1300B9E363 /* testNameOfEveryFolder.applescript in Sources */, D5E4CCD720303823009B4FFC /* selectAnArticle.applescript in Sources */, D5E4CCD820303823009B4FFC /* selectAFeed.applescript in Sources */, + D57BE7642051025E00D11AAC /* testFeedExists.applescript in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Evergreen/Info.plist b/Evergreen/Info.plist index 2813c9da5..4dbd03aae 100644 --- a/Evergreen/Info.plist +++ b/Evergreen/Info.plist @@ -18,6 +18,19 @@ APPL CFBundleShortVersionString 1.0d42 + CFBundleURLTypes + + + CFBundleTypeRole + Viewer + CFBundleURLName + RSS Feed + CFBundleURLSchemes + + feed + + + CFBundleVersion 522 LSMinimumSystemVersion diff --git a/Evergreen/Scriptability/Account+Scriptability.swift b/Evergreen/Scriptability/Account+Scriptability.swift index 61302f737..8162288ed 100644 --- a/Evergreen/Scriptability/Account+Scriptability.swift +++ b/Evergreen/Scriptability/Account+Scriptability.swift @@ -36,7 +36,7 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta // I am not sure if account should prefer to be specified by name or by ID // but in either case it seems like the accountID would be used as the keydata, so I chose ID - + @objc(uniqueId) var scriptingUniqueId:Any { return account.accountID } diff --git a/Evergreen/Scriptability/Article+Scriptability.swift b/Evergreen/Scriptability/Article+Scriptability.swift index fe15287a7..8dece707d 100644 --- a/Evergreen/Scriptability/Article+Scriptability.swift +++ b/Evergreen/Scriptability/Article+Scriptability.swift @@ -38,6 +38,7 @@ class ScriptableArticle: NSObject, UniqueIdScriptingObject, ScriptingObjectConta // articles have id in the Evergreen database and id in the feed // article.uniqueID here is the feed unique id + @objc(uniqueId) var scriptingUniqueId:Any { return article.uniqueID } @@ -68,11 +69,6 @@ class ScriptableArticle: NSObject, UniqueIdScriptingObject, ScriptingObjectConta var externalUrl:String? { return article.externalURL } - - @objc(uniqueId) - var uniqueId:String { - return article.uniqueID - } @objc(title) var title:String { diff --git a/Evergreen/Scriptability/Author+Scriptability.swift b/Evergreen/Scriptability/Author+Scriptability.swift index 9f2ce5d90..7c9f7fcc7 100644 --- a/Evergreen/Scriptability/Author+Scriptability.swift +++ b/Evergreen/Scriptability/Author+Scriptability.swift @@ -38,6 +38,7 @@ class ScriptableAuthor: NSObject, UniqueIdScriptingObject { // I am not sure if account should prefer to be specified by name or by ID // but in either case it seems like the accountID would be used as the keydata, so I chose ID + @objc(uniqueId) var scriptingUniqueId:Any { return author.authorID } @@ -49,11 +50,6 @@ class ScriptableAuthor: NSObject, UniqueIdScriptingObject { return self.author.url ?? "" } - @objc(uniqueId) - var uniqueId:String { - return self.author.authorID - } - @objc(name) var name:String { return self.author.name ?? "" diff --git a/Evergreen/Scriptability/Feed+Scriptability.swift b/Evergreen/Scriptability/Feed+Scriptability.swift index 5caec6bfd..c863111be 100644 --- a/Evergreen/Scriptability/Feed+Scriptability.swift +++ b/Evergreen/Scriptability/Feed+Scriptability.swift @@ -43,7 +43,7 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine // I am not sure if account should prefer to be specified by name or by ID // but in either case it seems like the accountID would be used as the keydata, so I chose ID - + @objc(uniqueId) var scriptingUniqueId:Any { return feed.feedID } @@ -141,11 +141,6 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine return self.feed.url } - @objc(uniqueId) - var uniqueId:String { - return self.feed.feedID - } - @objc(name) var name:String { return self.feed.name ?? "" diff --git a/Evergreen/Scriptability/Folder+Scriptability.swift b/Evergreen/Scriptability/Folder+Scriptability.swift index ad6039bad..0034fa5fc 100644 --- a/Evergreen/Scriptability/Folder+Scriptability.swift +++ b/Evergreen/Scriptability/Folder+Scriptability.swift @@ -39,6 +39,7 @@ class ScriptableFolder: NSObject, UniqueIdScriptingObject, ScriptingObjectContai // I am not sure if account should prefer to be specified by name or by ID // but in either case it seems like the accountID would be used as the keydata, so I chose ID + @objc(uniqueId) var scriptingUniqueId:Any { return folder.folderID } @@ -97,11 +98,6 @@ class ScriptableFolder: NSObject, UniqueIdScriptingObject, ScriptingObjectContai // MARK: --- Scriptable properties --- - @objc(uniqueId) - var uniqueId:Int { - return self.folder.folderID - } - @objc(name) var name:String { return self.folder.name ?? "" diff --git a/EvergreenTests/ScriptingTests/ScriptingTests.swift b/EvergreenTests/ScriptingTests/ScriptingTests.swift index 29574df34..409d9ecd0 100644 --- a/EvergreenTests/ScriptingTests/ScriptingTests.swift +++ b/EvergreenTests/ScriptingTests/ScriptingTests.swift @@ -48,6 +48,10 @@ class ScriptingTests: AppleScriptXCTestCase { _ = doIndividualScript(filename: "testNameOfAuthors") } + func testFeedExists() { + _ = doIndividualScript(filename: "testFeedExists") + } + func testFeedOPML() { _ = doIndividualScript(filename: "testFeedOPML") } diff --git a/EvergreenTests/ScriptingTests/scripts/testFeedExists.applescript b/EvergreenTests/ScriptingTests/scripts/testFeedExists.applescript new file mode 100644 index 000000000..620d11905 --- /dev/null +++ b/EvergreenTests/ScriptingTests/scripts/testFeedExists.applescript @@ -0,0 +1,10 @@ +-- this script just tests that no error was generated from the script +try + tell application "Evergreen" + exists feed 1 of account 1 + end tell +on error message + return {test_result:false, script_result:message} +end try + +return {test_result:true} From 3dd74ce1481a407c1272d049bb84b30af5f02ae9 Mon Sep 17 00:00:00 2001 From: Olof Hellman Date: Sun, 29 Apr 2018 19:36:40 -0700 Subject: [PATCH 2/2] better logic for rs_normalizedURLString --- Frameworks/RSCore/RSCore/NSString+RSCore.m | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/Frameworks/RSCore/RSCore/NSString+RSCore.m b/Frameworks/RSCore/RSCore/NSString+RSCore.m index b81b3180f..8914d8a4a 100755 --- a/Frameworks/RSCore/RSCore/NSString+RSCore.m +++ b/Frameworks/RSCore/RSCore/NSString+RSCore.m @@ -129,20 +129,41 @@ NSString *RSStringReplaceAll(NSString *stringToSearch, NSString *searchFor, NSSt return self; } +/* + given a URL that could be prefixed with 'feed:' or 'feeds:', + convert it to a URL that begins with 'http:' or 'https:' + + Note: must handle edge case (like boingboing.net) where the feed URL is feed:http://boingboing.net/feed + + Strategy: + 1) note whether or not this is a feed: or feeds: or other prefix + 2) strip the feed: or feeds: prefix + 3) if the resulting string is not prefixed with http: or https:, then add http:// as a prefix + +*/ - (NSString *)rs_normalizedURLString { NSString *s = [self rs_stringByTrimmingWhitespace]; static NSString *feedPrefix = @"feed:"; static NSString *feedsPrefix = @"feeds:"; - static NSString *httpPrefix = @"http:"; - static NSString *httpsPrefix = @"https:"; + static NSString *httpPrefix = @"http"; + static NSString *httpsPrefix = @"https"; + Boolean wasFeeds = false; + + NSString *lowercaseS = [s lowercaseString]; + if ([lowercaseS hasPrefix:feedPrefix] || [lowercaseS hasPrefix:feedsPrefix]) { + if ([lowercaseS hasPrefix:feedsPrefix]) { + wasFeeds = true; + s = [s rs_stringByStrippingPrefix:feedsPrefix caseSensitive:NO]; + } else { + s = [s rs_stringByStrippingPrefix:feedPrefix caseSensitive:NO]; + } + } - s = [s rs_stringByReplacingPrefix:feedPrefix withHTTPPrefix:httpPrefix]; - s = [s rs_stringByReplacingPrefix:feedsPrefix withHTTPPrefix:httpsPrefix]; - - if (![s hasPrefix:@"http"]) { - s = [NSString stringWithFormat:@"http://%@", s]; + lowercaseS = [s lowercaseString]; + if (![lowercaseS hasPrefix:httpPrefix]) { + s = [NSString stringWithFormat: @"%@://%@", wasFeeds ? httpsPrefix : httpPrefix, s]; } return s;