Jake.codes

BangLink

Friday, January 24, 2014

This is my take on SearchLink by Brett Terpstra and the Python port for Editorial by Ole Zorn. I wanted something for using in chat, not with Markdown. Along the way I fixed some problems/bugs (like iTunes searching).

See the BangLink Results for examples on how to use.

If you run in to trouble, you may need to install the python requests package. Try pip install requests and if that doesn’t work try easy_install requests.

OS X Service

Download and open to install then you can assign a keyboard shortcut for use when you have highlighted text.

Bookmarket for use with Pythonista

Create a new bookmark and change the url to this:

javascript:%20s%20=%20prompt('Enter%20search:',%20'');if%20(!s);if%20(s)%20location.href%20=%20'pythonista://BangLink?action=run&argv='+s+'&argv=safari';

Action for Drafts

Tap this link from iOS, just know you need to have BangLink.py in Pythonista for iPhone and iPad.

Python Script

# BangLink v0.3 ""by"" Jake Bilbrey
#
# BangLink is a fork of SearchLink by Brett Terpstra
# http://brettterpstra.com/projects/searchlink/
# and the Python vesion of which by Ole Zorn
# http://www.editorial-workflows.com/workflow/5872994651996160/qhw_Omf15jQ
#
# This is made to run as an OS X service or a Pythonista script
#
# For JavaScript bookmarklet
# javascript:%20s%20=%20prompt('Enter%20search:',%20'');if%20(!s);if%20(s)%20location.href%20=%20'pythonista://BangLink?action=run&argv='+s+'&argv=safari';
#
# For Drafts
# pythonista://BangLink?action=run&argv=[[draft]]&argv=drafts
import sys
import re
import urllib
import webbrowser
import requests
import json


# Config
country_code = 'US'
itunes_affiliate = '&at=1l3v3KV&ct=banglink'
amazon_partner = ["jakebilbrcom-20","1789","390957"]
custom_site_searches = [
    ('bt', 'brettterpstra.com'),
    ('md', 'www.macdrifter.com'),
    ('jb', 'jakebilbrey.com'),
    ('comix', 'www.comixology.com'),
    ('bg', 'bloopgroup.com'),
    ('imdb', 'imdb.com'),
    ('yt', 'youtube.com'),
    ('steam', 'store.steampowered.com')
]

# Search Functions
def google(terms):
    uri = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&filter=1&rsz=small&q=' + urllib.quote(terms)
    json_string = requests.get(uri, headers={'Referer': 'http://bretterpstra.com', 'User-Agent': 'BangLink (http://jtb.me)'}).text
    json_dict = json.loads(json_string)
    if json_dict.get('responseData', None):
        result = json_dict['responseData'].get('results', None)
        if not result:
            return None
        result = result[0]
        output_url = result['unescapedUrl']
        return output_url

def wiki(terms):
    uri = 'http://en.wikipedia.org/w/api.php?action=query&format=json&prop=info&inprop=url&titles=' + urllib.quote(terms)
    json_string = requests.get(uri, headers={'Referer': 'http://bretterpstra.com', 'User-Agent': 'BangLink (http://jtb.me)'}).text
    result = json.loads(json_string)
    if result:
        pages = result['query']['pages']
        first_page = pages[pages.keys()[0]]
        return first_page['fullurl']

def amazon_affiliatize(url, amazon_partner):
    if not amazon_partner:
        return url
    url_match = re.match(r'http:\/\/www.amazon.com\/(?:(.*?)\/)?dp\/([^\?]+)', url)
    if url_match:
        title = url_match.group(1)
        id_ = url_match.group(2)
        az_url = 'http://www.amazon.com/gp/product/%s/ref=as_li_ss_tl?ie=UTF8&camp=%s&creative=%s&creativeASIN=%s&linkCode=as2&tag=%s' % (id_, amazon_partner[1], amazon_partner[2], id_, amazon_partner[0])
        return az_url
    else:
        return url

def itunes(entity, terms, aff='', country_code='US'):
    url = 'http://itunes.apple.com/search?term=%s&entity=%s&country=%s' % (urllib.quote(terms), entity, country_code)
    json_string = requests.get(url).text
    json_dict = json.loads(json_string)
    if json_dict.get('resultCount') and json_dict.get('resultCount') > 0:
        result = json_dict['results'][0]
        if re.match(r'(mac|iPad)?(S|s)oftware',entity):
            output_url = result['trackViewUrl']
        elif re.match(r'(musicArtist|song|album|podcast)',entity):
            wrapper_type = result['wrapperType']
            if wrapper_type == 'track':
                output_url = result['trackViewUrl']
            elif wrapper_type == 'collection':
                output_url = result['collectionViewUrl']
            elif wrapper_type == 'artist':
                output_url = result['artistLinkUrl']
        return output_url + aff
    else:
        return None


# Commands and Functions
services = [
    ('g', 'google'),
    ('w', 'wikipedia'),
    ('a', 'amazon'),
    ('iart', 'musicArtist'),
    ('ialb', 'album'),
    ('isong', 'song'),
    ('iphone', 'software'),
    ('ipad', 'iPadSoftware'),
    ('mac', 'macSoftware'),
    ('pod','podcast')
]


# Parse and Call Search Functions
def bangLink(query):
    resultURL = ''
    for shortcut, searchFunction in services:
        service_identifier = '!%s' % shortcut
        if not service_identifier in query:
            continue
        query = (re.sub(service_identifier,'',query,count=1)).strip()
        
        if searchFunction == 'google':
            resultURL = google(query)
        elif searchFunction == 'wikipedia':
            resultURL = wiki(query)
        elif searchFunction == 'amazon':
            resultURL = amazon_affiliatize(google('site:amazon.com %s' % query), amazon_partner)
        elif searchFunction == 'musicArtist':
            resultURL = itunes('musicArtist', query, itunes_affiliate, country_code)
        elif searchFunction == 'album':
            resultURL = itunes('album', query, itunes_affiliate, country_code)
        elif searchFunction == 'song':
            resultURL = itunes('song', query, itunes_affiliate, country_code)
        elif searchFunction == 'software':
            resultURL = itunes('software', query, itunes_affiliate, country_code)
        elif searchFunction == 'iPadSoftware':
            resultURL = itunes('iPadSoftware', query, itunes_affiliate, country_code)
        elif searchFunction == 'macSoftware':
            resultURL = itunes('macSoftware', query, itunes_affiliate, country_code)
        elif searchFunction == 'podcast':
            resultURL = itunes('podcast', query, itunes_affiliate, country_code)
        break
    if resultURL == '':
        for shortcut, siteSearch in custom_site_searches:
            service_identifier = '!%s' % shortcut
            if not service_identifier in query:
                continue
            query = (re.sub(service_identifier,'',query,count=1)).strip()
            resultURL = google(siteSearch + ': ' + query)
    if resultURL == '':
        resultURL = 'https://duckduckgo.com/?q=' + urllib.quote(query)
            
    
    return resultURL


# Main

try:
    try:
        if sys.argv[2] == 'drafts':
            webbrowser.open('drafts://x-callback-url/create?text=' + bangLink(sys.argv[1]))
        elif sys.argv[2] == 'safari':
            webbrowser.open('safari-' + bangLink(sys.argv[1]))
    except:
        print bangLink(sys.argv[1])
except:
    print 'No input'

TextExpander Snipper

Create a new Shell Script snippet and paste this in:

#!/usr/bin/env python
# BangLink v0.3 ""by"" Jake Bilbrey
#
# BangLink is a fork of SearchLink by Brett Terpstra
# http://brettterpstra.com/projects/searchlink/
# and the Python vesion of which by Ole Zorn
# http://www.editorial-workflows.com/workflow/5872994651996160/qhw_Omf15jQ
#
# This is made to run as an OS X service or a Pythonista script
#
import sys
import re
import urllib
import webbrowser
import requests
import json


# Config
country_code = 'US'
itunes_affiliate = '&at=1l3v3KV&ct=banglink'
amazon_partner = ["jakebilbrcom-20","1789","390957"]
custom_site_searches = [
    ('bt', 'brettterpstra.com'),
    ('md', 'www.macdrifter.com'),
    ('jb', 'jakebilbrey.com'),
    ('comix', 'www.comixology.com'),
    ('bg', 'bloopgroup.com'),
    ('imdb', 'imdb.com'),
    ('yt', 'youtube.com'),
    ('steam', 'store.steampowered.com')
]

# Search Functions
def google(terms):
    uri = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&filter=1&rsz=small&q=' + urllib.quote(terms)
    json_string = requests.get(uri, headers={'Referer': 'http://bretterpstra.com', 'User-Agent': 'BangLink (http://jtb.me)'}).text
    json_dict = json.loads(json_string)
    if json_dict.get('responseData', None):
        result = json_dict['responseData'].get('results', None)
        if not result:
            return None
        result = result[0]
        output_url = result['unescapedUrl']
        return output_url

def wiki(terms):
    uri = 'http://en.wikipedia.org/w/api.php?action=query&format=json&prop=info&inprop=url&titles=' + urllib.quote(terms)
    json_string = requests.get(uri, headers={'Referer': 'http://bretterpstra.com', 'User-Agent': 'BangLink (http://jtb.me)'}).text
    result = json.loads(json_string)
    if result:
        pages = result['query']['pages']
        first_page = pages[pages.keys()[0]]
        return first_page['fullurl']

def amazon_affiliatize(url, amazon_partner):
    if not amazon_partner:
        return url
    url_match = re.match(r'http:\/\/www.amazon.com\/(?:(.*?)\/)?dp\/([^\?]+)', url)
    if url_match:
        title = url_match.group(1)
        id_ = url_match.group(2)
        az_url = 'http://www.amazon.com/gp/product/%s/ref=as_li_ss_tl?ie=UTF8&camp=%s&creative=%s&creativeASIN=%s&linkCode=as2&tag=%s' % (id_, amazon_partner[1], amazon_partner[2], id_, amazon_partner[0])
        return az_url
    else:
        return url

def itunes(entity, terms, aff='', country_code='US'):
    url = 'http://itunes.apple.com/search?term=%s&entity=%s&country=%s' % (urllib.quote(terms), entity, country_code)
    json_string = requests.get(url).text
    json_dict = json.loads(json_string)
    if json_dict.get('resultCount') and json_dict.get('resultCount') > 0:
        result = json_dict['results'][0]
        if re.match(r'(mac|iPad)?(S|s)oftware',entity):
            output_url = result['trackViewUrl']
        elif re.match(r'(musicArtist|song|album|podcast)',entity):
            wrapper_type = result['wrapperType']
            if wrapper_type == 'track':
                output_url = result['trackViewUrl']
            elif wrapper_type == 'collection':
                output_url = result['collectionViewUrl']
            elif wrapper_type == 'artist':
                output_url = result['artistLinkUrl']
        return output_url + aff
    else:
        return None


# Commands and Functions
services = [
    ('g', 'google'),
    ('w', 'wikipedia'),
    ('a', 'amazon'),
    ('iart', 'musicArtist'),
    ('ialb', 'album'),
    ('isong', 'song'),
    ('iphone', 'software'),
    ('ipad', 'iPadSoftware'),
    ('mac', 'macSoftware'),
    ('pod','podcast')
]


# Parse and Call Search Functions
def bangLink(query):
    resultURL = ''
    for shortcut, searchFunction in services:
        service_identifier = '!%s' % shortcut
        if not service_identifier in query:
            continue
        query = (re.sub(service_identifier,'',query,count=1)).strip()
        
        if searchFunction == 'google':
            resultURL = google(query)
        elif searchFunction == 'wikipedia':
            resultURL = wiki(query)
        elif searchFunction == 'amazon':
            resultURL = amazon_affiliatize(google('site:amazon.com %s' % query), amazon_partner)
        elif searchFunction == 'musicArtist':
            resultURL = itunes('musicArtist', query, itunes_affiliate, country_code)
        elif searchFunction == 'album':
            resultURL = itunes('album', query, itunes_affiliate, country_code)
        elif searchFunction == 'song':
            resultURL = itunes('song', query, itunes_affiliate, country_code)
        elif searchFunction == 'software':
            resultURL = itunes('software', query, itunes_affiliate, country_code)
        elif searchFunction == 'iPadSoftware':
            resultURL = itunes('iPadSoftware', query, itunes_affiliate, country_code)
        elif searchFunction == 'macSoftware':
            resultURL = itunes('macSoftware', query, itunes_affiliate, country_code)
        elif searchFunction == 'podcast':
            resultURL = itunes('podcast', query, itunes_affiliate, country_code)
        break
    if resultURL == '':
        for shortcut, siteSearch in custom_site_searches:
            service_identifier = '!%s' % shortcut
            if not service_identifier in query:
                continue
            query = (re.sub(service_identifier,'',query,count=1)).strip()
            resultURL = google(siteSearch + ': ' + query)
    if resultURL == '':
        resultURL = 'https://duckduckgo.com/?q=' + urllib.quote(query)
            
    
    return resultURL


# Main

try:
    sys.stdout.write(bangLink("%filltext:name=banglink:default=!g JakeBilbrey%"))
except:
    sys.stdout.write('No input')