Attachment 'gnuplot.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - GNUPLOT Command Data Parser
4
5 @copyright: 2008 MoinMoin:KwonChanYoung at europython2008
6 @license: GNU GPL, see COPYING for details.
7 """
8
9 """
10 example: {{{#!gnuplot
11 ...
12 ...
13 }}}
14 """
15
16 import os
17 import sys
18 import base64
19 import string
20 import StringIO
21 import exceptions
22 import codecs
23 import tempfile
24 import subprocess
25 import time
26 import ctypes
27 import sha
28
29 from MoinMoin import config
30 from MoinMoin.action import AttachFile
31 from MoinMoin import log
32 loggin = log.getLogger(__name__)
33
34 # After checking that the gnuplot has been installed successfully,
35 # Register executable
36 GnuPlotExe = '/usr/local/bin/gnuplot'
37 TempDir = '/dev/shm'
38
39 Dependencies = []
40
41 class Parser:
42 """
43 Sends plot image generated by gnuplot
44 """
45
46 extensions = []
47 Dependencies = Dependencies
48
49 def __init__(self, raw, request, **kw):
50 self.raw = raw
51 self.request = request
52
53 def format(self, formatter):
54 """ Send the text. """
55 self.request.flush() # to identify error text
56
57 img_name = sha.new(self.raw).hexdigest()
58 img_name = 'gnuplot_' + img_name + "_chart.img"
59
60 self.pagename = formatter.page.page_name
61 url = AttachFile.getAttachUrl(self.pagename, img_name, self.request)
62 self.attach_dir=AttachFile.getAttachDir(self.request,self.pagename,create=1)
63
64 self.delete_old_charts(formatter)
65
66 if not os.path.isfile(self.attach_dir + '/' + img_name):
67 img_data = self.gnuplot(self.raw.splitlines())
68 attached_file = file(self.attach_dir + '/' + img_name, 'wb')
69 attached_file.write(img_data)
70 attached_file.close()
71
72 self.request.write(formatter.image(src="%s" % url, alt=self.raw))
73
74 def delete_old_charts(self, formatter):
75 page_info = formatter.page.lastEditInfo()
76 try:
77 page_date = page_info['time']
78 except exceptions.KeyError, ex:
79 return
80 attach_files = AttachFile._get_files(self.request, self.pagename)
81 for chart in attach_files:
82 if chart.find('gnuplot_') == 0 and chart.find('_chart.img') > 0 :
83 fullpath = os.path.join(self.attach_dir, chart).encode(config.charset)
84 st = os.stat(fullpath)
85 chart_date = self.request.user.getFormattedDateTime(st.st_mtime)
86 if chart_date < page_date :
87 os.remove(fullpath)
88 else :
89 continue
90
91 def gnuplot(self, command_lines):
92 tmpfile = tempfile.NamedTemporaryFile('rw',-1,'','gnuplot_',TempDir)
93 cmdfilename = tmpfile.name + '.cmd'
94 imgfilename = tmpfile.name + '.img'
95 cmdfile = file(cmdfilename, 'w')
96
97 # set file
98 cmdfile.write('set terminal png size 600,400\n')
99 cmdfile.write('set output "' + string.replace(imgfilename, '\\', '/') + '"\n')
100
101 for command in command_lines:
102 command = string.strip(command)
103 smallcmd = string.lower(command)
104 tokens = string.split(smallcmd)
105 try:
106 if len(tokens) == 0 or command[0] == '#' :
107 cmdfile.write(command + '\n')
108 elif len(tokens) > 2 and string.find(tokens[1], 'output') > 0 and tokens[0] == 'set' > 0:
109 cmdfile.write('#' + command + '\n')
110 elif len(tokens) > 2 and string.find(tokens[1], 'term') == 0 and tokens[0] == 'set' > 0:
111 cmdfile.write('#' + command + '\n')
112 ## ToDo
113 else :
114 cmdfile.write(command + '\n')
115 except exceptions.IndexError, ex :
116 cmdfile.write(command + '\n')
117 cmdfile.flush()
118
119 cmdfile.close()
120
121 p = subprocess.Popen([GnuPlotExe, cmdfilename])
122 if sys.platform == 'win32':
123 import win32event
124 import win32file
125 PROCESS_TERMINATE = 1
126 SYNCRONIZE = int('0x00100000', 16)
127 handle = ctypes.windll.kernel32.OpenProcess(SYNCRONIZE|PROCESS_TERMINATE, False, p.pid)
128 if ctypes.windll.kernel32.WaitForSingleObject(handle, 5000) != win32event.WAIT_OBJECT_0 : # wait up to 5 seconds
129 ctypes.windll.kernel32.TerminateProcess(handle,0)
130 ctypes.windll.kernel32.CloseHandle(handle)
131 try:
132 os.remove(cmdfilename)
133 except exceptions.WindowsError, ex:
134 pass
135 except exceptions.EnvironmentError, ex:
136 os.kill(p.pid, 9)
137
138 else :
139 try:
140 p.wait()
141 os.remove(cmdfilename)
142 except exceptions.EnvironmentError, ex:
143 os.kill(p.pid, 9)
144
145 imgf = file(imgfilename, 'rb')
146 raw_data = imgf.read()
147 imgf.close()
148 os.remove(imgfilename)
149
150 return raw_data
151
152 if __name__ == '__main__' :
153 plotlines=['plot sin(x),cos(x)',]
154 plotparser = Parser('','')
155 print base64.b64encode(plotparser.gnuplot(plotlines))
156
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.