Deprecated: Return type of I::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 62

Deprecated: Return type of I::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 91

Deprecated: Return type of I::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 71

Deprecated: Return type of I::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 101

Deprecated: Return type of I::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 53

Deprecated: Return type of Collection::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/collection.php on line 80

Deprecated: parse_str(): Passing null to parameter #1 ($string) of type string is deprecated in /home/public/kirby/toolkit/lib/url.php on line 135
One Tap Less | Search in Apps with Custom !bangs

Search in Apps with Custom !bangs

Hey you! Check the update for this action here.

I’ve been dumping Google for good lately and you can read an overview of my current scenario in my recent AppStorm article. But when you’re on iOS, there’s much more to search than relying on a DuckDuckGo shortcut on Launch Center Pro.

At first, I thought it would be cool to create a Pythonista script which would identify a snippet in front of my query and lead me to the proper service. If you think wisely, DuckDuckGo already does that with its !bangs and offers a myriad of services to look into. So what’s the point? Many apps offer search from their url schemes, such as Fantastical, Due and 1Password. And you can search on any of them using a single Drafts action and a Pythonista script.

from webbrowser import open
from urllib import quote

query = sys.argv[1]

#Web Services
stackoverflow = '!s '
wikipedia = '!w '
macupdate = '!mac '
appshopper = '!app '
imdb = '!imdb '
amazon = '!amaz '
wolframalpha = '!wolf '
reddit = '!red '
alternativeto = '!to '
hackernews = '!hack '
merriamwebster = '!def '

#Apps
onepassword = '!op '
wikipanion = '!wiki '
tweetbot = '!tb '
terminology = '!te '
imdbapp = '!movie '
articles = '!art '
twitterrific = '!twi '
rdio = '!rd '
fantastical = '!day '
due = '!due '
wolframapp = '!wol '
appstore = '!store '

if stackoverflow in query:  
    open('safari-http://stackoverflow.com/search?q=' + quote(query.replace(stackoverflow,''))) #Stack Overflow
elif wikipedia in query:
    open('safari-https://en.wikipedia.org/w/index.php?search=' + quote(query.replace(wikipedia,'')) + '&title=Special%3ASearch') #Wikipedia
elif macupdate in query:
    open('safari-https://www.macupdate.com/find/mac/' + quote(query.replace(macupdate,''))) #MacUpdate
elif appshopper in query:
    open('safari-http://appshopper.com/search/?search=' + quote(query.replace(appshopper,''))) #AppShopper
elif imdb in query:
    open('safari-http://www.imdb.com/find?q=' + quote(query.replace(imdb,'')) + '&s=all') #IMDB
elif amazon in query:
    open('safari-http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=' + quote(query.replace(amazon,''))) #Amazon
elif wolframalpha in query:
    open('safari-http://www.wolframalpha.com/input/?i=' + quote(query.replace(wolframalpha,''))) #Wolfram|Alpha
elif reddit in query:
    open('safari-http://www.reddit.com/r/search/search?q=' + quote(query.replace(reddit,''))) #Reddit
elif alternativeto in query:
    open('safari-http://alternativeto.net/SearchResult.aspx?search=' + quote(query.replace(alternativeto,''))) #AlternativeTo
elif hackernews in query:
    open('safari-https://www.hnsearch.com/search#request/all&q=' + quote(query.replace(hackernews,'')) + '&start=0') #Hacker News
elif merriamwebster in query:
    open('safari-http://www.merriam-webster.com/dictionary/' + quote(query.replace(merriamwebster,''))) #Merriam-Webster
elif onepassword in query:
    open('onepassword://search/' + quote(query.replace(onepassword,''))) #1Password
elif wikipanion in query:
    open('wikipanion:///' + quote(query.replace(wikipanion,''))) #Wikipanion
elif tweetbot in query:
    open('tweetbot:///search?query=' + quote(query.replace(tweetbot,''))) #Tweetbot
elif terminology in query:
    open('terminology://x-callback-url/lookup?text=' + quote(query.replace(terminology,''))) #Terminology
elif imdbapp in query:
    open('imdb:///find?q=' + quote(query.replace(imdbapp,''))) #IMDB app
elif articles in query:
    open('x-articles://?search=' + quote(query.replace(articles,''))) #Articles
elif twitterrific in query:
    open('twitterrific:///search?q=' + quote(query.replace(twitterrific,''))) #Twitterrific
elif rdio in query:
    open('rdio://search/' + quote(query.replace(rdio,''))) #Rdio
elif fantastical in query:
    open('fantastical://search?query=' + quote(query.replace(fantastical,''))) #Fantastical
elif due in query:
    open('due://x-callback-url/search?query=' + quote(query.replace(due,''))) #Due
elif wolframapp in query:
    open('wolframalpha:///?i=' + quote(query.replace(wolframapp,''))) #Wolfram|Alpha app
elif appstore in query:
    open('http://phobos.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=' + quote(query.replace(appstore,''))) #AppStore
else:
    open('safari-https://duckduckgo.com/?q=' + quote(query)) #Falls back on DuckDuckGo

The code is long, but self-explanatory. It covers many services and apps and you should trim it down to only support services and apps you actually use. The first part is where you can customize which !bang opens which service. Change them as you want, but I recommend that you keep the blank space in the end to avoid conflicts later on.

The second part is a long if, starting with StackOverflow, which you can replace for another service to hold the if tag. We have several elif for our remaining searches and an else fall back into DuckDuckGo if there are no matches.

I made a very slim list for myself, containing StackOverflow, MacUpdate, Hacker News, 1Password, Articles, Twitterrific, IMDB, Due, Wolfram|Alpha and the App Store. Here’s my personal final script:

from webbrowser import open
from urllib import quote

query = sys.argv[1]

#Web Services
stackoverflow = '!py '
macupdate = '!mac '
hackernews = '!hack '

#Apps
onepassword = '!op '
imdb = '!imdb '
articles = '!w '
twitterrific = '!tw '
due = '!due '
wolframapp = '!wolf '
appstore = '!app '

if stackoverflow in query:  
    open('safari-http://stackoverflow.com/search?q=' + quote(query.replace(stackoverflow,''))) #Stack Overflow
elif macupdate in query:
    open('safari-https://www.macupdate.com/find/mac/' + quote(query.replace(macupdate,''))) #MacUpdate
elif hackernews in query:
    open('safari-https://www.hnsearch.com/search#request/all&q=' + quote(query.replace(hackernews,'')) + '&start=0') #Hacker News
elif onepassword in query:
    open('onepassword://search/' + quote(query.replace(onepassword,''))) #1Password
elif imdb in query:
    open('imdb:///find?q=' + quote(query.replace(imdb,''))) #IMDB
elif articles in query:
    open('x-articles://?search=' + quote(query.replace(articles,''))) #Articles
elif twitterrific in query:
    open('twitterrific:///search?q=' + quote(query.replace(twitterrific,''))) #Twitterrific
elif due in query:
    open('due://x-callback-url/search?query=' + quote(query.replace(due,''))) #Due
elif wolframapp in query:
    open('wolframalpha:///?i=' + quote(query.replace(wolframapp,''))) #Wolfram|Alpha
elif appstore in query:
    open('http://phobos.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=' + quote(query.replace(appstore,''))) #AppStore
else:
    open('safari-https://duckduckgo.com/?q=' + quote(query)) #Falls back on DuckDuckGo

Trigger this script from Drafts or Launch Center Pro with the actions below:

Launch Center Pro:

pythonista://BangSearch?action=run&argv=[prompt:search query]

Drafts:

pythonista://BangSearch?action=run&argv=[[draft]]

Happy searching.