refined README, specify testing mode via ENV variable
This commit is contained in:
parent
bd20839335
commit
170fb6c3ae
20
README.md
20
README.md
@ -1 +1,19 @@
|
|||||||
# codimd_note_overview
|
# CodiMD note overview
|
||||||
|
|
||||||
|
a searchable list of existing markdown files from CodiMD, i.e., [https://hackmd.wiai.de/](https://hackmd.wiai.de/), featuring sortable columns and fancy emojis where applicable.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Testing locally
|
||||||
|
|
||||||
|
|
||||||
|
Execute `docker build . --tag codimd; docker run -p 5000:5000 --env TESTING=True codimd` to run the app in testing mode locally. No database credentials are required for test
|
||||||
|
|
||||||
|
### Open issues
|
||||||
|
|
||||||
|
* make the layout responsive
|
||||||
|
* either read the DB credentials and URL from the environment or the config file
|
||||||
|
* load test data from a local file when run in testing mode
|
||||||
|
* add more/real testing data
|
||||||
|
* the up and down arrows in the table head fields are not invisible
|
||||||
|
* add more emojis ヘ( ^o^)ノ\(^_^ )
|
||||||
|
|||||||
43
src/main.py
43
src/main.py
@ -1,32 +1,31 @@
|
|||||||
import psycopg2
|
import psycopg2
|
||||||
|
|
||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
if os.environ.get('PRODUCTION'):
|
|
||||||
import config
|
|
||||||
else:
|
|
||||||
import config
|
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.debug = True
|
app.debug = True
|
||||||
|
|
||||||
sql_statement = 'SELECT "id","title","alias","shortid","viewcount","lastchangeAt","permission","content" FROM "Notes" ORDER BY "lastchangeAt" DESC;'
|
SQL_FETCH_NOTES = 'SELECT "id","title","alias","shortid","viewcount","lastchangeAt","permission","content" FROM "Notes" ORDER BY "lastchangeAt" DESC;'
|
||||||
|
|
||||||
|
# if the environment contains a variable TESTING that is set to "True" then run the application in testing mode
|
||||||
|
if os.environ.get('TESTING') == "True":
|
||||||
|
ENV_TESTING = True
|
||||||
|
else:
|
||||||
|
ENV_TESTING = False
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def main():
|
def main():
|
||||||
if os.environ.get('PRODUCTION'):
|
if ENV_TESTING:
|
||||||
return production()
|
|
||||||
else:
|
|
||||||
return testing()
|
return testing()
|
||||||
|
else:
|
||||||
|
return production()
|
||||||
|
|
||||||
|
|
||||||
def production():
|
def production():
|
||||||
|
import config
|
||||||
DB_HOST = os.environ.get('DB_HOST')
|
DB_HOST = os.environ.get('DB_HOST')
|
||||||
DB_NAME = os.environ.get('POSTGRES_DB')
|
DB_NAME = os.environ.get('POSTGRES_DB')
|
||||||
DB_USER = os.environ.get('POSTGRES_USER')
|
DB_USER = os.environ.get('POSTGRES_USER')
|
||||||
@ -36,7 +35,7 @@ def production():
|
|||||||
conn = psycopg2.connect(host=DB_HOST, database=DB_NAME, user=DB_USER,
|
conn = psycopg2.connect(host=DB_HOST, database=DB_NAME, user=DB_USER,
|
||||||
password=DB_PASSWORD)
|
password=DB_PASSWORD)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute(sql_statement)
|
cur.execute(SQL_FETCH_NOTES)
|
||||||
notes = cur.fetchall()
|
notes = cur.fetchall()
|
||||||
cur.close()
|
cur.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -74,22 +73,10 @@ def testing():
|
|||||||
'permission': "freely"
|
'permission': "freely"
|
||||||
}
|
}
|
||||||
|
|
||||||
notes_arr.append(x)
|
for _ in range(20):
|
||||||
notes_arr.append(x)
|
notes_arr.append(x)
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
notes_arr.append(x)
|
|
||||||
|
|
||||||
return render_template('index.html', notes=notes_arr, host=config.CODI_URL)
|
return render_template('index.html', notes=notes_arr, host="localhost")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
table.dataTable thead .sorting:after,
|
|
||||||
table.dataTable thead .sorting:before,
|
|
||||||
table.dataTable thead .sorting_asc:after,
|
|
||||||
table.dataTable thead .sorting_asc:before,
|
|
||||||
table.dataTable thead .sorting_asc_disabled:after,
|
|
||||||
table.dataTable thead .sorting_asc_disabled:before,
|
|
||||||
table.dataTable thead .sorting_desc:after,
|
|
||||||
table.dataTable thead .sorting_desc:before,
|
|
||||||
table.dataTable thead .sorting_desc_disabled:after,
|
|
||||||
table.dataTable thead .sorting_desc_disabled:before {
|
|
||||||
bottom: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataTables_length, .dataTables_info, .dataTables_paginate {
|
|
||||||
visibility: hidden
|
|
||||||
}
|
|
||||||
11
src/static/css/style.css
Normal file
11
src/static/css/style.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
/* Hide stuff from dataTables that we do not neeed */
|
||||||
|
.dataTables_length, .dataTables_info, .dataTables_paginate {
|
||||||
|
visibility: hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add some spacing above and below the search field */
|
||||||
|
.dataTables_filter {
|
||||||
|
padding-top: 10%;
|
||||||
|
padding-bottom: 10%;
|
||||||
|
}
|
||||||
7
src/static/js/script.js
Normal file
7
src/static/js/script.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
// make the table a dataTable and show all entries by default
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#example').DataTable({
|
||||||
|
"lengthMenu": [[-1], ["All"]]
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,5 +0,0 @@
|
|||||||
$(document).ready(function () {
|
|
||||||
$('#example').DataTable({
|
|
||||||
"lengthMenu": [[-1],["All"]]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -3,24 +3,26 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>CodiMD Notes</title>
|
<title>CodiMD notes</title>
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/jquery.dataTables.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.13/js/dataTables.bootstrap4.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.13/js/dataTables.bootstrap4.min.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='libs/bootstrap.min.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='libs/bootstrap.min.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
<script src="{{ url_for('static', filename='js/sort.js') }}"></script>
|
|
||||||
|
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-light bg-light">
|
<nav class="navbar navbar-light bg-light">
|
||||||
<a class="navbar-brand" href="#">
|
<a class="navbar-brand" href="#">
|
||||||
<h1>CodiMD Notes</h1>
|
<h1>CodiMD notes</h1>
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- <table id="dtBasicExample" class="table table-striped table-bordered table-sm" cellspacing="0" width="100%"> -->
|
|
||||||
<table id="example" class="table table-striped table-inverse table-bordered table-hover" cellspacing="0" width="100%">
|
<table id="example" class="table table-striped table-inverse table-bordered table-hover" cellspacing="0" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -35,7 +37,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for note in notes %}
|
{% for note in notes %}
|
||||||
<tr>
|
<tr>
|
||||||
<td scope="row"><a class="" href="{{host}}/{{note['shortid']}}">{{note['shortid']}}</a></td>
|
<td scope="row"><a href="{{host}}/{{note['shortid']}}" target="_blank">{{note['shortid']}}</a></td>
|
||||||
<td>{{note['title']}}</td>
|
<td>{{note['title']}}</td>
|
||||||
<td>{{note['alias']}}</td>
|
<td>{{note['alias']}}</td>
|
||||||
<td><span class="note-date">{{note['lastchangeAt'].strftime('%d.%m.%Y %H:%M')}}</span></td>
|
<td><span class="note-date">{{note['lastchangeAt'].strftime('%d.%m.%Y %H:%M')}}</span></td>
|
||||||
@ -45,7 +47,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<!-- </div> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user