Merge pull request #298 from olofhellman/master

Basic read-only support for account feed and folder
This commit is contained in:
Brent Simmons 2018-01-11 08:25:19 -08:00 committed by GitHub
commit 811084c106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 466 additions and 1 deletions

View File

@ -31,3 +31,9 @@ extension String {
return (sum) return (sum)
} }
} }
extension Int {
func FourCharCode() -> FourCharCode {
return (UInt32(self))
}
}

View File

@ -134,7 +134,18 @@
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 */; };
D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; }; D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; };
D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */; };
D5907D972004B7EB005947E5 /* Account+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907D962004B7EB005947E5 /* Account+Scriptability.swift */; };
D5907DB22004BB37005947E5 /* ScriptingObjectContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907DB12004BB37005947E5 /* ScriptingObjectContainer.swift */; };
D5907DB32005F45D005947E5 /* AppleEventUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD7200228B80066386B /* AppleEventUtils.swift */; };
D5D1751220020B980047B29D /* Evergreen.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D5D175012002039D0047B29D /* Evergreen.sdef */; }; D5D1751220020B980047B29D /* Evergreen.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D5D175012002039D0047B29D /* Evergreen.sdef */; };
D5F4EDB5200744A700B9E363 /* ScriptingObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */; };
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */; };
D5F4EDE620075C1300B9E363 /* testNameOfEveryFolder.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */; };
D5F4EDE820075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDE720075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript */; };
D5F4EDE920075C6700B9E363 /* testNameAndUrlOfEveryFeed.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5F4EDE720075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript */; };
D5F4EDEA20075C6700B9E363 /* testNameOfEveryFolder.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -428,6 +439,8 @@
dstPath = TestScripts; dstPath = TestScripts;
dstSubfolderSpec = 7; dstSubfolderSpec = 7;
files = ( files = (
D5F4EDE920075C6700B9E363 /* testNameAndUrlOfEveryFeed.applescript in CopyFiles */,
D5F4EDEA20075C6700B9E363 /* testNameOfEveryFolder.applescript in CopyFiles */,
D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */, D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */,
D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */, D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */,
); );
@ -562,7 +575,15 @@
D5907CDE2002F0BE005947E5 /* Evergreen_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project.xcconfig; sourceTree = "<group>"; }; D5907CDE2002F0BE005947E5 /* Evergreen_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project.xcconfig; sourceTree = "<group>"; };
D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = EvergreenTests_target.xcconfig; sourceTree = "<group>"; }; D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = EvergreenTests_target.xcconfig; sourceTree = "<group>"; };
D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_target.xcconfig; sourceTree = "<group>"; }; D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_target.xcconfig; sourceTree = "<group>"; };
D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApplication+Scriptability.swift"; sourceTree = "<group>"; };
D5907D962004B7EB005947E5 /* Account+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Scriptability.swift"; sourceTree = "<group>"; };
D5907DB12004BB37005947E5 /* ScriptingObjectContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptingObjectContainer.swift; 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>"; };
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptingObject.swift; sourceTree = "<group>"; };
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testNameOfEveryFolder.applescript; sourceTree = "<group>"; };
D5F4EDE720075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = testNameAndUrlOfEveryFeed.applescript; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -912,6 +933,7 @@
848F6AE31FC29CFA002D422E /* Favicons */, 848F6AE31FC29CFA002D422E /* Favicons */,
845213211FCA5B10003B6E93 /* Images */, 845213211FCA5B10003B6E93 /* Images */,
849A97961ED9EFAA007D329B /* Extensions */, 849A97961ED9EFAA007D329B /* Extensions */,
D5907D6F2004AB67005947E5 /* Scriptability */,
D5558FD6200227E60066386B /* AppleEvents */, D5558FD6200227E60066386B /* AppleEvents */,
849A97991ED9EFB6007D329B /* Resources */, 849A97991ED9EFB6007D329B /* Resources */,
84FB9A2C1EDCD6A4003D53B9 /* Frameworks */, 84FB9A2C1EDCD6A4003D53B9 /* Frameworks */,
@ -1092,6 +1114,8 @@
children = ( children = (
D5907C9D20023249005947E5 /* testGenericScript.applescript */, D5907C9D20023249005947E5 /* testGenericScript.applescript */,
D5558FD1200223F60066386B /* testGetURL.applescript */, D5558FD1200223F60066386B /* testGetURL.applescript */,
D5F4EDE720075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript */,
D5F4EDD720075C1300B9E363 /* testNameOfEveryFolder.applescript */,
); );
path = scripts; path = scripts;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1117,6 +1141,20 @@
path = xcconfig; path = xcconfig;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D5907D6F2004AB67005947E5 /* Scriptability */ = {
isa = PBXGroup;
children = (
D5907D962004B7EB005947E5 /* Account+Scriptability.swift */,
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */,
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */,
D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */,
D5907DB12004BB37005947E5 /* ScriptingObjectContainer.swift */,
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */,
);
name = Scriptability;
path = Evergreen/Scriptability;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -1495,12 +1533,14 @@
849C64641ED37A5D003D8FC0 /* AppDelegate.swift in Sources */, 849C64641ED37A5D003D8FC0 /* AppDelegate.swift in Sources */,
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */, 84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */,
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */, 84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
D5907D972004B7EB005947E5 /* Account+Scriptability.swift in Sources */,
842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */, 842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */,
844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */, 844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */,
84DAEE321F870B390058304B /* DockBadge.swift in Sources */, 84DAEE321F870B390058304B /* DockBadge.swift in Sources */,
842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */, 842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */,
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */, 842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */, 845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */,
D5907DB32005F45D005947E5 /* AppleEventUtils.swift in Sources */,
8444C8F21FED81840051386C /* OPMLExporter.swift in Sources */, 8444C8F21FED81840051386C /* OPMLExporter.swift in Sources */,
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */, 849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */, 842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
@ -1512,6 +1552,7 @@
84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */, 84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */,
845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */, 845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */,
84702AA41FA27AC0006B8943 /* MarkReadOrUnreadCommand.swift in Sources */, 84702AA41FA27AC0006B8943 /* MarkReadOrUnreadCommand.swift in Sources */,
D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */,
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */, 849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */, 849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */,
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */, 849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
@ -1525,6 +1566,7 @@
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */, 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */,
842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */, 842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */,
84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */, 84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */,
D5907DB22004BB37005947E5 /* ScriptingObjectContainer.swift in Sources */,
849A978A1ED9ECEF007D329B /* ArticleStylesManager.swift in Sources */, 849A978A1ED9ECEF007D329B /* ArticleStylesManager.swift in Sources */,
849A97791ED9EC04007D329B /* TimelineStringUtilities.swift in Sources */, 849A97791ED9EC04007D329B /* TimelineStringUtilities.swift in Sources */,
84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */, 84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */,
@ -1545,6 +1587,8 @@
849A978D1ED9EE4D007D329B /* FeedListWindowController.swift in Sources */, 849A978D1ED9EE4D007D329B /* FeedListWindowController.swift in Sources */,
849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */, 849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,
84B99C6B1FAE370B00ECDEDB /* FeedListFeed.swift in Sources */, 84B99C6B1FAE370B00ECDEDB /* FeedListFeed.swift in Sources */,
D5F4EDB5200744A700B9E363 /* ScriptingObject.swift in Sources */,
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */,
842611A01FCB72600086A189 /* FeaturedImageDownloader.swift in Sources */, 842611A01FCB72600086A189 /* FeaturedImageDownloader.swift in Sources */,
849A97781ED9EC04007D329B /* TimelineCellLayout.swift in Sources */, 849A97781ED9EC04007D329B /* TimelineCellLayout.swift in Sources */,
84CC08061FF5D2E000C0C0ED /* FeedListSplitViewController.swift in Sources */, 84CC08061FF5D2E000C0C0ED /* FeedListSplitViewController.swift in Sources */,
@ -1563,6 +1607,7 @@
84A1500320048D660046AD9A /* SendToCommand.swift in Sources */, 84A1500320048D660046AD9A /* SendToCommand.swift in Sources */,
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */, 845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */,
849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */, 849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */,
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */,
84E850861FCB60CE0072EA88 /* AuthorAvatarDownloader.swift in Sources */, 84E850861FCB60CE0072EA88 /* AuthorAvatarDownloader.swift in Sources */,
8414AD251FCF5A1E00955102 /* TimelineHeaderView.swift in Sources */, 8414AD251FCF5A1E00955102 /* TimelineHeaderView.swift in Sources */,
849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */, 849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */,
@ -1581,7 +1626,9 @@
D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */, D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */,
849C64761ED37A5D003D8FC0 /* EvergreenTests.swift in Sources */, 849C64761ED37A5D003D8FC0 /* EvergreenTests.swift in Sources */,
D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */, D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */,
D5F4EDE820075C1800B9E363 /* testNameAndUrlOfEveryFeed.applescript in Sources */,
D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */, D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */,
D5F4EDE620075C1300B9E363 /* testNameOfEveryFolder.applescript in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -5,6 +5,86 @@
<!-- declare the namespace for using XInclude so we can include the standard suite --> <!-- declare the namespace for using XInclude so we can include the standard suite -->
<dictionary title="sa;lfsdf" xmlns:xi="http://www.w3.org/2003/XInclude"> <dictionary title="sa;lfsdf" xmlns:xi="http://www.w3.org/2003/XInclude">
<suite name="Standard Suite" code="core" description="Subset of the Standard Suite.">
<class name="application" code="capp" description="The application's top-level scripting object.">
<cocoa class="NSApplication"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the application."/>
<property name="version" code="vers" type="text" access="r" description="The version number of the application."/>
</class>
</suite>
<suite name="Evergreen Suite" code="Geod" description="The Evergreen Application Suite.">
<class name="application" code="capp"
description="Evergreen Application" inherits="application">
<!-- the name of the Cocoa class where we have provided the
various accessor methods for our application class. -->
<cocoa class="NSApplication"/>
<element type="account">
<cocoa key="accounts"/>
</element>
</class>
<enumeration name="account type" code="enum">
<enumerator name="local" code="Locl" description="The On my Mac account"/>
<enumerator name="feedly" code="Fdly" description="A Feedly account"/>
<enumerator name="feedbin" code="Fdbn" description="A Feedbin account"/>
<enumerator name="feed wrangler" code="FWrg" description="A Feed Wrangler account"/>
<enumerator name="newsblur" code="NBlr" description="A Newsblur account"/>
</enumeration>
<class name="account" code="Acct" plural="accounts" description="An account for subscribing to feeds">
<cocoa class="ScriptableAccount"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the account">
<cocoa key="name"/>
</property>
<property name="id" code="id " type="text" access="r" description="The unique id of the account">
<cocoa key="uniqueId"/>
</property>
<property name="type" code="ATyp" type="account type" access="r" description="The type of the account">
<cocoa key="accountType"/>
</property>
<property name="contents" code="Cnts" access="r" description="The type of the account">
<cocoa key="contents"/>
<type type="account item" list="yes"/>
</property>
<element type="feed">
<cocoa key="feeds"/>
</element>
<element type="folder">
<cocoa key="folders"/>
</element>
</class>
<class name="account item" code="AItm" plural="account items" description="a folder or feed">
</class>
<class name="feed" code="Feed" plural="feeds" description="An RSS feeds" inherits="account item">
<cocoa class="ScriptableFeed"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the account">
<cocoa key="name"/>
</property>
<property name="id" code="id " type="text" access="r" description="The unique id of the account">
<cocoa key="uniqueId"/>
</property>
<property name="url" code="URL " type="text" access="r" description="The type of the account">
<cocoa key="url"/>
</property>
</class>
<class name="folder" code="fold" plural="folders" description="A folder for organizing feeds" inherits="account item">
<cocoa class="ScriptableFolder"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the account">
<cocoa key="name"/>
</property>
<property name="id" code="id " type="integer" access="r" description="The unique id of the account">
<cocoa key="uniqueId"/>
</property>
</class>
</suite>
<suite name="Internet Suite" code="GURL" <suite name="Internet Suite" code="GURL"
description="Standard Internet Suite."> description="Standard Internet Suite.">

View File

@ -0,0 +1,95 @@
//
// Account+Scriptability.swift
// Evergreen
//
// Created by Olof Hellman on 1/9/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Cocoa
import Account
import Data
@objc(ScriptableAccount)
class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
let account:Account
init (_ account:Account) {
self.account = account
}
@objc(objectSpecifier)
override var objectSpecifier: NSScriptObjectSpecifier? {
let myContainer = NSApplication.shared
let scriptObjectSpecifier = myContainer.makeFormUniqueIDScriptObjectSpecifier(forObject:self)
return (scriptObjectSpecifier)
}
// MARK: --- ScriptingObject protocol ---
var scriptingKey: String {
return "accounts"
}
// MARK: --- UniqueIdScriptingObject protocol ---
// 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
var scriptingUniqueId:Any {
return account.accountID
}
// MARK: --- ScriptingObjectContainer protocol ---
var scriptingClassDescription: NSScriptClassDescription {
return self.classDescription as! NSScriptClassDescription
}
// MARK: --- Scriptable elements ---
@objc(feeds)
var feeds:NSArray {
let feeds = account.children.flatMap { $0 as? Feed }
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
}
@objc(folders)
var folders:NSArray {
let folders = account.children.flatMap { $0 as? Folder }
return folders.map { ScriptableFolder($0, container:self) } as NSArray
}
// MARK: --- Scriptable properties ---
@objc(contents)
var contents:NSArray {
var contentsArray:[AnyObject] = []
for child in account.children {
if let aFeed = child as? Feed {
contentsArray.append(ScriptableFeed(aFeed, container:self))
} else if let aFolder = child as? Folder {
contentsArray.append(ScriptableFolder(aFolder, container:self))
}
}
return contentsArray as NSArray
}
@objc(accountType)
var accountType:OSType {
var osType:String = ""
switch self.account.type {
case .onMyMac:
osType = "Locl"
case .feedly:
osType = "Fdly"
case .feedbin:
osType = "Fdbn"
case .feedWrangler:
osType = "FWrg"
case .newsBlur:
osType = "NBlr"
}
return osType.FourCharCode()
}
}

View File

@ -0,0 +1,62 @@
//
// Feed+Scriptability.swift
// Evergreen
//
// Created by Olof Hellman on 1/10/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Foundation
import Account
import Data
@objc(ScriptableFeed)
class ScriptableFeed: NSObject, UniqueIdScriptingObject {
let feed:Feed
let container:ScriptingObjectContainer
init (_ feed:Feed, container:ScriptingObjectContainer) {
self.feed = feed
self.container = container
}
@objc(objectSpecifier)
override var objectSpecifier: NSScriptObjectSpecifier? {
let scriptObjectSpecifier = self.container.makeFormUniqueIDScriptObjectSpecifier(forObject:self)
return (scriptObjectSpecifier)
}
// MARK: --- ScriptingObject protocol ---
var scriptingKey: String {
return "feeds"
}
// MARK: --- UniqueIdScriptingObject protocol ---
// 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
var scriptingUniqueId:Any {
return feed.feedID
}
// MARK: --- Scriptable properties ---
@objc(url)
var url:String {
return self.feed.url
}
@objc(uniqueId)
var uniqueId:String {
return self.feed.feedID
}
@objc(name)
var name:String {
return self.feed.name ?? ""
}
}

View File

@ -0,0 +1,56 @@
//
// Folder+Scriptability.swift
// Evergreen
//
// Created by Olof Hellman on 1/10/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Foundation
import Account
@objc(ScriptableFolder)
class ScriptableFolder: NSObject, UniqueIdScriptingObject {
let folder:Folder
let container:ScriptingObjectContainer
init (_ folder:Folder, container:ScriptingObjectContainer) {
self.folder = folder
self.container = container
}
@objc(objectSpecifier)
override var objectSpecifier: NSScriptObjectSpecifier? {
let scriptObjectSpecifier = self.container.makeFormUniqueIDScriptObjectSpecifier(forObject:self)
return (scriptObjectSpecifier)
}
// MARK: --- ScriptingObject protocol ---
var scriptingKey: String {
return "folders"
}
// MARK: --- UniqueIdScriptingObject protocol ---
// 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
var scriptingUniqueId:Any {
return folder.folderID
}
// MARK: --- Scriptable properties ---
@objc(uniqueId)
var uniqueId:Int {
return self.folder.folderID
}
@objc(name)
var name:String {
return self.folder.name ?? ""
}
}

View File

@ -0,0 +1,30 @@
//
// NSApplication+Scriptability.swift
// Evergreen
//
// Created by Olof Hellman on 1/8/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Cocoa
import Account
extension NSApplication : ScriptingObjectContainer {
var scriptingClassDescription: NSScriptClassDescription {
return NSApplication.shared.classDescription as! NSScriptClassDescription
}
var scriptingKey: String {
return "application"
}
@objc(accounts)
func accounts() -> NSArray {
let accounts = AccountManager.shared.accounts
return accounts.map { ScriptableAccount($0) } as NSArray
}
}

View File

@ -0,0 +1,22 @@
//
// ScriptingObject.swift
// Evergreen
//
// Created by Olof Hellman on 1/10/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Foundation
protocol ScriptingObject {
var objectSpecifier: NSScriptObjectSpecifier? { get }
var scriptingKey: String { get }
}
protocol NamedScriptingObject: ScriptingObject {
var name:String { get }
}
protocol UniqueIdScriptingObject: ScriptingObject {
var scriptingUniqueId:Any { get }
}

View File

@ -0,0 +1,38 @@
//
// ScriptingObjectContainer.swift
// Account
//
// Created by Olof Hellman on 1/9/18.
// Copyright © 2018 Olof Hellman. All rights reserved.
//
import Cocoa
protocol ScriptingObjectContainer: ScriptingObject {
var scriptingClassDescription:NSScriptClassDescription { get }
}
extension ScriptingObjectContainer {
func makeFormNameScriptObjectSpecifier(forObject object:NamedScriptingObject) -> NSScriptObjectSpecifier? {
let containerClassDescription = self.scriptingClassDescription
let containerScriptObjectSpecifier = self.objectSpecifier
let scriptingKey = object.scriptingKey
let name = object.name
let specifier = NSNameSpecifier(containerClassDescription:containerClassDescription,
containerSpecifier:containerScriptObjectSpecifier, key:scriptingKey, name:name)
return specifier
}
func makeFormUniqueIDScriptObjectSpecifier(forObject object:UniqueIdScriptingObject) -> NSScriptObjectSpecifier? {
let containerClassDescription = self.scriptingClassDescription
let containerScriptObjectSpecifier = self.objectSpecifier
let scriptingKey = object.scriptingKey
let uniqueId = object.scriptingUniqueId
let specifier = NSUniqueIDSpecifier(containerClassDescription:containerClassDescription,
containerSpecifier:containerScriptObjectSpecifier, key:scriptingKey, uniqueID: uniqueId)
return specifier
}
}

View File

@ -78,4 +78,12 @@ class ScriptingTests: XCTestCase {
_ = doIndividualScript(filename: "testGetURL") _ = doIndividualScript(filename: "testGetURL")
} }
func testNameAndUrlOfEveryFeedScript() {
_ = doIndividualScript(filename: "testNameAndUrlOfEveryFeed")
}
func testNameOfEveryFolderScript() {
_ = doIndividualScript(filename: "testNameOfEveryFolder")
}
} }

View File

@ -0,0 +1,10 @@
-- this script just tests that no error was generated from the script
try
tell application "Evergreen"
{name, url} of every feed of every account
end tell
on error message
return {test_result:false, script_result:message}
end try
return {test_result:true}

View File

@ -0,0 +1,11 @@
-- this script just tests that no error was generated from the script
try
tell application "Evergreen"
name of every folder of every account
end tell
on error message
return {test_result:false, script_result:message}
end try
return {test_result:true}

View File

@ -14,7 +14,7 @@ public final class Folder: DisplayNameProvider, Container, UnreadCountProvider,
public weak var account: Account? public weak var account: Account?
public var children = [AnyObject]() public var children = [AnyObject]()
var name: String? public private(set) var name: String?
static let untitledName = NSLocalizedString("Untitled ƒ", comment: "Folder name") static let untitledName = NSLocalizedString("Untitled ƒ", comment: "Folder name")
public let folderID: Int // not saved: per-run only public let folderID: Int // not saved: per-run only
static var incrementingID = 0 static var incrementingID = 0