From 2cee0396de887f6c23283d05c5b5c4ff646d92b7 Mon Sep 17 00:00:00 2001 From: coolneng Date: Fri, 10 Jun 2022 20:03:25 +0200 Subject: [PATCH] Update mouse library --- mouse/.gitignore | 101 ++++ mouse/CHANGES.md | 30 ++ mouse/LICENSE.txt | 21 + mouse/Makefile | 18 + mouse/README.md | 500 ++++++++++++++++++ mouse/__init__.pyc | Bin 12107 -> 0 bytes mouse/__pycache__/__init__.cpython-38.pyc | Bin 9978 -> 0 bytes mouse/__pycache__/_generic.cpython-38.pyc | Bin 2485 -> 0 bytes mouse/__pycache__/_mouse_event.cpython-38.pyc | Bin 547 -> 0 bytes mouse/__pycache__/_nixcommon.cpython-38.pyc | Bin 5385 -> 0 bytes mouse/__pycache__/_nixmouse.cpython-38.pyc | Bin 3578 -> 0 bytes mouse/_generic.pyc | Bin 2992 -> 0 bytes mouse/_mouse_event.pyc | Bin 694 -> 0 bytes mouse/_nixcommon.pyc | Bin 6782 -> 0 bytes mouse/_nixmouse.pyc | Bin 4889 -> 0 bytes mouse/make_release.py | 91 ++++ mouse/{ => mouse}/__init__.py | 4 - mouse/{ => mouse}/__main__.py | 0 mouse/{ => mouse}/_generic.py | 0 mouse/{ => mouse}/_mouse_event.py | 0 mouse/{ => mouse}/_mouse_tests.py | 0 mouse/{ => mouse}/_nixcommon.py | 10 +- mouse/{ => mouse}/_nixmouse.py | 0 mouse/{ => mouse}/_winmouse.py | 0 mouse/setup.py | 38 ++ 25 files changed, 801 insertions(+), 12 deletions(-) create mode 100644 mouse/.gitignore create mode 100644 mouse/CHANGES.md create mode 100644 mouse/LICENSE.txt create mode 100644 mouse/Makefile create mode 100644 mouse/README.md delete mode 100644 mouse/__init__.pyc delete mode 100644 mouse/__pycache__/__init__.cpython-38.pyc delete mode 100644 mouse/__pycache__/_generic.cpython-38.pyc delete mode 100644 mouse/__pycache__/_mouse_event.cpython-38.pyc delete mode 100644 mouse/__pycache__/_nixcommon.cpython-38.pyc delete mode 100644 mouse/__pycache__/_nixmouse.cpython-38.pyc delete mode 100644 mouse/_generic.pyc delete mode 100644 mouse/_mouse_event.pyc delete mode 100644 mouse/_nixcommon.pyc delete mode 100644 mouse/_nixmouse.pyc create mode 100644 mouse/make_release.py rename mouse/{ => mouse}/__init__.py (98%) rename mouse/{ => mouse}/__main__.py (100%) rename mouse/{ => mouse}/_generic.py (100%) rename mouse/{ => mouse}/_mouse_event.py (100%) rename mouse/{ => mouse}/_mouse_tests.py (100%) rename mouse/{ => mouse}/_nixcommon.py (96%) rename mouse/{ => mouse}/_nixmouse.py (100%) rename mouse/{ => mouse}/_winmouse.py (100%) create mode 100644 mouse/setup.py diff --git a/mouse/.gitignore b/mouse/.gitignore new file mode 100644 index 0000000..7bbc71c --- /dev/null +++ b/mouse/.gitignore @@ -0,0 +1,101 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/mouse/CHANGES.md b/mouse/CHANGES.md new file mode 100644 index 0000000..e877696 --- /dev/null +++ b/mouse/CHANGES.md @@ -0,0 +1,30 @@ +# 0.7.1 + +- Fixed errors and incorrect information on setup.py. +- Fixed Windows segfault. +- Applied pending bug fixes. + + +# 0.7.0 + +- [All] Fix Windows hook error (#1). +- [All] Add __main__ module, allowing `python -m mouse` to save and load events. + + +# 0.6.1 + +- [Windows] Fixed ctypes type-checking error. +- [All] Misc fixes to release process. + + +# 0.6.0 + +- Added README and API docs. +- Bump version to replace old library. + + +# 0.0.1 + +- Initial release, migrated from `keyboard` package. + + diff --git a/mouse/LICENSE.txt b/mouse/LICENSE.txt new file mode 100644 index 0000000..4f3cb7b --- /dev/null +++ b/mouse/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Lucas Boppre Niehues + +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 +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/mouse/Makefile b/mouse/Makefile new file mode 100644 index 0000000..b2f750a --- /dev/null +++ b/mouse/Makefile @@ -0,0 +1,18 @@ +test: tests +tests: + python2 -m coverage run -m mouse._mouse_tests + python2 -m coverage run -am mouse._mouse_tests + python -m coverage run -am mouse._mouse_tests + python -m coverage run -am mouse._mouse_tests + python -m coverage report && coverage3 html + +build: tests mouse setup.py + python ../docstring2markdown/docstring2markdown.py mouse "https://github.com/boppreh/mouse/blob/master" > README.md + find . \( -name "*.py" -o -name "*.sh" -o -name "* .md" \) -exec dos2unix {} \; + python setup.py sdist --format=zip bdist_wheel --universal bdist_wininst && twine check dist/* + +release: + python make_release.py + +clean: + rm -rfv dist build coverage_html_report mouse.egg-info \ No newline at end of file diff --git a/mouse/README.md b/mouse/README.md new file mode 100644 index 0000000..ea98e2f --- /dev/null +++ b/mouse/README.md @@ -0,0 +1,500 @@ + +mouse +===== + +Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more. + +_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._ + +## Features + +- Global event hook on all mice devices (captures events regardless of focus). +- **Listen** and **sends** mouse events. +- Works with **Windows** and **Linux** (requires sudo). +- **Pure Python**, no C modules to be compiled. +- **Zero dependencies**. Trivial to install and deploy, just copy the files. +- **Python 2 and 3**. +- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play). +- Events automatically captured in separate thread, doesn't block main program. +- Tested and documented. + +This program makes no attempt to hide itself, so don't use it for keyloggers. + +## Usage + +Install the [PyPI package](https://pypi.python.org/pypi/mouse/): + + $ sudo pip install mouse + +or clone the repository (no installation required, source files are sufficient): + + $ git clone https://github.com/boppreh/mouse + +Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available. + + +## Known limitations: + +- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) +- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root. +- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events. + + + +# API +#### Table of Contents + +- [mouse.**ButtonEvent**](#mouse.ButtonEvent) +- [mouse.**DOUBLE**](#mouse.DOUBLE) +- [mouse.**DOWN**](#mouse.DOWN) +- [mouse.**LEFT**](#mouse.LEFT) +- [mouse.**MIDDLE**](#mouse.MIDDLE) +- [mouse.**MoveEvent**](#mouse.MoveEvent) +- [mouse.**RIGHT**](#mouse.RIGHT) +- [mouse.**UP**](#mouse.UP) +- [mouse.**WheelEvent**](#mouse.WheelEvent) +- [mouse.**X**](#mouse.X) +- [mouse.**X2**](#mouse.X2) +- [mouse.**version**](#mouse.version) +- [mouse.**is\_pressed**](#mouse.is_pressed) +- [mouse.**press**](#mouse.press) *(aliases: `hold`)* +- [mouse.**release**](#mouse.release) +- [mouse.**click**](#mouse.click) +- [mouse.**double\_click**](#mouse.double_click) +- [mouse.**right\_click**](#mouse.right_click) +- [mouse.**wheel**](#mouse.wheel) +- [mouse.**move**](#mouse.move) +- [mouse.**drag**](#mouse.drag) +- [mouse.**on\_button**](#mouse.on_button) +- [mouse.**on\_click**](#mouse.on_click) +- [mouse.**on\_double\_click**](#mouse.on_double_click) +- [mouse.**on\_right\_click**](#mouse.on_right_click) +- [mouse.**on\_middle\_click**](#mouse.on_middle_click) +- [mouse.**wait**](#mouse.wait) +- [mouse.**get\_position**](#mouse.get_position) +- [mouse.**hook**](#mouse.hook) +- [mouse.**unhook**](#mouse.unhook) +- [mouse.**unhook\_all**](#mouse.unhook_all) +- [mouse.**record**](#mouse.record) +- [mouse.**play**](#mouse.play) *(aliases: `replay`)* + + + + +## class mouse.**ButtonEvent** + +ButtonEvent(event_type, button, time) + + + + +### ButtonEvent.**button** + +Alias for field number 1 + + + + +### ButtonEvent.**count**(self, value, /) + +Return number of occurrences of value. + + + + +### ButtonEvent.**event\_type** + +Alias for field number 0 + + + + +### ButtonEvent.**index**(self, value, start=0, stop=9223372036854775807, /) + +Return first index of value. + +Raises ValueError if the value is not present. + + + + +### ButtonEvent.**time** + +Alias for field number 2 + + + + + + +## mouse.**DOUBLE** +```py += 'double' +``` + + + +## mouse.**DOWN** +```py += 'down' +``` + + + +## mouse.**LEFT** +```py += 'left' +``` + + + +## mouse.**MIDDLE** +```py += 'middle' +``` + + + +## class mouse.**MoveEvent** + +MoveEvent(x, y, time) + + + + +### MoveEvent.**count**(self, value, /) + +Return number of occurrences of value. + + + + +### MoveEvent.**index**(self, value, start=0, stop=9223372036854775807, /) + +Return first index of value. + +Raises ValueError if the value is not present. + + + + +### MoveEvent.**time** + +Alias for field number 2 + + + + +### MoveEvent.**x** + +Alias for field number 0 + + + + +### MoveEvent.**y** + +Alias for field number 1 + + + + + + +## mouse.**RIGHT** +```py += 'right' +``` + + + +## mouse.**UP** +```py += 'up' +``` + + + +## class mouse.**WheelEvent** + +WheelEvent(delta, time) + + + + +### WheelEvent.**count**(self, value, /) + +Return number of occurrences of value. + + + + +### WheelEvent.**delta** + +Alias for field number 0 + + + + +### WheelEvent.**index**(self, value, start=0, stop=9223372036854775807, /) + +Return first index of value. + +Raises ValueError if the value is not present. + + + + +### WheelEvent.**time** + +Alias for field number 1 + + + + + + +## mouse.**X** +```py += 'x' +``` + + + +## mouse.**X2** +```py += 'x2' +``` + + + +## mouse.**version** +```py += '0.7.1' +``` + + + +## mouse.**is\_pressed**(button='left') + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L78) + +Returns True if the given button is currently pressed. + + + + +## mouse.**press**(button='left') + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L83) + +Presses the given button (but doesn't release). + + + + +## mouse.**release**(button='left') + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L87) + +Releases the given button. + + + + +## mouse.**click**(button='left') + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L91) + +Sends a click with the given button. + + + + +## mouse.**double\_click**(button='left') + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L96) + +Sends a double click with the given button. + + + + +## mouse.**right\_click**() + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L101) + +Sends a right click with the given button. + + + + +## mouse.**wheel**(delta=1) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L105) + +Scrolls the wheel `delta` clicks. Sign indicates direction. + + + + +## mouse.**move**(x, y, absolute=True, duration=0) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L109) + + +Moves the mouse. If `absolute`, to position (x, y), otherwise move relative +to the current position. If `duration` is non-zero, animates the movement. + + + + + +## mouse.**drag**(start\_x, start\_y, end\_x, end\_y, absolute=True, duration=0) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L143) + + +Holds the left mouse button, moving from start to end position, then +releases. `absolute` and `duration` are parameters regarding the mouse +movement. + + + + + +## mouse.**on\_button**(callback, args=(), buttons=('left', 'middle', 'right', 'x', 'x2'), types=('up', 'down', 'double')) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L156) + +Invokes `callback` with `args` when the specified event happens. + + + + +## mouse.**on\_click**(callback, args=()) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L170) + +Invokes `callback` with `args` when the left button is clicked. + + + + +## mouse.**on\_double\_click**(callback, args=()) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L174) + + +Invokes `callback` with `args` when the left button is double clicked. + + + + + +## mouse.**on\_right\_click**(callback, args=()) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L180) + +Invokes `callback` with `args` when the right button is clicked. + + + + +## mouse.**on\_middle\_click**(callback, args=()) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L184) + +Invokes `callback` with `args` when the middle button is clicked. + + + + +## mouse.**wait**(button='left', target\_types=('up', 'down', 'double')) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L188) + + +Blocks program execution until the given button performs an event. + + + + + +## mouse.**get\_position**() + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L199) + +Returns the (x, y) mouse position. + + + + +## mouse.**hook**(callback) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L203) + + +Installs a global listener on all available mouses, invoking `callback` +each time it is moved, a key status changes or the wheel is spun. A mouse +event is passed as argument, with type either `mouse.ButtonEvent`, +`mouse.WheelEvent` or `mouse.MoveEvent`. + +Returns the given callback for easier development. + + + + + +## mouse.**unhook**(callback) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L215) + + +Removes a previously installed hook. + + + + + +## mouse.**unhook\_all**() + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L221) + + +Removes all hooks registered by this application. Note this may include +hooks installed by high level functions, such as [`record`](#mouse.record). + + + + + +## mouse.**record**(button='right', target\_types=('down',)) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L228) + + +Records all mouse events until the user presses the given button. +Then returns the list of events recorded. Pairs well with [`play(events)`](#mouse.play). + +Note: this is a blocking function. +Note: for more details on the mouse hook and events see [`hook`](#mouse.hook). + + + + + +## mouse.**play**(events, speed\_factor=1.0, include\_clicks=True, include\_moves=True, include\_wheel=True) + +[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L242) + + +Plays a sequence of recorded events, maintaining the relative time +intervals. If speed_factor is <= 0 then the actions are replayed as fast +as the OS allows. Pairs well with [`record()`](#mouse.record). + +The parameters `include_*` define if events of that type should be inluded +in the replay or ignored. + + + diff --git a/mouse/__init__.pyc b/mouse/__init__.pyc deleted file mode 100644 index 0e8936fcea774771629d0e2498c2c6f0ce753dce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12107 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
mRr`f>+-1;pbRvKD4XlMPY{MMjf?9>nu z9*+-B=p0@+Z;Bb;F?b#Zcmm4=IGbYj#RF4#VDcA-k%8vn6P77@D71p#ZN!G=?w;We()azZX|^y|e#&FBYwate$pX^aJNl4p{vJIodwm(PF|{-S?99? zq5*<6a(s%)RVJSiP&RR98oSRK1eSY$NC&(=@`=N0FO}LCguj0P+j5^al!7xtEJ+bc ztL74eJrDp!myTXd=;XhUHlp%?v=a^Y$=o27+Nnd`;0TT8<#3@gZM?42|_PmU=pHhq$D7TsJ<>eU+b&3Xt-_l6Z zN1kyN`s$@1MsB`ou$;>m`He`;O`8Lu1sqxUu465^>plXJT0zO9QhH??zdqtePteu^ z-x8wE zG3dUP{8_&Qi9soDdiVcBh7QQQa%iRxX<8utit$YTE15SV^A1XTh)=!ygV~2=HfCV+ z7(}h}h|D`GB93|Ze+LMalKi8-BridbC@dDASm4trL-Fe~sFXu~MuD0lu6|jlU*r^* zCbEa;Cf^7Wlqm428_E|rbzTiZe2qgt_1-1@I>RX^Vi-n{g+(EK_>uw}a6W7`u!R7F zKchC>TBd&Co3N+IzuRJMAp1}yeqqwDVzo*G)|_uaz*l2@B8213Qka3Ed<4P}O53%p zm%t`sLdq|=q7oh1f!iIuA}an+mNIXWI_%AwoRCwb`0b3(qaB~VL|hVmy;LVgDk%)5 zT&yGEo+t$aC7H}%a_cHF3hJxci(T2Z|)@NU?Oj?^1%f*q?MB`GRKu|FS945fE(<6&gLeYTWnZ;a7LYBx=(X2=H2IssQ*(o zZ8Smy$C@%QOCtYeJa~dTyN>oqkoVlj6+fn4SZ-``e6liKnf8vt>f@@MuH5hrSEjs^ y2d6626Vv1PH!(dig};YhIW#kWP(~)%&K{T=pPHVUoZ5Hv;ECr@`UjK=?|%Rz!ib0f diff --git a/mouse/__pycache__/__init__.cpython-38.pyc b/mouse/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 80e1dc4810ff8e2626acd2bf5959f55fd0060f5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9978 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 YIXzynD-)GcrF>|z`W#YhRu!`LKjl9Wb^rhX diff --git a/mouse/__pycache__/_generic.cpython-38.pyc b/mouse/__pycache__/_generic.cpython-38.pyc deleted file mode 100644 index f58ab70375696765d62678a5376aa791069365ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2485 zcmZ`)OK%%D5GJ_~tt4A^5~B^!G-Y~dAT+QG1i1x4g1p)yFw(|F90A34y`-&;SGzJv zsqw<@q0Y7cK{@&_@!C^t zBM;%%yHE)tXif&SM+dCOD2`d~^*q=5J-=Foo|gxMuoqJDniSk8va#P%FDb##NyA$D zh7@d@JSV~z!FwVC8J&2&reLo~H~a`^kuJ00R$s|PSpP+t?r(Of4SpKQkxWs1zAzX( zgkS#%l_WhXNRLVHg!Ftt1$$3=f$)S6Z72c}Lfa4x5kVV?rf5Oi6m78tZA&bR4zz8t z0vB1eE6-&iRhGWUw836V;e=ViJ|6uTetjLPJ#s{1zzAw;*a?mR8`y|#KI{56>L-QB zrP8*UyZy3aPx-LU1_x-@DYd?q`R*xEZJ7P{?nb{H$c?lt^FkJT8!uJ)R;EU83{{z^ z9hsSpK{?WLBi^fTxjsC!Q5aI#r2D<*P-TUQ<+~L0kfAn^V_6v6m||$D zbRgB$5^Ahu#kky;@eJi_FsV^OXp1r$u_d}ntFIPeSXgz*!x#Y$4FerSV?xosY8(2V z{_TiNd>lKkdnSO{P_Vy{0}Y&e+lV8qCr#9H^43(|cJj89w`)0~2HIr8PH>7i5!620*!aF4Pa#|weDS+c7WYe zRn>%@7TtB#EsL|=xRAImQHM7`%>@$i(PJU_ETkP8(H6tH!>X?ry?1$&3v@;k<{^q) zFyN>Y`X^)v7naq%t$wEYK$?CjxbByuT<{&qv%xTz10b9PSPKVt+Rs3i=84wp0OhsK z()@6y^;D@+oifK&b>$Q00xB||A`?31rf zkYYJbVhTD7ZS^G#@4~O$W94^P3qra@tIsdP<~VqX19Px2O#>7J%?Ft11X3D;G6iBh z2jY%KqI-bAVBRJ{M5`|rAvve{|FEpWYR4LS0gi9^ z&k*8c@NWXXmg5YboBWW&mJkz z7r&^AISbylA{odywyiiGlwy=)e<_X+MoC^v6na{HhSf4w$gUb%M>Zsqx{XyAt20zx z4-=!Wx?^lOjW&Z(i!&*}S diff --git a/mouse/__pycache__/_mouse_event.cpython-38.pyc b/mouse/__pycache__/_mouse_event.cpython-38.pyc deleted file mode 100644 index 5839c750fbe8990fb7301edd30af79c4ca604b8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 547 zcmYjMO^?$s5RKg=O_QcuKE;6p*ItOU7cMKrE)BF&wq2E$uI5su9n)sz#F684w_N!z zNc<&VIq?gSIN@{=FqYrUn>QLiFT&8bO#Jj-tiBS<`reTL!!hKIxz&vUw2*KsCqRgW z6ezZ!g*MpefP*f$*oHQG;9&2Pq4pjeW4H<{s12uMh)v3_6S{k z{6{^(Cm*cA(;wzNYe2MLq&Y)Xmz-&vvrkGpGTZJHxOs+Xn$GQxF|NrS(7RKhb!q&F z+rqdJ^_nyA_Drg5lXCEPLS~;up;E4ci&`mB#CujK?XxDW)S+bBT^|K)t1M^QUpC9{ zryOKlrMhz|_Uyhx4wFG&2OGgT+o((wm88bCwv+hXTsyPz`_Wvxm*e3uiNRTp;yBUd zTGQ)OO&3?%9!{4N?GC4l3!{4<p*vTgRspn=f9H%mTi>IQzj zigqGr(MAYfuwolsNpWLrR8c8KD%UJiQ7-C=MXO_49Y6W9JZSGM7g%%lx-nZlH_)Xv M`FsA=tv>0I-?bx{7XSbN diff --git a/mouse/__pycache__/_nixcommon.cpython-38.pyc b/mouse/__pycache__/_nixcommon.cpython-38.pyc deleted file mode 100644 index c614439e01fbfc5cd76955aced64214a293f4f5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5385 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 diff --git a/mouse/__pycache__/_nixmouse.cpython-38.pyc b/mouse/__pycache__/_nixmouse.cpython-38.pyc deleted file mode 100644 index 90d0e73032dfb662a86e506280d255db69c66927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3578 zcmbVONpsw|6$Zei*_*7*@+R-w^kghqo_)rdi9KqMRU^xeCC6=)Q%tJ?Nwmmj8$`=e ziha_Ya!OVHfOJ$<&iM(c{03Ze(l1DAQkBYkpkggaE+GpK55Ob%@VyN$>h%hN=WoH4 z@b7g({)&U653c?KTDD0E5k%0KaO_!36UG@W<{a(_N4T+@c-%{T?k6Q)N&+4vWnNAy zypmLT6=WUZ#kHi)>&XxwN>1@p$uJ*IM)*iF%14tiK9-F0@#Hi=olNkFgT2r2Gxon{ zZSTitl5_lAa-N@0F7OM7fIvxKH6lVK~1f*COhk4 z+Sk3l-UpkIM#=ciUxhz3U)lb7bKdq(7QeIo;;RMQKX|xkM%t^ZO0KrG429f?Ix;g= z+0FV&hAK^UqhhKL`&y^n=7#KQQ+c^2WnA#(C+UVPSa-hpXvuib=e~cuWc(*{v$OL} zLtBQm?iu#tnQ>>IzFcT{Cg_CysH;D|XZ(UQUMGYJT-Zn>5%!F?yrtwy2M>4j@nG;B zwCouWP1LZa(3lz)WRYm+jl1Ik^><2w?!wz`f)CV!u-nY?p4+HUYk- z3CL0WzTqrzr!_O9EO>QO5>eKR+grwe7j;GY&N!PhGoZ5G>dB0|9TCU8I-j=1e6+0E zYKyyl9mTx10@7i8Fjs5MbtApBres@W>MW?uYptg}*_|ym=OraG+>wvAX5~t|AM59U z_)Gi8J)$nb7nc0=$@E&9$mvd+#$DN6oqnd$H?pI%>7Gj4YFS2lI!XJPoDRFursbx3 zTc*C;k75xX9OV>ZHw1*R8gc2k6F31KqUs9F90NOmi5fHub`Fdt+Xy4wwvCYi8Bon& zbfm4guiXI~I0JV8X4obJU!y^MUDCle)#V(b0VqHZlv(On>RReq>TlEC@}QK1xpL=C zWrcxZ=t84vb+iDgGoX)}Kr#u0*IU2rOSSbZ1s9S^oyUdKNG>2b2gGlhiOL;?Fw4FImrPM1RuS7mty)` zBztV3a8$oQ#zIkRy=<%AF(eQK?zbMr{cLTI8MRYJY0~@VA#7DO82L+`FL_2FAzKomiPc+eiqw6veQYF3xJOb5EW z12F=r4glSD27Y%5q^cnGM_t>g3kGyZIJvvacG+t>aC1kWg4N&Y;oOBU7<_RJ=0^1B z3S0N#tFdhYCJF{+J)Q?SMk?%@!~fR<^{2OfPIgY`J~|-k1##&v{6xPsG%|FqF=3Cb zX5e(Zg4r&VSSu8sTcP_XbO?nWuf~y#0Wm{`sl(;1(3;+Xpi-FSjh|`N?`ZD#yS;X2 zox4a)8LC+L@^P~{uP{A9v4L@`=w8_vQ*c=!+<_tpRm*$Zmwjnm9VJL1&8j=FtgfO= zxv(|l0OMI*jnh`E>J|#zMsjF+Yjr=4GA+CFu$0{Z0zu-8(qYP&OI;SwOEjPp(AVIt z&>9OEW9k9O9rFbYllNr|gZ9uDw4>deoP)}~>l8uWfFO53X3slB*HquB2nuxpFM?`@ z5Ie-MKy!~O%qJ)H_j*ujvNc%A@GFdQ^$7a^Up<8|C=5o0QE>8yP}*YI&SVU0hrj$D zM*oor-y?zw6^P`3!#d=7=-KB`Z*oY7Funynjwz%=h!#W)(K;A;kSY(b+jEKp86$xB zxTN79!l*D9t*fc8koy|RO(ZAGUbo2+j?&iAhU|evQ9-E>wk}?%pmQ+)zk$R=`rl7= z{1g~f>M;m6ju`xireER`HJ*^MZl6@tdxy8O--1Yyj=;XCp85f1Ob~`i8wy*vFJQR; z7rT-5t;WyQ7bsE5`pa;YfV*F&Fm)QHB(LCQ0#a_0c8mB$Llxm{13SQ>&6AkpOf9sD z^uRZ5tYetkm{fT0P<{DJxm_B0;EWs<2`)BqEq^)};1a09f7z=oT`0I>e@-ZI^G zBE#^AJ*^Acq!ZjvQqhm)H)xXVH$X7K1oQ^IYu#@WlMlQ>J*Wg;!DBi)Xm$;FhY?0k Xw12pzQILbLSTI?0Yi>}flq&3Bk2L&v diff --git a/mouse/_generic.pyc b/mouse/_generic.pyc deleted file mode 100644 index f50aff620be211428b81f8eaeee82407731bfe18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2992 zcmb_e-)|d55S~5%JSU+A5>z36EFe@%paco=f>1>%EkcT{a;el1flimZO?=Mz&e>g? z2DJiF-uNr{8+qUnzL~Y1R^kcS_N`}kXLn}4{bu%Bf9(wZ?&~zC<)?%HFY&lv(G>V8 zs)(kFP83ZeI*CZ}XhceMyyL8ee^|*eI+NMVr1G0vclC@Ci zt`urT$3>e=pUxB&9r~TPlIQNDu{BxY+Yk?%{9-gzJi~5( zH#c+RZ$SFS)W(+iVd*?e>)=@RD?IKY8bchDiP&I>1jZ2tB4(k(9|4EIPqYmxF1O#}&rxnn$!1q`+@DjAX? z8%ns5`0qc-&CHigEj@3u+?;0lh4f~&tbJ;p{@%U(%xEWZ>_YqR@yZIbsUwP-eg;LIF{^d!Ar;f z4)pSKhR78(6QkQ4C^!lgF)wjLQDjvJqU$2zh#p-k8N5dWLDH&WLgXL(l z{BmAelQ5@bhN&mQBRe+TYjcv=mz1oN001X;f&vjK@eyOd06LV!<`-M?+>)!WQ*v-sK zKIG;$n(G4*>Hog9BuoHy%yIH`RUE~gIF5JYR=gGWhwNZ@Z;%TM%#wR0cq;L*r$Sb| zD>+Hp@Seq!D3Xo!lC5&nG^hL)B_=oIzQFlK0PqecpW`EV1GmC<)Ka@@2e-q&Cg+3N diff --git a/mouse/_mouse_event.pyc b/mouse/_mouse_event.pyc deleted file mode 100644 index 3c80f97d052f89ef50a787f34fd5b71f834dfa07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 694 zcmYjOO>fgc5FOh|n$HpnMI1PA%n3_exFAGJ42k3>l}SmpmniWpiIMHK>~TuC@-z6E z95}-41VPu{nb|k{X5QG|&q4QB`}rz{zpKgqE$`|F8|2r46d-dzIpClR$_4a5d4LU2 z4ZtR-CSVIx3-AQg31Ayk8?Xba1K0)C1?++90ro-lK|6p0z*E2nfJ4}N@SST81b+y4 zCZH?eseq4caeRF5G850?W^&?Vk8_tbk;#L- z&PmeRMk_iLTB>X$EtM(Bv|L$Q0Y`?_gREvv9geQdULSF*?l2n-*-4k!q^XW6F?kg+ z22wB#-Y;aLX!>EYkakzo@i+_wTuy=@lre8*zT4xNH`l@)&zCb{jORC(%&=pA3ZljI z-9;!OC-Z2k=Cj2`81*?9St-#On-TAOrh3Ike`hl7$Ht_&&bR(`X}+-9$}dW@E;l+M qKQncu{gt?te4`h|LAt)q4A!ZBV}C{UjLpz(IscyjvG>$Dcm4o<$&m5@ diff --git a/mouse/_nixcommon.pyc b/mouse/_nixcommon.pyc deleted file mode 100644 index 1112fead7343f022d1c27be20011df2fa2f96aea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6782 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 Bl0*Oi diff --git a/mouse/make_release.py b/mouse/make_release.py new file mode 100644 index 0000000..455fcb5 --- /dev/null +++ b/mouse/make_release.py @@ -0,0 +1,91 @@ +""" +This little guy streamlines the release process of Python packages. + +By running `python3 make_release.py` it'll do the following tasks automatically: + +- Update README by calling `make_readme.sh` if this file exists. +- Check PyPI RST long_description syntax. +- Show the latest version from CHANGES.md and ask for a new version number. +- Open vim to allow you to edit the list of changes for this new version, showing a list of commits since the last version. +- Prepend your list of changes to CHANGES.md (and ask if you want to commit it now). +- Add a git tag to the current commit. +- Push tag to GitHub. +- Publish a new release to GitHub, asking for the authentication token (optional). +- Publish a new release on PyPI. + +Suggested way to organize your project for a smooth process: + +- Use Markdown everywhere. +- Keep a description of your project in the package's docstring. +- Generate your README from the package docstring plus API docs. +- Convert your package docstring to RST in setup.py and use that as long_description. +- Use raw semantic versioning for CHANGES.md and PyPI (e.g. 2.3.1), and prepend 'v' for git tags and releases (e.g. v2.3.1). + +""" +import re +import sys +import os +from subprocess import run, check_output +import atexit +import requests +import mouse + +run(['make', 'clean', 'build'], check=True) + +assert re.fullmatch(r'\d+\.\d+\.\d+', mouse.version) +last_version = check_output(['git', 'describe', '--abbrev=0'], universal_newlines=True).strip('v\n') +assert mouse.version != last_version, 'Must update mouse.version first.' + +commits = check_output(['git', 'log', 'v{}..HEAD'.format(last_version), '--oneline'], universal_newlines=True) +with open('message.txt', 'w') as message_file: + atexit.register(lambda: os.remove('message.txt')) + + message_file.write('\n\n\n') + message_file.write('# Enter changes one per line like this:\n') + message_file.write('# - Added `foobar`.\n\n\n') + message_file.write('# As a reminder, here\'s the last commits since version {}:\n\n'.format(last_version)) + for line in commits.strip().split('\n'): + message_file.write('# {}\n'.format(line)) + +run(['vim', 'message.txt']) +with open('message.txt') as message_file: + lines = [line for line in message_file.readlines() if not line.startswith('#')] +message = ''.join(lines).strip() +if not message: + print('Aborting release due to empty message.') + exit() +with open('message.txt', 'w') as message_file: + message_file.write(message) + +with open('CHANGES.md') as changes_file: + old_changes = changes_file.read() +with open('CHANGES.md', 'w') as changes_file: + changes_file.write('# {}\n\n{}\n\n\n{}'.format(mouse.version, message, old_changes)) + + +tag_name = 'v' + mouse.version +if input('Commit README.md and CHANGES.md files? ').lower().startswith('y'): + run(['git', 'add', 'CHANGES.md', 'README.md']) + run(['git', 'commit', '-m', 'Update changes for {}'.format(tag_name)]) + run(['git', 'push']) +run(['git', 'tag', '-a', tag_name, '--file', 'message.txt'], check=True) +run(['git', 'push', 'origin', tag_name], check=True) + +token = input('To make a release enter your GitHub repo authorization token: ').strip() +if token: + git_remotes = check_output(['git', 'remote', '-v']).decode('utf-8') + repo_path = re.search(r'github.com[:/](.+?)(?:\.git)? \(push\)', git_remotes).group(1) + releases_url = 'https://api.github.com/repos/{}/releases'.format(repo_path) + print(releases_url) + release = { + "tag_name": tag_name, + "target_commitish": "master", + "name": tag_name, + "body": message, + "draft": False, + "prerelease": False, + } + response = requests.post(releases_url, json=release, headers={'Authorization': 'token ' + token}) + print(response.status_code, response.text) + +run(['twine', 'upload', 'dist/*'], check=True, shell=True) diff --git a/mouse/__init__.py b/mouse/mouse/__init__.py similarity index 98% rename from mouse/__init__.py rename to mouse/mouse/__init__.py index 71a9d14..3a21f46 100644 --- a/mouse/__init__.py +++ b/mouse/mouse/__init__.py @@ -166,10 +166,6 @@ def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP callback(*args) _listener.add_handler(handler) return handler - -def on_pressed(callback, args=()): - """ Invokes `callback` with `args` when the left button is pressed. """ - return on_button(callback, args, [LEFT], [DOWN]) def on_click(callback, args=()): """ Invokes `callback` with `args` when the left button is clicked. """ diff --git a/mouse/__main__.py b/mouse/mouse/__main__.py similarity index 100% rename from mouse/__main__.py rename to mouse/mouse/__main__.py diff --git a/mouse/_generic.py b/mouse/mouse/_generic.py similarity index 100% rename from mouse/_generic.py rename to mouse/mouse/_generic.py diff --git a/mouse/_mouse_event.py b/mouse/mouse/_mouse_event.py similarity index 100% rename from mouse/_mouse_event.py rename to mouse/mouse/_mouse_event.py diff --git a/mouse/_mouse_tests.py b/mouse/mouse/_mouse_tests.py similarity index 100% rename from mouse/_mouse_tests.py rename to mouse/mouse/_mouse_tests.py diff --git a/mouse/_nixcommon.py b/mouse/mouse/_nixcommon.py similarity index 96% rename from mouse/_nixcommon.py rename to mouse/mouse/_nixcommon.py index a77de1d..d240f99 100644 --- a/mouse/_nixcommon.py +++ b/mouse/mouse/_nixcommon.py @@ -20,8 +20,6 @@ EV_REL = 0x02 EV_ABS = 0x03 EV_MSC = 0x04 -INVALID_ARGUMENT_ERRNO = 22 - def make_uinput(): import fcntl, struct @@ -31,12 +29,8 @@ def make_uinput(): fcntl.ioctl(uinput, UI_SET_EVBIT, EV_KEY) UI_SET_KEYBIT = 0x40045565 - try: - for i in range(0x300): - fcntl.ioctl(uinput, UI_SET_KEYBIT, i) - except OSError as e: - if e.errno != INVALID_ARGUMENT_ERRNO: - raise e + for i in range(256): + fcntl.ioctl(uinput, UI_SET_KEYBIT, i) BUS_USB = 0x03 uinput_user_dev = "80sHHHHi64i64i64i64i" diff --git a/mouse/_nixmouse.py b/mouse/mouse/_nixmouse.py similarity index 100% rename from mouse/_nixmouse.py rename to mouse/mouse/_nixmouse.py diff --git a/mouse/_winmouse.py b/mouse/mouse/_winmouse.py similarity index 100% rename from mouse/_winmouse.py rename to mouse/mouse/_winmouse.py diff --git a/mouse/setup.py b/mouse/setup.py new file mode 100644 index 0000000..fdc1b9d --- /dev/null +++ b/mouse/setup.py @@ -0,0 +1,38 @@ +""" +Usage instructions: + +- If you are installing: `python setup.py install` +- If you are developing: `python setup.py sdist --format=zip bdist_wheel --universal bdist_wininst && twine check dist/*` +""" +import mouse + +from setuptools import setup +setup( + name='mouse', + version=mouse.version, + author='BoppreH', + author_email='boppreh@gmail.com', + packages=['mouse'], + package_data={'mouse': ['*.md']}, + url='https://github.com/boppreh/mouse', + license='MIT', + description='Hook and simulate mouse events on Windows and Linux', + keywords = 'mouse hook simulate hotkey', + + # Wheel creation breaks with Windows newlines. + # https://github.com/pypa/setuptools/issues/1126 + long_description=mouse.__doc__.replace('\r\n', '\n'), + long_description_content_type='text/markdown', + + install_requires=[], # OSX-specific dependency + classifiers=[ + 'Development Status :: 4 - Beta', + 'License :: OSI Approved :: MIT License', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: Unix', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: Utilities', + ], +)