updated css to match playlist manager, added engineering page

This commit is contained in:
aj 2020-01-19 23:54:06 +00:00
parent 29f2f340bc
commit 547bb44aa6
23 changed files with 424 additions and 113 deletions

View File

@ -20,4 +20,5 @@ __pycache__/
/setup.cfg /setup.cfg
env env
venv
node_modules/ node_modules/

View File

@ -8,3 +8,6 @@ handlers:
script: auto script: auto
secure: always secure: always
env_variables:
DEPLOY_DESTINATION: 'PROD'

View File

@ -1,24 +1,27 @@
cachetools==3.1.1 cachetools==4.0.0
certifi==2019.9.11 certifi==2019.11.28
chardet==3.0.4 chardet==3.0.4
Click==7.0 Click==7.0
Flask==1.1.1 Flask==1.1.1
google-api-core==1.14.3 google-api-core==1.16.0
google-auth==1.6.3 google-auth==1.10.1
google-cloud-core==1.0.3 google-cloud-core==1.2.0
google-cloud-firestore==1.4.0 google-cloud-firestore==1.6.1
googleapis-common-protos==1.6.0 google-cloud-logging==1.14.0
grpcio==1.24.1 googleapis-common-protos==1.51.0
grpcio==1.26.0
idna==2.8 idna==2.8
itsdangerous==1.1.0 itsdangerous==1.1.0
Jinja2==2.10.3 Jinja2==2.10.3
MarkupSafe==1.1.1 MarkupSafe==1.1.1
protobuf==3.10.0 numpy==1.18.1
pyasn1==0.4.7 opencv-python==4.1.2.30
pyasn1-modules==0.2.6 protobuf==3.11.2
pyasn1==0.4.8
pyasn1-modules==0.2.8
pytz==2019.3 pytz==2019.3
requests==2.22.0 requests==2.22.0
rsa==4.0 rsa==4.0
six==1.12.0 six==1.14.0
urllib3==1.25.6 urllib3==1.25.7
Werkzeug==0.16.0 Werkzeug==0.16.0

View File

@ -1 +1,35 @@
from .sarsoo import app from .sarsoo import app
import logging
import os
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')
fmframework_logger = logging.getLogger('fmframework')
if os.environ.get('DEPLOY_DESTINATION', None) == 'PROD':
import google.cloud.logging
from google.cloud.logging.handlers import CloudLoggingHandler, setup_logging
log_format = '%(funcName)s - %(message)s'
formatter = logging.Formatter(log_format)
client = google.cloud.logging.Client()
handler = CloudLoggingHandler(client, name="sarsooxyz")
setup_logging(handler)
handler.setFormatter(formatter)
logger.addHandler(handler)
fmframework_logger.addHandler(handler)
else:
log_format = '%(levelname)s %(name)s:%(funcName)s - %(message)s'
formatter = logging.Formatter(log_format)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
fmframework_logger.addHandler(stream_handler)

View File

@ -1,2 +1,3 @@
from .art_api import art_api_print from .art_api import art_api_print
from .dev_api import dev_api_print from .dev_api import dev_api_print
from .eng_api import eng_api_print

View File

@ -13,29 +13,14 @@ def get_all_collections():
try: try:
tags = dev_collection.get() tags = dev_collection.get()
response = {'dev': sorted([i.to_dict() for i in tags], key=lambda k: k['index'])}
return jsonify(response)
except exceptions.NotFound: except exceptions.NotFound:
abort(404) abort(404)
dicts = list(map(lambda x: x.to_dict(), tags))
dev_documents = []
for dev_dict in dicts:
dev_documents.append({
'name': dev_dict['name'],
'description': [i for i in dev_dict['description']],
'url': dev_dict['url'],
'index': dev_dict['index']
})
response = {'dev': sorted(dev_documents, key=lambda k: k['index'])}
return jsonify(response)
@dev_api_print.errorhandler(404) @dev_api_print.errorhandler(404)
def error400(error): def error400(error):
errorresponse = {'error': 'collection not found'} errorresponse = {'error': 'collection not found'}
return jsonify(errorresponse), 404 return jsonify(errorresponse), 404

26
sarsoo/api/eng_api.py Normal file
View File

@ -0,0 +1,26 @@
from flask import Blueprint, jsonify, abort
from google.cloud import firestore, exceptions
fs = firestore.Client()
eng_api_print = Blueprint('engapi', __name__)
@eng_api_print.route('/', methods=['GET'])
def get_all_collections():
eng_collection = fs.collection(u'eng')
try:
tags = eng_collection.get()
response = {'eng': sorted([i.to_dict() for i in tags], key=lambda k: k['index'])}
return jsonify(response)
except exceptions.NotFound:
abort(404)
@eng_api_print.errorhandler(404)
def error400(error):
errorresponse = {'error': 'collection not found'}
return jsonify(errorresponse), 404

View File

@ -1,16 +1,16 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}art{% endblock %} {% block title %}/art{% endblock %}
{% block content %} {% block content %}
{% for tag in tags %} {% for tag in tags %}
<div class="row"> <div class="row text-no-select">
<h1 class="sectiontitle">{{ tag.name }}</h1> <h1 class="sectiontitle">{{ tag.name }}</h1>
{% if tag.description %}<p>{{ tag.description }}</p>{% endif %} {% if tag.description %}<p>{{ tag.description }}</p>{% endif %}
</div> </div>
{% for row in tag.images|batch(3) %} {% for row in tag.images|batch(3) %}
<div class="row"> <div class="row text-no-select">
{% for image in row %} {% for image in row %}
{#{% if loop.index0 % 3 == 0 %}<div class="row">{% endif %}#} {#{% if loop.index0 % 3 == 0 %}<div class="row">{% endif %}#}
<div class="card pad-4"> <div class="card pad-4">

View File

@ -1,10 +1,10 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}art{% endblock %} {% block title %}/art{% endblock %}
{% block content %} {% block content %}
{% for row in tags|batch(4) %} {% for row in tags|batch(4) %}
<div class="row"> <div class="row text-no-select">
{% for tag in row %} {% for tag in row %}
<div class="pad-3 card"> <div class="pad-3 card">
<h1>{{ tag.name }}</h1> <h1>{{ tag.name }}</h1>

View File

@ -1,17 +1,17 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}music{% endblock %} {% block title %}/music{% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row text-no-select">
<h1 class = "col-12" style = "text-align: center; color: white;">most played of the last month</h1> <h1 class = "col-12" style = "text-align: center; color: white;">most played of the last month</h1>
</div> </div>
<div class="row"> <div class="row text-no-select">
{% for album in albums %} {% for album in albums %}
<div class = "pad-2 card"> <div class = "pad-2 card">
<img src="{{album.images[-1].link}}"> <img src="{{album.images[-1].link}}">
<p style="text-align:center">{{ album.name }}<br>{{ album.artist.name -}}</p> <p style="text-align:center">{{ album.name }}<br>{{ album.artist.name -}}</p>
<p style="text-align:center">{{- album.play_count }} plays</p> <p style="text-align:center">{{- album.user_scrobbles }} plays</p>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -4,8 +4,7 @@ import os
from .art import art_print from .art import art_print
from .music import music_print from .music import music_print
from .api import art_api_print from .api import art_api_print, dev_api_print, eng_api_print
from .api import dev_api_print
# Project ID is determined by the GCLOUD_PROJECT environment variable # Project ID is determined by the GCLOUD_PROJECT environment variable
db = firestore.Client() db = firestore.Client()
@ -16,6 +15,7 @@ app.register_blueprint(art_print, url_prefix='/art')
app.register_blueprint(music_print, url_prefix='/music') app.register_blueprint(music_print, url_prefix='/music')
app.register_blueprint(art_api_print, url_prefix='/api/art') app.register_blueprint(art_api_print, url_prefix='/api/art')
app.register_blueprint(dev_api_print, url_prefix='/api/dev') app.register_blueprint(dev_api_print, url_prefix='/api/dev')
app.register_blueprint(eng_api_print, url_prefix='/api/eng')
staticbucketurl = 'https://storage.googleapis.com/sarsooxyzstatic/' staticbucketurl = 'https://storage.googleapis.com/sarsooxyzstatic/'
@ -39,4 +39,9 @@ def main():
def dev(): def dev():
return render_template('dev.html') return render_template('dev.html')
@app.route('/engineering')
def eng():
return render_template('eng.html')
# [END gae_python37_app] # [END gae_python37_app]

View File

@ -1,10 +1,10 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<title>sarsoo/{% block title %}{% endblock %}</title> <title>sarsoo{% block title %}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link href="https://fonts.googleapis.com/css?family=Pirata+One|Lato" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Pirata+One|Roboto" rel="stylesheet">
<link rel="apple-touch-icon" sizes="180x180" href="https://storage.googleapis.com/sarsooxyzstatic/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="https://storage.googleapis.com/sarsooxyzstatic/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://storage.googleapis.com/sarsooxyzstatic/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="https://storage.googleapis.com/sarsooxyzstatic/favicon-32x32.png">
@ -26,10 +26,11 @@
<li><a href="/dev">dev</a></li> <li><a href="/dev">dev</a></li>
<li><a href="/art">art</a></li> <li><a href="/art">art</a></li>
<li><a href="/music">music</a></li> <li><a href="/music">music</a></li>
<li><a href="https://spotify.sarsoo.xyz">playlist manager</a></li> <li><a href="/engineering">engineering</a></li>
<li class="right"><a href="https://www.instagram.com/pack_it_in_/">art ig</a></li> <li class="right"><a href="https://www.instagram.com/pack_it_in_/">art ig</a></li>
<li class="right"><a href="https://www.last.fm/user/sarsoo">last.fm</a></li> <li class="right"><a href="https://www.last.fm/user/sarsoo">last.fm</a></li>
<li class="right"><a href="https://github.com/sarsoo">github</a></li> <li class="right"><a href="https://github.com/sarsoo">github</a></li>
<li class="right"><a href="https://spotify.sarsoo.xyz">playlist manager</a></li>
</ul> </ul>
{% block content %}{% endblock %} {% block content %}{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}dev{% endblock %} {% block title %}/dev{% endblock %}
{% block content %} {% block content %}
<div id="react"></div> <div id="react"></div>

View File

@ -0,0 +1,8 @@
{% extends 'base.html' %}
{% block title %}/engineering{% endblock %}
{% block content %}
<div id="react"></div>
<script src="{{ url_for('static', filename='js/eng.bundle.js') }}"></script>
{% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}home{% endblock %} {% block title %}{% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row text-no-select">
<div class="col-9" style="text-align:center"> <div class="col-9" style="text-align:center">
{% for text_entry in main_text %} {% for text_entry in main_text %}
<p>{{ text_entry }}</p> <p>{{ text_entry }}</p>
@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<div class="gallerystrip row"> <div class="gallerystrip row text-no-select">
{% for image in art %} {% for image in art %}
<img src="{{ staticroot }}art/{{ image.file_name }}.jpg" alt="{{ image.file_name }}" class="pad-4"> <img src="{{ staticroot }}art/{{ image.file_name }}.jpg" alt="{{ image.file_name }}" class="pad-4">
{% endfor %} {% endfor %}

View File

@ -1,6 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}music{% endblock %} {% block title %}/music{% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row">

1
sass Executable file
View File

@ -0,0 +1 @@
sass --style=compressed src/scss/style.scss build/style.css

View File

@ -30,7 +30,7 @@ class DevGallery extends Component {
render(){ render(){
var arrays = [], size = 2; var arrays = [], size = 3;
var a = this.state.entries.slice() var a = this.state.entries.slice()
while (a.length > 0) while (a.length > 0)
@ -38,7 +38,7 @@ class DevGallery extends Component {
const gallery = <div>{arrays.map((entry) => <Row entries={entry}/>)}</div>; const gallery = <div>{arrays.map((entry) => <Row entries={entry}/>)}</div>;
const loadingMessage = <p className="center-text" >loading...</p>; const loadingMessage = <p className="center-text text-no-select" >loading...</p>;
return this.state.isLoading ? loadingMessage : gallery; return this.state.isLoading ? loadingMessage : gallery;
} }
@ -48,8 +48,8 @@ class DevGallery extends Component {
function Row(props){ function Row(props){
return ( return (
<div className="row"> <div className="row text-no-select">
{props.entries.map((entry) => <DevEntry entry={entry} />)} {props.entries.map((entry) => <DevEntry entry={entry} key={entry.index} />)}
</div> </div>
); );
@ -59,7 +59,7 @@ function Row(props){
function DevEntry(props){ function DevEntry(props){
return ( return (
<div className="pad-6 card"> <div className="pad-4 card">
<h1>{props.entry.name}</h1> <h1>{props.entry.name}</h1>
{props.entry.description.map((entry) => <p key={entry} >{entry}</p>)} {props.entry.description.map((entry) => <p key={entry} >{entry}</p>)}

View File

@ -0,0 +1,73 @@
import React, { Component } from "react";
const axios = require('axios');
class EngineeringGallery extends Component {
constructor(props){
super(props);
this.state = {
entries: [],
isLoading: true
};
this.getEntries();
}
getEntries(){
var self = this;
axios.get('/api/eng')
.then(function (response){
self.setState({
entries: response.data.eng,
isLoading: false
});
})
.catch(function (error){
console.log(error);
});
}
render(){
var arrays = [], size = 3;
var a = this.state.entries.slice()
while (a.length > 0)
arrays.push(a.splice(0, size));
const gallery = <div>{arrays.map((entry) => <Row entries={entry} />)}</div>;
const loadingMessage = <p className="center-text text-no-select" >loading...</p>;
return this.state.isLoading ? loadingMessage : gallery;
}
}
function Row(props){
return (
<div className="row text-no-select">
{props.entries.map((entry) => <WorkEntry entry={entry} key={entry.index} />)}
</div>
);
}
function WorkEntry(props){
return (
<div className="pad-4 card">
<h1>{props.entry.name}</h1>
{props.entry.description.map((entry) => <p key={entry} >{entry}</p>)}
<a href={props.entry.url} className="button full-width">read</a>
</div>
);
}
export default EngineeringGallery;

6
src/js/eng/eng.js Normal file
View File

@ -0,0 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
import EngineeringGallery from "./EngineeringGallery.js";
ReactDOM.render(<EngineeringGallery />, document.getElementById('react'));

View File

@ -1,7 +1,10 @@
$font-stack: 'Lato', arial; $font-stack: 'Roboto', arial;
$background-colour: #202124; $background-colour: #202124;
$ui-colour: #131313; $ui-colour: #131313;
$light-ui: #575757;
$text-colour: white; $text-colour: white;
$ui-element: #505050;
$ui-shadow: #404040;
$pad-px: 20px; $pad-px: 20px;
@ -30,6 +33,10 @@ p {
padding: 10px; padding: 10px;
} }
.ui-text {
color: $text-colour;
}
.center-text { .center-text {
text-align: center; text-align: center;
} }
@ -38,28 +45,47 @@ p {
width: 100%; width: 100%;
} }
.half-width {
width: 50%;
}
.button { .button {
background-color: #505050; background-color: $ui-element;
color: black; color: $text-colour;
border-radius: 10px;
display: inline-block; display: inline-block;
border-radius: 3px;
border: none;
margin: 4px auto; margin: 4px auto;
cursor: pointer;
padding: 15px; padding: 15px;
box-shadow: 2px 2px 4px black;
/*-webkit-transition-duration: 0.4s; font-size: 15px;
transition-duration: 0.4s;*/
cursor: pointer;
box-shadow: 0 9px #383838;
text: { text: {
shadow: 0.5px 0.5px 0.5px rgba(0,0,0,0.14);
align: center; align: center;
decoration: none; decoration: none;
} }
&:hover { &:active {
box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19); box-shadow: 0 5px #383838;
transform: translateY(4px);
} }
} }
input[type=text], input[type=password], input[type=number], select {
padding: 15px;
background-color: $ui-element;
border: black;
border-radius: 3px;
color: white;
}
.row { .row {
margin: 30px; margin: 30px;
} }
@ -136,7 +162,7 @@ h1.title {
h1 { h1 {
text-align: center; text-align: center;
color: white; color: $text-colour;
text-shadow: 1px 1px 2px #4f4f4f; text-shadow: 1px 1px 2px #4f4f4f;
} }
@ -156,40 +182,54 @@ h1.title {
h1.sectiontitle { h1.sectiontitle {
text-align:center; text-align:center;
color: white; color: $text-colour;
font-family: 'Megrim', sans-serif; font-family: 'Megrim', sans-serif;
} }
ul.navbar { ul.navbar {
list-style-type: none; list-style-type: none;
border-radius: 5px 5px; background-color: $light-ui;
/*box-shadow: 3px 3px 1px grey;*/
margin: 10px; margin: 10px;
border-radius: 5px;
/*box-shadow: 3px 3px 1px grey;*/
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
background-color: $ui-colour;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
box-shadow: 0 9px 12px 0 black, 0 9px 12px 0 black;
li { li {
float: left; float: left;
position: -webkit-sticky; position: -webkit-sticky;
position: sticky; position: sticky;
top: 0; top: 0;
a { a {
display: block; display: block;
color: white; color: $text-colour;
text-align: center; text-align: center;
padding: 14px 16px; padding: 14px 16px;
// padding: 10px;
margin: 2px;
border-radius: 5px;
text-decoration: none; text-decoration: none;
text-shadow: 1px 1px 2px black; text-shadow: 1px 1px 1px rgba(0,0,0, 0.5);
-webkit-transition: background-color 0.4s; -webkit-transition: background-color 0.4s;
transition: background-color 0.4s; transition: background-color 0.4s;
&:hover { &:hover {
background-color: #080808; background-color: $ui-shadow;
} }
} }
} }
@ -197,6 +237,86 @@ ul.navbar {
li.right {float: right;} li.right {float: right;}
} }
.sidebar {
list-style-type: none;
background-color: $light-ui;
margin-left: 10px;
margin-right: 10px;
border-radius: 5px;
// padding-top: 10px;
// padding-bottom: 10px;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
box-shadow: 0 9px 12px 0 black, 0 9px 12px 0 black;
tr {
top: 0;
cursor: pointer;
td {
// height: 50px;
text-align: center;
vertical-align: center;
border-radius: 5px;
a {
color: $text-colour;
height: 100%;
width: 100%;
display: inline-block;
vertical-align: center;
padding: 10px;
text-decoration: none;
text-shadow: 1px 1px 1px rgba(0,0,0, 0.5);
-webkit-transition: background-color 0.4s;
transition: background-color 0.4s;
}
&:hover {
background-color: $ui-shadow;
}
}
}
}
.sidebar-selected {
background-color: black;
}
.app-table {
width: 100%;
margin: auto;
td {
padding: 5px;
}
}
.max-width {
max-width: 800px;
}
.text-no-select {
cursor: default;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
footer { footer {
p { p {
text-align: right; text-align: right;
@ -213,7 +333,49 @@ footer {
} }
} }
@media only screen and (max-width: 760px) { #snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: white;
color: black;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 50%;
bottom: 30px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@-webkit-keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
@keyframes fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
@media only screen and (max-width: 950px) {
ul.navbar li.right, ul.navbar li.right,
ul.navbar li {float: none;} ul.navbar li {float: none;}
} }

1
watchsass Executable file
View File

@ -0,0 +1 @@
sass --style=compressed --watch src/scss/style.scss build/style.css

View File

@ -4,7 +4,8 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = { module.exports = {
entry: { entry: {
dev: './src/js/dev/dev.js' dev: './src/js/dev/dev.js',
eng: './src/js/eng/eng.js'
}, },
module: { module: {
rules: [ rules: [