diff --git a/.gitignore b/.gitignore
index 0127b5a..ee00d16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -221,3 +221,7 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
+.idea/inspectionProfiles/
+.idea/vcs.xml
+Pipfile
+Pipfile.lock
diff --git a/README.md b/README.md
index 24c6345..0b21592 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,23 @@
# Bug-Reporter App
A Shotgun app for submit ticket for reporting bugs and request.
+![Bug Report](./resources/app_ui.png)
+
+This app originally was created by
+[Shotgun Software](https://www.shotgunsoftware.com/), I believe by
+[Jeff Beeland](https://www.linkedin.com/in/jefferybeeland/), and was
+demonstrated in [this video](https://www.youtube.com/watch?v=bT2WlQaJVmY). I
+modified it a bit to accommodate my need in our studio.
+
+### New Features
+* Ability to add the _error_ messages
+* Include the environment variable
+* Include the current _engine_ and _context_
+
+### Future Features
+* Specify Ticket Type _ex: bug or feature_
+* Specify the priority
+
+### Icon
+The Bug Icon is by youtube.com/AlfredoCreates & Flaticondesign.com from the
+Noun Project
\ No newline at end of file
diff --git a/icon_256.png b/icon_256.png
index cbef9e6..2738663 100644
Binary files a/icon_256.png and b/icon_256.png differ
diff --git a/python/app/dialog.py b/python/app/dialog.py
index 22cc884..7978828 100644
--- a/python/app/dialog.py
+++ b/python/app/dialog.py
@@ -8,29 +8,32 @@
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.
-import sgtk
import os
-import sys
-import threading
-import tempfile
import re
+import tempfile
+import sgtk
# by importing QT from sgtk rather than directly, we ensure that
# the code will be compatible with both PySide and PyQt.
from sgtk.platform.qt import QtCore, QtGui
+
from .ui.dialog import Ui_Dialog
-screen_grab = sgtk.platform.import_framework("tk-framework-qtwidgets", "screen_grab")
-shotgun_fields = sgtk.platform.import_framework("tk-framework-qtwidgets", "shotgun_fields")
+screen_grab = sgtk.platform.import_framework("tk-framework-qtwidgets",
+ "screen_grab")
+shotgun_fields = sgtk.platform.import_framework("tk-framework-qtwidgets",
+ "shotgun_fields")
+
def show_dialog(app_instance):
"""
Shows the main dialog window.
"""
- # in order to handle UIs seamlessly, each toolkit engine has methods for launching
- # different types of windows. By using these methods, your windows will be correctly
- # decorated and handled in a consistent fashion by the system.
-
+ # in order to handle UIs seamlessly, each toolkit engine has methods for
+ # launching different types of windows. By using these methods, your
+ # windows will be correctly decorated and handled in a consistent fashion
+ # by the system.
+
# we pass the dialog class to this method and leave the actual construction
# to be carried out by toolkit.
app_instance.engine.show_dialog("Report Bugs!", app_instance, AppDialog)
@@ -40,27 +43,27 @@ class AppDialog(QtGui.QWidget):
"""
Main application dialog window
"""
-
+
def __init__(self):
"""
Constructor
"""
# first, call the base class and let it do its thing.
- QtGui.QWidget.__init__(self)
-
+ super(AppDialog, self).__init__()
+
# now load in the UI that was created in the UI designer
self.ui = Ui_Dialog()
self.ui.setupUi(self)
-
- # most of the useful accessors are available through the Application class instance
- # it is often handy to keep a reference to this. You can get it via the following method:
+
+ # most of the useful accessors are available through the Application
+ # class instance it is often handy to keep a reference to this. You can
+ # get it via the following method:
self._app = sgtk.platform.current_bundle()
-
+
# via the self._app handle we can for example access:
# - The engine, via self._app.engine
# - A Shotgun API instance, via self._app.shotgun
# - A tk API instance, via self._app.tk
-
self.ui.buttons.accepted.connect(self.create_ticket)
self.ui.buttons.rejected.connect(self.close)
self.ui.screen_grab.clicked.connect(self.screen_grab)
@@ -69,10 +72,10 @@ def __init__(self):
self._cc_widget = None
# The ShotgunFieldManager is a factory used to build widgets for fields
- # associated with an entity type in Shotgun. It pulls down the schema from
- # Shotgun asynchronously when the initialize method is called, so before
- # we do that we need to hook up the signal it emits when it's done to our
- # method that gets the widget we want and adds it to the UI.
+ # associated with an entity type in Shotgun. It pulls down the schema
+ # from Shotgun asynchronously when the initialize method is called, so
+ # before we do that we need to hook up the signal it emits when it's
+ # done to our method that gets the widget we want and adds it to the UI.
self._field_manager = shotgun_fields.ShotgunFieldManager(parent=self)
self._field_manager.initialized.connect(self._get_shotgun_fields)
self._field_manager.initialize()
@@ -117,12 +120,27 @@ def create_ticket(self):
"""
# Create the new Ticket entity, pulling the project from the current
# context, and the title, ticket body, and cc list from the UI.
+ context_info = "__Engine Name__: {}\n__Engine Version__: " \
+ "{}\n__Context__: {}".format(self._app.engine.name,
+ self._app.engine.version,
+ self._app.context)
+ environment_info = "\n".join(["{} = {}".format(env, value)
+ for env, value in os.environ.items()])
+ description = self.ui.ticket_body.toPlainText()
+ error_log = '```\n{}\n```'.format(self.ui.error_log.toPlainText())
+
+ ticket_body = "{}\n### Description \n{}\n ### Error Log\n{}\n " \
+ "### Environment Variable\n{}".format(context_info,
+ description,
+ error_log,
+ environment_info)
+
result = self._app.shotgun.create(
"Ticket",
dict(
project=self._app.context.project,
title=self.ui.ticket_title.text(),
- description=self.ui.ticket_body.toPlainText(),
+ description=ticket_body,
addressings_cc=self._cc_widget.get_value(),
)
)
@@ -148,5 +166,3 @@ def create_ticket(self):
"Ticket #%s successfully submitted!" % result["id"],
)
self.close()
-
-
diff --git a/python/app/ui/dialog.py b/python/app/ui/dialog.py
index eaf2314..a4ef3fa 100644
--- a/python/app/ui/dialog.py
+++ b/python/app/ui/dialog.py
@@ -11,7 +11,7 @@
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
- Dialog.resize(431, 392)
+ Dialog.resize(452, 490)
self.verticalLayout = QtGui.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout_2 = QtGui.QHBoxLayout()
@@ -30,6 +30,9 @@ def setupUi(self, Dialog):
self.cc_label.setObjectName("cc_label")
self.cc_layout.addWidget(self.cc_label)
self.verticalLayout.addLayout(self.cc_layout)
+ self.label_2 = QtGui.QLabel(Dialog)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout.addWidget(self.label_2)
self.ticket_body = QtGui.QPlainTextEdit(Dialog)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -38,6 +41,17 @@ def setupUi(self, Dialog):
self.ticket_body.setSizePolicy(sizePolicy)
self.ticket_body.setObjectName("ticket_body")
self.verticalLayout.addWidget(self.ticket_body)
+ self.label_3 = QtGui.QLabel(Dialog)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout.addWidget(self.label_3)
+ self.error_log = QtGui.QPlainTextEdit(Dialog)
+ sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(1)
+ sizePolicy.setHeightForWidth(self.error_log.sizePolicy().hasHeightForWidth())
+ self.error_log.setSizePolicy(sizePolicy)
+ self.error_log.setObjectName("error_log")
+ self.verticalLayout.addWidget(self.error_log)
self.lower_layout = QtGui.QHBoxLayout()
self.lower_layout.setSpacing(5)
self.lower_layout.setContentsMargins(-1, 0, -1, -1)
@@ -67,6 +81,8 @@ def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Report a bug!", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Dialog", "Subject:", None, QtGui.QApplication.UnicodeUTF8))
self.cc_label.setText(QtGui.QApplication.translate("Dialog", "CC:", None, QtGui.QApplication.UnicodeUTF8))
+ self.label_2.setText(QtGui.QApplication.translate("Dialog", "Description:", None, QtGui.QApplication.UnicodeUTF8))
+ self.label_3.setText(QtGui.QApplication.translate("Dialog", "Error Log:", None, QtGui.QApplication.UnicodeUTF8))
self.screen_grab.setText(QtGui.QApplication.translate("Dialog", "Take a screenshot!", None, QtGui.QApplication.UnicodeUTF8))
from . import resources_rc
diff --git a/resources/app_ui.png b/resources/app_ui.png
new file mode 100644
index 0000000..401cc41
Binary files /dev/null and b/resources/app_ui.png differ
diff --git a/resources/dialog.ui b/resources/dialog.ui
index b41ad93..65e9fcc 100644
--- a/resources/dialog.ui
+++ b/resources/dialog.ui
@@ -6,8 +6,8 @@
0
0
- 431
- 392
+ 452
+ 490
@@ -42,6 +42,13 @@
+ -
+
+
+ Description:
+
+
+
-
@@ -52,6 +59,23 @@
+ -
+
+
+ Error Log:
+
+
+
+ -
+
+
+
+ 0
+ 1
+
+
+
+
-