Skip to content

Commit

Permalink
A bunch of fixes and improvemenbs (#289)
Browse files Browse the repository at this point in the history
* test: keys are released in reverse order

Since: a4bb988

* ci: Add Python 3.12 as supported

* ci: Quote shell variables

* ci: Move vncdo from /tmp/ to $PWD/.vncdo

Hard-coded paths below /tmp/ are a security issue on shared hosts.

/tmp/ is (often) cleaned up on reboot.

* doc: Fix building documentation

* doc: Improve documentation

Fix spelling errors.

Fix broken links, e.g. https:// everywhere.

Fix Sphinx reST markup.

* doc: Document API shutdown

Issue #288

* refactor: modernize type annotations

pyupgrade --py38-plus
ruff check --fix setup.py vncdotool/*.py

* fix: mouseDrag diagonally

move mouse diagonally instead of first going up/down and then
left/right.

Do not use `time.sleep()` with Twisted reactor as it will also pause all
other event processing.

Patch `vncev` to print all mouse events, including those where not button
is pressed / released.

Issue #287

* fixup! ci: Add Python 3.12 as supported

* fixup! doc: Improve documentation
  • Loading branch information
pmhahn authored Jun 22, 2024
1 parent 2b5f10c commit 317de66
Show file tree
Hide file tree
Showing 23 changed files with 275 additions and 192 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ vncdotool.egg-info
.coverage
.tox
docs/_build
.venv/
.vncdo/

*~
#*
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
1.3.0 (UNRELEASED)
----------------------
- Fix functional test suite (@phahn)
- Python 3.12 is supported (@phahn)
- Improve documentation (@phahn)
- Improve PEP-484 type hinting (@phahn)
- Fix mouse dragging (@phahn)

1.2.0 (2023-06-06)
----------------------
- fixes for api.shutdown and disconnect raise exceptions, #256
Expand Down
9 changes: 4 additions & 5 deletions DEVELOP.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ running. You can either manually configure and update your path or use the prov
OR

make libvnc-examples
export PATH=$PATH:/tmp/vncdo/libvncserver/examples
export PATH="$PATH:.vncdo/libvncserver-LibVNCServer-0.9.14/examples"
python -m unittest discover tests/functional


Expand All @@ -30,9 +30,8 @@ There is a community effort to document the protcol, _rfbproto_.
Preparing a Release
------------------------
1. ensure CHANGELOG.rst contains correct version
1. make version-new-version-number
6. add new section to CHANGELOG.rst
7. update vncdotool/__init__.py version
8. blog post/twitter
1. ``make version-new-version-number``
1. ``make release``
1. blog post/twitter

.. _rfbproto: https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ version:
version-%: OLDVERSION:=$(shell ./setup.py --version)
version-%: NEWVERSION=$(subst -,.,$*)
version-%:
sed -i '' -e s/$(OLDVERSION)/$(NEWVERSION)/ $(VERSION_FILE)
git ci $(VERSION_FILE) -m"bump version to $*"
sed -e "s/$(OLDVERSION)/$(NEWVERSION)/" -i "$(VERSION_FILE)"
git ci -m"bump version to $*" -- "$(VERSION_FILE)"

.PHONY: release
release: release-test release-tag upload
Expand All @@ -33,13 +33,13 @@ release-test: test-unit #test-func
.PHONY: release-tag
release-tag: VERSION:=$(shell ./setup.py --version)
release-tag:
git tag -a v$(VERSION) -m"release version $(VERSION)"
git tag -a "v$(VERSION)" -m"release version $(VERSION)"
git push --tags

.PHONY: upload
upload:
./setup.py sdist
twine upload dist/$(shell ./setup.py --fullname).*
twine upload dist/"$(shell ./setup.py --fullname)".*

.PHONY: docs
docs:
Expand Down
5 changes: 2 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ More documentation can be found on `Read the Docs`_.

Feedback
--------------------------------
If you need help getting VNCDoTool working try the community at `_Stackoverflow`
If you need help getting VNCDoTool working try the community at Stackoverflow_\ .

Patches, and ideas for improvements are welcome and appreciated, via `_GitHub` issues.
Patches, and ideas for improvements are welcome and appreciated, via GitHub_ issues.
If you are reporting a bug or issue please include the version of both vncdotool
and the VNC server you are using it with.

Expand All @@ -87,5 +87,4 @@ Also, to the TigerVNC_ project for creating a community focus RFB specification
.. _Read The Docs: http://vncdotool.readthedocs.org
.. _GitHub: http://github.com/sibson/vncdotool
.. _TigerVNC: http://sourceforge.net/apps/mediawiki/tigervnc/index.php?title=Main_Page
.. _python-vnc-viewer: http://code.google.com/p/python-vnc-viewer
.. _Stackoverflow: https://stackoverflow.com/questions/ask?tags=vncdotool
1 change: 1 addition & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.sphinxsidebarwrapper { overflow-y: scroll; }
2 changes: 1 addition & 1 deletion docs/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ mousedown BUTTON
------------------

mousemove X Y
-----------
---------------

mouseup BUTTON
-----------------
Expand Down
22 changes: 14 additions & 8 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
# serve to show the default.
# flake8: noqa

import os
import sys
from __future__ import annotations

#from pathlib import Path
#import sys

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
#sys.path.insert(0, str(Path(__file__).parents[1]))
#autodoc_mock_imports = ["twisted"]

# -- General configuration -----------------------------------------------------

Expand All @@ -43,16 +46,16 @@

# General information about the project.
project = u'VNCDoTool'
copyright = u'2013, Marc Sibson'
copyright = u'2013-2024, Marc Sibson'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.9'
from vncdotool import __version__ as version
# The full version, including alpha/beta/rc tags.
release = '0.9.0.dev0'
release = version

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -101,7 +104,9 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
html_theme_options = {
"sidebarwidth": "250px"
}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
Expand All @@ -126,6 +131,7 @@
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = ["custom.css"]

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
Expand Down Expand Up @@ -174,7 +180,7 @@

# -- Options for LaTeX output --------------------------------------------------

latex_elements = {
latex_elements: dict[str, str] = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

Expand Down
18 changes: 8 additions & 10 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ vncdotool is available on PyPI_, so in most cases you should be able to simply r

pip install vncdotool

vncdotool relies on a number of libraries, the two major ones are PIL_, the Python Imaging Library and
vncdotool relies on a number of libraries, the two major ones are Pillow_, the Python Imaging Library and
Twisted_, an asynchronous networking library.
While vncdotool should work with any recent version of these libraries sometimes things break.
If you are having issues getting things to work you can try using a stable set of libraries
Expand Down Expand Up @@ -50,15 +50,13 @@ If you are not familiar with Python, the most reliable way to install vncdotool

5. If Hello World shows up on the remote machine that has a VNC server running then its time to celebrate.
Otherwise, first check you can connect from your local machine to the remote using a normal GUI VNC Client.
Once you get the normal GUI client working try vncdotool again and if you still have problems try the community at `_Stackoverflow`.
Once you get the normal GUI client working try vncdotool again and if you still have problems try the community at Stackoverflow_\ .

.. _PyPI: https://pypi.python.org/pypi
.. _PIL: http://www.pythonware.com/products/pil/
.. _PIL Downloads: http://www.pythonware.com/products/pil/
.. _Official Python: http://python.org/downloads/
.. _Twisted: http://twistedmatrix.com/
.. _Twisted Downloads: http://twistedmatrix.com/trac/wiki/Downloads
.. _virtualenv: http://www.virtualenv.org/
.. _ez_setup.py: https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
.. _get_pip.py: https://raw.github.com/pypa/pip/master/contrib/get-pip.py
.. _Pillow: https://python-pillow.org/
.. _PIL Downloads: https://pypi.org/project/pillow/
.. _Official Python: https://python.org/downloads/
.. _Twisted: https://twistedmatrix.com/
.. _Twisted Downloads: https://pypi.org/project/Twisted/
.. _virtualenv: https://virtualenv.pypa.io/
.. _Stackoverflow: https://stackoverflow.com/questions/ask?tags=vncdotool
19 changes: 15 additions & 4 deletions docs/library.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
Embedding in Python Applications
===================================
vncdotool is built with the Twisted_ framework, as such it best intergrates with other Twisted Applications
vncdotool is built with the Twisted_ framework, as such it best integrates with other Twisted Applications.
Rewriting your application to use Twisted may not be an option, so vncdotool provides a compatibility layer.
It uses a separate thread to run the Twisted reactor and communicates with the main program using a threadsafe Queue.
It uses a separate thread to run the Twisted reactor and communicates with the main program using a thread-safe Queue.

.. warning::

While the Twisted reactor runs as a *daemon* thread, the reactor itself will start additional *worker threads*, which are *no daemon threads*.
Therefore the Reactor must be shut down explicitly by calling :func:`vncdotool.api.shutdown`.
Otherwise your application will not terminate as those worker threads remain running in the background.

This also applied when using the API as a context manager:
As the reactor cannot be restarted, it is a design decision to not shut it down as the end of the context.
That would prevent the API from being used multiple times in the same process.

To use the synchronous API you can do the following::

from vncdotool import api
client = api.connect('vncserver', password=None)

The first argument passed to the `connect` method is the VNC server to connect to, and it needs to be in the format `address[:display|::port]`. For example::
The first argument passed to the :func:`~vncdotool.api.connect` method is the VNC server to connect to, and it needs to be in the format ``address[:display|::port]``.
For example::

# connect to 192.168.1.1 on default port 5900
client = api.connect('192.168.1.1', password=None)
Expand Down Expand Up @@ -38,7 +49,7 @@ It is possible to set a per-client timeout in seconds to prevent calls from bloc
except TimeoutError:
print('Timeout when capturing screen')

In case of too many timeout errors, it is recommended to reset the client connection via the `disconnect` and `connect` methods.
In case of too many timeout errors, it is recommended to reset the client connection via the `disconnect` and :func:`~vncdotool.api.connect` methods.

The :class:`vncdotool.client.VNCDoToolClient` supports the context manager protocol.

Expand Down
31 changes: 31 additions & 0 deletions docs/modules.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Code Documentation
======================

:mod:`api` Module
-----------------

.. automodule:: vncdotool.api
:members:
:undoc-members:
:show-inheritance:

:mod:`client` Module
--------------------

Expand All @@ -9,3 +17,26 @@ Code Documentation
:undoc-members:
:show-inheritance:

:mod:`rfb` Module
-----------------

.. automodule:: vncdotool.rfb
:members:
:undoc-members:
:show-inheritance:

:mod:`command` Module
---------------------

.. automodule:: vncdotool.command
:members:
:undoc-members:
:show-inheritance:

:mod:`loggingproxy` Module
--------------------------

.. automodule:: vncdotool.loggingproxy
:members:
:undoc-members:
:show-inheritance:
7 changes: 4 additions & 3 deletions libvncserver.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
LIBVNCSERVER_VERSION?=0.9.14
BUILD_DIR?=/tmp/vncdo
BUILD_DIR?=.vncdo
PYTHON?=python3


Expand All @@ -21,11 +21,11 @@ LIBVNCSERVER_EXAMPLES_SRCS=$(addsuffix .c, $(LIBVNCSERVER_EXAMPLES))
libvnc-examples: $(LIBVNCSERVER_EXAMPLES)

.PHONY: veryclean
veryclean:
veryclean::
rm -rf $(BUILD_DIR)

.PHONY: clean
clean:
clean::
rm -f $(LIBVNCSERVER_EXAMPLES)


Expand All @@ -35,6 +35,7 @@ $(BUILD_DIR)/$(LIBVNCSERVER_TGZ):

$(LIBVNCSERVER_DIR): $(BUILD_DIR)/$(LIBVNCSERVER_TGZ)
tar xfzv $< -C $(BUILD_DIR)
sed -e '/^\s*if(buttonMask)\s*{$/s/buttonMask/1/' -i "$(LIBVNCSERVER_DIR)/examples/vncev.c"

$(LIBVNCSERVER_MAKEFILE): $(LIBVNCSERVER_MAKEFILE_SRCS)
cd $(LIBVNCSERVER_DIR) && cmake .
Expand Down
5 changes: 3 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-r requirements.txt
pexpect==4.8.0
pyvirtualdisplay==3.0
pexpect>=4.8.0
pyvirtualdisplay>=3.0
sphinx
twine
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Pillow==9.3.0
Twisted==22.10.0
zope.interface==5.4.0
pycryptodomex==3.12.0
Pillow>=9.3.0
Twisted>=22.10.0
zope.interface>=5.4.0
pycryptodomex>=3.12.0
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Topic :: Multimedia :: Graphics :: Viewers
Topic :: Software Development :: Testing

Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def test_key_ctrl_a(self) -> None:
self.run_vncdo('key ctrl-a')
self.assertKeyDown(rfb.KEY_ControlLeft)
self.assertKeyDown(ord('a'))
self.assertKeyUp(rfb.KEY_ControlLeft)
self.assertKeyUp(ord('a'))
self.assertKeyUp(rfb.KEY_ControlLeft)

def test_mouse(self) -> None:
self.run_vncdo('move 111 222 click 1')
Expand Down
10 changes: 8 additions & 2 deletions tests/functional/test_send_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def test_key_ctrl_a(self) -> None:
self.run_vncdo('key ctrl-a')
self.assertKeyDown(int(0xffe3))
self.assertKeyDown(ord('a'))
self.assertKeyUp(int(0xffe3))
self.assertKeyUp(ord('a'))
self.assertKeyUp(int(0xffe3))
self.assertDisconnect()

def test_type(self) -> None:
Expand All @@ -65,11 +65,17 @@ def test_type(self) -> None:
self.assertDisconnect()

def test_mouse_move(self) -> None:
# vncev only prints click events, but will include the position
self.run_vncdo('move 10 20 click 1')
self.assertMouse(10, 20, 0x1)
self.assertDisconnect()

def test_mouse_drag(self) -> None:
self.run_vncdo('move 10 20 drag 30 30 click 1')
self.assertMouse(10, 20, 0x0)
self.assertMouse(20, 25, 0x0)
self.assertMouse(30, 30, 0x1)
self.assertDisconnect()

def test_mouse_click_button_two(self) -> None:
self.run_vncdo('click 2')
self.assertMouse(0, 0, 0x2)
Expand Down
Loading

0 comments on commit 317de66

Please sign in to comment.