mirror of
https://github.com/NovaOSS/nova-web.git
synced 2024-11-29 11:53:58 +01:00
Compare commits
2 commits
41bc3ecaa0
...
feda964a6a
Author | SHA1 | Date | |
---|---|---|---|
feda964a6a | |||
16e1ae1bcb |
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -13,7 +13,12 @@
|
||||||
"static/css/home.css": true,
|
"static/css/home.css": true,
|
||||||
"static/css/navbar.css": true,
|
"static/css/navbar.css": true,
|
||||||
"static/css/input.css": true,
|
"static/css/input.css": true,
|
||||||
"static/css/footer.css": true
|
"static/css/footer.css": true,
|
||||||
|
"web/static/css/base.css": true,
|
||||||
|
"web/static/css/footer.css": true,
|
||||||
|
"web/static/css/home.css": true,
|
||||||
|
"web/static/css/input.css": true,
|
||||||
|
"web/static/css/navbar.css": true
|
||||||
},
|
},
|
||||||
"hide-files.files": [
|
"hide-files.files": [
|
||||||
"static/css/base.css",
|
"static/css/base.css",
|
||||||
|
|
|
@ -51,5 +51,5 @@ def create_app() -> flask.Flask:
|
||||||
production = create_app()
|
production = create_app()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print('* Live on http://localhost:2211')
|
print('* DEV environment online at http://localhost:2211')
|
||||||
create_app().run(debug=True, use_reloader=True, use_evalex=False, port=2211, host='0.0.0.0', threaded=True)
|
create_app().run(debug=True, use_reloader=True, use_evalex=False, port=2211, host='0.0.0.0', threaded=True)
|
||||||
|
|
|
@ -20,12 +20,12 @@ div.featured-box {
|
||||||
transition: all 200ms;
|
transition: all 200ms;
|
||||||
}
|
}
|
||||||
div.featured-box:hover {
|
div.featured-box:hover {
|
||||||
scale: 1.05;
|
scale: 1.025;
|
||||||
filter: brightness(1.1) saturate(1.1);
|
filter: brightness(1.1) saturate(1.1);
|
||||||
box-shadow: 0 0 30px rgba(244, 90, 136, 0.3803921569);
|
box-shadow: 0 0 30px rgba(244, 90, 136, 0.3803921569);
|
||||||
}
|
}
|
||||||
div.featured-box img {
|
div.featured-box img {
|
||||||
height: 100px;
|
height: 50px;
|
||||||
-o-object-fit: cover;
|
-o-object-fit: cover;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ div.featured-box h2 {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-block: auto;
|
margin-block: auto;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
font-size: 2rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
div.featured-box h2 span {
|
div.featured-box h2 span {
|
||||||
color: #f45a88;
|
color: #f45a88;
|
||||||
|
@ -52,7 +52,7 @@ div.user-quotes div.user-quote__field {
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
}
|
}
|
||||||
div.user-quotes div.user-quote__field:hover {
|
div.user-quotes div.user-quote__field:hover {
|
||||||
scale: 1.05;
|
scale: 1.025;
|
||||||
filter: brightness(1.1) saturate(1.1);
|
filter: brightness(1.1) saturate(1.1);
|
||||||
box-shadow: 0 0 30px rgba(244, 90, 136, 0.3803921569);
|
box-shadow: 0 0 30px rgba(244, 90, 136, 0.3803921569);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -20,19 +20,19 @@ div.featured-box
|
||||||
transition: all 200ms
|
transition: all 200ms
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
scale: 1.05
|
scale: 1.025
|
||||||
filter: brightness(1.1) saturate(1.1)
|
filter: brightness(1.1) saturate(1.1)
|
||||||
box-shadow: 0 0 30px $primary-glow
|
box-shadow: 0 0 30px $primary-glow
|
||||||
|
|
||||||
img
|
img
|
||||||
height: 100px
|
height: 50px
|
||||||
object-fit: cover
|
object-fit: cover
|
||||||
|
|
||||||
h2
|
h2
|
||||||
vertical-align: middle
|
vertical-align: middle
|
||||||
margin-block: auto
|
margin-block: auto
|
||||||
margin-left: 1rem
|
margin-left: 1rem
|
||||||
font-size: 2rem
|
font-size: 1.5rem
|
||||||
|
|
||||||
span
|
span
|
||||||
color: $primary-light
|
color: $primary-light
|
||||||
|
@ -55,7 +55,7 @@ div.user-quotes
|
||||||
min-height: 200px
|
min-height: 200px
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
scale: 1.05
|
scale: 1.025
|
||||||
filter: brightness(1.1) saturate(1.1)
|
filter: brightness(1.1) saturate(1.1)
|
||||||
box-shadow: 0 0 30px $primary-glow
|
box-shadow: 0 0 30px $primary-glow
|
||||||
|
|
||||||
|
|
26
web/templates/common/begin.html
Normal file
26
web/templates/common/begin.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
{% include 'common/seo.html' %}
|
||||||
|
|
||||||
|
{% for css in 'navbar base footer input fonts'.split() %}
|
||||||
|
<link rel="stylesheet" href="/static/css/{{ css }}.css">
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/static/ext/css/prism.css">
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.28.0/prism.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-bash.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-python.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-java.min.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||||
|
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||||
|
|
||||||
|
<title>NovaAI - Make AI Open Again</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include 'common/nav.html' %}
|
4
web/templates/common/end.html
Normal file
4
web/templates/common/end.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{% include 'common/footer.html' %}
|
||||||
|
</body>
|
||||||
|
<script src="/static/js/menu.js"></script>
|
||||||
|
</html>
|
36
web/templates/common/footer.html
Normal file
36
web/templates/common/footer.html
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<footer>
|
||||||
|
<div class="rows">
|
||||||
|
<div class="row">
|
||||||
|
<h2>Get started</h2>
|
||||||
|
<a href="/go">Start using the API</a>
|
||||||
|
<a href="/novacord">How to use NovaCord</a>
|
||||||
|
<a href="/replit">Secure your API keys when using Replit</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h2>About</h2>
|
||||||
|
<a href="/#faq">FAQ</a>
|
||||||
|
<a href="mailto:{{ contact_email }}">Contact</a>
|
||||||
|
<a href="https://github.com/novaoss/nova-api/graphs/contributors?type=a" target="_blank">Contributors</a>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h2>Links</h2>
|
||||||
|
<a href="https://github.com/novaoss" target="_blank">GitHub</a>
|
||||||
|
<a href="https://discord.nova-oss.com" target="_blank">Discord</a>
|
||||||
|
<a href="https://www.reddit.com/r/nova_ai" target="_blank">Reddit</a>
|
||||||
|
<a href="https://t.me/nova_gpt" target="_blank">Telegram</a>
|
||||||
|
<a href="https://trello.com/b/ar5MDmwH/nova-base" target="_blank">Trello</a>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h2>Legal</h2>
|
||||||
|
<a href="/legal/imprint">Imprint</a>
|
||||||
|
<a href="/legal/terms">Terms of Service</a>
|
||||||
|
<a href="/legal/privacy">Privacy Policy</a>
|
||||||
|
<a href="https://github.com/novaoss/nova-web/blob/main/LICENSE" target="_blank">License</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
© 2023. All rights reserved.
|
||||||
|
</p>
|
||||||
|
</footer>
|
25
web/templates/common/nav.html
Normal file
25
web/templates/common/nav.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<nav>
|
||||||
|
<!-- <img height="64" alt="NovaOSS Logo" aria-label="NovaOSS Logo" class="logo" src=""> -->
|
||||||
|
<svg class="logo" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sparkles" width="64" height="64" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M16 18a2 2 0 0 1 2 2a2 2 0 0 1 2 -2a2 2 0 0 1 -2 -2a2 2 0 0 1 -2 2zm0 -12a2 2 0 0 1 2 2a2 2 0 0 1 2 -2a2 2 0 0 1 -2 -2a2 2 0 0 1 -2 2zm-7 12a6 6 0 0 1 6 -6a6 6 0 0 1 -6 -6a6 6 0 0 1 -6 6a6 6 0 0 1 6 6z"></path></svg>
|
||||||
|
|
||||||
|
<h1>NovaAI
|
||||||
|
<mark>open source</mark>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<!-- Separator -->
|
||||||
|
<span></span>
|
||||||
|
|
||||||
|
<div id="links" class="link-menu">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<!-- <a href="https://status.nova-oss.com" target="_blank">Status</a> -->
|
||||||
|
<a href="https://code.nova-oss.com" target="_blank">GitHub</a>
|
||||||
|
<a href="mailto:{{ contact_email }}">Contact</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<svg alt="Mobile menu" id="menu" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-dots-vertical" width="40" height="40" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
|
<path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||||
|
<path d="M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||||
|
<path d="M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||||
|
</svg>
|
||||||
|
</nav>
|
33
web/templates/common/seo.html
Normal file
33
web/templates/common/seo.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<!-- Main -->
|
||||||
|
<link href="https://nova-oss.com/" rel="canonical"/>
|
||||||
|
<meta content="NovaAI" name="apple-mobile-web-app-title"/>
|
||||||
|
<meta content="en" http-equiv="Content-Language"/>
|
||||||
|
|
||||||
|
<!-- OpenGraph -->
|
||||||
|
<meta property="og:title" content="NovaAI: Use cutting-edge AI for free!">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:url" content="hhttps://nova-oss.com">
|
||||||
|
<meta property="og:image" content="https://nova-oss.com/static/img/banner.png">
|
||||||
|
|
||||||
|
<!-- Description -->
|
||||||
|
<meta property="og:description" content=
|
||||||
|
"🤖 Tired of paying for LLM APIs? NovaAI allows you to utilize the newest language models for free!"
|
||||||
|
>
|
||||||
|
<meta property="description" content=
|
||||||
|
"🤖 Tired of paying for LLM APIs? NovaAI allows you to utilize the newest language models for free!"
|
||||||
|
>
|
||||||
|
<meta name="description" content=
|
||||||
|
"🤖 Tired of paying for LLM APIs? NovaAI allows you to utilize the newest language models for free!"
|
||||||
|
>
|
||||||
|
|
||||||
|
<meta property="og:determiner" content="the">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta property="og:locale:alternate" content="en_GB">
|
||||||
|
<meta property="og:site_name" content="nova-oss.com | official website of project NovaAI">
|
||||||
|
|
||||||
|
<meta property="og:article:author" content="NovaAI">
|
||||||
|
<meta property="og:article:tag" content="NovaAI">
|
||||||
|
|
||||||
|
<!-- Other -->
|
||||||
|
<meta name="theme-color" content="#28aaf0">
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
<link rel="stylesheet" href="/static/css/home.css">
|
<link rel="stylesheet" href="/static/css/home.css">
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
@ -19,18 +19,26 @@
|
||||||
<a href="https://github.com/NovaOSS/nova-api" target="_blank">
|
<a href="https://github.com/NovaOSS/nova-api" target="_blank">
|
||||||
<button class="secondary">
|
<button class="secondary">
|
||||||
<i class="bi bi-github"></i>
|
<i class="bi bi-github"></i>
|
||||||
Open Source
|
GitHub
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<h2>Look, mom, I'm famous!</h2>
|
<h2>About Nova</h2>
|
||||||
|
<div class="featured-box">
|
||||||
|
<img src="https://icons.getbootstrap.com/assets/icons/cash-coin.svg" style="filter: invert(1);">
|
||||||
|
<h2>Free <span>forever</span> - no credit card required</h2>
|
||||||
|
</div>
|
||||||
|
<div class="featured-box" onclick="window.open('https://github.com/orgs/NovaOSS/repositories', '_blank')">
|
||||||
|
<img src="https://icons.getbootstrap.com/assets/icons/github.svg" style="filter: invert(1);">
|
||||||
|
<h2>Open source on <span>GitHub</span></h2>
|
||||||
|
</div>
|
||||||
<div class="featured-box" onclick="window.open('https://fmhy.pages.dev/ai', '_blank')">
|
<div class="featured-box" onclick="window.open('https://fmhy.pages.dev/ai', '_blank')">
|
||||||
<img src="https://fmhy.pages.dev/static/fmhy.ico">
|
<img src="https://fmhy.pages.dev/static/fmhy.ico">
|
||||||
<h2>Featured in <span>Free Media Heck Yeah</span></h2>
|
<h2>Featured in <span>Free Media Heck Yeah</span></h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Cherry-picked quotes</h2>
|
<h2>What users say</h2>
|
||||||
|
|
||||||
<div class="user-quotes">
|
<div class="user-quotes">
|
||||||
<div class="user-quote__field" onclick="window.open('https://discord.com/channels/1120037287300976640/1120037729644855427/1144279505981153302', '_blank')">
|
<div class="user-quote__field" onclick="window.open('https://discord.com/channels/1120037287300976640/1120037729644855427/1144279505981153302', '_blank')">
|
||||||
|
@ -83,4 +91,4 @@
|
||||||
punctuation on these messages.
|
punctuation on these messages.
|
||||||
</h6>
|
</h6>
|
||||||
</main>
|
</main>
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h1>Privacy</h1>
|
<h1>Privacy</h1>
|
||||||
|
@ -90,4 +90,4 @@
|
||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
{% if verify %}
|
{% if verify %}
|
||||||
|
@ -141,4 +141,4 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
<link rel="stylesheet" href="/static/css/home.css">
|
<link rel="stylesheet" href="/static/css/home.css">
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
@ -39,4 +39,4 @@
|
||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
<link rel="stylesheet" href="/static/css/home.css">
|
<link rel="stylesheet" href="/static/css/home.css">
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
@ -54,4 +54,4 @@ novaai.api_base = 'https://api.nova-oss.com/v1'</code></pre>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% include 'parts/begin.html' %}
|
{% include 'common/begin.html' %}
|
||||||
<link rel="stylesheet" href="/static/css/home.css">
|
<link rel="stylesheet" href="/static/css/home.css">
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
@ -68,4 +68,4 @@ client.login(process.env.DISCORD_BOT_TOKEN)</code></pre>
|
||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include 'parts/end.html' %}
|
{% include 'common/end.html' %}
|
||||||
|
|
15
web/tos.py
15
web/tos.py
|
@ -1,10 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import json
|
import ujson
|
||||||
import flask
|
import flask
|
||||||
import random
|
import random
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from json.decoder import JSONDecodeError
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
@ -21,12 +22,12 @@ def register(app):
|
||||||
open('data/tos.json', 'w', encoding='utf8').write('{}')
|
open('data/tos.json', 'w', encoding='utf8').write('{}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.load(open('data/tos.json', encoding='utf8'))
|
data = ujson.load(open('data/tos.json', encoding='utf8'))
|
||||||
except json.decoder.JSONDecodeError:
|
except JSONDecodeError:
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
data[code] = emoji
|
data[code] = emoji
|
||||||
json.dump(data, open('data/tos.json', 'w', encoding='utf8'))
|
ujson.dump(data, open('data/tos.json', 'w', encoding='utf8'))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'code': code,
|
'code': code,
|
||||||
|
@ -38,9 +39,9 @@ def register(app):
|
||||||
if not flask.request.headers.get('Authorization') == os.getenv('TOS_VERIFICATION_KEY'):
|
if not flask.request.headers.get('Authorization') == os.getenv('TOS_VERIFICATION_KEY'):
|
||||||
return 'Unauthorized', 401
|
return 'Unauthorized', 401
|
||||||
|
|
||||||
data = json.load(open('data/tos.json', encoding='utf8'))
|
data = ujson.load(open('data/tos.json', encoding='utf8'))
|
||||||
del data[code]
|
del data[code]
|
||||||
json.dump(data, open('data/tos.json', 'w', encoding='utf8'))
|
ujson.dump(data, open('data/tos.json', 'w', encoding='utf8'))
|
||||||
|
|
||||||
return 'Removed.', 204
|
return 'Removed.', 204
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ def register(app):
|
||||||
def legal_site(subpath):
|
def legal_site(subpath):
|
||||||
emoji = None
|
emoji = None
|
||||||
if subpath == 'terms':
|
if subpath == 'terms':
|
||||||
emoji = json.load(open('data/tos.json', encoding='utf8')).get(flask.request.args.get('verify'))
|
emoji = ujson.load(open('data/tos.json', encoding='utf8')).get(flask.request.args.get('verify'))
|
||||||
if emoji:
|
if emoji:
|
||||||
emoji = emoji.encode('utf8')
|
emoji = emoji.encode('utf8')
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue