Support for creating and deleting feeds in accounts and folders, and
for creating and deleting folders in accounts
This commit is contained in:
parent
71005b56af
commit
c48c54b468
|
@ -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 */; };
|
||||||
|
@ -502,6 +505,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 */,
|
||||||
|
@ -681,6 +685,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>"; };
|
||||||
|
@ -693,6 +698,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>"; };
|
||||||
|
@ -1355,6 +1361,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 */,
|
||||||
|
@ -1396,6 +1403,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;
|
||||||
|
@ -1535,12 +1543,12 @@
|
||||||
};
|
};
|
||||||
849C645F1ED37A5D003D8FC0 = {
|
849C645F1ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = M8L2WTLA8W;
|
DevelopmentTeam = 6V7D786XTL;
|
||||||
ProvisioningStyle = Manual;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
849C64701ED37A5D003D8FC0 = {
|
849C64701ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = 9C84TZ7Q6Z;
|
DevelopmentTeam = 6V7D786XTL;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
||||||
};
|
};
|
||||||
|
@ -1925,6 +1933,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 */,
|
||||||
|
@ -2018,6 +2027,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,6 +7,11 @@
|
||||||
|
|
||||||
<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."/>
|
||||||
|
@ -15,7 +20,6 @@
|
||||||
|
|
||||||
<command name="make" code="corecrel" description="Create a new object.">
|
<command name="make" code="corecrel" description="Create a new object.">
|
||||||
<cocoa class="Evergreen.EvergreenCreateElementCommand"/>
|
<cocoa class="Evergreen.EvergreenCreateElementCommand"/>
|
||||||
<access-group identifier="*"/>
|
|
||||||
<parameter name="new" code="kocl" type="type" description="The class of the new object.">
|
<parameter name="new" code="kocl" type="type" description="The class of the new object.">
|
||||||
<cocoa key="ObjectClass"/>
|
<cocoa key="ObjectClass"/>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
@ -158,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 {
|
||||||
|
@ -46,6 +47,18 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||||
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:)
|
@objc(isLocationRequiredToCreateForKey:)
|
||||||
func isLocationRequiredToCreate(forKey key:String) -> Bool {
|
func isLocationRequiredToCreate(forKey key:String) -> Bool {
|
||||||
return false;
|
return false;
|
||||||
|
@ -66,6 +79,13 @@ 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 {
|
||||||
let folders = account.children.compactMap { $0 as? Folder }
|
let folders = account.children.compactMap { $0 as? Folder }
|
||||||
|
|
|
@ -61,6 +61,71 @@ class EvergreenCreateElementCommand : NSCreateCommand {
|
||||||
let classDescription = self.createClassDescription
|
let classDescription = self.createClassDescription
|
||||||
if (classDescription.className == "feed") {
|
if (classDescription.className == "feed") {
|
||||||
return ScriptableFeed.handleCreateElement(command:self)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -81,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 ---
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,10 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||||
return self.classDescription as! NSScriptClassDescription
|
return self.classDescription as! NSScriptClassDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteElement(_ element:ScriptingObject) {
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: --- Create Element Handlers ---
|
// MARK: --- handle NSCreateCommand ---
|
||||||
|
|
||||||
class func parsedFeedForURL(_ urlString:String, _ completionHandler: @escaping (_ parsedFeed: ParsedFeed?) -> Void) {
|
class func parsedFeedForURL(_ urlString:String, _ completionHandler: @escaping (_ parsedFeed: ParsedFeed?) -> Void) {
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
|
@ -79,105 +81,51 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
class func accountAndFolderForNewFeed(appleEvent:NSAppleEventDescriptor?) -> (Account, Folder?) {
|
class func scriptableFeed(_ feed:Feed, account:Account, folder:Folder?) -> ScriptableFeed {
|
||||||
var account = AccountManager.shared.localAccount
|
let scriptableAccount = ScriptableAccount(account)
|
||||||
var folder:Folder? = nil
|
if let folder = folder {
|
||||||
if let appleEvent = appleEvent {
|
let scriptableFolder = ScriptableFolder(folder, container:scriptableAccount)
|
||||||
var descriptorToConsider:NSAppleEventDescriptor?
|
return ScriptableFeed(feed, container:scriptableFolder)
|
||||||
if let insertionLocationDescriptor = appleEvent.paramDescriptor(forKeyword:keyAEInsertHere) {
|
} else {
|
||||||
print("insertionLocation : \(insertionLocationDescriptor)")
|
return ScriptableFeed(feed, container:scriptableAccount)
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("found account : \(account)")
|
|
||||||
print("found folder : \(folder)")
|
|
||||||
}
|
}
|
||||||
return (account, folder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class func handleCreateElement(command:NSCreateCommand) -> Any? {
|
class func handleCreateElement(command:NSCreateCommand) -> Any? {
|
||||||
let appleEventManager = NSAppleEventManager.shared()
|
guard command.isCreateCommand(forClass:"Feed") else { return nil }
|
||||||
if let receivers = command.receiversSpecifier {
|
|
||||||
print("receivers : \(receivers)")
|
|
||||||
}
|
|
||||||
if let evaluatedReceivers = command.evaluatedReceivers {
|
|
||||||
print("evaluatedReceivers : \(evaluatedReceivers)")
|
|
||||||
}
|
|
||||||
if let evaluatedArguments = command.evaluatedArguments {
|
|
||||||
print("evaluatedArguments : \(evaluatedArguments)")
|
|
||||||
}
|
|
||||||
if let directObject = command.directParameter {
|
|
||||||
print("directObject : \(directObject)")
|
|
||||||
}
|
|
||||||
if let appleEvent = command.appleEvent { // keyDirectObject
|
|
||||||
print("appleEvent : \(appleEvent)")
|
|
||||||
if let subjectDescriptor = appleEvent.attributeDescriptor(forKeyword:"subj".FourCharCode()) {
|
|
||||||
print("subjectDescriptor : \(subjectDescriptor)")
|
|
||||||
let subjectObjectSpecifier = NSScriptObjectSpecifier(descriptor:subjectDescriptor)
|
|
||||||
let subjects = subjectObjectSpecifier?.objectsByEvaluatingSpecifier
|
|
||||||
print("resolvedSubjects : \(subjects)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let commandDescription = command.commandDescription
|
|
||||||
print("commandDescription : \(commandDescription)")
|
|
||||||
|
|
||||||
let (account, folder) = self.accountAndFolderForNewFeed(appleEvent:command.appleEvent)
|
|
||||||
let scriptableAccount = ScriptableAccount(account)
|
|
||||||
guard let arguments = command.arguments else {return nil}
|
guard let arguments = command.arguments else {return nil}
|
||||||
guard let newObjectClass = arguments["ObjectClass"] as? Int else {return nil}
|
let titleFromArgs = command.property(forKey:"name") as? String
|
||||||
guard (newObjectClass.FourCharCode() == "Feed".FourCharCode()) else {return nil}
|
let (account, folder) = command.accountAndFolderForNewChild()
|
||||||
guard let url = self.urlForNewFeed(arguments:arguments) else {return nil}
|
guard let url = self.urlForNewFeed(arguments:arguments) else {return nil}
|
||||||
|
|
||||||
if let existingFeed = account.existingFeed(withURL:url) {
|
if let existingFeed = account.existingFeed(withURL:url) {
|
||||||
return ScriptableFeed(existingFeed, container:scriptableAccount)
|
return self.scriptableFeed(existingFeed, account:account, folder:folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point, we have to download the feed and parse it.
|
// at this point, we need to download the feed and parse it.
|
||||||
// RS Parser does the callback for the download on the main thread
|
// 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
|
// because we can't wait here (on the main thread, maybe) for the callback, we have to return from this function
|
||||||
// generally, the means handling the appleEvent is over, but to prevent the apple event from returning
|
// Generally, returning from an AppleEvent handler function means that handling the appleEvent is over,
|
||||||
// we call suspendExecution here. When we get the callback, we can resume execution
|
// 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()
|
command.suspendExecution()
|
||||||
|
|
||||||
self.parsedFeedForURL(url, { (parsedFeedOptional) in
|
self.parsedFeedForURL(url, { (parsedFeedOptional) in
|
||||||
if let parsedFeed = parsedFeedOptional {
|
if let parsedFeed = parsedFeedOptional {
|
||||||
let titleFromFeed = parsedFeed.title
|
let titleFromFeed = parsedFeed.title
|
||||||
let titleFromArgs = arguments["name"] as? String
|
|
||||||
|
|
||||||
guard let feed = account.createFeed(with: titleFromFeed, editedName: titleFromArgs, url: url) else {
|
guard let feed = account.createFeed(with: titleFromFeed, editedName: titleFromArgs, url: url) else {
|
||||||
command.resumeExecution(withResult:nil)
|
command.resumeExecution(withResult:nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
account.update(feed, with:parsedFeed, {})
|
account.update(feed, with:parsedFeed, {})
|
||||||
|
|
||||||
// add the feed, puttin git in a folder if needed
|
// add the feed, putting it in a folder if needed
|
||||||
if account.addFeed(feed, to: folder) {
|
if account.addFeed(feed, to:folder) {
|
||||||
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolvedKeyDictionary = command.resolvedKeyDictionary
|
let scriptableFeed = self.scriptableFeed(feed, account:account, folder:folder)
|
||||||
print("resolvedKeyDictionary : \(resolvedKeyDictionary)")
|
|
||||||
let scriptableFeed = ScriptableFeed(feed, container:ScriptableAccount(account))
|
|
||||||
command.resumeExecution(withResult:scriptableFeed.objectSpecifier)
|
command.resumeExecution(withResult:scriptableFeed.objectSpecifier)
|
||||||
} else {
|
} else {
|
||||||
command.resumeExecution(withResult:nil)
|
command.resumeExecution(withResult:nil)
|
||||||
|
@ -185,12 +133,9 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||||
})
|
})
|
||||||
return 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)
|
||||||
|
|
|
@ -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 Ranchero Software. 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}
|
Loading…
Reference in New Issue