# 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)