def notify_win(title, text): try: from servo.win32_toast import WindowsToast w = WindowsToast() w.balloon_tip(title, text) except: from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto(("FlashWindowEx", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C params = FLASHWINDOW(sizeof(FLASHWINDOW), windll.kernel32.GetConsoleWindow(), FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params)
def notify(self, msg): """Show a desktop notification with the supplied message On Linux and Mac, this will show a desktop notification with the message, but on Windows we can only flash the screen. """ moz_nospam = os.environ.get('MOZ_NOSPAM') if moz_nospam: return try: if sys.platform.startswith('darwin'): try: notifier = which.which('terminal-notifier') except which.WhichError: raise Exception('Install terminal-notifier to get ' 'a notification when the build finishes.') self.run_process([notifier, '-title', 'Mozilla Build System', '-group', 'mozbuild', '-message', msg], ensure_exit_code=False) elif sys.platform.startswith('linux'): try: import dbus except ImportError: raise Exception('Install the python dbus module to ' 'get a notification when the build finishes.') bus = dbus.SessionBus() notify = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications') method = notify.get_dbus_method('Notify', 'org.freedesktop.Notifications') method('Mozilla Build System', 0, '', msg, '', [], [], -1) elif sys.platform.startswith('win'): from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto(("FlashWindowEx", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C # GetConsoleWindows returns NULL if no console is attached. We # can't flash nothing. console = windll.kernel32.GetConsoleWindow() if not console: return params = FLASHWINDOW(sizeof(FLASHWINDOW), console, FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params) except Exception as e: self.log(logging.WARNING, 'notifier-failed', {'error': e.message}, 'Notification center failed: {error}')
def notify(self, msg): """Show a desktop notification with the supplied message On Linux and Mac, this will show a desktop notification with the message, but on Windows we can only flash the screen. """ moz_nospam = os.environ.get('MOZ_NOSPAM') if moz_nospam: return try: if sys.platform.startswith('darwin'): notifier = which('terminal-notifier') if not notifier: raise Exception('Install terminal-notifier to get ' 'a notification when the build finishes.') self.run_process([notifier, '-title', 'Mozilla Build System', '-group', 'mozbuild', '-message', msg], ensure_exit_code=False) elif sys.platform.startswith('win'): from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto(("FlashWindowEx", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C # GetConsoleWindows returns NULL if no console is attached. We # can't flash nothing. console = windll.kernel32.GetConsoleWindow() if not console: return params = FLASHWINDOW(sizeof(FLASHWINDOW), console, FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params) else: notifier = which('notify-send') if not notifier: raise Exception('Install notify-send (usually part of ' 'the libnotify package) to get a notification when ' 'the build finishes.') self.run_process([notifier, '--app-name=Mozilla Build System', 'Mozilla Build System', msg], ensure_exit_code=False) except Exception as e: self.log(logging.WARNING, 'notifier-failed', {'error': str(e)}, 'Notification center failed: {error}')
def notify(elapsed): if elapsed < 30: return if sys.platform.startswith('linux'): try: import dbus bus = dbus.SessionBus() notify_obj = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications') method = notify_obj.get_dbus_method( 'Notify', 'org.freedesktop.Notifications') method('Servo Build System', 0, '', ' Servo build complete!', '', [], [], -1) except: print( "[Warning] Could not generate notification! Please make sure that the python dbus module is installed!" ) elif sys.platform.startswith('win'): try: from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto( ("FlashWindowEx", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C params = FLASHWINDOW( sizeof(FLASHWINDOW), windll.kernel32.GetConsoleWindow(), FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params) except: print( "[Warning] Could not generate notification! Please make sure that the required libraries are installed!" ) elif sys.platform.startswith('darwin'): # Notification code for Darwin here! For the time being printing simple msg print( "[Warning] : Darwin System! Notifications not supported currently!" )
def recognize_forever(self): """ Recognize speech in a loop. This will also call any scheduled timer functions and ensure that the correct window context is used. """ # Register for window change events to activate/deactivate grammars # and rules on window changes. This is done here because the SAPI5 # 'OnPhraseStart' grammar callback is called after grammar state # changes are allowed. WinEventProcType = WINFUNCTYPE(None, HANDLE, DWORD, HWND, LONG, LONG, DWORD, DWORD) def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime): window = Window.get_foreground() if hwnd == window.handle: for grammar in self.grammars: # Prevent 'notify_begin()' from being called. if grammar.name == "_recobs_grammar": continue grammar.process_begin(window.executable, window.title, window.handle) def set_hook(win_event_proc, event_type): return windll.user32.SetWinEventHook( event_type, event_type, 0, win_event_proc, 0, 0, win32con.WINEVENT_OUTOFCONTEXT) win_event_proc = WinEventProcType(callback) windll.user32.SetWinEventHook.restype = HANDLE [ set_hook(win_event_proc, et) for et in { win32con.EVENT_SYSTEM_FOREGROUND, win32con.EVENT_OBJECT_NAMECHANGE, } ] # Recognize speech, call timer functions and handle window change # events in a loop. self.speak('beginning loop!') while 1: pythoncom.PumpWaitingMessages() self._call_timer_callback() time.sleep(0.07)
def notify(msg, title='Notification', group='nwgh-py'): """Use the OS notification service to show a notification to the user. Args: msg: <string> message to put in notification title: <string, optional> title of notification group: <string, optional> where to group notification (OS X only) """ if sys.platform.startswith('darwin'): notifier = shutil.which('terminal-notifier') if not notifier: raise MissingUtilityException( 'Install terminal-notifier to get notifications') subprocess.call( [notifier, '-title', title, '-group', group, '-message', msg]) elif sys.platform.startswith('win'): from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto(("FlashWindowEX", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C console = windll.kernel32.GetConsoleWindow() if not console: raise MissingUtilityException('Could not find console window') params = FLASHWINDOW(sizeof(FLASHWINDOW), console, FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params) else: # linux notifier = shutil.which('notify-send') if not notifier: raise MissingUtilityException( 'Install notify-send to get notifications') subprocess.call([notifier, '--app-name=%s' % (title, ), title, msg])
def build(self, what=None, disable_extra_make_dependencies=None, jobs=0, verbose=False): import which from mozbuild.controller.building import BuildMonitor from mozbuild.util import resolve_target_to_make self.log_manager.register_structured_logger( logging.getLogger('mozbuild')) warnings_path = self._get_state_filename('warnings.json') monitor = self._spawn(BuildMonitor) monitor.init(warnings_path) ccache_start = monitor.ccache_stats() with BuildOutputManager(self.log_manager, monitor) as output: monitor.start() if what: top_make = os.path.join(self.topobjdir, 'Makefile') if not os.path.exists(top_make): print('Your tree has not been configured yet. Please run ' '|mach build| with no arguments.') return 1 # Collect target pairs. target_pairs = [] for target in what: path_arg = self._wrap_path_argument(target) make_dir, make_target = resolve_target_to_make( self.topobjdir, path_arg.relpath()) if make_dir is None and make_target is None: return 1 # See bug 886162 - we don't want to "accidentally" build # the entire tree (if that's really the intent, it's # unlikely they would have specified a directory.) if not make_dir and not make_target: print("The specified directory doesn't contain a " "Makefile and the first parent with one is the " "root of the tree. Please specify a directory " "with a Makefile or run |mach build| if you " "want to build the entire tree.") return 1 target_pairs.append((make_dir, make_target)) # Possibly add extra make depencies using dumbmake. if not disable_extra_make_dependencies: from dumbmake.dumbmake import (dependency_map, add_extra_dependencies) depfile = os.path.join(self.topsrcdir, 'build', 'dumbmake-dependencies') with open(depfile) as f: dm = dependency_map(f.readlines()) new_pairs = list(add_extra_dependencies(target_pairs, dm)) self.log( logging.DEBUG, 'dumbmake', { 'target_pairs': target_pairs, 'new_pairs': new_pairs }, 'Added extra dependencies: will build {new_pairs} ' + 'instead of {target_pairs}.') target_pairs = new_pairs # Ensure build backend is up to date. The alternative is to # have rules in the invoked Makefile to rebuild the build # backend. But that involves make reinvoking itself and there # are undesired side-effects of this. See bug 877308 for a # comprehensive history lesson. self._run_make(directory=self.topobjdir, target='backend.RecursiveMakeBackend', line_handler=output.on_line, log=False, print_directory=False) # Build target pairs. for make_dir, make_target in target_pairs: # We don't display build status messages during partial # tree builds because they aren't reliable there. This # could potentially be fixed if the build monitor were more # intelligent about encountering undefined state. status = self._run_make( directory=make_dir, target=make_target, line_handler=output.on_line, log=False, print_directory=False, ensure_exit_code=False, num_jobs=jobs, silent=not verbose, append_env={b'NO_BUILDSTATUS_MESSAGES': b'1'}) if status != 0: break else: monitor.start_resource_recording() status = self._run_make(srcdir=True, filename='client.mk', line_handler=output.on_line, log=False, print_directory=False, allow_parallel=False, ensure_exit_code=False, num_jobs=jobs, silent=not verbose) make_extra = self.mozconfig['make_extra'] or [] make_extra = dict(m.split('=', 1) for m in make_extra) # For universal builds, we need to run the automation steps in # the first architecture from MOZ_BUILD_PROJECTS projects = make_extra.get('MOZ_BUILD_PROJECTS') if projects: subdir = os.path.join(self.topobjdir, projects.split()[0]) else: subdir = self.topobjdir moz_automation = os.getenv('MOZ_AUTOMATION') or make_extra.get( 'export MOZ_AUTOMATION', None) if moz_automation and status == 0: status = self._run_make(target='automation/build', directory=subdir, line_handler=output.on_line, log=False, print_directory=False, ensure_exit_code=False, num_jobs=jobs, silent=not verbose) self.log(logging.WARNING, 'warning_summary', {'count': len(monitor.warnings_database)}, '{count} compiler warnings present.') monitor.finish(record_usage=status == 0) high_finder, finder_percent = monitor.have_high_finder_usage() if high_finder: print(FINDER_SLOW_MESSAGE % finder_percent) ccache_end = monitor.ccache_stats() if ccache_start and ccache_end: ccache_diff = ccache_end - ccache_start if ccache_diff: self.log(logging.INFO, 'ccache', {'msg': ccache_diff.hit_rate_message()}, "{msg}") moz_nospam = os.environ.get('MOZ_NOSPAM') if monitor.elapsed > 300 and not moz_nospam: # Display a notification when the build completes. # This could probably be uplifted into the mach core or at least # into a helper API. It is here as an experimentation to see how it # is received. try: if sys.platform.startswith('darwin'): try: notifier = which.which('terminal-notifier') except which.WhichError: raise Exception( 'Install terminal-notifier to get ' 'a notification when the build finishes.') self.run_process([ notifier, '-title', 'Mozilla Build System', '-group', 'mozbuild', '-message', 'Build complete' ], ensure_exit_code=False) elif sys.platform.startswith('linux'): try: import dbus except ImportError: raise Exception( 'Install the python dbus module to ' 'get a notification when the build finishes.') bus = dbus.SessionBus() notify = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications') method = notify.get_dbus_method( 'Notify', 'org.freedesktop.Notifications') method('Mozilla Build System', 0, '', 'Build complete', '', [], [], -1) elif sys.platform.startswith('win'): from ctypes import Structure, windll, POINTER, sizeof from ctypes.wintypes import DWORD, HANDLE, WINFUNCTYPE, BOOL, UINT class FLASHWINDOW(Structure): _fields_ = [("cbSize", UINT), ("hwnd", HANDLE), ("dwFlags", DWORD), ("uCount", UINT), ("dwTimeout", DWORD)] FlashWindowExProto = WINFUNCTYPE(BOOL, POINTER(FLASHWINDOW)) FlashWindowEx = FlashWindowExProto( ("FlashWindowEx", windll.user32)) FLASHW_CAPTION = 0x01 FLASHW_TRAY = 0x02 FLASHW_TIMERNOFG = 0x0C params = FLASHWINDOW( sizeof(FLASHWINDOW), windll.kernel32.GetConsoleWindow(), FLASHW_CAPTION | FLASHW_TRAY | FLASHW_TIMERNOFG, 3, 0) FlashWindowEx(params) except Exception as e: self.log(logging.WARNING, 'notifier-failed', {'error': e.message}, 'Notification center failed: {error}') if status: return status long_build = monitor.elapsed > 600 if long_build: output.on_line( 'We know it took a while, but your build finally finished successfully!' ) else: output.on_line('Your build was successful!') if monitor.have_resource_usage: excessive, swap_in, swap_out = monitor.have_excessive_swapping() # if excessive: # print(EXCESSIVE_SWAP_MESSAGE) print('To view resource usage of the build, run |mach ' 'resource-usage|.') # Only for full builds because incremental builders likely don't # need to be burdened with this. if not what: try: # Fennec doesn't have useful output from just building. We should # arguably make the build action useful for Fennec. Another day... if self.substs['MOZ_BUILD_APP'] != 'mobile/android': print( 'To take your build for a test drive, run: |mach run|') app = self.substs['MOZ_BUILD_APP'] if app in ('browser', 'mobile/android'): print( 'For more information on what to do now, see ' 'https://developer.mozilla.org/docs/Developer_Guide/So_You_Just_Built_Firefox' ) except Exception: # Ignore Exceptions in case we can't find config.status (such # as when doing OSX Universal builds) pass return status
from ctypes import windll, POINTER, byref, WinError from ctypes.wintypes import WINFUNCTYPE, HANDLE, DWORD, BOOL INFINITE = -1 WAIT_FAILED = 0xFFFFFFFF LPDWORD = POINTER(DWORD) _GetExitCodeProcessProto = WINFUNCTYPE(BOOL, HANDLE, LPDWORD) _GetExitCodeProcess = _GetExitCodeProcessProto( ("GetExitCodeProcess", windll.kernel32)) def GetExitCodeProcess(h): exitcode = DWORD() r = _GetExitCodeProcess(h, byref(exitcode)) if r is 0: raise WinError() return exitcode.value _WaitForMultipleObjectsProto = WINFUNCTYPE(DWORD, DWORD, POINTER(HANDLE), BOOL, DWORD) _WaitForMultipleObjects = _WaitForMultipleObjectsProto( ("WaitForMultipleObjects", windll.kernel32)) def WaitForAnyProcess(processes): arrtype = HANDLE * len(processes) harray = arrtype(*(int(p._handle) for p in processes)) r = _WaitForMultipleObjects(len(processes), harray, False, INFINITE)
_EnumDisplayMonitors = EnumDisplayMonitors def EnumDisplayMonitors(): results = [] def _callback(monitor, dc, rect, data): results.append(monitor) return 1 callback = MonitorEnumProc(_callback) _EnumDisplayMonitors(0, 0, callback, 0) return results WNDPROC = WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM) class WNDCLASSEX(Structure): _fields_ = [ ("cbSize", UINT), ("style", UINT), ("lpfnWndProc", WNDPROC), ("cbClsExtra", INT), ("cbWndExtra", INT), ("hInstance", HANDLE), ("hIcon", HANDLE), ("hCursor", HANDLE), ("hbrBackground", HANDLE), ("lpszMenuName", LPCWSTR), ("lpszClassName", LPCWSTR),
WSAID_CONNECTEX = GUID(0x25a207b9,0xddf3,0x4660, (c_ubyte * 8)(0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e)) """ BOOL PASCAL ConnectEx( __in SOCKET s, __in const struct sockaddr *name, __in int namelen, __in_opt PVOID lpSendBuffer, __in DWORD dwSendDataLength, __out LPDWORD lpdwBytesSent, __in LPOVERLAPPED lpOverlapped ); """ ConnectExFunc = WINFUNCTYPE(BOOL, SOCKET, sockaddr_inp, c_int, c_void_p, DWORD, POINTER(DWORD), POINTER(OVERLAPPED)) class socket: def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP): StartManager() _socket = WSASocket(family, type, proto, None, 0, WSA_FLAG_OVERLAPPED) if _socket == INVALID_SOCKET: raise WinError() # Bind the socket to the shared IO completion port. CreateIoCompletionPort(_socket, hIOCP, _socket, NULL) self.wsFnConnectEx = ConnectExFunc() dwBytes = DWORD() ret = WSAIoctl(_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, byref(WSAID_CONNECTEX), sizeof(WSAID_CONNECTEX), byref(self.wsFnConnectEx), sizeof(self.wsFnConnectEx), byref(dwBytes), cast(0, POINTER(OVERLAPPED)), 0)