Merge pull request #357 from olofhellman/master
AppleScript support for make/delete of feeds and folders
This commit is contained in:
commit
8720c19209
|
@ -161,6 +161,7 @@
|
||||||
D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD22002245C0066386B /* ScriptingTests.swift */; };
|
D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD22002245C0066386B /* ScriptingTests.swift */; };
|
||||||
D5558FD5200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */; };
|
D5558FD5200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */; };
|
||||||
D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD7200228B80066386B /* AppleEventUtils.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 */; };
|
||||||
D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; };
|
D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; };
|
||||||
D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; };
|
D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; };
|
||||||
D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; };
|
D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; };
|
||||||
|
@ -174,6 +175,8 @@
|
||||||
D5A2679D201313A200A8D3C0 /* testNameOfAuthors.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */; };
|
D5A2679D201313A200A8D3C0 /* testNameOfAuthors.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */; };
|
||||||
D5A267C120131B8300A8D3C0 /* testFeedOPML.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */; };
|
D5A267C120131B8300A8D3C0 /* testFeedOPML.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */; };
|
||||||
D5A267C220131BA000A8D3C0 /* testFeedOPML.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */; };
|
D5A267C220131BA000A8D3C0 /* testFeedOPML.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */; };
|
||||||
|
D5D07B18204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5D07B09204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript */; };
|
||||||
|
D5D07B19204B423C0093F739 /* testIterativeCreateAndDeleteFeed.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5D07B09204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript */; };
|
||||||
D5D1751220020B980047B29D /* Evergreen.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D5D175012002039D0047B29D /* Evergreen.sdef */; };
|
D5D1751220020B980047B29D /* Evergreen.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D5D175012002039D0047B29D /* Evergreen.sdef */; };
|
||||||
D5E4CC54202C1361009B4FFC /* AppDelegate+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */; };
|
D5E4CC54202C1361009B4FFC /* AppDelegate+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */; };
|
||||||
D5E4CC64202C1AC1009B4FFC /* MainWindowController+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */; };
|
D5E4CC64202C1AC1009B4FFC /* MainWindowController+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */; };
|
||||||
|
@ -480,6 +483,7 @@
|
||||||
dstPath = TestScripts;
|
dstPath = TestScripts;
|
||||||
dstSubfolderSpec = 7;
|
dstSubfolderSpec = 7;
|
||||||
files = (
|
files = (
|
||||||
|
D5D07B19204B423C0093F739 /* testIterativeCreateAndDeleteFeed.applescript in CopyFiles */,
|
||||||
D5E4CCDE20303A66009B4FFC /* testCurrentArticleIsNil.applescript in CopyFiles */,
|
D5E4CCDE20303A66009B4FFC /* testCurrentArticleIsNil.applescript in CopyFiles */,
|
||||||
D5E4CCDF20303A66009B4FFC /* testURLsOfCurrentArticle.applescript in CopyFiles */,
|
D5E4CCDF20303A66009B4FFC /* testURLsOfCurrentArticle.applescript in CopyFiles */,
|
||||||
D5E4CCDD20303A59009B4FFC /* establishMainWindowStartingState.applescript in CopyFiles */,
|
D5E4CCDD20303A59009B4FFC /* establishMainWindowStartingState.applescript in CopyFiles */,
|
||||||
|
@ -660,6 +664,7 @@
|
||||||
D5558FD22002245C0066386B /* ScriptingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScriptingTests.swift; path = EvergreenTests/ScriptingTests/ScriptingTests.swift; sourceTree = SOURCE_ROOT; };
|
D5558FD22002245C0066386B /* ScriptingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScriptingTests.swift; path = EvergreenTests/ScriptingTests/ScriptingTests.swift; sourceTree = SOURCE_ROOT; };
|
||||||
D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "NSAppleEventDescriptor+UserRecordFields.swift"; path = "AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift"; sourceTree = SOURCE_ROOT; };
|
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 = "<group>"; };
|
D5558FD7200228B80066386B /* AppleEventUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleEventUtils.swift; sourceTree = "<group>"; };
|
||||||
|
D57BE6DF204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSScriptCommand+Evergreen.swift"; sourceTree = "<group>"; };
|
||||||
D5907C9D20023249005947E5 /* testGenericScript.applescript */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.applescript; path = testGenericScript.applescript; sourceTree = "<group>"; };
|
D5907C9D20023249005947E5 /* testGenericScript.applescript */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.applescript; path = testGenericScript.applescript; sourceTree = "<group>"; };
|
||||||
D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_release.xcconfig; sourceTree = "<group>"; };
|
D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_release.xcconfig; sourceTree = "<group>"; };
|
||||||
D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_debug.xcconfig; sourceTree = "<group>"; };
|
D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
@ -672,6 +677,7 @@
|
||||||
D5A2678B20130ECF00A8D3C0 /* Author+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Author+Scriptability.swift"; sourceTree = "<group>"; };
|
D5A2678B20130ECF00A8D3C0 /* Author+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Author+Scriptability.swift"; sourceTree = "<group>"; };
|
||||||
D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testNameOfAuthors.applescript; sourceTree = "<group>"; };
|
D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testNameOfAuthors.applescript; sourceTree = "<group>"; };
|
||||||
D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testFeedOPML.applescript; sourceTree = "<group>"; };
|
D5A267B220131B8300A8D3C0 /* testFeedOPML.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testFeedOPML.applescript; sourceTree = "<group>"; };
|
||||||
|
D5D07B09204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testIterativeCreateAndDeleteFeed.applescript; sourceTree = "<group>"; };
|
||||||
D5D175012002039D0047B29D /* Evergreen.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Evergreen.sdef; path = ../Resources/Evergreen.sdef; sourceTree = "<group>"; };
|
D5D175012002039D0047B29D /* Evergreen.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Evergreen.sdef; path = ../Resources/Evergreen.sdef; sourceTree = "<group>"; };
|
||||||
D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Scriptability.swift"; sourceTree = "<group>"; };
|
D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Scriptability.swift"; sourceTree = "<group>"; };
|
||||||
D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainWindowController+Scriptability.swift"; sourceTree = "<group>"; };
|
D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainWindowController+Scriptability.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -1325,6 +1331,7 @@
|
||||||
D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */,
|
D5A2679B201312F900A8D3C0 /* testNameOfAuthors.applescript */,
|
||||||
D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */,
|
D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */,
|
||||||
D55373A02018797B006D8857 /* testTitleOfArticlesWhose.applescript */,
|
D55373A02018797B006D8857 /* testTitleOfArticlesWhose.applescript */,
|
||||||
|
D5D07B09204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript */,
|
||||||
D5E4CCD12030260E009B4FFC /* testCurrentArticleIsNil.applescript */,
|
D5E4CCD12030260E009B4FFC /* testCurrentArticleIsNil.applescript */,
|
||||||
D5E4CCCF203025FF009B4FFC /* testURLsOfCurrentArticle.applescript */,
|
D5E4CCCF203025FF009B4FFC /* testURLsOfCurrentArticle.applescript */,
|
||||||
D5E4CCB220300024009B4FFC /* uiScriptingTestSetup.applescript */,
|
D5E4CCB220300024009B4FFC /* uiScriptingTestSetup.applescript */,
|
||||||
|
@ -1366,6 +1373,7 @@
|
||||||
D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */,
|
D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */,
|
||||||
D5907DB12004BB37005947E5 /* ScriptingObjectContainer.swift */,
|
D5907DB12004BB37005947E5 /* ScriptingObjectContainer.swift */,
|
||||||
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */,
|
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */,
|
||||||
|
D57BE6DF204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift */,
|
||||||
);
|
);
|
||||||
name = Scriptability;
|
name = Scriptability;
|
||||||
path = Evergreen/Scriptability;
|
path = Evergreen/Scriptability;
|
||||||
|
@ -1876,6 +1884,7 @@
|
||||||
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
||||||
D5A2678C20130ECF00A8D3C0 /* Author+Scriptability.swift in Sources */,
|
D5A2678C20130ECF00A8D3C0 /* Author+Scriptability.swift in Sources */,
|
||||||
84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */,
|
84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */,
|
||||||
|
D57BE6E0204CD35F00D11AAC /* NSScriptCommand+Evergreen.swift in Sources */,
|
||||||
D553738B20186C20006D8857 /* Article+Scriptability.swift in Sources */,
|
D553738B20186C20006D8857 /* Article+Scriptability.swift in Sources */,
|
||||||
845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */,
|
845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */,
|
||||||
84702AA41FA27AC0006B8943 /* MarkStatusCommand.swift in Sources */,
|
84702AA41FA27AC0006B8943 /* MarkStatusCommand.swift in Sources */,
|
||||||
|
@ -1971,6 +1980,7 @@
|
||||||
D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */,
|
D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */,
|
||||||
D55373AF2018797C006D8857 /* testTitleOfArticlesWhose.applescript in Sources */,
|
D55373AF2018797C006D8857 /* testTitleOfArticlesWhose.applescript in Sources */,
|
||||||
D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */,
|
D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */,
|
||||||
|
D5D07B18204B42050093F739 /* testIterativeCreateAndDeleteFeed.applescript in Sources */,
|
||||||
D5A267C120131B8300A8D3C0 /* testFeedOPML.applescript in Sources */,
|
D5A267C120131B8300A8D3C0 /* testFeedOPML.applescript in Sources */,
|
||||||
D5A2679C201312F900A8D3C0 /* testNameOfAuthors.applescript in Sources */,
|
D5A2679C201312F900A8D3C0 /* testNameOfAuthors.applescript in Sources */,
|
||||||
849C64761ED37A5D003D8FC0 /* EvergreenTests.swift in Sources */,
|
849C64761ED37A5D003D8FC0 /* EvergreenTests.swift in Sources */,
|
||||||
|
|
|
@ -7,12 +7,34 @@
|
||||||
|
|
||||||
<suite name="Standard Suite" code="core" description="Subset of the Standard Suite.">
|
<suite name="Standard Suite" code="core" description="Subset of the Standard Suite.">
|
||||||
<access-group identifier="com.ranchero.Evergreen" access="rw"/>
|
<access-group identifier="com.ranchero.Evergreen" access="rw"/>
|
||||||
|
<command name="delete" code="coredelo" description="Delete an object.">
|
||||||
|
<cocoa class="Evergreen.EvergreenDeleteCommand"/>
|
||||||
|
<direct-parameter type="specifier" description="The object(s) to delete."/>
|
||||||
|
</command>
|
||||||
|
|
||||||
<command name="exists" code="coredoex" description="Verify that an object exists.">
|
<command name="exists" code="coredoex" description="Verify that an object exists.">
|
||||||
<cocoa class="Evergreen.EvergreenExistsCommand"/>
|
<cocoa class="Evergreen.EvergreenExistsCommand"/>
|
||||||
<direct-parameter type="any" requires-access="r" description="The object(s) to check."/>
|
<direct-parameter type="any" requires-access="r" description="The object(s) to check."/>
|
||||||
<result type="boolean" description="Does the object(s) exist?"/>
|
<result type="boolean" description="Does the object(s) exist?"/>
|
||||||
</command>
|
</command>
|
||||||
|
|
||||||
|
<command name="make" code="corecrel" description="Create a new object.">
|
||||||
|
<cocoa class="Evergreen.EvergreenCreateElementCommand"/>
|
||||||
|
<parameter name="new" code="kocl" type="type" description="The class of the new object.">
|
||||||
|
<cocoa key="ObjectClass"/>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="at" code="insh" type="location specifier" optional="yes" description="The location at which to insert the object.">
|
||||||
|
<cocoa key="Location"/>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="with data" code="data" type="any" optional="yes" description="The initial contents of the object.">
|
||||||
|
<cocoa key="ObjectData"/>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="with properties" code="prdt" type="record" optional="yes" description="The initial values for properties of the object.">
|
||||||
|
<cocoa key="KeyDictionary"/>
|
||||||
|
</parameter>
|
||||||
|
<result type="specifier" description="The new object."/>
|
||||||
|
</command>
|
||||||
|
|
||||||
<class name="application" code="capp" description="The application's top-level scripting object.">
|
<class name="application" code="capp" description="The application's top-level scripting object.">
|
||||||
<cocoa class="NSApplication"/>
|
<cocoa class="NSApplication"/>
|
||||||
<property name="name" code="pnam" type="text" access="r" description="The name of the application."/>
|
<property name="name" code="pnam" type="text" access="r" description="The name of the application."/>
|
||||||
|
@ -140,6 +162,9 @@
|
||||||
<property name="opml representation" code="OPML" type="text" access="r" description="OPML representation for the folder">
|
<property name="opml representation" code="OPML" type="text" access="r" description="OPML representation for the folder">
|
||||||
<cocoa key="opmlRepresentation"/>
|
<cocoa key="opmlRepresentation"/>
|
||||||
</property>
|
</property>
|
||||||
|
<element type="feed">
|
||||||
|
<cocoa key="feeds"/>
|
||||||
|
</element>
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
<class name="article" code="Arcl" plural="articles" description="An article in a feed">
|
<class name="article" code="Arcl" plural="articles" description="An article in a feed">
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import AppKit
|
import AppKit
|
||||||
import Account
|
import Account
|
||||||
import Data
|
import Data
|
||||||
|
import RSCore
|
||||||
|
|
||||||
@objc(ScriptableAccount)
|
@objc(ScriptableAccount)
|
||||||
class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
|
class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
|
||||||
|
@ -45,6 +46,23 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||||
var scriptingClassDescription: NSScriptClassDescription {
|
var scriptingClassDescription: NSScriptClassDescription {
|
||||||
return self.classDescription as! NSScriptClassDescription
|
return self.classDescription as! NSScriptClassDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
if let scriptableFolder = element as? ScriptableFolder {
|
||||||
|
BatchUpdate.shared.perform {
|
||||||
|
account.deleteFolder(scriptableFolder.folder)
|
||||||
|
}
|
||||||
|
} else if let scriptableFeed = element as? ScriptableFeed {
|
||||||
|
BatchUpdate.shared.perform {
|
||||||
|
account.deleteFeed(scriptableFeed.feed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc(isLocationRequiredToCreateForKey:)
|
||||||
|
func isLocationRequiredToCreate(forKey key:String) -> Bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- Scriptable elements ---
|
// MARK: --- Scriptable elements ---
|
||||||
|
|
||||||
|
@ -61,6 +79,12 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||||
return ScriptableFeed(feed, container:self)
|
return ScriptableFeed(feed, container:self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc(valueInFeedsWithName:)
|
||||||
|
func valueInFeeds(withName name:String) -> ScriptableFeed? {
|
||||||
|
let feeds = account.children.compactMap { $0 as? Feed }
|
||||||
|
guard let feed = feeds.first(where:{$0.name == name}) else { return nil }
|
||||||
|
return ScriptableFeed(feed, container:self)
|
||||||
|
}
|
||||||
|
|
||||||
@objc(folders)
|
@objc(folders)
|
||||||
var folders:NSArray {
|
var folders:NSArray {
|
||||||
|
@ -74,8 +98,7 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||||
let folders = account.children.compactMap { $0 as? Folder }
|
let folders = account.children.compactMap { $0 as? Folder }
|
||||||
guard let folder = folders.first(where:{$0.folderID == folderId}) else { return nil }
|
guard let folder = folders.first(where:{$0.folderID == folderId}) else { return nil }
|
||||||
return ScriptableFolder(folder, container:self)
|
return ScriptableFolder(folder, container:self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: --- Scriptable properties ---
|
// MARK: --- Scriptable properties ---
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// Evergreen
|
// Evergreen
|
||||||
//
|
//
|
||||||
// Created by Olof Hellman on 2/7/18.
|
// Created by Olof Hellman on 2/7/18.
|
||||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
// Copyright © 2018 Olof Hellman. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -56,8 +56,83 @@ extension AppDelegate : AppDelegateAppleEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EvergreenExistsCommand : NSExistsCommand {
|
class EvergreenCreateElementCommand : NSCreateCommand {
|
||||||
|
override func performDefaultImplementation() -> Any? {
|
||||||
|
let classDescription = self.createClassDescription
|
||||||
|
if (classDescription.className == "feed") {
|
||||||
|
return ScriptableFeed.handleCreateElement(command:self)
|
||||||
|
} else if (classDescription.className == "folder") {
|
||||||
|
return ScriptableFolder.handleCreateElement(command:self)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NSDeleteCommand is kind of an oddball AppleScript command in that the command dispatch
|
||||||
|
goes to the container of the object(s) to be deleted, and the container needs to
|
||||||
|
figure out what to delete. In the code below, 'receivers' is the container object(s)
|
||||||
|
and keySpecifier is the thing to delete, relative to the container(s). Because there
|
||||||
|
is ambiguity about whether specifiers are lists or single objects, the code switches
|
||||||
|
based on which it is.
|
||||||
|
*/
|
||||||
|
class EvergreenDeleteCommand : NSDeleteCommand {
|
||||||
|
|
||||||
|
/*
|
||||||
|
delete(objectToDelete:, from container:)
|
||||||
|
At this point in handling the command, we know what the container is.
|
||||||
|
Here the code unravels the case of objectToDelete being a list or a single object,
|
||||||
|
ultimately calling container.deleteElement(element) for each element to delete
|
||||||
|
*/
|
||||||
|
func delete(objectToDelete:Any, from container:ScriptingObjectContainer) {
|
||||||
|
if let objectList = objectToDelete as? [Any] {
|
||||||
|
for nthObject in objectList {
|
||||||
|
self.delete(objectToDelete:nthObject, from:container)
|
||||||
|
}
|
||||||
|
} else if let element = objectToDelete as? ScriptingObject {
|
||||||
|
container.deleteElement(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
delete(specifier:, from container:)
|
||||||
|
At this point in handling the command, the container could be a list or a single object,
|
||||||
|
and what to delete is still an unresolved NSScriptObjectSpecifier.
|
||||||
|
Here the code unravels the case of container being a list or a single object. Once the
|
||||||
|
container(s) is known, it is possible to resolve the keySpecifier based on that container.
|
||||||
|
After resolving, we call delete(objectToDelete:, from container:) with the container and
|
||||||
|
the resolved objects
|
||||||
|
*/
|
||||||
|
func delete(specifier:NSScriptObjectSpecifier, from container:Any) {
|
||||||
|
if let containerList = container as? [Any] {
|
||||||
|
for nthObject in containerList {
|
||||||
|
self.delete(specifier:specifier, from:nthObject)
|
||||||
|
}
|
||||||
|
} else if let container = container as? ScriptingObjectContainer {
|
||||||
|
if let resolvedObjects = specifier.objectsByEvaluating(withContainers:container) {
|
||||||
|
self.delete(objectToDelete:resolvedObjects, from:container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
performDefaultImplementation()
|
||||||
|
This is where handling the delete event starts. receiversSpecifier should be the container(s) of
|
||||||
|
the item to be deleted. keySpecifier is the thing in that container(s) to be deleted
|
||||||
|
The first step is to resolve the receiversSpecifier and then call delete(specifier:, from container:)
|
||||||
|
*/
|
||||||
|
override func performDefaultImplementation() -> Any? {
|
||||||
|
if let receiversSpecifier = self.receiversSpecifier {
|
||||||
|
if let receiverObjects = receiversSpecifier.objectsByEvaluatingSpecifier {
|
||||||
|
self.delete(specifier:self.keySpecifier, from:receiverObjects)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EvergreenExistsCommand : NSExistsCommand {
|
||||||
|
|
||||||
// cocoa default behavior doesn't work here, because of cases where we define an object's property
|
// cocoa default behavior doesn't work here, because of cases where we define an object's property
|
||||||
// to be another object type. e.g., 'permalink of the current article' parses as
|
// to be another object type. e.g., 'permalink of the current article' parses as
|
||||||
// <property> of <property> of <top level object>
|
// <property> of <property> of <top level object>
|
||||||
|
@ -71,8 +146,6 @@ class EvergreenExistsCommand : NSExistsCommand {
|
||||||
override func performDefaultImplementation() -> Any? {
|
override func performDefaultImplementation() -> Any? {
|
||||||
guard let result = super.performDefaultImplementation() else { return NSNumber(booleanLiteral:false) }
|
guard let result = super.performDefaultImplementation() else { return NSNumber(booleanLiteral:false) }
|
||||||
return result
|
return result
|
||||||
// return NSNumber(booleanLiteral:true)
|
|
||||||
// scriptingContainer.handleDoObjectsExist(command:self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@ class ScriptableArticle: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||||
var scriptingClassDescription: NSScriptClassDescription {
|
var scriptingClassDescription: NSScriptClassDescription {
|
||||||
return self.classDescription as! NSScriptClassDescription
|
return self.classDescription as! NSScriptClassDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
print ("delete event not handled")
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- Scriptable properties ---
|
// MARK: --- Scriptable properties ---
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import RSParser
|
||||||
import Account
|
import Account
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
|
@ -27,6 +28,11 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||||
return (scriptObjectSpecifier)
|
return (scriptObjectSpecifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc(scriptingSpecifierDescriptor)
|
||||||
|
func scriptingSpecifierDescriptor() -> NSScriptObjectSpecifier {
|
||||||
|
return (self.objectSpecifier ?? NSScriptObjectSpecifier() )
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- ScriptingObject protocol ---
|
// MARK: --- ScriptingObject protocol ---
|
||||||
|
|
||||||
var scriptingKey: String {
|
var scriptingKey: String {
|
||||||
|
@ -47,9 +53,89 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||||
var scriptingClassDescription: NSScriptClassDescription {
|
var scriptingClassDescription: NSScriptClassDescription {
|
||||||
return self.classDescription as! NSScriptClassDescription
|
return self.classDescription as! NSScriptClassDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: --- handle NSCreateCommand ---
|
||||||
|
|
||||||
|
class func parsedFeedForURL(_ urlString:String, _ completionHandler: @escaping (_ parsedFeed: ParsedFeed?) -> Void) {
|
||||||
|
guard let url = URL(string: urlString) else {
|
||||||
|
completionHandler(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
InitialFeedDownloader.download(url) { (parsedFeed) in
|
||||||
|
completionHandler(parsedFeed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class func urlForNewFeed(arguments:[String:Any]) -> String? {
|
||||||
|
var url:String?
|
||||||
|
if let withDataParam = arguments["ObjectData"] {
|
||||||
|
if let objectDataDescriptor = withDataParam as? NSAppleEventDescriptor {
|
||||||
|
url = objectDataDescriptor.stringValue
|
||||||
|
}
|
||||||
|
} else if let withPropsParam = arguments["ObjectProperties"] as? [String:Any] {
|
||||||
|
url = withPropsParam["url"] as? String
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
class func scriptableFeed(_ feed:Feed, account:Account, folder:Folder?) -> ScriptableFeed {
|
||||||
|
let scriptableAccount = ScriptableAccount(account)
|
||||||
|
if let folder = folder {
|
||||||
|
let scriptableFolder = ScriptableFolder(folder, container:scriptableAccount)
|
||||||
|
return ScriptableFeed(feed, container:scriptableFolder)
|
||||||
|
} else {
|
||||||
|
return ScriptableFeed(feed, container:scriptableAccount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class func handleCreateElement(command:NSCreateCommand) -> Any? {
|
||||||
|
guard command.isCreateCommand(forClass:"Feed") else { return nil }
|
||||||
|
guard let arguments = command.arguments else {return nil}
|
||||||
|
let titleFromArgs = command.property(forKey:"name") as? String
|
||||||
|
let (account, folder) = command.accountAndFolderForNewChild()
|
||||||
|
guard let url = self.urlForNewFeed(arguments:arguments) else {return nil}
|
||||||
|
|
||||||
|
if let existingFeed = account.existingFeed(withURL:url) {
|
||||||
|
return self.scriptableFeed(existingFeed, account:account, folder:folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this point, we need to download the feed and parse it.
|
||||||
|
// RS Parser does the callback for the download on the main thread (which it probably shouldn't?)
|
||||||
|
// because we can't wait here (on the main thread, maybe) for the callback, we have to return from this function
|
||||||
|
// Generally, returning from an AppleEvent handler function means that handling the appleEvent is over,
|
||||||
|
// but we don't yet have the result of the event yet, so we prevent the AppleEvent from returning by calling
|
||||||
|
// suspendExecution(). When we get the callback, we can supply the event result and call resumeExecution()
|
||||||
|
command.suspendExecution()
|
||||||
|
|
||||||
|
self.parsedFeedForURL(url, { (parsedFeedOptional) in
|
||||||
|
if let parsedFeed = parsedFeedOptional {
|
||||||
|
let titleFromFeed = parsedFeed.title
|
||||||
|
|
||||||
|
guard let feed = account.createFeed(with: titleFromFeed, editedName: titleFromArgs, url: url) else {
|
||||||
|
command.resumeExecution(withResult:nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
account.update(feed, with:parsedFeed, {})
|
||||||
|
|
||||||
|
// add the feed, putting it in a folder if needed
|
||||||
|
if account.addFeed(feed, to:folder) {
|
||||||
|
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
||||||
|
}
|
||||||
|
|
||||||
|
let scriptableFeed = self.scriptableFeed(feed, account:account, folder:folder)
|
||||||
|
command.resumeExecution(withResult:scriptableFeed.objectSpecifier)
|
||||||
|
} else {
|
||||||
|
command.resumeExecution(withResult:nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- Scriptable properties ---
|
// MARK: --- Scriptable properties ---
|
||||||
|
|
||||||
@objc(url)
|
@objc(url)
|
||||||
var url:String {
|
var url:String {
|
||||||
return self.feed.url
|
return self.feed.url
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import Account
|
import Account
|
||||||
|
import Data
|
||||||
|
import RSCore
|
||||||
|
|
||||||
@objc(ScriptableFolder)
|
@objc(ScriptableFolder)
|
||||||
class ScriptableFolder: NSObject, UniqueIdScriptingObject {
|
class ScriptableFolder: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
|
||||||
|
|
||||||
let folder:Folder
|
let folder:Folder
|
||||||
let container:ScriptingObjectContainer
|
let container:ScriptingObjectContainer
|
||||||
|
@ -41,6 +43,58 @@ class ScriptableFolder: NSObject, UniqueIdScriptingObject {
|
||||||
return folder.folderID
|
return folder.folderID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: --- ScriptingObjectContainer protocol ---
|
||||||
|
|
||||||
|
var scriptingClassDescription: NSScriptClassDescription {
|
||||||
|
return self.classDescription as! NSScriptClassDescription
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
if let scriptableFolder = element as? ScriptableFolder {
|
||||||
|
BatchUpdate.shared.perform {
|
||||||
|
folder.deleteFolder(scriptableFolder.folder)
|
||||||
|
}
|
||||||
|
} else if let scriptableFeed = element as? ScriptableFeed {
|
||||||
|
BatchUpdate.shared.perform {
|
||||||
|
folder.deleteFeed(scriptableFeed.feed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: --- handle NSCreateCommand ---
|
||||||
|
/*
|
||||||
|
handle an AppleScript like
|
||||||
|
make new folder in account X with properties {name:"new folder name"}
|
||||||
|
or
|
||||||
|
tell account X to make new folder at end with properties {name:"new folder name"}
|
||||||
|
*/
|
||||||
|
class func handleCreateElement(command:NSCreateCommand) -> Any? {
|
||||||
|
guard command.isCreateCommand(forClass:"fold") else { return nil }
|
||||||
|
let name = command.property(forKey:"name") as? String ?? ""
|
||||||
|
|
||||||
|
// some combination of the tell target and the location specifier ("in" or "at")
|
||||||
|
// identifies where the new folder should be created
|
||||||
|
let (account, folder) = command.accountAndFolderForNewChild()
|
||||||
|
guard folder == nil else {
|
||||||
|
print("support for folders within folders is NYI");
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let scriptableAccount = ScriptableAccount(account)
|
||||||
|
if let newFolder = account.ensureFolder(with:name) {
|
||||||
|
let scriptableFolder = ScriptableFolder(newFolder, container:scriptableAccount)
|
||||||
|
return(scriptableFolder.objectSpecifier)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: --- Scriptable elements ---
|
||||||
|
|
||||||
|
@objc(feeds)
|
||||||
|
var feeds:NSArray {
|
||||||
|
let feeds = folder.children.compactMap { $0 as? Feed }
|
||||||
|
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- Scriptable properties ---
|
// MARK: --- Scriptable properties ---
|
||||||
|
|
||||||
@objc(uniqueId)
|
@objc(uniqueId)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// Evergreen
|
// Evergreen
|
||||||
//
|
//
|
||||||
// Created by Olof Hellman on 2/7/18.
|
// Created by Olof Hellman on 2/7/18.
|
||||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
// Copyright © 2018 Olof Hellman. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
|
@ -11,11 +11,17 @@ import Account
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
extension NSApplication : ScriptingObjectContainer {
|
extension NSApplication : ScriptingObjectContainer {
|
||||||
|
|
||||||
|
// MARK: --- ScriptingObjectContainer protocol ---
|
||||||
|
|
||||||
var scriptingClassDescription: NSScriptClassDescription {
|
var scriptingClassDescription: NSScriptClassDescription {
|
||||||
return NSApplication.shared.classDescription as! NSScriptClassDescription
|
return NSApplication.shared.classDescription as! NSScriptClassDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
print ("delete event not handled")
|
||||||
|
}
|
||||||
|
|
||||||
var scriptingKey: String {
|
var scriptingKey: String {
|
||||||
return "application"
|
return "application"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// NSScriptCommand+Evergreen.swift
|
||||||
|
// Evergreen
|
||||||
|
//
|
||||||
|
// Created by Olof Hellman on 3/4/18.
|
||||||
|
// Copyright © 2018 Olof Hellman. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Account
|
||||||
|
|
||||||
|
extension NSScriptCommand {
|
||||||
|
func property(forKey key:String) -> Any? {
|
||||||
|
if let evaluatedArguments = self.evaluatedArguments {
|
||||||
|
if let props = evaluatedArguments["KeyDictionary"] as? [String: Any] {
|
||||||
|
return props[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCreateCommand(forClass whatClass:String) -> Bool {
|
||||||
|
guard let arguments = self.arguments else {return false}
|
||||||
|
guard let newObjectClass = arguments["ObjectClass"] as? Int else {return false}
|
||||||
|
guard (newObjectClass.FourCharCode() == whatClass.FourCharCode()) else {return false}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func accountAndFolderForNewChild() -> (Account, Folder?) {
|
||||||
|
let appleEvent = self.appleEvent
|
||||||
|
var account = AccountManager.shared.localAccount
|
||||||
|
var folder:Folder? = nil
|
||||||
|
if let appleEvent = appleEvent {
|
||||||
|
var descriptorToConsider:NSAppleEventDescriptor?
|
||||||
|
if let insertionLocationDescriptor = appleEvent.paramDescriptor(forKeyword:keyAEInsertHere) {
|
||||||
|
print("insertionLocation : \(insertionLocationDescriptor)")
|
||||||
|
// insertion location can be a typeObjectSpecifier, e.g. 'in account "Acct"'
|
||||||
|
// or a typeInsertionLocation, e.g. 'at end of folder "
|
||||||
|
if (insertionLocationDescriptor.descriptorType == "insl".FourCharCode()) {
|
||||||
|
descriptorToConsider = insertionLocationDescriptor.forKeyword("kobj".FourCharCode())
|
||||||
|
} else if ( insertionLocationDescriptor.descriptorType == "obj ".FourCharCode()) {
|
||||||
|
descriptorToConsider = insertionLocationDescriptor
|
||||||
|
}
|
||||||
|
} else if let subjectDescriptor = appleEvent.attributeDescriptor(forKeyword:"subj".FourCharCode()) {
|
||||||
|
descriptorToConsider = subjectDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let descriptorToConsider = descriptorToConsider {
|
||||||
|
guard let newContainerSpecifier = NSScriptObjectSpecifier(descriptor:descriptorToConsider) else {return (account, folder)}
|
||||||
|
let newContainer = newContainerSpecifier.objectsByEvaluatingSpecifier
|
||||||
|
if let scriptableAccount = newContainer as? ScriptableAccount {
|
||||||
|
account = scriptableAccount.account
|
||||||
|
} else if let scriptableFolder = newContainer as? ScriptableFolder {
|
||||||
|
if let folderAccount = scriptableFolder.folder.account {
|
||||||
|
folder = scriptableFolder.folder
|
||||||
|
account = folderAccount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (account, folder)
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,9 +7,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import AppKit
|
import AppKit
|
||||||
|
import Account
|
||||||
|
|
||||||
protocol ScriptingObjectContainer: ScriptingObject {
|
protocol ScriptingObjectContainer: ScriptingObject {
|
||||||
var scriptingClassDescription:NSScriptClassDescription { get }
|
var scriptingClassDescription:NSScriptClassDescription { get }
|
||||||
|
func deleteElement(_ element:ScriptingObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ScriptingObjectContainer {
|
extension ScriptingObjectContainer {
|
||||||
|
|
|
@ -56,6 +56,10 @@ class ScriptingTests: AppleScriptXCTestCase {
|
||||||
_ = doIndividualScript(filename: "testTitleOfArticlesWhose")
|
_ = doIndividualScript(filename: "testTitleOfArticlesWhose")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testIterativeCreateAndDeleteScript() {
|
||||||
|
_ = doIndividualScriptWithExpectation(filename: "testIterativeCreateAndDeleteFeed")
|
||||||
|
}
|
||||||
|
|
||||||
func doIndividualScriptWithExpectation(filename:String) {
|
func doIndividualScriptWithExpectation(filename:String) {
|
||||||
let queue = DispatchQueue(label:"testQueue")
|
let queue = DispatchQueue(label:"testQueue")
|
||||||
let scriptExpectation = self.expectation(description: filename+"expectation")
|
let scriptExpectation = self.expectation(description: filename+"expectation")
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
try
|
||||||
|
tell application "Evergreen"
|
||||||
|
tell account id "OnMyMac"
|
||||||
|
repeat 3 times
|
||||||
|
set newFeed to make new feed with data "https://boingboing.net/feed"
|
||||||
|
delete newFeed
|
||||||
|
end repeat
|
||||||
|
|
||||||
|
set newFolder to make new folder with properties {name:"XCTest folder"}
|
||||||
|
repeat 3 times
|
||||||
|
set newFeed to make new feed in newFolder with data "https://boingboing.net/feed"
|
||||||
|
delete newFeed
|
||||||
|
end repeat
|
||||||
|
delete newFolder
|
||||||
|
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
|
||||||
|
|
||||||
|
set test_result to true
|
||||||
|
set script_result to "Success"
|
||||||
|
on error message
|
||||||
|
return {test_result:false, script_result:message}
|
||||||
|
end try
|
||||||
|
|
||||||
|
return {test_result:test_result, script_result:script_result}
|
|
@ -258,6 +258,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
||||||
let feed = Feed(accountID: accountID, url: url, feedID: url)
|
let feed = Feed(accountID: accountID, url: url, feedID: url)
|
||||||
feed.name = name
|
feed.name = name
|
||||||
feed.editedName = editedName
|
feed.editedName = editedName
|
||||||
|
|
||||||
return feed
|
return feed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue