# vi:sw=4: import chimera, sys import httplib, mimetypes, urlparse ADDL_INFO = "(Describe the actions that caused this problem to occur here)" def canonPlatName(plat): plat_names = { 'linux2' : "Linux", 'osf1V5' : "Alpha Tru64 Unix", 'win32' : "Windows", 'irix6-n32' : "SGI IRIX", 'darwin' : "Mac OS X" } try: return plat_names[plat] except KeyError: return plat def encode_multipart_formdata(fields, files): """ fields is a sequence of (name, value) elements for regular form fields. files is a sequence of (name, filename, value) elements for data to be uploaded as files Return (content_type, body) ready for httplib.HTTP instance """ BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' CRLF = '\r\n' L = [] for (key, value) in fields: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"' % key) L.append('') if isinstance(value, unicode): value = value.encode('utf8') L.append(value) for (key, filename, value) in files: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) L.append('Content-Type: %s' % get_content_type(filename)) L.append('Content-Length: %d' % len(value)) L.append('') L.append(value) L.append('--' + BOUNDARY + '--') L.append('') body = CRLF.join(L) content_type = 'multipart/form-data; boundary=%s' % BOUNDARY return content_type, body def get_content_type(filename): return mimetypes.guess_type(filename)[0] or 'application/octet-stream' class BugReport: def __init__(self, name='', email='', description='', info='', filename='', version='', platform='', includeSysInfo=True): self.name = name self.email = email self.description = description self.info = info self.filename = filename self.version = version or chimera.version.release import platform as pyplat self.platform = platform or ("%s%s (%s) %s" % ( pyplat.system(), "64" if sys.maxsize > 2 ** 32 else "", chimera.opengl_platform(), chimera.operating_system())) if self.description: self.description = self.description.replace("&", "&") self.description = self.description.replace("<", "<") self.description = self.description.replace(">", ">") self.description = '
\n'.join(self.description.split('\n')) if self.info: self.info = self.info.replace("&", "&") self.info = self.info.replace("<", "<") self.info = self.info.replace(">", ">") self.info = '
\n'.join(self.info.split('\n')) if not self.description: self.description = \ "%s\n" % ADDL_INFO if includeSysInfo: self.addSysInfo() self.addGraphicsSettings() def addGraphicsSettings(self): if self.info: self.info += "
\n" self.info += graphicsSettings() def addSysInfo(self): if self.info: self.info += "
\n" self.info += systemInfo() def getValue(self, val): try: return getattr(self, val) except AttributeError: return None def printStuff(self): ## for debugging print "NAME ", self.name print "EMAIL", self.email print "DESC ", self.description print "INFO ", self.info print "VERS ", self.version print "PLAT ", self.platform def graphicsSettings(): import chimera, Lighting v = chimera.viewer c = v.camera om = chimera.openModels cofrm = {om.Fixed:'fixed', om.CenterOfModels:'center of models', om.Independent:'independent', om.CenterOfView:'center of view', om.FrontCenter:'front center'}.get(om.cofrMethod, 'unknown') lod = chimera.LODControl.get() try: graphicsInfo = ( "Multisampling: %s
\n" % (chimera.multisample,) + "Shadows: %s
\n" % (v.showShadows,) + "Shadow texture size: %s
\n" % (v.shadowTextureSize,) + "Silhouettes: %s
\n" % (v.showSilhouette,) + "Depth cue: %s
\n" % (v.depthCue,) + "Subdivision quality: %.2f
\n" % (lod.quality,) + "Single-layer transparency: %s
\n" % (v.singleLayerTransparency,) + "Transparent background: %s
\n" % (chimera.bgopacity,) + "Shaders supported: %s
\n" % (v.haveShaderSupport(),) + "Using shader: %s
\n" % (v.haveShader(),) + "Window size: %d %d
\n" % tuple(v.windowSize) + "Camera mode: %s
\n" % (c.mode(),) + "Orthographic projection: %s
\n" % (c.ortho,) + "Center of rotation: %s
\n" % (cofrm,) + "Near/far clipping: %s
\n" % (v.clipping,) + "Key light: %s
\n" % (v.keyLight != None,) + "Fill light: %s
\n" % (v.fillLight != None,) + "Back light: %s
\n" % (v.backLight != None,) + "Ambient light: %.2f
\n" % (v.ambient,) + "Specular sharpness: %.2f
\n" % (Lighting.sharpness(),) + "Specular reflectivity: %.2f
\n" % (Lighting.reflectivity(),)) graphicsInfo += '
\n' + openGLCapabilities() except: graphicsInfo = "Error gathering graphics info" return graphicsInfo def openGLCapabilities(): import OpenGLDebug, libgfxinfo as gi fni = OpenGLDebug.Features.items() fni.sort() flist = [] for n,i in fni: s = gi.hasInfo(i) if s & 0x2: state = 'native' elif s & 0x1: state = 'extension' else: state = 'not supported' if s & 0x4: state += ', disabled' flist.append('%s: %s
' % (n,state)) cap = '\n'.join(flist) return cap def systemInfo(): from chimera import SubprocessMonitor as SM from xml.sax.saxutils import escape openglInfo = ( "OpenGL Vendor: %s
\n" "OpenGL Renderer: %s
\n" "OpenGL Version: %s
\n" % ( escape(chimera.opengl_vendor()), escape(chimera.opengl_renderer()), escape(chimera.opengl_version())) ) import os rootdir = os.getenv('CHIMERA') if not rootdir: bindir = '' else: bindir = os.path.join(rootdir, 'bin') if sys.platform == 'win32': prog = [os.path.join(bindir, 'machinfo.exe')] elif sys.platform.startswith('linux'): prog = [os.path.join(bindir, 'linuxdist')] elif sys.platform.startswith('darwin'): prog = [ '/usr/sbin/system_profiler', '-detailLevel', 'mini', 'SPHardwareDataType', 'SPSoftwareDataType', 'SPDisplaysDataType' ] else: prog = [] if not prog: osInfo = [] else: try: subproc = SM.Popen(prog, stdin=None, stdout=SM.PIPE, stderr=None) osInfo = subproc.stdout.readlines() except OSError: osInfo = [] for i, line in enumerate(osInfo): line = line.strip().decode('utf-8', 'replace') colon = line.find(':') if colon == -1 or colon + 1 == len(line): osInfo[i] = escape(line) continue osInfo[i] = '%s%s' % (escape(line[:colon]), escape(line[colon:])) info = "%s%s" % (openglInfo, '
'.join(osInfo)) return info from chimera import dialogs, replyobj from BugReportGUI import BugReportGUI, BugNotification def displayDialog(wait=False): if dialogs.find(BugReportGUI.name): replyobj.status("Bug report already in progress!", color="red", blankAfter=15) return None else: br_gui = dialogs.display(BugReportGUI.name, wait) return br_gui def bugNotify(explanation, description): BugNotification(explanation, description) dialogs.register(BugReportGUI.name, BugReportGUI)