Compare commits

...

4 Commits

Author SHA1 Message Date
Mario Fetka 502885fd23 update compat 2023-07-01 11:55:09 +02:00
Mario Fetka 8a6603ece7 Imported Upstream version 3.1.0 2023-07-01 11:54:39 +02:00
Mario Fetka 9f2d889ce3 Imported Upstream version 3.0.0 2021-10-27 08:42:58 +02:00
Mario Fetka 7401b914a4 Imported Upstream version 3.0.0 2021-10-27 08:42:14 +02:00
17 changed files with 193 additions and 43 deletions

57
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: CI
on:
pull_request: {}
push: {}
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e lint
check-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e check-docs
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
experimental: [false]
include:
- python-version: "3.12-dev"
experimental: true
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip setuptools
python3 -m pip install tox tox-gh-actions
- run: tox

View File

@ -9,7 +9,7 @@ lint:
.PHONY: test .PHONY: test
test: test:
coverage run -m py.test coverage run -m pytest
coverage report coverage report
.PHONY: clean .PHONY: clean
@ -49,15 +49,11 @@ check-docs:
deb-local: clean sdist deb-local: clean sdist
docker build -t afancontrol-debuild -f ./Dockerfile.debian . docker build -t afancontrol-debuild -f ./Dockerfile.debian .
docker run -it --rm \ docker run -it --rm \
-e DEBFULLNAME="`git config --global user.name`" \
-e DEBEMAIL="`git config --global user.email`" \
-v `pwd`/dist:/afancontrol/dist \ -v `pwd`/dist:/afancontrol/dist \
-v `pwd`/debian:/afancontrol/debian \ -v `pwd`/debian:/afancontrol/debian \
afancontrol-debuild sh -ex -c '\ afancontrol-debuild sh -ex -c '\
tar xaf /afancontrol/dist/afancontrol-*.tar.gz --strip 1; \ tar xaf /afancontrol/dist/afancontrol-*.tar.gz --strip 1; \
dch -v `python3 setup.py --version` -b --distribution=unstable; \
debuild -us -uc -b; \ debuild -us -uc -b; \
cp debian/changelog /afancontrol/debian/; \
cd ../; \ cd ../; \
ls -alh; \ ls -alh; \
mkdir /afancontrol/dist/debian; \ mkdir /afancontrol/dist/debian; \

View File

@ -5,8 +5,8 @@ afancontrol
:target: https://pypi.python.org/pypi/afancontrol/ :target: https://pypi.python.org/pypi/afancontrol/
:alt: Latest Version :alt: Latest Version
.. image:: https://img.shields.io/travis/KostyaEsmukov/afancontrol.svg?style=flat-square .. image:: https://img.shields.io/github/workflow/status/KostyaEsmukov/afancontrol/CI?style=flat-square
:target: https://travis-ci.org/KostyaEsmukov/afancontrol :target: https://github.com/KostyaEsmukov/afancontrol/actions
:alt: Build Status :alt: Build Status
.. image:: https://img.shields.io/github/license/KostyaEsmukov/afancontrol.svg?style=flat-square .. image:: https://img.shields.io/github/license/KostyaEsmukov/afancontrol.svg?style=flat-square

19
debian/changelog vendored
View File

@ -1,3 +1,22 @@
<<<<<<< HEAD
=======
afancontrol (3.1.0-1) unstable; urgency=medium
[ Juha Yrjölä ]
* Support glob expansion with fans (#9)
[ Kostya Esmukov ]
* Drop Python 3.6 support, add 3.11
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 28 Nov 2022 00:11:43 +0200
afancontrol (3.0.0-2) unstable; urgency=medium
* Bump debhelper compat to 13
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 02 Aug 2021 19:19:34 +0000
>>>>>>> upstream/3.1.0
afancontrol (3.0.0-1) unstable; urgency=medium afancontrol (3.0.0-1) unstable; urgency=medium
* Drop support for prometheus-client < 0.1.0 (debian stretch) * Drop support for prometheus-client < 0.1.0 (debian stretch)

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

28
debian/control vendored
View File

@ -2,37 +2,43 @@ Source: afancontrol
Section: utils Section: utils
Priority: optional Priority: optional
Maintainer: Kostya Esmukov <kostya@esmukov.ru> Maintainer: Kostya Esmukov <kostya@esmukov.ru>
Build-Depends: debhelper (>= 9), Build-Depends: debhelper-compat (= 13),
dh-python, dh-python,
debhelper (>= 9.20160709) | dh-systemd, debhelper (>= 9.20160709) | dh-systemd,
python3-all, python3-all,
python3-click,
python3-prometheus-client (>= 0.1.0),
python3-pytest,
python3-requests,
python3-serial,
python3-setuptools python3-setuptools
<<<<<<< HEAD
Build-Depends-Indep: python3-pytest, Build-Depends-Indep: python3-pytest,
python3-requests, python3-requests,
python3-click, python3-click,
python3-prometheus-client (>= 0.1.0), python3-prometheus-client (>= 0.1.0),
python3-serial python3-serial
=======
>>>>>>> upstream/3.1.0
Standards-Version: 3.9.8 Standards-Version: 3.9.8
Homepage: https://github.com/KostyaEsmukov/afancontrol Homepage: https://github.com/KostyaEsmukov/afancontrol
X-Python3-Version: >= 3.5
#Vcs-Git: https://anonscm.debian.org/git/python-modules/packages/python3-afancontrol.git
#Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/python3-afancontrol.git/
#Testsuite: autopkgtest-pkg-python
Package: afancontrol Package: afancontrol
Architecture: all Architecture: all
Depends: ${python3:Depends}, Depends: hddtemp,
${misc:Depends},
hddtemp,
lm-sensors, lm-sensors,
python3-click, python3-click,
python3-pkg-resources, python3-pkg-resources,
python3-prometheus-client (>= 0.1.0), python3-prometheus-client (>= 0.1.0),
<<<<<<< HEAD
python3-serial python3-serial
Suggests: freeipmi-tools, Suggests: freeipmi-tools,
=======
python3-serial,
${misc:Depends},
${python3:Depends}
Suggests: freeipmi-tools
>>>>>>> upstream/3.1.0
Description: Advanced Fan Control program (Python 3) Description: Advanced Fan Control program (Python 3)
afancontrol is an Advanced Fan Control program, which controls PWM afancontrol is an Advanced Fan Control program, which controls PWM
fans according to the current temperatures of the system components. fans according to the current temperatures of the system components.
.
This package installs the library for Python 3.

0
debian/rules vendored Normal file → Executable file
View File

View File

@ -25,13 +25,16 @@ per-file-ignores =
src/afancontrol/config.py:C901 src/afancontrol/config.py:C901
[isort] [isort]
; https://github.com/timothycrosley/isort#multi-line-output-modes
multi_line_output = 3 multi_line_output = 3
<<<<<<< HEAD
; https://github.com/ambv/black#how-black-wraps-lines ; https://github.com/ambv/black#how-black-wraps-lines
include_trailing_comma = True include_trailing_comma = True
force_grid_wrap = 0 force_grid_wrap = 0
combine_as_imports = True combine_as_imports = True
line_length = 88 line_length = 88
=======
profile = black
>>>>>>> upstream/3.1.0
[metadata] [metadata]
author = Kostya Esmukov author = Kostya Esmukov
@ -45,10 +48,13 @@ classifier =
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
<<<<<<< HEAD
Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
=======
>>>>>>> upstream/3.1.0
Topic :: System :: Hardware Topic :: System :: Hardware
Topic :: System :: Monitoring Topic :: System :: Monitoring
Topic :: System :: Systems Administration Topic :: System :: Systems Administration
@ -76,7 +82,11 @@ install_requires =
package_dir = package_dir =
= src = src
packages = find: packages = find:
<<<<<<< HEAD
python_requires = >=3.6 python_requires = >=3.6
=======
python_requires = >=3.7
>>>>>>> upstream/3.1.0
[options.entry_points] [options.entry_points]
console_scripts = console_scripts =
@ -88,6 +98,7 @@ arduino =
metrics = metrics =
prometheus-client>=0.1.0 prometheus-client>=0.1.0
dev = dev =
<<<<<<< HEAD
black==20.8b1 black==20.8b1
coverage==5.3 coverage==5.3
flake8==3.8.4 flake8==3.8.4
@ -97,6 +108,18 @@ dev =
requests requests
sphinx==3.2.1 sphinx==3.2.1
wheel wheel
=======
black==22.10.0
coverage==6.5.0
flake8==5.0.4
isort==5.10.1
mypy==0.990
pytest==7.2.0
sphinx==4.3.2
vcrpy==4.2.1
requests
types-requests
>>>>>>> upstream/3.1.0
[options.packages.find] [options.packages.find]
where = src where = src

View File

@ -1 +1,5 @@
<<<<<<< HEAD
__version__ = "3.0.0" __version__ = "3.0.0"
=======
__version__ = "3.1.0"
>>>>>>> upstream/3.1.0

View File

@ -1,4 +1,8 @@
import configparser import configparser
<<<<<<< HEAD
=======
import glob
>>>>>>> upstream/3.1.0
from typing import Any, Generic, Iterator, Optional, Type, TypeVar, Union, overload from typing import Any, Generic, Iterator, Optional, Type, TypeVar, Union, overload
T = TypeVar("T", bound=str) T = TypeVar("T", bound=str)
@ -127,3 +131,15 @@ class ConfigParserSection(Generic[T]):
"[%s] %r option is expected to be set" % (self.__section.name, option) "[%s] %r option is expected to be set" % (self.__section.name, option)
) )
return res return res
<<<<<<< HEAD
=======
def expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))
>>>>>>> upstream/3.1.0

View File

@ -187,7 +187,8 @@ def fantest(
elif fan_type == "arduino": elif fan_type == "arduino":
if not arduino_serial_url: if not arduino_serial_url:
arduino_serial_url = click.prompt( arduino_serial_url = click.prompt(
"\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL, type=str "\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL,
type=str, # type: ignore
) )
# typeshed currently specifies `Optional[str]` for `default`, # typeshed currently specifies `Optional[str]` for `default`,
@ -197,17 +198,19 @@ def fantest(
# Hence the `type: ignore`. # Hence the `type: ignore`.
arduino_baudrate = click.prompt( # type: ignore arduino_baudrate = click.prompt( # type: ignore
"\n%s\nBaudrate" % HELP_ARDUINO_BAUDRATE, "\n%s\nBaudrate" % HELP_ARDUINO_BAUDRATE,
type=int, type=int, # type: ignore
default=str(arduino_baudrate), default=str(arduino_baudrate),
show_default=True, show_default=True,
) )
if not arduino_pwm_pin and arduino_pwm_pin != 0: if not arduino_pwm_pin and arduino_pwm_pin != 0:
arduino_pwm_pin = click.prompt( arduino_pwm_pin = click.prompt(
"\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN, type=int "\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN,
type=int, # type: ignore
) )
if not arduino_tacho_pin and arduino_tacho_pin != 0: if not arduino_tacho_pin and arduino_tacho_pin != 0:
arduino_tacho_pin = click.prompt( arduino_tacho_pin = click.prompt(
"\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN, type=int "\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN,
type=int, # type: ignore
) )
assert arduino_serial_url is not None assert arduino_serial_url is not None

View File

@ -1,11 +1,13 @@
import abc import abc
from typing import NewType, Type from typing import NewType, Tuple, Type
PWMValue = NewType("PWMValue", int) # [0..255] PWMValue = NewType("PWMValue", int) # [0..255]
FanValue = NewType("FanValue", int) FanValue = NewType("FanValue", int)
class _SlotsReprMixin: class _SlotsReprMixin:
__slots__: Tuple[str, ...]
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, type(self)): if isinstance(other, type(self)):
for attr in self.__slots__: for attr in self.__slots__:

View File

@ -1,7 +1,11 @@
from pathlib import Path from pathlib import Path
from typing import NewType from typing import NewType
<<<<<<< HEAD
from afancontrol.configparser import ConfigParserSection from afancontrol.configparser import ConfigParserSection
=======
from afancontrol.configparser import ConfigParserSection, expand_glob
>>>>>>> upstream/3.1.0
from afancontrol.pwmfan.base import ( from afancontrol.pwmfan.base import (
BaseFanPWMRead, BaseFanPWMRead,
BaseFanPWMWrite, BaseFanPWMWrite,
@ -18,7 +22,11 @@ class LinuxFanSpeed(BaseFanSpeed):
__slots__ = ("_fan_input",) __slots__ = ("_fan_input",)
def __init__(self, fan_input: FanInputDevice) -> None: def __init__(self, fan_input: FanInputDevice) -> None:
self._fan_input = Path(fan_input) self._fan_input = Path(expand_glob(fan_input))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanSpeed:
return cls(FanInputDevice(section["fan_input"]))
@classmethod @classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanSpeed: def from_configparser(cls, section: ConfigParserSection) -> BaseFanSpeed:
@ -35,7 +43,11 @@ class LinuxFanPWMRead(BaseFanPWMRead):
min_pwm = PWMValue(0) min_pwm = PWMValue(0)
def __init__(self, pwm: PWMDevice) -> None: def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm) self._pwm = Path(expand_glob(pwm))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMRead:
return cls(PWMDevice(section["pwm"]))
@classmethod @classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMRead: def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMRead:
@ -51,8 +63,13 @@ class LinuxFanPWMWrite(BaseFanPWMWrite):
read_cls = LinuxFanPWMRead read_cls = LinuxFanPWMRead
def __init__(self, pwm: PWMDevice) -> None: def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm) base = expand_glob(pwm)
self._pwm_enable = Path(pwm + "_enable") self._pwm = Path(base)
self._pwm_enable = Path(base + "_enable")
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMWrite:
return cls(PWMDevice(section["pwm"]))
@classmethod @classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMWrite: def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMWrite:

View File

@ -1,21 +1,15 @@
import glob
import re import re
from pathlib import Path from pathlib import Path
from typing import Optional, Tuple from typing import Optional, Tuple
<<<<<<< HEAD
from afancontrol.configparser import ConfigParserSection from afancontrol.configparser import ConfigParserSection
=======
from afancontrol.configparser import ConfigParserSection, expand_glob
>>>>>>> upstream/3.1.0
from afancontrol.temp.base import Temp, TempCelsius from afancontrol.temp.base import Temp, TempCelsius
def _expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))
class FileTemp(Temp): class FileTemp(Temp):
def __init__( def __init__(
self, self,
@ -33,7 +27,7 @@ class FileTemp(Temp):
# /sys/devices/pci0000:00/0000:00:01.3/[...]/hwmon/hwmon*/temp1_input # /sys/devices/pci0000:00/0000:00:01.3/[...]/hwmon/hwmon*/temp1_input
# The `hwmon*` might change after reboot, but it is always a single # The `hwmon*` might change after reboot, but it is always a single
# directory within the device. # directory within the device.
temp_path = _expand_glob(temp_path + "_input") temp_path = expand_glob(temp_path + "_input")
temp_path = re.sub(r"_input$", "", temp_path) temp_path = re.sub(r"_input$", "", temp_path)
self._temp_input = Path(temp_path + "_input") self._temp_input = Path(temp_path + "_input")

View File

@ -6,7 +6,8 @@ import pytest
from click.testing import CliRunner from click.testing import CliRunner
from afancontrol import daemon from afancontrol import daemon
from afancontrol.daemon import PidFile, Signals, daemon as main from afancontrol.daemon import PidFile, Signals
from afancontrol.daemon import daemon as main
def test_main_smoke(temp_path): def test_main_smoke(temp_path):

View File

@ -10,9 +10,9 @@ from afancontrol.fantest import (
CSVMeasurementsOutput, CSVMeasurementsOutput,
HumanMeasurementsOutput, HumanMeasurementsOutput,
MeasurementsOutput, MeasurementsOutput,
fantest as main,
run_fantest,
) )
from afancontrol.fantest import fantest as main
from afancontrol.fantest import run_fantest
from afancontrol.pwmfan import ( from afancontrol.pwmfan import (
BaseFanPWMRead, BaseFanPWMRead,
BaseFanPWMWrite, BaseFanPWMWrite,

13
tox.ini
View File

@ -1,5 +1,9 @@
[tox] [tox]
<<<<<<< HEAD
envlist=py{36,37,38,39,310}{,-arduino,-metrics},lint,check-docs envlist=py{36,37,38,39,310}{,-arduino,-metrics},lint,check-docs
=======
envlist=py{37,38,39,310,311,312}{,-arduino,-metrics},lint,check-docs
>>>>>>> upstream/3.1.0
[testenv] [testenv]
extras = extras =
@ -12,6 +16,15 @@ commands = make test
; sources to the working dir by default. ; sources to the working dir by default.
usedevelop = True usedevelop = True
[gh-actions]
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
[testenv:lint] [testenv:lint]
extras = extras =
arduino arduino