15
15
)
16
16
from database import db
17
17
from util .calculate import calculate_user_time
18
- from util .statement import create_statement_from_kernel_data
18
+ from util .statement import create_statement_from_kernel_data , TRANSLATIONS
19
+ from utils import validate_object_id
19
20
20
21
21
22
async def compute_time ():
@@ -35,51 +36,111 @@ async def compute_ay_time():
35
36
users = await db .zvms .get_collection ("users" ).find ({}).to_list (None )
36
37
now = datetime .now ()
37
38
ay = now .year if now .month >= 9 else now .year - 1
38
- soy = datetime .now ().replace (month = 8 , day = 1 , year = ay , hour = 0 , minute = 0 , second = 0 , microsecond = 0 )
39
- eoy = datetime .now ().replace (month = 7 , day = 31 , year = ay + 1 , hour = 23 , minute = 59 , second = 59 , microsecond = 999999 )
39
+ soy = datetime .now ().replace (
40
+ month = 8 , day = 1 , year = ay , hour = 0 , minute = 0 , second = 0 , microsecond = 0
41
+ )
42
+ eoy = datetime .now ().replace (
43
+ month = 7 , day = 31 , year = ay + 1 , hour = 23 , minute = 59 , second = 59 , microsecond = 999999
44
+ )
40
45
for user in users :
41
46
user_id = str (user ["_id" ])
42
47
entry = user_id [:4 ]
43
- result = await calculate_user_time (user_id , date_start = soy , date_end = eoy , allow_cache = False )
44
- await db .zvms_new .get_collection ("time_academic_year" ).delete_many ({"user" : user_id })
45
- await db .zvms_new .get_collection ("time_academic_year" ).insert_one ({
46
- "user" : user_id ,
47
- "entry" : entry ,
48
- "academic_year" : ay ,
49
- "start_of_year" : soy ,
50
- "end_of_year" : eoy ,
51
- ** result
52
- })
48
+ result = await calculate_user_time (
49
+ user_id , date_start = soy , date_end = eoy , allow_cache = False
50
+ )
51
+ await db .zvms_new .get_collection ("time_academic_year" ).delete_many (
52
+ {"user" : user_id }
53
+ )
54
+ await db .zvms_new .get_collection ("time_academic_year" ).insert_one (
55
+ {
56
+ "user" : user_id ,
57
+ "entry" : entry ,
58
+ "academic_year" : ay ,
59
+ "start_of_year" : soy ,
60
+ "end_of_year" : eoy ,
61
+ ** result ,
62
+ }
63
+ )
64
+
53
65
54
66
async def generate_reports ():
55
- classes = await db .zvms .get_collection ("groups" ).find ({"type" : "class" }).to_list (None )
56
- if not os .path .exists ('./export' ):
57
- os .makedirs ('./export' )
67
+ classes = (
68
+ await db .zvms .get_collection ("groups" ).find ({"type" : "class" }).to_list (None )
69
+ )
70
+ await db .zvms_new .get_collection ("daily_exports" ).delete_many ({})
71
+ db_data = await db .zvms_new .get_collection ("daily_exports" ).insert_one (
72
+ {"created_at" : datetime .now (), "status" : "processing" , "data" : []}
73
+ )
74
+ db_id = validate_object_id (db_data .inserted_id )
75
+ if not os .path .exists ("./export" ):
76
+ os .makedirs ("./export" )
58
77
else :
59
- for item in os .listdir (' ./export' ):
60
- item_path = os .path .join (' ./export' , item )
78
+ for item in os .listdir (" ./export" ):
79
+ item_path = os .path .join (" ./export" , item )
61
80
if os .path .isdir (item_path ):
62
81
for file in os .listdir (item_path ):
63
82
file_path = os .path .join (item_path , file )
64
- if file .endswith (' .pdf' ):
83
+ if file .endswith (" .pdf" ):
65
84
os .remove (file_path )
66
85
os .rmdir (item_path )
67
86
for class_id in classes :
68
- users = await db .zvms .get_collection ("users" ).find ({"group" : str (class_id ["_id" ])}).to_list (None )
87
+ users = (
88
+ await db .zvms .get_collection ("users" )
89
+ .find ({"group" : str (class_id ["_id" ])})
90
+ .to_list (None )
91
+ )
69
92
os .makedirs (f'./export/{ class_id ["name" ]} ' , exist_ok = True )
70
93
for user in users :
71
94
user_id = str (user ["id" ])
72
95
entry = int (user_id [:4 ])
73
- soy = datetime .now ().replace (month = 8 , day = 1 , year = entry , hour = 0 , minute = 0 , second = 0 , microsecond = 0 )
74
- eoy = datetime .now ().replace (month = 7 , day = 31 , year = entry + 3 , hour = 23 , minute = 59 , second = 59 , microsecond = 999999 )
75
- await create_statement_from_kernel_data (str (user ['_id' ]), (soy , eoy ), filename = f'./export/{ class_id ['name' ]} /{ user ['id' ]} _{ user ["name" ]} .pdf' , language = 'zh' )
76
- print (f"Exported statement for { user ['name' ]} in class { class_id ['name' ]} ." )
96
+ soy = datetime .now ().replace (
97
+ month = 8 , day = 1 , year = entry , hour = 0 , minute = 0 , second = 0 , microsecond = 0
98
+ )
99
+ eoy = datetime .now ().replace (
100
+ month = 7 ,
101
+ day = 31 ,
102
+ year = entry + 3 ,
103
+ hour = 23 ,
104
+ minute = 59 ,
105
+ second = 59 ,
106
+ microsecond = 999999 ,
107
+ )
108
+ filename , spreadsheet = await create_statement_from_kernel_data (
109
+ str (user ["_id" ]),
110
+ (soy , eoy ),
111
+ filename = f'./export/{ class_id ['name' ]} /{ user ['id' ]} _{ user ["name" ]} .pdf' ,
112
+ language = "zh" ,
113
+ )
114
+ await db .zvms_new .get_collection ("daily_exports" ).update_one (
115
+ {"_id" : db_id },
116
+ {
117
+ "$push" : {
118
+ "data" : {
119
+ ** spreadsheet ,
120
+ "filename" : filename ,
121
+ }
122
+ }
123
+ },
124
+ )
125
+ print (
126
+ f"Exported statement for { user ['name' ]} in class { class_id ['name' ]} (saved to { filename } )."
127
+ )
77
128
print (f"Exported statements for class { class_id ['name' ]} ." )
78
129
# Create a tar.gz archive of the export directory
79
- if os .path .exists ('./data/export.tar.gz' ):
80
- os .remove ('./data/export.tar.gz' )
81
- with tarfile .open ('./data/export.tar.gz' , 'w:gz' ) as tar :
82
- tar .add ('./export' , arcname = 'export' )
130
+ spreadsheet_items = await db .zvms_new .get_collection ("daily_exports" ).find_one (
131
+ {"_id" : db_id }
132
+ )
133
+ spreadsheet_items = spreadsheet_items .get ("data" , [])
134
+ df = pd .DataFrame (spreadsheet_items )
135
+ df .rename (columns = TRANSLATIONS ["zh" ]["spreadsheet" ], inplace = True )
136
+ if os .path .exists ("./export/summary.xlsx" ):
137
+ os .remove ("./export/summary.xlsx" )
138
+ df .to_excel (f"./export/summary.xlsx" , index = False )
139
+ if os .path .exists ("./data/export.tar.gz" ):
140
+ os .remove ("./data/export.tar.gz" )
141
+ with tarfile .open ("./data/export.tar.gz" , "w:gz" ) as tar :
142
+ tar .add ("./export" , arcname = "export" )
143
+ return "./data/export.tar.gz"
83
144
84
145
85
146
def describe_percentile (items : np .ndarray , step : int , bound : float ) -> dict [str , float ]:
@@ -142,7 +203,14 @@ def process_time_data(time_df: pd.DataFrame) -> pd.DataFrame:
142
203
1 ,
143
204
)
144
205
time_df ["social-practice" ] = time_df ["social_practice" ]
145
- time_df ["diff" ] = BASE_ON_CAMPUS + BASE_OFF_CAMPUS + BASE_SOCIAL_PRACTICE - time_df ['on-campus' ] - time_df ['off-campus' ] - time_df ['social-practice' ]
206
+ time_df ["diff" ] = (
207
+ BASE_ON_CAMPUS
208
+ + BASE_OFF_CAMPUS
209
+ + BASE_SOCIAL_PRACTICE
210
+ - time_df ["on-campus" ]
211
+ - time_df ["off-campus" ]
212
+ - time_df ["social-practice" ]
213
+ )
146
214
return time_df
147
215
148
216
0 commit comments