mirror of
https://codeberg.org/catask-org/catask.git
synced 2025-04-19 21:33:41 -05:00
add import/export functions
This commit is contained in:
parent
283f2e5784
commit
86fb42c6f6
1 changed files with 150 additions and 0 deletions
150
functions.py
150
functions.py
|
@ -528,6 +528,156 @@ def generateFavicon(file_name):
|
||||||
resized_img_absolute_path = const.faviconDir / filename
|
resized_img_absolute_path = const.faviconDir / filename
|
||||||
resized_img.save(resized_img_absolute_path)
|
resized_img.save(resized_img_absolute_path)
|
||||||
|
|
||||||
|
def createExport():
|
||||||
|
try:
|
||||||
|
# just to test if connection works
|
||||||
|
conn = connectToDb()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
timestamp_morereadable = datetime.now().strftime('%b %d, %Y %H:%M')
|
||||||
|
export_dir = const.exportsDir
|
||||||
|
temp_dir = const.tempDir
|
||||||
|
os.makedirs(export_dir, exist_ok=True)
|
||||||
|
os.makedirs(temp_dir, exist_ok=True)
|
||||||
|
|
||||||
|
config_dest_path = temp_dir / const.configFile
|
||||||
|
shutil.copy(const.configFile, config_dest_path)
|
||||||
|
|
||||||
|
# Export database to SQL file
|
||||||
|
dump_file = temp_dir / 'database.sql'
|
||||||
|
result = subprocess.Popen(
|
||||||
|
f'mysqldump --quote-names -u {dbUser} -p{dbPass} {dbName} --result-file={dump_file}',
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
encoding="utf-8"
|
||||||
|
)
|
||||||
|
# absolutely dumb workaround for an error
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Create export zip archive
|
||||||
|
zip_file_path = export_dir / f'export-{timestamp}.zip'
|
||||||
|
with zipfile.ZipFile(zip_file_path, 'w') as export_zip:
|
||||||
|
export_zip.write(config_dest_path, arcname=const.configFile)
|
||||||
|
export_zip.write(dump_file, arcname='database.sql')
|
||||||
|
|
||||||
|
# Add favicon and emojis folders to the zip archive
|
||||||
|
favicon_dir = Path('static/icons/favicon')
|
||||||
|
emojis_dir = Path('static/emojis')
|
||||||
|
|
||||||
|
if favicon_dir.exists():
|
||||||
|
for root, _, files in os.walk(favicon_dir):
|
||||||
|
for file in files:
|
||||||
|
file_path = Path(root) / file
|
||||||
|
export_zip.write(file_path, arcname=file_path.relative_to(favicon_dir.parent.parent))
|
||||||
|
|
||||||
|
if emojis_dir.exists():
|
||||||
|
for root, _, files in os.walk(emojis_dir):
|
||||||
|
for file in files:
|
||||||
|
file_path = Path(root) / file
|
||||||
|
export_zip.write(file_path, arcname=file_path.relative_to(emojis_dir.parent))
|
||||||
|
|
||||||
|
# Record export metadata
|
||||||
|
export_data = {
|
||||||
|
'timestamp_esc': timestamp,
|
||||||
|
'timestamp': timestamp_morereadable,
|
||||||
|
'downloadPath': str(zip_file_path)
|
||||||
|
}
|
||||||
|
appendToJSON(export_data, const.exportsFile)
|
||||||
|
shutil.rmtree(temp_dir)
|
||||||
|
|
||||||
|
return {'message': 'Export created successfully!'}
|
||||||
|
except mysql.connector.Error as e:
|
||||||
|
return {'error': str(e)}, 500
|
||||||
|
except Exception as e:
|
||||||
|
return {'error': str(e)}, 500
|
||||||
|
|
||||||
|
|
||||||
|
def importData(export_file):
|
||||||
|
try:
|
||||||
|
shutil.unpack_archive(export_file, const.tempDir)
|
||||||
|
|
||||||
|
# Replace config file
|
||||||
|
os.remove(const.configFile)
|
||||||
|
shutil.move(const.tempDir / const.configFile, Path.cwd() / const.configFile)
|
||||||
|
|
||||||
|
# Replace favicon and emojis folders
|
||||||
|
favicon_dest = Path('static/icons/favicon')
|
||||||
|
emojis_dest = Path('static/emojis')
|
||||||
|
|
||||||
|
shutil.rmtree(favicon_dest)
|
||||||
|
shutil.copytree(const.tempDir / 'icons' / 'favicon', favicon_dest)
|
||||||
|
|
||||||
|
shutil.rmtree(emojis_dest)
|
||||||
|
shutil.copytree(const.tempDir / 'emojis', emojis_dest)
|
||||||
|
|
||||||
|
# Restore database from SQL file
|
||||||
|
conn = connectToDb()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
with open(const.tempDir / 'database.sql', 'r') as schema_file:
|
||||||
|
try:
|
||||||
|
# for some reason `cursor.execute(schema, multi=True)` doesn't work, so we use this instead
|
||||||
|
schema = schema_file.read()
|
||||||
|
queries = schema.split(';')
|
||||||
|
for query in queries:
|
||||||
|
cursor.execute(query)
|
||||||
|
except mysql.connector.Error as e:
|
||||||
|
return {'error': str(e)}, 500
|
||||||
|
finally:
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
shutil.rmtree(const.tempDir)
|
||||||
|
|
||||||
|
return {'message': 'Data imported successfully!'}
|
||||||
|
except Exception as e:
|
||||||
|
return {'error': str(e)}, 500
|
||||||
|
|
||||||
|
# will probably get to it in 1.8.0 because my brain can't do it rn
|
||||||
|
"""
|
||||||
|
def retrospringImport(export_file):
|
||||||
|
shutil.unpack_archive(export_file, const.tempDir)
|
||||||
|
# probably a hack but whateva
|
||||||
|
export_dirname = Path(export_file).stem
|
||||||
|
export_dir = const.tempDir / export_dirname
|
||||||
|
|
||||||
|
conn = connectToDb()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
questions_file = loadJSON(export_dir / 'questions.json')
|
||||||
|
answers_file = loadJSON(export_dir / 'answers.json')
|
||||||
|
|
||||||
|
# Extract answers list
|
||||||
|
questions_list = questions_file.get('questions', [])
|
||||||
|
answers_list = answers_file.get('answers', [])
|
||||||
|
# ['related']['question']['anonymous']
|
||||||
|
|
||||||
|
for question in questions_list:
|
||||||
|
# addQuestion(answer['related']['question']['anonymous'], question['content'], None, noAntispam=True)
|
||||||
|
for answer in answers_list:
|
||||||
|
print("anonymous:", answer['related']['question']['anonymous'])
|
||||||
|
print(question['id'], answer['content'], None)
|
||||||
|
# addAnswer(question['id'], answer['content'], None)
|
||||||
|
|
||||||
|
# shutil.rmtree(const.tempDir)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def deleteExport(timestamp):
|
||||||
|
try:
|
||||||
|
export_file = Path('static') / 'exports' / f'export-{timestamp}.zip'
|
||||||
|
data = loadJSON(const.exportsFile)
|
||||||
|
data = [export for export in data if export["timestamp_esc"] != timestamp]
|
||||||
|
export_file.unlink()
|
||||||
|
saveJSON(data, const.exportsFile)
|
||||||
|
return {'message': f'Export {timestamp} deleted successfully.'}
|
||||||
|
except Exception as e:
|
||||||
|
return {'error': str(e)}, 500
|
||||||
|
|
||||||
# reserved for 1.7.0 or later
|
# reserved for 1.7.0 or later
|
||||||
"""
|
"""
|
||||||
def getUserIp():
|
def getUserIp():
|
||||||
|
|
Loading…
Add table
Reference in a new issue