Repository: fossasia/open-event-server

Issue:
Export speakers as CSV
**Is your feature request related to a problem? Please describe.**
Add an endpoint to export speakers as CSV

**Describe the solution you'd like**
Follow the one used in v1.

**Describe alternatives you've considered**
\-


Discussion:

Resolving patch:
diff --git a/app/api/exports.py b/app/api/exports.py
--- a/app/api/exports.py
+++ b/app/api/exports.py
@@ -232,3 +232,23 @@ def export_sessions_csv(event_identifier):
     return jsonify(
         task_url=url_for('tasks.celery_task', task_id=task.id)
     )
+
+
+@export_routes.route('/events/<string:event_identifier>/export/speakers/csv', methods=['GET'])
+@jwt_required()
+def export_speakers_csv(event_identifier):
+    if not event_identifier.isdigit():
+        event = db.session.query(Event).filter_by(identifier=event_identifier).first()
+        event_id = str(event.id)
+    else:
+        event_id = event_identifier
+
+    from .helpers.tasks import export_speakers_csv_task
+
+    task = export_speakers_csv_task.delay(event_id)
+
+    create_export_job(task.id, event_id)
+
+    return jsonify(
+        task_url=url_for('tasks.celery_task', task_id=task.id)
+    )
diff --git a/app/api/helpers/csv_jobs_util.py b/app/api/helpers/csv_jobs_util.py
--- a/app/api/helpers/csv_jobs_util.py
+++ b/app/api/helpers/csv_jobs_util.py
@@ -67,3 +67,26 @@ def export_sessions_csv(sessions):
             rows.append(column)
 
     return rows
+
+
+def export_speakers_csv(speakers):
+    headers = ['Speaker Name', 'Speaker Email', 'Speaker Session(s)',
+               'Speaker Mobile', 'Speaker Bio', 'Speaker Organisation', 'Speaker Position']
+    rows = [headers]
+    for speaker in speakers:
+        column = [speaker.name if speaker.name else '', speaker.email if speaker.email else '']
+        if speaker.sessions:
+            session_details = ''
+            for session in speaker.sessions:
+                if not session.deleted_at:
+                    session_details += session.title + ' (' + session.state + '); '
+            column.append(session_details[:-2])
+        else:
+            column.append('')
+        column.append(speaker.mobile if speaker.mobile else '')
+        column.append(speaker.short_biography if speaker.short_biography else '')
+        column.append(speaker.organisation if speaker.organisation else '')
+        column.append(speaker.position if speaker.position else '')
+        rows.append(column)
+
+    return rows
diff --git a/app/api/helpers/tasks.py b/app/api/helpers/tasks.py
--- a/app/api/helpers/tasks.py
+++ b/app/api/helpers/tasks.py
@@ -10,6 +10,7 @@
 from app import make_celery
 from app.api.helpers.utilities import strip_tags
 from app.models.session import Session
+from app.models.speaker import Speaker
 
 """
 Define all API v2 celery tasks here
@@ -356,3 +357,32 @@ def export_sessions_csv_task(self, event_id):
         result = {'__error': True, 'result': str(e)}
 
     return result
+
+
+@celery.task(base=RequestContextTask, name='export.speakers.csv', bind=True)
+def export_speakers_csv_task(self, event_id):
+    speakers = db.session.query(Speaker).filter_by(event_id=event_id)
+    try:
+        filedir = os.path.join(current_app.config.get('BASE_DIR'), 'static/uploads/temp/')
+        if not os.path.isdir(filedir):
+            os.makedirs(filedir)
+        filename = "speakers-{}.csv".format(uuid.uuid1().hex)
+        file_path = os.path.join(filedir, filename)
+
+        with open(file_path, "w") as temp_file:
+            writer = csv.writer(temp_file)
+            from app.api.helpers.csv_jobs_util import export_speakers_csv
+            content = export_speakers_csv(speakers)
+            for row in content:
+                writer.writerow(row)
+        speakers_csv_file = UploadedFile(file_path=file_path, filename=filename)
+        speakers_csv_url = upload(speakers_csv_file,
+                                  UPLOAD_PATHS['exports-temp']['csv'].format(event_id=event_id, identifier=''))
+        result = {
+            'download_url': speakers_csv_url
+        }
+    except Exception as e:
+        print(traceback.format_exc())
+        result = {'__error': True, 'result': str(e)}
+
+    return result


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -3708,6 +3708,19 @@ def event_sessions_export_csv_get(transaction):
         db.session.add(event)
         db.session.commit()
 
+
+@hooks.before(
+    "Event Export > Start Speakers Export as CSV > Start a Task to Export Speakers of an Event as CSV")
+def event_speakers_export_csv_get(transaction):
+    """
+    :param transaction:
+    :return:
+    """
+    with stash['app'].app_context():
+        event = EventFactoryBasic()
+        db.session.add(event)
+        db.session.commit()
+
 # ------------------------- Import -------------------------
 @hooks.before(
     "Event Import > Start Event Import > Start a Task to Import an Event")