11import os
2- import threading
32import uuid
43from datetime import datetime , timezone
54from pathlib import Path
65
7- from flask import Blueprint , jsonify , send_file
6+ from flask import Blueprint , current_app , jsonify , send_file
87from flask_login import current_user
98
109from pydatalab .config import CONFIG
1110from pydatalab .export_utils import create_eln_file
1211from pydatalab .models .export_task import ExportStatus , ExportTask
1312from pydatalab .mongo import flask_mongo
1413from pydatalab .permissions import active_users_or_get_only
14+ from pydatalab .scheduler import export_scheduler
1515
1616EXPORT = Blueprint ("export" , __name__ )
1717
2121def _ (): ...
2222
2323
24- def _generate_export_in_background (task_id : str , collection_id : str ):
24+ def _generate_export_in_background (task_id : str , collection_id : str , app ):
2525 """Background function to generate the .eln file.
2626
2727 Parameters:
2828 task_id: ID of the export task
2929 collection_id: ID of the collection to export
30+ app: Flask application instance
3031 """
31- try :
32- flask_mongo .db .export_tasks .update_one (
33- {"task_id" : task_id }, {"$set" : {"status" : ExportStatus .PROCESSING }}
34- )
35-
36- export_dir = Path (CONFIG .FILE_DIRECTORY ) / "exports"
37- export_dir .mkdir (exist_ok = True )
38-
39- output_path = export_dir / f"{ task_id } .eln"
40- create_eln_file (collection_id , str (output_path ))
41-
42- flask_mongo .db .export_tasks .update_one (
43- {"task_id" : task_id },
44- {
45- "$set" : {
46- "status" : ExportStatus .READY ,
47- "file_path" : str (output_path ),
48- "completed_at" : datetime .now (tz = timezone .utc ),
49- }
50- },
51- )
52-
53- except Exception as e :
54- flask_mongo .db .export_tasks .update_one (
55- {"task_id" : task_id },
56- {
57- "$set" : {
58- "status" : ExportStatus .ERROR ,
59- "error_message" : str (e ),
60- "completed_at" : datetime .now (tz = timezone .utc ),
61- }
62- },
63- )
32+ with app .app_context ():
33+ try :
34+ flask_mongo .db .export_tasks .update_one (
35+ {"task_id" : task_id }, {"$set" : {"status" : ExportStatus .PROCESSING }}
36+ )
37+
38+ export_dir = Path (CONFIG .FILE_DIRECTORY ) / "exports"
39+ export_dir .mkdir (exist_ok = True )
40+
41+ output_path = export_dir / f"{ task_id } .eln"
42+ create_eln_file (collection_id , str (output_path ))
43+
44+ flask_mongo .db .export_tasks .update_one (
45+ {"task_id" : task_id },
46+ {
47+ "$set" : {
48+ "status" : ExportStatus .READY ,
49+ "file_path" : str (output_path ),
50+ "completed_at" : datetime .now (tz = timezone .utc ),
51+ }
52+ },
53+ )
54+
55+ except Exception as e :
56+ flask_mongo .db .export_tasks .update_one (
57+ {"task_id" : task_id },
58+ {
59+ "$set" : {
60+ "status" : ExportStatus .ERROR ,
61+ "error_message" : str (e ),
62+ "completed_at" : datetime .now (tz = timezone .utc ),
63+ }
64+ },
65+ )
6466
6567
6668@EXPORT .route ("/collections/<string:collection_id>/export" , methods = ["POST" ])
6769def start_collection_export (collection_id : str ):
68- """Start exporting a collection to .eln format.
69-
70- Parameters:
71- collection_id: The collection ID to export
70+ from pydatalab .permissions import get_default_permissions
7271
73- Returns:
74- JSON response with task_id and status_url
75- """
72+ collection_exists = flask_mongo . db . collections . find_one ({ "collection_id" : collection_id })
73+ if not collection_exists :
74+ return jsonify ({ "status" : "error" , "message" : "Collection not found" }), 404
7675
77- collection = flask_mongo .db .collections .find_one ({"collection_id" : collection_id })
78- if not collection :
79- return jsonify ({"status" : "error" , "message" : f"Collection { collection_id } not found" }), 404
76+ collection_with_perms = flask_mongo .db .collections .find_one (
77+ {"collection_id" : collection_id , ** get_default_permissions (user_only = True )}
78+ )
79+ if not collection_with_perms :
80+ return jsonify ({"status" : "error" , "message" : "Access denied" }), 403
8081
8182 task_id = str (uuid .uuid4 ())
8283
@@ -94,9 +95,13 @@ def start_collection_export(collection_id: str):
9495
9596 flask_mongo .db .export_tasks .insert_one (export_task .dict ())
9697
97- thread = threading .Thread (target = _generate_export_in_background , args = (task_id , collection_id ))
98- thread .daemon = True
99- thread .start ()
98+ app = current_app ._get_current_object ()
99+
100+ export_scheduler .add_job (
101+ func = _generate_export_in_background ,
102+ args = [task_id , collection_id , app ],
103+ job_id = f"export_{ task_id } " ,
104+ )
100105
101106 return jsonify (
102107 {"status" : "success" , "task_id" : task_id , "status_url" : f"/exports/{ task_id } /status" }
0 commit comments