fohrloop / wakepy

Cross-platform keep-awake with python
MIT License
189 stars 13 forks source link

Add support for BSD systems #359

Closed fohrloop closed 1 week ago

fohrloop commented 3 months ago

Currently (v0.9.1), wakepy checks if platform.system() returns "Linux". All wakepy.Methods have to advertise which system they support.

Task:

fohrloop commented 3 months ago

I'm just about to install GhostBSD 24.04.1 and try to make wakepy work on it.

fohrloop commented 3 months ago

This is what wakepy 0.9.1 gives on GhostBSD:

(venv) fohrloop@fohrloop-ghostbsd ~/c/wakepy (main)> wakepy
/home/fohrloop/code/wakepy/venv/lib/python3.9/site-packages/wakepy/core/platform.py:17: UserWarning: Could not detect current platform! platform.system() returned FreeBSD
  warnings.warn(
                  _
                 | |
 __      __ __ _ | | __ ___  _ __   _   _
 \ \ /\ / // _` || |/ // _ \| '_ \ | | | |
  \ V  V /| (_| ||   <|  __/| |_) || |_| |
   \_/\_/  \__,_||_|\_\\___|| .__/  \__, |
  v.0.9.1                   | |      __/ |
                            |_|     |___/ 
 [x] System will continue running programs
 [ ] Presentation mode is on

    Wakepy could not activate the "keep.running" mode. This might occur because
of a bug or because your current platform is not yet supported or your system is
missing required software.

    Check if there is already a related issue in the issue tracker at
https://github.com/fohrloop/wakepy/issues/ and if not, please create a new one.

    Include the following:
    - wakepy version: 0.9.1
    - Mode: keep.running
    - Python version: 3.9.18 (main, Apr 27 2024, 17:22:44)
[Clang 17.0.6 (https://github.com/llvm/llvm-project.git llvmorg-17.0.6-0-g60097
    - Operating system & version: [PLEASE FILL THIS]
    - Desktop Environment & version (if not default): [FILL OR REMOVE THIS LINE]
    - Additional details: [FILL OR REMOVE THIS LINE]

    Thank you!
fohrloop commented 3 months ago

This is what you can see in GhostBSD 24.04.1, CPython 3.9.18:

>>> os.name
'posix'
>>> sys.platform
'freebsd14'
>>> platform.system()
'FreeBSD'
>>> sysconfig.get_platform()
'freebsd-14.0-STABLE-amd64'

How wakepy works currently

class SomeMethod(Method):
    supported_platforms = (PlatformName.LINUX,)

How wakepy could work in the future

Proposed solution (option A)

With the proposed solution, every wakepy method is tried on each unknown ("OTHER") platform, which is better than failing without trying any methods.

Proposed solution (option B)

Proposed solution (option C)

Here UNIX would be a special platform, which currently would say:

>>> LINUX in PlatformSupport(UNIX)
True
>>> WINDOWS in PlatformSupport(UNIX)
False
>>> OTHER in PlatformSupport(UNIX) # freebsd for example
None

but when UNIX is updated, it would be union of LINUX and BSD, and BSD would be union of all known BSDs, like FREEBSD, OPENBSD.

This way the Methods definitions would hardly ever require update. For example the method for Gnome could be PlatformSupport(UNIX, unsupported=MACOS), and then just the definition of UNIX would be updated in the future.

fohrloop commented 2 weeks ago

I have been thinking this now for a while, and I think that the Method.supported_platforms may go. The main motivation behind keeping supported_platforms would be the ability to automatically gather lists of Methods for certain platforms for documentation. But there are also downsides:

  1. The platforms are many, and it's hard to list them all. One possible list could be CYGWIN, WSL, JUPYTER_NOTEBOOK, ANDROID, FREEBSD, OPENBSD, NETBSD, LINUX, MACOS, WINDOWS10, WINDOWS11, OTHER. When defining Methods, one probably would like to use shortcuts like BSD (=FREEBSD | OPENBSD | NETBSD) or UNIX_LIKE (=LINUX | BSD | MACOS | ANDROID?), and managing this all is not easy. One should also implement different types of operations for these (union, difference, is_in checks, etc.).
  2. Wakepy does not really much care about the "platform", but what it cares is which executables or d-bus APIs available and what the desktop environment is, if there is such. Investing a lot to the platform detection logic does not make sense in wakepy at least in this stage (possible that this changes still in the future). Some individual Methods might care a bit about the platform, though.
  3. The automatic documentation part is as easy also with a collection of lists, where each list has supported Methods for a platform. For example, there could be a WINDOWS list, UNIX_LIKE (Linux+BSD?) list, etc. And this would be probably approximately as easy to keep in sync as would be the list of supported platforms on each Method class.

What to use instead of Method.supported_platforms?

Perhaps the best would be that each subclass of Method would check the platform compatibility in the Method.caniuse() if that's really required. There can be some helper functions like platform_is_windows() or platform_is_wsl(), etc. to help there. There could be a new PlatformUnsupportedException for communication of platform check specific failure in the caniuse phase.

This way..

  1. When support for new platform is added to wakepy, one does not have to go through all the Methods and update some "supported platforms" or "unsupported platforms" list. You would only have to edit the caniuse() the specific Method.
  2. There is really just one check for "can I use", and that is in the caniuse() method. This call could also check the used desktop environment, and not just the used OS.

I'll create another ticket for moving the platform check process to be part of the caniuse() check.

fohrloop commented 1 week ago

I tried some BSD systems on instantworkstation.com for getting the platform information in python. I was only successful on OpenBSD 7.4:

Could not install python (or anything) on NetBSD/DragonflyBSD and did not have time to debug it.

fohrloop commented 1 week ago

Playing around with wakepy on FreeBSD 14.1 + GNOME 42.5