├── .github └── workflows │ └── python-publish.yml ├── .gitmodules ├── 45dd60cb7ef14bd4bfeb4c9061919e67.png ├── CONSTANTS.py ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── __init__.py ├── __pycache__ ├── CONSTANTS.cpython-310.pyc ├── __init__.cpython-310.pyc ├── info.cpython-310.pyc └── mac_terminal.cpython-310.pyc ├── alerts_cmd.sh ├── audio_cmd.sh ├── camera_cmd.sh ├── exceptions.py ├── info.py ├── install_dependencies.sh ├── macos ├── CONSTANTS.py ├── __init__.py ├── app_config.py ├── app_system.py ├── audiorecorder.py ├── background_screen.py ├── bluetooth.py ├── brightness.py ├── buffer.py ├── devices.py ├── exceptions.py ├── file_config.py ├── illumination.py ├── mouse.py ├── notifier.py ├── open.py ├── password.py ├── rotate.py ├── sound.py ├── sys_config.py ├── theme.py ├── usb.py ├── volume.py ├── webcamera.py └── wifi.py ├── voices.txt └── windows ├── __init__.py ├── brightness.py ├── exceptions.py ├── notifier.py └── password.py /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | release: 13 | types: [published] 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | deploy: 20 | 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@v3 25 | - name: Set up Python 26 | uses: actions/setup-python@v3 27 | with: 28 | python-version: '3.x' 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install build 33 | - name: Build package 34 | run: python -m build 35 | - name: Publish package 36 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 37 | with: 38 | user: __token__ 39 | password: ${{ secrets.PYPI_API_TOKEN }} 40 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "blueutil"] 2 | path = blueutil 3 | url = https://github.com/toy/blueutil 4 | [submodule "brightness"] 5 | path = brightness 6 | url = https://github.com/nriley/brightness 7 | [submodule "brew"] 8 | path = brew 9 | url = https://github.com/Homebrew/brew 10 | -------------------------------------------------------------------------------- /45dd60cb7ef14bd4bfeb4c9061919e67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/45dd60cb7ef14bd4bfeb4c9061919e67.png -------------------------------------------------------------------------------- /CONSTANTS.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "SOUNDS_SUBMARINE_SOUND", 3 | 'SOUNDS_PING_SOUND', 4 | 'SOUNDS_FUNK_SOUND', 5 | 'SOUNDS_POP_SOUND', 6 | 'SOUNDS_BLOW_SOUND', 7 | 'SOUNDS_GLASS_SOUND', 8 | 'BLUE_COLOR', 9 | 'RED_COLOR', 10 | 'GREEN_COLOR', 11 | 'BLACK_COLOR', 12 | 'YELLOW_COLOR' 13 | ] 14 | 15 | 16 | # Sounds list 17 | 18 | 19 | SOUNDS_SUBMARINE_SOUND = 'Submarine' 20 | 21 | SOUNDS_POP_SOUND = 'Pop' 22 | 23 | 24 | SOUNDS_FUNK_SOUND = 'Funk' 25 | 26 | 27 | SOUNDS_GLASS_SOUND = 'Glass' 28 | 29 | SOUNDS_PING_SOUND = 'Ping' 30 | 31 | 32 | SOUNDS_BLOW_SOUND = 'Blow' 33 | 34 | 35 | """Taken from Pyautogui Documentation""" 36 | 37 | KeyHexType = { 38 | 'a': 0x00, # kVK_ANSI_A 39 | 's': 0x01, # kVK_ANSI_S 40 | 'd': 0x02, # kVK_ANSI_D 41 | 'f': 0x03, # kVK_ANSI_F 42 | 'h': 0x04, # kVK_ANSI_H 43 | 'g': 0x05, # kVK_ANSI_G 44 | 'z': 0x06, # kVK_ANSI_Z 45 | 'x': 0x07, # kVK_ANSI_X 46 | 'c': 0x08, # kVK_ANSI_C 47 | 'v': 0x09, # kVK_ANSI_V 48 | 'b': 0x0b, # kVK_ANSI_B 49 | 'q': 0x0c, # kVK_ANSI_Q 50 | 'w': 0x0d, # kVK_ANSI_W 51 | 'e': 0x0e, # kVK_ANSI_E 52 | 'r': 0x0f, # kVK_ANSI_R 53 | 'y': 0x10, # kVK_ANSI_Y 54 | 't': 0x11, # kVK_ANSI_T 55 | '1': 0x12, # kVK_ANSI_1 56 | '!': 0x12, # kVK_ANSI_1 57 | '2': 0x13, # kVK_ANSI_2 58 | '@': 0x13, # kVK_ANSI_2 59 | '3': 0x14, # kVK_ANSI_3 60 | '#': 0x14, # kVK_ANSI_3 61 | '4': 0x15, # kVK_ANSI_4 62 | '$': 0x15, # kVK_ANSI_4 63 | '6': 0x16, # kVK_ANSI_6 64 | '^': 0x16, # kVK_ANSI_6 65 | '5': 0x17, # kVK_ANSI_5 66 | '%': 0x17, # kVK_ANSI_5 67 | '=': 0x18, # kVK_ANSI_Equal 68 | '+': 0x18, # kVK_ANSI_Equal 69 | '9': 0x19, # kVK_ANSI_9 70 | '(': 0x19, # kVK_ANSI_9 71 | '7': 0x1a, # kVK_ANSI_7 72 | '&': 0x1a, # kVK_ANSI_7 73 | '-': 0x1b, # kVK_ANSI_Minus 74 | '_': 0x1b, # kVK_ANSI_Minus 75 | '8': 0x1c, # kVK_ANSI_8 76 | '*': 0x1c, # kVK_ANSI_8 77 | '0': 0x1d, # kVK_ANSI_0 78 | ')': 0x1d, # kVK_ANSI_0 79 | ']': 0x1e, # kVK_ANSI_RightBracket 80 | '}': 0x1e, # kVK_ANSI_RightBracket 81 | 'o': 0x1f, # kVK_ANSI_O 82 | 'u': 0x20, # kVK_ANSI_U 83 | '[': 0x21, # kVK_ANSI_LeftBracket 84 | '{': 0x21, # kVK_ANSI_LeftBracket 85 | 'i': 0x22, # kVK_ANSI_I 86 | 'p': 0x23, # kVK_ANSI_P 87 | 'l': 0x25, # kVK_ANSI_L 88 | 'j': 0x26, # kVK_ANSI_J 89 | "'": 0x27, # kVK_ANSI_Quote 90 | '"': 0x27, # kVK_ANSI_Quote 91 | 'k': 0x28, # kVK_ANSI_K 92 | ';': 0x29, # kVK_ANSI_Semicolon 93 | ':': 0x29, # kVK_ANSI_Semicolon 94 | '\\': 0x2a, # kVK_ANSI_Backslash 95 | '|': 0x2a, # kVK_ANSI_Backslash 96 | ',': 0x2b, # kVK_ANSI_Comma 97 | '<': 0x2b, # kVK_ANSI_Comma 98 | '/': 0x2c, # kVK_ANSI_Slash 99 | '?': 0x2c, # kVK_ANSI_Slash 100 | 'n': 0x2d, # kVK_ANSI_N 101 | 'm': 0x2e, # kVK_ANSI_M 102 | '.': 0x2f, # kVK_ANSI_Period 103 | '>': 0x2f, # kVK_ANSI_Period 104 | '`': 0x32, # kVK_ANSI_Grave 105 | '~': 0x32, # kVK_ANSI_Grave 106 | ' ': 0x31, # kVK_Space 107 | 'space': 0x31, 108 | '\r': 0x24, # kVK_Return 109 | '\n': 0x24, # kVK_Return 110 | 'enter': 0x24, # kVK_Return 111 | 'return': 0x24, # kVK_Return 112 | '\t': 0x30, # kVK_Tab 113 | 'tab': 0x30, # kVK_Tab 114 | 'backspace': 0x33, # kVK_Delete, which is "Backspace" on OS X. 115 | '\b': 0x33, # kVK_Delete, which is "Backspace" on OS X. 116 | 'esc': 0x35, # kVK_Escape 117 | 'escape': 0x35, # kVK_Escape 118 | 'command': 0x37, # kVK_Command 119 | 'shift': 0x38, # kVK_Shift 120 | 'shiftleft': 0x38, # kVK_Shift 121 | 'capslock': 0x39, # kVK_CapsLock 122 | 'option': 0x3a, # kVK_Option 123 | 'optionleft': 0x3a, # kVK_Option 124 | 'alt': 0x3a, # kVK_Option 125 | 'altleft': 0x3a, # kVK_Option 126 | 'ctrl': 0x3b, # kVK_Control 127 | 'ctrlleft': 0x3b, # kVK_Control 128 | 'shiftright': 0x3c, # kVK_RightShift 129 | 'optionright': 0x3d, # kVK_RightOption 130 | 'ctrlright': 0x3e, # kVK_RightControl 131 | 'fn': 0x3f, # kVK_Function 132 | 'f17': 0x40, # kVK_F17 133 | 'volumeup': 0x48, # kVK_VolumeUp 134 | 'volumedown': 0x49, # kVK_VolumeDown 135 | 'volumemute': 0x4a, # kVK_Mute 136 | 'f18': 0x4f, # kVK_F18 137 | 'f19': 0x50, # kVK_F19 138 | 'f20': 0x5a, # kVK_F20 139 | 'f5': 0x60, # kVK_F5 140 | 'f6': 0x61, # kVK_F6 141 | 'f7': 0x62, # kVK_F7 142 | 'f3': 0x63, # kVK_F3 143 | 'f8': 0x64, # kVK_F8 144 | 'f9': 0x65, # kVK_F9 145 | 'f11': 0x67, # kVK_F11 146 | 'f13': 0x69, # kVK_F13 147 | 'f16': 0x6a, # kVK_F16 148 | 'f14': 0x6b, # kVK_F14 149 | 'f10': 0x6d, # kVK_F10 150 | 'f12': 0x6f, # kVK_F12 151 | 'f15': 0x71, # kVK_F15 152 | 'help': 0x72, # kVK_Help 153 | 'home': 0x73, # kVK_Home 154 | 'pageup': 0x74, # kVK_PageUp 155 | 'pgup': 0x74, # kVK_PageUp 156 | 'del': 0x75, # kVK_ForwardDelete 157 | 'delete': 0x75, # kVK_ForwardDelete 158 | 'f4': 0x76, # kVK_F4 159 | 'end': 0x77, # kVK_End 160 | 'f2': 0x78, # kVK_F2 161 | 'pagedown': 0x79, # kVK_PageDown 162 | 'pgdn': 0x79, # kVK_PageDown 163 | 'f1': 0x7a, # kVK_F1 164 | 'left': 0x7b, # kVK_LeftArrow 165 | 'right': 0x7c, # kVK_RightArrow 166 | 'down': 0x7d, # kVK_DownArrow 167 | 'up': 0x7e, # kVK_UpArrow 168 | 'yen': 0x5d, # kVK_JIS_Yen 169 | 'underscore' : 0x5e, # kVK_JIS_Underscore (only applies to Japanese keyboards) 170 | 'comma': 0x5f, # kVK_JIS_KeypadComma (only applies to Japanese keyboards) 171 | 'eisu': 0x66, # kVK_JIS_Eisu 172 | 'kana': 0x68, # kVK_JIS_Kana 173 | } 174 | 175 | RED_COLOR = 'red' 176 | 177 | GREEN_COLOR = 'green' 178 | 179 | YELLOW_COLOR = 'yellow' 180 | 181 | BLUE_COLOR = 'blue' 182 | 183 | BLACK_COLOR = 'black' 184 | 185 | # END FILE 186 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Alexandr Bosov Vladimirovich. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # ---------------------- # 3 | # Initialize scripts 4 | 5 | from sys import platform 6 | 7 | 8 | if platform == 'linux': 9 | 10 | from ._linux_engine import LinuxCmd 11 | 12 | elif platform == 'darwin': 13 | 14 | from ._mac_engine import MacCmd # The project frozen until unknown time from July 4 2023 - ??? 15 | 16 | elif platform == 'win32': 17 | 18 | from ._windows_engine import WindowsCmd 19 | 20 | else: 21 | raise OSError() 22 | 23 | 24 | if __name__ == '__main__': 25 | pass 26 | 27 | 28 | # -------------------------- # 29 | 30 | -------------------------------------------------------------------------------- /__pycache__/CONSTANTS.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/__pycache__/CONSTANTS.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/info.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/__pycache__/info.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/mac_terminal.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/__pycache__/mac_terminal.cpython-310.pyc -------------------------------------------------------------------------------- /alerts_cmd.sh: -------------------------------------------------------------------------------- 1 | #(notifies) 2 | 3 | terminal-notifier -message "Hello, this is my message" -title "Message Title" 4 | 5 | osascript -e 'display notification "Notification text" with title "Notification Title" subtitle "Notification sub-title" sound name "Pop"' 6 | echo Successful 7 | -------------------------------------------------------------------------------- /audio_cmd.sh: -------------------------------------------------------------------------------- 1 | # Shell command for test installed commands 2 | 3 | /opt/local/bin/ffmpeg -f avfoundation -i ":0" -t 10 audio.mp3 4 | -------------------------------------------------------------------------------- /camera_cmd.sh: -------------------------------------------------------------------------------- 1 | # Test shell code for release an image. 2 | 3 | /opt/local/bin/ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -i "0" -vframes 1 cam_img.png 4 | 5 | -------------------------------------------------------------------------------- /exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Individual exceptions for driver_controller 4 | 5 | """ 6 | 7 | try: 8 | exc = ExceptionGroup 9 | except NameError: 10 | exc = ReferenceError 11 | 12 | 13 | class ApplicationNameError(NameError): 14 | """ 15 | App with pointed out name not exist. 16 | """ 17 | 18 | 19 | class ApplicationNotExist(SystemError): 20 | """ 21 | Application, which you point outed is not exist 22 | """ 23 | 24 | 25 | class UnsupportedFormat(FileExistsError): 26 | """ 27 | Method screenshot support only ['png', 'jpg', 'ico', 'gif', 'pict'] formats. 28 | """ 29 | 30 | 31 | class ConfirmationError(TypeError): 32 | """ 33 | If confirmation is [False]. 34 | """ 35 | 36 | 37 | class InvalidExtension(NameError): 38 | """ 39 | No extension specified. 40 | """ 41 | 42 | 43 | class WifiNameConnectError(NameError): 44 | """ 45 | Password or SSID/Wi-fi name of Network is not right. 46 | """ 47 | 48 | 49 | class ValueBrightnessError(ValueError, TypeError): 50 | """ 51 | Value is not type [int]. 52 | """ 53 | 54 | 55 | class WifiValueError(ValueError, BaseException): 56 | """ 57 | There is no wi-fi network in util "bunch keys". 58 | """ 59 | 60 | 61 | class ExtensionError(ValueError): 62 | pass 63 | 64 | 65 | class PathError(FileNotFoundError): 66 | pass 67 | 68 | 69 | class CallError(exc): 70 | pass 71 | 72 | 73 | class RgbValueError(ValueError): 74 | """No available color for bg""" 75 | pass 76 | 77 | 78 | class OpenPossibilityError(FileExistsError): 79 | """Can not open file in that app.""" 80 | 81 | 82 | class ScreenErrorIndex(IndexError): 83 | """Screen ID not exist.""" 84 | 85 | 86 | class ScreenWarning(Warning): 87 | """Not support bridge with objective-c and python via IOKit.""" 88 | 89 | 90 | class BluetoothConnectionError(ConnectionRefusedError): 91 | """Specify not right address to pair.""" 92 | 93 | # END FILE 94 | -------------------------------------------------------------------------------- /info.py: -------------------------------------------------------------------------------- 1 | 2 | # ----------------------- # 3 | __author__ = 'AlexAndro1112' 4 | 5 | __version__ = '1.0.3' 6 | 7 | __author_email__ = 'aleksandrbosov872@gmail.com' 8 | 9 | __year_create__ = '2022' 10 | __all__ = [ 11 | '__version__', '__author__', '__year_create__', '__author_email__'] 12 | 13 | if __name__ == '__main__': 14 | pass 15 | -------------------------------------------------------------------------------- /install_dependencies.sh: -------------------------------------------------------------------------------- 1 | /usr/bin/sh 2 | $ response=' ' 3 | 4 | GREEN='\033[0;32m' 5 | YELLOW='\033[0;33m' 6 | 7 | plt=$(uname) 8 | if [[ "$plt" == 'Linux' ]]; then 9 | $ response='Your Platform:Ubuntu(Linux): Wait installation..' 10 | cd ~ 11 | # ܿܿܿܿܿܿܿܿܿܿܿܿܿܿܿܿReplace '~' to working path to directory 12 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 13 | brew install ffmpeg 14 | brew install blueutil 15 | brew install brightness 16 | brew install terminal-notifier && echo -e "${GREEN} Successful!" 17 | elif [[ "$plt" == 'Darwin' ]]; then 18 | $ responses= 'Your Platform:Mac-os: Wait installation..' 19 | cd /Users//PycharmProjects/~ 20 | # ܿܿܿܿܿܿܿܿܿܿܿܿܿܿܿܿReplace '~' to working path to directory 21 | brew install ffmpeg 22 | brew install blueutil 23 | brew install brightness 24 | brew install terminal-notifier && echo -e "${GREEN} Successful!" 25 | 26 | 27 | elif [[ "$plt" == 'Win32' ]]; then 28 | echo "${YELLOW} For windows no dependencies. Run Code." 29 | exit 1; 30 | else 31 | echo "platform "$plt" not support." 32 | 33 | 34 | fi 35 | -------------------------------------------------------------------------------- /macos/CONSTANTS.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "SOUNDS_SUBMARINE_SOUND", 3 | 'SOUNDS_PING_SOUND', 4 | 'SOUNDS_FUNK_SOUND', 5 | 'SOUNDS_POP_SOUND', 6 | 'SOUNDS_BLOW_SOUND', 7 | 'SOUNDS_GLASS_SOUND', 8 | 'BLUE_COLOR', 9 | 'RED_COLOR', 10 | 'GREEN_COLOR', 11 | 'BLACK_COLOR', 12 | 'YELLOW_COLOR' 13 | ] 14 | 15 | 16 | # Sounds list 17 | 18 | 19 | SOUNDS_SUBMARINE_SOUND = 'Submarine' 20 | 21 | SOUNDS_POP_SOUND = 'Pop' 22 | 23 | 24 | SOUNDS_FUNK_SOUND = 'Funk' 25 | 26 | 27 | SOUNDS_GLASS_SOUND = 'Glass' 28 | 29 | SOUNDS_PING_SOUND = 'Ping' 30 | 31 | 32 | SOUNDS_BLOW_SOUND = 'Blow' 33 | 34 | 35 | """Taken from Pyautogui Documentation""" 36 | 37 | KeyHexType = { 38 | 'a': 0x00, # kVK_ANSI_A 39 | 's': 0x01, # kVK_ANSI_S 40 | 'd': 0x02, # kVK_ANSI_D 41 | 'f': 0x03, # kVK_ANSI_F 42 | 'h': 0x04, # kVK_ANSI_H 43 | 'g': 0x05, # kVK_ANSI_G 44 | 'z': 0x06, # kVK_ANSI_Z 45 | 'x': 0x07, # kVK_ANSI_X 46 | 'c': 0x08, # kVK_ANSI_C 47 | 'v': 0x09, # kVK_ANSI_V 48 | 'b': 0x0b, # kVK_ANSI_B 49 | 'q': 0x0c, # kVK_ANSI_Q 50 | 'w': 0x0d, # kVK_ANSI_W 51 | 'e': 0x0e, # kVK_ANSI_E 52 | 'r': 0x0f, # kVK_ANSI_R 53 | 'y': 0x10, # kVK_ANSI_Y 54 | 't': 0x11, # kVK_ANSI_T 55 | '1': 0x12, # kVK_ANSI_1 56 | '!': 0x12, # kVK_ANSI_1 57 | '2': 0x13, # kVK_ANSI_2 58 | '@': 0x13, # kVK_ANSI_2 59 | '3': 0x14, # kVK_ANSI_3 60 | '#': 0x14, # kVK_ANSI_3 61 | '4': 0x15, # kVK_ANSI_4 62 | '$': 0x15, # kVK_ANSI_4 63 | '6': 0x16, # kVK_ANSI_6 64 | '^': 0x16, # kVK_ANSI_6 65 | '5': 0x17, # kVK_ANSI_5 66 | '%': 0x17, # kVK_ANSI_5 67 | '=': 0x18, # kVK_ANSI_Equal 68 | '+': 0x18, # kVK_ANSI_Equal 69 | '9': 0x19, # kVK_ANSI_9 70 | '(': 0x19, # kVK_ANSI_9 71 | '7': 0x1a, # kVK_ANSI_7 72 | '&': 0x1a, # kVK_ANSI_7 73 | '-': 0x1b, # kVK_ANSI_Minus 74 | '_': 0x1b, # kVK_ANSI_Minus 75 | '8': 0x1c, # kVK_ANSI_8 76 | '*': 0x1c, # kVK_ANSI_8 77 | '0': 0x1d, # kVK_ANSI_0 78 | ')': 0x1d, # kVK_ANSI_0 79 | ']': 0x1e, # kVK_ANSI_RightBracket 80 | '}': 0x1e, # kVK_ANSI_RightBracket 81 | 'o': 0x1f, # kVK_ANSI_O 82 | 'u': 0x20, # kVK_ANSI_U 83 | '[': 0x21, # kVK_ANSI_LeftBracket 84 | '{': 0x21, # kVK_ANSI_LeftBracket 85 | 'i': 0x22, # kVK_ANSI_I 86 | 'p': 0x23, # kVK_ANSI_P 87 | 'l': 0x25, # kVK_ANSI_L 88 | 'j': 0x26, # kVK_ANSI_J 89 | "'": 0x27, # kVK_ANSI_Quote 90 | '"': 0x27, # kVK_ANSI_Quote 91 | 'k': 0x28, # kVK_ANSI_K 92 | ';': 0x29, # kVK_ANSI_Semicolon 93 | ':': 0x29, # kVK_ANSI_Semicolon 94 | '\\': 0x2a, # kVK_ANSI_Backslash 95 | '|': 0x2a, # kVK_ANSI_Backslash 96 | ',': 0x2b, # kVK_ANSI_Comma 97 | '<': 0x2b, # kVK_ANSI_Comma 98 | '/': 0x2c, # kVK_ANSI_Slash 99 | '?': 0x2c, # kVK_ANSI_Slash 100 | 'n': 0x2d, # kVK_ANSI_N 101 | 'm': 0x2e, # kVK_ANSI_M 102 | '.': 0x2f, # kVK_ANSI_Period 103 | '>': 0x2f, # kVK_ANSI_Period 104 | '`': 0x32, # kVK_ANSI_Grave 105 | '~': 0x32, # kVK_ANSI_Grave 106 | ' ': 0x31, # kVK_Space 107 | 'space': 0x31, 108 | '\r': 0x24, # kVK_Return 109 | '\n': 0x24, # kVK_Return 110 | 'enter': 0x24, # kVK_Return 111 | 'return': 0x24, # kVK_Return 112 | '\t': 0x30, # kVK_Tab 113 | 'tab': 0x30, # kVK_Tab 114 | 'backspace': 0x33, # kVK_Delete, which is "Backspace" on OS X. 115 | '\b': 0x33, # kVK_Delete, which is "Backspace" on OS X. 116 | 'esc': 0x35, # kVK_Escape 117 | 'escape': 0x35, # kVK_Escape 118 | 'command': 0x37, # kVK_Command 119 | 'shift': 0x38, # kVK_Shift 120 | 'shiftleft': 0x38, # kVK_Shift 121 | 'capslock': 0x39, # kVK_CapsLock 122 | 'option': 0x3a, # kVK_Option 123 | 'optionleft': 0x3a, # kVK_Option 124 | 'alt': 0x3a, # kVK_Option 125 | 'altleft': 0x3a, # kVK_Option 126 | 'ctrl': 0x3b, # kVK_Control 127 | 'ctrlleft': 0x3b, # kVK_Control 128 | 'shiftright': 0x3c, # kVK_RightShift 129 | 'optionright': 0x3d, # kVK_RightOption 130 | 'ctrlright': 0x3e, # kVK_RightControl 131 | 'fn': 0x3f, # kVK_Function 132 | 'f17': 0x40, # kVK_F17 133 | 'volumeup': 0x48, # kVK_VolumeUp 134 | 'volumedown': 0x49, # kVK_VolumeDown 135 | 'volumemute': 0x4a, # kVK_Mute 136 | 'f18': 0x4f, # kVK_F18 137 | 'f19': 0x50, # kVK_F19 138 | 'f20': 0x5a, # kVK_F20 139 | 'f5': 0x60, # kVK_F5 140 | 'f6': 0x61, # kVK_F6 141 | 'f7': 0x62, # kVK_F7 142 | 'f3': 0x63, # kVK_F3 143 | 'f8': 0x64, # kVK_F8 144 | 'f9': 0x65, # kVK_F9 145 | 'f11': 0x67, # kVK_F11 146 | 'f13': 0x69, # kVK_F13 147 | 'f16': 0x6a, # kVK_F16 148 | 'f14': 0x6b, # kVK_F14 149 | 'f10': 0x6d, # kVK_F10 150 | 'f12': 0x6f, # kVK_F12 151 | 'f15': 0x71, # kVK_F15 152 | 'help': 0x72, # kVK_Help 153 | 'home': 0x73, # kVK_Home 154 | 'pageup': 0x74, # kVK_PageUp 155 | 'pgup': 0x74, # kVK_PageUp 156 | 'del': 0x75, # kVK_ForwardDelete 157 | 'delete': 0x75, # kVK_ForwardDelete 158 | 'f4': 0x76, # kVK_F4 159 | 'end': 0x77, # kVK_End 160 | 'f2': 0x78, # kVK_F2 161 | 'pagedown': 0x79, # kVK_PageDown 162 | 'pgdn': 0x79, # kVK_PageDown 163 | 'f1': 0x7a, # kVK_F1 164 | 'left': 0x7b, # kVK_LeftArrow 165 | 'right': 0x7c, # kVK_RightArrow 166 | 'down': 0x7d, # kVK_DownArrow 167 | 'up': 0x7e, # kVK_UpArrow 168 | 'yen': 0x5d, # kVK_JIS_Yen 169 | 'underscore' : 0x5e, # kVK_JIS_Underscore (only applies to Japanese keyboards) 170 | 'comma': 0x5f, # kVK_JIS_KeypadComma (only applies to Japanese keyboards) 171 | 'eisu': 0x66, # kVK_JIS_Eisu 172 | 'kana': 0x68, # kVK_JIS_Kana 173 | } 174 | 175 | RED_COLOR = 'red' 176 | 177 | GREEN_COLOR = 'green' 178 | 179 | YELLOW_COLOR = 'yellow' 180 | 181 | BLUE_COLOR = 'blue' 182 | 183 | BLACK_COLOR = 'black' 184 | 185 | # END FILE 186 | -------------------------------------------------------------------------------- /macos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/macos/__init__.py -------------------------------------------------------------------------------- /macos/app_config.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import psutil 3 | import AppKit 4 | from .exceptions import ApplicationNameError 5 | 6 | 7 | class AppConfigure(object): 8 | """App-settings""" 9 | 10 | def get_full_path_by_app_name(self, app): 11 | return AppKit.NSWorkspace.sharedWorkspace().fullPathForApplication_(app) 12 | 13 | def get_app_size(self, app_name): 14 | """ 15 | Return size of app by him name. 16 | :param app_name: App name, which exist in /Applications/.app 17 | :return: Size in megabytes/gigabytes 18 | """ 19 | path = f'du -sh {self.get_full_path_by_app_name(app_name)}' 20 | if app_name not in (i.name() for i in psutil.process_iter()): 21 | raise ApplicationNameError 22 | else: 23 | return subprocess.getoutput(cmd=path).split()[0] 24 | 25 | def move_app(self, app, x, y, width, height): 26 | return subprocess.getoutput(cmd="""osascript -e 'tell application "%s" 27 | set bounds of front window to {%s, %s, %s, %s} 28 | end tell'""" % (app, x, y, width, height), encoding='utf-8') 29 | 30 | -------------------------------------------------------------------------------- /macos/app_system.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from time import sleep 3 | import AppKit 4 | from psutil import process_iter 5 | 6 | 7 | class AppSystem(object): 8 | def __init__(self): 9 | self.apps = process_iter() 10 | 11 | def is_exist(self, application_name): 12 | """ 13 | Check of existing of app({application_name}) 14 | :param application_name: APP name 15 | :return: [True] if application 16 | exist on your devise, [False] - if no. 17 | """ 18 | return application_name in (i.name() for i in self.apps) 19 | 20 | def close_app(self, application_name): 21 | """ 22 | Close app. 23 | :param application_name: 24 | Name of App which will 25 | be close. 26 | :return: [None] 27 | """ 28 | subprocess.getoutput(cmd=f'pkill {application_name}') 29 | 30 | 31 | def close_all_app(self): 32 | for apps in AppKit.NSWorkspace.sharedWorkspace().runningApplications(): 33 | apps.terminate() 34 | 35 | def current_opened_app(self, pause): 36 | sleep(pause) 37 | activeAppName = AppKit.NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName'] 38 | return activeAppName 39 | 40 | def isopened(self, application_name): 41 | """Returns a boolean value depending on whether the application is open.""" 42 | return AppKit.NSWorkspace.sharedWorkspace().openFile_withApplication_andDeactivate_(None, 43 | f'{application_name}', 44 | None) 45 | 46 | def get_size_icon_by_app(self, application_name): 47 | activeAppName = AppKit.NSWorkspace.sharedWorkspace().iconForFile_( 48 | f'/Applications/{application_name}') 49 | size = str(activeAppName).split(' ')[2] + str(activeAppName).split(' ')[3] 50 | return size 51 | -------------------------------------------------------------------------------- /macos/audiorecorder.py: -------------------------------------------------------------------------------- 1 | import time 2 | import AVFoundation 3 | 4 | 5 | class AudioRecorder: 6 | def record(self, url, duration): 7 | url = AVFoundation.NSURL.fileURLWithPath_(url) 8 | query = { 9 | AVFoundation.AVSampleRateKey: 44100.0, 10 | AVFoundation.AVNumberOfChannelsKey: 2, 11 | AVFoundation.AVEncoderBitRateKey: 12800, 12 | AVFoundation.AVLinearPCMBitDepthKey: 16, 13 | AVFoundation.AVEncoderAudioQualityKey: AVFoundation.AVAudioQualityHigh, 14 | } 15 | audio, err = AVFoundation.AVAudioRecorder.alloc().initWithURL_settings_error_(url, query, None) 16 | if audio is None: 17 | raise FileNotFoundError 18 | audio.record() 19 | time.sleep(duration) 20 | audio.stop() 21 | audio.release() 22 | 23 | -------------------------------------------------------------------------------- /macos/background_screen.py: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import Quartz 3 | import Foundation 4 | from .exceptions import * 5 | 6 | class BackGroundScreen: 7 | 8 | def current_background_image(self): 9 | Id = Quartz.NSScreen.mainScreen() 10 | boolean = AppKit.NSWorkspace.sharedWorkspace().desktopImageURLForScreen_(Id) 11 | return boolean 12 | 13 | def set_backgroud(self, filename: str, stretch_img_by_screen_size: bool, image_bg_color='white'): 14 | try: 15 | file_url = Foundation.NSURL.fileURLthPath_(filename) 16 | config = { 17 | AppKit.NSWorkspaceDesktopImageScalingKey: AppKit.NSImageScaleProportionallyUpOrDown, 18 | AppKit.NSWorkspaceDesktopImageAllowClippingKey: AppKit.NO if stretch_img_by_screen_size is 19 | not True else AppKit.YES, 20 | AppKit.NSWorkspaceDesktopImageFillColorKey: eval(f"AppKit.NSColor.{image_bg_color}Color()") 21 | } 22 | 23 | ws = AppKit.NSWorkspace.sharedWorkspace() 24 | for screens in AppKit.NSScreen.screens(): 25 | ws.setDesktopImageURL_forScreen_options_error_( 26 | file_url, screens, config, None) 27 | except Exception: 28 | raise UnsupportedFormat(f'Image not support format {repr(str(filename).split(".")[-1])}.') 29 | -------------------------------------------------------------------------------- /macos/bluetooth.py: -------------------------------------------------------------------------------- 1 | import objc 2 | import subprocess 3 | from .exceptions import * 4 | 5 | class BlueTooth(object): 6 | def __init__(self): 7 | bundle_path = '/System/Library/Frameworks/IOBluetooth.framework' 8 | 9 | objc.loadBundle(objc.infoForFramework(bundle_path)[1], bundle_path=bundle_path, 10 | module_globals=globals()) 11 | 12 | self.bluetooth = subprocess.getoutput(cmd='system_profiler SPBluetoothDataType') 13 | 14 | devices = globals()['IOBluetoothDevice'] # Ignore error.IOBluetoothDevice not objective-class, 15 | # and when I pack him in objc.loadBundle I 16 | # got error, based at subcridiable. 17 | address = devices.recentDevices_(0) or devices.pairedDevices() 18 | 19 | for query in address: 20 | self.device = query 21 | 22 | def get_paired_devices(self): 23 | return (self.device.getNameOrAddress()) 24 | 25 | def isEnable(self): 26 | return globals()['IOBluetoothPreferenceGetControllerPowerState']() != 0 27 | 28 | def set_bluetooth_by_enable(self): 29 | globals()['IOBluetoothPreferenceSetControllerPowerState'](1) 30 | 31 | def set_bluetooth_by_disable(self): 32 | globals()['IOBluetoothPreferenceSetControllerPowerState'](0) 33 | 34 | def get_all_address(self): 35 | """[0] or [1]""" 36 | addr = subprocess.getoutput(cmd='system_profiler SPBluetoothDataType | grep Address').split('Address')[1:] 37 | addr = set(addr) 38 | for id in addr: 39 | yield id.rstrip().replace(': ', '').lstrip() 40 | 41 | def pair_to_devise(self, address, duration_pair): 42 | try: 43 | device = globals()['IOBluetoothDevice'].withAddressString_(address) 44 | device.openConnection() 45 | device.openConnection_withPageTimeout_authenticationRequired_(None, duration_pair, True) 46 | except AttributeError: 47 | raise BluetoothConnectionError(f'Can not connect to devise, with address {repr(address)}') 48 | 49 | 50 | -------------------------------------------------------------------------------- /macos/brightness.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | from time import sleep 3 | from warnings import simplefilter 4 | from .exceptions import ValueBrightnessError, ScreenWarning 5 | import subprocess 6 | import Foundation 7 | import Quartz 8 | from ColorSync import * 9 | 10 | 11 | class Brightness(object): 12 | """Set brightness""" 13 | 14 | def __init__(self): 15 | global iokit 16 | simplefilter("ignore") 17 | iokit = dict(iokit) 18 | simplefilter("default") 19 | 20 | self.get_cur_brightness_per = iokit["IODisplayGetFloatParameter"]( 21 | Quartz.CGDisplayIOServicePort(Quartz.CGMainDisplayID()), 22 | 0, 23 | iokit["kDisplayBrightness"], None) 24 | 25 | def set_brightness(self, brightness_percent: [int, float]): 26 | """ 27 | Automatically set brightness 28 | percent [type - float] 29 | example: 0.25; 0.50; 0.75; 0.1(max) 30 | 31 | """ 32 | 33 | success = Quartz.IKMonitorBrightnessController.alloc().setBrightnessOnAllDisplays_(brightness_percent) 34 | if not success is None: 35 | raise ValueBrightnessError('Brightness must be type: int, float') 36 | 37 | def set_max_brightness(self): 38 | """ 39 | Set max brightness of 40 | screen equal one hundred. 41 | :return: Successfully 42 | """ 43 | self.set_brightness(1.0) 44 | 45 | def set_min_brightness(self): 46 | """ 47 | Set min brightness of 48 | screen equal zero. 49 | :return: Successfully 50 | """ 51 | 52 | self.set_brightness(0.0) 53 | 54 | def increase_brightness(self, division): 55 | """Increase brightness by 1 division""" 56 | if division >= 1: 57 | for repeat in range(division + 2): 58 | subprocess.getoutput( 59 | cmd="""osascript -e 'tell application "System Events"' -e 'key code 144' -e ' end tell'""") 60 | else: 61 | division = division.imag 62 | division += 1 63 | 64 | def decrease_brightness(self, division: int): 65 | if division >= 1: 66 | for repeat in range(division + 2): 67 | subprocess.getoutput( 68 | cmd="""osascript -e 'tell application "System Events"' -e 'key code 145' -e ' end tell'""") 69 | else: 70 | division = division.imag 71 | division += 1 72 | 73 | def sleep_mac(self, pause: [int, float]): 74 | """Sleep Mac""" 75 | sleep(pause) 76 | subprocess.getoutput(cmd="osascript - e 'tell application \"finder\" to sleep'") 77 | 78 | @property 79 | def get_brightness(self): 80 | """Get brightness percent""" 81 | if self.get_cur_brightness_per[0] != 0: 82 | raise ScreenWarning('No has access to IOKit and display ID.') 83 | return self.get_cur_brightness_per[-1] 84 | 85 | def set_color_profile(self, profile_path): 86 | 87 | graphics_path = f'file://{profile_path}' 88 | display_uuid = CGDisplayCreateUUIDFromDisplayID(Quartz.CGMainDisplayID()) 89 | fullURL = Foundation.CFURLCreateWithString(objc.NULL, graphics_path, objc.NULL) 90 | config_new = NSDictionary({kColorSyncDeviceDefaultProfileID: fullURL}) 91 | success = ColorSyncDeviceSetCustomProfiles(kColorSyncDisplayDeviceClass, display_uuid, config_new) 92 | if not success: 93 | raise ImportError(f'Can not import color profile named {profile_path}, or it not support.') 94 | 95 | def get_color_profile(self): 96 | display_uuid = CGDisplayCreateUUIDFromDisplayID(Quartz.CGMainDisplayID()) 97 | colorInfo = ColorSyncDeviceCopyDeviceInfo(kColorSyncDisplayDeviceClass, display_uuid) 98 | return dict(dict(colorInfo['FactoryProfiles'])['1'])['DeviceProfileURL'] 99 | -------------------------------------------------------------------------------- /macos/buffer.py: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import pyperclip 3 | 4 | class Buffer: 5 | def copyText(self, text): 6 | init = AppKit.NSStringPboardType 7 | 8 | pb = AppKit.NSPasteboard.generalPasteboard() 9 | pb.declareTypes_owner_([init], None) 10 | 11 | newStrIng = AppKit.NSString.stringthString_(text) 12 | newData = newStrIng.nsstring().dataUsingEncoding_(AppKit.NSUTF8StringEncoding) 13 | pb.setData_forType_(newData, init) 14 | 15 | def paste(self): 16 | return pyperclip.paste() -------------------------------------------------------------------------------- /macos/devices.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from AVFoundation import * 3 | 4 | import objc 5 | import CoreWLAN 6 | 7 | 8 | class OutputListsDevises(object): 9 | """ Return output devises """ 10 | 11 | def get_list_wifi_networks(self): 12 | """ Function output all wi-fi networks, 13 | which available for your devise.""" 14 | if 'loadBundle' in dir(objc): 15 | pass 16 | else: 17 | raise AttributeError 18 | bundle_path = '/System/Library/Frameworks/CoreWLAN.framework' 19 | objc._objc.loadBundle(objc.infoForFramework(bundle_path)[1], bundle_path=bundle_path, 20 | module_globals=globals()) 21 | 22 | response = CoreWLAN.CWInterface.interface() 23 | r = response.scanForNetworksWithName_includeHidden_error_(None, True, None) 24 | for networks in r[0]: 25 | yield networks.ssid() 26 | 27 | def get_list_bluetooth_device(self): 28 | """ Function output all bluetooth devise(s), 29 | which available for your devise.""" 30 | 31 | return None # Not manage yet. 32 | 33 | def get_list_cameras(self): 34 | devices = AVCaptureDevice.devicesWithMediaType_('Video') 35 | list_devices = [] 36 | for device in devices: 37 | list_devices.append(device.localizedName()) 38 | yield list_devices[-1] 39 | 40 | def get_list_audio_devises(self): 41 | """ 42 | Return all audio 43 | connectable devises. 44 | :return: devises 45 | 46 | """ 47 | 48 | devices = AVCaptureDevice.devicesWithMediaType_('Audio') 49 | list_devices = [] 50 | for device in devices: 51 | list_devices.append(device.localizedName()) 52 | yield list_devices[-1] 53 | 54 | 55 | -------------------------------------------------------------------------------- /macos/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Individual exceptions for driver_controller 4 | 5 | """ 6 | 7 | 8 | try: 9 | exc = ExceptionGroup 10 | except NameError: 11 | exc = ReferenceError 12 | 13 | 14 | class ApplicationNameError(NameError): 15 | """ 16 | App with pointed out name not exist. 17 | """ 18 | 19 | 20 | class ApplicationNotExist(SystemError): 21 | """ 22 | Application, which you point outed is not exist 23 | """ 24 | 25 | 26 | class UnsupportedFormat(FileExistsError): 27 | """ 28 | Method screenshot support only ['png', 'jpg', 'ico', 'gif', 'pict'] formats. 29 | """ 30 | 31 | 32 | class ConfirmationError(TypeError): 33 | """ 34 | If confirmation is [False]. 35 | """ 36 | 37 | 38 | class InvalidExtension(NameError): 39 | """ 40 | No extension specified. 41 | """ 42 | 43 | 44 | class WifiNameConnectError(NameError): 45 | """ 46 | Password or SSID/Wi-fi name of Network is not right. 47 | """ 48 | 49 | 50 | class ValueBrightnessError(ValueError, TypeError): 51 | """ 52 | Value is not type [int]. 53 | """ 54 | 55 | 56 | class WifiValueError(ValueError, BaseException): 57 | """ 58 | There is no wi-fi network in util "bunch keys". 59 | """ 60 | 61 | 62 | class ExtensionError(ValueError): 63 | pass 64 | 65 | 66 | class PathError(FileNotFoundError): 67 | pass 68 | 69 | 70 | class CallError(exc): 71 | pass 72 | 73 | 74 | class RgbValueError(ValueError): 75 | """No available color for bg""" 76 | pass 77 | 78 | 79 | class OpenPossibilityError(FileExistsError): 80 | """Can not open file in that app.""" 81 | 82 | 83 | class ScreenErrorIndex(IndexError): 84 | """Screen ID not exist.""" 85 | 86 | 87 | class ScreenWarning(Warning): 88 | """Not support bridge with objective-c and python via IOKit.""" 89 | 90 | 91 | class BluetoothConnectionError(ConnectionRefusedError): 92 | """Specify not right address to pair.""" 93 | 94 | # END FILE 95 | -------------------------------------------------------------------------------- /macos/file_config.py: -------------------------------------------------------------------------------- 1 | from time import ctime 2 | import os 3 | import subprocess 4 | 5 | 6 | class FileConfig(object): 7 | 8 | def get_date_create_file(self, path): 9 | """ 10 | Return time, when file was used. 11 | :param path: 12 | :return: 13 | """ 14 | return ctime(os.stat(path).st_birthtime) 15 | 16 | def get_file_size(self, path): 17 | 18 | """ 19 | Return size of file. 20 | :param path: Path to file 21 | :return: 22 | """ 23 | 24 | return subprocess.getoutput(f'du -sh {path}').split('\t')[0].strip() 25 | 26 | def extension(self, path): 27 | return str(path).split('.')[-1] 28 | 29 | def name(self, path): 30 | """:return Name by path""" 31 | return path.split('/', maxsplit=3)[-1].split('.')[0] 32 | 33 | def get_files_in_folder(self, path: str): 34 | """Return all files in folder""" 35 | if not os.path.exists(path=path): 36 | raise FileExistsError 37 | if path == subprocess.getoutput(cmd=f'ls {path}'): 38 | return None 39 | return subprocess.getoutput(cmd=f'ls {path}') 40 | 41 | def get_folder_size(self, path): 42 | """Return all files in folder""" 43 | if os.path.exists(path=path): 44 | 45 | return subprocess.getoutput(cmd=f'du -sh {path}').split() 46 | else: 47 | raise FileExistsError(f'No file name {path}') -------------------------------------------------------------------------------- /macos/illumination.py: -------------------------------------------------------------------------------- 1 | import objc 2 | 3 | 4 | def load(): 5 | objc.loadBundle('CoreBrightness', bundle_path='/System/Library/PrivateFrameworks/CoreBrightness.framework', 6 | module_globals=globals()) 7 | 8 | 9 | class Illumination: 10 | """Illumination object. 11 | Connect keyboard and CoreBrightness API. 12 | """ 13 | def setBrightness(self, level: float): 14 | """set brightness on keyboard.""" 15 | load() 16 | brightness = globals()['KeyboardBrightnessClient'].alloc().init().setBrightness_forKeyboard_(level, True) 17 | if not bool(brightness): 18 | raise ValueError('Can not set level of illumination with value equal {}'.format(level)) 19 | else: 20 | return 0 21 | 22 | def getBrightness(self): 23 | load() 24 | return round(globals()['KeyboardBrightnessClient'].alloc().init().brightnessForKeyboard_(True)) 25 | -------------------------------------------------------------------------------- /macos/mouse.py: -------------------------------------------------------------------------------- 1 | import Quartz.CoreGraphics 2 | import time 3 | 4 | 5 | class MouseController: 6 | def move_mouse(self, x, y): 7 | move_event = Quartz.NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_( 8 | Quartz.NSEventTypeMouseMoved, 9 | Quartz.NSPoint(x, y), 10 | 0, 11 | Quartz.CGEventGetTimestamp(Quartz.CGEventCreate(None)), 12 | 0, 13 | None, 14 | 0, 15 | 0, 16 | 0.5 17 | ) 18 | 19 | Quartz.CGEventPost(Quartz.kCGHIDEventTap, move_event.CGEvent()) 20 | 21 | def click_mouse(self, x, y): 22 | 23 | self.move_mouse(x, y) 24 | time.sleep(0.1) 25 | 26 | down_event = Quartz.NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_( 27 | Quartz.NSEventTypeLeftMouseDown, 28 | Quartz.NSPoint(x, y), 29 | 0, 30 | Quartz.CGEventGetTimestamp(Quartz.CGEventCreate(None)), 31 | 0, 32 | None, 33 | 0, 34 | 0, 35 | 0.5 36 | ) 37 | Quartz.CGEventPost(Quartz.kCGHIDEventTap, down_event.CGEvent()) 38 | 39 | up_event = Quartz.NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_( 40 | Quartz.NSEventTypeLeftMouseUp, 41 | Quartz.NSPoint(x, y), 42 | 0, 43 | Quartz.CGEventGetTimestamp(Quartz.CGEventCreate(None)), 44 | 0, 45 | None, 46 | 0, 47 | 0, 48 | 0.5 49 | ) 50 | Quartz.CGEventPost(Quartz.kCGHIDEventTap, up_event.CGEvent()) 51 | 52 | def scroll_mouse(self, to): 53 | scroll_event = Quartz.CGEventCreateScrollWheelEvent(None, 54 | 0, 55 | Quartz.CoreGraphics.kCGScrollEventUnitLine, 56 | to) 57 | Quartz.CGEventPost(Quartz.kCGHIDEventTap, scroll_event) 58 | 59 | def location(self): 60 | return Quartz.NSEvent.mouseLocation() 61 | 62 | -------------------------------------------------------------------------------- /macos/notifier.py: -------------------------------------------------------------------------------- 1 | 2 | import AppKit 3 | 4 | 5 | class Notifier: 6 | """Send different alerts""" 7 | 8 | def send_text_alert(self, button, message, icon): 9 | """Method is deprecated.Use other Alert manager PyMasl API.""" 10 | alert = AppKit.NSAlert.alloc().init() 11 | if isinstance(button, tuple): 12 | for i in button: 13 | alert.setMessageText_(i) 14 | alert.addButtonWithTitle_(i) 15 | else: 16 | alert.addButtonWithTitle_(str(button)) 17 | alert.setInformativeText_(message) 18 | 19 | alert.setShowsHelp_(1) 20 | alert.setAlertStyle_(1) 21 | 22 | alert.startSpeaking_(0) 23 | alert.showsSuppressionButton() 24 | img = AppKit.NSImage.alloc().initWithContentsOfFile_(icon) 25 | 26 | alert.setIcon_(img) 27 | 28 | return alert.runModal() - 1000 29 | 30 | def send_notification(self, title, subtitle, informative_text, sound_name, image_path): 31 | # Create a notification object 32 | notification = AppKit.NSUserNotification.alloc().init() 33 | 34 | # Set notification properties 35 | notification.setTitle_(title) 36 | notification.setSubtitle_(subtitle) 37 | notification.setInformativeText_(informative_text) 38 | notification.setSoundName_(sound_name) 39 | 40 | # If you want to set an image, you can use an NSImage 41 | if image_path: 42 | 43 | image = AppKit.NSImage.alloc().initWithContentsOfFile_(image_path) 44 | notification.setContentImage_(image) 45 | 46 | center = AppKit.NSUserNotificationCenter.defaultUserNotificationCenter() 47 | center.deliverNotification_(notification) 48 | -------------------------------------------------------------------------------- /macos/open.py: -------------------------------------------------------------------------------- 1 | import AppKit 2 | from .exceptions import * 3 | import subprocess 4 | 5 | 6 | class Open(object): 7 | 8 | def application(self, application_name): 9 | """ 10 | Open application by his name. 11 | :param path_app: Path to Application 12 | (begin from /Applications/{path_app}.app) 13 | EXAMPLE [/Applications/Finder.app] 14 | :return: Successful if successful opened app. 15 | """ 16 | boolean = AppKit.NSWorkspace.sharedWorkspace().launchApplication_( 17 | application_name 18 | ) 19 | if not boolean: 20 | raise ApplicationNotExist(f'Application {application_name} not exist.') 21 | 22 | def url(self, url, browser='Safari'): 23 | """ 24 | Open url in main browser 25 | DEFAULT BROWSER: Safari. 26 | :param url: 'url' 27 | :return: None 28 | :param url: 29 | :return: 30 | """ # SAFARI - DEFAULT MAIN BROWSER, CHANGE YOUR 31 | cmd = f'open /Applications/{browser}.app {url}' # Select your main browser 32 | return subprocess.getoutput(cmd=cmd) 33 | 34 | def open_spotlight(self): 35 | """Open spotlight menu.""" 36 | 37 | 38 | def open_file(self, path): 39 | AppKit.NSWorkspace.sharedWorkspace().openFile_( 40 | path) 41 | 42 | def open_file_in_app(self, app_name, file): 43 | open_objc = AppKit.NSWorkspace.sharedWorkspace().openFile_withApplication_(file, app_name) 44 | 45 | if open_objc is False: 46 | raise OpenPossibilityError \ 47 | (f'Can not open file {file}, because application {app_name} not support format this files.') -------------------------------------------------------------------------------- /macos/password.py: -------------------------------------------------------------------------------- 1 | 2 | from Security import (SecItemCopyMatching, kSecClass, kSecAttrAccount, kSecAttrService, kSecReturnData, 3 | kSecClassGenericPassword, kSecPropertyTypeSuccess) 4 | 5 | 6 | class PasswordManager: 7 | def get_wifi_password(self, ssid): 8 | # Define the query for the Keychain 9 | query = { 10 | kSecClass: kSecClassGenericPassword, 11 | kSecReturnData: True, 12 | kSecAttrAccount: ssid 13 | } 14 | 15 | status, data = SecItemCopyMatching(query, None) 16 | if status == 0: 17 | psw = data.bytes().tobytes() 18 | return psw.decode() 19 | else: 20 | return None 21 | 22 | -------------------------------------------------------------------------------- /macos/rotate.py: -------------------------------------------------------------------------------- 1 | import objc 2 | import Quartz 3 | 4 | 5 | def load(): 6 | """Load MonitorPanel framework API.""" 7 | objc.loadBundle('MonitorPanel', bundle_path='/System/Library/PrivateFrameworks/MonitorPanel.framework.framework', 8 | module_globals=globals()) 9 | 10 | 11 | class Rotation: 12 | def setRotate(self, angle): 13 | load() 14 | 15 | mpd = globals()['MPDisplay'].alloc().init() 16 | if angle % 90 != 0: 17 | raise ValueError('The angle must be 90, 180, 270, or 0 degrees, not {}.'.format(angle)) 18 | if not mpd.canChangeOrientation(): 19 | raise PermissionError(f'Can not manage main display, including {self.setRotate.__name__} possibility.') 20 | else: 21 | mpd.setOrientation_(angle) 22 | 23 | def get_rotate(self): 24 | load() 25 | return Quartz.CGDisplayRotation(Quartz.CGMainDisplayID()) 26 | -------------------------------------------------------------------------------- /macos/sound.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | import subprocess 3 | import AppKit 4 | import mutagen.mp3 5 | from time import sleep 6 | import Foundation 7 | from .exceptions import * 8 | 9 | 10 | class Sound(object): 11 | """ 12 | class Voice add more available 13 | voices & effects(which beforehand 14 | installed in Mac-os by path /System/Library/Sounds/) 15 | (Available only on Mac-os). And play other sounds. 16 | """ 17 | 18 | 19 | 20 | def playSoundByName(self, soundfile): 21 | absolute_path = str(pathlib.Path(soundfile).cwd()) + str('/') + soundfile 22 | url = Foundation.NSURL.URLWithString_( 23 | absolute_path 24 | ) 25 | 26 | duration_Start = AppKit.NSSound.alloc().initWithContentsOfURL_byReference_(url, True) 27 | try: 28 | duration_Start.play() 29 | sleep(float(duration_Start.duration())) 30 | 31 | except AttributeError: 32 | raise PathError(f'No sound name {url}, or it not support') 33 | 34 | def sound_length(self, file): 35 | return mutagen.mp3.MP3(file).info.length 36 | -------------------------------------------------------------------------------- /macos/sys_config.py: -------------------------------------------------------------------------------- 1 | import CoreLocation 2 | from warnings import simplefilter 3 | import CoreWLAN 4 | import subprocess 5 | from time import sleep 6 | import objc 7 | import Quartz 8 | import Foundation 9 | import _sysconfigdata__darwin_darwin as dar 10 | 11 | 12 | iokit = None 13 | def init(): 14 | global iokit 15 | iokit = {} 16 | 17 | iokitBundle = objc.initFrameworkWrapper( 18 | "IOKit", 19 | frameworkIdentifier="com.apple.iokit", 20 | frameworkPath=objc.pathForFramework("/System/Library/Frameworks/IOKit.framework"), 21 | globals=globals() 22 | ) 23 | 24 | # The IOKit functions to be retrieved 25 | functions = [ 26 | ("IOServiceGetMatchingServices", b"iI@o^I"), 27 | ('IODisplayGetIntegerRangeParameter', b"II^{__CFString=}^i^ii"), 28 | ('IOHIDDeviceActivate', b'^{__IOHIDDevice=}v'), 29 | ('IODisplayCreateInfoDictionary', b'II^{__CFDictionary=}') 30 | 31 | ] 32 | objc._objc.loadBundleFunctions(iokitBundle, iokit, functions) 33 | 34 | class SystemConfig(object): 35 | """Data about mac""" 36 | simplefilter('ignore') 37 | 38 | simplefilter("default") 39 | 40 | def __init__(self): 41 | global iokit 42 | manager = CoreLocation.CLLocationManager.alloc().init() 43 | manager.delegate() 44 | manager.startUpdatingLocation() 45 | while CoreLocation.CLLocationManager.authorizationStatus() != 3 or manager.location() is None: 46 | sleep(0.01) 47 | coord = manager.location().coordinate() 48 | self.lat = coord.latitude 49 | self.lon = coord.longitude 50 | self.percent = iokit['IOPSCopyPowerSourcesByType'](0)[0]['Current Capacity'] # ignore: noqa 401 51 | self.vers = subprocess.getoutput(cmd="sw_vers -productVersion") 52 | self.net = CoreWLAN.CWInterface.interfaceWithName_("en0") 53 | self.size = iokit['IODisplayCreateInfoDictionary'](Quartz.CGDisplayIOServicePort(Quartz.CGMainDisplayID()), 0)[ 54 | 'resolution-preview-width'] * 10, \ 55 | iokit['IODisplayCreateInfoDictionary'](Quartz.CGDisplayIOServicePort(Quartz.CGMainDisplayID()), 0)[ 56 | 'resolution-preview-height'] * 10 57 | self.mem_size = subprocess.getoutput(cmd='sysctl -a | grep \'^hw\.m\'') 58 | self.processor = subprocess.getoutput(cmd='sysctl -n machdep.cpu.brand_string') 59 | self.num = 'system_profiler SPHardwareDataType | grep x "Serial Number (system)"' 60 | self.disk_mem = 'diskutil list | grep GUID_partition_scheme' # Diskutil not found: https://superuser.com/questions/213088/diskutil-command-not-found-in-os-x-terminal 61 | self.video_crd_nm = subprocess.getoutput( 62 | cmd='system_profiler SPDisplaysDataType | grep "Chipset Model"') # system profiler: command not found https://github.com/jlhonora/lsusb/issues/12?ysclid=ldu37f5jk9865312203 63 | self.temp = subprocess.getoutput( 64 | cmd='sysctl machdep.xcpm.cpu_thermal_level sysctl machdep.xcpm.gpu_thermal_level') 65 | 66 | self.name = Foundation.NSUserName() 67 | 68 | @property 69 | def devise_battery(self): 70 | """ 71 | Return battery percent of 72 | computer at current time. 73 | :return: Battery percent [str] 74 | """ 75 | return f'Battery percent: {self.percent}' 76 | 77 | @property 78 | def macos_version(self): 79 | """ 80 | Function. 81 | :return: Version your devise. 82 | """ 83 | return self.vers 84 | 85 | @property 86 | def current_connected_wifi_network(self): 87 | """ 88 | Return current wi-fi network. 89 | :return: Current wi-fi network, 90 | which you connect to. 91 | (Available only on Mac-os) 92 | """ 93 | 94 | return self.net.ssidData().decode('ascii') 95 | 96 | @property 97 | def screen_size(self): 98 | """ 99 | Screen size of your mac-book. 100 | :return: screen size 101 | """ 102 | 103 | return self.size 104 | 105 | @property 106 | def get_processor_name(self): 107 | """ 108 | Return current processor name 109 | :return: Processor mark 110 | """ 111 | return self.processor 112 | 113 | @property 114 | def memory_size(self): 115 | return int(self.mem_size.split(': ')[-1]) / pow(1024, 3) 116 | 117 | @property 118 | def get_mac_serial_number(self): 119 | return subprocess.getoutput(cmd=self.num).strip().split(': ')[-1] 120 | 121 | @property 122 | def get_disk_memory(self): 123 | """Return disk meomory.""" 124 | return subprocess.getoutput(cmd=self.disk_mem).replace('*', '').split()[2] + 'Gb' 125 | 126 | @property 127 | def get_video_card_name(self): 128 | """Return vide card name""" 129 | return self.video_crd_nm.strip().split(':')[-1] 130 | 131 | def sensor_temperature(self): 132 | return round(int(self.temp.split('\n')[0].split(':')[-1])) 133 | 134 | @property 135 | def mac_name(self): 136 | return self.name 137 | 138 | @property 139 | def darwin_version(self): 140 | if dar is None: 141 | return "" 142 | return dar.build_time_vars['BUILD_GNU_TYPE'] 143 | 144 | def mac_location(self): 145 | """Return mac location from geolocation-service. Enable this functions for python. 146 | System Preferences -> Security and Privacy -> allow geolocation services for python. 147 | More info: https://howtoenable.net/how-to-enable-geolocation-on-mac/""" 148 | 149 | return (self.lat, self.lon) 150 | 151 | def mac_address(self): 152 | """Return mac address in format XX:XX:XX:XX:XX:XX(not show him)""" 153 | return self.net.hardwareAddress().split()[-1] -------------------------------------------------------------------------------- /macos/theme.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from time import sleep 3 | from AppKit import NSUserDefaults 4 | 5 | class Theme: 6 | def __init__(self): 7 | self.cmd = 'osascript -e \'tell app "System Events" to tell appearance ' \ 8 | 'preferences to set dark mode to not dark mode\'' 9 | 10 | def change_color_mode(self): 11 | subprocess.getoutput(self.cmd) 12 | 13 | def current_theme(self): 14 | """Print current color mode on mac.""" 15 | return NSUserDefaults.standardUserDefaults().stringForKey_(u"AppleInterfaceStyle") 16 | -------------------------------------------------------------------------------- /macos/usb.py: -------------------------------------------------------------------------------- 1 | import objc 2 | from Foundation import NSBundle 3 | import CoreFoundation 4 | 5 | 6 | class USB: 7 | def __init__(self): 8 | iokit = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit') 9 | functions = [ 10 | ("IOServiceGetMatchingService", b'II@'), 11 | ("IOServiceMatching", b'@*'), 12 | ('IORegistryEntryCreateCFProperties', b'IIo^@@I'), 13 | ] 14 | 15 | variables = [ 16 | ('kIOMasterPortDefault', b'I') 17 | ] 18 | 19 | objc.loadBundleFunctions(iokit, globals(), functions) 20 | objc.loadBundleVariables(iokit, globals(), variables) 21 | 22 | usb_devs = globals()['IOServiceGetMatchingService']( 23 | globals()['kIOMasterPortDefault'], 24 | globals()['IOServiceMatching'](b'IOUSBDevice') 25 | ) 26 | 27 | err, self.props = globals()['IORegistryEntryCreateCFProperties']( 28 | usb_devs, 29 | None, 30 | CoreFoundation.kCFAllocatorDefault, 31 | 0 32 | ) 33 | if self.props: 34 | for keys, values in self.props.items(): 35 | setattr(self, keys, values) # add attributes 36 | 37 | def query(self): 38 | return self.props 39 | 40 | def __getattr__(self, item): 41 | if self.props: 42 | pass 43 | raise NotImplementedError 44 | 45 | def get(self, name): 46 | if len(name.split()) >= 2: 47 | return getattr(self, name).strip() 48 | -------------------------------------------------------------------------------- /macos/volume.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import Quartz 3 | 4 | class Volume(object): 5 | def __init__(self): 6 | 7 | self.volume = 'osascript -e "set Volume %s"' 8 | self.max_volume = 'osascript -e "set Volume 10"' 9 | self.min_volume = 'osascript -e "set Volume 0"' 10 | 11 | self.muted = subprocess.getoutput(cmd='osascript -e \'get volume settings\'') 12 | self.input_volume = subprocess.getoutput(cmd='osascript -e \'get volume settings\'').split(' ')[ 13 | 3].replace(',', '') 14 | self.output_volume = subprocess.getoutput(cmd='osascript -e \'get volume settings\'').split(' ')[ 15 | 1].replace(',', '') 16 | self.alert_vol = subprocess.getoutput(cmd='osascript -e \'get volume settings\'').split(' ')[ 17 | 5].replace( 18 | ',', '') 19 | 20 | def set_volume(self, volume): 21 | """Set volume by value.""" 22 | 23 | subprocess.getoutput(cmd=self.volume % volume) 24 | if subprocess.getstatusoutput(cmd=self.volume % volume)[0] == 1: 25 | raise ValueError 26 | else: 27 | return 0 28 | 29 | def set_max_volume(self): 30 | subprocess.getoutput(cmd=self.max_volume) 31 | return 0 32 | 33 | def set_min_volume(self): 34 | subprocess.getoutput(cmd=self.min_volume) 35 | return 0 36 | 37 | @property 38 | def get_output_volume_percent(self): 39 | """ 40 | Return output volume percent 41 | :return: 42 | """ 43 | 44 | return self.output_volume 45 | 46 | @property 47 | def get_input_volume_percent(self): 48 | """ 49 | Return input volume percent 50 | :return: 51 | """ 52 | return self.input_volume 53 | 54 | @property 55 | def get_alert_volume(self): 56 | return self.alert_vol 57 | 58 | def ismuted(self): 59 | return self.muted.split(', ')[-1].split(':')[-1].capitalize() 60 | 61 | 62 | -------------------------------------------------------------------------------- /macos/webcamera.py: -------------------------------------------------------------------------------- 1 | 2 | from AVFoundation import * 3 | from Cocoa import NSURL 4 | from time import sleep 5 | import time 6 | 7 | __all__ = ('WebCameraCapture', ) 8 | 9 | class WebCameraCapture(object): 10 | """Collect data in camera""" 11 | def webcam_capture(self, filename, camera_index): 12 | """ 13 | Record video in webcam 14 | :param record_time: Recording time(seconds) 15 | :param filename: Name of created file 16 | 17 | :return: [None] 18 | """ 19 | 20 | 21 | 22 | session = AVCaptureSession.alloc().init() 23 | 24 | device = AVCaptureDevice.devicesWithMediaType_(AVMediaTypeVideo)[camera_index] 25 | 26 | input, err = AVCaptureDeviceInput.deviceInputWithDevice_error_(device, None) 27 | session.addInput_(input) 28 | output_url = NSURL.fileURLWithPath_(filename) 29 | 30 | video_settings = { 31 | AVVideoWidthKey: 640, 32 | AVVideoHeightKey: 180, 33 | AVVideoCompressionPropertiesKey: { 34 | AVVideoAverageBitRateKey: 10 ** 10, 35 | AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel, 36 | AVVideoAllowFrameReorderingKey: kCFBooleanFalse 37 | }, 38 | AVVideoColorPropertiesKey: { 39 | AVVideoColorPrimariesKey: AVVideoColorPrimaries_ITU_R_709_2, 40 | AVVideoTransferFunctionKey: AVVideoTransferFunction_ITU_R_709_2, 41 | AVVideoFieldMode: kCFBooleanTrue 42 | 43 | } 44 | } 45 | 46 | output = AVCaptureMovieFileOutput.alloc().init() 47 | session.addOutput_(output) 48 | session.startRunning() 49 | 50 | output.startRecordingToOutputFileURL_recordingDelegate_(output_url, CFDictionaryRef(video_settings)) 51 | 52 | 53 | output.stopRecording() 54 | session.stopRunning() 55 | return session 56 | 57 | def webcamera_video_capture(self, filename, record_time, camera_index): 58 | session = AVCaptureSession.alloc().init() 59 | session.setSessionPreset_(AVCaptureSessionPresetHigh) 60 | 61 | devices = AVCaptureDevice.devicesWithMediaType_(AVMediaTypeVideo) 62 | device = devices[camera_index] if devices else None 63 | 64 | input = AVCaptureDeviceInput.deviceInputWithDevice_error_(device, None)[0] 65 | output = AVCaptureMovieFileOutput.alloc().init() 66 | 67 | if session.canAddInput_(input): 68 | session.addInput_(input) 69 | if session.canAddOutput_(output): 70 | session.addOutput_(output) 71 | 72 | session.startRunning() 73 | 74 | file_url = NSURL.fileURLWithPath_(NSString.stringWithString_(filename)) 75 | output.startRecordingToOutputFileURL_recordingDelegate_(file_url, True) 76 | 77 | sleep(record_time) 78 | 79 | output.stopRecording() 80 | session.stopRunning() 81 | 82 | @property 83 | def list_devises(self): 84 | """ 85 | Return all available devises for recording audio/video. 86 | :return: Devises 87 | """ 88 | 89 | params = [AVCaptureDeviceTypeBuiltInWideAngleCamera, 90 | AVCaptureDeviceTypeExternalUnknown] 91 | dtype = ( 92 | AVFoundation.AVCaptureDevicePositionFront & AVFoundation.AVCaptureDevicePositionBack 93 | ) 94 | 95 | camerasData = AVFoundation.AVCaptureDeviceDiscoverySession.discoverySessionWithDeviceTypes_mediaType_position_( 96 | params, 97 | AVFoundation.AVMediaTypeVideo, 98 | dtype 99 | ) 100 | return camerasData.devices() 101 | 102 | -------------------------------------------------------------------------------- /macos/wifi.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import CoreWLAN 3 | from .exceptions import * 4 | import SystemConfiguration 5 | import warnings 6 | 7 | 8 | class Wifi(object): 9 | """Connect to wi-fi networks/ Data about wifi.""" 10 | 11 | def __init__(self): 12 | import CoreWLAN 13 | self.interface = CoreWLAN.CWInterface.interfaceWithName_("en0") 14 | 15 | self.speed = subprocess.getoutput(cmd='airport -I | grep maxRate') 16 | self.last_speed = subprocess.getoutput(cmd='airport -I | grep lastTxRate') 17 | self.secT = subprocess.getoutput(cmd='airport -I | grep "link auth"') 18 | 19 | @staticmethod 20 | def connectTo(wifi_network, password): 21 | """ 22 | Auto connect to wi-fi network. 23 | :param wifi_network: Wi-fi name, which you would to connect. 24 | :param password: Password of this Network.(use hide variable) 25 | :return: 'Successful...' if you successfully connect to wi-fi. 26 | """ 27 | 28 | iface = CoreWLAN.CWInterface.interface() 29 | 30 | networks, error = iface.scanForNetworksWithName_error_(wifi_network, None) 31 | 32 | network = networks.anyObject() 33 | 34 | success_connect, error = iface.associateToNetwork_password_error_(network, password, None) 35 | if error: 36 | raise WifiNameConnectError(f'Can not connect to wifi network name "{wifi_network}"') 37 | 38 | def Disconnect(self): 39 | subprocess.getoutput(cmd='networksetup -setnetworkserviceenabled Wi-Fi off') 40 | 41 | def Connect(self): 42 | subprocess.getoutput(cmd='networksetup -setnetworkserviceenabled Wi-Fi on') 43 | 44 | def connectToMacAddress(self): 45 | """Connect to wi-fi which used your Mac. 46 | (Actually connect to Your Mac address, start host Apmode.)""" 47 | self.interface.startHostAPMode_(None) 48 | 49 | def NetworkNoise(self): 50 | """Noise of current connected wi-fi network.""" 51 | return int(self.interface.noise()) 52 | 53 | def Bssid(self): 54 | ps = subprocess.getoutput(cmd='airport -I | grep BSSID').strip(' ') 55 | return ps 56 | 57 | def InfoNetwork(self): 58 | """Ruturn a lot of data about current wifi network""" 59 | return str(self.interface.ipMonitor()).strip().split('>')[1] 60 | 61 | def TransmitRate(self): 62 | return self.interface.transmitRate() 63 | 64 | def ChannelGhz(self): 65 | """Ghz type channel.It is 2Ghz or 5Ghz.""" 66 | if str(self.interface.wlanChannel()).split('>')[-1].split(',')[0].strip() == 'None': 67 | return None 68 | return str(self.interface.wlanChannel()).split('>')[-1].split(',')[0].strip() 69 | 70 | def RssiChannelValue(self): 71 | return self.interface.aggregateRSSI() 72 | 73 | def _get_speed_by_current_network(self): # Deleted method. 74 | raise NotImplementedError( 75 | f'{repr(self._get_speed_by_current_network.__name__)} ' 76 | f'Deleted method. Because it already not support.') 77 | 78 | def Get_maxSpeed(self): 79 | return subprocess.getoutput(cmd='airport -I | grep maxRate').strip() 80 | 81 | def get_last_speed_by_current_network(self): 82 | return self.last_speed.strip().split(':')[-1] 83 | 84 | def IsEnable(self): 85 | return not subprocess.getoutput(cmd='airport -I | grep SSID').split(':')[-1].strip() == '' 86 | 87 | def wifiChannel(self): 88 | """Return Wi-fi channel """ 89 | return self.interface.channel() 90 | 91 | def UnplugWifi(self): 92 | """Unplug wi-fi""" 93 | self.interface.setPower_error_(None, None) 94 | 95 | def SecurityType(self): 96 | """Return security type of current wi-fi network""" 97 | return self.secT.split(':')[-1] 98 | 99 | def get_info(self, ssid): 100 | return \ 101 | str(CoreWLAN.CWInterface.interfaceWithName_("en0").scanForNetworksWithName_error_(ssid, None)).split('[')[ 102 | 1].split(', ')[:4] 103 | 104 | def GetCounrtyCodeByCurrentWifi(self): 105 | return self.interface.countryCodeInternal() 106 | 107 | 108 | -------------------------------------------------------------------------------- /voices.txt: -------------------------------------------------------------------------------- 1 | 2 | # Voices for python funtions. 3 | 4 | """ 5 | Agnes en_US 6 | Albert en_US 7 | Alex en_US 8 | Alice it_IT 9 | Alva sv_SE 10 | Amelie fr_CA 11 | Anna de_DE 12 | Bad News en_US 13 | Bahh en_US 14 | Bells en_US 15 | Boing en_US 16 | Bruce en_US 17 | Bubbles en_US 18 | Carmit he_IL 19 | Cellos en_US 20 | Damayanti id_ID 21 | Daniel en_GB 22 | Deranged en_US 23 | Diego es_AR 24 | Ellen nl_BE 25 | Fiona en-scotland 26 | Fred en_US 27 | Good News en_US 28 | Hysterical en_US 29 | Ioana ro_RO 30 | Joana pt_PT 31 | Junior en_US 32 | Kanya th_TH 33 | Karen en_AU 34 | Kathy en_US 35 | Kyoko ja_JP 36 | Laura sk_SK 37 | Lekha hi_IN 38 | Luciana pt_BR 39 | Mariska hu_HU 40 | Mei-Jia zh_TW 41 | Melina el_GR 42 | Milena ru_RU 43 | Moira en_IE 44 | Monica es_ES 45 | Nora nb_NO 46 | Paulina es_MX 47 | Pipe Organ en_US 48 | Princess en_US 49 | Ralph en_US 50 | Samantha en_US 51 | Sara da_DK 52 | Satu fi_FI 53 | Sin-ji zh_HK 54 | Tarik ar_SA 55 | Tessa en_ZA 56 | Thomas fr_FR 57 | Ting-Ting zh_CN 58 | Trinoids en_US 59 | Veena en_IN 60 | Vicki en_US 61 | Victoria en_US 62 | Whisper en_US 63 | Xander nl_NL 64 | Yelda tr_TR 65 | Yuna ko_KR 66 | Zarvox en_US 67 | Zosia pl_PL 68 | Zuzana cs_CZ 69 | """ 70 | 71 | -------------------------------------------------------------------------------- /windows/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alexandro1112/driver_controller/32596a13d5f06ad998d995858404e2fcfdb2c6da/windows/__init__.py -------------------------------------------------------------------------------- /windows/brightness.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from .exceptions import ValueBrightnessError 3 | 4 | class Brightness: 5 | def set_brightness(self, brightness): 6 | if type(brightness) != int or type(brightness) != float: 7 | raise ValueBrightnessError('Brightness must be type:', int, float) 8 | cmd = 'powershell (Get-WmiObject -Namespace root/WMI -Class WmiMonitorBrightnessMethods).WmiSetBrightness(1,%s)' 9 | subprocess.getoutput(cmd=cmd) -------------------------------------------------------------------------------- /windows/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Individual exceptions for driver_controller 4 | 5 | """ 6 | 7 | 8 | try: 9 | exc = ExceptionGroup 10 | except NameError: 11 | exc = ReferenceError 12 | 13 | 14 | class ApplicationNameError(NameError): 15 | """ 16 | App with pointed out name not exist. 17 | """ 18 | 19 | 20 | class ApplicationNotExist(SystemError): 21 | """ 22 | Application, which you point outed is not exist 23 | """ 24 | 25 | 26 | class UnsupportedFormat(FileExistsError): 27 | """ 28 | Method screenshot support only ['png', 'jpg', 'ico', 'gif', 'pict'] formats. 29 | """ 30 | 31 | 32 | class ConfirmationError(TypeError): 33 | """ 34 | If confirmation is [False]. 35 | """ 36 | 37 | 38 | class InvalidExtension(NameError): 39 | """ 40 | No extension specified. 41 | """ 42 | 43 | 44 | class WifiNameConnectError(NameError): 45 | """ 46 | Password or SSID/Wi-fi name of Network is not right. 47 | """ 48 | 49 | 50 | class ValueBrightnessError(ValueError, TypeError): 51 | """ 52 | Value is not type [int]. 53 | """ 54 | 55 | 56 | class WifiValueError(ValueError, BaseException): 57 | """ 58 | There is no wi-fi network in util "bunch keys". 59 | """ 60 | 61 | 62 | class ExtensionError(ValueError): 63 | pass 64 | 65 | 66 | class PathError(FileNotFoundError): 67 | pass 68 | 69 | 70 | class CallError(exc): 71 | pass 72 | 73 | 74 | class RgbValueError(ValueError): 75 | """No available color for bg""" 76 | pass 77 | 78 | 79 | class OpenPossibilityError(FileExistsError): 80 | """Can not open file in that app.""" 81 | 82 | 83 | class ScreenErrorIndex(IndexError): 84 | """Screen ID not exist.""" 85 | 86 | 87 | class ScreenWarning(Warning): 88 | """Not support bridge with objective-c and python via IOKit.""" 89 | 90 | 91 | class BluetoothConnectionError(ConnectionRefusedError): 92 | """Specify not right address to pair.""" 93 | 94 | # END FILE 95 | -------------------------------------------------------------------------------- /windows/notifier.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | class Notifier(object): 4 | def __init__(self): 5 | self.STOP_ICON = 0x10 6 | self.WARNING_ICON = 0x30 7 | self.QUESTION_ICON = 0x20 8 | self.center_message = 'powershell (New-Object -ComObject Wscript.Shell).Popup("""%s""",0,"""%s""",%s)' 9 | 10 | def send_text_message(self, text, label, icon): 11 | 12 | if icon == 'stop': 13 | subprocess.getoutput(cmd=self.center_message % (text, label, self.STOP_ICON)) 14 | elif icon == 'warning': 15 | subprocess.getoutput(cmd=self.center_message % (text, label, self.WARNING_ICON)) 16 | elif icon == 'question': 17 | subprocess.getoutput(cmd=self.center_message % (text, label, self.QUESTION_ICON)) 18 | 19 | else: 20 | raise ValueError(' ') -------------------------------------------------------------------------------- /windows/password.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from .exceptions import * 3 | class Password: 4 | def show_password_wifi(self, name_wifi_network): 5 | if subprocess.getstatusoutput(cmd=f'netsh wlan show profile name={name_wifi_network} key=clear')[ 6 | 0] == 1: 7 | raise WifiValueError(f'Can not find wifi-network {repr(name_wifi_network)}') 8 | else: 9 | password = subprocess.getoutput( 10 | cmd=f'netsh wlan show profile name={name_wifi_network} key=clear') 11 | return password.strip() --------------------------------------------------------------------------------