Changes to help with deployment main
authorGeorgios Atheridis <georgios@atheridis.org>
Tue, 24 Jan 2023 13:39:27 +0000 (13:39 +0000)
committerGeorgios Atheridis <georgios@atheridis.org>
Wed, 25 Jan 2023 18:08:11 +0000 (18:08 +0000)
Made changes to settings so that it is easier to deploy the django
application. Created instructions to deploy to Debian 11 and added extra
help files to go along with the deployment.

28 files changed:
.gitignore
README [new file with mode: 0644]
TODO
core/core/settings.py
core/manager/migrations/0001_initial.py
core/manager/migrations/0002_rename_user_clip_account.py [deleted file]
core/manager/migrations/0003_alter_clip_account.py [deleted file]
core/manager/migrations/0004_alter_clip_id.py [deleted file]
core/manager/migrations/0005_myuser_alter_clip_account.py [deleted file]
core/manager/migrations/0006_clip_date_added_alter_clip_account_delete_myuser.py [deleted file]
core/manager/migrations/0007_resettime.py [deleted file]
core/manager/migrations/0008_resettime_clip_amount.py [deleted file]
core/manager/migrations/0009_rename_clip_amount_resettime_max_clips.py [deleted file]
core/manager/migrations/0010_rename_resettime_resetdata.py [deleted file]
core/manager/migrations/0011_clip_rank.py [deleted file]
core/manager/migrations/0012_resetdata_ranks.py [deleted file]
core/manager/migrations/0013_resetdata_clip_limit_to_channels_and_more.py [deleted file]
core/manager/migrations/0014_allowedchannel.py [deleted file]
core/manager/migrations/0015_remove_resetdata_clip_limit_to_channels_and_more.py [deleted file]
core/manager/request_clip.py
core/manager/templates/manager/clip_viewer.html
core/manager/templates/manager/final.html
core/manager/views.py
example.com.env [new file with mode: 0644]
example.com.nginx [new file with mode: 0644]
example.com.service [new file with mode: 0644]
generate_random_key.sh [new file with mode: 0755]
requirements.txt [new file with mode: 0644]

index b6e47617de110dea7ca47e087ff1347cc2646eda..e8796ee975bacb469d90c4ec211d564aab868a5e 100644 (file)
@@ -60,6 +60,7 @@ coverage.xml
 local_settings.py
 db.sqlite3
 db.sqlite3-journal
+staticfiles/
 
 # Flask stuff:
 instance/
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..6c5643c
--- /dev/null
+++ b/README
@@ -0,0 +1,65 @@
+How to deploy on Debian 11
+==========================
+
+
+Dependencies:
+==========================
+Python
+--------------------------
+python3
+
+Django
+--------------------------
+python3-django
+python3-django-allauth
+python3-psycopg2
+python3-whitenoise
+libjs-jquery
+
+Serving
+--------------------------
+gunicorn
+nginx
+
+SSL
+--------------------------
+certbot
+python3-certbot-nginx
+
+Postgres
+--------------------------
+postgresql
+postgresql-contrib
+
+
+Installation Instructions:
+==========================
+ 1. Install the necessary dependencies
+ 2. Create the directories; change example.com to your domain
+    a. /var/log/gunicorn/
+    b. /var/run/gunicorn/
+    c. /var/www/example.com/
+    d. /usr/local/etc/gunicorn/
+ 3. Copy example.com.service to /etc/systemd/system/ and change the name to your domain
+ 4. Edit the values of example.com.service by changing example.com to your domain
+ 5. Copy example.com.env to /usr/local/etc/gunicorn/ and change the name to your domain
+ 6. Edit the values of example.com.env
+    a. Generate a secret key by running generate_random_key.sh
+ 7. Change the user and group ownership of (2.abd) directories to www-data recursively
+ 8. In postgres create a user with a password and a database owned by the user
+ 9. Export your environment variables and inside core, run `python3 manage.py migrate`
+10. Inside core, run `python3 manage.py createsuperuser`
+11. Inside core, run `python3 manage.py collectstatic`
+12. Copy the contents of core/ into /var/www/example.com/
+13. Copy example.com.nginx to /etc/nginx/sites-available/ and change the name
+14. Edit the file example.com.nginx replacing example.com with your domain
+15. Run certbot to verify your domain
+16. Enable gunicorn `systemctl enable --now example.com.service`
+17. Enable nginx `systemctl enable --now example.com.service`
+
+
+Finalising Deployment:
+==========================
+1. Log into the admin panel of your website and edit / create site values in "Sites"
+2. Create a Social Application.
+3. Create a ResetData object.
diff --git a/TODO b/TODO
index 8308d21cb63fadbb0392705be4fb33549c22ded9..d3533dfb9b0f16ff8bc95033b3fd44656c1c5d2f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,3 +5,17 @@
 
 - Display clip info more clearly
 -- Clip comments?
+
+- Allow users to delete clips they've added during a block
+
+- Add left and right buttons on clips during ranking
+
+- Show a list of all clips during ranking with a button to quickly go to
+
+- A button to quickly go to the specific clip ranking from the results
+
+- Let users view clips uploaded by others and let them see the final page
+
+- Show historical rankings
+
+- If a clip has been ranked, show its ranking during the ranking phase
index cac04644a1b982c6d0ccb20b8edad8e0f9c87171..b63bf9d089fcffaabc1d6b7098aef596023b330f 100644 (file)
@@ -20,19 +20,22 @@ BASE_DIR = Path(__file__).resolve().parent.parent
 # Quick-start development settings - unsuitable for production
 # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
 
-# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = "django-insecure-!nzce=4gwub(n+!6@lh^vjl+m(*ibo42&gav2kvr@d4!$3ausi"
 
 # SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = True
+DEBUG = os.getenv("CLIP_RANKER_DEBUG", "") != "False"
 
 if DEBUG:
     import dotenv
 
     dotenv.load_dotenv()
 
-ALLOWED_HOSTS = []
 
+ALLOWED_HOSTS = os.getenv("CLIP_RANKER_ALLOWED_HOSTS", "").split(";")
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = os.getenv(
+    "CLIP_RANKER_SECRET_KEY", "04t8gx%o4!^1ae_@%3r@vb^=lx^r$%u*5&+88568$s%w)u1b@f"
+)
 
 # Application definition
 
@@ -62,6 +65,7 @@ MIDDLEWARE = [
     "django.contrib.auth.middleware.AuthenticationMiddleware",
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
+    "whitenoise.middleware.WhiteNoiseMiddleware",
 ]
 
 ROOT_URLCONF = "core.urls"
@@ -92,12 +96,15 @@ WSGI_APPLICATION = "core.wsgi.application"
 
 DATABASES = {
     "default": {
-        "ENGINE": "django.db.backends.sqlite3",
-        "NAME": BASE_DIR / "db.sqlite3",
+        "ENGINE": "django.db.backends.postgresql",
+        "NAME": os.getenv("CLIP_RANKER_DB_NAME"),
+        "USER": os.getenv("CLIP_RANKER_DB_USER"),
+        "PASSWORD": os.getenv("CLIP_RANKER_DB_PASS"),
+        "HOST": os.getenv("CLIP_RANKER_DB_HOST"),
+        "PORT": os.getenv("CLIP_RANKER_DB_PORT"),
     }
 }
 
-
 # Password validation
 # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
 
@@ -132,9 +139,12 @@ USE_TZ = True
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/4.1/howto/static-files/
 
-STATIC_URL = "static/"
+STATIC_URL = "/static/"
+
 STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
 
+STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
+
 # Default primary key field type
 # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
 
index a04301a51e2038df6d5349815a6e73f883873695..aac1326f1f7149b83bf033a91cf498d3004a92dd 100644 (file)
@@ -1,5 +1,7 @@
-# Generated by Django 4.1.5 on 2023-01-22 12:47
+# Generated by Django 4.1.5 on 2023-01-25 14:32
 
+import datetime
+from django.conf import settings
 from django.db import migrations, models
 import django.db.models.deletion
 
@@ -9,16 +11,46 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ("socialaccount", "0003_extra_data_default_dict"),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
     ]
 
     operations = [
+        migrations.CreateModel(
+            name="ResetData",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("date_time", models.DateTimeField()),
+                (
+                    "end_date_time",
+                    models.DateTimeField(default=datetime.datetime(2038, 1, 19, 3, 14)),
+                ),
+                ("max_clips", models.IntegerField(default=2)),
+                ("ranks", models.IntegerField(default=5)),
+                ("user_created_clip", models.BooleanField(default=True)),
+                (
+                    "clip_newer_than",
+                    models.DateTimeField(
+                        default=datetime.datetime(1970, 1, 1, 0, 0, 1)
+                    ),
+                ),
+            ],
+        ),
         migrations.CreateModel(
             name="Clip",
             fields=[
                 (
                     "id",
-                    models.CharField(max_length=100, primary_key=True, serialize=False),
+                    models.CharField(
+                        max_length=100, primary_key=True, serialize=False, unique=True
+                    ),
                 ),
                 ("url", models.URLField(null=True)),
                 ("embed_url", models.URLField(null=True)),
@@ -34,13 +66,40 @@ class Migration(migrations.Migration):
                 ("thumbnail_url", models.URLField(null=True)),
                 ("duration", models.FloatField(null=True)),
                 ("vod_offset", models.IntegerField(null=True)),
+                ("date_added", models.DateTimeField(null=True)),
+                ("rank", models.IntegerField(null=True)),
+                (
+                    "account",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+        ),
+        migrations.CreateModel(
+            name="AllowedChannel",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("broadcaster_id", models.CharField(max_length=100)),
                 (
-                    "user",
+                    "reset_data",
                     models.ForeignKey(
                         on_delete=django.db.models.deletion.CASCADE,
-                        to="socialaccount.socialaccount",
+                        to="manager.resetdata",
                     ),
                 ),
             ],
+            options={
+                "unique_together": {("broadcaster_id", "reset_data")},
+            },
         ),
     ]
diff --git a/core/manager/migrations/0002_rename_user_clip_account.py b/core/manager/migrations/0002_rename_user_clip_account.py
deleted file mode 100644 (file)
index c1c4aaf..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 12:48
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0001_initial"),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name="clip",
-            old_name="user",
-            new_name="account",
-        ),
-    ]
diff --git a/core/manager/migrations/0003_alter_clip_account.py b/core/manager/migrations/0003_alter_clip_account.py
deleted file mode 100644 (file)
index 2d1f5c9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 12:52
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ("manager", "0002_rename_user_clip_account"),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name="clip",
-            name="account",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
-            ),
-        ),
-    ]
diff --git a/core/manager/migrations/0004_alter_clip_id.py b/core/manager/migrations/0004_alter_clip_id.py
deleted file mode 100644 (file)
index 4709e22..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 13:10
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0003_alter_clip_account"),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name="clip",
-            name="id",
-            field=models.CharField(
-                max_length=100, primary_key=True, serialize=False, unique=True
-            ),
-        ),
-    ]
diff --git a/core/manager/migrations/0005_myuser_alter_clip_account.py b/core/manager/migrations/0005_myuser_alter_clip_account.py
deleted file mode 100644 (file)
index ffebc21..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 13:30
-
-from django.conf import settings
-import django.contrib.auth.models
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("auth", "0012_alter_user_first_name_max_length"),
-        ("manager", "0004_alter_clip_id"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="MyUser",
-            fields=[
-                (
-                    "user_ptr",
-                    models.OneToOneField(
-                        auto_created=True,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        parent_link=True,
-                        primary_key=True,
-                        serialize=False,
-                        to=settings.AUTH_USER_MODEL,
-                    ),
-                ),
-                ("clip_amount", models.IntegerField(default=0)),
-            ],
-            options={
-                "verbose_name": "user",
-                "verbose_name_plural": "users",
-                "abstract": False,
-            },
-            bases=("auth.user",),
-            managers=[
-                ("objects", django.contrib.auth.models.UserManager()),
-            ],
-        ),
-        migrations.AlterField(
-            model_name="clip",
-            name="account",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE, to="manager.myuser"
-            ),
-        ),
-    ]
diff --git a/core/manager/migrations/0006_clip_date_added_alter_clip_account_delete_myuser.py b/core/manager/migrations/0006_clip_date_added_alter_clip_account_delete_myuser.py
deleted file mode 100644 (file)
index f523efb..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 13:42
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ("manager", "0005_myuser_alter_clip_account"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="clip",
-            name="date_added",
-            field=models.DateTimeField(null=True),
-        ),
-        migrations.AlterField(
-            model_name="clip",
-            name="account",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
-            ),
-        ),
-        migrations.DeleteModel(
-            name="MyUser",
-        ),
-    ]
diff --git a/core/manager/migrations/0007_resettime.py b/core/manager/migrations/0007_resettime.py
deleted file mode 100644 (file)
index 6cafcbe..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 13:50
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0006_clip_date_added_alter_clip_account_delete_myuser"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="ResetTime",
-            fields=[
-                (
-                    "id",
-                    models.BigAutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                ("date_time", models.DateTimeField()),
-            ],
-        ),
-    ]
diff --git a/core/manager/migrations/0008_resettime_clip_amount.py b/core/manager/migrations/0008_resettime_clip_amount.py
deleted file mode 100644 (file)
index c41dc35..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 13:58
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0007_resettime"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="resettime",
-            name="clip_amount",
-            field=models.IntegerField(default=2),
-        ),
-    ]
diff --git a/core/manager/migrations/0009_rename_clip_amount_resettime_max_clips.py b/core/manager/migrations/0009_rename_clip_amount_resettime_max_clips.py
deleted file mode 100644 (file)
index d73a64e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 14:00
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0008_resettime_clip_amount"),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name="resettime",
-            old_name="clip_amount",
-            new_name="max_clips",
-        ),
-    ]
diff --git a/core/manager/migrations/0010_rename_resettime_resetdata.py b/core/manager/migrations/0010_rename_resettime_resetdata.py
deleted file mode 100644 (file)
index f3619e5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 14:02
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0009_rename_clip_amount_resettime_max_clips"),
-    ]
-
-    operations = [
-        migrations.RenameModel(
-            old_name="ResetTime",
-            new_name="ResetData",
-        ),
-    ]
diff --git a/core/manager/migrations/0011_clip_rank.py b/core/manager/migrations/0011_clip_rank.py
deleted file mode 100644 (file)
index 2c76633..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-22 16:24
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0010_rename_resettime_resetdata"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="clip",
-            name="rank",
-            field=models.IntegerField(null=True),
-        ),
-    ]
diff --git a/core/manager/migrations/0012_resetdata_ranks.py b/core/manager/migrations/0012_resetdata_ranks.py
deleted file mode 100644 (file)
index a4c260f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-23 00:22
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0011_clip_rank"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="resetdata",
-            name="ranks",
-            field=models.IntegerField(default=5),
-        ),
-    ]
diff --git a/core/manager/migrations/0013_resetdata_clip_limit_to_channels_and_more.py b/core/manager/migrations/0013_resetdata_clip_limit_to_channels_and_more.py
deleted file mode 100644 (file)
index 62a60d9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-23 11:51
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0012_resetdata_ranks"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="resetdata",
-            name="clip_limit_to_channels",
-            field=models.JSONField(null=True),
-        ),
-        migrations.AddField(
-            model_name="resetdata",
-            name="clip_newer_than",
-            field=models.DateTimeField(default=datetime.datetime(1970, 1, 1, 0, 0, 1)),
-        ),
-        migrations.AddField(
-            model_name="resetdata",
-            name="user_created_clip",
-            field=models.BooleanField(default=True),
-        ),
-    ]
diff --git a/core/manager/migrations/0014_allowedchannel.py b/core/manager/migrations/0014_allowedchannel.py
deleted file mode 100644 (file)
index ec93b98..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-23 12:03
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0013_resetdata_clip_limit_to_channels_and_more"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="AllowedChannel",
-            fields=[
-                (
-                    "id",
-                    models.BigAutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                ("broadcaster_id", models.CharField(max_length=100)),
-                (
-                    "reset_data",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        to="manager.resetdata",
-                    ),
-                ),
-            ],
-        ),
-    ]
diff --git a/core/manager/migrations/0015_remove_resetdata_clip_limit_to_channels_and_more.py b/core/manager/migrations/0015_remove_resetdata_clip_limit_to_channels_and_more.py
deleted file mode 100644 (file)
index 3ad93f1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.1.5 on 2023-01-23 12:14
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("manager", "0014_allowedchannel"),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name="resetdata",
-            name="clip_limit_to_channels",
-        ),
-        migrations.AddField(
-            model_name="resetdata",
-            name="end_date_time",
-            field=models.DateTimeField(default=datetime.datetime(2038, 1, 19, 3, 14)),
-        ),
-    ]
index cf7ccdb168402b5a261de850b293269d28f18018..a3d963ec4f1f6d18f3b287ea9ea0cec1ec23bc99 100644 (file)
@@ -127,9 +127,8 @@ def request_clip(user, clip: str):
         if not allowed_channels.exists():
             raise ChannelNotAllowedError
 
-    if (
-            reset_data.clip_newer_than
-            > datetime.datetime.strptime(data["created_at"], "%Y-%m-%dT%H:%M:%S%z")
+    if reset_data.clip_newer_than > datetime.datetime.strptime(
+        data["created_at"], "%Y-%m-%dT%H:%M:%S%z"
     ):
         raise ClipTooOldError
 
index 3660ffa44a76fd290672640af1bba37e4265ab0f..c9d77fa4b7b9f37b1c9d417caf24dc8ccd1cf398 100644 (file)
@@ -3,7 +3,7 @@
 <div id="group">
     <h1>uploaded by: {{ video.account.username }}</h1>
     <iframe
-            src="https://clips.twitch.tv/embed?clip={{ video.id }}&parent=localhost"
+            src="https://clips.twitch.tv/embed?clip={{ video.id }}{% for site in sites %}&parent={{ site.domain }}{% endfor %}"
             height="600"
             width="1000"
             preload="none"
index a9ca52d35ad9dafa0a90c87958b9fd90d9a04b58..37ca36fb0de3de84d7e71473a8c206fdd24b4785 100644 (file)
@@ -8,7 +8,7 @@
         {% if video.rank == i %}
         <td>
             <iframe
-                    src="https://clips.twitch.tv/embed?clip={{ video.id }}&parent=localhost"
+                    src="https://clips.twitch.tv/embed?clip={{ video.id }}{% for site in sites %}&parent={{ site.domain }}{% endfor %}"
                     height="135"
                     width="240"
                     preload="none"
index f464b274a4d3cc795f45e0ed3320f61bccf1cb27..a326b9800b990838167589ef92b90a35b761e76a 100644 (file)
@@ -17,6 +17,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 from django.shortcuts import render, redirect
 from django.core.exceptions import ValidationError
 from django.contrib.admin.views.decorators import staff_member_required
+from django.contrib.sites.models import Site
 
 from .request_clip import request_clip
 from .forms import ClipForm, RankForm
@@ -31,7 +32,6 @@ from .errors import (
     NotFoundError,
 )
 from .models import Clip, ResetData
-import traceback
 
 
 @staff_member_required
@@ -39,9 +39,9 @@ def show_clips(request, id):
     reset_data = ResetData.objects.latest("date_time")
     reset_time = reset_data.date_time
     try:
-        video = Clip.objects.filter(
-            date_added__gt=reset_time
-        ).order_by("date_added")[id - 1]
+        video = Clip.objects.filter(date_added__gt=reset_time).order_by("date_added")[
+            id - 1
+        ]
     except IndexError:
         return redirect(final_ranking)
     if request.method == "POST":
@@ -56,6 +56,7 @@ def show_clips(request, id):
         context={
             "video": video,
             "ranks": range(reset_data.ranks, 0, -1),
+            "sites": Site.objects.all(),
         },
     )
 
@@ -70,6 +71,7 @@ def final_ranking(request):
         context={
             "videos": Clip.objects.filter(date_added__gt=reset_time),
             "ranks": range(reset_data.ranks, 0, -1),
+            "sites": Site.objects.all(),
         },
     )
 
diff --git a/example.com.env b/example.com.env
new file mode 100644 (file)
index 0000000..7a3ab11
--- /dev/null
@@ -0,0 +1,9 @@
+CLIP_RANKER_DEBUG="False"
+CLIP_RANKER_ALLOWED_HOSTS="example.com;www.example.com"
+CLIP_RANKER_SECRET_KEY="yoursecretkey"
+CLIP_RANKER_STATIC_ROOT="/var/www/example.com"
+CLIP_RANKER_DB_USER="username"
+CLIP_RANKER_DB_PASS="password"
+CLIP_RANKER_DB_HOST="localhost"
+CLIP_RANKER_DB_PORT="5432"
+CLIP_RANKER_DB_NAME="dbname"
diff --git a/example.com.nginx b/example.com.nginx
new file mode 100644 (file)
index 0000000..8753ba2
--- /dev/null
@@ -0,0 +1,17 @@
+server {
+    server_name example.com www.example.com;
+
+    location / {
+        include proxy_params;
+        proxy_pass http://unix:/var/run/gunicorn/example.com.sock;
+    }
+
+    location = /favicon.ico {
+        access_log off;
+        log_not_found off;
+    }
+
+    location /static/ {
+        alias /var/www/example.com/staticfiles/;
+    }
+}
diff --git a/example.com.service b/example.com.service
new file mode 100644 (file)
index 0000000..aabf926
--- /dev/null
@@ -0,0 +1,15 @@
+[Unit]
+Description=example.com gunicorn daemon
+After=network.target
+
+[Service]
+User=www-data
+Group=www-data
+WorkingDirectory=/var/www/example.com/
+EnvironmentFile=/usr/local/etc/gunicorn/example.com.env
+StandardOutput=file:/var/log/gunicorn/example.com.log
+StandardError=file:/var/log/gunicorn/example.com.log
+ExecStart=gunicorn3 --access-logfile - --workers 3 --bind unix:/var/run/gunicorn/example.com.sock core.wsgi:application
+
+[Install]
+WantedBy=multi-user.target
diff --git a/generate_random_key.sh b/generate_random_key.sh
new file mode 100755 (executable)
index 0000000..8972eb7
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python3 -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
diff --git a/requirements.txt b/requirements.txt
new file mode 100644 (file)
index 0000000..f9144dd
--- /dev/null
@@ -0,0 +1,23 @@
+asgiref==3.6.0
+certifi==2022.12.7
+cffi==1.15.1
+charset-normalizer==3.0.1
+cryptography==39.0.0
+defusedxml==0.7.1
+dj-database-url==1.2.0
+Django==4.1.5
+django-allauth==0.52.0
+gunicorn==20.1.0
+idna==3.4
+oauthlib==3.2.2
+psycopg2==2.9.5
+pycparser==2.21
+PyJWT==2.6.0
+python-dotenv==0.21.0
+python3-openid==3.2.0
+pytz==2022.7.1
+requests==2.28.2
+requests-oauthlib==1.3.1
+sqlparse==0.4.3
+urllib3==1.26.14
+whitenoise==6.3.0