From f29e139cbb7e4a4d539cba6e894ef4a6acd312d6 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Wed, 31 May 2023 09:22:00 +0300 Subject: WIP: big refactoring --- test/mqtt_relay_server_util.py | 17 ++++++++++++++++ test/mqtt_relay_util.py | 38 ++++++++++++++++++++++++++++++++++++ test/test_amixer.py | 2 +- test/test_api.py | 2 +- test/test_esp32_cam.py | 6 +++--- test/test_inverter_monitor.py | 2 +- test/test_ipcam_server_cleanup.py | 2 +- test/test_record_upload.py | 6 +++--- test/test_send_fake_sound_hit.py | 4 ++-- test/test_sound_server_api.py | 2 +- test/test_telegram_aio_send_photo.py | 2 +- 11 files changed, 69 insertions(+), 14 deletions(-) create mode 100755 test/mqtt_relay_server_util.py create mode 100755 test/mqtt_relay_util.py (limited to 'test') diff --git a/test/mqtt_relay_server_util.py b/test/mqtt_relay_server_util.py new file mode 100755 index 0000000..ac6a9ae --- /dev/null +++ b/test/mqtt_relay_server_util.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +import sys +import os.path +sys.path.extend([ + os.path.realpath( + os.path.join(os.path.dirname(os.path.join(__file__)), '..') + ) +]) + +from src.home.config import config +from src.home.mqtt.relay import MQTTRelayClient + + +if __name__ == '__main__': + config.load_app('test_mqtt_relay_server') + relay = MQTTRelayClient('test') + relay.connect_and_loop() diff --git a/test/mqtt_relay_util.py b/test/mqtt_relay_util.py new file mode 100755 index 0000000..0d8c764 --- /dev/null +++ b/test/mqtt_relay_util.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import sys +import os.path +sys.path.extend([ + os.path.realpath( + os.path.join(os.path.dirname(os.path.join(__file__)), '..') + ) +]) + +from argparse import ArgumentParser +from src.home.config import config +from src.home.mqtt.relay import MQTTRelayController + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--on', action='store_true') + parser.add_argument('--off', action='store_true') + parser.add_argument('--stat', action='store_true') + + config.load_app('test_mqtt_relay', parser=parser) + arg = parser.parse_args() + + relay = MQTTRelayController('test') + relay.connect_and_loop(loop_forever=False) + + if arg.on: + relay.set_power(True) + + elif arg.off: + relay.set_power(False) + + elif arg.stat: + relay.send_stat(dict( + state=False, + signal=-59, + fw_v=1.0 + )) \ No newline at end of file diff --git a/test/test_amixer.py b/test/test_amixer.py index c8bd546..464941e 100755 --- a/test/test_amixer.py +++ b/test/test_amixer.py @@ -28,7 +28,7 @@ if __name__ == '__main__': parser.add_argument('--decr', type=str) # parser.add_argument('--dump-config', action='store_true') - args = config.load('test_amixer', parser=parser) + args = config.load_app('test_amixer', parser=parser) # if args.dump_config: # print(config.data) diff --git a/test/test_api.py b/test/test_api.py index 1f6361c..e80eb4c 100755 --- a/test/test_api.py +++ b/test/test_api.py @@ -13,7 +13,7 @@ from src.home.config import config if __name__ == '__main__': - config.load('test_api') + config.load_app('test_api') api = WebAPIClient() print(api.log_bot_request(BotType.ADMIN, 1, "test_api.py")) diff --git a/test/test_esp32_cam.py b/test/test_esp32_cam.py index 27ce379..6a4ad25 100755 --- a/test/test_esp32_cam.py +++ b/test/test_esp32_cam.py @@ -10,7 +10,7 @@ sys.path.extend([ from pprint import pprint from argparse import ArgumentParser from time import sleep -from src.home.util import parse_addr +from src.home.util import Addr from src.home.camera import esp32 from src.home.config import config @@ -21,8 +21,8 @@ if __name__ == '__main__': parser.add_argument('--status', action='store_true', help='print status and exit') - arg = config.load(False, parser=parser) - cam = esp32.WebClient(addr=parse_addr(arg.addr)) + arg = config.load_app(False, parser=parser) + cam = esp32.WebClient(addr=Addr.fromstring(arg.addr)) if arg.status: status = cam.getstatus() diff --git a/test/test_inverter_monitor.py b/test/test_inverter_monitor.py index 3b1c6b0..621c0e9 100755 --- a/test/test_inverter_monitor.py +++ b/test/test_inverter_monitor.py @@ -372,5 +372,5 @@ def main(): if __name__ == '__main__': - config.load('test_inverter_monitor') + config.load_app('test_inverter_monitor') main() diff --git a/test/test_ipcam_server_cleanup.py b/test/test_ipcam_server_cleanup.py index b7eb23a..5f313a4 100644 --- a/test/test_ipcam_server_cleanup.py +++ b/test/test_ipcam_server_cleanup.py @@ -77,5 +77,5 @@ def cleanup_job(): if __name__ == '__main__': - config.load('ipcam_server') + config.load_app('ipcam_server') cleanup_job() diff --git a/test/test_record_upload.py b/test/test_record_upload.py index cbd3ca2..835504f 100755 --- a/test/test_record_upload.py +++ b/test/test_record_upload.py @@ -13,7 +13,7 @@ import time from src.home.api import WebAPIClient, RequestParams from src.home.config import config from src.home.media import SoundRecordClient -from src.home.util import parse_addr +from src.home.util import Addr logger = logging.getLogger(__name__) @@ -64,11 +64,11 @@ def api_success_handler(response, name, req: RequestParams): if __name__ == '__main__': - config.load('test_record_upload') + config.load_app('test_record_upload') nodes = {} for name, addr in config['nodes'].items(): - nodes[name] = parse_addr(addr) + nodes[name] = Addr(addr) record = SoundRecordClient(nodes, error_handler=record_error, finished_handler=record_finished, diff --git a/test/test_send_fake_sound_hit.py b/test/test_send_fake_sound_hit.py index 9660c45..61886cd 100755 --- a/test/test_send_fake_sound_hit.py +++ b/test/test_send_fake_sound_hit.py @@ -8,7 +8,7 @@ sys.path.extend([ ]) from argparse import ArgumentParser -from src.home.util import send_datagram, stringify, parse_addr +from src.home.util import send_datagram, stringify, Addr if __name__ == '__main__': @@ -22,4 +22,4 @@ if __name__ == '__main__': args = parser.parse_args() - send_datagram(stringify([args.name, args.hits]), parse_addr(args.server)) + send_datagram(stringify([args.name, args.hits]), Addr.fromstring(args.server)) diff --git a/test/test_sound_server_api.py b/test/test_sound_server_api.py index e68c6f8..5295a5d 100755 --- a/test/test_sound_server_api.py +++ b/test/test_sound_server_api.py @@ -56,7 +56,7 @@ def hits_sender(): if __name__ == '__main__': - config.load('test_api') + config.load_app('test_api') hc = HitCounter() api = WebAPIClient() diff --git a/test/test_telegram_aio_send_photo.py b/test/test_telegram_aio_send_photo.py index 705e534..4d05c03 100644 --- a/test/test_telegram_aio_send_photo.py +++ b/test/test_telegram_aio_send_photo.py @@ -20,7 +20,7 @@ async def main(): if __name__ == '__main__': - config.load('test_telegram_aio_send_photo') + config.load_app('test_telegram_aio_send_photo') loop = asyncio.get_event_loop() asyncio.ensure_future(main()) -- cgit v1.2.3 From 3790c2205396cf860738f297e6ddc49cd2b2a03f Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sat, 10 Jun 2023 22:29:24 +0300 Subject: new config: port openwrt_logger and webapiclient --- test/test_api.py | 4 ++-- test/test_record_upload.py | 4 ++-- test/test_sound_server_api.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/test_api.py b/test/test_api.py index e80eb4c..ecf8764 100755 --- a/test/test_api.py +++ b/test/test_api.py @@ -7,7 +7,7 @@ sys.path.extend([ ) ]) -from src.home.api import WebAPIClient +from src.home.api import WebApiClient from src.home.api.types import BotType from src.home.config import config @@ -15,5 +15,5 @@ from src.home.config import config if __name__ == '__main__': config.load_app('test_api') - api = WebAPIClient() + api = WebApiClient() print(api.log_bot_request(BotType.ADMIN, 1, "test_api.py")) diff --git a/test/test_record_upload.py b/test/test_record_upload.py index 835504f..c0daceb 100755 --- a/test/test_record_upload.py +++ b/test/test_record_upload.py @@ -10,7 +10,7 @@ sys.path.extend([ import time -from src.home.api import WebAPIClient, RequestParams +from src.home.api import WebApiClient, RequestParams from src.home.config import config from src.home.media import SoundRecordClient from src.home.util import Addr @@ -74,7 +74,7 @@ if __name__ == '__main__': finished_handler=record_finished, download_on_finish=True) - api = WebAPIClient() + api = WebApiClient() api.enable_async(error_handler=api_error_handler, success_handler=api_success_handler) diff --git a/test/test_sound_server_api.py b/test/test_sound_server_api.py index 5295a5d..77fe1ba 100755 --- a/test/test_sound_server_api.py +++ b/test/test_sound_server_api.py @@ -10,7 +10,7 @@ import threading from time import sleep from src.home.config import config -from src.home.api import WebAPIClient +from src.home.api import WebApiClient from src.home.api.types import SoundSensorLocation from typing import List, Tuple @@ -59,7 +59,7 @@ if __name__ == '__main__': config.load_app('test_api') hc = HitCounter() - api = WebAPIClient() + api = WebApiClient() hc.add('spb1', 1) # hc.add('big_house', 123) -- cgit v1.2.3 From b0bf43e6a272d42a55158e657bd937cb82fc3d8d Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sat, 10 Jun 2023 23:02:34 +0300 Subject: move files, rename home package to homekit --- test/__init__.py | 0 test/test.py | 2 +- test/test_stopwatch.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 test/__init__.py (limited to 'test') diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/test.py b/test/test.py index 7ea37e6..413c25c 100755 --- a/test/test.py +++ b/test/test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from home.relay import RelayClient +from homekit.relay import RelayClient if __name__ == '__main__': diff --git a/test/test_stopwatch.py b/test/test_stopwatch.py index 6ff2c0e..9dd7762 100755 --- a/test/test_stopwatch.py +++ b/test/test_stopwatch.py @@ -1,4 +1,4 @@ -from home.util import Stopwatch, StopwatchError +from homekit.util import Stopwatch, StopwatchError from time import sleep -- cgit v1.2.3 From a6d8ba93056c1a4e243d56da447e241b2504fae2 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sat, 10 Jun 2023 23:20:37 +0300 Subject: move files again --- test/__py_include.py | 9 +++++++++ test/mqtt_relay_server_util.py | 18 ++++++------------ test/mqtt_relay_util.py | 12 +++--------- test/test.py | 1 + test/test_amixer.py | 9 +++------ test/test_api.py | 14 ++++---------- test/test_esp32_cam.py | 14 ++++---------- test/test_inverter_monitor.py | 19 ++++--------------- test/test_ipcam_server_cleanup.py | 14 ++++---------- test/test_polaris_stuff.py | 11 ++--------- test/test_record_upload.py | 17 +++++------------ test/test_send_fake_sound_hit.py | 10 ++-------- test/test_sensors_plot.py | 0 test/test_sound_node_client.py | 9 +++------ test/test_sound_server_api.py | 14 ++++---------- test/test_stopwatch.py | 1 + test/test_telegram_aio_send_photo.py | 13 +++---------- 17 files changed, 58 insertions(+), 127 deletions(-) create mode 100644 test/__py_include.py delete mode 100755 test/test_sensors_plot.py (limited to 'test') diff --git a/test/__py_include.py b/test/__py_include.py new file mode 100644 index 0000000..8f98830 --- /dev/null +++ b/test/__py_include.py @@ -0,0 +1,9 @@ +import sys +import os.path + +for _name in ('include/py',): + sys.path.extend([ + os.path.realpath( + os.path.join(os.path.dirname(os.path.join(__file__)), '..', _name) + ) + ]) \ No newline at end of file diff --git a/test/mqtt_relay_server_util.py b/test/mqtt_relay_server_util.py index ac6a9ae..6c02d75 100755 --- a/test/mqtt_relay_server_util.py +++ b/test/mqtt_relay_server_util.py @@ -1,17 +1,11 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include -from src.home.config import config -from src.home.mqtt.relay import MQTTRelayClient +from homekit.config import config if __name__ == '__main__': - config.load_app('test_mqtt_relay_server') - relay = MQTTRelayClient('test') - relay.connect_and_loop() + print(config) + # config.load_app('test_mqtt_relay_server') + # relay = MQTTRelayClient('test') + # relay.connect_and_loop() diff --git a/test/mqtt_relay_util.py b/test/mqtt_relay_util.py index 0d8c764..394bbe8 100755 --- a/test/mqtt_relay_util.py +++ b/test/mqtt_relay_util.py @@ -1,15 +1,9 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include from argparse import ArgumentParser -from src.home.config import config -from src.home.mqtt.relay import MQTTRelayController +from homekit.config import config +from homekit.mqtt.relay import MQTTRelayController if __name__ == '__main__': diff --git a/test/test.py b/test/test.py index 413c25c..267a19f 100755 --- a/test/test.py +++ b/test/test.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import __py_include from homekit.relay import RelayClient diff --git a/test/test_amixer.py b/test/test_amixer.py index 464941e..e4abc73 100755 --- a/test/test_amixer.py +++ b/test/test_amixer.py @@ -1,12 +1,9 @@ #!/usr/bin/env python3 -import sys, os.path -sys.path.extend([ - os.path.realpath(os.path.join(os.path.dirname(os.path.join(__file__)), '..')), -]) +import __py_include from argparse import ArgumentParser -from src.home.config import config -from src.home.audio import amixer +from homekit.config import config +from homekit.audio import amixer def validate_control(input: str): diff --git a/test/test_api.py b/test/test_api.py index ecf8764..80ab62a 100755 --- a/test/test_api.py +++ b/test/test_api.py @@ -1,15 +1,9 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include -from src.home.api import WebApiClient -from src.home.api.types import BotType -from src.home.config import config +from homekit.api import WebApiClient +from homekit.api.types import BotType +from homekit.config import config if __name__ == '__main__': diff --git a/test/test_esp32_cam.py b/test/test_esp32_cam.py index 6a4ad25..962768f 100755 --- a/test/test_esp32_cam.py +++ b/test/test_esp32_cam.py @@ -1,18 +1,12 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include from pprint import pprint from argparse import ArgumentParser from time import sleep -from src.home.util import Addr -from src.home.camera import esp32 -from src.home.config import config +from homekit.util import Addr +from homekit.camera import esp32 +from homekit.config import config if __name__ == '__main__': parser = ArgumentParser() diff --git a/test/test_inverter_monitor.py b/test/test_inverter_monitor.py index 621c0e9..3231bab 100755 --- a/test/test_inverter_monitor.py +++ b/test/test_inverter_monitor.py @@ -1,22 +1,11 @@ #!/usr/bin/env python3 -import cmd -import time -import logging -import socket -import sys -import threading -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include from enum import Enum, auto from typing import Optional -from src.home.util import stringify -from src.home.config import config -from src.home.inverter import ( +from homekit.util import stringify +from homekit.config import config +from homekit.inverter import ( wrapper_instance as inverter, InverterMonitor, diff --git a/test/test_ipcam_server_cleanup.py b/test/test_ipcam_server_cleanup.py index 5f313a4..ae8d31c 100644 --- a/test/test_ipcam_server_cleanup.py +++ b/test/test_ipcam_server_cleanup.py @@ -1,19 +1,13 @@ #!/usr/bin/env python3 -import shutil -import sys +import __py_include +import logging import os +import shutil import re -import logging -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) from functools import cmp_to_key from datetime import datetime -from pprint import pprint -from src.home.config import config +from homekit.config import config logger = logging.getLogger(__name__) diff --git a/test/test_polaris_stuff.py b/test/test_polaris_stuff.py index b921891..7778667 100755 --- a/test/test_polaris_stuff.py +++ b/test/test_polaris_stuff.py @@ -1,13 +1,6 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) - -import src.syncleo as polaris +import __py_include +import syncleo if __name__ == '__main__': diff --git a/test/test_record_upload.py b/test/test_record_upload.py index c0daceb..f9c83d8 100755 --- a/test/test_record_upload.py +++ b/test/test_record_upload.py @@ -1,19 +1,12 @@ #!/usr/bin/env python3 +import __py_include import logging -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) - import time -from src.home.api import WebApiClient, RequestParams -from src.home.config import config -from src.home.media import SoundRecordClient -from src.home.util import Addr +from homekit.api import WebApiClient, RequestParams +from homekit.config import config +from homekit.media import SoundRecordClient +from homekit.util import Addr logger = logging.getLogger(__name__) diff --git a/test/test_send_fake_sound_hit.py b/test/test_send_fake_sound_hit.py index 61886cd..3cc3e50 100755 --- a/test/test_send_fake_sound_hit.py +++ b/test/test_send_fake_sound_hit.py @@ -1,14 +1,8 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include from argparse import ArgumentParser -from src.home.util import send_datagram, stringify, Addr +from homekit.util import send_datagram, stringify, Addr if __name__ == '__main__': diff --git a/test/test_sensors_plot.py b/test/test_sensors_plot.py deleted file mode 100755 index e69de29..0000000 diff --git a/test/test_sound_node_client.py b/test/test_sound_node_client.py index 16feb78..c3748ca 100755 --- a/test/test_sound_node_client.py +++ b/test/test_sound_node_client.py @@ -1,11 +1,8 @@ #!/usr/bin/env python3 -import sys, os.path -sys.path.extend([ - os.path.realpath(os.path.join(os.path.dirname(os.path.join(__file__)), '..')), -]) +import __py_include -from src.home.api.errors import ApiResponseError -from src.home.media import SoundNodeClient +from homekit.api.errors import ApiResponseError +from homekit.media import SoundNodeClient if __name__ == '__main__': diff --git a/test/test_sound_server_api.py b/test/test_sound_server_api.py index 77fe1ba..11cd422 100755 --- a/test/test_sound_server_api.py +++ b/test/test_sound_server_api.py @@ -1,17 +1,11 @@ #!/usr/bin/env python3 -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import __py_include import threading from time import sleep -from src.home.config import config -from src.home.api import WebApiClient -from src.home.api.types import SoundSensorLocation +from homekit.config import config +from homekit.api import WebApiClient +from homekit.api.types import SoundSensorLocation from typing import List, Tuple interrupted = False diff --git a/test/test_stopwatch.py b/test/test_stopwatch.py index 9dd7762..1da0fe7 100755 --- a/test/test_stopwatch.py +++ b/test/test_stopwatch.py @@ -1,3 +1,4 @@ +import __py_include from homekit.util import Stopwatch, StopwatchError from time import sleep diff --git a/test/test_telegram_aio_send_photo.py b/test/test_telegram_aio_send_photo.py index 4d05c03..019fa92 100644 --- a/test/test_telegram_aio_send_photo.py +++ b/test/test_telegram_aio_send_photo.py @@ -1,16 +1,9 @@ #!/usr/bin/env python3 +import __py_include import asyncio -import sys -import os.path -sys.path.extend([ - os.path.realpath( - os.path.join(os.path.dirname(os.path.join(__file__)), '..') - ) -]) +import homekit.telegram.aio as telegram -import src.home.telegram.aio as telegram - -from src.home.config import config +from homekit.config import config async def main(): -- cgit v1.2.3 From 1d0b9c5d1c90c4f7c7a6eb0c3cf32ffb843f2533 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 11 Jun 2023 02:07:51 +0300 Subject: telegram bots: get rid of requests logging via webapi --- test/test_api.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/test_api.py b/test/test_api.py index 80ab62a..b35a597 100755 --- a/test/test_api.py +++ b/test/test_api.py @@ -2,12 +2,11 @@ import __py_include from homekit.api import WebApiClient -from homekit.api.types import BotType from homekit.config import config if __name__ == '__main__': config.load_app('test_api') - api = WebApiClient() - print(api.log_bot_request(BotType.ADMIN, 1, "test_api.py")) + # api = WebApiClient() + # print(api.log_bot_request(BotType.ADMIN, 1, "test_api.py")) -- cgit v1.2.3 From 62ee71fdb0eb07adbf0071103617aa96c993fe22 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 11 Jun 2023 05:03:43 +0300 Subject: ipcam: start porting to new config and multiserver scheme --- test/test.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/test.py b/test/test.py index 267a19f..0c4a347 100755 --- a/test/test.py +++ b/test/test.py @@ -1,8 +1,10 @@ #!/usr/bin/env python import __py_include -from homekit.relay import RelayClient + +from pprint import pprint +from homekit.camera.config import IpcamConfig if __name__ == '__main__': - c = RelayClient() - print(c, c._host) \ No newline at end of file + c = IpcamConfig() + pprint(c.get()) \ No newline at end of file -- cgit v1.2.3 From 58b5a1b5fca1cd898b1121778a3205ce2dafae36 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 11 Jun 2023 14:02:31 +0300 Subject: delete test/test.py --- test/test.py | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100755 test/test.py (limited to 'test') diff --git a/test/test.py b/test/test.py deleted file mode 100755 index 0c4a347..0000000 --- a/test/test.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import __py_include - -from pprint import pprint -from homekit.camera.config import IpcamConfig - - -if __name__ == '__main__': - c = IpcamConfig() - pprint(c.get()) \ No newline at end of file -- cgit v1.2.3