<commit_before>#coding:utf8
import time
import threading
import thread
import win32con, win32api, win32gui, ctypes, ctypes.wintypes #@UnresolvedImport @UnusedImport
from functools import wraps
from syncplay.players.basePlayer import BasePlayer
import re
from syncplay.utils import retry
from syncplay import constants  
from syncplay.messages import getMessage
import os.path

class MpcHcApi:
    def __init__(self):
        self.callbacks = self.__Callbacks()
        self.loadState = None
        self.playState = None
        self.filePlaying = None
        self.fileDuration = None
        self.filePath = None
        self.lastFilePosition = None
        self.version = None
        self.__playpause_warden = False
        self.__locks = self.__Locks()
        self.__mpcExistenceChecking = threading.Thread(target=self.__mpcReadyInSlaveMode, name="Check MPC window")
        self.__mpcExistenceChecking.setDaemon(True)
        self.__listener = self.__Listener(self, self.__locks)
        self.__listener.setDaemon(True)
        self.__listener.start()
        self.__locks.listenerStart.wait()
    
    def waitForFileStateReady(f): #@NoSelf
        @wraps(f)
        def wrapper(self, *args, **kwds):
            if(not self.__locks.fileReady.wait(constants.MPC_LOCK_WAIT_TIME)):
                raise self.PlayerNotReadyException()
            return f(self, *args, **kwds)
        return wrapper
            
    def startMpc(self, path, args=()):
        args = "%s /slave %s" % (" ".join(args), str(self.__listener.hwnd))
        win32api.ShellExecute(0, "open", path, args, None, 1)
        if(not self.__locks.mpcStart.wait(constants.MPC_OPEN_MAX_WAIT_TIME)):
            raise self.NoSlaveDetectedException(getMessage("en", "mpc-slave-error"))
        self.__mpcExistenceChecking.start() 

    def openFile(self, filePath):
        self.__listener.SendCommand(self.CMD_OPENFILE, filePath)
    
    def isPaused(self):
        return (self.playState <> self.__MPC_PLAYSTATE.PS_PLAY and self.playState <> None)
 
    def askForVersion(self):
        self.__listener.SendCommand(self.CMD_GETVERSION)
 
    @waitForFileStateReady
    def pause(self):
        self.__listener.SendCommand(self.CMD_PAUSE)
 
    @waitForFileStateReady
    def playPause(self):
        self.__listener.SendCommand(self.CMD_PLAYPAUSE)
     
    @waitForFileStateReady
    def unpause(self):
        self.__listener.SendCommand(self.CMD_PLAY)
 
    @waitForFileStateReady
    def askForCurrentPosition(self):
        self.__listener.SendCommand(self.CMD_GETCURRENTPOSITION)

    @waitForFileStateReady
    def seek(self, position):
        self.__listener.SendCommand(self.CMD_SETPOSITION, unicode(position))

    @waitForFileStateReady
    def setSpeed(self, rate):
        self.__listener.SendCommand(self.CMD_SETSPEED, unicode(rate))

    def sendOsd(self, message, MsgPos=constants.MPC_OSD_POSITION, DurationMs=(constants.OSD_DURATION*1000)):
        class __OSDDATASTRUCT(ctypes.Structure):
            _fields_ = [
                ('nMsgPos', ctypes.c_int32),
                ('nDurationMS', ctypes.c_int32),
                ('strMsg', ctypes.c_wchar * (len(message) + 1))
            ]    
        cmessage = __OSDDATASTRUCT() 
        cmessage.nMsgPos = MsgPos 
        cmessage.nDurationMS = DurationMs 
        cmessage.strMsg = message
        self.__listener.SendCommand(self.CMD_OSDSHOWMESSAGE, cmessage)
        
    def sendRawCommand(self, cmd, value):
        self.__listener.SendCommand(cmd, value)

    def handleCommand(self, cmd, value):
        if (cmd == self.CMD_CONNECT): 
            self.__listener.mpcHandle = int(value)
            self.__locks.mpcStart.set()
            if(self.callbacks.onConnected): 
                thread.start_new_thread(self.callbacks.onConnected, ())
                <commit_msg>Fixed MPC displaying OSD with utf8 characters improperly<commit_after>#coding:utf8
import time
import threading
import thread
import win32con, win32api, win32gui, ctypes, ctypes.wintypes #@UnresolvedImport @UnusedImport
from functools import wraps
from syncplay.players.basePlayer import BasePlayer
import re
from syncplay.utils import retry
from syncplay import constants  
from syncplay.messages import getMessage
import os.path

class MpcHcApi:
    def __init__(self):
        self.callbacks = self.__Callbacks()
        self.loadState = None
        self.playState = None
        self.filePlaying = None
        self.fileDuration = None
        self.filePath = None
        self.lastFilePosition = None
        self.version = None
        self.__playpause_warden = False
        self.__locks = self.__Locks()
        self.__mpcExistenceChecking = threading.Thread(target=self.__mpcReadyInSlaveMode, name="Check MPC window")
        self.__mpcExistenceChecking.setDaemon(True)
        self.__listener = self.__Listener(self, self.__locks)
        self.__listener.setDaemon(True)
        self.__listener.start()
        self.__locks.listenerStart.wait()
    
    def waitForFileStateReady(f): #@NoSelf
        @wraps(f)
        def wrapper(self, *args, **kwds):
            if(not self.__locks.fileReady.wait(constants.MPC_LOCK_WAIT_TIME)):
                raise self.PlayerNotReadyException()
            return f(self, *args, **kwds)
        return wrapper
            
    def startMpc(self, path, args=()):
        args = "%s /slave %s" % (" ".join(args), str(self.__listener.hwnd))
        win32api.ShellExecute(0, "open", path, args, None, 1)
        if(not self.__locks.mpcStart.wait(constants.MPC_OPEN_MAX_WAIT_TIME)):
            raise self.NoSlaveDetectedException(getMessage("en", "mpc-slave-error"))
        self.__mpcExistenceChecking.start() 

    def openFile(self, filePath):
        self.__listener.SendCommand(self.CMD_OPENFILE, filePath)
    
    def isPaused(self):
        return (self.playState <> self.__MPC_PLAYSTATE.PS_PLAY and self.playState <> None)
 
    def askForVersion(self):
        self.__listener.SendCommand(self.CMD_GETVERSION)
 
    @waitForFileStateReady
    def pause(self):
        self.__listener.SendCommand(self.CMD_PAUSE)
 
    @waitForFileStateReady
    def playPause(self):
        self.__listener.SendCommand(self.CMD_PLAYPAUSE)
     
    @waitForFileStateReady
    def unpause(self):
        self.__listener.SendCommand(self.CMD_PLAY)
 
    @waitForFileStateReady
    def askForCurrentPosition(self):
        self.__listener.SendCommand(self.CMD_GETCURRENTPOSITION)

    @waitForFileStateReady
    def seek(self, position):
        self.__listener.SendCommand(self.CMD_SETPOSITION, unicode(position))

    @waitForFileStateReady
    def setSpeed(self, rate):
        self.__listener.SendCommand(self.CMD_SETSPEED, unicode(rate))

    def sendOsd(self, message, MsgPos=constants.MPC_OSD_POSITION, DurationMs=(constants.OSD_DURATION*1000)):
        message = message.decode()
        class __OSDDATASTRUCT(ctypes.Structure):
            _fields_ = [
                ('nMsgPos', ctypes.c_int32),
                ('nDurationMS', ctypes.c_int32),
                ('strMsg', ctypes.c_wchar * (len(message) + 1))
            ]    
        cmessage = __OSDDATASTRUCT() 
        cmessage.nMsgPos = MsgPos 
        cmessage.nDurationMS = DurationMs 
        cmessage.strMsg = message
        self.__listener.SendCommand(self.CMD_OSDSHOWMESSAGE, cmessage)
        
    def sendRawCommand(self, cmd, value):
        self.__listener.SendCommand(cmd, value)

    def handleCommand(self, cmd, value):
        if (cmd == self.CMD_CONNECT): 
            self.__listener.mpcHandle = int(value)
            self.__locks.mpcStart.set()
            if(self.callbacks.onConnected): 
                thread.start_new_thread(self.callbacks.onConnected, ())
                
{'fraction_non_alphanumeric': 0.09842009842009843, 'fraction_numerical': 0.005309505309505309, 'mean_word_length': 2.8346573982125123, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '4192212', 'n_tokens_mistral': 2399, 'n_tokens_neox': 2312, 'n_words': 415}