mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Add CSV export for teams+members+fields which is teams with fields and their team members with fields (#2147)
* Add CSV export for `teams+members+fields` which is teams with fields and their team members with fields * Closes #2145
This commit is contained in:
@@ -216,6 +216,66 @@ def dump_teams_with_fields_csv():
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def dump_teams_with_members_fields_csv():
|
||||||
|
temp = StringIO()
|
||||||
|
writer = csv.writer(temp)
|
||||||
|
|
||||||
|
team_fields = TeamFields.query.all()
|
||||||
|
team_field_ids = [f.id for f in team_fields]
|
||||||
|
team_field_names = [f.name for f in team_fields]
|
||||||
|
|
||||||
|
user_fields = UserFields.query.all()
|
||||||
|
user_field_ids = [f.id for f in user_fields]
|
||||||
|
user_field_names = [f.name for f in user_fields]
|
||||||
|
|
||||||
|
user_header = [
|
||||||
|
f"member_{column.name}" for column in Users.__mapper__.columns
|
||||||
|
] + user_field_names
|
||||||
|
|
||||||
|
header = (
|
||||||
|
[column.name for column in Teams.__mapper__.columns]
|
||||||
|
+ team_field_names
|
||||||
|
+ user_header
|
||||||
|
)
|
||||||
|
writer.writerow(header)
|
||||||
|
|
||||||
|
responses = Teams.query.all()
|
||||||
|
|
||||||
|
for curr in responses:
|
||||||
|
team_field_entries = {f.field_id: f.value for f in curr.field_entries}
|
||||||
|
team_field_values = [
|
||||||
|
team_field_entries.get(f_id, "") for f_id in team_field_ids
|
||||||
|
]
|
||||||
|
|
||||||
|
team_row = [
|
||||||
|
getattr(curr, column.name) for column in Teams.__mapper__.columns
|
||||||
|
] + team_field_values
|
||||||
|
|
||||||
|
writer.writerow(team_row)
|
||||||
|
|
||||||
|
for member in curr.members:
|
||||||
|
padding = [""] * len(team_row)
|
||||||
|
|
||||||
|
user_field_entries = {f.field_id: f.value for f in member.field_entries}
|
||||||
|
user_field_values = [
|
||||||
|
user_field_entries.get(f_id, "") for f_id in user_field_ids
|
||||||
|
]
|
||||||
|
user_row = [
|
||||||
|
getattr(member, column.name) for column in Users.__mapper__.columns
|
||||||
|
] + user_field_values
|
||||||
|
writer.writerow(padding + user_row)
|
||||||
|
|
||||||
|
temp.seek(0)
|
||||||
|
|
||||||
|
# In Python 3 send_file requires bytes
|
||||||
|
output = BytesIO()
|
||||||
|
output.write(temp.getvalue().encode("utf-8"))
|
||||||
|
output.seek(0)
|
||||||
|
temp.close()
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
def dump_database_table(tablename):
|
def dump_database_table(tablename):
|
||||||
# TODO: It might make sense to limit dumpable tables. Config could potentially leak sensitive information.
|
# TODO: It might make sense to limit dumpable tables. Config could potentially leak sensitive information.
|
||||||
model = get_class_by_tablename(tablename)
|
model = get_class_by_tablename(tablename)
|
||||||
@@ -334,4 +394,5 @@ CSV_KEYS = {
|
|||||||
"scoreboard": dump_scoreboard_csv,
|
"scoreboard": dump_scoreboard_csv,
|
||||||
"users+fields": dump_users_with_fields_csv,
|
"users+fields": dump_users_with_fields_csv,
|
||||||
"teams+fields": dump_teams_with_fields_csv,
|
"teams+fields": dump_teams_with_fields_csv,
|
||||||
|
"teams+members+fields": dump_teams_with_members_fields_csv,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user