Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
SCODOC_R6A06
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Paul Milleville
SCODOC_R6A06
Commits
06727f1b
Commit
06727f1b
authored
1 year ago
by
Iziram
Browse files
Options
Downloads
Patches
Plain Diff
gen_api_map fini + annotation QUERY assiduites/justificatifs
parent
c37a92aa
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
app/api/assiduites.py
+54
-4
54 additions, 4 deletions
app/api/assiduites.py
app/api/justificatifs.py
+36
-3
36 additions, 3 deletions
app/api/justificatifs.py
tools/create_api_map.py
+131
-50
131 additions, 50 deletions
tools/create_api_map.py
with
221 additions
and
57 deletions
app/api/assiduites.py
+
54
−
4
View file @
06727f1b
...
...
@@ -161,8 +161,17 @@ def count_assiduites(
query?est_just=f
query?est_just=t
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
moduleimpl_id:<int:moduleimpl_id>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
formsemestre_id:<int:formsemestre_id>
metric:<array[string]:metric>
split:<bool:split>
"""
...
...
@@ -253,6 +262,15 @@ def assiduites(etudid: int = None, nip=None, ine=None, with_query: bool = False)
query?est_just=f
query?est_just=t
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
moduleimpl_id:<int:moduleimpl_id>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
formsemestre_id:<int:formsemestre_id>
"""
...
...
@@ -329,6 +347,16 @@ def assiduites_group(with_query: bool = False):
query?est_just=f
query?est_just=t
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
moduleimpl_id:<int:moduleimpl_id>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
etudids:<array[int]:etudids
formsemestre_id:<int:formsemestre_id>
"""
...
...
@@ -388,7 +416,16 @@ def assiduites_group(with_query: bool = False):
@as_json
@permission_required
(
Permission
.
ScoView
)
def
assiduites_formsemestre
(
formsemestre_id
:
int
,
with_query
:
bool
=
False
):
"""
Retourne toutes les assiduités du formsemestre
"""
"""
Retourne toutes les assiduités du formsemestre
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
moduleimpl_id:<int:moduleimpl_id>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
"""
# Récupération du formsemestre à partir du formsemestre_id
formsemestre
:
FormSemestre
=
None
...
...
@@ -438,7 +475,20 @@ def assiduites_formsemestre(formsemestre_id: int, with_query: bool = False):
def
count_assiduites_formsemestre
(
formsemestre_id
:
int
=
None
,
with_query
:
bool
=
False
):
"""
Comptage des assiduités du formsemestre
"""
"""
Comptage des assiduités du formsemestre
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
moduleimpl_id:<int:moduleimpl_id>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
formsemestre_id:<int:formsemestre_id>
metric:<array[string]:metric>
split:<bool:split>
"""
# Récupération du formsemestre à partir du formsemestre_id
formsemestre
:
FormSemestre
=
None
...
...
This diff is collapsed.
Click to expand it.
app/api/justificatifs.py
+
36
−
3
View file @
06727f1b
...
...
@@ -3,8 +3,8 @@
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
# See LICENSE
##############################################################################
"""
ScoDoc 9 API : Justificatifs
"""
"""
ScoDoc 9 API : Justificatifs
"""
from
datetime
import
datetime
from
flask_json
import
as_json
...
...
@@ -113,6 +113,16 @@ def justificatifs(etudid: int = None, nip=None, ine=None, with_query: bool = Fal
user_id (l
'
id de l
'
auteur du justificatif)
query?user_id=[int]
ex query?user_id=3
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
"""
# Récupération de l'étudiant
etud
:
Identite
=
tools
.
get_etud
(
etudid
,
nip
,
ine
)
...
...
@@ -154,6 +164,17 @@ def justificatifs_dept(dept_id: int = None, with_query: bool = False):
"""
Renvoie tous les justificatifs d
'
un département
(en ajoutant un champ
"
formsemestre
"
si possible)
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
"""
# Récupération du département et des étudiants du département
...
...
@@ -225,7 +246,19 @@ def _set_sems(justi: Justificatif, restrict: bool) -> dict:
@as_json
@permission_required
(
Permission
.
ScoView
)
def
justificatifs_formsemestre
(
formsemestre_id
:
int
,
with_query
:
bool
=
False
):
"""
Retourne tous les justificatifs du formsemestre
"""
"""
Retourne tous les justificatifs du formsemestre
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
"""
# Récupération du formsemestre
formsemestre
:
FormSemestre
=
None
...
...
This diff is collapsed.
Click to expand it.
tools/create_api_map.py
+
131
−
50
View file @
06727f1b
import
xml.etree.ElementTree
as
ET
import
re
class
COLORS
:
...
...
@@ -6,16 +7,16 @@ class COLORS:
GREEN
=
"
rgb(165,214,165)
"
PINK
=
"
rgb(230,156,190)
"
GREY
=
"
rgb(224,224,224)
"
ORANGE
=
"
rgb(253,191,111)
"
class
Token
:
def
__init__
(
self
,
name
,
method
=
"
GET
"
,
query
=
None
,
leaf
=
False
):
def
__init__
(
self
,
name
,
method
=
"
GET
"
,
query
=
None
,
leaf
=
False
,
func_name
=
""
):
self
.
children
:
list
[
"
Token
"
]
=
[]
self
.
name
:
str
=
name
self
.
method
:
str
=
method
self
.
query
:
dict
[
str
,
str
]
=
query
or
{}
self
.
force_leaf
:
bool
=
leaf
self
.
func_name
=
""
def
add_child
(
self
,
child
):
self
.
children
.
append
(
child
)
...
...
@@ -56,17 +57,23 @@ class Token:
):
group
=
ET
.
Element
(
"
g
"
)
color
=
COLORS
.
BLUE
if
self
.
force_leaf
or
self
.
is_leaf
():
if
self
.
is_leaf
():
if
self
.
method
==
"
GET
"
:
color
=
COLORS
.
GREEN
elif
self
.
method
==
"
POST
"
:
color
=
COLORS
.
PINK
# if self.force_leaf and not self.is_leaf():
# color = COLORS.ORANGE
element
=
_create_svg_element
(
self
.
name
,
color
)
element
.
set
(
"
transform
"
,
f
"
translate(
{
x_offset
}
,
{
y_offset
}
)
"
)
current_start_coords
,
current_end_coords
=
_get_anchor_coords
(
element
,
x_offset
,
y_offset
)
href
=
"
#
"
+
self
.
func_name
.
replace
(
"
_
"
,
"
-
"
)
if
self
.
query
:
href
+=
"
-query
"
question_mark_group
=
_create_question_mark_group
(
current_end_coords
,
href
)
group
.
append
(
element
)
# Add an arrow from the parent element to the current element
...
...
@@ -91,9 +98,10 @@ class Token:
current_end_coords
=
_get_anchor_coords
(
group
,
0
,
0
)[
1
]
query_y_offset
=
y_offset
ampersand_start_coords
=
None
ampersand_end_coords
=
None
query_sub_element
=
ET
.
Element
(
"
g
"
)
for
key
,
value
in
self
.
query
.
items
():
sub_group
=
ET
.
Element
(
"
g
"
)
# <param>=<value>
translate_x
=
x_offset
+
x_step
...
...
@@ -103,14 +111,14 @@ class Token:
"
transform
"
,
f
"
translate(
{
translate_x
}
,
{
query_y_offset
}
)
"
,
)
group
.
append
(
param_el
)
sub_
group
.
append
(
param_el
)
# add Arrow from "query" to element
coords
=
(
current_end_coords
,
_get_anchor_coords
(
param_el
,
translate_x
,
query_y_offset
)[
0
],
)
group
.
append
(
_create_arrow
(
*
coords
))
sub_
group
.
append
(
_create_arrow
(
*
coords
))
# =
equal_el
=
_create_svg_element
(
"
=
"
,
COLORS
.
GREY
)
...
...
@@ -119,7 +127,7 @@ class Token:
"
transform
"
,
f
"
translate(
{
translate_x
}
,
{
query_y_offset
}
)
"
,
)
group
.
append
(
equal_el
)
sub_
group
.
append
(
equal_el
)
# <value>
value_el
=
_create_svg_element
(
value
,
COLORS
.
GREEN
)
...
...
@@ -132,7 +140,7 @@ class Token:
"
transform
"
,
f
"
translate(
{
translate_x
}
,
{
query_y_offset
}
)
"
,
)
group
.
append
(
value_el
)
sub_
group
.
append
(
value_el
)
if
len
(
self
.
query
)
==
1
:
continue
ampersand_group
=
_create_svg_element
(
"
&
"
,
"
rgb(224,224,224)
"
)
...
...
@@ -145,27 +153,15 @@ class Token:
"
transform
"
,
f
"
translate(
{
translate_x
}
,
{
query_y_offset
}
)
"
,
)
group
.
append
(
ampersand_group
)
# Track the start and end coordinates of the ampersands
if
ampersand_start_coords
is
None
:
ampersand_start_coords
=
_get_anchor_coords
(
ampersand_group
,
translate_x
,
query_y_offset
)[
1
]
ampersand_end_coords
=
_get_anchor_coords
(
ampersand_group
,
translate_x
,
query_y_offset
)[
1
]
# Draw line connecting all ampersands
if
ampersand_start_coords
and
ampersand_end_coords
and
len
(
self
.
query
)
>
1
:
line
=
_create_line
(
ampersand_start_coords
,
ampersand_end_coords
)
group
.
append
(
line
)
sub_group
.
append
(
ampersand_group
)
query_y_offset
+=
y_step
y_offset
=
query_y_offset
query_sub_element
.
append
(
sub_group
)
group
.
append
(
query_sub_element
)
y_offset
=
query_y_offset
current_y_offset
=
y_offset
for
child
in
self
.
children
:
rel_x_offset
=
x_offset
+
_get_group_width
(
group
)
if
len
(
self
.
children
)
>
1
:
...
...
@@ -181,23 +177,11 @@ class Token:
group
.
append
(
child_group
)
current_y_offset
+=
child
.
get_height
(
y_step
)
return
group
def
_create_line
(
start_coords
,
end_coords
):
start_x
,
start_y
=
start_coords
end_x
,
end_y
=
end_coords
path_data
=
f
"
M
{
start_x
}
,
{
start_y
}
L
{
start_x
+
20
}
,
{
start_y
}
L
{
start_x
+
20
}
,
{
end_y
}
L
{
end_x
}
,
{
end_y
}
"
# add `?` circle a:href to element
if
self
.
force_leaf
or
self
.
is_leaf
():
group
.
append
(
question_mark_group
)
path
=
ET
.
Element
(
"
path
"
,
{
"
d
"
:
path_data
,
"
style
"
:
"
stroke:black;stroke-width:2;fill:none
"
,
},
)
return
path
return
group
def
_create_svg_element
(
text
,
color
=
"
rgb(230,156,190)
"
):
...
...
@@ -289,6 +273,51 @@ def _get_group_width(group):
return
sum
(
_get_element_width
(
child
)
for
child
in
group
)
def
_create_question_mark_group
(
coords
,
href
):
x
,
y
=
coords
radius
=
10
# Radius of the circle
y
-=
radius
*
2
font_size
=
17
# Font size of the question mark
group
=
ET
.
Element
(
"
g
"
)
# Create the circle
ET
.
SubElement
(
group
,
"
circle
"
,
{
"
cx
"
:
str
(
x
),
"
cy
"
:
str
(
y
),
"
r
"
:
str
(
radius
),
"
fill
"
:
COLORS
.
GREY
,
"
stroke
"
:
"
black
"
,
"
stroke-width
"
:
"
2
"
,
},
)
# Create the link element
link
=
ET
.
Element
(
"
a
"
,
{
"
href
"
:
href
})
# Create the text element
text_element
=
ET
.
SubElement
(
link
,
"
text
"
,
{
"
x
"
:
str
(
x
+
1
),
"
y
"
:
str
(
y
+
font_size
/
3
),
# Adjust to vertically center the text
"
text-anchor
"
:
"
middle
"
,
# Center the text horizontally
"
font-family
"
:
"
Arial
"
,
"
font-size
"
:
str
(
font_size
),
"
fill
"
:
"
black
"
,
},
)
text_element
.
text
=
"
?
"
group
.
append
(
link
)
return
group
def
gen_api_map
(
app
):
api_map
=
Token
(
""
)
for
rule
in
app
.
url_map
.
iter_rules
():
...
...
@@ -303,15 +332,19 @@ def gen_api_map(app):
# Check if the segment already exists in the current level
child
=
current_token
.
find_child
(
segment
)
if
child
is
None
:
# If it's the last segment and it has query parameters
if
i
==
len
(
segments
)
-
1
and
segment
==
"
query
"
:
func
=
app
.
view_functions
[
rule
.
endpoint
]
# If it's the last segment
if
i
==
len
(
segments
)
-
1
:
child
=
Token
(
segment
,
leaf
=
True
,
query
=
parse_query_doc
(
func
.
__doc__
or
""
),
)
# TODO Parse QUERY doc
else
:
child
=
Token
(
segment
)
child
=
Token
(
segment
,
)
child
.
func_name
=
func
.
__name__
method
:
str
=
"
POST
"
if
"
POST
"
in
rule
.
methods
else
"
GET
"
child
.
method
=
method
current_token
.
add_child
(
child
)
...
...
@@ -322,6 +355,10 @@ def gen_api_map(app):
current_token
.
force_leaf
=
True
generate_svg
(
api_map
.
to_svg_group
(),
"
/tmp/api_map.svg
"
)
print
(
"
La carte a été générée avec succès.
"
+
"
Vous pouvez la consulter à l
'
adresse suivante : /tmp/api_map.svg
"
)
def
_get_bbox
(
element
,
x_offset
=
0
,
y_offset
=
0
):
...
...
@@ -366,8 +403,8 @@ def _get_bbox(element, x_offset=0, y_offset=0):
def
generate_svg
(
element
,
fname
):
bbox
=
_get_bbox
(
element
)
width
=
bbox
[
"
x_max
"
]
-
bbox
[
"
x_min
"
]
+
2
0
# Add some padding
height
=
bbox
[
"
y_max
"
]
-
bbox
[
"
y_min
"
]
+
2
0
# Add some padding
width
=
bbox
[
"
x_max
"
]
-
bbox
[
"
x_min
"
]
+
8
0
# Add some padding
height
=
bbox
[
"
y_max
"
]
-
bbox
[
"
y_min
"
]
+
8
0
# Add some padding
svg
=
ET
.
Element
(
"
svg
"
,
...
...
@@ -401,15 +438,59 @@ def generate_svg(element, fname):
tree
.
write
(
fname
,
encoding
=
"
utf-8
"
,
xml_declaration
=
True
)
def
parse_query_doc
(
doc
):
"""
renvoie un dictionnaire {param: <type:nom_param>} (ex: {assiduite_id : <int:assiduite_id>})
La doc doit contenir des lignes de la forme:
QUERY
-----
param:<string:nom_param>
param1:<int:num>
param2:<array[string]:array_nom>
Dès qu
'
une ligne ne respecte pas ce format (voir regex dans la fonction), on arrête de parser
Attention, la ligne ----- doit être collée contre QUERY et contre le premier paramètre
"""
lines
=
[
line
.
strip
()
for
line
in
doc
.
split
(
"
\n
"
)]
try
:
query_index
=
lines
.
index
(
"
QUERY
"
)
if
lines
[
query_index
+
1
]
!=
"
-----
"
:
return
{}
except
ValueError
:
return
{}
query_lines
=
lines
[
query_index
+
2
:]
query
=
{}
regex
=
re
.
compile
(
r
"
^(\w+):(<.+>)$
"
)
for
line
in
query_lines
:
parts
=
regex
.
match
(
line
)
if
not
parts
:
break
param
,
type_nom_param
=
parts
.
groups
()
query
[
param
]
=
type_nom_param
return
query
if
__name__
==
"
__main__
"
:
root
=
Token
(
"
api
"
)
child1
=
Token
(
"
assiduites
"
,
leaf
=
True
)
child1
=
Token
(
"
assiduites
"
,
leaf
=
True
,
func_name
=
"
assiduites_get
"
)
child2
=
Token
(
"
count
"
)
child22
=
Token
(
"
all
"
)
child23
=
Token
(
"
query
"
,
query
=
{
"
param1
"
:
"
value1
"
,
"
param2
"
:
"
value2
"
,
"
param3
"
:
"
value3
"
}
"
query
"
,
query
=
{
"
etat
"
:
"
<string:etat>
"
,
"
moduleimpl_id
"
:
"
<int:moduleimpl_id>
"
,
"
count
"
:
"
<int:count>
"
,
"
formsemestre_id
"
:
"
<int:formsemestre_id>
"
,
},
)
child3
=
Token
(
"
justificatifs
"
,
"
POST
"
)
child3
=
Token
(
"
justificatifs
"
,
"
POST
"
,
func_name
=
"
justificatifs_post
"
)
root
.
add_child
(
child1
)
child1
.
add_child
(
child2
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment