Created
June 30, 2015 23:44
-
-
Save bluetech/f9aa4ede5a25c765c6e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2 | |
"""Display the error message for an Oracle error either from the internet | |
or from the cache db, based on the error code ("the query") you get when | |
confronted with the error.""" | |
import sys, os, re, urllib2, urlparse, anydbm | |
from BeautifulSoup import BeautifulSoup | |
BASE_URL = "http://download.oracle.com/docs/cd/B19306_01/server.102/b14219/" | |
TOC_URL = BASE_URL + "toc.htm" | |
DEFAULT_PREFIX = "ORA" | |
CACHE_PATH = "oraerr.cache" | |
db = anydbm.open(CACHE_PATH, "c") | |
def get_error_message(query): | |
query = tidy_query(query) | |
return db.get(query) or fetch_error_message(query) | |
def tidy_query(query): | |
# turn a query into the canonical form, or raise an error if not possible. | |
if query.isdigit(): | |
errprefix, errnum = DEFAULT_PREFIX, query | |
else: | |
errprefix, _, errnum = query.partition("-") | |
if not errprefix.isalpha(): | |
raise ValueError("error prefix must be alphabetical") | |
if not errnum or not errnum.isdigit() or len(str(int(errnum))) > 5: | |
raise ValueError("error number can't be more then five digits") | |
return "%s-%.5d" % (errprefix.upper(), int(errnum)) | |
def fetch_error_message(query): | |
url = find_query_url(query) | |
if not url: | |
raise ValueError("the error you requested does not exist on the server") | |
soup = BeautifulSoup(get_html(url)) | |
try: | |
errmsg = strip_tags(soup.find("a", id=query).parent.parent.parent.renderContents()) | |
except AttributeError: | |
if not soup.find("a", id=query): | |
return None | |
else: | |
raise IOError("html page layout is irregular") | |
db[query] = errmsg | |
return errmsg | |
def find_query_url(query): | |
# Go to the index page, find the section with the | |
# query prefix and range, and return its url. | |
toc = BeautifulSoup(get_html(TOC_URL)) | |
errprefix, errnum = query.split("-") | |
rangere = re.compile(r"%s-(\d+) to %s-(\d+)" % (errprefix, errprefix)) | |
for h2 in toc("h2", "tocheader"): | |
s = rangere.search(h2.a.renderContents()) | |
if s and s.group(1) <= errnum <= s.group(2): | |
return urlparse.urljoin(BASE_URL, h2.a["href"]) | |
return None | |
def get_html(url): | |
try: | |
return urllib2.urlopen(url).read() | |
except urllib2.URLError: | |
raise IOError("could not fetch data from server") | |
def strip_tags(html): | |
return re.sub("\n+", "\n", re.sub("<[^>]*>", "", html)).strip() | |
if __name__ == "__main__": | |
APPNAME = os.path.basename(__file__) | |
if len(sys.argv) < 2: | |
print >> sys.stderr, "usage:", APPNAME, "<prefix>-<number>" | |
print >> sys.stderr, "default prefix:", DEFAULT_PREFIX | |
sys.exit(2) | |
try: | |
print >> sys.stderr, "fetching error message...\n" | |
print get_error_message(sys.argv[1]) | |
except (ValueError, IOError), e: | |
print >> sys.stderr, "%s: error: %s" % (APPNAME, e) | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment