Skip to content

Commit

Permalink
use info.json, not info.plist, for plugins. add plugin usage example …
Browse files Browse the repository at this point in the history
…field
  • Loading branch information
nate-parrott committed Nov 10, 2014
1 parent 8c9a270 commit 8aff87a
Show file tree
Hide file tree
Showing 29 changed files with 106 additions and 65 deletions.
2 changes: 1 addition & 1 deletion FlashlightApp/EasySIMBL/Flashlight-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.21</string>
<string>0.22</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
7 changes: 5 additions & 2 deletions FlashlightApp/EasySIMBL/PluginListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
CGFloat topInset = 7;
CGFloat bottomInset = 7;
CGFloat rightInset = 65;
return [[[self.arrayController.arrangedObjects objectAtIndex:row] attributedString] boundingRectWithSize:CGSizeMake(tableView.bounds.size.width-leftInset-rightInset, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin].size.height + topInset + bottomInset;
return [[[self.arrayController.arrangedObjects objectAtIndex:row] attributedString] boundingRectWithSize:CGSizeMake(tableView.bounds.size.width-leftInset-rightInset, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin].size.height + topInset + bottomInset + 4;
}

- (NSIndexSet *)tableView:(NSTableView *)tableView
Expand Down Expand Up @@ -163,7 +163,10 @@ - (void)reloadFromDisk {
NSMutableArray *models = [NSMutableArray new];
for (NSString *itemName in contents) {
if ([[itemName pathExtension] isEqualToString:@"bundle"]) {
[models addObject:[PluginModel fromPath:[[self localPluginsPath] stringByAppendingPathComponent:itemName]]];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:[[[self localPluginsPath] stringByAppendingPathComponent:itemName] stringByAppendingPathComponent:@"info.json"]] options:0 error:nil];
PluginModel *model = [PluginModel fromJson:json baseURL:nil];
model.installed = YES;
[models addObject:model];
}
}
self.installedPlugins = models;
Expand Down
2 changes: 1 addition & 1 deletion FlashlightApp/EasySIMBL/PluginModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
@interface PluginModel : NSObject <NSCopying>

@property (nonatomic) NSString *name, *displayName, *pluginDescription;
@property (nonatomic) NSArray *examples;
@property (nonatomic) BOOL installed;
@property (nonatomic) BOOL installing;
@property (nonatomic) NSURL *zipURL;

+ (PluginModel *)fromPath:(NSString *)path;
+ (PluginModel *)fromJson:(NSDictionary *)json baseURL:(NSURL *)url;

+ (NSArray *)mergeDuplicates:(NSArray *)models;
Expand Down
40 changes: 25 additions & 15 deletions FlashlightApp/EasySIMBL/PluginModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,16 @@ - (id)copyWithZone:(NSZone *)zone {
p.pluginDescription = self.pluginDescription;
p.installed = self.installed;
p.installing = self.installing;
p.examples = self.examples;
return p;
}

+ (PluginModel *)fromPath:(NSString *)path {
NSBundle *bundle = [NSBundle bundleWithPath:path];
PluginModel *model = [PluginModel new];
model.name = [path lastPathComponent].stringByDeletingPathExtension;
model.displayName = [bundle infoDictionary][@"CFBundleDisplayName"];
model.pluginDescription = [bundle infoDictionary][@"Description"];
model.installed = YES;
return model;
}

+ (PluginModel *)fromJson:(NSDictionary *)json baseURL:(NSURL *)url {
PluginModel *model = [PluginModel new];
model.name = json[@"name"];
model.displayName = json[@"CFBundleDisplayName"];
model.pluginDescription = json[@"Description"];
model.displayName = json[@"displayName"];
model.pluginDescription = json[@"description"];
model.examples = json[@"examples"];
model.installed = NO;
model.zipURL = [NSURL URLWithString:json[@"zip_url"] relativeToURL:url];
return model;
Expand All @@ -61,9 +53,27 @@ - (PluginModel *)mergeWith:(PluginModel *)other {
}

- (NSAttributedString *)attributedString {
NSMutableAttributedString* s = [NSMutableAttributedString new];
[s appendAttributedString:[[NSAttributedString alloc] initWithString:[self.displayName stringByAppendingString:@"\n"] attributes:@{NSFontAttributeName: [NSFont boldSystemFontOfSize:[NSFont systemFontSize]]}]];
[s appendAttributedString:[[NSAttributedString alloc] initWithString:self.pluginDescription attributes:@{NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSize]]}]];
NSMutableArray *stringsToJoin = [NSMutableArray new];
[stringsToJoin addObject:[[NSAttributedString alloc] initWithString:self.displayName attributes:@{NSFontAttributeName: [NSFont boldSystemFontOfSize:[NSFont systemFontSize]]}]];
if (self.pluginDescription.length) {
[stringsToJoin addObject:[[NSAttributedString alloc] initWithString:self.pluginDescription attributes:@{NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSize]]}]];
}
if (self.examples.count) {
NSMutableParagraphStyle *para = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
NSFont *font = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] toHaveTrait:NSItalicFontMask];
NSColor *color = [NSColor grayColor];
NSDictionary *attrs = @{NSFontAttributeName: font, NSForegroundColorAttributeName: color, NSParagraphStyleAttributeName: para};
NSAttributedString *s = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\"%@\"", [self.examples componentsJoinedByString:@"\" \""]] attributes:attrs];
[stringsToJoin addObject:s];
}

NSMutableAttributedString *s = [NSMutableAttributedString new];
for (NSAttributedString *a in stringsToJoin) {
[s appendAttributedString:a];
if (a != stringsToJoin.lastObject) {
[s appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
}
}
return s;
}

Expand Down
5 changes: 2 additions & 3 deletions PluginDirectory/generate_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Zips up all the bundles and adds them to `index.json`.
"""

import plistlib, zipfile, json, os
import zipfile, json, os

index = []
for filename in os.listdir('.'):
Expand All @@ -13,8 +13,7 @@
for f in files:
zipped.write(os.path.join(dir, f), os.path.join(dir, f))
zipped.close()
info = plistlib.readPlist(os.path.join(filename, 'Info.plist'))
info['name'] = name
info = json.load(open(os.path.join(filename, 'info.json')))
info['zip_url'] = name + ".zip"
index.append(info)
comment = "This index is automatically generated by generate_index.py"
Expand Down
2 changes: 1 addition & 1 deletion PluginDirectory/index.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"comment": "This index is automatically generated by generate_index.py", "plugins": [{"CFBundleDisplayName": "Pig latin <message>", "zip_url": "piglatin.zip", "Description": "Translates your message into Pig Latin.", "name": "piglatin"}, {"CFBundleDisplayName": "Say <message>", "zip_url": "say.zip", "Description": "Speaks your message out-loud.", "name": "say"}, {"CFBundleDisplayName": "Terminal", "zip_url": "terminal.zip", "Description": "Run a terminal command.", "IconPath": "/Applications/Utilities/Terminal.app/Contents/Resources/Terminal.icns", "name": "terminal"}, {"CFBundleDisplayName": "Weather <location>", "zip_url": "weather.zip", "Description": "Today's weather.", "name": "weather"}, {"CFBundleDisplayName": "Ask Wolfram Alpha <a question>", "zip_url": "wolfram-alpha.zip", "Description": "Search Wolfram|Alpha.", "name": "wolfram-alpha"}]}
{"comment": "This index is automatically generated by generate_index.py", "plugins": [{"examples": ["translate hello world into pig latin", "pig latin hello world"], "zip_url": "piglatin.zip", "displayName": "Pig Latin", "name": "piglatin", "description": "Translate a message into Pig Latin"}, {"examples": ["say good morning"], "zip_url": "say.zip", "displayName": "Say", "name": "say", "description": "Speak a message out loud."}, {"examples": ["rm -f *.py", "git push", "$ ping google.com"], "zip_url": "terminal.zip", "displayName": "Terminal", "name": "terminal", "description": "Run Terminal commands. If Finder is open, commands are run in the current folder."}, {"examples": ["weather brooklyn", "how's the weather in houston?"], "zip_url": "weather.zip", "displayName": "Weather", "name": "weather", "description": "View the forecast in Spotlight."}, {"zip_url": "websearch.zip", "displayName": "Web Search", "name": "websearch", "examples": ["google Apple stock", "g Apple stock", "search duck duck go for Flashlight", "ddg Flashlight", "image search for rubber ducks"]}, {"zip_url": "wolfram-alpha.zip", "displayName": "Wolfram|Alpha Search", "name": "wolfram-alpha", "examples": ["ask wolfram alpha 1 + 1", "wa first 10 prime numbers", "population of india"]}]}
10 changes: 0 additions & 10 deletions PluginDirectory/piglatin.bundle/Info.plist

This file was deleted.

6 changes: 6 additions & 0 deletions PluginDirectory/piglatin.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "piglatin",
"displayName": "Pig Latin",
"description": "Translate a message into Pig Latin",
"examples": ["translate hello world into pig latin", "pig latin hello world"]
}
Binary file modified PluginDirectory/piglatin.bundle/plugin.pyc
Binary file not shown.
Binary file modified PluginDirectory/piglatin.zip
Binary file not shown.
10 changes: 0 additions & 10 deletions PluginDirectory/say.bundle/Info.plist

This file was deleted.

6 changes: 6 additions & 0 deletions PluginDirectory/say.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "say",
"displayName": "Say",
"description": "Speak a message out loud.",
"examples": ["say good morning"]
}
Binary file modified PluginDirectory/say.bundle/plugin.pyc
Binary file not shown.
Binary file modified PluginDirectory/say.zip
Binary file not shown.
6 changes: 6 additions & 0 deletions PluginDirectory/terminal.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "terminal",
"displayName": "Terminal",
"description": "Run Terminal commands. If Finder is open, commands are run in the current folder.",
"examples": ["rm -f *.py", "git push", "$ ping google.com"]
}
Binary file modified PluginDirectory/terminal.zip
Binary file not shown.
10 changes: 0 additions & 10 deletions PluginDirectory/weather.bundle/Info.plist

This file was deleted.

6 changes: 6 additions & 0 deletions PluginDirectory/weather.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "weather",
"displayName": "Weather",
"description": "View the forecast in Spotlight.",
"examples": ["weather brooklyn", "how's the weather in houston?"]
}
Binary file modified PluginDirectory/weather.zip
Binary file not shown.
12 changes: 12 additions & 0 deletions PluginDirectory/websearch.bundle/examples.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
duck duck go search ~duckduckgoquery(query here)
search duck duck go for ~duckduckgoquery(query here)
ddg ~duckduckgoquery(query here)

google search ~googlequery(query here)
search the web for ~googlequery(query here)
g ~googlequery(query here)

image search for ~googleimagequery(query here)
show me images of ~googleimagequery(query here)
show me a picture of ~googleimagequery(query here)
gi ~googleimagequery(query here)
5 changes: 5 additions & 0 deletions PluginDirectory/websearch.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "websearch",
"displayName": "Web Search",
"examples": ["google Apple stock", "g Apple stock", "search duck duck go for Flashlight", "ddg Flashlight", "image search for rubber ducks"]
}
18 changes: 18 additions & 0 deletions PluginDirectory/websearch.bundle/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import urllib

def results(parsed, original_query):
search_specs = [
["Google", "~googlequery", "https://www.google.com/search?q="],
["Duck Duck Go", "~duckduckgoquery", "https://duckduckgo.com/?q="],
["Google Images", "~googleimagequery", "https://www.google.com/search?tbm=isch&q="]
]
for name, key, url in search_specs:
if key in parsed:
return {
"title": "Search {0} for '{1}'".format(name, parsed[key]),
"run_args": [url + urllib.quote_plus(parsed[key])]
}

def run(url):
import os
os.system('open "{0}"'.format(url))
Binary file added PluginDirectory/websearch.bundle/plugin.pyc
Binary file not shown.
Binary file added PluginDirectory/websearch.zip
Binary file not shown.
10 changes: 0 additions & 10 deletions PluginDirectory/wolfram-alpha.bundle/Info.plist

This file was deleted.

2 changes: 2 additions & 0 deletions PluginDirectory/wolfram-alpha.bundle/examples.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ walpha wa_query(population of india)
wa_query(what is the population of china)
wa_query(how many calories in a bagel) ?
wa_query(how far is it from bristol to liverpool) wolfram alpha
ask wolfram alpha for wa_query(the size of alaska) ?
wa wa_query(100th prime number)
5 changes: 5 additions & 0 deletions PluginDirectory/wolfram-alpha.bundle/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "wolfram-alpha",
"displayName": "Wolfram|Alpha Search",
"examples": ["ask wolfram alpha 1 + 1", "wa first 10 prime numbers", "population of india"]
}
Binary file modified PluginDirectory/wolfram-alpha.zip
Binary file not shown.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ Flashlight plugins are `.bundle` files in `~/Library/FlashlightPlugins`. They ha
- MyPlugin.bundle
- plugin.py
- examples.txt
- Info.plist
(create these with Xcode. Must contain 'CFBundleDisplayName' and 'Description' keys)
- Info.json
- key 'name' (string): name of the folder, without .bundle
- key 'displayName' (string)
- key 'description' (string)
- key 'examples' (array of strings): usage examples
```

`examples.txt` looks like this:
Expand Down

0 comments on commit 8aff87a

Please sign in to comment.