ositah 24.4.dev1__py3-none-any.whl → 24.7.dev1__py3-none-any.whl

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.
Files changed (47) hide show
  1. {ositah-24.4.dev1.dist-info → ositah-24.7.dev1.dist-info}/METADATA +1 -1
  2. ositah-24.7.dev1.dist-info/RECORD +6 -0
  3. {ositah-24.4.dev1.dist-info → ositah-24.7.dev1.dist-info}/WHEEL +1 -1
  4. ositah/__init__.py +0 -0
  5. ositah/app.py +0 -17
  6. ositah/apps/__init__.py +0 -0
  7. ositah/apps/analysis.py +0 -774
  8. ositah/apps/configuration/__init__.py +0 -0
  9. ositah/apps/configuration/callbacks.py +0 -917
  10. ositah/apps/configuration/main.py +0 -542
  11. ositah/apps/configuration/parameters.py +0 -74
  12. ositah/apps/configuration/tools.py +0 -112
  13. ositah/apps/export.py +0 -1172
  14. ositah/apps/validation/__init__.py +0 -0
  15. ositah/apps/validation/callbacks.py +0 -240
  16. ositah/apps/validation/main.py +0 -89
  17. ositah/apps/validation/parameters.py +0 -25
  18. ositah/apps/validation/tables.py +0 -654
  19. ositah/apps/validation/tools.py +0 -533
  20. ositah/assets/arrow_down_up.svg +0 -4
  21. ositah/assets/ositah.css +0 -54
  22. ositah/assets/sort_ascending.svg +0 -5
  23. ositah/assets/sort_descending.svg +0 -6
  24. ositah/assets/sorttable.js +0 -499
  25. ositah/main.py +0 -449
  26. ositah/ositah.example.cfg +0 -215
  27. ositah/static/style.css +0 -54
  28. ositah/templates/base.html +0 -22
  29. ositah/templates/bootstrap_login.html +0 -38
  30. ositah/templates/login_form.html +0 -27
  31. ositah/utils/__init__.py +0 -0
  32. ositah/utils/agents.py +0 -117
  33. ositah/utils/authentication.py +0 -287
  34. ositah/utils/cache.py +0 -19
  35. ositah/utils/core.py +0 -13
  36. ositah/utils/exceptions.py +0 -64
  37. ositah/utils/hito_db.py +0 -51
  38. ositah/utils/hito_db_model.py +0 -245
  39. ositah/utils/menus.py +0 -339
  40. ositah/utils/period.py +0 -135
  41. ositah/utils/projects.py +0 -1175
  42. ositah/utils/teams.py +0 -42
  43. ositah/utils/utils.py +0 -459
  44. ositah-24.4.dev1.dist-info/RECORD +0 -46
  45. {ositah-24.4.dev1.dist-info → ositah-24.7.dev1.dist-info}/LICENSE +0 -0
  46. {ositah-24.4.dev1.dist-info → ositah-24.7.dev1.dist-info}/entry_points.txt +0 -0
  47. {ositah-24.4.dev1.dist-info → ositah-24.7.dev1.dist-info}/top_level.txt +0 -0
ositah/main.py DELETED
@@ -1,449 +0,0 @@
1
- #!/usr/bin/env python
2
-
3
- """
4
- Application to display the declared time on projects by agents in Hito and to allow validation of
5
- these declarations by the line managers.
6
- """
7
-
8
- import argparse
9
- import os
10
- from datetime import datetime, timedelta
11
-
12
- import dash_bootstrap_components as dbc
13
- from dash import dcc, html
14
- from dash.dependencies import Input, Output, State
15
- from flask import session
16
-
17
- from ositah.app import app
18
- from ositah.apps.analysis import analysis_layout
19
- from ositah.apps.configuration.main import configuration_layout
20
- from ositah.apps.export import export_layout
21
- from ositah.apps.validation.main import validation_layout
22
- from ositah.utils.agents import get_agent_by_email
23
- from ositah.utils.authentication import (
24
- LOGIN_URL,
25
- LOGOUT_URL,
26
- SESSION_MAX_DURATION,
27
- configure_multipass_ldap,
28
- identity_list,
29
- multipass,
30
- protect_views,
31
- )
32
- from ositah.utils.menus import (
33
- TEAM_SELECTED_VALUE_ID,
34
- TEAM_SELECTION_DATE_ID,
35
- VALIDATION_PERIOD_SELECTED_ID,
36
- ositah_jumbotron,
37
- )
38
- from ositah.utils.utils import (
39
- AUTHORIZED_ROLES,
40
- HITO_ROLE_TEAM_MGR,
41
- TEAM_LIST_ALL_AGENTS,
42
- GlobalParams,
43
- define_config_params,
44
- )
45
-
46
- # Minimum role to access the configuration page
47
- CONFIGURATION_MIN_ROLE = HITO_ROLE_TEAM_MGR
48
-
49
- CONFIG_FILE_NAME_DEFAULT = "ositah.cfg"
50
-
51
- SIDEBAR_WIDTH = 16
52
- SIDEBAR_HREF_HOME = "/"
53
- SIDEBAR_HREF_ANALYSIS = "/analysis"
54
- SIDEBAR_HREF_CONFIGURATION = "/configuration"
55
- SIDEBAR_HREF_NSIP_EXPORT = "/export"
56
- SIDEBAR_HREF_VALIDATION = "/validation"
57
- # SIDEBAR_HREF_ALL entry order must match render_page_content callback
58
- # output order
59
- SIDEBAR_HREF_ALL = [
60
- SIDEBAR_HREF_ANALYSIS,
61
- SIDEBAR_HREF_CONFIGURATION,
62
- SIDEBAR_HREF_NSIP_EXPORT,
63
- SIDEBAR_HREF_VALIDATION,
64
- LOGOUT_URL,
65
- SIDEBAR_HREF_HOME,
66
- LOGIN_URL,
67
- ]
68
-
69
- MENU_ID_ANALYSIS = "analysis-menu"
70
- MENU_ID_CONFIGURATION = "configuration-menu"
71
- MENU_ID_EXPORT = "export-menu"
72
- MENU_ID_HOME = "home-menu"
73
- MENU_ID_LOGIN = "login-menu"
74
- MENU_ID_LOGOUT = "logout-menu"
75
- MENU_ID_VALIDATION = "validation-menu"
76
-
77
-
78
- # the style arguments for the sidebar. We use position:fixed and a fixed width
79
- SIDEBAR_STYLE = {
80
- "position": "fixed",
81
- "top": 0,
82
- "left": 0,
83
- "bottom": 0,
84
- "width": f"{SIDEBAR_WIDTH}rem",
85
- "padding": "2rem 1rem",
86
- "background-color": "#f8f9fa",
87
- }
88
-
89
- # the styles for the main content position it to the right of the sidebar and
90
- # add some padding.
91
- CONTENT_STYLE = {
92
- "margin-left": f"{SIDEBAR_WIDTH+2}rem",
93
- "margin-right": "2rem",
94
- "padding": "2rem 1rem",
95
- }
96
-
97
-
98
- # Get default configuration file: look first in the current directory and if not
99
- # found use the application directory.
100
- def default_config_path() -> str:
101
- config_file = f"{os.getcwd()}/{CONFIG_FILE_NAME_DEFAULT}"
102
- if not os.path.exists(config_file):
103
- config_file = f"{os.path.dirname(os.path.abspath(__file__))}/{CONFIG_FILE_NAME_DEFAULT}"
104
-
105
- return config_file
106
-
107
-
108
- # URL not found jumbotron
109
- def url_not_found(path):
110
- return ositah_jumbotron(
111
- "404: Not found",
112
- f"URL {path} was not recognised...",
113
- title_class="text-danger",
114
- )
115
-
116
-
117
- # valid role missing jumbotron
118
- def valid_role_missing(msg):
119
- return ositah_jumbotron(
120
- "You don't have a valid Hito role to OSITAH",
121
- msg,
122
- title_class="text-warning",
123
- )
124
-
125
-
126
- @app.callback(
127
- [
128
- Output("page-content", "children"),
129
- Output("login-info", "children"),
130
- # Output order must match SIDEBAR_HREF_ALL entry order
131
- Output(MENU_ID_ANALYSIS, "disabled"),
132
- Output(MENU_ID_CONFIGURATION, "disabled"),
133
- Output(MENU_ID_EXPORT, "disabled"),
134
- Output(MENU_ID_VALIDATION, "disabled"),
135
- Output(MENU_ID_LOGOUT, "disabled"),
136
- ],
137
- Input("url", "pathname"),
138
- State("login-info", "children"),
139
- )
140
- def render_page_content(pathname, login_menu):
141
- """
142
- Function called to render the main page in OSITAH. It is also in charge of managing user
143
- sessions.
144
-
145
- :param pathname:
146
- :param login_menu:
147
- :return: callback output
148
- """
149
-
150
- from ositah.utils.authentication import remove_session
151
- from ositah.utils.hito_db import get_db, new_uuid
152
- from ositah.utils.hito_db_model import OSITAHSession, Team
153
-
154
- global_params = GlobalParams()
155
- logged_in_user = login_menu
156
- menus_disabled = True
157
-
158
- db = get_db()
159
- OSITAHSession.__table__.create(db.session.bind, checkfirst=True)
160
-
161
- user_authenticated = False
162
- if "user_id" in session:
163
- # 'user_id' is defined by Multipass if the login was successful
164
- if "uid" in session and "user_email" in session:
165
- # The user already logged in successfully once, check if the session is among the known
166
- # valid sessions. As id and email columns have a unique constraint, the query can
167
- # return only 0 or 1 value
168
- saved_session = OSITAHSession.query.filter(
169
- OSITAHSession.id == str(session["uid"]),
170
- OSITAHSession.email == session["user_email"],
171
- ).first()
172
- if saved_session:
173
- current_time = datetime.now()
174
- if current_time > saved_session.last_use + timedelta(hours=SESSION_MAX_DURATION):
175
- remove_session()
176
- else:
177
- saved_session.last_use = current_time
178
- db.session.commit()
179
- user_authenticated = True
180
- if not user_authenticated and session["user_id"] in identity_list:
181
- # Session has been fully initialized yet: do it and save it
182
- session["user_email"] = identity_list[session["user_id"]].email
183
- session["uid"] = new_uuid()
184
- this_session = OSITAHSession(
185
- id=str(session["uid"]),
186
- email=session["user_email"],
187
- last_use=datetime.now(),
188
- )
189
- db.session.add(this_session)
190
- db.session.commit()
191
- user_authenticated = True
192
-
193
- if user_authenticated:
194
- user_session_data = global_params.session_data
195
- user = get_agent_by_email(session["user_email"])
196
- role_ok = False
197
- user_roles = user.roles
198
- for role in AUTHORIZED_ROLES:
199
- if role in user_roles:
200
- role_ok = True
201
- user_session_data.role = role
202
- break
203
- if role_ok:
204
- if not user_session_data.agent_teams:
205
- if role == HITO_ROLE_TEAM_MGR:
206
- # For a team manager, show only the teams he/she is a manager
207
- teams = Team.query.filter(Team.managers.any(email=session["user_email"])).all()
208
- if len(teams) == 0:
209
- # A user with role ROLE_RESP but is not the manager of any team is degraded
210
- # to ROLE_AGENT
211
- role_ok = False
212
- role_not_ok_msg = (
213
- f"{user.prenom} {user.nom} n'est" " responsable d'aucune équipe"
214
- )
215
- team_list = []
216
- else:
217
- teams.extend(
218
- Team.query.filter(
219
- Team.children_managers.any(email_auth=session["user_email"])
220
- ).all()
221
- )
222
- team_list = sorted([t.nom for t in teams])
223
- else:
224
- # For other allowed roles, show all teams and add an entry for all agents
225
- teams = Team.query.all()
226
- team_list = sorted([t.nom for t in teams])
227
- team_list.insert(0, TEAM_LIST_ALL_AGENTS)
228
- user_session_data.add_teams(team_list, sort_list=False)
229
- logged_in_user = f"logged in as {user.prenom} {user.nom}"
230
- menus_disabled = False
231
- else:
232
- role_not_ok_msg = (
233
- f"{user.prenom} {user.nom} n'a pas de role Hito approprié"
234
- " ({', '.join(AUTHORIZED_ROLES)})"
235
- )
236
- else:
237
- logged_in_user = login_menu_link()
238
- role_ok = True
239
-
240
- return_values = [logged_in_user]
241
- for i in range(len(SIDEBAR_HREF_ALL) - 2):
242
- if (
243
- SIDEBAR_HREF_ALL[i] == SIDEBAR_HREF_CONFIGURATION
244
- and user_authenticated
245
- and AUTHORIZED_ROLES.index(user_session_data.role)
246
- > AUTHORIZED_ROLES.index(CONFIGURATION_MIN_ROLE)
247
- ):
248
- disable_flag = True
249
- else:
250
- disable_flag = menus_disabled
251
- return_values.append(disable_flag)
252
- if not role_ok:
253
- return_values.insert(0, valid_role_missing(role_not_ok_msg))
254
- return return_values
255
-
256
- if user_authenticated:
257
- if pathname == SIDEBAR_HREF_VALIDATION:
258
- return_values.insert(0, validation_layout())
259
- return return_values
260
- elif pathname == SIDEBAR_HREF_ANALYSIS:
261
- return_values.insert(0, analysis_layout())
262
- return return_values
263
- elif pathname == SIDEBAR_HREF_NSIP_EXPORT:
264
- return_values.insert(0, export_layout())
265
- return return_values
266
- elif pathname == SIDEBAR_HREF_CONFIGURATION:
267
- return_values.insert(0, configuration_layout())
268
- return return_values
269
-
270
- # Display the same message based on the login state for all valid URLs if none matched
271
- # previously
272
- if pathname in SIDEBAR_HREF_ALL:
273
- if user_authenticated:
274
- return_values.insert(
275
- 0,
276
- html.P("Sélectionner ce que vous souhaitez faire dans le menu principal"),
277
- )
278
- else:
279
- return_values.insert(0, html.P("Veuillez vous authentifier"))
280
- return return_values
281
-
282
- # If the user tries to reach a different page, return a 404 message
283
- return_values.insert(0, url_not_found(pathname))
284
- return return_values
285
-
286
-
287
- def login_menu_link():
288
- """
289
- :return: graphic object for login menu
290
- """
291
-
292
- return dbc.NavLink("Login", id=MENU_ID_LOGIN, href=LOGIN_URL, external_link=True)
293
-
294
-
295
- def make_app(environ=None, start_response=None, options=None):
296
- """
297
- Function to create the application without running it. It is the main entry point when called
298
- as a uWSGI application (from gunicorn or uwswgi for example). Must return the Flask application
299
- server.
300
-
301
- :param environ: environment variables received from the uWSGI server
302
- :param start_response: function received from the uWSGI server (not used)
303
- :param options: parser options (will be initialized to sensible values when called from a uSWGI
304
- server)
305
- :return: Flask application server
306
- """
307
-
308
- # Initialize options to sensible values: required when called from a uWSGI server
309
- if options is None:
310
- options = argparse.Namespace()
311
- options.configuration_file = default_config_path()
312
- options.debug = True
313
-
314
- config = define_config_params(options.configuration_file)
315
-
316
- configure_multipass_ldap(app.server, config["server"]["authentication"]["provider_name"])
317
- multipass.init_app(app.server)
318
-
319
- app.server.secret_key = "ositah-dashboard"
320
-
321
- protect_views(app)
322
-
323
- # Import from hito_db must not be done after configuration has been loaded
324
- from ositah.utils.hito_db import get_db
325
-
326
- # Initialize DB connection by calling get_db()
327
- get_db(init_session=False)
328
-
329
- sidebar = html.Div(
330
- [
331
- html.H2("OSITAH", className="display-4"),
332
- html.Hr(),
333
- html.P("Suivi des déclarations de temps", className="lead"),
334
- dbc.Nav(
335
- [
336
- # external_link=True is required for the callback on dcc.Location to work
337
- html.Div(login_menu_link(), id="login-info"),
338
- dbc.NavLink(
339
- "Logout",
340
- id=MENU_ID_LOGOUT,
341
- href=LOGOUT_URL,
342
- disabled=True,
343
- external_link=True,
344
- ),
345
- ],
346
- vertical="md",
347
- ),
348
- html.Hr(),
349
- dbc.Nav(
350
- [
351
- dbc.NavLink(
352
- "Home",
353
- id=MENU_ID_HOME,
354
- href=SIDEBAR_HREF_HOME,
355
- active="exact",
356
- ),
357
- dbc.NavLink(
358
- "Suvi / Validation",
359
- id=MENU_ID_VALIDATION,
360
- href=SIDEBAR_HREF_VALIDATION,
361
- active="exact",
362
- disabled=True,
363
- ),
364
- dbc.NavLink(
365
- "Analyse",
366
- id=MENU_ID_ANALYSIS,
367
- href=SIDEBAR_HREF_ANALYSIS,
368
- active="exact",
369
- disabled=True,
370
- ),
371
- dbc.NavLink(
372
- "Export NSIP",
373
- id=MENU_ID_EXPORT,
374
- href=SIDEBAR_HREF_NSIP_EXPORT,
375
- active="exact",
376
- disabled=True,
377
- ),
378
- dbc.NavLink(
379
- "Configuration",
380
- id=MENU_ID_CONFIGURATION,
381
- href=SIDEBAR_HREF_CONFIGURATION,
382
- active="exact",
383
- disabled=True,
384
- ),
385
- ],
386
- vertical="md",
387
- pills=True,
388
- ),
389
- dcc.Store(id=TEAM_SELECTED_VALUE_ID, data=""),
390
- dcc.Store(id=TEAM_SELECTION_DATE_ID, data=""),
391
- dcc.Store(id=VALIDATION_PERIOD_SELECTED_ID, data=""),
392
- ],
393
- style=SIDEBAR_STYLE,
394
- )
395
-
396
- content = html.Div(id="page-content", style=CONTENT_STYLE)
397
-
398
- app.layout = html.Div([dcc.Location(id="url"), sidebar, content])
399
-
400
- return app.server
401
-
402
-
403
- def main():
404
- """
405
- Main entry point when executing the application from the command line
406
-
407
- :return: exit status
408
- """
409
-
410
- global_params = GlobalParams()
411
-
412
- DEBUG_DASH = "dash"
413
- DEBUG_SQLALCHEMY = "db"
414
- DEBUG_ALL = "all"
415
- DEBUG_NONE = "none"
416
-
417
- # parser must be run here to avoid messing up with gunicorn
418
- parser = argparse.ArgumentParser()
419
- parser.add_argument(
420
- "--configuration-file",
421
- default=default_config_path(),
422
- help=f"Configuration file (D: {default_config_path()})",
423
- )
424
- parser.add_argument(
425
- "--debug",
426
- choices=[DEBUG_DASH, DEBUG_SQLALCHEMY, DEBUG_ALL, DEBUG_NONE],
427
- default=DEBUG_NONE,
428
- help="Enable debugging mode in Dash and/or SQLAlchemy (do not use in production)",
429
- )
430
- options = parser.parse_args()
431
-
432
- dash_debug = False
433
- sqlalchemy_debug = False
434
- if options.debug == DEBUG_DASH or options.debug == DEBUG_ALL:
435
- dash_debug = True
436
- if options.debug == DEBUG_SQLALCHEMY or options.debug == DEBUG_ALL:
437
- sqlalchemy_debug = "debug"
438
-
439
- make_app(options=options)
440
-
441
- # If --debug, enable SQLAlchemy verbose mode
442
- if sqlalchemy_debug:
443
- app.server.config["SQLALCHEMY_ECHO"] = True
444
-
445
- app.run_server(debug=dash_debug, port=global_params.port)
446
-
447
-
448
- if __name__ == "__main__":
449
- exit(main())
ositah/ositah.example.cfg DELETED
@@ -1,215 +0,0 @@
1
- # Configuration file for OSITAH application
2
-
3
- # Where to read the data
4
- hito:
5
- db:
6
- # type muste be sqlite or mysql
7
- #type: sqlite
8
- type: mysql
9
- # location must be a filename for sqlite or server/database for mysql
10
- #location: 'c:\temp\hito-dev.sqlite'
11
- location: 'localhost/hito'
12
- user: hitousery
13
- password: *verysecret*
14
- # After this time (in seconds), DB connection is recycled
15
- inactivity_timeout: 900
16
- # For some unidentified reason, in SQLite, "stagiaire" carriere type is not found with an exact match...
17
- agent_query: |
18
- SELECT
19
- DISTINCT(agent.id)
20
- , agent.nom
21
- , agent.prenom
22
- , agent.team_id as team_id
23
- , team.nom as team
24
- , agent.statut as statut
25
- , agent.email as email
26
- , agent.corps_exercice_metier as cem
27
- , CASE
28
- WHEN agent.email_auth IS NULL THEN agent.email
29
- ELSE agent.email_auth
30
- END AS email_auth
31
- FROM
32
- agent
33
- LEFT JOIN team on team.id = agent.team_id
34
- JOIN carriere on carriere.agent_id = agent.id
35
- WHERE
36
- agent.archive = 0
37
- AND
38
- carriere.date_debut = (
39
- SELECT MAX(c.date_debut)
40
- FROM carriere AS c
41
- WHERE
42
- agent.id = c.agent_id
43
- AND
44
- (c.type IN ("apprenti", "cdd", "emeritat", "stagiaire", "visiteur") OR c.type LIKE "arrivee%" OR c.type LIKE "stagiaire%")
45
- )
46
- AND
47
- carriere.date_debut <= $$TODAY$$
48
- # Patterns to identify the different activity categories from the activity name
49
- categories:
50
- consultance: 'Consultances & Expertises'
51
- enseignement: 'Enseignement Supérieur'
52
- local_project: 'Local projects'
53
- service: 'Services & Support'
54
- # Time unit (default is hours for categories not listed). Supported values h(our), w(eek)
55
- time_unit:
56
- local_project: w
57
- nsip_project: w
58
- service: w
59
- # Column titles to use when displying the information about categories and agents
60
- titles:
61
- consultance: 'Consultance'
62
- declarations_number: 'Déclarations effectuées'
63
- enseignement: 'Enseignement'
64
- fullname: 'Agent'
65
- local_project: 'projets locaux'
66
- missings_number: 'Déclarations obligatoires manquantes'
67
- nsip_project: 'projets NSIP'
68
- percent_global: 'Temps déclarés (%)'
69
- service: 'Service'
70
- statut: 'Statut'
71
- team: 'Equipe'
72
-
73
- # Web server information
74
- server:
75
- port: 9999
76
- authentication:
77
- ldap:
78
- # uri can be space-separated list
79
- uri: 'ldaps://ijclabad1.ijclab.in2p3.fr ldaps://ijclabad2.ijclab.in2p3.fr ldaps://ccijclabad01.ijclab.in2p3.fr'
80
- base_dn: 'ou=ijclab,dc=ijclab,dc=in2p3,dc=fr'
81
- bind_dn: 'CN=Non-Interactive Queries,OU=SI,OU=Services techniques,OU=Laboratoire,DC=lal,DC=in2p3,DC=fr'
82
- password: 'ldap_bind_password'
83
- provider_name: "MyLab account"
84
-
85
- # Options related to declarations
86
- declaration:
87
- # Default date must be a date included into the selected validation period. It is a default, if no other explicitly select
88
- #default_date: 2021-07-01
89
- # max_hours specifies the upper valid value for activities declared in hours
90
- max_hours: 400
91
- # Agent statut whose declaration is not mandatory
92
- optional_statutes:
93
- - benevole
94
- - emerite
95
- - stagiaire
96
- - visiteur
97
- # Team who are not required to declare: values must match the beginning of the team name
98
- optional_teams:
99
- - Administration
100
- - Support
101
- # Thresholds used to mark declarations as low, suspect or good
102
- # The value is the upper bound for the corresonding class
103
- thresholds:
104
- low: 50
105
- suspect: 80
106
- good: 100
107
-
108
- # Information related to validation
109
- validation:
110
- override_period:
111
- - ROLE_SUPER_ADMIN
112
- - ROLE_PROJECT_MANAGER
113
-
114
- # Users with specific rights
115
- roles:
116
- # List users (with their connection email) who are given a read-only access to OSITAH (no validation right)
117
- read-only:
118
- - user@my.dom.ain
119
-
120
- # NSIP related parameters
121
-
122
- nsip:
123
- # The following sections configures information about NSIP service
124
- # For each part of the API, there must be a base URL and some operation sub-urls
125
- agent_api:
126
- base_url: /api_labo/agent
127
- declaration_add: /declaration/create
128
- declaration_delete: /declaration/delete
129
- declaration_update: /declaration/update
130
- institute_api:
131
- base_url: /api_institut
132
- declaration_period_list: /declaration_period/list
133
- lab_api:
134
- base_url: /api_labo
135
- agent_list: /agent/list
136
- declaration_list: /declaration/list
137
- project_list: /project/list
138
- reference_list: /reference/list
139
- server_url: https://nsip.in2p3.fr
140
- token: nsip_lab_token
141
-
142
- # teaching dictionary allows to define a ratio to apply to teaching activities.
143
- # It also allows to define (optionally) a list of CEM that this ratio must
144
- # be applied to (instead of all agents).
145
- # master allows to define the masterproject identifying teaching activities
146
- # (default: Enseignement Supérieur)
147
- teaching:
148
- masterproject: Enseignement Supérieur
149
- ratio: 4.4
150
- cem:
151
- - cem_enseignant_chercheur
152
-
153
- # Match against NSIP reference types to define the OSITAH masterproject.
154
- # A reference with no value will cause the entry to be ignored by OSITAH.
155
- # Reference types can be regex.
156
- reference_masterprojects:
157
- consultancyexpertise: Consultances & Expertises
158
- highereducation: Enseignement Supérieur
159
- servicesupport: Services & Support
160
-
161
-
162
- # project_teams allow to define a list of teams for a project
163
- # The project name is matched against the list of defined projects and must be a regex matching
164
- # the beginning of the project name. A team can be specified as a regex.
165
- # Example below is for IJCLab: update according to your needs.
166
- project_teams:
167
- Consultances & Expertises:
168
- - .*
169
- Enseignement Supérieur:
170
- - Accélérateurs.*
171
- - A2C.*
172
- - Direction
173
- - Energie.*
174
- - Ingénierie.*
175
- - Nucléaire.*
176
- - PHE.*
177
- - Plateforme.*
178
- - Santé.*
179
- - Théorie.*
180
- Services & Support / Assurance-Qualité:
181
- - Support - Projets
182
- Services & Support / Budget-Finances:
183
- - Administration - Division financière
184
- Services & Support / Communication-Documentation:
185
- - Support - Communication
186
- #Services & Support / Environnement:
187
- Services & Support / Formation:
188
- - Support - Enseignement
189
- #Services & Support / Hygiène-Sécurité:
190
- Services & Support / Management:
191
- - .*
192
- Services & Support / Partenariat:
193
- - Support - STIRI
194
- Services & Support / Patrimoine:
195
- - Support - Infrastructure
196
- Services & Support / Radioprotection:
197
- - Support - Service SPR
198
- Services & Support / Ressources Humaines:
199
- - Administration.* - RH.*
200
- Services & Support / Secrétariat:
201
- - Direction - Assistantes
202
- #Services & Support / Services Généraux:
203
- Services & Support / Support-Biologie:
204
- - Santé.*
205
- Services & Support / Support-Electronique:
206
- - Ingénierie - Electronique.*
207
- Services & Support / Support-Informatique:
208
- - Ingénierie - Informatique
209
- Services & Support / Support-Instrumentation:
210
- - Ingénierie - Détecteurs.*
211
- Services & Support / Support-Mécanique:
212
- - Ingénierie - Mécanique
213
- #Services & Support / Sûreté:
214
- Services & Support / Valorisation:
215
- - Support - STIRI