sarmat 1.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sarmat-1.2.3/LICENSE +19 -0
- sarmat-1.2.3/PKG-INFO +122 -0
- sarmat-1.2.3/README.md +88 -0
- sarmat-1.2.3/pyproject.toml +25 -0
- sarmat-1.2.3/sarmat/__init__.py +3 -0
- sarmat-1.2.3/sarmat/core/__init__.py +5 -0
- sarmat-1.2.3/sarmat/core/actions/__init__.py +20 -0
- sarmat-1.2.3/sarmat/core/actions/bases.py +17 -0
- sarmat-1.2.3/sarmat/core/actions/dispatcher.py +205 -0
- sarmat-1.2.3/sarmat/core/actions/geo_locations.py +48 -0
- sarmat-1.2.3/sarmat/core/actions/traffic_management.py +302 -0
- sarmat-1.2.3/sarmat/core/behavior/__init__.py +24 -0
- sarmat-1.2.3/sarmat/core/behavior/bases.py +86 -0
- sarmat-1.2.3/sarmat/core/behavior/geo_locations.py +196 -0
- sarmat-1.2.3/sarmat/core/behavior/sarmat.py +64 -0
- sarmat-1.2.3/sarmat/core/behavior/traffic_management.py +632 -0
- sarmat-1.2.3/sarmat/core/behavior/vehicle.py +164 -0
- sarmat-1.2.3/sarmat/core/constants/__init__.py +38 -0
- sarmat-1.2.3/sarmat/core/constants/exception_constants.py +66 -0
- sarmat-1.2.3/sarmat/core/constants/formats.py +12 -0
- sarmat-1.2.3/sarmat/core/constants/sarmat_constants.py +328 -0
- sarmat-1.2.3/sarmat/core/context/__init__.py +0 -0
- sarmat-1.2.3/sarmat/core/context/containers/__init__.py +43 -0
- sarmat-1.2.3/sarmat/core/context/containers/dispatcher_containers.py +86 -0
- sarmat-1.2.3/sarmat/core/context/containers/geo_containers.py +47 -0
- sarmat-1.2.3/sarmat/core/context/containers/sarmat_containers.py +75 -0
- sarmat-1.2.3/sarmat/core/context/containers/traffic_management_containers.py +111 -0
- sarmat-1.2.3/sarmat/core/context/containers/vehicle_containers.py +57 -0
- sarmat-1.2.3/sarmat/core/context/models/__init__.py +40 -0
- sarmat-1.2.3/sarmat/core/context/models/dispatcher_models.py +126 -0
- sarmat-1.2.3/sarmat/core/context/models/geo_models.py +131 -0
- sarmat-1.2.3/sarmat/core/context/models/sarmat_models.py +120 -0
- sarmat-1.2.3/sarmat/core/context/models/traffic_management_models.py +306 -0
- sarmat-1.2.3/sarmat/core/context/models/vehicle_models.py +120 -0
- sarmat-1.2.3/sarmat/core/exceptions/__init__.py +13 -0
- sarmat-1.2.3/sarmat/core/exceptions/exceptions.py +62 -0
- sarmat-1.2.3/sarmat/core/exceptions/sarmat_exceptions.py +30 -0
- sarmat-1.2.3/sarmat/core/factory/__init__.py +26 -0
- sarmat-1.2.3/sarmat/core/factory/base_creator.py +178 -0
- sarmat-1.2.3/sarmat/core/factory/geo_creator.py +52 -0
- sarmat-1.2.3/sarmat/core/factory/traffic_manager_creator.py +214 -0
- sarmat-1.2.3/sarmat/core/factory/vehicle_creator.py +81 -0
- sarmat-1.2.3/sarmat/core/verification/__init__.py +33 -0
- sarmat-1.2.3/sarmat/core/verification/base_verifications.py +48 -0
- sarmat-1.2.3/sarmat/core/verification/customize_verifications.py +17 -0
- sarmat-1.2.3/sarmat/core/verification/geo_verifications.py +68 -0
- sarmat-1.2.3/sarmat/core/verification/traffic_management_verifications.py +89 -0
- sarmat-1.2.3/sarmat/core/verification/vehicle_verifications.py +54 -0
- sarmat-1.2.3/sarmat/tools/__init__.py +5 -0
- sarmat-1.2.3/sarmat/tools/fare_calculation.py +324 -0
- sarmat-1.2.3/sarmat/tools/fare_containers.py +56 -0
- sarmat-1.2.3/sarmat/tools/geo_tools.py +36 -0
- sarmat-1.2.3/sarmat/tools/json_encoder.py +66 -0
- sarmat-1.2.3/sarmat.egg-info/PKG-INFO +122 -0
- sarmat-1.2.3/sarmat.egg-info/SOURCES.txt +63 -0
- sarmat-1.2.3/sarmat.egg-info/dependency_links.txt +1 -0
- sarmat-1.2.3/sarmat.egg-info/requires.txt +1 -0
- sarmat-1.2.3/sarmat.egg-info/top_level.txt +1 -0
- sarmat-1.2.3/setup.cfg +23 -0
- sarmat-1.2.3/setup.py +27 -0
- sarmat-1.2.3/tests/test_constants.py +202 -0
- sarmat-1.2.3/tests/test_fare.py +35 -0
- sarmat-1.2.3/tests/test_fare_calculation.py +47 -0
- sarmat-1.2.3/tests/test_fare_strategy.py +116 -0
sarmat-1.2.3/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
sarmat-1.2.3/PKG-INFO
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: sarmat
|
|
3
|
+
Version: 1.2.3
|
|
4
|
+
Summary: Sarmat
|
|
5
|
+
Home-page:
|
|
6
|
+
Author: Artel
|
|
7
|
+
Author-email: Artel <artel61@gmail.com>
|
|
8
|
+
License: Copyright (c) 2018 The Python Packaging Authority
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Classifier: Programming Language :: Python :: 3
|
|
29
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
+
Classifier: Operating System :: OS Independent
|
|
31
|
+
Requires-Python: >=3.8
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
|
|
35
|
+
# Sarmat.
|
|
36
|
+
|
|
37
|
+
Библиотека для построения решений в сфере пассажирского транспорта.
|
|
38
|
+
|
|
39
|
+
Основу работы библиотеки составляют объекты для построения рейсов
|
|
40
|
+
и шаблонов для них, выполнения диспетчерских операций,
|
|
41
|
+
и управления автотранспортом.
|
|
42
|
+
|
|
43
|
+
## Состав библиотеки
|
|
44
|
+
|
|
45
|
+
Библиотека состоит из набора тематических модулей, у каждого из которых своя область
|
|
46
|
+
применения:
|
|
47
|
+
|
|
48
|
+
* Сущности для описания справочников
|
|
49
|
+
* Сущности для построения рейсов и маршрутов
|
|
50
|
+
* Сущности для описания работы транспортной компании.
|
|
51
|
+
|
|
52
|
+
## Композиция объектов
|
|
53
|
+
|
|
54
|
+
Каждый из тематических объектов представлен в виде композиции классов.
|
|
55
|
+
|
|
56
|
+
### Модели и контейнеры
|
|
57
|
+
|
|
58
|
+
Модель содержит набор атрибутов, присущих объекту класса,
|
|
59
|
+
а также методы создания модели на основе контейнера. Реализована вложенность
|
|
60
|
+
моделей. В том числе для описания иерархической модели справочников. Каждая модель
|
|
61
|
+
является фабрикой для создания объектов своего типа. Фабричный метод принимает
|
|
62
|
+
на вход аргумент, который имеет тип соответствующего контейнера.
|
|
63
|
+
Контейнеры также могут быть вложенными.
|
|
64
|
+
|
|
65
|
+
Контейнеры повторяют набор атрибутов, описанных в модели. Контейнеры предназначены
|
|
66
|
+
для получения атрибутов извне и правильного создания модели
|
|
67
|
+
на основе полученных данных. Контейнеры написаны на основе классов `pydantic`.
|
|
68
|
+
|
|
69
|
+
### Верификация объектов
|
|
70
|
+
|
|
71
|
+
Основные правила верификации объектов описаны в контейнерах. Все случаи проверки,
|
|
72
|
+
которые являются частью бизнес-логики, описаны в специальных классах верификаторах.
|
|
73
|
+
Эти классы задействуются перед созданием модели из контейнера. Верификацию
|
|
74
|
+
проходят **контейнеры**. Объекты верификации содержат рбязательный метод `verify`,
|
|
75
|
+
в котором реализована логика проверки. Верификаторы могут быть вложенными. В этом
|
|
76
|
+
случае процесс проверки будет идти от дочернего верификатора к родительскому.
|
|
77
|
+
Метод верификации не возвращает значений, но возбуздает исключения
|
|
78
|
+
в случае нарушения правил проверки.
|
|
79
|
+
|
|
80
|
+
Базовый верификатор проверяет на непустоту указанных атрибутов. Есть возможность
|
|
81
|
+
создать верификатор на основе кастомного класса. В нем проверка происходит
|
|
82
|
+
на основе встроенного словаря. Ключами словаря могут выступать строковые константы,
|
|
83
|
+
а значениями - вызываемые объекты.
|
|
84
|
+
|
|
85
|
+
### Поведение объектов
|
|
86
|
+
|
|
87
|
+
Поведение объектов описано в поведенческих классах. Там реализован набор
|
|
88
|
+
простейших операций, упрощающих процесс прикладной разработки. Поведенческие
|
|
89
|
+
классы позволяют проводить сравнение двух объектов между собой (`==`, `!=`),
|
|
90
|
+
выполнять операции проверки на неравенство (`>`, `<`, `>=`, `<=`).
|
|
91
|
+
Для объектов, содержащих другие объекты, реализована проверка на вхождение
|
|
92
|
+
во множество (`in`). За это ответственны поведенческие классы сравнения. Базовым
|
|
93
|
+
поведенческим классом является класс `BhNoAction`, который можно использовать
|
|
94
|
+
для переопределения или дополнения модели поведения для того или иного класса
|
|
95
|
+
в рамках той или иной роли приложения.
|
|
96
|
+
К примеру, сотрудник с правами оператора системы может создавать рейсы и
|
|
97
|
+
проводить с ними прочие операции редактирования. Другой сотрудник с правами
|
|
98
|
+
диспетчера может обрабатывать созданные рейсы, но не может их создавать. Для
|
|
99
|
+
описания этих различных моделей поведения необходимо создать два поведенческих класса
|
|
100
|
+
`Actor` и `Dispatcher`, первый из которых будет содержать методы CRUD для работы
|
|
101
|
+
с объектом, а втрой будет иметь набор методов работы с созданныим рейсами. Оба класса
|
|
102
|
+
регистрируются в фабрике классов под своими псевдонимами. Потом нужный псевдоним
|
|
103
|
+
указывается при вызове фабрики, и для каждой модели ищется соответствующий класс.
|
|
104
|
+
Если необходимо совместить для пользователя полномочия, то соответствующие
|
|
105
|
+
псевдонимы склеиваются. В качестве разделителя используется точка.
|
|
106
|
+
|
|
107
|
+
### Действия с объектами
|
|
108
|
+
|
|
109
|
+
Для объектов реализованы простейшие операции. Такие, как, например, копирование
|
|
110
|
+
объекта. Реализованы специфические операции для конкретных объектов.
|
|
111
|
+
|
|
112
|
+
## Сборка объектов
|
|
113
|
+
|
|
114
|
+
Сборкой объектов занимаются фабрики классов. Каждая тематическая фабрика обладает
|
|
115
|
+
набором методов, каждый из которых создает объект своего типа. Сборка объектов
|
|
116
|
+
производится вызовом `type` с последующей инициализацией полученного класса при
|
|
117
|
+
помощи данных, которые передаются в контейнере. В фабрике перечисляются
|
|
118
|
+
родительские классы, а также указываются дополнительные атрибуты для будущего
|
|
119
|
+
объекта: в атрибуте `controller` передается экземпляр фабрики для последующего
|
|
120
|
+
использования при создании объектов во время выполнения бизнесс процессов.
|
|
121
|
+
Также передается набор тегов доступа, которые были определены пользователю
|
|
122
|
+
изначально.
|
sarmat-1.2.3/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Sarmat.
|
|
2
|
+
|
|
3
|
+
Библиотека для построения решений в сфере пассажирского транспорта.
|
|
4
|
+
|
|
5
|
+
Основу работы библиотеки составляют объекты для построения рейсов
|
|
6
|
+
и шаблонов для них, выполнения диспетчерских операций,
|
|
7
|
+
и управления автотранспортом.
|
|
8
|
+
|
|
9
|
+
## Состав библиотеки
|
|
10
|
+
|
|
11
|
+
Библиотека состоит из набора тематических модулей, у каждого из которых своя область
|
|
12
|
+
применения:
|
|
13
|
+
|
|
14
|
+
* Сущности для описания справочников
|
|
15
|
+
* Сущности для построения рейсов и маршрутов
|
|
16
|
+
* Сущности для описания работы транспортной компании.
|
|
17
|
+
|
|
18
|
+
## Композиция объектов
|
|
19
|
+
|
|
20
|
+
Каждый из тематических объектов представлен в виде композиции классов.
|
|
21
|
+
|
|
22
|
+
### Модели и контейнеры
|
|
23
|
+
|
|
24
|
+
Модель содержит набор атрибутов, присущих объекту класса,
|
|
25
|
+
а также методы создания модели на основе контейнера. Реализована вложенность
|
|
26
|
+
моделей. В том числе для описания иерархической модели справочников. Каждая модель
|
|
27
|
+
является фабрикой для создания объектов своего типа. Фабричный метод принимает
|
|
28
|
+
на вход аргумент, который имеет тип соответствующего контейнера.
|
|
29
|
+
Контейнеры также могут быть вложенными.
|
|
30
|
+
|
|
31
|
+
Контейнеры повторяют набор атрибутов, описанных в модели. Контейнеры предназначены
|
|
32
|
+
для получения атрибутов извне и правильного создания модели
|
|
33
|
+
на основе полученных данных. Контейнеры написаны на основе классов `pydantic`.
|
|
34
|
+
|
|
35
|
+
### Верификация объектов
|
|
36
|
+
|
|
37
|
+
Основные правила верификации объектов описаны в контейнерах. Все случаи проверки,
|
|
38
|
+
которые являются частью бизнес-логики, описаны в специальных классах верификаторах.
|
|
39
|
+
Эти классы задействуются перед созданием модели из контейнера. Верификацию
|
|
40
|
+
проходят **контейнеры**. Объекты верификации содержат рбязательный метод `verify`,
|
|
41
|
+
в котором реализована логика проверки. Верификаторы могут быть вложенными. В этом
|
|
42
|
+
случае процесс проверки будет идти от дочернего верификатора к родительскому.
|
|
43
|
+
Метод верификации не возвращает значений, но возбуздает исключения
|
|
44
|
+
в случае нарушения правил проверки.
|
|
45
|
+
|
|
46
|
+
Базовый верификатор проверяет на непустоту указанных атрибутов. Есть возможность
|
|
47
|
+
создать верификатор на основе кастомного класса. В нем проверка происходит
|
|
48
|
+
на основе встроенного словаря. Ключами словаря могут выступать строковые константы,
|
|
49
|
+
а значениями - вызываемые объекты.
|
|
50
|
+
|
|
51
|
+
### Поведение объектов
|
|
52
|
+
|
|
53
|
+
Поведение объектов описано в поведенческих классах. Там реализован набор
|
|
54
|
+
простейших операций, упрощающих процесс прикладной разработки. Поведенческие
|
|
55
|
+
классы позволяют проводить сравнение двух объектов между собой (`==`, `!=`),
|
|
56
|
+
выполнять операции проверки на неравенство (`>`, `<`, `>=`, `<=`).
|
|
57
|
+
Для объектов, содержащих другие объекты, реализована проверка на вхождение
|
|
58
|
+
во множество (`in`). За это ответственны поведенческие классы сравнения. Базовым
|
|
59
|
+
поведенческим классом является класс `BhNoAction`, который можно использовать
|
|
60
|
+
для переопределения или дополнения модели поведения для того или иного класса
|
|
61
|
+
в рамках той или иной роли приложения.
|
|
62
|
+
К примеру, сотрудник с правами оператора системы может создавать рейсы и
|
|
63
|
+
проводить с ними прочие операции редактирования. Другой сотрудник с правами
|
|
64
|
+
диспетчера может обрабатывать созданные рейсы, но не может их создавать. Для
|
|
65
|
+
описания этих различных моделей поведения необходимо создать два поведенческих класса
|
|
66
|
+
`Actor` и `Dispatcher`, первый из которых будет содержать методы CRUD для работы
|
|
67
|
+
с объектом, а втрой будет иметь набор методов работы с созданныим рейсами. Оба класса
|
|
68
|
+
регистрируются в фабрике классов под своими псевдонимами. Потом нужный псевдоним
|
|
69
|
+
указывается при вызове фабрики, и для каждой модели ищется соответствующий класс.
|
|
70
|
+
Если необходимо совместить для пользователя полномочия, то соответствующие
|
|
71
|
+
псевдонимы склеиваются. В качестве разделителя используется точка.
|
|
72
|
+
|
|
73
|
+
### Действия с объектами
|
|
74
|
+
|
|
75
|
+
Для объектов реализованы простейшие операции. Такие, как, например, копирование
|
|
76
|
+
объекта. Реализованы специфические операции для конкретных объектов.
|
|
77
|
+
|
|
78
|
+
## Сборка объектов
|
|
79
|
+
|
|
80
|
+
Сборкой объектов занимаются фабрики классов. Каждая тематическая фабрика обладает
|
|
81
|
+
набором методов, каждый из которых создает объект своего типа. Сборка объектов
|
|
82
|
+
производится вызовом `type` с последующей инициализацией полученного класса при
|
|
83
|
+
помощи данных, которые передаются в контейнере. В фабрике перечисляются
|
|
84
|
+
родительские классы, а также указываются дополнительные атрибуты для будущего
|
|
85
|
+
объекта: в атрибуте `controller` передается экземпляр фабрики для последующего
|
|
86
|
+
использования при создании объектов во время выполнения бизнесс процессов.
|
|
87
|
+
Также передается набор тегов доступа, которые были определены пользователю
|
|
88
|
+
изначально.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "pydantic"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sarmat"
|
|
7
|
+
version = "1.2.3"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Artel", email="artel61@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "Sarmat"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
license = { file="LICENSE" }
|
|
14
|
+
requires-python = ">=3.8"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[tool.pytest.ini_options]
|
|
22
|
+
minversion = "6.0"
|
|
23
|
+
testpaths = [
|
|
24
|
+
"tests",
|
|
25
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sarmat.
|
|
3
|
+
|
|
4
|
+
Описание действий с объектами.
|
|
5
|
+
"""
|
|
6
|
+
__all__ = (
|
|
7
|
+
"AGeoLocationMixin", "ADestinationPointMixin", "AStationMixin", "ARouteMixin", "AJourneyMixin",
|
|
8
|
+
"AJourneyBunchMixin",
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from .geo_locations import (
|
|
12
|
+
ADestinationPointMixin,
|
|
13
|
+
AGeoLocationMixin,
|
|
14
|
+
)
|
|
15
|
+
from .traffic_management import (
|
|
16
|
+
AJourneyMixin,
|
|
17
|
+
AJourneyBunchMixin,
|
|
18
|
+
ARouteMixin,
|
|
19
|
+
AStationMixin,
|
|
20
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sarmat.
|
|
3
|
+
|
|
4
|
+
Описание действий с объектами.
|
|
5
|
+
|
|
6
|
+
Базовые классы.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ActionMixin:
|
|
11
|
+
"""Базовый класс-примесь для описания работы с объектами"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, **kwargs):
|
|
14
|
+
super().__init__(**kwargs)
|
|
15
|
+
|
|
16
|
+
def copy(self):
|
|
17
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sarmat.
|
|
3
|
+
|
|
4
|
+
Описание поведения объектов.
|
|
5
|
+
|
|
6
|
+
Поведение объектов в режиме работы диспетчера.
|
|
7
|
+
"""
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from datetime import date, datetime, tzinfo
|
|
10
|
+
from typing import Dict, Optional, List, Union
|
|
11
|
+
from uuid import uuid4
|
|
12
|
+
|
|
13
|
+
from sarmat.core.constants import JourneyClass, JourneyState
|
|
14
|
+
from sarmat.core.context.models import (
|
|
15
|
+
PermitModel,
|
|
16
|
+
RouteItemModel,
|
|
17
|
+
StationModel,
|
|
18
|
+
JourneyProgressModel,
|
|
19
|
+
JourneyScheduleModel,
|
|
20
|
+
JourneyModel,
|
|
21
|
+
)
|
|
22
|
+
from sarmat.core.exceptions.sarmat_exceptions import ImpossibleOperationError
|
|
23
|
+
|
|
24
|
+
from sarmat.core.behavior.traffic_management import BhJourney
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Journey(BhJourney):
|
|
28
|
+
"""Поведение объекта Рейс"""
|
|
29
|
+
|
|
30
|
+
def activate(
|
|
31
|
+
self,
|
|
32
|
+
start_date: date,
|
|
33
|
+
permit: PermitModel,
|
|
34
|
+
) -> Dict[str, Union[JourneyProgressModel, List[JourneyScheduleModel]]]:
|
|
35
|
+
"""
|
|
36
|
+
Активизация рейса (выписка рейсовой ведомости, создание расписания по рейсу)
|
|
37
|
+
Args:
|
|
38
|
+
start_date: дата начала выполнения рейса (отправление из начальной точки)
|
|
39
|
+
permit: путевой лист
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
рейсовая ведомость
|
|
43
|
+
список активных пунктов маршрута
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
# атрибуты текущего рейса и список активных станций, через которые проходит рейс
|
|
47
|
+
this_journey = JourneyModel.from_container(self.raw()) # type: ignore
|
|
48
|
+
journey_stations = [item for item in self.get_journey_schedule(start_date) if item.station is not None]
|
|
49
|
+
first_station, *middleware_stations, last_station = journey_stations
|
|
50
|
+
|
|
51
|
+
journey_progress = JourneyProgressModel( # Атрибуты рейсовой ведомости
|
|
52
|
+
uid=str(uuid4()), # идентификатор ведомости
|
|
53
|
+
depart_date=start_date, # дата отправления в рейс
|
|
54
|
+
journey=this_journey, # рейс
|
|
55
|
+
permit=permit, # путевой лист
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
journey_schedule = [
|
|
59
|
+
JourneyScheduleModel(
|
|
60
|
+
uid=str(uuid4()), # идентификатор строки
|
|
61
|
+
journey_progress=journey_progress, # рейсовая ведомость
|
|
62
|
+
journey_class=JourneyClass.BASE, # класс рейса (формирующийся)
|
|
63
|
+
station=first_station.station, # станция
|
|
64
|
+
point=first_station.point, # пункт прохождения маршрута
|
|
65
|
+
state=JourneyState.READY, # состояние рейса
|
|
66
|
+
plan_depart=first_station.depart, # плановое время отправления
|
|
67
|
+
platform='', # платформа
|
|
68
|
+
comment='', # комментарий к текущему пункту
|
|
69
|
+
)
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
journey_schedule += [
|
|
73
|
+
JourneyScheduleModel(
|
|
74
|
+
uid=str(uuid4()), # идентификатор строки
|
|
75
|
+
journey_progress=journey_progress, # рейсовая ведомость
|
|
76
|
+
journey_class=JourneyClass.TRANSIT, # класс рейса (формирующийся)
|
|
77
|
+
station=item.station, # станция
|
|
78
|
+
point=item.point, # пункт прохождения маршрута
|
|
79
|
+
state=JourneyState.READY, # состояние рейса
|
|
80
|
+
plan_arrive=item.arrive, # плановое время прибытия
|
|
81
|
+
plan_depart=item.depart, # плановое время отправления
|
|
82
|
+
platform='', # платформа
|
|
83
|
+
comment='', # комментарий к текущему пункту
|
|
84
|
+
)
|
|
85
|
+
for item in middleware_stations
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
journey_schedule.append(
|
|
89
|
+
JourneyScheduleModel(
|
|
90
|
+
uid=str(uuid4()), # идентификатор строки
|
|
91
|
+
journey_progress=journey_progress, # рейсовая ведомость
|
|
92
|
+
journey_class=JourneyClass.ARRIVING, # класс рейса (формирующийся)
|
|
93
|
+
station=last_station.station, # станция
|
|
94
|
+
point=last_station.point, # пункт прохождения маршрута
|
|
95
|
+
state=JourneyState.READY, # состояние рейса
|
|
96
|
+
plan_arrive=last_station.arrive, # плановое время прибытия
|
|
97
|
+
platform='', # платформа
|
|
98
|
+
comment='', # комментарий к текущему пункту
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
for idx, item in enumerate(journey_schedule):
|
|
103
|
+
journey_schedule[idx].last_items = journey_schedule[idx+1:]
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
'JourneyProgress': journey_progress,
|
|
107
|
+
'JourneyScheduleStructure': journey_schedule,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class JourneySchedule:
|
|
112
|
+
"""Поведение объекта Рейсовая ведомость в активном расписании"""
|
|
113
|
+
|
|
114
|
+
journey_class: JourneyClass
|
|
115
|
+
state: JourneyState
|
|
116
|
+
fact_arrive: datetime
|
|
117
|
+
fact_depart: datetime
|
|
118
|
+
permit: Optional[PermitModel]
|
|
119
|
+
platform: str
|
|
120
|
+
comment: str
|
|
121
|
+
last_items: List['JourneySchedule']
|
|
122
|
+
current_item: RouteItemModel
|
|
123
|
+
|
|
124
|
+
def make_departure(self, time_zone: Optional[tzinfo] = None) -> None:
|
|
125
|
+
"""Операция отправления на текущем пункте"""
|
|
126
|
+
|
|
127
|
+
if self.journey_class == JourneyClass.ARRIVING:
|
|
128
|
+
raise ImpossibleOperationError("На последнем пункте маршрута операция отправления не выполняется")
|
|
129
|
+
|
|
130
|
+
self.state = JourneyState.DEPARTED
|
|
131
|
+
self.fact_depart = datetime.now(time_zone)
|
|
132
|
+
|
|
133
|
+
def make_registration(self,
|
|
134
|
+
permit: Optional[PermitModel] = None,
|
|
135
|
+
platform: Optional[str] = None,
|
|
136
|
+
comments: Optional[str] = None) -> None:
|
|
137
|
+
"""
|
|
138
|
+
Операция по регистрации рейса. Заполнение реквизитов
|
|
139
|
+
Args:
|
|
140
|
+
permit: путевой лист
|
|
141
|
+
platform: номер платформы
|
|
142
|
+
comments: комментарии диспетчера
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
if permit and (permit != self.permit):
|
|
146
|
+
self.permit = permit
|
|
147
|
+
|
|
148
|
+
if platform and platform != self.platform:
|
|
149
|
+
self.platform = platform
|
|
150
|
+
|
|
151
|
+
# NOTE: комментарий дозволяется затереть
|
|
152
|
+
if comments != self.comment:
|
|
153
|
+
self.comment = comments or ''
|
|
154
|
+
|
|
155
|
+
def make_arrival(self, time_zone: Optional[tzinfo] = None) -> None:
|
|
156
|
+
"""Операция прибытия на текущем пункте"""
|
|
157
|
+
is_last = self.journey_class == JourneyClass.ARRIVING
|
|
158
|
+
operational_time = datetime.now(time_zone)
|
|
159
|
+
|
|
160
|
+
new_state = JourneyState.ARRIVED if is_last else JourneyState.ON_REGISTRATION
|
|
161
|
+
self.state = new_state
|
|
162
|
+
self.fact_arrive = operational_time
|
|
163
|
+
|
|
164
|
+
def cancel_journey(self) -> None:
|
|
165
|
+
"""Отмена рейса"""
|
|
166
|
+
self._set_state_for_items_chain(JourneyState.CANCELLED)
|
|
167
|
+
|
|
168
|
+
def close_journey(self) -> None:
|
|
169
|
+
"""Закрытие рейса"""
|
|
170
|
+
self._set_state_for_items_chain(JourneyState.CLOSED)
|
|
171
|
+
|
|
172
|
+
def break_journey(self) -> None:
|
|
173
|
+
"""Отметка о срыве"""
|
|
174
|
+
self._set_state_for_items_chain(JourneyState.DISRUPTED)
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def current_station(self) -> Optional[StationModel]:
|
|
178
|
+
"""Текущий пункт прохождения рейса"""
|
|
179
|
+
return self.current_item.station if self.current_item else None
|
|
180
|
+
|
|
181
|
+
def _set_state_for_items_chain(self, state: JourneyState) -> None:
|
|
182
|
+
"""Назначение состояния текущему элементу и всем последующим"""
|
|
183
|
+
self.state = state
|
|
184
|
+
for item in self.last_items:
|
|
185
|
+
item.state = state
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class JourneyHook(ABC):
|
|
189
|
+
"""Поведение объекта Рейсовая Ведомость"""
|
|
190
|
+
|
|
191
|
+
@abstractmethod
|
|
192
|
+
def lock_register(self):
|
|
193
|
+
"""Блокировка ведомости"""
|
|
194
|
+
|
|
195
|
+
@abstractmethod
|
|
196
|
+
def unlock_register(self):
|
|
197
|
+
"""Снятие блокировки с ведомости"""
|
|
198
|
+
|
|
199
|
+
@abstractmethod
|
|
200
|
+
def register_place(self):
|
|
201
|
+
"""Регистрация места на ведомости"""
|
|
202
|
+
|
|
203
|
+
@abstractmethod
|
|
204
|
+
def unregister_place(self):
|
|
205
|
+
"""Отмена регистрации места на ведомости"""
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sarmat.
|
|
3
|
+
|
|
4
|
+
Описание действий с объектами.
|
|
5
|
+
|
|
6
|
+
Классы для работы с объектами гео локации.
|
|
7
|
+
"""
|
|
8
|
+
from sarmat.core.constants import LocationType, SettlementType
|
|
9
|
+
|
|
10
|
+
from .bases import ActionMixin
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AGeoLocationMixin(ActionMixin):
|
|
14
|
+
"""Действия с объектами гео локации"""
|
|
15
|
+
|
|
16
|
+
name: str
|
|
17
|
+
latin_name: str
|
|
18
|
+
mapping_data: dict
|
|
19
|
+
tags: str
|
|
20
|
+
location_type: LocationType
|
|
21
|
+
parent: object
|
|
22
|
+
|
|
23
|
+
def copy(self):
|
|
24
|
+
return self.__class__(
|
|
25
|
+
id=0,
|
|
26
|
+
name=f"Копия {self.name}",
|
|
27
|
+
location_type=self.location_type,
|
|
28
|
+
latin_name=f"Copy of {self.latin_name}" if self.latin_name else "",
|
|
29
|
+
mapping_data=self.mapping_data,
|
|
30
|
+
tags=self.tags,
|
|
31
|
+
parent=self.parent,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ADestinationPointMixin(ActionMixin):
|
|
36
|
+
"""Действия с пунктами назначения"""
|
|
37
|
+
|
|
38
|
+
name: str
|
|
39
|
+
state: object
|
|
40
|
+
point_type: SettlementType
|
|
41
|
+
|
|
42
|
+
def copy(self):
|
|
43
|
+
return self.__class__(
|
|
44
|
+
id=0,
|
|
45
|
+
name=f"Копия {self.name}",
|
|
46
|
+
state=self.state,
|
|
47
|
+
point_type=self.point_type,
|
|
48
|
+
)
|