Goldendict: succeed in hacking urban dictionary

Created on 22 Dec 2013  路  7Comments  路  Source: goldendict/goldendict

basically call a python script to parse the text;
set up steps:
dictionaries(F3)-->program->add->type:html->Name: Urban dictionary-->command line python theFile.py where theFile.py has the following contents

Done!
ref and inspired by: http://www.cnblogs.com/skyhacker/archive/2012/02/10/2346111.html

!/usr/bin/env python

coding:utf-8

import urllib2, re
import sys
reload(sys)

sys.setdefaultencoding('utf-8')
html = urllib2.urlopen("http://www.urbandictionary.com/define.php?term="+sys.argv[1]).read()

try:
start = re.search('',html).end()
end = re.search('',html).start()
except AttributeError:
sys.exit(0)

head = """


"""
html = head + html[start:end]
print html

Most helpful comment

@imd Bro thank you for the fix but the code above doesnt work with python 3.5

I modified as below for python 3.5:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys
import urllib.parse
import urllib.request
import codecs
from imp import reload
reload(sys)


# https://github.com/narfman0/helga-lingo

import json, re, urllib
def ud(*args):
    """ Define from urban dictionary """
    if len(args) == 0:
        return u'You need to give me a term to look up.'
    term, index = parse_args(' '.join(args))
    try:
        data = execute_request(term)
        total = len(data['list'])

        # hack to ignore parameter 'index', print out all definitions
        # defn = define(term, data, index)
        # example = define(term, data, index, 'example')
        # return '{0} e.g.: {1} [{2}/{3}]'.format(defn, example, index, total)
        if total == 0: sys.exit(0)
        # %20 rendered by urllib.quote
        result = urllib.parse.unquote(term) + ' (total definitions: ' + str(total) + ')' +  '<br><hr>'
        # for index in range(1, min(5, total)+1):
        for index in range(1, total+1):
            defn = define(term, data, index).replace("\n","<br>")
            example = define(term, data, index, 'example').replace("\n","<br>")
            result += '<b>{2}. </b>{0}<br><font color=grey>{1}</font><br><br>'.format(defn, example, index)
        return result
    # hack end
    except Exception as e:
        return 'Urban Dictionary returned exception for ' + term + ":" + str(e)

def execute_request(term):
    """ Invoke API to retrieve json hopefully representing term """
    api_url = 'http://api.urbandictionary.com/v0/define?term='
    # use requests
    # import requests
    # response = requests.get(api_url + term)
    # if response.status_code != 200:
    #     raise Exception('Error status code returned: ' + str(response.status_code))
    # response_json = json.loads(response.content)
    # if not response_json:
    #     raise Exception('Response falsy for given term: ' + term)
    # return response_json

    # or use urllib2

    req = urllib.request.Request(api_url + term)
    handler = urllib.request.urlopen(req)
    status_code = handler.getcode()
    # handler.headers.getheader('content-type')
    content = handler.read().decode('utf-8')
    if status_code != 200:
        raise Exception('Error status code returned: ' + str(status_code))
    response_json = json.loads(content)
    if not response_json:
        raise Exception('Response falsy for given term: ' + term)
    return response_json

def define(term, data, index=1, action='definition'):
    """ Retrieve the definition for the term """
    return data['list'][index-1][action]

def parse_args(args):
    """ Parse arguments to extract desired search term and index in def list """
    index = 1
    match = re.search(r'\d+$', args)
    if match is not None:
        index = int(match.group())
        args=args[:-len(str(index))-1]
    term = urllib.parse.quote(args)
    return (term, index)

if __name__ == "__main__":
    result = ud(sys.argv[1])
    print (result)

PS: for folks that meet the Error : ud(sys.argv[1]) IndexError: list index out of range

you need to add %GDWORD% after command line

ex:dictionaries(F3)-->program->add->type:html->Name: Urban dictionary-->command line python theFile.py %GDWORD%

All 7 comments

Is this hack still working for you ? Here, I get "exit code 255".
If I try in a terminal ($ python theFile.py hello), I don't get anything : result neither error.

Hi Iaspic, the website has changed its front-end. Instead I switched to api call. Here are the currently working codes:

!/usr/bin/env python

-_- coding: utf-8 -_-

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

https://github.com/narfman0/helga-lingo

import json, re, urllib, urllib2
def ud(*args):
""" Define from urban dictionary """
if len(args) == 0:
return u'You need to give me a term to look up.'
term, index = parse_args(' '.join(args))
try:
data = execute_request(term)
total = len(data['list'])

    # hack to ignore parameter 'index', print out all definitions
    # defn = define(term, data, index)
    # example = define(term, data, index, 'example')
    # return '{0} e.g.: {1} [{2}/{3}]'.format(defn, example, index, total)
    if total == 0: sys.exit(0)
    # %20 rendered by urllib.quote
    result = urllib.unquote(term) + ' (total definitions: ' + str(total) + ')' +  '<br><hr>'
    # for index in range(1, min(5, total)+1):
    for index in range(1, total+1):
        defn = define(term, data, index).replace("\n","<br>")
        example = define(term, data, index, 'example').replace("\n","<br>")
        result += '<b>{2}. </b>{0}<br><font color=grey>{1}</font><br><br>'.format(defn, example, index)
    return result
    # hack end
except Exception as e:
    return unicode('Urban Dictionary returned exception for ' + term + ":" + str(e))

def execute_request(term):
""" Invoke API to retrieve json hopefully representing term """
api_url = 'http://api.urbandictionary.com/v0/define?term='
# use requests
# import requests
# response = requests.get(api_url + term)
# if response.status_code != 200:
# raise Exception('Error status code returned: ' + str(response.status_code))
# response_json = json.loads(response.content)
# if not response_json:
# raise Exception('Response falsy for given term: ' + term)
# return response_json

# or use urllib2
req = urllib2.Request(api_url + term)
handler = urllib2.urlopen(req)
status_code = handler.getcode()
# handler.headers.getheader('content-type')
content = handler.read()
if status_code != 200:
    raise Exception('Error status code returned: ' + str(status_code))
response_json = json.loads(content)
if not response_json:
    raise Exception('Response falsy for given term: ' + term)
return response_json

def define(term, data, index=1, action='definition'):
""" Retrieve the definition for the term """
return data['list'][index-1][action]

def parse_args(args):
""" Parse arguments to extract desired search term and index in def list """
index = 1
match = re.search(r'd+$', args)
if match is not None:
index = int(match.group())
args=args[:-len(str(index))-1]
term = urllib.quote(args)
return (term, index)

if name == "main":
result = ud(sys.argv[1])
print result

@jerryzhujian9 sorry, your code is corrupted
Could you write this code between ``` symbols?

I fixed the formatting and tested it.

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys
reload(sys)

sys.setdefaultencoding('utf-8')  

# https://github.com/narfman0/helga-lingo

import json, re, urllib, urllib2
def ud(*args):
    """ Define from urban dictionary """
    if len(args) == 0:
        return u'You need to give me a term to look up.'
    term, index = parse_args(' '.join(args))
    try:
        data = execute_request(term)
        total = len(data['list'])

        # hack to ignore parameter 'index', print out all definitions
        # defn = define(term, data, index)
        # example = define(term, data, index, 'example')
        # return '{0} e.g.: {1} [{2}/{3}]'.format(defn, example, index, total)
        if total == 0: sys.exit(0)
        # %20 rendered by urllib.quote
        result = urllib.unquote(term) + ' (total definitions: ' + str(total) + ')' +  '<br><hr>'
        # for index in range(1, min(5, total)+1):
        for index in range(1, total+1):
            defn = define(term, data, index).replace("\n","<br>")
            example = define(term, data, index, 'example').replace("\n","<br>")
            result += '<b>{2}. </b>{0}<br><font color=grey>{1}</font><br><br>'.format(defn, example, index)
        return result
    # hack end
    except Exception as e:
        return unicode('Urban Dictionary returned exception for ' + term + ":" + str(e))

def execute_request(term):
    """ Invoke API to retrieve json hopefully representing term """
    api_url = 'http://api.urbandictionary.com/v0/define?term='
    # use requests
    # import requests
    # response = requests.get(api_url + term)
    # if response.status_code != 200:
    #     raise Exception('Error status code returned: ' + str(response.status_code))
    # response_json = json.loads(response.content)
    # if not response_json:
    #     raise Exception('Response falsy for given term: ' + term)
    # return response_json

    # or use urllib2
    req = urllib2.Request(api_url + term)
    handler = urllib2.urlopen(req)
    status_code = handler.getcode()
    # handler.headers.getheader('content-type')
    content = handler.read()
    if status_code != 200:
        raise Exception('Error status code returned: ' + str(status_code))
    response_json = json.loads(content)
    if not response_json:
        raise Exception('Response falsy for given term: ' + term)
    return response_json

def define(term, data, index=1, action='definition'):
    """ Retrieve the definition for the term """
    return data['list'][index-1][action]

def parse_args(args):
    """ Parse arguments to extract desired search term and index in def list """
    index = 1
    match = re.search(r'\d+$', args)
    if match is not None:
        index = int(match.group())
        args=args[:-len(str(index))-1]
    term = urllib.quote(args)
    return (term, index)

if __name__ == "__main__":
    result = ud(sys.argv[1])
    print result

Omg, thank you very much. It works great. I use it on windows

@imd Bro thank you for the fix but the code above doesnt work with python 3.5

I modified as below for python 3.5:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys
import urllib.parse
import urllib.request
import codecs
from imp import reload
reload(sys)


# https://github.com/narfman0/helga-lingo

import json, re, urllib
def ud(*args):
    """ Define from urban dictionary """
    if len(args) == 0:
        return u'You need to give me a term to look up.'
    term, index = parse_args(' '.join(args))
    try:
        data = execute_request(term)
        total = len(data['list'])

        # hack to ignore parameter 'index', print out all definitions
        # defn = define(term, data, index)
        # example = define(term, data, index, 'example')
        # return '{0} e.g.: {1} [{2}/{3}]'.format(defn, example, index, total)
        if total == 0: sys.exit(0)
        # %20 rendered by urllib.quote
        result = urllib.parse.unquote(term) + ' (total definitions: ' + str(total) + ')' +  '<br><hr>'
        # for index in range(1, min(5, total)+1):
        for index in range(1, total+1):
            defn = define(term, data, index).replace("\n","<br>")
            example = define(term, data, index, 'example').replace("\n","<br>")
            result += '<b>{2}. </b>{0}<br><font color=grey>{1}</font><br><br>'.format(defn, example, index)
        return result
    # hack end
    except Exception as e:
        return 'Urban Dictionary returned exception for ' + term + ":" + str(e)

def execute_request(term):
    """ Invoke API to retrieve json hopefully representing term """
    api_url = 'http://api.urbandictionary.com/v0/define?term='
    # use requests
    # import requests
    # response = requests.get(api_url + term)
    # if response.status_code != 200:
    #     raise Exception('Error status code returned: ' + str(response.status_code))
    # response_json = json.loads(response.content)
    # if not response_json:
    #     raise Exception('Response falsy for given term: ' + term)
    # return response_json

    # or use urllib2

    req = urllib.request.Request(api_url + term)
    handler = urllib.request.urlopen(req)
    status_code = handler.getcode()
    # handler.headers.getheader('content-type')
    content = handler.read().decode('utf-8')
    if status_code != 200:
        raise Exception('Error status code returned: ' + str(status_code))
    response_json = json.loads(content)
    if not response_json:
        raise Exception('Response falsy for given term: ' + term)
    return response_json

def define(term, data, index=1, action='definition'):
    """ Retrieve the definition for the term """
    return data['list'][index-1][action]

def parse_args(args):
    """ Parse arguments to extract desired search term and index in def list """
    index = 1
    match = re.search(r'\d+$', args)
    if match is not None:
        index = int(match.group())
        args=args[:-len(str(index))-1]
    term = urllib.parse.quote(args)
    return (term, index)

if __name__ == "__main__":
    result = ud(sys.argv[1])
    print (result)

PS: for folks that meet the Error : ud(sys.argv[1]) IndexError: list index out of range

you need to add %GDWORD% after command line

ex:dictionaries(F3)-->program->add->type:html->Name: Urban dictionary-->command line python theFile.py %GDWORD%

@NhatQuangDau I have to modify the last line to sys.stdout.buffer.write(result.encode('utf-8')) due to encoding issue: locale.getpreferredencoding() gives me cp1252. BTW, I live on Windows 10 1703 64bit, Python3.

refs:
https://stackoverflow.com/questions/25127673/how-to-print-utf-8-to-console-with-python-3-4-windows-8

Was this page helpful?
0 / 5 - 0 ratings

Related issues

embar- picture embar-  路  3Comments

bdfish picture bdfish  路  8Comments

bcdavasconcelos picture bcdavasconcelos  路  5Comments

Spirituaway picture Spirituaway  路  4Comments

gitbuh1 picture gitbuh1  路  8Comments