diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e20c616 --- /dev/null +++ b/.gitignore @@ -0,0 +1,137 @@ +# Django # +*.log +*.pot +*.pyc +__pycache__ +db.sqlite3 +media + +# Backup files # +*.bak + +# If you are using PyCharm # +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# File-based project format +*.iws + +# IntelliJ +out/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Python # +*.py[cod] +*$py.class + +# Distribution / packaging +.Python build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +.pytest_cache/ +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery +celerybeat-schedule.* + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Sublime Text # +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +*.sublime-project + +# sftp configuration file +sftp-config.json + +# Package control specific files Package +Control.last-run +Control.ca-list +Control.ca-bundle +Control.system-ca-bundle +GitHub.sublime-settings + +# Visual Studio Code # +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..26ee535 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +django = "*" + +[dev-packages] + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..a1abc28 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,75 @@ +{ + "_meta": { + "hash": { + "sha256": "99c4b9ec1b8891ff787677276760beb6d6d4919c55660da1c713682156a6086c" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "asgiref": { + "hashes": [ + "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4", + "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424" + ], + "markers": "python_version >= '3.7'", + "version": "==3.5.2" + }, + "backports.zoneinfo": { + "hashes": [ + "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf", + "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328", + "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546", + "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6", + "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570", + "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9", + "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7", + "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987", + "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722", + "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582", + "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc", + "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b", + "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1", + "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08", + "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac", + "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2" + ], + "markers": "python_version < '3.9'", + "version": "==0.2.1" + }, + "django": { + "hashes": [ + "sha256:678bbfc8604eb246ed54e2063f0765f13b321a50526bdc8cb1f943eda7fa31f1", + "sha256:6b1de6886cae14c7c44d188f580f8ba8da05750f544c80ae5ad43375ab293cd5" + ], + "index": "pypi", + "version": "==4.1.3" + }, + "sqlparse": { + "hashes": [ + "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34", + "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268" + ], + "markers": "python_version >= '3.5'", + "version": "==0.4.3" + }, + "tzdata": { + "hashes": [ + "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d", + "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa" + ], + "markers": "sys_platform == 'win32'", + "version": "==2022.7" + } + }, + "develop": {} +} diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..5825c8e --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/viewer/__init__.py b/viewer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewer/apps/player/__init__.py b/viewer/apps/player/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewer/apps/player/admin.py b/viewer/apps/player/admin.py new file mode 100644 index 0000000..ea5d68b --- /dev/null +++ b/viewer/apps/player/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/viewer/apps/player/apps.py b/viewer/apps/player/apps.py new file mode 100644 index 0000000..de4a93b --- /dev/null +++ b/viewer/apps/player/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PlayerConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "player" diff --git a/viewer/apps/player/migrations/__init__.py b/viewer/apps/player/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewer/apps/player/models.py b/viewer/apps/player/models.py new file mode 100644 index 0000000..fd18c6e --- /dev/null +++ b/viewer/apps/player/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/viewer/apps/player/tests.py b/viewer/apps/player/tests.py new file mode 100644 index 0000000..de8bdc0 --- /dev/null +++ b/viewer/apps/player/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/viewer/apps/player/urls.py b/viewer/apps/player/urls.py new file mode 100644 index 0000000..4440fef --- /dev/null +++ b/viewer/apps/player/urls.py @@ -0,0 +1,6 @@ +from . import views +from django.urls import path + +urlpatterns = [ + path("", views.player), +] diff --git a/viewer/apps/player/views.py b/viewer/apps/player/views.py new file mode 100644 index 0000000..4fd086f --- /dev/null +++ b/viewer/apps/player/views.py @@ -0,0 +1,5 @@ +from django.shortcuts import render + +# Create your views here. +def player(request): + return render(request, "player/player.html") \ No newline at end of file diff --git a/viewer/apps/users/__init__.py b/viewer/apps/users/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewer/apps/users/admin.py b/viewer/apps/users/admin.py new file mode 100644 index 0000000..c47b200 --- /dev/null +++ b/viewer/apps/users/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from . import models +# Register your models here. +admin.site.register(models.Annotation) +admin.site.register(models.Comment) \ No newline at end of file diff --git a/viewer/apps/users/apps.py b/viewer/apps/users/apps.py new file mode 100644 index 0000000..e9121c9 --- /dev/null +++ b/viewer/apps/users/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "users" diff --git a/viewer/apps/users/migrations/__init__.py b/viewer/apps/users/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewer/apps/users/models.py b/viewer/apps/users/models.py new file mode 100644 index 0000000..03b8b7f --- /dev/null +++ b/viewer/apps/users/models.py @@ -0,0 +1,20 @@ +from django.db import models +from django.contrib.auth.models import User + +# Create your models here. +class Annotation(models.Model): + id = models.AutoField(primary_key=True) + timestamp = models.CharField(max_length=20) + contents = models.CharField(max_length=1000) + + def __str__(self): + return f"{self.timestamp}" + +class Comment(models.Model): + id = models.AutoField(primary_key=True) + timestamp = models.CharField(max_length=20) + contents = models.CharField(max_length=1000) + author = models.ForeignKey(User, on_delete=models.CASCADE) + + def __str__(self): + return f"{self.timestamp} @ {self.author}" \ No newline at end of file diff --git a/viewer/apps/users/tests.py b/viewer/apps/users/tests.py new file mode 100644 index 0000000..de8bdc0 --- /dev/null +++ b/viewer/apps/users/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/viewer/apps/users/urls.py b/viewer/apps/users/urls.py new file mode 100644 index 0000000..e37c768 --- /dev/null +++ b/viewer/apps/users/urls.py @@ -0,0 +1,7 @@ +from . import views +from django.urls import path, include + +urlpatterns = [ + path("login/", views.login, name="login"), + path("signup/", views.signup, name="signup") +] \ No newline at end of file diff --git a/viewer/apps/users/views.py b/viewer/apps/users/views.py new file mode 100644 index 0000000..0a88b17 --- /dev/null +++ b/viewer/apps/users/views.py @@ -0,0 +1,8 @@ +from django.shortcuts import render + +# Create your views here. +def signup(request): + return render(request, "users/signup.html") + +def login(request): + return render(request, "users/login.html") \ No newline at end of file diff --git a/viewer/asgi.py b/viewer/asgi.py new file mode 100644 index 0000000..f299b4d --- /dev/null +++ b/viewer/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for viewer project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.settings") + +application = get_asgi_application() diff --git a/viewer/settings/.gitignore b/viewer/settings/.gitignore new file mode 100644 index 0000000..b47515c --- /dev/null +++ b/viewer/settings/.gitignore @@ -0,0 +1 @@ +secret.py \ No newline at end of file diff --git a/viewer/settings/__init__.py b/viewer/settings/__init__.py new file mode 100644 index 0000000..d4d4bf3 --- /dev/null +++ b/viewer/settings/__init__.py @@ -0,0 +1,130 @@ +""" +Django settings for viewer project. + +Generated by 'django-admin startproject' using Django 4.1.3. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.1/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +ALLOWED_HOSTS = ["localhost", "127.0.0.1"] + + +# Application definition + +INSTALLED_APPS = [ + + + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "viewer.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + 'DIRS': [BASE_DIR / 'templates'], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "viewer.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.1/topics/i18n/ + +LANGUAGE_CODE = "en-us" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_ROOT = BASE_DIR / 'serve/' + +STATIC_URL = '/static/' + +STATICFILES_DIRS = ( + BASE_DIR / 'static/', +) + +MEDIA_ROOT = BASE_DIR / 'media/' + +MEDIA_URL = '/media/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +try: + from .secret import * +except ImportError: + pass diff --git a/viewer/settings/secret.sample b/viewer/settings/secret.sample new file mode 100644 index 0000000..4799eb5 --- /dev/null +++ b/viewer/settings/secret.sample @@ -0,0 +1,2 @@ +SECRET_KEY=secret +DEBUG=True \ No newline at end of file diff --git a/viewer/static/css/base.css b/viewer/static/css/base.css new file mode 100644 index 0000000..d08095a --- /dev/null +++ b/viewer/static/css/base.css @@ -0,0 +1,55 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +:root { + --background: #FCEFC2 +} + +body { + background: var(--background) +} + +* { + box-sizing: border-box; +} + +body { + font-family: Arial, Helvetica, sans-serif; +} + +/* Float four columns side by side */ +.column { + float: left; + width: 25%; + padding: 0 10px; +} + +/* Remove extra left and right margins, due to padding */ +.row {margin: 0 -5px;} + +/* Clear floats after the columns */ +.row:after { + content: ""; + display: table; + clear: both; +} + +/* Responsive columns */ +@media screen and (max-width: 600px) { + .column { + width: 100%; + display: block; + margin-bottom: 20px; + } +} + +/* Style the counter cards */ +.card { + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); + padding: 16px; + text-align: center; + background-color: #f1f1f1; +} \ No newline at end of file diff --git a/viewer/static/css/registration.css b/viewer/static/css/registration.css new file mode 100644 index 0000000..f40c487 --- /dev/null +++ b/viewer/static/css/registration.css @@ -0,0 +1,11 @@ +form { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + background: none; + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/viewer/templates/player/base.html b/viewer/templates/player/base.html new file mode 100644 index 0000000..867256a --- /dev/null +++ b/viewer/templates/player/base.html @@ -0,0 +1,19 @@ + + +{% load static %} + + + + + + + + MIT Regressions + + + + {% block head %}{% endblock %} + + + {% block body %}{% endblock %} + \ No newline at end of file diff --git a/viewer/templates/player/player.html b/viewer/templates/player/player.html new file mode 100644 index 0000000..7e4f4dc --- /dev/null +++ b/viewer/templates/player/player.html @@ -0,0 +1,38 @@ +{% extends "player/base.html" %} +{% block head %} + + +{% endblock %} +{% block body %} + + +
+
+
+

timestamp

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+
+
+
+{% endblock %} \ No newline at end of file diff --git a/viewer/templates/users/login.html b/viewer/templates/users/login.html new file mode 100644 index 0000000..53aea69 --- /dev/null +++ b/viewer/templates/users/login.html @@ -0,0 +1,14 @@ +{% extends "player/base.html" %} +{% load static %} +{% block head %} + +{% endblock %} + +{% block body %} +
+

login

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} \ No newline at end of file diff --git a/viewer/templates/users/signup.html b/viewer/templates/users/signup.html new file mode 100644 index 0000000..4a851e3 --- /dev/null +++ b/viewer/templates/users/signup.html @@ -0,0 +1,14 @@ +{% extends "player/base.html" %} +{% load static %} +{% block head %} + +{% endblock %} + +{% block body %} +
+

register

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} \ No newline at end of file diff --git a/viewer/urls.py b/viewer/urls.py new file mode 100644 index 0000000..41e9c34 --- /dev/null +++ b/viewer/urls.py @@ -0,0 +1,23 @@ +"""viewer URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path("admin/", admin.site.urls), + path("accounts", include("viewer.apps.users.urls")), + path("", include("viewer.apps.player.urls")), +] diff --git a/viewer/wsgi.py b/viewer/wsgi.py new file mode 100644 index 0000000..0a490e7 --- /dev/null +++ b/viewer/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for viewer project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.settings") + +application = get_wsgi_application()