Edgewall Software

ProcessorBazaar: svgdw.3.py

File svgdw.3.py, 4.5 kB (added by anonymous, 12 months ago)
Line 
1# Name: Chris Lee
2# email: chunghualee@gmail.com
3# developed for trac 0.10.4
4# usage: [[svgdw(your_attachement)]]
5# works on FireFox, sorry for IE user.
6
7# The attached SVG file is copied to another place, outside the trac.
8# The returned HTML code will generate an object with link to that file
9# Before use this macro:
10#       in trac.ini, add render_unsafe_content = true in [attachment]
11#       Set this to the directory you want the images stored in. Web server must have write access.
12images_folder = 'D:/web/phpBB/branches/phpBB-2.0.22/files/svgdw'
13#       Base URL of the folder.
14images_url = 'http://ezsrv/files/svgdw'
15
16# Adapted from the Image.py macro created by Shun-ichi Goto <gotoh@taiyo.co.jp>
17#
18# Display image in attachment or repository into the wiki page.
19#
20# First argument is filename (file spec).
21#
22# The file specification may refer attachments:
23#  * 'module:id:file', with module being either 'wiki' or 'ticket',
24#    to refer to the attachment named 'file' in the module:id object
25#  * 'id:file' same as above, module defaulted to 'wiki' (id can be dir/dir/node)
26#  * 'file' to refer to a local attachment named 'file'
27#    (but then, this works only from within a wiki page or a ticket).
28#
29# Ex.
30#   [[Image(photo.jpg)]]                           # simplest
31#
32# You can use image from other page, other ticket or other module.
33#   [[Image(OtherPage:foo.bmp)]]    # if current module is wiki
34#   [[Image(base/sub:bar.bmp)]]     # from hierarchical wiki page
35#   [[Image(#3:baz.bmp)]]           # if in a ticket, point to #3
36#   [[Image(ticket:36:boo.jpg)]]
37#   [[Image(source:/images/bee.jpg)]] # straight from the repository!
38
39
40import os
41import re
42import string
43import shutil 
44import md5
45from trac.attachment import Attachment
46
47def execute(hdf, txt, env):
48        # args will be null if the macro is called without parenthesis.
49        if not txt:
50                return ''
51        # parse arguments
52        # we expect the 1st argument to be a filename (filespec)
53        args = txt.split(',')
54        if len(args) == 0:
55           raise Exception("No argument.")
56        filespec = args[0]
57        # parse filespec argument to get module and id if contained.
58        parts = filespec.split(':')
59        if len(parts) == 3:                 # module:id:attachment
60                if parts[0] in ['wiki', 'ticket']:
61                        module, id, file = parts
62                else:
63                        raise Exception("%s module can't have attachments" % parts[0])
64        elif len(parts) == 2:               # #ticket:attachment or WikiPage:attachment
65                # FIXME: do something generic about shorthand forms...
66                id, file = parts
67                if id and id[0] == '#':
68                        module = 'ticket'
69                        id = id[1:]
70                else:
71                        module = 'wiki'
72        elif len(parts) == 1:               # attachment
73                file = filespec
74                # get current module and id from hdf
75                module = hdf.getValue('args.mode', 'wiki')
76                if module == 'wiki':
77                        id = hdf.getValue('args.page', 'WikiStart')
78                elif module == 'ticket':
79                        id = hdf['args.id'] # for ticket
80                else:
81                        # limit of use
82                        raise Exception('Cannot use this macro in %s module' % module)
83        else:
84                raise Exception( 'No filespec given' )
85        try:
86                attachment = Attachment(env, module, id, file)
87                org_path = attachment.path
88                return svg_render(images_folder, images_url, org_path)
89        except:
90                return '%s not found' % (filespec)
91
92def svg_render(images_folder, images_url, org_path):
93        md5sum = md5.new(org_path).hexdigest()
94        img_path = '%s/%s.svg' % (images_folder, md5sum)
95        url = '%s/%s.svg' % (images_url, md5sum)
96        img_time=org_time=''
97        try:
98                if not os.access(img_path, os.F_OK):
99                        shutil.copy2(org_path, img_path)
100                else:
101                        org_time = os.path.getmtime(org_path)
102                        img_time = os.path.getmtime(img_path)
103                        if org_time != img_time:
104                                shutil.copy2(org_path, img_path)
105        except:
106                raise Exception(  'can not render svg file')
107        try:
108                f = open(img_path, 'r')
109                svg = f.readlines()
110                f.close()
111                svg = "".join(svg).replace('\n', '')
112                w = re.search('width="([0-9]+)(.*?)" ', svg)
113                h = re.search('height="([0-9]+)(.*?)"', svg)
114                (w_val, w_unit) = w.group(1,2)
115                (h_val, h_unit) = h.group(1,2)
116                # Graphviz seems to underestimate height/width for SVG images,
117                # so we have to adjust them. The correction factor seems to be constant.
118                [w_val, h_val] = [ 1.2 * x for x in (int(w_val), int(h_val))]
119                dimensions = 'width="%(w_val)s%(w_unit)s" height="%(h_val)s%(h_unit)s"' % locals()
120        except:
121                dimensions = 'width="100%" height="100%"'
122        return '<object type="image/svg+xml" data="%s" %s>\
123        <embed src="%s" type="image/svg+xml"\
124        PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/"></embed>\
125        </object>\n' % (url,dimensions,url)