mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 22:14:25 +01:00
Upgrading exports (#283)
* Upgrading export capabilities * Only apply sqlite hacks for sqlite This fixes #250, #246 Adds export.py to save CTFs without needing to actually spin up CTFd Also forcing charset properly for MySQL
This commit is contained in:
@@ -41,14 +41,20 @@ def create_app(config='CTFd.config.Config'):
|
|||||||
if url.drivername == 'postgres':
|
if url.drivername == 'postgres':
|
||||||
url.drivername = 'postgresql'
|
url.drivername = 'postgresql'
|
||||||
|
|
||||||
|
if url.drivername.startswith('mysql'):
|
||||||
|
url.query['charset'] = 'utf8mb4'
|
||||||
|
|
||||||
# Creates database if the database database does not exist
|
# Creates database if the database database does not exist
|
||||||
if not database_exists(url):
|
if not database_exists(url):
|
||||||
if url.drivername.startswith('mysql'):
|
if url.drivername.startswith('mysql'):
|
||||||
url.query['charset'] = 'utf8mb4'
|
|
||||||
create_database(url, encoding='utf8mb4')
|
create_database(url, encoding='utf8mb4')
|
||||||
else:
|
else:
|
||||||
create_database(url)
|
create_database(url)
|
||||||
|
|
||||||
|
# This allows any changes to the SQLALCHEMY_DATABASE_URI to get pushed back in
|
||||||
|
# This is mostly so we can force MySQL's charset
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = str(url)
|
||||||
|
|
||||||
# Register database
|
# Register database
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,8 @@ def admin_import_ctf():
|
|||||||
import_ctf(backup, segments=segments.split(','))
|
import_ctf(backup, segments=segments.split(','))
|
||||||
else:
|
else:
|
||||||
import_ctf(backup)
|
import_ctf(backup)
|
||||||
except TypeError:
|
|
||||||
errors.append('The backup file is invalid')
|
|
||||||
except IntegrityError as e:
|
|
||||||
errors.append(e.message)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
errors.append(type(e).__name__)
|
errors.append(type(e).__name__)
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
|
|||||||
@@ -792,6 +792,15 @@ def import_ctf(backup, segments=None, erase=False):
|
|||||||
saved = json.loads(data)
|
saved = json.loads(data)
|
||||||
for entry in saved['results']:
|
for entry in saved['results']:
|
||||||
entry_id = entry.pop('id', None)
|
entry_id = entry.pop('id', None)
|
||||||
|
# This is a hack to get SQlite to properly accept datetime values from dataset
|
||||||
|
# See Issue #246
|
||||||
|
if get_config('SQLALCHEMY_DATABASE_URI').startswith('sqlite'):
|
||||||
|
for k, v in entry.items():
|
||||||
|
if isinstance(v, six.string_types):
|
||||||
|
try:
|
||||||
|
entry[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S')
|
||||||
|
except ValueError as e:
|
||||||
|
pass
|
||||||
table.insert(entry)
|
table.insert(entry)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|||||||
23
export.py
Normal file
23
export.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from CTFd import create_app
|
||||||
|
from CTFd.utils import ctf_name, export_ctf
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
|
||||||
|
app = create_app()
|
||||||
|
with app.app_context():
|
||||||
|
backup = export_ctf()
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
with open(sys.argv[1], 'wb') as target:
|
||||||
|
shutil.copyfileobj(backup, target)
|
||||||
|
else:
|
||||||
|
ctf_name = ctf_name()
|
||||||
|
day = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||||
|
full_name = "{}.{}.zip".format(ctf_name, day)
|
||||||
|
|
||||||
|
with open(full_name, 'wb') as target:
|
||||||
|
shutil.copyfileobj(backup, target)
|
||||||
Reference in New Issue
Block a user