Skip to content
This repository was archived by the owner on May 16, 2019. It is now read-only.

Commit 4a69399

Browse files
committed
Add base functionality for backup tool python code
1 parent e812d26 commit 4a69399

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

backupTool.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import csv
2+
import db.datastore as db
3+
import os
4+
import re
5+
import shutil
6+
import sqlite3 as lite
7+
import tarfile
8+
import time
9+
10+
TABLES = [
11+
('hashmap', ['hash', 'filepath']),
12+
('profile', ['id', 'serializedUserInfo']),
13+
('listings', ['id', 'serializedListings']),
14+
('keys', ['type', 'privkey', 'pubkey']),
15+
('followers', ['id', 'serializedFollowers']),
16+
('following', ['id', 'serializedFollowing']),
17+
('messages', ['guid', 'handle', 'signed_pubkey', 'encryption_pubkey', 'subject', 'message_type', 'message', 'timestamp', 'avatar_hash', 'signature', 'outgoing']),
18+
('notifications', ['guid', 'handle', 'message', 'timestamp', 'avatar_hash']),
19+
('vendors', ['guid', 'ip', 'port', 'signedPubkey']),
20+
('moderators', ['guid', 'signedPubkey', 'encryptionKey', 'encryptionSignature', 'bitcoinKey', 'bitcoinSignature', 'handle']),
21+
('purchases', ['id', 'title', 'timestamp', 'btc', 'address', 'status', 'thumbnail', 'seller', 'proofSig']),
22+
('sales', ['id', 'title', 'timestamp', 'btc', 'address', 'status', 'thumbnail', 'seller']),
23+
('dht', ['keyword', 'id', 'value', 'birthday'])
24+
]
25+
26+
# TODO: Add all files and directories to back up together with the database
27+
# Ex: ['file', 'path/to/file2', ...]
28+
FILES = []
29+
30+
def _getDatabase():
31+
Database = db.Database()
32+
return Database.DATABASE
33+
34+
def _exportDatabaseToCsv(tablesAndColumns):
35+
"""Reads the database for all given tables and stores them as CSV files."""
36+
dbFile = _getDatabase()
37+
result = None
38+
with lite.connect(dbFile) as dbConnection:
39+
dbConnection.text_factory = str
40+
cursor = dbConnection.cursor()
41+
for table in tablesAndColumns:
42+
table_name = table[0]
43+
table_columns = ', '.join(table[1])
44+
data = cursor.execute("SELECT {0} FROM {1}".format(table_columns, table_name))
45+
fileName = 'table_{0}.csv'.format(table_name)
46+
filePath = os.path.join('backup', fileName)
47+
with open(filePath, 'wb') as f:
48+
writer = csv.writer(f)
49+
writer.writerow(table[1])
50+
writer.writerows(data)
51+
return result
52+
53+
def backup(tablesAndColumns, files, output=None):
54+
"""Archives given tables and files in a single tar archive."""
55+
# Remove existing database files and re-make them
56+
if os.path.exists('backup'):
57+
shutil.rmtree('backup')
58+
os.makedirs('backup')
59+
_exportDatabaseToCsv(tablesAndColumns)
60+
61+
# Archive files
62+
if not output:
63+
output = 'backup_{0}.tar.gz'.format(time.strftime('%Y-%m-%d'))
64+
with tarfile.open(output, 'w:gz') as tar:
65+
tar.add('backup')
66+
for f in files:
67+
tar.add(f)
68+
tar.close()
69+
70+
def _importCsvToTable(fileName, deleteDataFirst=False):
71+
"""Imports given CSV file to the database."""
72+
tableName = re.search('table_(\w+).csv', fileName).group(1)
73+
dbFile = _getDatabase()
74+
with lite.connect(dbFile) as dbConnection:
75+
dbConnection.text_factory = str
76+
cursor = dbConnection.cursor()
77+
if deleteDataFirst:
78+
cursor.execute('DELETE FROM {0}'.format(tableName))
79+
with open(fileName, 'rb') as f:
80+
reader = csv.reader(f)
81+
header = True
82+
for row in reader:
83+
if header:
84+
header = False
85+
columns = ', '.join(['?' for column in row])
86+
insertsql = 'INSERT INTO {0} VALUES ({1})'.format(tableName, columns)
87+
rowlen = len(row)
88+
else:
89+
if len(row) == rowlen:
90+
print 'Insert into {0}: {1}'.format(tableName, row)
91+
print insertsql
92+
cursor.execute(insertsql, row)
93+
94+
95+
def restore(input, deleteTableDataFirst=False):
96+
"""Restores files and tables of given archive."""
97+
# Remove existing database files if any
98+
if os.path.exists('backup'):
99+
shutil.rmtree('backup')
100+
101+
# Unarchive files
102+
with tarfile.open(input, 'r:gz') as tar:
103+
tar.extractall()
104+
105+
# Restore database files to the database
106+
if os.path.exists('backup'):
107+
files = ['backup/{0}'.format(f) for f in os.listdir('backup')]
108+
for f in files:
109+
_importCsvToTable(f, deleteTableDataFirst)
110+
111+
if __name__ == '__main__':
112+
print 'Backup tool works as a library.'

0 commit comments

Comments
 (0)