support multiple accounts, fix misc server issues
This commit is contained in:
parent
fb1180ae60
commit
953351e8a8
|
@ -32,7 +32,8 @@ Does not support different accounts.
|
|||
```shell
|
||||
SQLITE3_DB=<path to your sqlite3 database>
|
||||
HTTP_AUTH_PASS=<your encoded password>
|
||||
```
|
||||
EMAIL_ARCHIVE_ROOT=<archive root path>
|
||||
```
|
||||
5. `sudo chmod 600 /etc/secrets/imapviewer`
|
||||
6. Reload and start the service.
|
||||
|
||||
|
|
54
server.py
54
server.py
|
@ -15,6 +15,8 @@ if not os.environ.get('SQLITE3_DB'):
|
|||
raise Exception('SQLITE3_DB not set.')
|
||||
if not os.environ.get('HTTP_AUTH_PASS'):
|
||||
raise Exception('HTTP_AUTH_PASS not set.')
|
||||
if not os.environ.get('EMAIL_ARCHIVE_ROOT'):
|
||||
raise Exception('EMAIL_ARCHIVE_ROOT not set.')
|
||||
|
||||
try:
|
||||
user_password = base64.b64decode(os.environ.get('HTTP_AUTH_PASS')).decode().replace('\n', '')
|
||||
|
@ -34,12 +36,6 @@ def get_pw(username):
|
|||
return None
|
||||
|
||||
|
||||
def get_db_connection():
|
||||
conn = sqlite3.connect(os.environ.get('SQLITE3_DB'))
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
|
||||
def dict_from_row(row):
|
||||
return dict(zip(row.keys(), row))
|
||||
|
||||
|
@ -47,45 +43,59 @@ def dict_from_row(row):
|
|||
@app.route('/')
|
||||
@auth.login_required
|
||||
def index():
|
||||
conn = get_db_connection()
|
||||
return render_template('index.html', accounts=[x.name for x in list(Path(os.environ.get('EMAIL_ARCHIVE_ROOT')).iterdir())])
|
||||
|
||||
|
||||
@app.route('/<email_account>/')
|
||||
@auth.login_required
|
||||
def account(email_account):
|
||||
conn = get_db_connection(email_account)
|
||||
folders = conn.execute('SELECT name, table_name FROM folders_mapping').fetchall()
|
||||
syncs = conn.execute('SELECT * FROM syncs ORDER BY timestamp DESC').fetchall()
|
||||
conn.close()
|
||||
syncs = [dict_from_row(sync) for sync in syncs]
|
||||
for sync in syncs:
|
||||
sync['timestamp'] = datetime.fromtimestamp(sync['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
|
||||
return render_template('index.html', folders=folders, syncs=syncs)
|
||||
return render_template('account.html', folders=folders, syncs=syncs, email_account=email_account)
|
||||
|
||||
|
||||
@app.route('/folder/<table_name>')
|
||||
@app.route('/<email_account>/folder/<table_name>')
|
||||
@auth.login_required
|
||||
def folder(table_name):
|
||||
conn = get_db_connection()
|
||||
def folder(email_account, table_name):
|
||||
conn = get_db_connection(email_account)
|
||||
emails = conn.execute(f'SELECT * FROM {table_name} ORDER BY timestamp DESC').fetchall()
|
||||
conn.close()
|
||||
emails = [dict_from_row(email) for email in emails]
|
||||
for email in emails:
|
||||
email['timestamp'] = datetime.fromtimestamp(email['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
|
||||
return render_template('folder.html', emails=emails, table_name=table_name)
|
||||
return render_template('folder.html', emails=emails, table_name=table_name, email_account=email_account)
|
||||
|
||||
|
||||
@app.route('/email/<table_name>/<id>')
|
||||
@app.route('/<email_account>/email/<table_name>/<id>')
|
||||
@auth.login_required
|
||||
def email(table_name, id):
|
||||
conn = get_db_connection()
|
||||
email = conn.execute(f'SELECT * FROM {table_name} WHERE id = ?', (id,)).fetchone()
|
||||
def email(email_account, table_name, id):
|
||||
conn = get_db_connection(email_account)
|
||||
email = dict_from_row(conn.execute(f'SELECT * FROM {table_name} WHERE id = ?', (id,)).fetchone())
|
||||
conn.close()
|
||||
email = dict_from_row(email)
|
||||
email['timestamp'] = datetime.fromtimestamp(email['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
|
||||
attachments = json.loads(email['attachments'])
|
||||
return render_template('email.html', email=email, attachments=attachments)
|
||||
return render_template('email.html', email=email, attachments=attachments, email_account=email_account)
|
||||
|
||||
|
||||
@app.route('/attachments/<path:filename>')
|
||||
@app.route('/<email_account>/attachments/<path:filename>')
|
||||
@auth.login_required
|
||||
def download_file(filename):
|
||||
mimetype = magic.from_file(str(Path('attachments', filename)), mime=True)
|
||||
return send_from_directory('attachments', filename, mimetype=mimetype)
|
||||
def download_file(email_account, filename):
|
||||
p = Path(os.environ.get('EMAIL_ARCHIVE_ROOT'), email_account, 'attachments', filename)
|
||||
if not p.exists():
|
||||
return 404
|
||||
mimetype = magic.from_file(str(p), mime=True)
|
||||
return send_from_directory(Path(os.environ.get('EMAIL_ARCHIVE_ROOT'), email_account, 'attachments'), filename, mimetype=mimetype)
|
||||
|
||||
|
||||
def get_db_connection(email_account):
|
||||
conn = sqlite3.connect(os.path.join(os.environ.get('EMAIL_ARCHIVE_ROOT'), email_account, 'emails.db'))
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Email Folders</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Email Folders</h1>
|
||||
<h3>{{ email_account }}</h3>
|
||||
<ul>
|
||||
{% for folder in folders %}
|
||||
<li><a href="{{ url_for('folder', email_account=email_account, table_name=folder.table_name) }}">{{ folder.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h1>Last Syncs</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Type</th>
|
||||
<th>New Emails</th>
|
||||
<th>New Attachments</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
{% for sync in syncs %}
|
||||
<tr>
|
||||
<td>{{ sync.timestamp }}</td>
|
||||
<td>{{ sync.type }}</td>
|
||||
<td>{{ sync.new_emails }}</td>
|
||||
<td>{{ sync.new_attachments }}</td>
|
||||
<td>{{ sync.duration }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
<style>
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
</style>
|
||||
</html>
|
|
@ -8,7 +8,7 @@
|
|||
<h2>Attachments</h2>
|
||||
<ul>
|
||||
{% for attachment in attachments %}
|
||||
<a href="{{ url_for('download_file', filename='F' + attachment.hash) }}">{{ attachment.filename }}</a>
|
||||
<a href="{{ url_for('download_file', email_account=email_account, filename='F' + attachment.hash) }}">{{ attachment.filename }}</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h2>Content</h2>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<ul>
|
||||
{% for email in emails %}
|
||||
<li>
|
||||
<a href="{{ url_for('email', table_name=table_name, id=email.id) }}">
|
||||
<a href="{{ url_for('email', email_account=email_account, table_name=table_name, id=email.id) }}">
|
||||
{{ email.timestamp }} | <i>{{ email.from_email }}</i> - <strong>{{ email.subject }}</strong>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,39 +1,14 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Email Folders</title>
|
||||
<title>Email Archive</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Email Folders</h1>
|
||||
<h3>Accounts</h3>
|
||||
<ul>
|
||||
{% for folder in folders %}
|
||||
<li><a href="{{ url_for('folder', table_name=folder.table_name) }}">{{ folder.name }}</a></li>
|
||||
{% for account in accounts %}
|
||||
<li><a href="/{{ account }}">{{ account }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h1>Last Syncs</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Type</th>
|
||||
<th>New Emails</th>
|
||||
<th>New Attachments</th>
|
||||
<th>New Folders</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
{% for sync in syncs %}
|
||||
<tr>
|
||||
<td>{{ sync.timestamp }}</td>
|
||||
<td>{{ sync.type }}</td>
|
||||
<td>{{ sync.new_emails }}</td>
|
||||
<td>{{ sync.new_attachments }}</td>
|
||||
<td>{{ sync.duration }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
<style>
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue