Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUI in separate thread (fix #189) #203

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions rpg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,11 @@ def write_spec(self):

def build_srpm(self):
""" Builds srpm into base directory. """
print('Building SRPM...')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use logging instead of prints, please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use logging.info instead, please.

if not self.spec.Source or not self.archive_path.exists():
self.create_archive()
self.write_spec()
print('Spec file created.')
self._package_builder.build_srpm(
self.spec_path, self.archive_path, self.base_dir)

Expand Down Expand Up @@ -274,6 +276,23 @@ def build_project(self):
self.compiled_dir,
self.spec.build)

def copr_create_and_build(self, name, chroots, desc, intro, url):
print("Creating new project...")
try:
self.copr_create_project(name, chroots, desc, intro)
except:
print("Error in creating project! Please check your login.")
return
print("Creating new project - DONE")
print("Build proccess started...")
print("It takes a while, but it may be safely interrupted.")
try:
self.copr_build(name, url)
except:
print("Error in building project! Please check your url.")
return
print("Building new project - DONE")

def copr_set_config(self, username, login, token):
""" Logs into copr with username, login and token.
This has to be called before copr_create_project and copr_build
Expand Down
62 changes: 62 additions & 0 deletions rpg/gui/thread.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from multiprocessing import Process, Queue
from threading import Thread
from io import StringIO
from contextlib import redirect_stdout


class _StringIO(StringIO):
""" Overwriting of StringIO for real time output caching. """

def __init__(self, buff):
super(_StringIO, self).__init__()
self.buff = buff

def write(self, s):
super(_StringIO, self).write(s)
if s and s != '\n':
self.buff.put(s)


class ThreadWrapper():
""" Unblocking way to connect functions with GUI for redirection
it's output in real time. """

def __init__(self, widget, func, *args):
""" Runs function in new process and add output
to GUI widget from thread with queue. """
self._widget = widget
self._queue = Queue()
self._process = Process(target=self.wrapper,
args=(self._queue, func, args, ))
self._thread = Thread(target=self.writer)
self._running = False

def run(self):
""" Starts the process and the thread. """
if not self._running:
self._process.start()
self._thread.start()
self._running = True

def kill(self):
""" Stops the process and the thread (there are no official
way to stop thread. This will unlocked thread and it will
be stopped with GUI - without error). """
self._thread._tstate_lock = None
self._thread._stop()
self._thread.join()
self._process.terminate()

@staticmethod
def wrapper(queue, func, args):
""" Redirects stdout and call function.
Output will be in queue."""
f = _StringIO(queue)
with redirect_stdout(f):
func(*args)
f.close()

def writer(self):
""" Appends output from function to the GUI widget. """
while self._process.is_alive():
self._widget.appendPlainText(self._queue.get())
Loading