Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
66f94a7
Initial plan
Copilot Feb 3, 2026
e7e9f3f
chore: address mypy warnings part 1
Copilot Feb 3, 2026
339a37e
refine dtconv gettext setup
Copilot Feb 3, 2026
3a3f7db
defer Callable import in dtconv
Copilot Feb 3, 2026
e52b196
Update translation files
github-actions[bot] Feb 3, 2026
e380428
apply formatting suggested by pre-commit
Copilot Feb 3, 2026
a691d10
Update translation files
github-actions[bot] Feb 3, 2026
df3a010
ci: do not allow mypy to fail anymore
MichaIng Feb 3, 2026
6af1648
Co-authored-by: MichaIng <28480705+MichaIng@users.noreply.github.com>
Copilot Feb 3, 2026
e8ec459
Tighten mypy coverage across utilities and handlers
Copilot Feb 3, 2026
d46da40
Update translation files
github-actions[bot] Feb 3, 2026
dbcfe95
Co-authored-by: MichaIng <28480705+MichaIng@users.noreply.github.com>
Copilot Feb 3, 2026
28b94ae
Tighten mypy compliance by deduplicating codec helpers and fixing han…
Copilot Feb 3, 2026
452d403
fix handler mypy return-value
Copilot Feb 3, 2026
10e4797
cleanup rtsp typing and revert remote error handling
Copilot Feb 3, 2026
ee094cc
handle response.error exceptions cleanly
Copilot Feb 3, 2026
75bacaf
simplify rtsp connect flow with nonlocal stream
Copilot Feb 3, 2026
46c3eeb
remove redundant return in rtsp connect
Copilot Feb 3, 2026
caf4e56
coding: cleanup
MichaIng Feb 3, 2026
71beb1d
close existing rtsp stream before reconnect
Copilot Feb 3, 2026
a803973
coding: solve 2 more mypy annotations
MichaIng Feb 3, 2026
384682c
cast handler_mapping for tornado Application
Copilot Feb 3, 2026
8fcaf18
Update translation files
github-actions[bot] Feb 3, 2026
7d70f91
coding: declare router mapping as sequence in the first place
MichaIng Feb 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- run: python3 -m build
- run: python3 -m pip install .
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive --exclude build/ . || true
- run: mypy --ignore-missing-imports --install-types --non-interactive --exclude build/ .
- run: pytest --ignore=tests/test_utils/test_mjpeg.py
--ignore=tests/test_utils/test_rtmp.py . || true
- run: pytest --fixtures tests/test_utils/test_mjpeg.py || true
Expand Down
2 changes: 1 addition & 1 deletion motioneye/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
]

_main_config_cache = None
_camera_config_cache = {}
_camera_config_cache: dict = {}
_camera_ids_cache = None
_additional_section_funcs = []
_additional_config_funcs = []
Expand Down
5 changes: 3 additions & 2 deletions motioneye/handlers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ def _handle_get_config_response(
# do not add this camera to the list if admin-only, but reduce the async counter so listing can finish
if admin_only and self.current_user != 'admin':
length[0] -= 1
return self.check_finished(cameras, length)
self.check_finished(cameras, length)
return

if not resp.remote_ui_config['enabled'] and local_config['@enabled']:
# if a remote camera is disabled, make sure it's disabled locally as well
Expand All @@ -422,7 +423,7 @@ def _handle_get_config_response(

cameras.append(resp.remote_ui_config)

return self.check_finished(cameras, length)
self.check_finished(cameras, length)

@BaseHandler.auth()
async def list(self):
Expand Down
2 changes: 1 addition & 1 deletion motioneye/locale/motioneye.js.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-03 17:02+0000\n"
"POT-Creation-Date: 2026-02-03 23:54+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down
60 changes: 30 additions & 30 deletions motioneye/locale/motioneye.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-02-03 17:02+0000\n"
"POT-Creation-Date: 2026-02-03 23:54+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -37,67 +37,67 @@ msgstr ""
msgid "URLs are not allowed to contain caret ^, semicolon ;, or apostrophe '"
msgstr ""

#: motioneye/server.py:232
#: motioneye/server.py:233
msgid "interrompa signalo ricevita, fermanta …"
msgstr ""

#: motioneye/server.py:276
#: motioneye/server.py:277
msgid "smb-akcioj postulas radikajn privilegiojn"
msgstr ""

#: motioneye/server.py:283
#: motioneye/server.py:284
msgid "bonvolu instali tornado version 3.1 aŭ pli"
msgstr ""

#: motioneye/server.py:290
#: motioneye/server.py:291
msgid "bonvolu instali jinja2"
msgstr ""

#: motioneye/server.py:297
#: motioneye/server.py:298
msgid "bonvolu instali pillow aŭ PIL"
msgstr ""

#: motioneye/server.py:304
#: motioneye/server.py:305
msgid "bonvolu instali pycurl"
msgstr ""

#: motioneye/server.py:422
#: motioneye/server.py:423
msgid "saluton! ĉi tio estas motionEye-servilo "
msgstr ""

#: motioneye/server.py:437
#: motioneye/server.py:438
msgid "purigado komenciĝis"
msgstr ""

#: motioneye/server.py:439
#: motioneye/server.py:440
msgid "wsswitch komenciĝis"
msgstr ""

#: motioneye/server.py:442
#: motioneye/server.py:443
msgid "taskoj komenciĝis"
msgstr ""

#: motioneye/server.py:446
#: motioneye/server.py:447
msgid "mjpg klienta rubo-kolektanto komenciĝis"
msgstr ""

#: motioneye/server.py:464
#: motioneye/server.py:465
msgid "servilo komenciĝis"
msgstr ""

#: motioneye/server.py:470
#: motioneye/server.py:471
msgid "servilo haltis"
msgstr ""

#: motioneye/server.py:472
#: motioneye/server.py:473
msgid "taskoj haltis"
msgstr ""

#: motioneye/server.py:480
#: motioneye/server.py:481
msgid "motion haltis"
msgstr ""

#: motioneye/server.py:485
#: motioneye/server.py:486
msgid "adiaŭ!"
msgstr ""

Expand Down Expand Up @@ -920,7 +920,7 @@ msgstr ""

#: motioneye/templates/main.html:780 motioneye/templates/main.html:893
#: motioneye/templates/main.html:968 motioneye/templates/main.html:1097
#: motioneye/utils/dtconv.py:146 motioneye/utils/dtconv.py:149
#: motioneye/utils/dtconv.py:154 motioneye/utils/dtconv.py:157
msgid "sekundoj"
msgstr ""

Expand Down Expand Up @@ -1048,7 +1048,7 @@ msgstr ""
msgid "Filmoj Vivdaŭro"
msgstr ""

#: motioneye/templates/main.html:912 motioneye/utils/dtconv.py:125
#: motioneye/templates/main.html:912 motioneye/utils/dtconv.py:133
msgid "tagoj"
msgstr ""

Expand Down Expand Up @@ -1509,46 +1509,46 @@ msgstr ""
msgid "Difinas, ĉu moviĝodetekto devas esti aktiva dum aŭ ekster la laborista horaro."
msgstr ""

#: motioneye/utils/dtconv.py:26 motioneye/utils/dtconv.py:65
#: motioneye/utils/dtconv.py:34 motioneye/utils/dtconv.py:73
msgid "neniam"
msgstr ""

#: motioneye/utils/dtconv.py:113
#: motioneye/utils/dtconv.py:121
msgid "tago"
msgstr ""

#: motioneye/utils/dtconv.py:116
#: motioneye/utils/dtconv.py:124
msgid "semajno"
msgstr ""

#: motioneye/utils/dtconv.py:119
#: motioneye/utils/dtconv.py:127
msgid "monato"
msgstr ""

#: motioneye/utils/dtconv.py:122
#: motioneye/utils/dtconv.py:130
msgid "jaro"
msgstr ""

#: motioneye/utils/dtconv.py:129
#: motioneye/utils/dtconv.py:137
msgid "horo"
msgstr ""

#: motioneye/utils/dtconv.py:132
#: motioneye/utils/dtconv.py:140
msgid "horoj"
msgstr ""

#: motioneye/utils/dtconv.py:136
#: motioneye/utils/dtconv.py:144
msgid "minuto"
msgstr ""

#: motioneye/utils/dtconv.py:139
#: motioneye/utils/dtconv.py:147
msgid "minutoj"
msgstr ""

#: motioneye/utils/dtconv.py:143
#: motioneye/utils/dtconv.py:151
msgid "sekundo"
msgstr ""

#: motioneye/utils/dtconv.py:153
#: motioneye/utils/dtconv.py:161
msgid "minus"
msgstr ""
20 changes: 14 additions & 6 deletions motioneye/mediafiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
}

# a cache of prepared files (whose preparing time is significant)
_prepared_files = {}
_prepared_files: dict = {}

_timelapse_process = None
_timelapse_data = None
Expand All @@ -105,7 +105,10 @@


def _list_media_files(
base_path: str, exts: typing.List[str], sub_path: str = None, with_stat: bool = True
base_path: str,
exts: typing.List[str],
sub_path: str | None = None,
with_stat: bool = True,
) -> typing.List[tuple]:
# Determine scan path based on sub_path parameter
if sub_path is not None:
Expand Down Expand Up @@ -416,7 +419,9 @@ def cleanup_media(media_type: str) -> None:
logging.debug(
f'calling _remove_older_files: {cloud_enabled} {clean_cloud_enabled} {clean_cloud_info}'
)
_remove_older_files(target_dir, preserve_moment, clean_cloud_info, exts=exts)
_remove_older_files(
target_dir, preserve_moment, clean_cloud_info or {}, exts=exts
)


def make_movie_preview(camera_config: dict, full_path: str) -> typing.Union[str, None]:
Expand Down Expand Up @@ -489,9 +494,12 @@ def make_movie_preview(camera_config: dict, full_path: str) -> typing.Union[str,


def list_media(
camera_config: dict, media_type: str, prefix=None, with_stat: bool = True
camera_config: dict,
media_type: str,
prefix: str | None = None,
with_stat: bool = True,
) -> typing.Awaitable:
fut = Future()
fut: Future = Future()
target_dir = camera_config.get('target_dir')

if media_type == 'picture':
Expand Down Expand Up @@ -576,7 +584,7 @@ def get_media_content(camera_config, path, media_type):
def get_zipped_content(
camera_config: dict, media_type: str, group: str
) -> typing.Awaitable:
fut = Future()
fut: Future = Future()
target_dir = camera_config.get('target_dir')

if media_type == 'picture':
Expand Down
4 changes: 2 additions & 2 deletions motioneye/mjpgclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
class MjpgClient(IOStream):
_FPS_LEN = 10

clients = {} # dictionary of clients indexed by camera id
clients: dict = {} # dictionary of clients indexed by camera id
_last_erroneous_close_time = (
0 # helps detecting erroneous connections and restart motion
)
Expand Down Expand Up @@ -186,7 +186,7 @@ def _on_connect(self, future: Future) -> None:

self._seek_http()

def _seek_http(self, future: Future = False) -> None:
def _seek_http(self, future: Future | None = None) -> None:
result, _ = self._get_future_result(future) if future else (True, False)

if not result or self._check_error():
Expand Down
6 changes: 3 additions & 3 deletions motioneye/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@

DEFAULT_INTERVAL = 1 # seconds

_monitor_info_cache_by_camera_id = {}
_last_call_time_by_camera_id = {}
_interval_by_camera_id = {}
_monitor_info_cache_by_camera_id: dict = {}
_last_call_time_by_camera_id: dict = {}
_interval_by_camera_id: dict = {}


def get_monitor_info(camera_id):
Expand Down
Loading
Loading