PageRenderTime 55ms CodeModel.GetById 1ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/datatypes/images.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 348 lines | 254 code | 62 blank | 32 comment | 8 complexity | ad3dc532df84e93a9d26c8aa2393d0da MD5 | raw file
  1"""
  2Image classes
  3"""
  4
  5import data
  6import logging
  7from galaxy.datatypes.binary import Binary
  8from galaxy.datatypes.metadata import MetadataElement
  9from galaxy.datatypes import metadata
 10from galaxy.datatypes.sniff import *
 11from galaxy.datatypes.util.image_util import *
 12from urllib import urlencode, quote_plus
 13import zipfile
 14import os, subprocess, tempfile, imghdr
 15
 16try:
 17    import Image as PIL
 18except ImportError:
 19    try:
 20        from PIL import Image as PIL
 21    except:
 22        PIL = None
 23
 24log = logging.getLogger(__name__)
 25
 26# TODO: Uploading image files of various types is supported in Galaxy, but on
 27# the main public instance, the display_in_upload is not set for these data
 28# types in datatypes_conf.xml because we do not allow image files to be uploaded
 29# there.  There is currently no API feature that allows uploading files outside
 30# of a data library ( where it requires either the upload_paths or upload_directory
 31# option to be enabled, which is not the case on the main public instance ).  Because
 32# of this, we're currently safe, but when the api is enhanced to allow other uploads,
 33# we need to ensure that the implementation is such that image files cannot be uploaded
 34# to our main public instance.
 35
 36
 37class Image( data.Data ):
 38    """Class describing an image"""
 39    def set_peek( self, dataset, is_multi_byte=False ):
 40        if not dataset.dataset.purged:
 41            dataset.peek = 'Image in %s format' % dataset.extension
 42            dataset.blurb = data.nice_size( dataset.get_size() )
 43        else:
 44            dataset.peek = 'file does not exist'
 45            dataset.blurb = 'file purged from disk'
 46    def sniff( self, filename ):
 47        # First check if we can  use PIL
 48        if PIL is not None:
 49            try:
 50                im = PIL.open( filename )
 51                im.close()
 52                return True
 53            except:
 54                return False
 55        else:
 56            if imghdr.what( filename ) is not None:
 57                return True
 58            else:
 59                return False
 60
 61
 62class Jpg( Image ):
 63    file_ext = "jpeg"
 64
 65    def sniff(self, filename, image=None):
 66        """Determine if the file is in jpg format."""
 67        return check_image_type( filename, ['JPEG'], image )
 68
 69
 70class Png( Image ):
 71    file_ext = "png"
 72
 73    def sniff(self, filename, image=None):
 74        """Determine if the file is in png format."""
 75        return check_image_type( filename, ['PNG'], image )
 76
 77
 78class Tiff( Image ):
 79    file_ext = "tiff"
 80
 81    def sniff(self, filename, image=None):
 82        """Determine if the file is in tiff format."""
 83        return check_image_type( filename, ['TIFF'], image )
 84
 85
 86class Bmp( Image ):
 87    file_ext = "bmp"
 88
 89    def sniff(self, filename, image=None):
 90        """Determine if the file is in bmp format."""
 91        return check_image_type( filename, ['BMP'], image )
 92
 93
 94class Gif( Image ):
 95    file_ext = "gif"
 96
 97    def sniff(self, filename, image=None):
 98        """Determine if the file is in gif format."""
 99        return check_image_type( filename, ['GIF'], image )
100
101
102class Im( Image ):
103    file_ext = "im"
104
105    def sniff(self, filename, image=None):
106        """Determine if the file is in im format."""
107        return check_image_type( filename, ['IM'], image )
108
109
110class Pcd( Image ):
111    file_ext = "pcd"
112
113    def sniff(self, filename, image=None):
114        """Determine if the file is in pcd format."""
115        return check_image_type( filename, ['PCD'], image )
116
117
118class Pcx( Image ):
119    file_ext = "pcx"
120
121    def sniff(self, filename, image=None):
122        """Determine if the file is in pcx format."""
123        return check_image_type( filename, ['PCX'], image )
124
125
126class Ppm( Image ):
127    file_ext = "ppm"
128
129    def sniff(self, filename, image=None):
130        """Determine if the file is in ppm format."""
131        return check_image_type( filename, ['PPM'], image )
132
133
134class Psd( Image ):
135    file_ext = "psd"
136
137    def sniff(self, filename, image=None):
138        """Determine if the file is in psd format."""
139        return check_image_type( filename, ['PSD'], image )
140
141
142class Xbm( Image ):
143    file_ext = "xbm"
144
145    def sniff(self, filename, image=None):
146        """Determine if the file is in XBM format."""
147        return check_image_type( filename, ['XBM'], image )
148
149
150class Xpm( Image ):
151    file_ext = "xpm"
152
153    def sniff(self, filename, image=None):
154        """Determine if the file is in XPM format."""
155        return check_image_type( filename, ['XPM'], image )
156
157
158class Rgb( Image ):
159    file_ext = "rgb"
160
161    def sniff(self, filename, image=None):
162        """Determine if the file is in RGB format."""
163        return check_image_type( filename, ['RGB'], image )
164
165
166class Pbm( Image ):
167    file_ext = "pbm"
168
169    def sniff(self, filename, image=None):
170        """Determine if the file is in PBM format"""
171        return check_image_type( filename, ['PBM'], image )
172
173
174class Pgm( Image ):
175    file_ext = "pgm"
176
177    def sniff(self, filename, image=None):
178        """Determine if the file is in PGM format"""
179        return check_image_type( filename, ['PGM'], image )
180
181
182class Eps( Image ):
183    file_ext = "eps"
184
185    def sniff(self, filename, image=None):
186        """Determine if the file is in eps format."""
187        return check_image_type( filename, ['EPS'], image )
188
189
190class Rast( Image ):
191    file_ext = "rast"
192
193    def sniff(self, filename, image=None):
194        """Determine if the file is in rast format"""
195        return check_image_type( filename, ['RAST'], image )
196
197
198class Pdf( Image ):
199    file_ext = "pdf"
200
201    def sniff(self, filename):
202        """Determine if the file is in pdf format."""
203        headers = get_headers(filename, None, 1)
204        try:
205            if headers[0][0].startswith("%PDF"):
206                return True
207            else:
208                return False
209        except IndexError:
210            return False
211
212Binary.register_sniffable_binary_format("pdf", "pdf", Pdf)
213
214def create_applet_tag_peek( class_name, archive, params ):
215    text = """
216<object classid="java:%s"
217      type="application/x-java-applet"
218      height="30" width="200" align="center" >
219      <param name="archive" value="%s"/>""" % ( class_name, archive )
220    for name, value in params.iteritems():
221        text += """<param name="%s" value="%s"/>""" % ( name, value )
222    text += """
223<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
224        height="30" width="200" >
225        <param name="code" value="%s" />
226        <param name="archive" value="%s"/>""" % ( class_name, archive )
227    for name, value in params.iteritems():
228        text += """<param name="%s" value="%s"/>""" % ( name, value )
229    text += """<div class="errormessage">You must install and enable Java in your browser in order to access this applet.<div></object>
230</object>
231"""
232    return """<div><p align="center">%s</p></div>""" % text
233
234class Gmaj( data.Data ):
235    """Class describing a GMAJ Applet"""
236    file_ext = "gmaj.zip"
237    copy_safe_peek = False
238    def set_peek( self, dataset, is_multi_byte=False ):
239        if not dataset.dataset.purged:
240            if hasattr( dataset, 'history_id' ):
241                params = {
242                "bundle":"display?id=%s&tofile=yes&toext=.zip" % dataset.id,
243                "buttonlabel": "Launch GMAJ",
244                "nobutton": "false",
245                "urlpause" :"100",
246                "debug": "false",
247                "posturl": "history_add_to?%s" % "&".join( map( lambda x: "%s=%s" % ( x[0], quote_plus( str( x[1] ) ) ), [ ( 'copy_access_from', dataset.id), ( 'history_id', dataset.history_id ), ( 'ext', 'maf' ), ( 'name', 'GMAJ Output on data %s' % dataset.hid ), ( 'info', 'Added by GMAJ' ), ( 'dbkey', dataset.dbkey ) ] ) )
248                }
249                class_name = "edu.psu.bx.gmaj.MajApplet.class"
250                archive = "/static/gmaj/gmaj.jar"
251                dataset.peek = create_applet_tag_peek( class_name, archive, params )
252                dataset.blurb = 'GMAJ Multiple Alignment Viewer'
253            else:
254                dataset.peek = "After you add this item to your history, you will be able to launch the GMAJ applet."
255                dataset.blurb = 'GMAJ Multiple Alignment Viewer'
256        else:
257            dataset.peek = 'file does not exist'
258            dataset.blurb = 'file purged from disk'
259    def display_peek(self, dataset):
260        try:
261            return dataset.peek
262        except:
263            return "peek unavailable"
264    def get_mime(self):
265        """Returns the mime type of the datatype"""
266        return 'application/zip'
267    def sniff(self, filename):
268        """
269        NOTE: the sniff.convert_newlines() call in the upload utility will keep Gmaj data types from being
270        correctly sniffed, but the files can be uploaded (they'll be sniffed as 'txt').  This sniff function
271        is here to provide an example of a sniffer for a zip file.
272        """
273        if not zipfile.is_zipfile( filename ):
274            return False
275        contains_gmaj_file = False
276        zip_file = zipfile.ZipFile(filename, "r")
277        for name in zip_file.namelist():
278            if name.split(".")[1].strip().lower() == 'gmaj':
279                contains_gmaj_file = True
280                break
281        zip_file.close()
282        if not contains_gmaj_file:
283            return False
284        return True
285
286class Html( data.Text ):
287    """Class describing an html file"""
288    file_ext = "html"
289
290    def set_peek( self, dataset, is_multi_byte=False ):
291        if not dataset.dataset.purged:
292            dataset.peek = "HTML file"
293            dataset.blurb = data.nice_size( dataset.get_size() )
294        else:
295            dataset.peek = 'file does not exist'
296            dataset.blurb = 'file purged from disk'
297    def get_mime(self):
298        """Returns the mime type of the datatype"""
299        return 'text/html'
300    def sniff( self, filename ):
301        """
302        Determines whether the file is in html format
303
304        >>> fname = get_test_fname( 'complete.bed' )
305        >>> Html().sniff( fname )
306        False
307        >>> fname = get_test_fname( 'file.html' )
308        >>> Html().sniff( fname )
309        True
310        """
311        headers = get_headers( filename, None )
312        try:
313            for i, hdr in enumerate(headers):
314                if hdr and hdr[0].lower().find( '<html>' ) >=0:
315                    return True
316            return False
317        except:
318            return True
319
320class Laj( data.Text ):
321    """Class describing a LAJ Applet"""
322    file_ext = "laj"
323    copy_safe_peek = False
324
325    def set_peek( self, dataset, is_multi_byte=False ):
326        if not dataset.dataset.purged:
327            if hasattr( dataset, 'history_id' ):
328                params = {
329                "alignfile1": "display?id=%s" % dataset.id,
330                "buttonlabel": "Launch LAJ",
331                "title": "LAJ in Galaxy",
332                "posturl": quote_plus( "history_add_to?%s" % "&".join( [ "%s=%s" % ( key, value ) for key, value in { 'history_id': dataset.history_id, 'ext': 'lav', 'name': 'LAJ Output', 'info': 'Added by LAJ', 'dbkey': dataset.dbkey, 'copy_access_from': dataset.id }.items() ] ) ),
333                "noseq": "true"
334                }
335                class_name = "edu.psu.cse.bio.laj.LajApplet.class"
336                archive = "/static/laj/laj.jar"
337                dataset.peek = create_applet_tag_peek( class_name, archive, params )
338            else:
339                dataset.peek = "After you add this item to your history, you will be able to launch the LAJ applet."
340                dataset.blurb = 'LAJ Multiple Alignment Viewer'
341        else:
342            dataset.peek = 'file does not exist'
343            dataset.blurb = 'file purged from disk'
344    def display_peek(self, dataset):
345        try:
346            return dataset.peek
347        except:
348            return "peek unavailable"