mirror of https://github.com/JohnHammond/CTFd.git
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 MySQLselenium-screenshot-testing
parent
34237e6292
commit
f0c44ed6d6
|
@ -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
|
||||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue