<commit_before># -*- coding: utf-8 -*-


# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

import os
from queue import Queue
import signal
import subprocess
import sys
from threading import Thread

import psutil

from .lib import get_location_of_file


# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# WINE SESSION CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class wine_session_class:


	def __init__(self, session_id, parameter, session_log):

		self.id = session_id
		self.p = parameter
		self.log = session_log

		self.log.out('wine session starting ...')

		# Get location of this script file
		self.location = get_location_of_file(__file__)

		self.__server_start__()

		self.log.out('wine session started')


	def terminate(self):

		self.__server_stop__()

		self.log.out('wine session terminated')


	def __set_env__(self):

		# Change the environment for Wine: Architecture
		os.environ['WINEARCH'] = self.p['arch']

		# Change the environment for Wine: Wine prefix / profile directory
		os.environ['WINEPREFIX'] = os.path.join(self.location, self.p['arch'] + '-wine')


	def __server_start__(self):

		# Set environment variables
		self.__set_env__()

		# Python interpreter's directory seen from this script
		pydir_unix = os.path.join(self.location, self.p['arch'] + '-python' + self.p['version'])

		# Translate Python interpreter's Unix path into Wine path
		# pydir_win = self.translate_path_unix2win(pydir_unix)

		# Translate server's Unix path into Wine path
		location_win = self.translate_path_unix2win(self.location)

		# Prepare Wine-Python server command with session id
		py_cmd = [
			os.path.join(pydir_unix, 'python.exe'),
			"%s\\wine_server.py" % location_win,
			self.id
			]

		# Identify wine command for 32 or 64 bit
		if self.p['arch'] == 'win32':
			py_cmd.insert(0, 'wine')
		else: # win64
			py_cmd.insert(0, 'wine64')

		# Launch server
		self.__launch_wine__(py_cmd)


	def __read_output_from_pipe__(self, pipe, funcs):

		for line in iter(pipe.readline, b''):
			for func in funcs:
				func(line.decode('utf-8'))
		pipe.close()


	def __launch_wine__(self, command_list):

		self.wine_p = subprocess.Popen(
			command_list,
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE,
			shell = False,
			preexec_fn = os.setsid,
			close_fds = True,
			bufsize = 1
			)

# wineserver first
# log via reverse xmlrpc

		print([p for p in psutil.process_iter() if self.id in p.cmdline()])
		self.python_proc = [p for p in psutil.process_iter() if self.id in p.cmdline()][0]
		print(self.python_proc)


		q = Queue()

		stdout_thread = Thread(
			target = self.__read_output_from_pipe__, args = (self.wine_p.stdout, [q.put, self.log.out])
			)

		stderr_thread = Thread(
			target = self.__read_output_from_pipe__, args = (self.wine_p.stderr, [q.put, self.log.err])
			)

		for t in (stdout_thread, stderr_thread):
			t.daemon = True
			t.start()

		self.wine_p.wait()

		for t in (stdout_thread, stderr_thread):
			t.join()

		q.put(None)


	def __server_stop__(self):

		# os.killpg(os.getpgid(self.wine_p.pid), signal.SIGTERM)
		os.killpg(os.getpgid(self.python_proc.pid), signal.SIGTERM)


	def translate_path_unix2win(self, path):

		# Start winepath for tanslating path, catch output from all pipes
		winepath_p = subprocess.Popen(
			['winepath', '-w', path],
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE
			)
		# Get stdout and stderr
		wine_out, wine_err = winepath_p.communicate()

		# Pass stderr into log
		self.log.err(wine_err.decode(encoding = 'UTF-8'))

		# Return translated path
		return wine_out.decode(encoding = 'UTF-8').strip()<commit_msg>code cleanup, not working<commit_after># -*- coding: utf-8 -*-


# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

import os
from queue import Queue
import signal
import subprocess
import sys
from threading import Thread
import time

import psutil

from .lib import get_location_of_file


# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# WINE SESSION CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class wine_session_class:


	# session init
	def __init__(self, session_id, parameter, session_log):

		# Set ID, parameters and pointer to log
		self.id = session_id
		self.p = parameter
		self.log = session_log

		# Log status
		self.log.out('wine session starting ...')

		# Fire session up
		self.__session_start__()

		# Log status
		self.log.out('wine session started')


	# flow control routine for setting things up, called once from init
	def __session_start__(self):

		# Get location of this script file
		self.dir_thisfile = get_location_of_file(__file__)

		# Set environment variables for wine
		self.__set_wine_env__()

		# Translate this file's Unix path into Wine path
		self.dir_thisfile_wine = self.translate_path_unix2win(self.dir_thisfile)

		# Start wine server
		self.__wine_server_start__()

		# Start wine python, no wait ...
		self.__wine_python_start__(self.__compile_wine_python_command__())


	# session destructor
	def terminate(self):

		# Log status
		self.log.out('wine session terminating ...')

		# Shut down wine python
		self.__wine_python_stop__()

		# Stop wine server
		self.__wine_server_stop__()

		# Log status
		self.log.out('wine session terminated')


	def __set_wine_env__(self):

		# Change the environment for Wine: Architecture
		os.environ['WINEARCH'] = self.p['arch']

		# Change the environment for Wine: Wine prefix / profile directory
		os.environ['WINEPREFIX'] = os.path.join(self.dir_thisfile, self.p['arch'] + '-wine')


	def __wine_server_start__(self):

		# Start wine server into prepared environment
		self.proc_wineserver = subprocess.Popen(
			['wineserver', '-f', '-p'], # run persistent in foreground
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE,
			shell = False
			)

		# Status log
		self.log.out('wineserver started with PID %d' % self.proc_wineserver.pid)

		# HACK wait due to lack of feedback
		time.sleep(1) # seconds


	def __compile_wine_python_command__(self):

		# Python interpreter's directory seen from this script
		self.dir_python = os.path.join(self.dir_thisfile, self.p['arch'] + '-python' + self.p['version'])

		# Identify wine command for 32 or 64 bit
		if self.p['arch'] == 'win32':
			wine_cmd = 'wine'
		elif self.p['arch'] == 'win64':
			wine_cmd = 'wine64'
		else:
			raise # TODO error

		# Prepare Wine-Python server command with session id and return it
		return [
			wine_cmd,
			os.path.join(self.dir_python, 'python.exe'),
			"%s\\wine_server.py" % self.dir_thisfile_wine,
			self.id
			]


	def __read_output_from_pipe__(self, pipe, funcs):

		for line in iter(pipe.readline, b''):
			for func in funcs:
				func(line.decode('utf-8'))
		pipe.close()


	def __wine_python_start__(self, command_list):

		# Fire up Wine-Python process
		self.proc_winepython = subprocess.Popen(
			command_list,
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE,
			shell = False,
			preexec_fn = os.setsid,
			close_fds = True,
			bufsize = 1
			)

		# Status log
		self.log.out('wine-python started with PID %d' % self.proc_winepython.pid)


		# print([p for p in psutil.process_iter() if self.id in p.cmdline()])
		# self.proc_python = [p for p in psutil.process_iter() if self.id in p.cmdline()][0]
		# print(self.proc_python)


		q = Queue()

		stdout_thread = Thread(
			target = self.__read_output_from_pipe__, args = (self.proc_winepython.stdout, [q.put, self.log.out])
			)

		stderr_thread = Thread(
			target = self.__read_output_from_pipe__, args = (self.proc_winepython.stderr, [q.put, self.log.err])
			)

		for t in (stdout_thread, stderr_thread):
			t.daemon = True
			t.start()

		self.proc_winepython.wait()

		for t in (stdout_thread, stderr_thread):
			t.join()

		q.put(None)


	def __wine_python_stop__(self):

		# Terminate Wine-Python
		os.kill(self.proc_winepython.pid, signal.SIGTERM)

		# HACK wait for its destructor
		time.sleep(1) # seconds


	def __wine_server_stop__(self):

		# Killing the server requires two signals as specified in the man page
		os.kill(self.proc_wineserver.pid, signal.SIGINT)
		os.kill(self.proc_wineserver.pid, signal.SIGKILL)


	def translate_path_unix2win(self, path):

		# Start winepath for tanslating path, catch output from all pipes
		winepath_p = subprocess.Popen(
			['winepath', '-w', path],
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE
			)

		# Get stdout and stderr
		wine_out, wine_err = winepath_p.communicate()

		# Pass stderr into log
		self.log.err(wine_err.decode(encoding = 'UTF-8'))

		# Return translated path
		return wine_out.decode(encoding = 'UTF-8').strip()
{'fraction_non_alphanumeric': 0.193006993006993, 'fraction_numerical': 0.004410973641742873, 'mean_word_length': 4.210762331838565, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191142', 'n_tokens_mistral': 3600, 'n_tokens_neox': 3010, 'n_words': 732}