Skip to content

Commit 5f303eb

Browse files
committed
Add project files
1 parent 9ece844 commit 5f303eb

13 files changed

+1569
-0
lines changed

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,24 @@ cython_debug/
205205
marimo/_static/
206206
marimo/_lsp/
207207
__marimo__/
208+
209+
# Игнорировать все файлы и папки в корне проекта, кроме тех, что разрешены явно
210+
/*
211+
!.gitignore
212+
!ftp_server.spec
213+
!src/
214+
215+
# Игнорировать содержимое папки src, кроме разрешенных файлов
216+
/src/*
217+
!/src/*.py
218+
!/src/icon.ico
219+
!/src/version_info.txt
220+
221+
# Явно игнорируем ненужные папки и их содержимое
222+
build/
223+
dist/
224+
src/!_backup/
225+
src/ico/
226+
*.pyc
227+
__pycache__/
228+
*.log

ftp_server.spec

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
a = Analysis(
5+
['src\\ftp_server.py'],
6+
pathex=[],
7+
binaries=[],
8+
datas=[],
9+
hiddenimports=[],
10+
hookspath=[],
11+
hooksconfig={},
12+
runtime_hooks=[],
13+
excludes=[],
14+
noarchive=False,
15+
optimize=0,
16+
)
17+
pyz = PYZ(a.pure)
18+
19+
exe = EXE(
20+
pyz,
21+
a.scripts,
22+
a.binaries,
23+
a.datas,
24+
[],
25+
name='ftp_server',
26+
debug=False,
27+
bootloader_ignore_signals=False,
28+
strip=False,
29+
upx=True,
30+
upx_exclude=[],
31+
runtime_tmpdir=None,
32+
console=True,
33+
disable_windowed_traceback=False,
34+
argv_emulation=False,
35+
target_arch=None,
36+
codesign_identity=None,
37+
entitlements_file=None,
38+
icon='src\\icon.ico',
39+
version='src\\version_info.txt'
40+
)

src/ftp_server.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import sys
2+
import os
3+
import argparse
4+
import traceback
5+
from ftp_server_config import ConfigManager
6+
from ftp_server_service import ServiceManager
7+
from ftp_server_console import run_console_mode
8+
from ftp_server_types import LoggerProtocol
9+
10+
def get_absolute_path(filename):
11+
"""Возвращает абсолютный путь к файлу"""
12+
if getattr(sys, 'frozen', False):
13+
base_dir = os.path.dirname(sys.executable)
14+
# Берем базовое имя EXE файла без расширения
15+
exe_name = os.path.splitext(os.path.basename(sys.executable))[0]
16+
else:
17+
base_dir = os.path.dirname(os.path.abspath(__file__))
18+
exe_name = 'ftp_server'
19+
20+
# Используем имя EXE файла как основу
21+
base_filename = f"{exe_name}.{filename.split('.')[-1]}"
22+
return os.path.join(base_dir, base_filename)
23+
24+
# Используем динамические имена файлов
25+
CONFIG_FILENAME = get_absolute_path('ftp_server.cfg')
26+
LOG_FILENAME = get_absolute_path('ftp_server.log')
27+
PID_FILENAME = get_absolute_path('ftp_server.pid')
28+
29+
class ServiceLogger:
30+
"""Логгер для режима сервиса"""
31+
def __init__(self, log_file: str):
32+
self.log_file = log_file
33+
self.is_service = False
34+
35+
def __call__(self, message: str, log_to_file: bool = True):
36+
import time
37+
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
38+
39+
if self.is_service and log_to_file:
40+
# В режиме сервиса пишем в файл с timestamp
41+
log_message = f"[{timestamp}] {message}\n"
42+
try:
43+
with open(self.log_file, 'a', encoding='utf-8') as f:
44+
f.write(log_message)
45+
except Exception as e:
46+
print(f"Ошибка записи в лог: {e}")
47+
else:
48+
# В консольном режиме или без логирования в файл - просто выводим
49+
print(message)
50+
51+
def main():
52+
try:
53+
# Парсинг аргументов командной строки
54+
parser = argparse.ArgumentParser(description='FTP Server для сканирования с МФУ')
55+
parser.add_argument('--service-stop', action='store_true', help='Остановить работающий сервис')
56+
parser.add_argument('--service-start', action='store_true', help='Запустить в режиме сервиса')
57+
parser.add_argument('--service-worker', action='store_true', help='Внутренний аргумент для рабочего процесса')
58+
parser.add_argument('--console', action='store_true', help='Запустить в консольном режиме')
59+
args = parser.parse_args()
60+
61+
logger = ServiceLogger(LOG_FILENAME)
62+
config_manager = ConfigManager()
63+
64+
# Обработка команды остановки сервиса
65+
if args.service_stop:
66+
service_manager = ServiceManager(config_manager, logger)
67+
if service_manager.stop_service():
68+
sys.exit(0)
69+
else:
70+
sys.exit(1)
71+
72+
# Загрузка конфигурации
73+
try:
74+
config_data = config_manager.load_config()
75+
service_mode = config_manager.server_config.service_mode
76+
except Exception as e:
77+
error_msg = f"Ошибка загрузки конфигурации: {e}\n"
78+
error_msg += f"Traceback: {traceback.format_exc()}"
79+
print(error_msg)
80+
sys.exit(1)
81+
82+
# Проверка, не запущен ли уже сервис
83+
service_manager = ServiceManager(config_manager, logger)
84+
85+
# Запуск рабочего процесса сервиса
86+
if args.service_worker:
87+
logger.is_service = True
88+
service_manager.run_service_worker()
89+
sys.exit(0)
90+
91+
92+
if service_manager.is_service_running() and not args.console:
93+
print("Сервис уже запущен. Используйте --console для принудительного запуска в консольном режиме.")
94+
sys.exit(1)
95+
96+
# Определение режима работы
97+
if args.service_start:
98+
# Принудительный запуск в режиме сервиса
99+
service_manager.run_service_mode()
100+
sys.exit(0) # Завершаем родительский процесс
101+
elif args.console:
102+
# Принудительный запуск в консольном режиме
103+
run_console_mode(config_manager, logger)
104+
elif service_mode:
105+
# Режим из конфига - сервис
106+
if service_manager.run_service_mode():
107+
sys.exit(0) # Немедленное завершение родительского процесса
108+
else:
109+
sys.exit(1)
110+
else:
111+
# Режим из конфига - консоль
112+
run_console_mode(config_manager, logger)
113+
114+
except Exception as e:
115+
error_msg = f"Критическая ошибка в главной функции: {e}\n"
116+
error_msg += f"Тип ошибки: {type(e).__name__}\n"
117+
error_msg += f"Traceback: {traceback.format_exc()}"
118+
print(error_msg)
119+
sys.exit(1)
120+
121+
if __name__ == '__main__':
122+
main()

0 commit comments

Comments
 (0)