# HG changeset patch
# User catherine@cordelia
# Date 1246620760 14400
# Node ID ea6d35cb6c73216ae7f84e8dbe09cdba746fc227
# Parent 5e98e7917de887cc042d162343eb14a6f86d4fcd
images work, except brackets get escaped
diff -r 5e98e7917de8 -r ea6d35cb6c73 docs/source/index.rst
--- a/docs/source/index.rst Tue Jun 02 07:42:09 2009 -0400
+++ b/docs/source/index.rst Fri Jul 03 07:32:40 2009 -0400
@@ -5,6 +5,8 @@
Welcome to SQLPython's documentation!
=====================================
+Dayton *Dynamic* Languages Group is **awesome**
+
Contents:
.. toctree::
diff -r 5e98e7917de8 -r ea6d35cb6c73 sqlpython/imagedetect.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sqlpython/imagedetect.py Fri Jul 03 07:32:40 2009 -0400
@@ -0,0 +1,45 @@
+# Small utilities for detecting common image types based on the first
+# few bytes of their content.
+
+# by Ole Laursen, sponsored by IOLA 2009
+
+def is_jpg(data):
+ """True if data is the first 11 bytes of a JPEG file."""
+ return data[:4] == '\xff\xd8\xff\xe0' and data[6:11] == 'JFIF\0'
+
+def is_png(data):
+ """True if data is the first 8 bytes of a PNG file."""
+ return data[:8] == '\x89PNG\x0d\x0a\x1a\x0a'
+
+def is_tiff(data):
+ """True if data is the first 4 bytes of a TIFF file."""
+ return data[:4] == 'MM\x00\x2a' or data[:4] == 'II\x2a\x00'
+
+def is_gif(data):
+ """True if data is the first 4 bytes of a GIF file."""
+ return data[:4] == 'GIF8'
+
+def extension_from_data(data):
+ """Returns extension (like '.jpg') from first 11 bytes of image data.
+
+ An empty string is returned if no match is found."""
+ if is_jpg(data):
+ return ".jpg"
+ elif is_png(data):
+ return ".png"
+ elif is_tiff(data):
+ return ".tif"
+ elif is_gif(data):
+ return ".gif"
+
+ return ''
+
+def extension_from_file(path):
+ """Returns extension (like '.jpg') based on content of image file at path.
+
+ An empty string is returned if no match is found."""
+ f = file(path, 'r')
+ ext = extension_from_data(f.read(11))
+ f.close()
+ return ext
+
diff -r 5e98e7917de8 -r ea6d35cb6c73 sqlpython/output_templates.py
--- a/sqlpython/output_templates.py Tue Jun 02 07:42:09 2009 -0400
+++ b/sqlpython/output_templates.py Fri Jul 03 07:32:40 2009 -0400
@@ -41,7 +41,7 @@
- Value
+ Value
|
diff -r 5e98e7917de8 -r ea6d35cb6c73 sqlpython/sqlpyPlus.py
--- a/sqlpython/sqlpyPlus.py Tue Jun 02 07:42:09 2009 -0400
+++ b/sqlpython/sqlpyPlus.py Fri Jul 03 07:32:40 2009 -0400
@@ -23,12 +23,13 @@
- catherinedevlin.blogspot.com May 31, 2006
"""
-import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion, datetime, pickle, binascii, subprocess
+import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion, datetime, pickle, binascii, subprocess, time, itertools
from cmd2 import Cmd, make_option, options, Statekeeper, Cmd2TestCase
from output_templates import output_templates
from metadata import metaqueries
from plothandler import Plot
from sqlpython import Parser
+import imagedetect
import warnings
warnings.filterwarnings('ignore', 'BaseException.message', DeprecationWarning)
try:
@@ -281,6 +282,41 @@
return lineNum, line, offset
lineNum += 1
offset -= len(line)
+
+class BlobDisplayer(object):
+ start_timestamp = int(time.time())
+ folder_name = 'sqlpython_blob_store_%d' % start_timestamp
+ file_index = itertools.count()
+ def folder_ok(self):
+ if not os.access(self.folder_name, os.F_OK):
+ try:
+ os.mkdir(self.folder_name)
+ readme = open(os.path.join(self.folder_name, 'README.txt'),'w')
+ readme.write('''
+ Temporary files for display of BLOBs from within
+ sqlpython. Delete when sqlpython is closed.''')
+ readme.close()
+ except:
+ return False
+ return True
+ def __init__(self, blob):
+ self.url = ''
+ self.timestamp = time.time()
+ self.blob = blob.read()
+ self.extension = imagedetect.extension_from_data(self.blob)
+ if self.folder_ok():
+ self.file_name = '%s/blob%d%s' % (
+ os.path.join(os.getcwd(), self.folder_name),
+ self.file_index.next(), self.extension)
+ self.url = 'file://%s' % self.file_name
+ outfile = open(self.file_name, 'wb')
+ outfile.write(self.blob)
+ outfile.close()
+ def __str__(self):
+ return '(BLOB at %s)' % self.url
+ def html(self):
+ return '' % (
+ self.url, self.url)
class sqlpyPlus(sqlpython.sqlpython):
defaultExtension = 'sql'
@@ -449,7 +485,6 @@
self.colnames = [d[0] for d in self.curs.description]
if outformat in output_templates:
self.colnamelen = max(len(colname) for colname in self.colnames)
- self.coltypes = [d[1] for d in self.curs.description]
result = output_templates[outformat].generate(formattedForSql=self.formattedForSql, **self.__dict__)
elif outformat == '\\t': # transposed
rows = [self.colnames]
@@ -668,7 +703,7 @@
return
total_len -= len(rset)
self.pystate['r'][i] = []
-
+
def do_select(self, arg, bindVarsIn=None, terminator=None):
"""Fetch rows from a table.
@@ -698,6 +733,12 @@
else: # this is an ugly workaround for the evil paramstyle curse upon DB-API2
self.curs.execute(self.querytext)
self.rows = self.curs.fetchmany(min(self.maxfetch, (rowlimit or self.maxfetch)))
+ self.coltypes = [d[1] for d in self.curs.description]
+ if cx_Oracle.BLOB in self.coltypes:
+ self.rows = [
+ [((coltype == cx_Oracle.BLOB) and BlobDisplayer(datum)) or datum
+ for (datum, coltype) in zip(row, self.coltypes)]
+ for row in self.rows]
self.rc = len(self.rows)
if self.rc != 0:
resultset = ResultSet()