Skip to content

Commit f0c44ed

Browse files
authoredJun 16, 2017
Upgrading exports (CTFd#283)
* Upgrading export capabilities * Only apply sqlite hacks for sqlite This fixes CTFd#250, CTFd#246 Adds export.py to save CTFs without needing to actually spin up CTFd Also forcing charset properly for MySQL
1 parent 34237e6 commit f0c44ed

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed
 

‎CTFd/__init__.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,20 @@ def create_app(config='CTFd.config.Config'):
4141
if url.drivername == 'postgres':
4242
url.drivername = 'postgresql'
4343

44+
if url.drivername.startswith('mysql'):
45+
url.query['charset'] = 'utf8mb4'
46+
4447
# Creates database if the database database does not exist
4548
if not database_exists(url):
4649
if url.drivername.startswith('mysql'):
47-
url.query['charset'] = 'utf8mb4'
4850
create_database(url, encoding='utf8mb4')
4951
else:
5052
create_database(url)
5153

54+
# This allows any changes to the SQLALCHEMY_DATABASE_URI to get pushed back in
55+
# This is mostly so we can force MySQL's charset
56+
app.config['SQLALCHEMY_DATABASE_URI'] = str(url)
57+
5258
# Register database
5359
db.init_app(app)
5460

‎CTFd/admin/__init__.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,8 @@ def admin_import_ctf():
6363
import_ctf(backup, segments=segments.split(','))
6464
else:
6565
import_ctf(backup)
66-
except TypeError:
67-
errors.append('The backup file is invalid')
68-
except IntegrityError as e:
69-
errors.append(e.message)
7066
except Exception as e:
67+
print(e)
7168
errors.append(type(e).__name__)
7269

7370
if errors:

‎CTFd/utils.py

+9
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,15 @@ def import_ctf(backup, segments=None, erase=False):
792792
saved = json.loads(data)
793793
for entry in saved['results']:
794794
entry_id = entry.pop('id', None)
795+
# This is a hack to get SQlite to properly accept datetime values from dataset
796+
# See Issue #246
797+
if get_config('SQLALCHEMY_DATABASE_URI').startswith('sqlite'):
798+
for k, v in entry.items():
799+
if isinstance(v, six.string_types):
800+
try:
801+
entry[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S')
802+
except ValueError as e:
803+
pass
795804
table.insert(entry)
796805
else:
797806
continue

‎export.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from CTFd import create_app
2+
from CTFd.utils import ctf_name, export_ctf
3+
4+
import datetime
5+
import sys
6+
import shutil
7+
import zipfile
8+
9+
10+
app = create_app()
11+
with app.app_context():
12+
backup = export_ctf()
13+
14+
if len(sys.argv) > 1:
15+
with open(sys.argv[1], 'wb') as target:
16+
shutil.copyfileobj(backup, target)
17+
else:
18+
ctf_name = ctf_name()
19+
day = datetime.datetime.now().strftime("%Y-%m-%d")
20+
full_name = "{}.{}.zip".format(ctf_name, day)
21+
22+
with open(full_name, 'wb') as target:
23+
shutil.copyfileobj(backup, target)

0 commit comments

Comments
 (0)
Please sign in to comment.