initial commit with first pass backend
This commit is contained in:
commit
549d8b4e10
121
.gitignore
vendored
Normal file
121
.gitignore
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
|
||||
node_modules/
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
*/__pycache__/*
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
.idea
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
11
app.yaml
Normal file
11
app.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
runtime: python37
|
||||
service: spotify
|
||||
|
||||
handlers:
|
||||
- url: /static
|
||||
static_dir: build
|
||||
|
||||
- url: /.*
|
||||
script: auto
|
||||
secure: always
|
||||
|
6
main.py
Normal file
6
main.py
Normal file
@ -0,0 +1,6 @@
|
||||
from spotify import app
|
||||
|
||||
app = app
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='127.0.0.1', port=8080, debug=True)
|
1
spotify/__init__.py
Normal file
1
spotify/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .spotify import app
|
38
spotify/spotify.py
Normal file
38
spotify/spotify.py
Normal file
@ -0,0 +1,38 @@
|
||||
from flask import Flask, render_template, redirect
|
||||
from google.cloud import firestore
|
||||
import os
|
||||
import urllib
|
||||
|
||||
# Project ID is determined by the GCLOUD_PROJECT environment variable
|
||||
db = firestore.Client()
|
||||
|
||||
app = Flask(__name__, static_folder=os.path.join(os.path.dirname(__file__), '..', 'build'), template_folder="templates")
|
||||
|
||||
staticbucketurl = 'https://storage.googleapis.com/sarsooxyzstatic/'
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def main():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@app.route('/auth')
|
||||
def auth():
|
||||
client_id = db.document('key/spotify').get().to_dict()['clientid']
|
||||
params = urllib.parse.urlencode(
|
||||
{
|
||||
'client_id': client_id,
|
||||
'response_type': 'code',
|
||||
'scope': 'playlist-modify-public playlist-modify-private playlist-read-private',
|
||||
'redirect_uri': 'https://spotify.sarsoo.xyz/app'
|
||||
}
|
||||
)
|
||||
|
||||
return redirect(urllib.parse.urlunparse(['https', 'accounts.spotify.com', 'authorize', '', params, '']))
|
||||
|
||||
|
||||
@app.route('/app')
|
||||
def app_route():
|
||||
return render_template('app.html')
|
||||
|
||||
# [END gae_python37_app]
|
8
spotify/templates/app.html
Normal file
8
spotify/templates/app.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}spotify{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row"></div>
|
||||
{% endblock %}
|
33
spotify/templates/base.html
Normal file
33
spotify/templates/base.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>sarsoo/{% block title %}{% endblock %}</title>
|
||||
<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 href="https://fonts.googleapis.com/css?family=Pirata+One|Lato" rel="stylesheet">
|
||||
|
||||
<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="16x16" href="https://storage.googleapis.com/sarsooxyzstatic/favicon-16x16.png">
|
||||
<link rel="manifest" href="https://storage.googleapis.com/sarsooxyzstatic/site.webmanifest">
|
||||
<link rel="mask-icon" href="https://storage.googleapis.com/sarsooxyzstatic/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="https://storage.googleapis.com/sarsooxyzstatic/favicon.ico">
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1 class="title">andy</h1>
|
||||
</div>
|
||||
<br><br>
|
||||
<ul class="navbar">
|
||||
<li><a href="/">home</a></li>
|
||||
</ul>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
<footer>
|
||||
<a href="https://github.com/Sarsoo/sarsoo.xyz">view source code</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
16
spotify/templates/index.html
Normal file
16
spotify/templates/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}spotify{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div class="pad-12 card">
|
||||
<h1>Spotify Playlist Manager</h1>
|
||||
|
||||
<p class="center-text">create "super-playlists" of smaller modular playlists</p>
|
||||
|
||||
<a class="button full-width" href="/auth">launch</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
257
src/scss/style.scss
Normal file
257
src/scss/style.scss
Normal file
@ -0,0 +1,257 @@
|
||||
$font-stack: 'Lato', arial;
|
||||
$background-colour: #202124;
|
||||
$ui-colour: #131313;
|
||||
$text-colour: white;
|
||||
|
||||
$pad-px: 20px;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: $font-stack;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: $background-colour;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $text-colour;
|
||||
font-size: 20px;
|
||||
/*text-shadow: 1px 1px 1px #aaa;*/
|
||||
}
|
||||
|
||||
p {
|
||||
color: $text-colour;
|
||||
font-size: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.center-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: #505050;
|
||||
color: black;
|
||||
border-radius: 10px;
|
||||
display: inline-block;
|
||||
margin: 4px auto;
|
||||
cursor: pointer;
|
||||
padding: 15px;
|
||||
box-shadow: 2px 2px 4px black;
|
||||
/*-webkit-transition-duration: 0.4s;
|
||||
transition-duration: 0.4s;*/
|
||||
|
||||
text: {
|
||||
align: center;
|
||||
decoration: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
.gallerystrip{
|
||||
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
margin-top: 15px;
|
||||
|
||||
|
||||
img {
|
||||
height: auto;
|
||||
border: 10px solid #313439;
|
||||
margin: $pad-px / 2;
|
||||
box-shadow: 4px 4px 7px #070707;
|
||||
}
|
||||
}
|
||||
|
||||
.profile {
|
||||
background-color: $ui-colour;
|
||||
height: auto;
|
||||
margin-top: 10px;
|
||||
/*border: 8px solid #313439;*/
|
||||
border-radius: 0px;
|
||||
box-shadow: 7px 7px 8px black;
|
||||
|
||||
|
||||
img {
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 10px;
|
||||
border: 8px solid #212121;
|
||||
box-shadow: 4px 4px 3px #0c0c0c;
|
||||
}
|
||||
}
|
||||
|
||||
h1.title {
|
||||
color: black;
|
||||
font-size: 6em;
|
||||
font-family: 'Pirata One', arial;
|
||||
text-shadow: 3px 3px 3px #aaa;
|
||||
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
background-color: white;
|
||||
padding: 0px;
|
||||
/*font-size: 16em;*/
|
||||
width: 2.5em;
|
||||
height: 1.3em;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
box-shadow: 5px 5px 8px #000000;
|
||||
|
||||
}
|
||||
|
||||
.card {
|
||||
/*background-color: grey;*/
|
||||
background-color: $ui-colour;
|
||||
box-shadow: 4px 4px 8px black;
|
||||
padding: 10px;
|
||||
margin: $pad-px / 2;
|
||||
/*border-radius: 3px;*/
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: white;
|
||||
text-shadow: 1px 1px 2px #4f4f4f;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 8px;
|
||||
box-shadow: 2px 2px 2px black;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
h1.sectiontitle {
|
||||
text-align:center;
|
||||
color: white;
|
||||
font-family: 'Megrim', sans-serif;
|
||||
}
|
||||
|
||||
ul.navbar {
|
||||
list-style-type: none;
|
||||
border-radius: 5px 5px;
|
||||
/*box-shadow: 3px 3px 1px grey;*/
|
||||
margin: 10px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: $ui-colour;
|
||||
|
||||
|
||||
li {
|
||||
float: left;
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
|
||||
a {
|
||||
display: block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
text-shadow: 1px 1px 2px black;
|
||||
-webkit-transition: background-color 0.4s;
|
||||
transition: background-color 0.4s;
|
||||
|
||||
|
||||
&:hover {
|
||||
background-color: #080808;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li.right {float: right;}
|
||||
}
|
||||
|
||||
footer {
|
||||
p {
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
a {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: right;
|
||||
display: block;
|
||||
color: grey;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
ul.navbar li.right,
|
||||
ul.navbar li {float: none;}
|
||||
}
|
||||
|
||||
[class*="col-"] {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[class*="pad-"] {
|
||||
float: left;
|
||||
width: calc(100% - #{$pad-px});
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
/* For desktop: */
|
||||
.col-1 {width: 8.33%;}
|
||||
.col-2 {width: 16.66%;}
|
||||
.col-3 {width: 25%;}
|
||||
.col-4 {width: 33.33%;}
|
||||
.col-5 {width: 41.66%;}
|
||||
.col-6 {width: 50%;}
|
||||
.col-7 {width: 58.33%;}
|
||||
.col-8 {width: 66.66%;}
|
||||
.col-9 {width: 75%;}
|
||||
.col-10 {width: 83.33%;}
|
||||
.col-11 {width: 91.66%;}
|
||||
.col-12 {width: 100%;}
|
||||
|
||||
/* For desktop: */
|
||||
.pad-2 {width: calc(16.66% - #{$pad-px});}
|
||||
.pad-3 {width: calc(25% - #{$pad-px});}
|
||||
.pad-4 {width: calc(33.33% - #{$pad-px});}
|
||||
.pad-5 {width: calc(41.66% - #{$pad-px});}
|
||||
.pad-6 {width: calc(50% - #{$pad-px});}
|
||||
.pad-7 {width: calc(58.33% - #{$pad-px});}
|
||||
.pad-8 {width: calc(66.66% - #{$pad-px});}
|
||||
.pad-9 {width: calc(75% - #{$pad-px});}
|
||||
.pad-10 {width: calc(83.33% - #{$pad-px});}
|
||||
.pad-11 {width: calc(91.66% - #{$pad-px});}
|
||||
.pad-12 {width: calc(100% - #{$pad-px});}
|
||||
}
|
||||
|
||||
.row::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
Loading…
Reference in New Issue
Block a user