Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23b0819079 | ||
|
|
9fcaf72457 | ||
|
|
0df4bf926b | ||
|
|
fe26621221 | ||
|
|
b47fdac633 | ||
|
|
b18c83a8ca | ||
|
|
a21dc5f73f | ||
|
|
0d4eec9c80 | ||
|
|
8db34a6d74 | ||
|
|
a79dc7742b | ||
|
|
76b5ebb53d | ||
|
|
ab2d4b04ad | ||
|
|
63895052f0 | ||
|
|
6fce468dc0 | ||
|
|
7e6043891d | ||
|
|
c500214da0 | ||
|
|
6ebc172aac | ||
|
|
2b8ce9c4c8 | ||
|
|
0fcb5e9b7b | ||
|
|
b40cb00d4d | ||
|
|
567f736d0d | ||
|
|
a2f47b4730 | ||
|
|
1df0feeea0 | ||
|
|
d76a02ed26 | ||
|
|
ab734d7ef1 | ||
|
|
8b78fa2480 | ||
|
|
fdcf2c3d96 | ||
|
|
86989a00fd | ||
|
|
19f6e3940e | ||
|
|
60a5d598fc | ||
|
|
249ff7a5f3 | ||
|
|
931448bc05 | ||
|
|
03863b0250 | ||
|
|
f4fd5a6dac | ||
|
|
17c3ca4a90 | ||
|
|
d0c38799e2 | ||
|
|
1d62847284 | ||
|
|
d8708fe173 | ||
|
|
5d8939bad3 | ||
|
|
12c2a13c89 | ||
|
|
ca9d826386 | ||
|
|
6df8673ac1 | ||
|
|
4312e3e683 | ||
|
|
174dfa3b52 | ||
|
|
e03ce3174a | ||
|
|
8a6599354e | ||
|
|
525d4ee431 | ||
|
|
2c0f4e1fab | ||
|
|
e55b0b7613 | ||
|
|
f3124628cb | ||
|
|
2de4f9af9c | ||
|
|
1ee6a96d58 | ||
|
|
db4a7cc46e | ||
|
|
9483193ebb | ||
|
|
f8efe51891 | ||
|
|
e7cc0ed609 | ||
|
|
665c8e905d | ||
|
|
b907c1a546 | ||
|
|
d20f558232 | ||
|
|
96230b38ef | ||
|
|
00171b10e5 | ||
|
|
f7f3c6f100 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
.venv/
|
||||
.vscode/
|
||||
|
||||
*.pyc
|
||||
__pycache__/
|
||||
@@ -16,3 +17,4 @@ build/
|
||||
/myriad/static/blinkies
|
||||
/myriad/static/stamps
|
||||
myriad/static/tmp
|
||||
myriad/static/misc
|
||||
|
||||
141
README.md
141
README.md
@@ -1,6 +1,6 @@
|
||||
# myriad
|
||||
|
||||
flask app for plurals to publicly share member lists
|
||||
flask app for plural systems to publicly share member lists. the software is in basically a usable state right now, just be sure to keep regular backups. documentation is fairly limited but we're working on that. drop an email to `myriad [at] cubes [dot] link` if you wanna contact us about this project :)
|
||||
|
||||
logged in users are presumed to all be admins with distinction only between being logged in and not
|
||||
|
||||
@@ -10,140 +10,29 @@ the blinkies and stamps stuff is literally just because i want an easy way to up
|
||||
|
||||
make sure blinkies are actually blinkie-sized, and stamps are likewise stamp-sized. too much variation in size will make the layout weird. there's not validation because its designed just to make uploading the images not require ftp + manual code as i had been doing before.
|
||||
|
||||
# dev set up (windows)
|
||||
# A note on data export/import
|
||||
|
||||
- after cloning, run `py -3 -m venv .venv` in the root directory and then `.venv\Scripts\activate`
|
||||
- then `pip install Flask` inside the virtual env
|
||||
- you might also need to init a database, so use `flask --app myriad init-db`
|
||||
- to start the site use `flask --app myriad run --debug`
|
||||
there are currently various ways to export and import data for use within myriad. individual member exports and imports deal only with the fields (though icons, stamps, and blinkies can be exported to a zip folder). they're designed to be used with an active database for whatever purpose the user requires.
|
||||
|
||||
do not deploy this way, the packaged flask server is not secure. production instructions will be provided when the project is ready
|
||||
the other option is to export the entire system to json or zip file. **importing an entire system is best used on a completely empty database, as it deals with inserting id fields**. a full system import is useful for when an update is released that requires the database to be re-initialised, you can quickly restore information and images you had before.
|
||||
|
||||
- you will need to run `.venv\Scripts\activate` from the folder every time you start working on it
|
||||
- re-building the entire database with `flask --app myriad init-db` (losing all the data inside) will be necessary as development continues. DO NOT STORE ANYTHING IMPORTANT DURING DEVELOPMENT
|
||||
- start the site with `flask --app myriad run --debug` as usual
|
||||
both are a little janky as they've just been implemented rather quickly to cover the base requirement of being able to migrate the database in some form. **don't rely on them, be sure to keep your own backups**.
|
||||
|
||||
# prod set up (linux)
|
||||
**individual member import via zip folder is not currently possible**
|
||||
|
||||
it is recommended to run waitress in a tmux window for easier management
|
||||
# Development set up (Windows)
|
||||
|
||||
create new tmux window
|
||||
[Dev instructions are here](https://tea.cubes.link/cube/myriad/wiki/Development-setup-%28Windows%29)
|
||||
|
||||
`tmux new -s myriad`
|
||||
# Deployment
|
||||
|
||||
detach from tmux window
|
||||
[Deployment instructions are here](https://tea.cubes.link/cube/myriad/wiki/deployment-instructions)
|
||||
|
||||
`ctrl+b` -> `d`
|
||||
# Usage
|
||||
|
||||
attach to existing tmux window
|
||||
- The software here is free to use, and there's no requirement to link back
|
||||
- Edit the styles and functionality to suit your needs. I'm sure some of you out there are far better with CSS than us
|
||||
|
||||
`tmux attach -t myriad`
|
||||
# Preview
|
||||
|
||||
## installing
|
||||
|
||||
clone the repo and set up virtual env
|
||||
|
||||
`git clone https://tea.cubes.link/cube/myriad.git`
|
||||
|
||||
`cd myriad`
|
||||
|
||||
`python3 -m venv venv`
|
||||
|
||||
`source venv/bin/activate`
|
||||
|
||||
install necessary packages in the virtual env
|
||||
|
||||
`pip install flask`
|
||||
|
||||
`pip install waitress`
|
||||
|
||||
make sure all directories exist
|
||||
|
||||
`mkdir instance`
|
||||
|
||||
`mkdir myriad/static/icons`
|
||||
|
||||
`mkdir myriad/static/blinkies`
|
||||
|
||||
`mkdir myriad/static/stamps`
|
||||
|
||||
`mkdir myriad/static/tmp`
|
||||
|
||||
copy sample from readme and paste into the following
|
||||
|
||||
`sudo nano instance/config.py`
|
||||
|
||||
in a window where you can copy the output, (or in python itself) generate a secret key and copy it to the clipboard
|
||||
|
||||
`python -c 'import secrets; print(secrets.token_hex())'`
|
||||
|
||||
add a new line to config.py and paste in the key
|
||||
|
||||
`SECRET_KEY = '(paste generated key here)'`
|
||||
|
||||
initialize the database
|
||||
|
||||
`flask --app myriad init-db`
|
||||
|
||||
start running the site
|
||||
|
||||
`waitress-serve --port=80 --call 'myriad:create_app'`
|
||||
|
||||
after running and setting up first user stop waitress (CTRL+C), then edit the config to disable user registration for security
|
||||
|
||||
`sudo nano instance/config.py`
|
||||
|
||||
`REGISTRATION = False`
|
||||
|
||||
once you have disabled registration you will need to go to /auth/login in order to log in. removing the link in the sidebar just (slightly) obfuscates the possibilty from passing users
|
||||
|
||||
## updating
|
||||
|
||||
stop waitress (CTRL+C) and use `git pull` to pull changes
|
||||
|
||||
start waitress again to reload
|
||||
|
||||
if it is a database changing update, use backup features, re-init db, then re-import from backup
|
||||
|
||||
|
||||
# config
|
||||
|
||||
- create `config.py` in the instance folder and customise the following settings to your needs
|
||||
|
||||
```
|
||||
REGISTRATION = True # Make sure to disable in production
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} # Can be anything you want
|
||||
ICON_UPLOAD_FOLDER = 'myriad/static/icons' # where member icons will be stored
|
||||
BLINKIES_UPLOAD_FOLDER = 'myriad/static/blinkies' # where site assets "blinkies" will be stored
|
||||
STAMPS_UPLOAD_FOLDER = 'myriad/static/stamps' # where site assets "stamps" will be stored
|
||||
THEMES_FOLDER = 'myriad/static/themes' # where theme choices will be stored
|
||||
TMP_FOLDER = 'myriad/static/tmp' # folder for creating export files
|
||||
```
|
||||
|
||||
# usage
|
||||
|
||||
- the software here is free to use, and there's no requirement to link back
|
||||
- edit the styles and functionality to suit your needs. i'm sure some of you out there are far better with CSS than I am
|
||||
|
||||
# dependencies
|
||||
|
||||
- Flask
|
||||
|
||||
# preview
|
||||
|
||||
- these screenshots are all from the public viewer's perspective
|
||||
|
||||
- homepage with pinned members
|
||||

|
||||
|
||||
- main blog post feed
|
||||

|
||||
|
||||
- member page showing their uploaded icons (just about)
|
||||

|
||||
|
||||
- groups view
|
||||

|
||||
|
||||
- a sample part of the administration
|
||||

|
||||
[Check out our own personal instance](https://system.cubes.link)
|
||||
@@ -1,9 +1,11 @@
|
||||
import os
|
||||
import os, datetime
|
||||
|
||||
from flask import Flask
|
||||
from myriad.utilities import server_time, get_datetime_str, remove_html
|
||||
from myriad.db import get_db
|
||||
|
||||
|
||||
def create_app(test_config=None):
|
||||
def create_app():
|
||||
# create and configure the app
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
app.config.from_pyfile('config.py')
|
||||
@@ -33,6 +35,16 @@ def create_app(test_config=None):
|
||||
def get_themes():
|
||||
themes = os.listdir(app.config["THEMES_FOLDER"])
|
||||
return themes
|
||||
return dict(get_themes=get_themes)
|
||||
def w_server_time():
|
||||
return server_time()
|
||||
def w_get_datetime_str(dt_obj):
|
||||
return get_datetime_str(dt_obj)
|
||||
def get_member(mid):
|
||||
db = get_db()
|
||||
member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone()
|
||||
return member
|
||||
|
||||
|
||||
return dict(get_themes=get_themes, server_time=w_server_time, get_datetime_str=w_get_datetime_str, get_member=get_member, remove_html=remove_html)
|
||||
|
||||
return app
|
||||
|
||||
@@ -14,9 +14,7 @@ def login_required(view):
|
||||
def wrapped_view(**kwargs):
|
||||
if g.user is None:
|
||||
return redirect(url_for('auth.login'))
|
||||
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
|
||||
|
||||
@@ -27,9 +25,7 @@ def load_logged_in_user():
|
||||
if user_id is None:
|
||||
g.user = None
|
||||
else:
|
||||
g.user = get_db().execute(
|
||||
'SELECT * FROM user WHERE id = ?', (user_id,)
|
||||
).fetchone()
|
||||
g.user = get_db().execute('SELECT * FROM user WHERE id = ?', (user_id,)).fetchone()
|
||||
|
||||
|
||||
|
||||
@@ -50,10 +46,7 @@ def register():
|
||||
|
||||
if error is None:
|
||||
try:
|
||||
db.execute(
|
||||
"INSERT INTO user (username, password) VALUES (?, ?)",
|
||||
(username, generate_password_hash(password)),
|
||||
)
|
||||
db.execute("INSERT INTO user (username, password) VALUES (?, ?)",(username, generate_password_hash(password)),)
|
||||
db.commit()
|
||||
except db.IntegrityError:
|
||||
error = f"User {username} is already registered."
|
||||
@@ -71,9 +64,7 @@ def login():
|
||||
password = request.form['password']
|
||||
db = get_db()
|
||||
error = None
|
||||
user = db.execute(
|
||||
'SELECT * FROM user WHERE username = ?', (username,)
|
||||
).fetchone()
|
||||
user = db.execute('SELECT * FROM user WHERE username = ?', (username,)).fetchone()
|
||||
|
||||
if user is None:
|
||||
error = 'Incorrect username.'
|
||||
|
||||
@@ -3,6 +3,7 @@ from flask import (
|
||||
)
|
||||
from werkzeug.utils import secure_filename
|
||||
import os, uuid
|
||||
from myriad.utilities import server_time, get_datetime_obj, get_datetime_str
|
||||
|
||||
from myriad.auth import login_required
|
||||
from myriad.db import get_db
|
||||
@@ -29,15 +30,16 @@ def blog():
|
||||
@login_required
|
||||
def new():
|
||||
db = get_db()
|
||||
members = db.execute("SELECT id,member_name FROM member").fetchall()
|
||||
members = db.execute("SELECT id,member_name FROM member ORDER BY member_name COLLATE NOCASE").fetchall()
|
||||
|
||||
if request.method == 'POST':
|
||||
title = request.form['title']
|
||||
content = request.form['content']
|
||||
mid = request.form["mid"]
|
||||
privacy = request.form["privacy"]
|
||||
created = get_datetime_obj(server_time())
|
||||
|
||||
db.execute("INSERT INTO blog (member_id, title, content, public) VALUES (?, ?, ?, ?)",(mid, title, content, privacy))
|
||||
db.execute("INSERT INTO blog (member_id, title, content, public, created) VALUES (?, ?, ?, ?, ?)",(mid, title, content, privacy, created))
|
||||
db.commit()
|
||||
|
||||
return redirect(url_for('blog.blog'))
|
||||
|
||||
@@ -12,7 +12,24 @@ bp = Blueprint('home', __name__)
|
||||
def index():
|
||||
db = get_db()
|
||||
fronters = db.execute("SELECT * FROM member WHERE front=(?) ORDER BY member_name",(1,)).fetchall()
|
||||
homepage = db.execute("SELECT * FROM member WHERE homepage=(?) ORDER BY member_name",(1,)).fetchall()
|
||||
homepage = db.execute("SELECT * FROM member WHERE homepage=(?) ORDER BY member_name COLLATE NOCASE",(1,)).fetchall()
|
||||
|
||||
latest_start = db.execute("SELECT start_time FROM front_log ORDER BY start_time DESC").fetchone()
|
||||
latest_end = db.execute("SELECT end_time FROM front_log ORDER BY end_time DESC").fetchone()
|
||||
|
||||
latest = None
|
||||
if latest_start and latest_end:
|
||||
start = latest_start[0]
|
||||
end = latest_end[0]
|
||||
if end:
|
||||
if start > end:
|
||||
latest = start
|
||||
else:
|
||||
latest = end
|
||||
else:
|
||||
latest = start
|
||||
elif latest_start and not latest_end:
|
||||
latest = latest_start[0]
|
||||
|
||||
icons={}
|
||||
for member in homepage:
|
||||
@@ -24,12 +41,12 @@ def index():
|
||||
else:
|
||||
icons[member[0]] = None
|
||||
|
||||
return render_template('index.html', front_list=fronters, home_pins=homepage, icons=icons)
|
||||
return render_template('index.html', front_list=fronters, home_pins=homepage, icons=icons, last_updated=latest)
|
||||
|
||||
@bp.route('/full')
|
||||
def full_list():
|
||||
db = get_db()
|
||||
members = db.execute('SELECT * FROM member ORDER BY member_name').fetchall()
|
||||
members = db.execute('SELECT * FROM member ORDER BY member_name COLLATE NOCASE').fetchall()
|
||||
|
||||
icons={}
|
||||
for member in members:
|
||||
@@ -52,8 +69,14 @@ def page(mid):
|
||||
all_icons = db.execute("SELECT icon_location FROM icons WHERE member_id=(?)",(mid,)).fetchall()
|
||||
blinkies = db.execute("SELECT blinkie_location FROM blinkies WHERE member_id=(?)",(mid,)).fetchall()
|
||||
stamps = db.execute("SELECT stamp_location FROM stamps WHERE member_id=(?)",(mid,)).fetchall()
|
||||
blog_public = db.execute("SELECT * FROM blog WHERE member_id=(?) AND public=(?)",(mid,1)).fetchall()
|
||||
sections = db.execute("SELECT * FROM sections WHERE member_id=(?) ORDER BY position ASC",(mid,)).fetchall()
|
||||
|
||||
return render_template('page.html', member=member, blog=blog, icon=icon, all_icons=all_icons, blinkies=blinkies, stamps=stamps)
|
||||
blog_public_show = False
|
||||
if len(blog_public) > 0:
|
||||
blog_public_show = True
|
||||
|
||||
return render_template('page.html', member=member, blog=blog, icon=icon, all_icons=all_icons, blinkies=blinkies, stamps=stamps, blog_public_show=blog_public_show, sections=sections)
|
||||
|
||||
@bp.route("/groups")
|
||||
def groups():
|
||||
|
||||
261
myriad/manage.py
261
myriad/manage.py
@@ -2,9 +2,11 @@ from flask import Blueprint, flash, g, redirect, render_template, request, sessi
|
||||
|
||||
from werkzeug.utils import secure_filename
|
||||
import os, uuid, json, zipfile, datetime
|
||||
from myriad.utilities import server_time, get_datetime_obj, server_time_obj
|
||||
|
||||
from myriad.auth import login_required
|
||||
from myriad.db import get_db
|
||||
from myriad.utilities import get_datetime_str
|
||||
|
||||
bp = Blueprint('manage', __name__, url_prefix='/manage')
|
||||
|
||||
@@ -16,11 +18,18 @@ def new():
|
||||
subtitle = request.form["subtitle"]
|
||||
bio = request.form['bio']
|
||||
user_id = g.user[0]
|
||||
date_created = get_datetime_obj(server_time())
|
||||
privacy = request.form["privacy"]
|
||||
|
||||
db = get_db()
|
||||
|
||||
db.execute("INSERT INTO member (user_id, member_name, bio, subtitle) VALUES (?, ?, ?, ?)",(user_id, name, bio, subtitle))
|
||||
db.execute("INSERT INTO member (user_id, member_name, bio, subtitle, created, public) VALUES (?, ?, ?, ?, ?, ?)",(user_id, name, bio, subtitle, date_created, privacy))
|
||||
db.commit()
|
||||
return redirect(url_for('home.full_list'))
|
||||
|
||||
last = db.execute('SELECT last_insert_rowid()').fetchone()
|
||||
new_mid = last[0]
|
||||
|
||||
return redirect(url_for('manage.edit', mid=new_mid))
|
||||
|
||||
return render_template('manage/new.html')
|
||||
|
||||
@@ -29,7 +38,6 @@ def new():
|
||||
def import_member_route():
|
||||
db = get_db()
|
||||
response=""
|
||||
data=None
|
||||
mid=None
|
||||
|
||||
if request.method=="POST":
|
||||
@@ -74,6 +82,30 @@ def edit(mid):
|
||||
|
||||
edit_location = "details"
|
||||
|
||||
if "page_settings" in request.form:
|
||||
show_groups = "show_groups" in request.form
|
||||
show_blog = "show_blog" in request.form
|
||||
show_icons = "show_icons" in request.form
|
||||
show_blinkies = "show_blinkies" in request.form
|
||||
show_stamps = "show_stamps" in request.form
|
||||
|
||||
db.execute("UPDATE member SET show_groups=(?), show_blog=(?), show_icons=(?), show_blinkies=(?), show_stamps=(?) WHERE id=(?)",(show_groups, show_blog, show_icons, show_blinkies, show_stamps, mid))
|
||||
db.commit()
|
||||
|
||||
edit_location = "page_settings"
|
||||
|
||||
if "section_titles" in request.form:
|
||||
groups_title = request.form["groups_title"]
|
||||
blog_title = request.form["blog_title"]
|
||||
icons_title = request.form["icons_title"]
|
||||
blinkies_title = request.form["blinkies_title"]
|
||||
stamps_title = request.form["stamps_title"]
|
||||
|
||||
db.execute("UPDATE member SET groups_title=(?), blog_title=(?), icons_title=(?), blinkies_title=(?), stamps_title=(?) WHERE id=(?)",(groups_title, blog_title, icons_title, blinkies_title, stamps_title, mid))
|
||||
db.commit()
|
||||
|
||||
edit_location = "page_settings"
|
||||
|
||||
if "file" in request.files:
|
||||
# here we are just saving the uploaded file to the icons folder.
|
||||
# we're not going hard on security because we expect there to only be 1 admin
|
||||
@@ -118,11 +150,32 @@ def edit(mid):
|
||||
|
||||
edit_location = "stamps"
|
||||
|
||||
if "new_section" in request.form:
|
||||
section_title = request.form["section_title"]
|
||||
section_content = request.form["section_content"]
|
||||
|
||||
db.execute("INSERT INTO sections (member_id, title, content) VALUES (?, ?, ?)", (mid, section_title, section_content))
|
||||
db.commit()
|
||||
|
||||
edit_location = "sections"
|
||||
|
||||
if "update_section" in request.form:
|
||||
section_id = request.form["section_id"]
|
||||
section_title = request.form["section_title"]
|
||||
section_content = request.form["section_content"]
|
||||
section_position = request.form["section_pos"]
|
||||
|
||||
db.execute("UPDATE sections SET title=(?), content=(?), position=(?) WHERE id=(?)",(section_title, section_content, section_position, section_id))
|
||||
db.commit()
|
||||
|
||||
edit_location = "sections"
|
||||
|
||||
|
||||
member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone()
|
||||
icons = db.execute("SELECT * FROM icons WHERE member_id=(?)",(mid,)).fetchall()
|
||||
blinkies = db.execute("SELECT * FROM blinkies WHERE member_id=(?)",(mid,)).fetchall()
|
||||
stamps = db.execute("SELECT * FROM stamps WHERE member_id=(?)",(mid,)).fetchall()
|
||||
sections = db.execute("SELECT * FROM sections WHERE member_id=(?)",(mid,)).fetchall()
|
||||
|
||||
groups = db.execute("SELECT * FROM groups").fetchall()
|
||||
member_groups = db.execute("SELECT * FROM group_members WHERE member_id=(?)",(mid,)).fetchall()
|
||||
@@ -142,7 +195,18 @@ def edit(mid):
|
||||
|
||||
themes = os.listdir(current_app.config["THEMES_FOLDER"])
|
||||
|
||||
return render_template("manage/edit.html", member=member, icons=icons, unjoined_groups=unjoined_groups, joined_groups=joined_groups, themes=themes, edit_location=edit_location, blinkies=blinkies, stamps=stamps)
|
||||
return render_template("manage/edit.html", member=member, icons=icons, unjoined_groups=unjoined_groups, joined_groups=joined_groups, themes=themes, edit_location=edit_location, blinkies=blinkies, stamps=stamps, sections=sections)
|
||||
|
||||
|
||||
@bp.route("/delete_section/<sid>")
|
||||
@login_required
|
||||
def delete_section(sid):
|
||||
db = get_db()
|
||||
mid = db.execute("SELECT member_id FROM sections WHERE id=(?)",(sid,)).fetchone()[0]
|
||||
db.execute("DELETE FROM sections WHERE id=(?)",(sid,))
|
||||
db.commit()
|
||||
|
||||
return redirect(url_for("manage.edit", mid=mid))
|
||||
|
||||
@bp.route("/set_main_icon/<mid>/<icon_id>")
|
||||
@login_required
|
||||
@@ -194,8 +258,13 @@ def add_to_front(mid,location):
|
||||
db.execute("UPDATE member SET front=(?) WHERE id=(?)",(1, mid))
|
||||
db.commit()
|
||||
|
||||
db.execute("INSERT INTO front_log (member_id, start_time) VALUES (?, ?)",(mid, server_time_obj()))
|
||||
db.commit()
|
||||
|
||||
if location == "home":
|
||||
return redirect(url_for('index'))
|
||||
elif location == "mid":
|
||||
return redirect(url_for('home.page', mid=mid))
|
||||
else:
|
||||
return redirect(url_for('home.full_list'))
|
||||
|
||||
@@ -206,11 +275,27 @@ def remove_front(mid, location):
|
||||
db.execute("UPDATE member SET front=(?) WHERE id=(?)",(0, mid))
|
||||
db.commit()
|
||||
|
||||
current_entry = db.execute("SELECT id FROM front_log WHERE member_id=(?) AND end_time IS NULL",(mid,)).fetchone()
|
||||
current_entry_id = current_entry[0]
|
||||
db.execute("UPDATE front_log SET end_time=(?) WHERE id=(?)",(server_time_obj(), current_entry_id))
|
||||
db.commit()
|
||||
|
||||
if location == "home":
|
||||
return redirect(url_for('index'))
|
||||
elif location == "mid":
|
||||
return redirect(url_for('home.page', mid=mid))
|
||||
else:
|
||||
return redirect(url_for('home.full_list'))
|
||||
|
||||
@bp.route("/delete_front_log/<fid>")
|
||||
@login_required
|
||||
def delete_front_log(fid):
|
||||
db = get_db()
|
||||
db.execute("DELETE FROM front_log WHERE id=(?)",(fid,))
|
||||
db.commit()
|
||||
|
||||
return redirect(url_for('manage.admin'))
|
||||
|
||||
|
||||
@bp.route("/add_to_home/<mid>/<location>")
|
||||
@login_required
|
||||
@@ -221,6 +306,8 @@ def add_to_home(mid, location):
|
||||
|
||||
if location == "home":
|
||||
return redirect(url_for('index'))
|
||||
elif location == "mid":
|
||||
return redirect(url_for('home.page', mid=mid))
|
||||
else:
|
||||
return redirect(url_for('home.full_list'))
|
||||
|
||||
@@ -233,6 +320,8 @@ def remove_home(mid,location):
|
||||
|
||||
if location == "home":
|
||||
return redirect(url_for('index'))
|
||||
elif location == "mid":
|
||||
return redirect(url_for('home.page', mid=mid))
|
||||
else:
|
||||
return redirect(url_for('home.full_list'))
|
||||
|
||||
@@ -255,12 +344,9 @@ def import_groups(groups):
|
||||
def import_member(member):
|
||||
db = get_db()
|
||||
|
||||
date_raw = member["date-created"].split(",")
|
||||
date = date_raw[0]
|
||||
day,month,year = date.split("/")
|
||||
time = date_raw[1]
|
||||
hour,minute,second = time.split(":")
|
||||
date_created = datetime.datetime(int(year), int(month), int(day), int(hour), int(minute), int(second))
|
||||
mid = member["id"]
|
||||
|
||||
date_created_obj = get_datetime_obj(member["date-created"])
|
||||
|
||||
name = member["name"]
|
||||
subtitle = member["subtitle"]
|
||||
@@ -272,9 +358,65 @@ def import_member(member):
|
||||
privacy = 0
|
||||
|
||||
theme = member["theme"]
|
||||
homepage = member["homepage-pin"]
|
||||
|
||||
user_id = 0
|
||||
main_icon_id = ""
|
||||
|
||||
groups = member["groups"]
|
||||
for group in groups:
|
||||
db.execute("INSERT INTO group_members (group_id, member_id) VALUES (?, ?)",(group, mid))
|
||||
db.commit()
|
||||
|
||||
blog = member["blog"]
|
||||
for post in blog:
|
||||
post_date_created = get_datetime_obj(post["date-created"])
|
||||
|
||||
title = post["title"]
|
||||
content = post["content"]
|
||||
|
||||
if post["privacy"] == "public":
|
||||
privacy = 1
|
||||
else:
|
||||
privacy = 0
|
||||
|
||||
db.execute("INSERT INTO blog (member_id, created, title, content, public) VALUES (?, ?, ?, ?, ?)",(mid, post_date_created, title, content, privacy))
|
||||
db.commit()
|
||||
|
||||
icons = member["icons"]
|
||||
for icon in icons:
|
||||
db.execute("INSERT INTO icons (member_id, icon_location) VALUES (?, ?)",(mid, icon))
|
||||
db.commit()
|
||||
if icon == member["main-icon"]:
|
||||
last = db.execute('SELECT last_insert_rowid()').fetchone()
|
||||
main_icon_id = last[0]
|
||||
|
||||
blinkies = member["blinkies"]
|
||||
for blinkie in blinkies:
|
||||
db.execute("INSERT INTO blinkies (member_id, blinkie_location) VALUES (?, ?)",(mid, blinkie))
|
||||
db.commit()
|
||||
|
||||
stamps = member["stamps"]
|
||||
for stamp in stamps:
|
||||
db.execute("INSERT INTO stamps (member_id, stamp_location) VALUES (?, ?)",(mid, stamp))
|
||||
db.commit()
|
||||
|
||||
show_blog = member["show-blog"]
|
||||
show_icons = member["show-icons"]
|
||||
show_blinkies = member["show-blinkies"]
|
||||
show_stamps = member["show-stamps"]
|
||||
show_groups = member["show-groups"]
|
||||
|
||||
blog_title = member["blog-title"]
|
||||
icons_title = member["icons-title"]
|
||||
blinkies_title = member["blinkies-title"]
|
||||
stamps_title = member["stamps-title"]
|
||||
groups_title = member["groups-title"]
|
||||
|
||||
db.execute("INSERT INTO member (id,created,user_id, member_name,subtitle, bio,public,theme,homepage,main_icon,show_blog,show_icons,show_blinkies,show_stamps,show_groups,blog_title,icons_title,blinkies_title,stamps_title,groups_title) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
(mid, date_created_obj, user_id, name, subtitle, description,privacy, theme, homepage, main_icon_id, show_blog, show_icons, show_blinkies, show_stamps, show_groups, blog_title, icons_title, blinkies_title, stamps_title, groups_title))
|
||||
db.commit()
|
||||
|
||||
#db.execute("INSERT INTO member (created,user_id, member_name, bio,public) VALUES (?, ?, ?, ?, ?)",(data[0], data[1], data[2], data[3], data[4]))
|
||||
#db.commit()
|
||||
|
||||
|
||||
@bp.route("/admin", methods=("GET", "POST"))
|
||||
@@ -295,15 +437,35 @@ def admin():
|
||||
for member in members:
|
||||
import_member(member)
|
||||
|
||||
|
||||
return "<a href='/'>go home</a>"
|
||||
|
||||
elif "zip" in request.files:
|
||||
return "upload zip"
|
||||
file = request.files["zip"]
|
||||
with zipfile.ZipFile(file, "r") as zipf:
|
||||
for f in zipf.namelist():
|
||||
dirs = f.split("/")
|
||||
content_type = dirs[2]
|
||||
filename = dirs[3]
|
||||
|
||||
if content_type == "tmp":
|
||||
system_content = zipf.read(f)
|
||||
system_json = json.loads(system_content.decode())
|
||||
|
||||
groups = system_json["groups"]
|
||||
import_groups(groups)
|
||||
|
||||
for m in system_json["members"]:
|
||||
import_member(m)
|
||||
|
||||
else:
|
||||
zipf.extract(f)
|
||||
|
||||
return "<a href='/'>go home</a>"
|
||||
|
||||
users = db.execute("SELECT * FROM user").fetchall()
|
||||
front_log = db.execute("SELECT * FROM front_log ORDER BY start_time DESC").fetchall()
|
||||
|
||||
return render_template("manage/admin.html", users=users)
|
||||
return render_template("manage/admin.html", users=users, front_log=front_log)
|
||||
|
||||
|
||||
|
||||
@@ -318,20 +480,25 @@ def generate_json(mid):
|
||||
member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone()
|
||||
groups_r = db.execute("SELECT group_id FROM group_members WHERE member_id=(?)",(mid,)).fetchall()
|
||||
blog_r = db.execute("SELECT * FROM blog WHERE member_id=(?)",(mid,)).fetchall()
|
||||
icons_r = db.execute("SELECT icon_location FROM icons WHERE member_id=(?)",(mid,)).fetchall()
|
||||
blinkies_r = db.execute("SELECT blinkie_location FROM blinkies WHERE member_id=(?)",(mid,)).fetchall()
|
||||
stamps_r = db.execute("SELECT stamp_location FROM stamps WHERE member_id=(?)",(mid,)).fetchall()
|
||||
|
||||
if member[9] == 1:
|
||||
privacy = "public"
|
||||
member_privacy = "public"
|
||||
else:
|
||||
privacy = "private"
|
||||
member_privacy = "private"
|
||||
|
||||
date_created = member[2].strftime("%d/%m/%Y, %H:%M:%S")
|
||||
date_created = get_datetime_str(member[2])
|
||||
|
||||
homepage = member[7]
|
||||
|
||||
groups = []
|
||||
for group in groups_r:
|
||||
groups.append(group[0])
|
||||
blog = []
|
||||
for post in blog_r:
|
||||
d_c = post[2].strftime("%d/%m/%Y, %H:%M:%S")
|
||||
d_c = get_datetime_str(post[2])
|
||||
|
||||
if post[5] == 1:
|
||||
priv = "public"
|
||||
@@ -350,6 +517,21 @@ def generate_json(mid):
|
||||
|
||||
blog.append(p)
|
||||
|
||||
icons = []
|
||||
for icon in icons_r:
|
||||
icons.append(icon[0])
|
||||
|
||||
main_icon_id = member[6]
|
||||
main_icon = db.execute("SELECT icon_location FROM icons WHERE id=(?)",(main_icon_id,)).fetchone()
|
||||
|
||||
blinkies = []
|
||||
for blinkie in blinkies_r:
|
||||
blinkies.append(blinkie[0])
|
||||
|
||||
stamps = []
|
||||
for stamp in stamps_r:
|
||||
stamps.append(stamp[0])
|
||||
|
||||
|
||||
data = {
|
||||
"id":mid,
|
||||
@@ -358,11 +540,29 @@ def generate_json(mid):
|
||||
"name":member[3],
|
||||
"subtitle":member[4],
|
||||
"description":member[5],
|
||||
"privacy":privacy,
|
||||
"privacy":member_privacy,
|
||||
"theme":member[10],
|
||||
"groups":groups,
|
||||
"blog":blog
|
||||
"blog":blog,
|
||||
"icons":icons,
|
||||
"blinkies":blinkies,
|
||||
"stamps":stamps,
|
||||
"homepage-pin":homepage,
|
||||
"show-blog":member[11],
|
||||
"show-icons":member[12],
|
||||
"show-blinkies":member[13],
|
||||
"show-stamps":member[14],
|
||||
"show-groups":member[15],
|
||||
"blog-title":member[16],
|
||||
"icons-title":member[17],
|
||||
"blinkies-title":member[18],
|
||||
"stamps-title":member[19],
|
||||
"groups-title":member[20]
|
||||
}
|
||||
if main_icon:
|
||||
data["main-icon"] = main_icon[0]
|
||||
else:
|
||||
data["main-icon"] = ""
|
||||
|
||||
return data
|
||||
|
||||
@@ -571,6 +771,22 @@ def assets():
|
||||
filename = file.filename
|
||||
file.save(os.path.join(current_app.config["STAMPS_UPLOAD_FOLDER"], filename))
|
||||
|
||||
if "image" in request.files:
|
||||
file = request.files["image"]
|
||||
filename = file.filename
|
||||
fname, ftype = filename.split(".")
|
||||
|
||||
i = 0
|
||||
if os.path.exists(os.path.join(current_app.config["MISC_UPLOAD_FOLDER"], filename)):
|
||||
i = 2
|
||||
while os.path.exists(os.path.join(current_app.config["MISC_UPLOAD_FOLDER"], fname+str(i)+"."+ftype)):
|
||||
i += 1
|
||||
|
||||
if i == 0:
|
||||
file.save(os.path.join(current_app.config["MISC_UPLOAD_FOLDER"], filename))
|
||||
else:
|
||||
file.save(os.path.join(current_app.config["MISC_UPLOAD_FOLDER"], fname+str(i)+"."+ftype))
|
||||
|
||||
icons = db.execute("SELECT * FROM icons").fetchall()
|
||||
icon_storage = os.listdir(current_app.config["ICON_UPLOAD_FOLDER"])
|
||||
|
||||
@@ -593,8 +809,9 @@ def assets():
|
||||
|
||||
blinkies = os.listdir(current_app.config["BLINKIES_UPLOAD_FOLDER"])
|
||||
stamps = os.listdir(current_app.config["STAMPS_UPLOAD_FOLDER"])
|
||||
images = os.listdir(current_app.config["MISC_UPLOAD_FOLDER"])
|
||||
|
||||
return render_template("manage/assets.html", icons=unlinked_icons, icon_storage=i_storage, blinkies=blinkies, stamps=stamps)
|
||||
return render_template("manage/assets.html", icons=unlinked_icons, icon_storage=i_storage, blinkies=blinkies, stamps=stamps, images=images)
|
||||
|
||||
@bp.route("/delete_idb")
|
||||
@login_required
|
||||
|
||||
@@ -6,7 +6,9 @@ DROP TABLE IF EXISTS group_members;
|
||||
DROP TABLE IF EXISTS blog;
|
||||
DROP TABLE IF EXISTS blinkies;
|
||||
DROP TABLE IF EXISTS stamps;
|
||||
DROP TABLE IF EXISTS front_log;
|
||||
DROP TABLE IF EXISTS sections;
|
||||
DROP TABLE IF EXISTS pages;
|
||||
|
||||
CREATE TABLE user (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -17,7 +19,7 @@ CREATE TABLE user (
|
||||
CREATE TABLE member (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created TIMESTAMP,
|
||||
member_name TEXT NOT NULL,
|
||||
subtitle TEXT DEFAULT "",
|
||||
bio TEXT,
|
||||
@@ -26,6 +28,16 @@ CREATE TABLE member (
|
||||
front BOOLEAN NOT NULL DEFAULT 0,
|
||||
public BOOLEAN NOT NULL DEFAULT 1,
|
||||
theme TEXT NOT NULL DEFAULT 'default',
|
||||
show_blog BOOLEAN NOT NULL DEFAULT 1,
|
||||
show_icons BOOLEAN NOT NULL DEFAULT 1,
|
||||
show_blinkies BOOLEAN NOT NULL DEFAULT 1,
|
||||
show_stamps BOOLEAN NOT NULL DEFAULT 1,
|
||||
show_groups BOOLEAN NOT NULL DEFAULT 1,
|
||||
blog_title TEXT DEFAULT "Blog",
|
||||
icons_title TEXT DEFAULT "Icons",
|
||||
blinkies_title TEXT DEFAULT "Blinkies",
|
||||
stamps_title TEXT DEFAULT "Stamps",
|
||||
groups_title TEXT DEFAULT "Groups",
|
||||
FOREIGN KEY (user_id) REFERENCES user (id),
|
||||
FOREIGN KEY (main_icon) REFERENCES icons (id)
|
||||
);
|
||||
@@ -55,7 +67,7 @@ CREATE TABLE group_members (
|
||||
CREATE TABLE blog (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
member_id INTEGER NOT NULL,
|
||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created TIMESTAMP,
|
||||
title TEXT,
|
||||
content TEXT,
|
||||
public BOOLEAN NOT NULL DEFAULT 1,
|
||||
@@ -76,10 +88,26 @@ CREATE TABLE stamps (
|
||||
FOREIGN KEY (member_id) REFERENCES member (id)
|
||||
);
|
||||
|
||||
CREATE TABLE front_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
member_id INTEGER NOT NULL,
|
||||
start_time TIMESTAMP,
|
||||
end_time TIMESTAMP,
|
||||
FOREIGN KEY (member_id) REFERENCES member (id)
|
||||
);
|
||||
|
||||
CREATE TABLE sections (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
member_id INTEGER NOT NULL,
|
||||
title TEXT,
|
||||
content TEXT,
|
||||
position INTEGER,
|
||||
FOREIGN KEY (member_id) REFERENCES member (id)
|
||||
);
|
||||
|
||||
CREATE TABLE pages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT,
|
||||
content TEXT,
|
||||
position INTEGER
|
||||
);
|
||||
BIN
myriad/static/lock.png
Normal file
BIN
myriad/static/lock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 264 B |
@@ -42,35 +42,6 @@ form textarea{
|
||||
|
||||
|
||||
|
||||
#main{
|
||||
background-color: rgb(255, 255, 255, 0);
|
||||
border-radius: 5px;
|
||||
width: 60%;
|
||||
margin:auto;
|
||||
padding:20px;
|
||||
display:flex;
|
||||
margin-top:20px;
|
||||
}
|
||||
#nav{
|
||||
margin-right:20px;
|
||||
flex:20%;
|
||||
height:fit-content;
|
||||
position:sticky;
|
||||
position: -webkit-sticky;
|
||||
}
|
||||
.navitem{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.container{
|
||||
background-color:#e6f7ff;
|
||||
border-color:#99dfff;
|
||||
border-style:solid;
|
||||
border-width:2px;
|
||||
flex: 80%;
|
||||
padding: 10px;
|
||||
border-radius:5px;
|
||||
}
|
||||
|
||||
.profile{
|
||||
margin:15px;
|
||||
@@ -124,6 +95,33 @@ form textarea{
|
||||
height:100px;
|
||||
float:left;
|
||||
}
|
||||
.manage_images_3{
|
||||
display:block;
|
||||
width:180px;
|
||||
height:100px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.blinkie
|
||||
{
|
||||
height:20px;
|
||||
width:auto;
|
||||
}
|
||||
.stamp
|
||||
{
|
||||
height:56px;
|
||||
width:auto;
|
||||
}
|
||||
.mng_img
|
||||
{
|
||||
height:56px;
|
||||
width:auto;
|
||||
object-fit:scale-down;
|
||||
max-width:180px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -164,9 +162,9 @@ form textarea{
|
||||
|
||||
.title{
|
||||
font-size:20px;
|
||||
display:block;
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
display:block;
|
||||
}
|
||||
.heading.big{
|
||||
font-size:20px;
|
||||
@@ -182,6 +180,17 @@ form textarea{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.lock{
|
||||
float:left;
|
||||
margin-right:10px;
|
||||
}
|
||||
.minilock{
|
||||
width:16px;
|
||||
height:auto;
|
||||
float:left;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
#blog{
|
||||
max-height:300px;
|
||||
overflow-y:scroll;
|
||||
@@ -225,16 +234,96 @@ form textarea{
|
||||
font-size:10px;
|
||||
}
|
||||
|
||||
.log{
|
||||
max-height:300px;
|
||||
overflow-y:scroll;
|
||||
}
|
||||
.image-sections{
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
#mobile-nav{
|
||||
display:none;
|
||||
background-color:#e6f7ff;
|
||||
border-color:#99dfff;
|
||||
border-style:solid;
|
||||
border-width:2px;
|
||||
border-radius:5px;
|
||||
}
|
||||
#main{
|
||||
width:90%;
|
||||
background-color: rgb(255, 255, 255, 0);
|
||||
border-radius: 5px;
|
||||
width: 60%;
|
||||
margin:auto;
|
||||
padding:20px;
|
||||
display:flex;
|
||||
margin-top:20px;
|
||||
}
|
||||
#nav{
|
||||
margin-left:-20px;
|
||||
margin-right:20px;
|
||||
flex:25%;
|
||||
height:fit-content;
|
||||
position:sticky;
|
||||
position: -webkit-sticky;
|
||||
}
|
||||
.navitem{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.container{
|
||||
background-color:#e6f7ff;
|
||||
border-color:#99dfff;
|
||||
border-style:solid;
|
||||
border-width:2px;
|
||||
border-radius:5px;
|
||||
flex: 80%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.mobile{
|
||||
display:none;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px)
|
||||
{
|
||||
#main{
|
||||
width:100%;
|
||||
margin-left:-20px;
|
||||
}
|
||||
.profile{
|
||||
width:100%;
|
||||
margin:auto;
|
||||
margin-top:20px;
|
||||
}
|
||||
#nav{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.mobile{
|
||||
display:inline;
|
||||
}
|
||||
#mobile-nav
|
||||
{
|
||||
display:inline-block;
|
||||
top:0;
|
||||
position:absolute;
|
||||
padding:10px;
|
||||
margin-left:20px;
|
||||
margin-top:10px;
|
||||
}
|
||||
.container{
|
||||
margin-top:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:300px;
|
||||
}
|
||||
.icon{
|
||||
width:80px;
|
||||
height:80px;
|
||||
}
|
||||
.manage_icons_3, .manage_blinkies_3, .manage_stamps_3{
|
||||
clear:both;
|
||||
}
|
||||
}
|
||||
|
||||
43
myriad/static/themes/christmas.css
Normal file
43
myriad/static/themes/christmas.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.christmas{
|
||||
background-color:#fac9c9;
|
||||
border-color:#da1414;
|
||||
color:black;
|
||||
}
|
||||
.christmas .heading
|
||||
{
|
||||
background-color:#c4efd2;
|
||||
border-color:#4e9e81;
|
||||
color:black;
|
||||
}
|
||||
.christmas .heading b
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
.christmas a{
|
||||
color: #329d76;
|
||||
}
|
||||
.christmas a:hover{
|
||||
color: #22694f;
|
||||
}
|
||||
.christmas ::selection {
|
||||
background:#da1414;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.christmas ::-moz-selection {
|
||||
background: #da1414;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
.christmas .icon{
|
||||
border-color:#da1414;
|
||||
}
|
||||
|
||||
body.christmas{
|
||||
background: linear-gradient(90deg, #5abf72 0%, #da1414 50%, #bf8282 100%);
|
||||
scrollbar-color:#da1414 #f49191;
|
||||
}
|
||||
.christmas .container, .christmas #mobile-nav{
|
||||
background-color:#fac9c9;
|
||||
border-color:#da1414;
|
||||
}
|
||||
43
myriad/static/themes/dark-blue.css
Normal file
43
myriad/static/themes/dark-blue.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.dark-blue{
|
||||
background-color:#c9cbfa;
|
||||
border-color:#1438da;
|
||||
color:black;
|
||||
}
|
||||
.dark-blue .heading
|
||||
{
|
||||
background-color:#9691f4;
|
||||
border-color:#142eda;
|
||||
color:black;
|
||||
}
|
||||
.dark-blue .heading b
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
.dark-blue a{
|
||||
color: #141bda;
|
||||
}
|
||||
.dark-blue a:hover{
|
||||
color: #0e1798;
|
||||
}
|
||||
.dark-blue ::selection {
|
||||
background:#144fda;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dark-blue ::-moz-selection {
|
||||
background: #144fda;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dark-blue .icon{
|
||||
border-color:#1438da;
|
||||
}
|
||||
|
||||
body.dark-blue{
|
||||
background: linear-gradient(90deg, #4685fb 0%, #142bda 50%, #0e1598 100%);
|
||||
scrollbar-color:#a414da #d991f4;
|
||||
}
|
||||
.dark-blue .container, .dark-blue #mobile-nav{
|
||||
background-color:#c9cffa;
|
||||
border-color:#142bda;
|
||||
}
|
||||
43
myriad/static/themes/dark-green.css
Normal file
43
myriad/static/themes/dark-green.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.dark-green{
|
||||
background-color:#92dea3;
|
||||
border-color:rgb(60, 138, 105);
|
||||
color:black;
|
||||
}
|
||||
.dark-green .heading
|
||||
{
|
||||
background-color:#75d78b;
|
||||
border-color:#4c9576;
|
||||
color:black;
|
||||
}
|
||||
.dark-green .heading b
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
.dark-green a{
|
||||
color: #379162;
|
||||
}
|
||||
.dark-green a:hover{
|
||||
color: #19533b;
|
||||
}
|
||||
.dark-green ::selection {
|
||||
background:#44b889;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dark-green ::-moz-selection {
|
||||
background: #44b889;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dark-green .icon{
|
||||
border-color:#0e985e;
|
||||
}
|
||||
|
||||
body.dark-green{
|
||||
background: linear-gradient(90deg, #6dad9e 0%, #41da86 50%, #36b78c 100%);
|
||||
scrollbar-color:#5ed3a2 #a8d0c5;
|
||||
}
|
||||
.dark-green .container, .dark-green #mobile-nav{
|
||||
background-color:#c9fae8;
|
||||
border-color:#59d7af;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
.dark{
|
||||
background-color:#1B1F23;
|
||||
background-color:#2c3339;
|
||||
border-color:#000000;
|
||||
color:#D0D5DA;
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
}
|
||||
.dark .heading
|
||||
{
|
||||
background-color:#292F35;
|
||||
background-color:#1B1F23;
|
||||
border-color:#000000;
|
||||
color:#D0D5DA;
|
||||
}
|
||||
@@ -23,12 +23,12 @@
|
||||
color: #D0D5DA;
|
||||
}
|
||||
.dark ::selection {
|
||||
background:#D0D5DA;
|
||||
background:#1B1F23;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.dark ::-moz-selection {
|
||||
background: #D0D5DA;
|
||||
background: #1B1F23;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
@@ -40,7 +40,15 @@ body.dark{
|
||||
background: linear-gradient(90deg, #1B1F23 0%, #1B1F23 50%, #1B1F23 100%);
|
||||
scrollbar-color:#292F35 #373b3e;
|
||||
}
|
||||
.dark .container{
|
||||
background-color:#1B1F23;
|
||||
.dark .container, .dark #mobile-nav{
|
||||
background-color:#2c3339;
|
||||
border-color:black;
|
||||
}
|
||||
.dark .post{
|
||||
border-color:black;
|
||||
background-color:#1B1F23 ;
|
||||
color:white;
|
||||
}
|
||||
.dark #blog .timestamp{
|
||||
color:#959595;
|
||||
}
|
||||
@@ -38,3 +38,7 @@
|
||||
background: linear-gradient(90deg, #00b7ff 0%, #57c785 50%, #eddd53 100%);
|
||||
scrollbar-color:#008bcc #b3e7ff;
|
||||
}
|
||||
.default .container, .default #mobile-nav{
|
||||
background-color:#e6f7ff;
|
||||
border-color:#99dfff;
|
||||
}
|
||||
43
myriad/static/themes/green.css
Normal file
43
myriad/static/themes/green.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.green{
|
||||
background-color:#c9facf;
|
||||
border-color:#14da84;
|
||||
color:black;
|
||||
}
|
||||
.green .heading
|
||||
{
|
||||
background-color:#91f4b7;
|
||||
border-color:#14da88;
|
||||
color:black;
|
||||
}
|
||||
.green .heading b
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
.green a{
|
||||
color: #11c668;
|
||||
}
|
||||
.green a:hover{
|
||||
color: #0e985e;
|
||||
}
|
||||
.green ::selection {
|
||||
background:#14da8b;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.green ::-moz-selection {
|
||||
background: #14da8b;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
.green .icon{
|
||||
border-color:#14da88;
|
||||
}
|
||||
|
||||
body.green{
|
||||
background: linear-gradient(90deg, #67e2ab 0%, #14da8b 50%, #0e986a 100%);
|
||||
scrollbar-color:#14da88 #91f4d8;
|
||||
}
|
||||
.green .container, .green #mobile-nav{
|
||||
background-color:#c9fae8;
|
||||
border-color:#14da9b;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ body.pink-lighter{
|
||||
background: linear-gradient(90deg, #f5c2ea 0%, #e89dfb 50%, #f6959c 100%);
|
||||
scrollbar-color:#a414da #d991f4;
|
||||
}
|
||||
.pink-lighter .container{
|
||||
.pink-lighter .container, .pink-lighter #mobile-nav{
|
||||
background-color:#fac9f6;
|
||||
border-color:#da14c6;
|
||||
}
|
||||
@@ -34,10 +34,10 @@
|
||||
}
|
||||
|
||||
body.pink{
|
||||
background: linear-gradient(90deg, #f8a1e5 0%, #d55ff3 50%, #f5c35e 100%);
|
||||
background: linear-gradient(90deg, rgba(235, 202, 202, 1) 0%, rgba(201, 77, 255, 1) 50%, rgba(242, 234, 124, 1) 100%);
|
||||
scrollbar-color:#a414da #d991f4;
|
||||
}
|
||||
.pink .container{
|
||||
.pink .container, .pink #mobile-nav{
|
||||
background-color:#fac9f6;
|
||||
border-color:#da14c6;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ body.purple{
|
||||
background: linear-gradient(90deg, #fb46c0 0%, #a414da 50%, #720e98 100%);
|
||||
scrollbar-color:#a414da #d991f4;
|
||||
}
|
||||
.purple .container{
|
||||
.purple .container, .purple #mobile-nav{
|
||||
background-color:#ecc9fa;
|
||||
border-color:#a414da;
|
||||
}
|
||||
43
myriad/static/themes/red.css
Normal file
43
myriad/static/themes/red.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.red{
|
||||
background-color:#fac9c9;
|
||||
border-color:#da1414;
|
||||
color:black;
|
||||
}
|
||||
.red .heading
|
||||
{
|
||||
background-color:#f49191;
|
||||
border-color:#da1414;
|
||||
color:black;
|
||||
}
|
||||
.red .heading b
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
.red a{
|
||||
color: #c61111;
|
||||
}
|
||||
.red a:hover{
|
||||
color: #980e0e;
|
||||
}
|
||||
.red ::selection {
|
||||
background:#da1414;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
.red ::-moz-selection {
|
||||
background: #da1414;
|
||||
color: #EEE;
|
||||
text-shadow: none;
|
||||
}
|
||||
.red .icon{
|
||||
border-color:#da1414;
|
||||
}
|
||||
|
||||
body.red{
|
||||
background: linear-gradient(90deg, #fb4646 0%, #da1414 50%, #980e0e 100%);
|
||||
scrollbar-color:#da1414 #f49191;
|
||||
}
|
||||
.red .container, .red #mobile-nav{
|
||||
background-color:#fac9c9;
|
||||
border-color:#da1414;
|
||||
}
|
||||
@@ -8,10 +8,14 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='themes/'+theme) }}">
|
||||
{% endfor %}
|
||||
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div class="container" id="nav">
|
||||
<div class="navitem">{{ server_time() }}</div>
|
||||
<div class="heading">Myriad</div>
|
||||
<div class="navitem">> <a href="{{ url_for('home.index') }}">Home</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('home.full_list') }}">Full List</a></div>
|
||||
@@ -20,8 +24,8 @@
|
||||
{% if g.user %}
|
||||
<div class="heading">Manage</div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.new') }}">Add New Member</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.import_member') }}">Import New Member</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.groups') }}">Member groups</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.import_member_route') }}">Import New Member</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.groups') }}">Manage groups</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.assets') }}">Site Assets</a></div>
|
||||
<div class="navitem">> <a href="{{ url_for('manage.admin') }}">Site Administration</a></div>
|
||||
{% endif %}
|
||||
@@ -47,6 +51,14 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="mobile-nav">
|
||||
<a href="{{ url_for('home.index') }}">Home</a> |
|
||||
<a href="{{ url_for('home.full_list') }}">Full List</a> |
|
||||
<a href="{{ url_for('home.groups') }}">Groups</a> |
|
||||
<a href="{{ url_for('blog.blog') }}">Blog</a> |
|
||||
{% if g.user %}<a class="mobile" href="{{ url_for('manage.admin') }}">Admin</a>{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
{% if g.user %}<a class="mobile" href="{{ url_for('blog.new') }}">New post</a>{% endif %}
|
||||
|
||||
{% for post in blog %}
|
||||
{% set op = member_ids[post[1]] %}
|
||||
{% if not g.user and op[9]==0 %}
|
||||
@@ -19,9 +21,9 @@
|
||||
<img src="{{ url_for('static', filename='any.jpg') }}" class="icon">
|
||||
{% endif %}
|
||||
<div class="title">{{post[3]|safe}}</div>
|
||||
<div class="timestamp">{{post[2]}} - <a href="{{ url_for('home.page', mid=post[1]) }}">{{op[3]}}</a> {% if g.user %}{% if op[9]==0 %}(Private){% else %}(Public)</b>{% endif %}{% endif %}</div>
|
||||
<div class="timestamp">{{ get_datetime_str(post[2]) }} - <a href="{{ url_for('home.page', mid=post[1]) }}">{{op[3]}}</a> {% if g.user %}{% if op[9]==0 %}(Private){% else %}(Public)</b>{% endif %}{% endif %}</div>
|
||||
<div class="content">
|
||||
{{post[4]|safe}}
|
||||
{{post[4].replace('\n', '<br>')|safe}}
|
||||
</div>
|
||||
<br class="clear" />
|
||||
{% if g.user %}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{% for member in memberlist %}
|
||||
{% if not g.user and member[9]==0 %}
|
||||
{% else %}
|
||||
<a href="#m{{ member[0] }}">{{ member[3] }}</a> |
|
||||
<a href="#m{{ member[0] }}">{{ member[3]|safe }}</a> |
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -25,14 +25,14 @@
|
||||
|
||||
{% else %}
|
||||
<div class="profile {{member[10]}}" id="m{{ member[0] }}">
|
||||
<div class="heading"><b>{{ member[3]|safe }}</b> {{ member[4]|safe }}</div>
|
||||
<div class="heading">{% if member[9]==0 %}<img class="minilock" src="{{ url_for('static', filename='lock.png') }}">{% endif %}<b>{{ member[3]|safe }}</b> {{ member[4]|safe }}</div>
|
||||
{% if icons[member[0]] %}
|
||||
<img src="{{ url_for('static', filename='icons/'+icons[member[0]]) }}" class="icon">
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='any.jpg') }}" class="icon">
|
||||
{% endif %}
|
||||
<div class="bio">
|
||||
{{ member[5]|safe }}
|
||||
{{ member[5].replace('\n', '<br>')|safe }}
|
||||
</div>
|
||||
<br class="clear" />
|
||||
<div class="heading links"><a href="{{ url_for('home.page', mid=member[0]) }}">View Page</a>{% if g.user %} ☆ {% if member[8]==0 %}<a href="{{ url_for('manage.add_to_front', mid=member[0],location='full') }}">Add to Front</a>{% else %}<a href="{{ url_for('manage.remove_front', mid=member[0],location='full') }}">Remove from Front</a>{% endif %} ☆ <a href="{{ url_for('manage.edit', mid=member[0]) }}">Edit</a> ☆ {% if member[7]==0 %}<a href="{{ url_for('manage.add_to_home', mid=member[0],location='full') }}">Pin to Homepage</a>{% else %}<a href="{{ url_for('manage.remove_home', mid=member[0],location='full') }}">Unpin from Homepage</a>{% endif %}{% endif %}</div>
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
{{group[2]}}<br><br>
|
||||
{% if group[0] in group_members %}
|
||||
{% for member in group_members[group[0]] %}
|
||||
✰ <a href="{{ url_for('home.page', mid=member[0]) }}">{{ member[3] }}</a> <br>
|
||||
{% if not g.user and member[9]==0 %}
|
||||
{% else %}
|
||||
✰ <a href="{{ url_for('home.page', mid=member[0]) }}">{{ member[3]|safe }}</a> <br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
{% if front_list|length > 0 %}
|
||||
<div id="frontbanner" class="heading">
|
||||
<b>currently fronting: </b> {% for member in front_list %}{% if not g.user and member[9]==0 %}{% else %}<a href="{{ url_for('home.page', mid=member[0]) }}">{{ member[3] }}</a> {% if front_list.index(member) != front_list|length -1 %}&{% endif %}{% endif %} {% endfor %}
|
||||
</div>
|
||||
{% if front_list|length > 0 %}
|
||||
<b>currently fronting: </b> {% for member in front_list %}{% if not g.user and member[9]==0 %}{% else %}<a href="{{ url_for('home.page', mid=member[0]) }}">{{ member[3]|safe }}</a> {% if front_list.index(member) != front_list|length -1 %}&{% endif %}{% endif %} {% endfor %}
|
||||
{% else %}
|
||||
<p>There are currently no members listed as fronting</p>
|
||||
<i><sub>There are currently no members listed as fronting</sub></i>
|
||||
{% endif %}
|
||||
{% if last_updated %}<br><i><sub>last updated: {{ get_datetime_str(last_updated) }}</sub></i>{% endif %}
|
||||
</div>
|
||||
|
||||
{% for member in home_pins %}
|
||||
|
||||
@@ -19,14 +20,14 @@
|
||||
|
||||
|
||||
<div class="profile {{member[10]}}" id="m{{ member[0] }}">
|
||||
<div class="heading"><b>{{ member[3]|safe }}</b> {{ member[4]|safe }}</div>
|
||||
<div class="heading">{% if member[9]==0 %}<img class="minilock" src="{{ url_for('static', filename='lock.png') }}">{% endif %}<b>{{ member[3]|safe }}</b> {{ member[4]|safe }}</div>
|
||||
{% if icons[member[0]] %}
|
||||
<img src="{{ url_for('static', filename='icons/'+icons[member[0]]) }}" class="icon">
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='any.jpg') }}" class="icon">
|
||||
{% endif %}
|
||||
<div class="bio">
|
||||
{{ member[5]|safe }}
|
||||
{{ member[5].replace('\n', '<br>')|safe }}
|
||||
</div>
|
||||
<br class="clear" />
|
||||
<div class="heading links"><a href="{{ url_for('home.page', mid=member[0]) }}">View Page</a>{% if g.user %} ☆ {% if member[8]==0 %}<a href="{{ url_for('manage.add_to_front', mid=member[0],location='home') }}">Add to Front</a>{% else %}<a href="{{ url_for('manage.remove_front', mid=member[0],location='home') }}">Remove from Front</a>{% endif %} ☆ <a href="{{ url_for('manage.edit', mid=member[0]) }}">Edit</a> ☆ {% if member[7]==0 %}<a href="{{ url_for('manage.add_to_home', mid=member[0],location='home') }}">Pin to Homepage</a>{% else %}<a href="{{ url_for('manage.remove_home', mid=member[0],location='home') }}">Unpin from Homepage</a>{% endif %}{% endif %}</div>
|
||||
|
||||
@@ -6,9 +6,25 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="mobile">
|
||||
<div class="heading">Manage Members</div>
|
||||
<a href="{{ url_for('manage.new') }}">Add new member</a><br><br>
|
||||
<a href="{{ url_for('manage.groups') }}">Manage groups</a><br><br>
|
||||
<a href="{{ url_for('manage.assets') }}">Site assets</a>
|
||||
</div>
|
||||
|
||||
<div class="heading">Front Log</div>
|
||||
<div class="maintext">Front change history</div>
|
||||
<div class="log">
|
||||
{% for front in front_log %}
|
||||
<p><b>{{ get_datetime_str(front[2]) }}</b> - {{ get_member(front[1])[3]|safe }}{% if front[3] %} <i>(ended: {{ get_datetime_str(front[3]) }})</i> | <a class="danger" href="{{ url_for('manage.delete_front_log', fid=front[0]) }}">delete</a>{% endif %}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="heading">Backup</div>
|
||||
<a href="{{ url_for('manage.export_system') }}">Export entire system TEXT ONLY</a><br>
|
||||
<a href="{{ url_for('manage.export_system_full') }}">Export entire system WITH ATTACHMENTS</a>
|
||||
<a href="{{ url_for('manage.export_system') }}">Export entire system as JSON</a> (without images)<br>
|
||||
<a href="{{ url_for('manage.export_system_full') }}">Export entire system as ZIP</a> (with images)
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -30,10 +46,6 @@
|
||||
|
||||
<hr>
|
||||
|
||||
<a class="danger">Clear database</a> WARNING: this action is permanent and irreversible<br>
|
||||
|
||||
<br><br>
|
||||
|
||||
<div class="heading big pink">WIP ZONE</div>
|
||||
<div class="heading">Site Users</div>
|
||||
<div class="maintext">These are the usernames that can log in to the site</div>
|
||||
@@ -45,9 +57,6 @@
|
||||
<div class="heading">Admin Log</div>
|
||||
<div class="maintext">Actions taken by registered users</div>
|
||||
|
||||
<div class="heading">Front Log</div>
|
||||
<div class="maintext">Front change history</div>
|
||||
|
||||
<div class="heading">Site Theme</div>
|
||||
<div class="maintext">Choose the overall theme for the site here</div>
|
||||
<form>
|
||||
|
||||
@@ -36,9 +36,44 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="heading big">Blinkies</div>
|
||||
|
||||
<p>Not implemented yet (sorry!)</p>
|
||||
|
||||
<div class="heading big">Stamps</div>
|
||||
<p>Not implemented yet (sorry!)</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="heading big">Upload Images</div>
|
||||
<p>Upload images for use in pages and custom sections.
|
||||
Just right click, copy image URL, then use it in the HTML
|
||||
however you like. You can use style tags to customize how the
|
||||
images look/behave on your page, just be careful not to use class or
|
||||
id selectors that already exist (or do, if you are wanting to overwrite
|
||||
their behaviour!). We will make a list of in-use class and ids here, soon.
|
||||
</p>
|
||||
<form method="post" enctype="multipart/form-data" id="image">
|
||||
<input type="file" name="image" class="mobile-edit">
|
||||
<input type="submit" value="Upload to Site">
|
||||
</form>
|
||||
|
||||
<div class="manage_images">
|
||||
<div class="manage_images_2">
|
||||
{% for image in images %}
|
||||
<div class="manage_images_3">
|
||||
<img class="mng_img" src="{{ url_for('static', filename='misc/'+image) }}">
|
||||
<br class="clear" />
|
||||
{% set imgurl = url_for('static', filename='misc/'+image) %}
|
||||
<a href="" onclick="copyURL('{{imgurl}}')">Copy Image URL</a> ☆ <a href="">Delete</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyURL(a) {
|
||||
navigator.clipboard.writeText(a);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<div class="title">{% block title %}Edit {{ member[3] }}{% endblock %}</div>
|
||||
<div class="title">{% block title %}Edit {{ remove_html(member[3]) }}{% endblock %}</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<a href="{{url_for('home.page', mid=member[0])}}">View {{member[3]}}'s page</a>
|
||||
<a href="{{url_for('home.page', mid=member[0])}}">View {{member[3]|safe}}'s page</a>
|
||||
<br class="clear" />
|
||||
|
||||
<div class="heading">Edit Details</div>
|
||||
@@ -33,9 +33,40 @@
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<a href="{{ url_for('manage.delete', mid=member[0]) }}" class="danger">Delete member</a> - WARNING: this is permanent and cannot be undone!
|
||||
<div class="heading">Public Page Settings</div>
|
||||
<p>Select which sections to show on this member's public page</p>
|
||||
<form method="post" id="page_settings">
|
||||
<input type="checkbox" id="show_groups" name="show_groups" {% if member[15] %}checked{% endif %}>
|
||||
<label for="show_groups">Groups</label><br>
|
||||
<input type="checkbox" id="show_blog" name="show_blog" {% if member[11] %}checked{% endif %}>
|
||||
<label for="show_blog">Blog</label><br>
|
||||
<input type="checkbox" id="show_icons" name="show_icons" {% if member[12] %}checked{% endif %}>
|
||||
<label for="show_icons">Icons</label><br>
|
||||
<input type="checkbox" id="show_blinkies" name="show_blinkies" {% if member[13] %}checked{% endif %}>
|
||||
<label for="show_blinkies">Blinkies</label><br>
|
||||
<input type="checkbox" id="show_stamps" name="show_stamps" {% if member[14] %}checked{% endif %}>
|
||||
<label for="show_stamps">Stamps</label><br>
|
||||
<input type="submit" name="page_settings" value="Submit">
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Customize section titles. Leave blank to hide the heading bar for that section altogether.</p>
|
||||
<form method="post">
|
||||
<label for="groups_title">Groups</label>
|
||||
<input name="groups_title" id="groups_title" value="{{ member[20] }}"><br>
|
||||
<label for="blog_title">Blog</label>
|
||||
<input name="blog_title" id="blog_title" value="{{ member[16] }}"><br>
|
||||
<label for="icons_title">Icons</label>
|
||||
<input name="icons_title" id="icons_title" value="{{ member[17] }}"><br>
|
||||
<label for="blinkies_title">Blinkies</label>
|
||||
<input name="blinkies_title" id="blinkies_title" value="{{ member[18] }}"><br>
|
||||
<label for="stamps_title">Stamps</label>
|
||||
<input name="stamps_title" id="stamps_title" value="{{ member[19] }}"><br>
|
||||
<input type="submit" name="section_titles" value="Submit">
|
||||
</form>
|
||||
|
||||
{% if unjoined_groups or joined_groups %}
|
||||
<div class="heading">Manage groups</div>
|
||||
|
||||
<form method="post" id="groups">
|
||||
@@ -55,11 +86,12 @@
|
||||
</select>
|
||||
<input type="submit" value="Remove from group">
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="heading">Manage Icons</div>
|
||||
<form method="post" enctype="multipart/form-data" id="icons">
|
||||
<input type="file" name="file">
|
||||
<input type="file" name="file" class="mobile-edit">
|
||||
<input type="submit" value="Upload New Icon">
|
||||
</form>
|
||||
|
||||
@@ -80,7 +112,7 @@
|
||||
|
||||
<div class="heading">Manage Blinkies</div>
|
||||
<form method="post" enctype="multipart/form-data" id="blinkies">
|
||||
<input type="file" name="blinkie">
|
||||
<input type="file" name="blinkie" class="mobile-edit">
|
||||
<input type="submit" value="Upload to Blinkies">
|
||||
</form>
|
||||
|
||||
@@ -88,7 +120,7 @@
|
||||
<div class="manage_images_2">
|
||||
{% for blinkie in blinkies %}
|
||||
<div class="manage_blinkies_3">
|
||||
<img src="{{ url_for('static', filename='blinkies/'+blinkie[2]) }}">
|
||||
<img class="blinkie" src="{{ url_for('static', filename='blinkies/'+blinkie[2]) }}">
|
||||
<br class="clear" />
|
||||
<a href="{{ url_for('manage.delete_blinkie', mid=member[0], blinkie_id=blinkie[0]) }}">Delete</a>
|
||||
</div>
|
||||
@@ -99,7 +131,7 @@
|
||||
|
||||
<div class="heading">Manage Stamps</div>
|
||||
<form method="post" enctype="multipart/form-data" id="stamps">
|
||||
<input type="file" name="stamp">
|
||||
<input type="file" name="stamp" class="mobile-edit">
|
||||
<input type="submit" value="Upload to Stamps">
|
||||
</form>
|
||||
|
||||
@@ -107,7 +139,7 @@
|
||||
<div class="manage_images_2">
|
||||
{% for stamp in stamps %}
|
||||
<div class="manage_stamps_3">
|
||||
<img src="{{ url_for('static', filename='stamps/'+stamp[2]) }}">
|
||||
<img class="stamp" src="{{ url_for('static', filename='stamps/'+stamp[2]) }}">
|
||||
<br class="clear" />
|
||||
<a href="{{ url_for('manage.delete_stamp', mid=member[0], stamp_id=stamp[0]) }}">Delete</a>
|
||||
</div>
|
||||
@@ -115,6 +147,36 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="heading">Custom Page Sections</div>
|
||||
<p>Here you can make sections for your page, embed whatever you like</p>
|
||||
<form method="post" id="sections">
|
||||
<label for="section_title">Section Title</label>
|
||||
<input name="section_title" id="section_title"><br>
|
||||
<label for="section_content">Section Content</label>
|
||||
<textarea name="section_content" id="section_content">Hello World!</textarea><br><br>
|
||||
<input type="submit" name="new_section" value="Create New Section">
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
{% for section in sections %}
|
||||
<form method="post">
|
||||
<label for="section_pos">Position</label>
|
||||
<input name="section_pos" id="section_pos" value="{{section[4]}}"><br>
|
||||
<label for="section_title">Section Title</label>
|
||||
<input name="section_title" id="section_title" value="{{section[2]}}"><br>
|
||||
<label for="section_content">Section Content</label>
|
||||
<textarea name="section_content" id="section_content">{{section[3]}}</textarea><br><br>
|
||||
<input type="hidden" id="section_id" name="section_id" value="{{section[0]}}">
|
||||
<input type="submit" name="update_section" value="Update Section">
|
||||
</form>
|
||||
|
||||
<a href="{{ url_for('manage.delete_section', sid=section[0]) }}">Delete section</a>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
||||
<div class="heading">Manage Member Data</div>
|
||||
<a href="{{ url_for('manage.export_fields', mid=member[0]) }}">Export Fields</a><br>
|
||||
@@ -123,6 +185,9 @@
|
||||
{% if stamps %}<a href="{{ url_for('manage.export_stamps', mid=member[0]) }}">Export stamps</a><br>{% endif %}
|
||||
{% if icons or blinkies or stamps %}<a href="{{ url_for('manage.export_member', mid=member[0]) }}">Export all member data</a><br>{% endif %}
|
||||
|
||||
<hr>
|
||||
<div class="heading danger">Danger zone</div>
|
||||
<a href="{{ url_for('manage.delete', mid=member[0]) }}" class="danger">Delete member</a> - WARNING: this is permanent and cannot be undone!
|
||||
|
||||
|
||||
{% if edit_location %}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
<input name="subtitle" id="subtitle"><br>
|
||||
<label for="bio">Description</label>
|
||||
<textarea name="bio" id="bio"></textarea><br>
|
||||
<input type="radio" id="public" name="privacy" value=1 checked>
|
||||
<label for="public">Public</label><br>
|
||||
<input type="radio" id="private" name="privacy" value=0>
|
||||
<label for="private">Private</label><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}{{ member[3] }}{% endblock %}
|
||||
{% block title %}{{ remove_html(member[3]) }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -12,23 +12,29 @@
|
||||
{% else %}
|
||||
|
||||
{% if g.user %}
|
||||
<a href="{{url_for('manage.edit', mid=member[0])}}">Edit member</a>
|
||||
<a href="{{url_for('manage.edit', mid=member[0])}}">Edit member</a> ☆ {% if member[8]==0 %}<a href="{{ url_for('manage.add_to_front', mid=member[0],location='mid') }}">Add to Front</a>{% else %}<a href="{{ url_for('manage.remove_front', mid=member[0],location='mid') }}">Remove from Front</a>{% endif %} ☆ {% if member[7]==0 %}<a href="{{ url_for('manage.add_to_home', mid=member[0],location='mid') }}">Pin to Homepage</a>{% else %}<a href="{{ url_for('manage.remove_home', mid=member[0],location='mid') }}">Unpin from Homepage</a>{% endif %}
|
||||
<br class="clear" />
|
||||
{% endif %}
|
||||
|
||||
{% if member[8]==1 %}<div class="heading"><i>Currently Fronting</i></div>{% endif %}
|
||||
|
||||
{% if icon %}
|
||||
<img class="icon" src="{{ url_for('static', filename='icons/'+icon[0]) }}">
|
||||
{% else %}
|
||||
<img class="icon" src="{{ url_for('static', filename='any.jpg') }}">
|
||||
{% endif %}
|
||||
<div class="title">{{member[3]}}</div>
|
||||
<div class="title">{% if member[9]==0 %}<img class="lock" src="{{ url_for('static', filename='lock.png') }}">{% endif %}{{member[3]|safe}}</div>
|
||||
<div class="maintext">
|
||||
{{member[5]|safe}}
|
||||
{{member[5].replace('\n', '<br>')|safe}}
|
||||
</div>
|
||||
<br class="clear" />
|
||||
|
||||
{% if member[11] %}
|
||||
{% if blog|length > 0 %}
|
||||
<div class="heading big">{{member[3]}}'s blog</div>
|
||||
{% if not g.user and not blog_public_show %}
|
||||
{% else %}
|
||||
{% if member[16] %}<div class="heading big">{{ member[16] }}</div>{% endif %}
|
||||
{% endif %}
|
||||
<div id="blog">
|
||||
{% for post in blog %}
|
||||
{% if not g.user and post[5]==0 %}
|
||||
@@ -37,7 +43,7 @@
|
||||
<div class="title">{{post[3]|safe}}</div>
|
||||
<div class="timestamp">{{post[2]}} {% if g.user %}{% if post[5]==0 %}(Private){% else %}(Public){% endif %}{% endif %}</div>
|
||||
<div class="content">
|
||||
{{post[4]|safe}}
|
||||
{{post[4].replace('\n', '<br>')|safe}}
|
||||
</div>
|
||||
{% if g.user %}<a href="{{url_for('blog.toggle',pid=post[0], location=member[0])}}">Toggle privacy</a> | <a href="{{url_for('blog.edit',pid=post[0],location=member[0])}}">Edit Post</a> | <a href="{{url_for('blog.delete', pid=post[0], location=member[0])}}" class="danger">Delete post</a>{% endif %}
|
||||
</div>
|
||||
@@ -45,30 +51,56 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% for section in sections %}
|
||||
{% if section[2] %}<div class="heading big">{{ section[2] }}</div>{% endif %}
|
||||
{{ section[3]|safe }}
|
||||
{% endfor %}
|
||||
|
||||
<!-- {% if groups|length > 0 %}
|
||||
<div class="heading big">{{ member[20] }}</div>
|
||||
{% for group in groups %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %} -->
|
||||
|
||||
{% if member[13] %}
|
||||
{% if blinkies|length > 0 %}
|
||||
{% if member[18] %}<div class="heading big">{{ member[18] }}</div>{% endif %}
|
||||
<div class="image-section">
|
||||
{% for blinkie in blinkies %}
|
||||
<img class="blinkie" src="{{ url_for('static', filename='blinkies/'+blinkie[0]) }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<br class="clear" />
|
||||
|
||||
{% if member[14] %}
|
||||
{% if stamps|length > 0 %}
|
||||
{% if member[19] %}<div class="heading big">{{ member[19] }}</div>{% endif %}
|
||||
<div class="image-section">
|
||||
{% for stamp in stamps %}
|
||||
<img class="stamp" src="{{ url_for('static', filename='stamps/'+stamp[0]) }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<br class="clear" />
|
||||
|
||||
{% if member[12] %}
|
||||
{% if all_icons|length > 1 %}
|
||||
<div class="heading big">Icons</div>
|
||||
{% if member[17] %}<div class="heading big">{{ member[17] }}</div>{% endif %}
|
||||
<div class="image-section">
|
||||
{% for i in all_icons %}
|
||||
<img class="icon" src="{{ url_for('static', filename='icons/'+i[0]) }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<br class="clear" />
|
||||
|
||||
{% if blinkies|length > 0 %}
|
||||
<div class="heading big">Blinkies</div>
|
||||
{% for blinkie in blinkies %}
|
||||
<img src="{{ url_for('static', filename='blinkies/'+blinkie[0]) }}">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<br class="clear" />
|
||||
|
||||
{% if stamps|length > 0 %}
|
||||
<div class="heading big">Stamps</div>
|
||||
{% for stamp in stamps %}
|
||||
<img src="{{ url_for('static', filename='stamps/'+stamp[0]) }}">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
25
myriad/utilities.py
Normal file
25
myriad/utilities.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import datetime, re
|
||||
|
||||
def server_time():
|
||||
raw = datetime.datetime.now()
|
||||
real = raw.strftime("%d/%m/%Y, %H:%M:%S")
|
||||
return real
|
||||
|
||||
def server_time_obj():
|
||||
return datetime.datetime.now()
|
||||
|
||||
def get_datetime_obj(dt_string):
|
||||
date_raw = dt_string.split(",")
|
||||
date = date_raw[0]
|
||||
day,month,year = date.split("/")
|
||||
time = date_raw[1]
|
||||
hour,minute,second = time.split(":")
|
||||
dt_obj = datetime.datetime(int(year), int(month), int(day), int(hour), int(minute), int(second))
|
||||
return dt_obj
|
||||
|
||||
def get_datetime_str(dt_obj):
|
||||
return dt_obj.strftime("%d/%m/%Y, %H:%M:%S")
|
||||
|
||||
def remove_html(mystring):
|
||||
newstring = re.sub('<[^<]+?>', '', mystring)
|
||||
return newstring
|
||||
Reference in New Issue
Block a user