diff --git a/administration/migrations/0001_initial.py b/administration/migrations/0001_initial.py index e9366599d40d7e904ee324478b2256d478b5cfbb..de7061bb5b822b1bdb73537ed6f3ed02053028ff 100644 --- a/administration/migrations/0001_initial.py +++ b/administration/migrations/0001_initial.py @@ -1,9 +1,7 @@ -# Generated by Django 3.1 on 2020-10-30 15:29 +# Generated by Django 3.0.3 on 2020-05-08 14:42 -from django.conf import settings +import django.contrib.postgres.fields.jsonb from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone class Migration(migrations.Migration): @@ -11,40 +9,28 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('app', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ - migrations.CreateModel( - name='VerificationSetting', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=250)), - ('description', models.TextField(default='')), - ('archived', models.BooleanField(default=False)), - ('archived_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), - ], - ), migrations.CreateModel( name='VerificationReport', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('report', models.JSONField()), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('status', models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ('DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan'), ('BLOCKED', 'Diblokir')], default='PENDING', max_length=30)), - ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi')), - ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), + ('report', django.contrib.postgres.fields.jsonb.JSONField()), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('status', models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ( + 'DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan')], default='PENDING', max_length=30)), ], ), migrations.CreateModel( - name='DeletionHistory', + name='VerificationSetting', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('deleted_user_name', models.CharField(max_length=150)), - ('deleted_user_role', models.CharField(max_length=150)), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('deletor_admin', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=250)), + ('description', models.TextField(default='')), + ('archived', models.BooleanField(default=False)), ], ), ] diff --git a/administration/migrations/0002_verificationreport_materi.py b/administration/migrations/0002_verificationreport_materi.py new file mode 100644 index 0000000000000000000000000000000000000000..a1b8db8f58940d8965b879efd43c80f06b4bca72 --- /dev/null +++ b/administration/migrations/0002_verificationreport_materi.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2020-05-08 14:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('app', '0001_initial'), + ('administration', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='verificationreport', + name='materi', + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.Materi'), + ), + ] diff --git a/administration/migrations/0003_verificationreport_user.py b/administration/migrations/0003_verificationreport_user.py new file mode 100644 index 0000000000000000000000000000000000000000..236da3cd510b6203fbca8812fbcf4a33dc0da15c --- /dev/null +++ b/administration/migrations/0003_verificationreport_user.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.3 on 2020-05-08 14:42 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('administration', '0002_verificationreport_materi'), + ] + + operations = [ + migrations.AddField( + model_name='verificationreport', + name='user', + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/administration/migrations/0004_auto_20200517_1713.py b/administration/migrations/0004_auto_20200517_1713.py new file mode 100644 index 0000000000000000000000000000000000000000..8189cd965de7bc2ddf6453176ec3ec75c07fc7f9 --- /dev/null +++ b/administration/migrations/0004_auto_20200517_1713.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2020-05-17 10:13 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0003_verificationreport_user'), + ] + + operations = [ + migrations.AlterField( + model_name='verificationreport', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/administration/migrations/0005_deletionhistory.py b/administration/migrations/0005_deletionhistory.py new file mode 100644 index 0000000000000000000000000000000000000000..a23c37e1428e4b164cfbfa9b53a58b092cb63790 --- /dev/null +++ b/administration/migrations/0005_deletionhistory.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.3 on 2020-06-03 12:57 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('administration', '0004_auto_20200517_1713'), + ] + + operations = [ + migrations.CreateModel( + name='DeletionHistory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('deleted_user_name', models.CharField(max_length=150)), + ('deleted_user_role', models.CharField(max_length=150)), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('deletor_admin', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/administration/migrations/0005_verificationsetting_archived_by.py b/administration/migrations/0005_verificationsetting_archived_by.py new file mode 100644 index 0000000000000000000000000000000000000000..dadfd72ea51694f051a7730b60c37bf32210d354 --- /dev/null +++ b/administration/migrations/0005_verificationsetting_archived_by.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.3 on 2020-06-04 00:09 + +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), + ('administration', '0004_auto_20200517_1713'), + ] + + operations = [ + migrations.AddField( + model_name='verificationsetting', + name='archived_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/administration/migrations/0006_merge_20200604_0718.py b/administration/migrations/0006_merge_20200604_0718.py new file mode 100644 index 0000000000000000000000000000000000000000..92c7b037550593a95bfd8bdd25312fc5568f1bd3 --- /dev/null +++ b/administration/migrations/0006_merge_20200604_0718.py @@ -0,0 +1,14 @@ +# Generated by Django 3.0.3 on 2020-06-04 00:18 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0005_deletionhistory'), + ('administration', '0005_verificationsetting_archived_by'), + ] + + operations = [ + ] diff --git a/administration/migrations/0007_auto_20200929_1218.py b/administration/migrations/0007_auto_20200929_1218.py new file mode 100644 index 0000000000000000000000000000000000000000..735e71572df51f52e11ffe98a319fdceb3f46ba7 --- /dev/null +++ b/administration/migrations/0007_auto_20200929_1218.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-09-29 05:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0006_merge_20200604_0718'), + ] + + operations = [ + migrations.AlterField( + model_name='verificationreport', + name='report', + field=models.JSONField(), + ), + ] diff --git a/administration/migrations/0008_auto_20201009_1829.py b/administration/migrations/0008_auto_20201009_1829.py new file mode 100644 index 0000000000000000000000000000000000000000..0302d90c1ccf01e6a7a1b313ed4ce7ee95c79573 --- /dev/null +++ b/administration/migrations/0008_auto_20201009_1829.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-09 11:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administration', '0007_auto_20200929_1218'), + ] + + operations = [ + migrations.AlterField( + model_name='verificationreport', + name='status', + field=models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ('DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan'), ('BLOCKED', 'Diblokir')], default='PENDING', max_length=30), + ), + ] diff --git a/app/migrations/0001_initial.py b/app/migrations/0001_initial.py index 2e76e78466a5b35f01834a00102bee3798f0b177..51a62f576bc233af8f04a305c6be41ee5073e1fe 100644 --- a/app/migrations/0001_initial.py +++ b/app/migrations/0001_initial.py @@ -1,12 +1,6 @@ -# Generated by Django 3.1 on 2020-10-30 15:28 +# Generated by Django 3.0.3 on 2020-05-08 14:42 -import app.models -from django.conf import settings -import django.contrib.postgres.search -import django.core.validators from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone class Migration(migrations.Migration): @@ -14,215 +8,44 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Category', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=20)), - ('description', models.TextField(default='')), - ('archived', models.BooleanField(default=False)), - ('archived_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('description', models.CharField(max_length=20)), ], ), migrations.CreateModel( name='Comment', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), ('username', models.CharField(max_length=100)), - ('profile', models.CharField(default=app.models.getRandomColor, max_length=100)), - ('comment', models.CharField(default='comments', max_length=240)), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ], - ), - migrations.CreateModel( - name='DownloadStatistics', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('downloader', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='riwayat_unduh', to=settings.AUTH_USER_MODEL)), + ('profile', models.CharField(default='56acdf', max_length=100)), + ('comment', models.CharField(default='comments', max_length=150)), ], ), migrations.CreateModel( name='Materi', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('deleted_at', models.DateTimeField(blank=True, null=True)), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), ('cover', models.ImageField(upload_to='')), ('content', models.FileField(upload_to='')), - ('title', models.CharField(default='Judul', max_length=50)), - ('author', models.CharField(default='Penyusun', max_length=30)), - ('publisher', models.CharField(default='Penerbit', max_length=30)), - ('release_year', models.IntegerField(default=app.models.current_year)), + ('title', models.CharField(default='title', max_length=50)), + ('author', models.CharField(default='author', max_length=30)), + ('publisher', models.CharField(default='publiser', max_length=30)), ('pages', models.IntegerField(default=0)), - ('descriptions', models.TextField(default='Deskripsi')), - ('status', models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ('DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan'), ('BLOCKED', 'Diblokir')], default='PENDING', max_length=30)), - ('date_created', models.DateTimeField(default=django.utils.timezone.now)), - ('date_modified', models.DateTimeField(auto_now=True)), - ('yt_video_id', models.CharField(blank=True, max_length=100, null=True)), - ('_search_vector', django.contrib.postgres.search.SearchVectorField(editable=False, null=True)), + ('descriptions', models.TextField(default='descriptions')), + ('status', models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ( + 'DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan')], default='PENDING', max_length=30)), + ('date_added', models.DateTimeField(auto_now_add=True)), ('categories', models.ManyToManyField(to='app.Category')), - ('uploader', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='ReqMaterial', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=100)), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ], - ), - migrations.CreateModel( - name='SubmitVisitor', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('user_id', models.CharField(max_length=50)), - ('email', models.CharField(max_length=50)), - ('msg', models.CharField(max_length=100)), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ], - ), - migrations.CreateModel( - name='SubscribeModel', - fields=[ - ('sys_id', models.AutoField(primary_key=True, serialize=False)), - ('email', models.EmailField(blank=True, max_length=200, unique=True)), - ('status', models.CharField(blank=True, max_length=64)), - ('created_date', models.DateTimeField(blank=True)), - ('updated_date', models.DateTimeField(blank=True)), - ], - options={ - 'db_table': 'app_subscribe', - }, - ), - migrations.CreateModel( - name='ViewStatistics', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='baca', to='app.materi')), - ], - ), - migrations.CreateModel( - name='Review', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('username', models.CharField(max_length=100)), - ('profile', models.CharField(default=app.models.getRandomColor, max_length=100)), - ('review', models.TextField(default='review')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi')), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='RatingContributor', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(auto_now=True)), - ('score', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)])), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='LikeComment', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('session_id', models.CharField(max_length=32)), - ('comment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.comment')), - ], - ), - migrations.CreateModel( - name='Like', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('session_id', models.CharField(max_length=32)), - ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi')), - ], - ), - migrations.CreateModel( - name='LaporanMateri', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('laporan', models.TextField(default='', validators=[django.core.validators.MinValueValidator(30), django.core.validators.MaxValueValidator(120)])), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('is_rejected', models.BooleanField(default=False)), - ('materi', models.ForeignKey(max_length=120, on_delete=django.db.models.deletion.CASCADE, to='app.materi')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='DummyViewStatistics', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.viewstatistics')), - ], - ), - migrations.CreateModel( - name='DummyLike', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.like')), - ], - ), - migrations.CreateModel( - name='DummyDownloadStatistics', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.downloadstatistics')), - ], - ), - migrations.CreateModel( - name='DummyComment', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.comment')), - ], - ), - migrations.AddField( - model_name='downloadstatistics', - name='materi', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='unduh', to='app.materi'), - ), - migrations.CreateModel( - name='DislikeComment', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('session_id', models.CharField(max_length=32)), - ('comment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.comment')), - ], - ), - migrations.AddField( - model_name='comment', - name='materi', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi'), - ), - migrations.AddField( - model_name='comment', - name='user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), - ), - migrations.CreateModel( - name='Rating', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('score', models.IntegerField()), - ('materi', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.materi')), - ('user', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], - options={ - 'unique_together': {('materi', 'user')}, - }, ), ] diff --git a/app/migrations/0002_auto_20200508_2142.py b/app/migrations/0002_auto_20200508_2142.py new file mode 100644 index 0000000000000000000000000000000000000000..dfeeb8495f7ea4ab0e77001b5dec910341522e0e --- /dev/null +++ b/app/migrations/0002_auto_20200508_2142.py @@ -0,0 +1,36 @@ +# Generated by Django 3.0.3 on 2020-05-08 14:42 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='materi', + name='uploader', + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='comment', + name='materi', + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.Materi'), + ), + migrations.AddField( + model_name='comment', + name='user', + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0003_auto_20200509_2108.py b/app/migrations/0003_auto_20200509_2108.py new file mode 100644 index 0000000000000000000000000000000000000000..844d9d85ad27f5f5b3102597c4e8e8ef6173f8fd --- /dev/null +++ b/app/migrations/0003_auto_20200509_2108.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2020-05-09 14:08 + +import app.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0002_auto_20200508_2142'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='profile', + field=models.CharField(default=app.models.getRandomColor, max_length=100), + ), + ] diff --git a/app/migrations/0004_like.py b/app/migrations/0004_like.py new file mode 100644 index 0000000000000000000000000000000000000000..7240ea7ac31c62b66b4ef2cdcd9790b2f6d2e143 --- /dev/null +++ b/app/migrations/0004_like.py @@ -0,0 +1,22 @@ +# Generated by Django 3.0.3 on 2020-05-12 08:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0003_auto_20200509_2108'), + ] + + operations = [ + migrations.CreateModel( + name='Like', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.Materi')), + ], + ), + ] diff --git a/app/migrations/0005_like_session_id.py b/app/migrations/0005_like_session_id.py new file mode 100644 index 0000000000000000000000000000000000000000..8520a4d3769e9bf68d9ed2fad52454391df55777 --- /dev/null +++ b/app/migrations/0005_like_session_id.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2020-05-12 09:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0004_like'), + ] + + operations = [ + migrations.AddField( + model_name='like', + name='session_id', + field=models.CharField(default='', max_length=32), + preserve_default=False, + ), + ] diff --git a/app/migrations/0006_downloadstatistics_viewstatistics.py b/app/migrations/0006_downloadstatistics_viewstatistics.py new file mode 100644 index 0000000000000000000000000000000000000000..2b29fb125a53831e97d5888d6d878894dcd580d3 --- /dev/null +++ b/app/migrations/0006_downloadstatistics_viewstatistics.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.3 on 2020-05-13 10:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0005_like_session_id'), + ] + + operations = [ + migrations.CreateModel( + name='ViewStatistics', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='baca', to='app.Materi')), + ], + ), + migrations.CreateModel( + name='DownloadStatistics', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='unduh', to='app.Materi')), + ], + ), + ] diff --git a/app/migrations/0007_auto_20200516_1743.py b/app/migrations/0007_auto_20200516_1743.py new file mode 100644 index 0000000000000000000000000000000000000000..5a0973432393117a5aa0435217f0244c49a9cfe3 --- /dev/null +++ b/app/migrations/0007_auto_20200516_1743.py @@ -0,0 +1,43 @@ +# Generated by Django 3.0.3 on 2020-05-16 10:43 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0006_downloadstatistics_viewstatistics'), + ] + + operations = [ + migrations.RemoveField( + model_name='materi', + name='date_added', + ), + migrations.AddField( + model_name='materi', + name='date_created', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AddField( + model_name='materi', + name='date_modified', + field=models.DateTimeField(auto_now=True), + ), + migrations.AlterField( + model_name='downloadstatistics', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='like', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='viewstatistics', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/app/migrations/0008_auto_20200518_1919.py b/app/migrations/0008_auto_20200518_1919.py new file mode 100644 index 0000000000000000000000000000000000000000..df20b16663a25a3d064ff3f30b01012f1ecf150c --- /dev/null +++ b/app/migrations/0008_auto_20200518_1919.py @@ -0,0 +1,48 @@ +# Generated by Django 3.0.3 on 2020-05-18 12:19 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0007_auto_20200516_1743'), + ] + + operations = [ + migrations.AddField( + model_name='comment', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.CreateModel( + name='DummyViewStatistics', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.ViewStatistics')), + ], + ), + migrations.CreateModel( + name='DummyLike', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Like')), + ], + ), + migrations.CreateModel( + name='DummyDownloadStatistics', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.DownloadStatistics')), + ], + ), + migrations.CreateModel( + name='DummyComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Comment')), + ], + ), + ] diff --git a/app/migrations/0009_auto_20200518_2245.py b/app/migrations/0009_auto_20200518_2245.py new file mode 100644 index 0000000000000000000000000000000000000000..68785da21a33971eced0e5cf01c37c9e350a56d9 --- /dev/null +++ b/app/migrations/0009_auto_20200518_2245.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2020-05-18 15:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0008_auto_20200518_1919'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='comment', + field=models.CharField(default='comments', max_length=240), + ), + ] diff --git a/app/migrations/0010_category_archived.py b/app/migrations/0010_category_archived.py new file mode 100644 index 0000000000000000000000000000000000000000..a864e59965a382bdc242de2970ab9cc7b76de822 --- /dev/null +++ b/app/migrations/0010_category_archived.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2020-06-03 06:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0009_auto_20200518_2245'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='archived', + field=models.BooleanField(default=False), + ), + ] diff --git a/app/migrations/0011_auto_20200603_1350.py b/app/migrations/0011_auto_20200603_1350.py new file mode 100644 index 0000000000000000000000000000000000000000..14c08847378c0a4a310c77303a176bd5182ba90b --- /dev/null +++ b/app/migrations/0011_auto_20200603_1350.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2020-06-03 06:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0010_category_archived'), + ] + + operations = [ + migrations.AlterField( + model_name='category', + name='description', + field=models.TextField(default=''), + ), + ] diff --git a/app/migrations/0012_category_archived_by.py b/app/migrations/0012_category_archived_by.py new file mode 100644 index 0000000000000000000000000000000000000000..9919bf0538e111bef9794eeb7ab32517e3cb65e7 --- /dev/null +++ b/app/migrations/0012_category_archived_by.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.3 on 2020-06-04 00:09 + +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), + ('app', '0011_auto_20200603_1350'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='archived_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0013_auto_20200919_2055.py b/app/migrations/0013_auto_20200919_2055.py new file mode 100644 index 0000000000000000000000000000000000000000..7b7993c96f79f86abbf68a24f2c520e98ad3882a --- /dev/null +++ b/app/migrations/0013_auto_20200919_2055.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.3 on 2020-09-19 13:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0012_category_archived_by'), + ] + + operations = [ + migrations.AlterField( + model_name='materi', + name='author', + field=models.CharField(default='Penyusun', max_length=30), + ), + migrations.AlterField( + model_name='materi', + name='descriptions', + field=models.TextField(default='Deskripsi'), + ), + migrations.AlterField( + model_name='materi', + name='publisher', + field=models.CharField(default='Penerbit', max_length=30), + ), + migrations.AlterField( + model_name='materi', + name='title', + field=models.CharField(default='Judul', max_length=50), + ), + ] diff --git a/app/migrations/0014_rating.py b/app/migrations/0014_rating.py new file mode 100644 index 0000000000000000000000000000000000000000..69ae6aa1e7dcd3345443a22672118f591ef8e680 --- /dev/null +++ b/app/migrations/0014_rating.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.3 on 2020-09-29 11:30 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0013_auto_20200919_2055'), + ] + + operations = [ + migrations.CreateModel( + name='Rating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('score', models.IntegerField()), + ('materi', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Materi')), + ('user', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('materi', 'user')}, + }, + ), + ] diff --git a/app/migrations/0015_downloadstatistics_downloader.py b/app/migrations/0015_downloadstatistics_downloader.py new file mode 100644 index 0000000000000000000000000000000000000000..16780d0c070064f852acf2e180dfcb1ba5179afc --- /dev/null +++ b/app/migrations/0015_downloadstatistics_downloader.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.4 on 2020-09-30 04:50 + +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), + ('app', '0014_rating'), + ] + + operations = [ + migrations.AddField( + model_name='downloadstatistics', + name='downloader', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='riwayat_unduh', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0015_reqmaterial.py b/app/migrations/0015_reqmaterial.py new file mode 100644 index 0000000000000000000000000000000000000000..197e5a18d1dbb8cc0daf3436660d9667ee421939 --- /dev/null +++ b/app/migrations/0015_reqmaterial.py @@ -0,0 +1,22 @@ +# Generated by Django 3.0.3 on 2020-10-01 04:23 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0014_rating'), + ] + + operations = [ + migrations.CreateModel( + name='ReqMaterial', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=100)), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ], + ), + ] diff --git a/app/migrations/0016_ratingcontributor.py b/app/migrations/0016_ratingcontributor.py new file mode 100644 index 0000000000000000000000000000000000000000..86d787f0b6a357456c259f9842dfd7e3b7e49415 --- /dev/null +++ b/app/migrations/0016_ratingcontributor.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.1 on 2020-10-05 14:41 + +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), + ('app', '0015_reqmaterial'), + ] + + operations = [ + migrations.CreateModel( + name='RatingContributor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now=True)), + ('score', models.IntegerField()), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/app/migrations/0017_auto_20201005_2145.py b/app/migrations/0017_auto_20201005_2145.py new file mode 100644 index 0000000000000000000000000000000000000000..732caef72a1b44acef70e15c4d29b91a5df106b2 --- /dev/null +++ b/app/migrations/0017_auto_20201005_2145.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.1 on 2020-10-05 14:45 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0016_ratingcontributor'), + ] + + operations = [ + migrations.AlterField( + model_name='ratingcontributor', + name='score', + field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)]), + ), + ] diff --git a/app/migrations/0018_merge_20201009_0700.py b/app/migrations/0018_merge_20201009_0700.py new file mode 100644 index 0000000000000000000000000000000000000000..2e5d56480fa1f304956819f4012e5e52c2100d5e --- /dev/null +++ b/app/migrations/0018_merge_20201009_0700.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1 on 2020-10-09 00:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0017_auto_20201005_2145'), + ('app', '0015_downloadstatistics_downloader'), + ] + + operations = [ + ] diff --git a/app/migrations/0019_auto_20201009_1829.py b/app/migrations/0019_auto_20201009_1829.py new file mode 100644 index 0000000000000000000000000000000000000000..15bec11ed71a0b3062e68aeceda2e7434ec804e8 --- /dev/null +++ b/app/migrations/0019_auto_20201009_1829.py @@ -0,0 +1,34 @@ +# Generated by Django 3.1 on 2020-10-09 11:29 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0018_merge_20201009_0700'), + ] + + operations = [ + migrations.AlterField( + model_name='materi', + name='status', + field=models.CharField(choices=[('PENDING', 'Diproses'), ('APPROVE', 'Diterima'), ('DISAPPROVE', 'Ditolak'), ('REVISION', 'Perbaikan'), ('BLOCKED', 'Diblokir')], default='PENDING', max_length=30), + ), + migrations.CreateModel( + name='LaporanMateri', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('laporan', models.TextField(default='', validators=[django.core.validators.MinValueValidator(30), django.core.validators.MaxValueValidator(120)])), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('is_rejected', models.BooleanField(default=False)), + ('materi', models.ForeignKey(max_length=120, on_delete=django.db.models.deletion.CASCADE, to='app.materi')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/app/migrations/0019_materi__search_vector.py b/app/migrations/0019_materi__search_vector.py new file mode 100644 index 0000000000000000000000000000000000000000..bd148040bd07b733963274efadcb1ad9995396c7 --- /dev/null +++ b/app/migrations/0019_materi__search_vector.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1 on 2020-10-09 11:19 + +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0018_merge_20201009_0700'), + ] + + operations = [ + migrations.AddField( + model_name='materi', + name='_search_vector', + field=django.contrib.postgres.search.SearchVectorField(editable=False, null=True), + ), + ] diff --git a/app/migrations/0019_materi_yt_video_id.py b/app/migrations/0019_materi_yt_video_id.py new file mode 100644 index 0000000000000000000000000000000000000000..df8dc1afeba6a410f437c1ce8c29de0e0c947346 --- /dev/null +++ b/app/migrations/0019_materi_yt_video_id.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-09 13:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0018_merge_20201009_0700'), + ] + + operations = [ + migrations.AddField( + model_name='materi', + name='yt_video_id', + field=models.CharField(blank=True, max_length=100, null=True), + ), + ] diff --git a/app/migrations/0020_merge_20201009_2039.py b/app/migrations/0020_merge_20201009_2039.py new file mode 100644 index 0000000000000000000000000000000000000000..80867b028075f48fb2cd1b5838561fe9b20aa4cc --- /dev/null +++ b/app/migrations/0020_merge_20201009_2039.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1 on 2020-10-09 13:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0019_materi__search_vector'), + ('app', '0019_auto_20201009_1829'), + ] + + operations = [ + ] diff --git a/app/migrations/0021_dislikecomment_likecomment.py b/app/migrations/0021_dislikecomment_likecomment.py new file mode 100644 index 0000000000000000000000000000000000000000..1ce9111268da53f8e2a88fdf877c4250fb354695 --- /dev/null +++ b/app/migrations/0021_dislikecomment_likecomment.py @@ -0,0 +1,33 @@ +# Generated by Django 3.1 on 2020-10-09 16:19 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0020_merge_20201009_2039'), + ] + + operations = [ + migrations.CreateModel( + name='LikeComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('session_id', models.CharField(max_length=32)), + ('comment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.comment')), + ], + ), + migrations.CreateModel( + name='DislikeComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('session_id', models.CharField(max_length=32)), + ('comment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.comment')), + ], + ), + ] diff --git a/app/migrations/0021_materi_release_year.py b/app/migrations/0021_materi_release_year.py new file mode 100644 index 0000000000000000000000000000000000000000..8294e44629dc026ddff721b329e610946de3a7d5 --- /dev/null +++ b/app/migrations/0021_materi_release_year.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1 on 2020-10-09 16:13 + +import app.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0020_merge_20201009_2039'), + ] + + operations = [ + migrations.AddField( + model_name='materi', + name='release_year', + field=models.IntegerField(default=app.models.current_year), + ), + ] diff --git a/app/migrations/0022_merge_20201011_1122.py b/app/migrations/0022_merge_20201011_1122.py new file mode 100644 index 0000000000000000000000000000000000000000..4b0d5ebf263822713c41cced80792494eb749a21 --- /dev/null +++ b/app/migrations/0022_merge_20201011_1122.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1 on 2020-10-11 04:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0021_dislikecomment_likecomment'), + ('app', '0021_materi_release_year'), + ] + + operations = [ + ] diff --git a/app/migrations/0023_materi_deleted_at.py b/app/migrations/0023_materi_deleted_at.py new file mode 100644 index 0000000000000000000000000000000000000000..2a695fcfe8cfa105ee5b2b04ba7b163460267b26 --- /dev/null +++ b/app/migrations/0023_materi_deleted_at.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-23 03:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0022_merge_20201011_1122'), + ] + + operations = [ + migrations.AddField( + model_name='materi', + name='deleted_at', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/app/migrations/0023_merge_20201016_1713.py b/app/migrations/0023_merge_20201016_1713.py new file mode 100644 index 0000000000000000000000000000000000000000..ecb8c7929320e2599b38912d405bce12532e23a5 --- /dev/null +++ b/app/migrations/0023_merge_20201016_1713.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1 on 2020-10-16 10:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0022_merge_20201011_1122'), + ('app', '0019_materi_yt_video_id'), + ] + + operations = [ + ] diff --git a/app/migrations/0024_merge_20201026_0812.py b/app/migrations/0024_merge_20201026_0812.py new file mode 100644 index 0000000000000000000000000000000000000000..adc2f2f6bb36bb959b15608d753516fed53bf5df --- /dev/null +++ b/app/migrations/0024_merge_20201026_0812.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1 on 2020-10-26 01:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0023_merge_20201016_1713'), + ('app', '0023_materi_deleted_at'), + ] + + operations = [ + ] diff --git a/app/migrations/0025_review.py b/app/migrations/0025_review.py new file mode 100644 index 0000000000000000000000000000000000000000..79b7b89a4f655cf6851c7265539222047eef56e1 --- /dev/null +++ b/app/migrations/0025_review.py @@ -0,0 +1,30 @@ +# Generated by Django 3.1 on 2020-10-29 11:22 + +import app.models +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0024_merge_20201026_0812'), + ] + + operations = [ + migrations.CreateModel( + name='Review', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('username', models.CharField(max_length=100)), + ('profile', models.CharField(default=app.models.getRandomColor, max_length=100)), + ('review', models.TextField(default='review')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/app/migrations/0026_submitvisitor.py b/app/migrations/0026_submitvisitor.py new file mode 100644 index 0000000000000000000000000000000000000000..b8497c75b257983dd84ea6b3cbc8b5228f6cd29d --- /dev/null +++ b/app/migrations/0026_submitvisitor.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1 on 2020-10-29 13:45 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0025_review'), + ] + + operations = [ + migrations.CreateModel( + name='SubmitVisitor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_id', models.CharField(max_length=50)), + ('email', models.CharField(max_length=50)), + ('msg', models.CharField(max_length=100)), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ], + ), + ] diff --git a/app/models.py b/app/models.py index 661cde6be8d78d8b5d785ab31b34c8764c7ecd18..e531ad121c188ab50d73c93dfbedd3eafb464389 100644 --- a/app/models.py +++ b/app/models.py @@ -47,7 +47,7 @@ class MateriManager(models.Manager): if self.alive_only: return SoftDeletionQuerySet(self.model).filter(deleted_at=None) return SoftDeletionQuerySet(self.model) - + def search(self, search_text): search_vector = search.SearchVector("title", weight="A") search_query = search.SearchQuery(search_text) @@ -68,10 +68,10 @@ class SoftDeleteModel(models.Model): deleted_at = models.DateTimeField(blank=True, null=True) all_objects = MateriManager(alive_only=False) - + class Meta: abstract = True - + def soft_delete(self): self.deleted_at = timezone.now() self.save() @@ -85,7 +85,7 @@ class Materi(SoftDeleteModel): publisher = models.CharField(max_length=30, default="Penerbit") release_year = models.IntegerField(default=current_year) pages = models.IntegerField(default=0) - descriptions = models.TextField(default="Deskripsi") + descriptions = models.TextField(default="Deskripsi") status = models.CharField(max_length=30, choices=VERIFICATION_STATUS, default=VERIFICATION_STATUS[0][0]) categories = models.ManyToManyField(Category) date_created = models.DateTimeField(default=timezone.now) @@ -124,7 +124,7 @@ class Materi(SoftDeleteModel): def like_count(self): count = Like.objects.filter(materi=self).count() return count - + @property def comment_count(self): count = Comment.objects.filter(materi=self).count() @@ -157,7 +157,7 @@ class Comment(models.Model): def like_count(self): count = LikeComment.objects.filter(comment=self).count() return count - + @property def dislike_count(self): count = DislikeComment.objects.filter(comment=self).count() @@ -265,19 +265,6 @@ class RatingContributor(models.Model): class Meta: unique_together = ["contributor", "user"] -class SubscribeModel(models.Model): - sys_id = models.AutoField(primary_key=True, null=False, blank=True) - email = models.EmailField(null=False, blank=True, max_length=200, unique=True) - status = models.CharField(max_length=64, null=False, blank=True) - created_date = models.DateTimeField(null=False, blank=True) - updated_date = models.DateTimeField(null=False, blank=True) - - class Meta: - app_label = "app" - db_table = "app_subscribe" - - def __str__(self): - return self.email class LaporanMateri(models.Model): materi = models.ForeignKey(Materi, on_delete=models.CASCADE, max_length=120) diff --git a/app/static/images/sub-btn.png b/app/static/images/sub-btn.png deleted file mode 100644 index 81b0489c7c988c9769980e0bca8698a24cc3851d..0000000000000000000000000000000000000000 Binary files a/app/static/images/sub-btn.png and /dev/null differ diff --git a/app/templates/app/emails/subscription.html b/app/templates/app/emails/subscription.html deleted file mode 100644 index 6a83c2d0a33ee439882c3b3008ce091db597ee62..0000000000000000000000000000000000000000 --- a/app/templates/app/emails/subscription.html +++ /dev/null @@ -1,20 +0,0 @@ -<div style="padding: 20px; background: #fafafa;font-size:15px;"> - Hi<br> - Thanks for subscribing to {{ project_name }} newsletter.<br> - We will be sending you latest published articles on <a href="{{ site_url }}">{{ site_url }}</a>. Mail frequency won't be more than twice a month.<br> - We hate spamming as much as you do.<br> - <br> - To confirm your subscription, please click on the link given below. If clicking doesn't work, copy paste the URL in browser.<br> - If you think this is a mistake, just ignore this email and we won't bother you again. - <br> - <br> - <a href="{{ confirmation_url }}">{{ confirmation_url }}</a> - - <br> - <br> - <p> - Note:<br> - This is notification only email. Please do not reply on this email.<br> - You can <a href="{{ contact_us_url }}">contact us here</a>. - </p> -</div> \ No newline at end of file diff --git a/app/templates/app/katalog_materi.html b/app/templates/app/katalog_materi.html index 93c719b560ad93d582913d20205b0d125f799565..224232c1a609e82a1004dd0183bd6ac83059cd48 100644 --- a/app/templates/app/katalog_materi.html +++ b/app/templates/app/katalog_materi.html @@ -48,7 +48,7 @@ </head> <body style="background-color: #f8f8f8;"> - + <!-- Page Content --> <div class="container"> @@ -76,14 +76,14 @@ </div> </div> </header> - + <a href="/download-history/" class="btn-history">Riwayat Unduh</a><br><br> <div id="container-materi-ordering"> <a href="?random=1" class="btn-materi-ordering">Acak Materi</a><br><br> <a href="?recommendation=1" class="btn-materi-ordering">Rekomendasi</a><br><br> </div> - + <div class="container"> <div class="row content"> <div class="col-3 sidebar"> @@ -209,4 +209,4 @@ </html> -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/app/templates/subscribe.html b/app/templates/subscribe.html deleted file mode 100644 index 566776b36cbc0b63a6e9c57cd980f7a8220b6cec..0000000000000000000000000000000000000000 --- a/app/templates/subscribe.html +++ /dev/null @@ -1,12 +0,0 @@ -<div style="border: 1px solid darkgreen; border-radius: 2px; padding:10px; text-align: center;"> - <div><strong>SUBSCRIBE</strong></div> - <div style="margin-bottom: 10px;">Please subscribe to get the latest articles in your mailbox.</div> - <div> - <form action="{% url 'subscribe' %}" method="post" class="form-horizontal"> - {% csrf_token %} - <input type="email" name="email" class="form-control" placeholder="Your Email ID Please" required> - <br> - <input type="submit" value="Subscribe" class="btn btn-primary btn-sm"> - </form> - </div> -</div> \ No newline at end of file diff --git a/app/tests.py b/app/tests.py index 2a0a6e069a9d9297915b0907ee1b1b932c5b6e6a..9f10c73f27f528bd814fb834b1084391f60514d9 100644 --- a/app/tests.py +++ b/app/tests.py @@ -67,9 +67,6 @@ from .views import ( ) from app.forms import SuntingProfilForm, year_choices from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata -import pandas as pd -from django.core import mail -from app.utils.email_utility import send_gmail from app.utils.PasswordValidator import PasswordPolicyValidator ERROR_403_MESSAGE = "Kamu harus login untuk mengakses halaman ini" @@ -229,7 +226,7 @@ class DaftarKatalogSortingByJumlahTampilanTest(TestCase): self.client.get(self.url) response = self.client.get("/?sort=jumlah_tampilan") self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*') - + class DaftarKatalogPerKontributorTest(TestCase): def setUp(self): self.client = Client() @@ -325,13 +322,13 @@ class DetailMateriTest(TestCase): "ExampleCover921.jpg", b"Test file") self.content = SimpleUploadedFile("ExampleFile921.pdf", b"Test file") - self.materi1 = Materi.objects.create(title="Materi 1", author="Agas", - uploader=self.contributor, publisher="Kelas SC", - descriptions="Deskripsi Materi 1", status="APPROVE", + self.materi1 = Materi.objects.create(title="Materi 1", author="Agas", + uploader=self.contributor, publisher="Kelas SC", + descriptions="Deskripsi Materi 1", status="APPROVE", cover=self.cover, content=self.content) - self.materi2 = Materi.objects.create(title="Materi 2", author="Agad", - uploader=self.contributor, publisher="Kelas SM", - descriptions="Deskripsi Materi 2", status="APPROVE", + self.materi2 = Materi.objects.create(title="Materi 2", author="Agad", + uploader=self.contributor, publisher="Kelas SM", + descriptions="Deskripsi Materi 2", status="APPROVE", cover=self.cover, content=self.content) self.url = "/materi/" + str(self.materi1.id) + "/" self.download_url1 = self.url + "unduh" @@ -459,10 +456,10 @@ class DetailMateriTest(TestCase): comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] - + payload = {"comment": comment, "session_id": session_id} self.client.post("/comment/dislike/", payload) - + self.client.post("/comment/dislike/", payload) num_of_comment_dislikes = DislikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_dislikes, 0) @@ -476,10 +473,10 @@ class DetailMateriTest(TestCase): comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] - + payload = {"comment": comment, "session_id": session_id} self.client.post("/comment/like/", payload) - + self.client.post("/comment/like/", payload) num_of_comment_likes = LikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_likes, 0) @@ -519,9 +516,9 @@ class DetailMateriTest(TestCase): is_subscribing_to_material_comments=True ) - material = Materi.objects.create(title="Materi-subscribed", author="Tester", - uploader=contributor_subscribed, publisher="Kelas PMPL", - descriptions="Deskripsi Materi subscribed", status="APPROVE", + material = Materi.objects.create(title="Materi-subscribed", author="Tester", + uploader=contributor_subscribed, publisher="Kelas PMPL", + descriptions="Deskripsi Materi subscribed", status="APPROVE", cover=self.cover, content=self.content) url = "/materi/" + str(material.id) + "/" self.client.login(**self.contributor_credential) # comment with other user @@ -546,9 +543,9 @@ class DetailMateriTest(TestCase): is_subscribing_to_material_comments=False ) - material = Materi.objects.create(title="Materi-not-subscribed", author="Tester", - uploader=contributor_not_subscribed, publisher="Kelas PMPL", - descriptions="Deskripsi Materi non-subscribed", status="APPROVE", + material = Materi.objects.create(title="Materi-not-subscribed", author="Tester", + uploader=contributor_not_subscribed, publisher="Kelas PMPL", + descriptions="Deskripsi Materi non-subscribed", status="APPROVE", cover=self.cover, content=self.content) url = "/materi/" + str(material.id) + "/" self.client.login(**self.contributor_credential) # comment with other user @@ -576,9 +573,9 @@ class DetailMateriTest(TestCase): is_subscribing_to_material_comments=True ) - material = Materi.objects.create(title="Materi-subscribed", author="Tester", - uploader=contributor_subscribed, publisher="Kelas PMPL", - descriptions="Deskripsi Materi subscribed", status="APPROVE", + material = Materi.objects.create(title="Materi-subscribed", author="Tester", + uploader=contributor_subscribed, publisher="Kelas PMPL", + descriptions="Deskripsi Materi subscribed", status="APPROVE", cover=self.cover, content=self.content) url = "/materi/" + str(material.id) + "/" self.client.login(**contributor_subscribed_credentials) # comment with the same user @@ -656,7 +653,7 @@ class DetailMateriTest(TestCase): count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 1) - + def test_review_models_can_create_new_object(self): test = Review.objects.create( username="saul", profile="121212", review="232323") @@ -703,7 +700,7 @@ class DetailMateriTest(TestCase): self.client.post(url, {"review": "This is new review by Anonymous"}) response = self.client.get(url) self.assertContains(response, "Anonymous") - + def test_detail_materi_contains_review_count(self): url = self.url self.client.login(**self.contributor_credential) @@ -734,25 +731,25 @@ class DetailMateriTest(TestCase): def test_hasil_citasi_APA_materi_has_no_published_date(self): response = self.client.get(self.url) - expected = self.materi1.author + " . (n.d) . " + self.materi1.title + " . " + self.materi1.publisher + expected = self.materi1.author + " . (n.d) . " + self.materi1.title + " . " + self.materi1.publisher self.assertIn(expected, response.context["citationAPA"]) self.assertIn(expected, response.context["citationAPA"]) def test_hasil_citasi_APA_materi_has_published_date(self): response = self.client.get(self.materi_with_published_date_url) - published_date = self.materi_with_published_date.published_date.strftime("%Y-%m-%d %H:%M") - expected = ( - self.materi_with_published_date.author - + " . (" - + published_date - + ") . " - + self.materi_with_published_date.title - + " . " - + self.materi_with_published_date.publisher - ) + published_date = self.materi_with_published_date.published_date.strftime("%Y-%m-%d %H:%M") + expected = ( + self.materi_with_published_date.author + + " . (" + + published_date + + ") . " + + self.materi_with_published_date.title + + " . " + + self.materi_with_published_date.publisher + ) self.assertIn(expected, response.context["citationAPA"]) - + def test_citation_IEEE_button(self): response = self.client.get(self.url) self.assertContains(response, "Citate IEEE") @@ -764,19 +761,19 @@ class DetailMateriTest(TestCase): current_month = current_date.strftime("%b") current_year = str(current_date.year) - expected = ( - "Agas, " - + "Materi 1. " - + "Kelas SC, n.d. " - + "Accessed on: " - + current_month - + ". " - + current_day - + ", " - + current_year - + ". [Online]. " - + "Available: http://testserver" - + self.url + expected = ( + "Agas, " + + "Materi 1. " + + "Kelas SC, n.d. " + + "Accessed on: " + + current_month + + ". " + + current_day + + ", " + + current_year + + ". [Online]. " + + "Available: http://testserver" + + self.url ) self.assertIn(expected, response.context["citationIEEE"]) @@ -859,7 +856,7 @@ class DetailMateriTest(TestCase): self.assertNotEqual(context1['materi_download_count'], context2['materi_download_count']) self.assertEqual(context1['materi_download_count'], 3) self.assertEqual(context2['materi_download_count'], 2) - + def test_download_count_displayed_on_template_when_no_download(self): response = self.client.get(self.url) html = response.content.decode("utf-8") @@ -904,12 +901,12 @@ class DetailMateriTest(TestCase): self.check_materi_info_not_in_html(self.dcount_info_name, dcount_materi2, html) self.check_materi_info_in_html(self.dcount_info_name, dcount_materi2, html2) self.check_materi_info_not_in_html(self.dcount_info_name, dcount_materi1, html2) - + def test_like_count_displayed_on_template_when_no_like(self): response = self.client.get(self.url) html = response.content.decode("utf-8") self.check_materi_info_in_html(self.lcount_info_name, 0, html) - + def test_like_count_displayed_on_template_when_single_like(self): payload = { 'materi_id': self.materi1.id, @@ -919,8 +916,8 @@ class DetailMateriTest(TestCase): response = self.client.get(self.url) html = response.content.decode("utf-8") - self.check_materi_info_in_html(self.lcount_info_name, 1, html) - + self.check_materi_info_in_html(self.lcount_info_name, 1, html) + def test_like_count_displayed_on_template_when_multiple_like(self): payload1 = { 'materi_id': self.materi1.id, @@ -932,17 +929,17 @@ class DetailMateriTest(TestCase): } self.client.post(self.like_url, payload1) self.client.post(self.like_url, payload2) - + response = self.client.get(self.url) html = response.content.decode("utf-8") self.check_materi_info_in_html(self.lcount_info_name, 2, html) - + def test_like_count_displayed_on_template_when_unlike(self): payload = { 'materi_id': self.materi1.id, 'session_id': "dummysession" } - + # Like materi once self.client.post(self.like_url, payload) response = self.client.get(self.url) @@ -984,11 +981,11 @@ class PostsViewTest(TestCase): for j in range (LIKES_COUNT_PER_POST[i]): Like.objects.create( - timestamp=datetime.now(), - materi=post, + timestamp=datetime.now(), + materi=post, session_id=("dummysession-" + str(i) + '-' + str(j)) ) - + for i, post_id in enumerate(post_comment_group_dict): post = post_comment_group_dict[post_id]["data"] @@ -1130,13 +1127,13 @@ class UploadPageTest(TestCase): response = Client().get("/fake/") self.assertEqual(response.status_code, 404) - def test_upload_page_url_admin_doesnt_exist(self): + def test_upload_page_url_admin_doesnt_exist(self): self.client.login(email="admin@gov.id", password="admin") response = self.client.get("/unggah/") self.assertEqual(response.status_code, 403) - def test_upload_page_url_admin_cant_upload(self): + def test_upload_page_url_admin_cant_upload(self): self.client.login(email="admin@gov.id", password="admin") response = self.client.post("/unggah/") @@ -1274,7 +1271,7 @@ class UploadExcelPageTest(TestCase): with open(file_name, 'rb') as fp: response = self.client.post("/unggah_excel/", {'excel': fp}) - + messages = list(dj_messages.get_messages(response.wsgi_request)) msg_text = messages[0].message @@ -1292,7 +1289,7 @@ class UploadExcelPageTest(TestCase): with open(file_name, 'rb') as fp: response = self.client.post("/unggah_excel/", {'excel': fp}) - + messages = list(dj_messages.get_messages(response.wsgi_request)) msg_text = messages[0].message @@ -1311,7 +1308,7 @@ class UploadExcelPageTest(TestCase): with open(file_name, 'rb') as fp: response = self.client.post("/unggah_excel/", {'excel': fp}) - + messages = list(dj_messages.get_messages(response.wsgi_request)) msg_text = messages[0].message @@ -1330,7 +1327,7 @@ class UploadExcelPageTest(TestCase): with open(file_name, 'rb') as fp: response = self.client.post("/unggah_excel/", {'excel': fp}) - + messages = list(dj_messages.get_messages(response.wsgi_request)) msg_text = messages[0].message @@ -1351,12 +1348,12 @@ class UploadExcelPageTest(TestCase): } categories = ['Computer Science','Machine Learning','Deep Learning'] - + file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths, categories=categories) with open(file_name, 'rb') as fp: self.client.post("/unggah_excel/", {'excel': fp}) - + title = data_frame['Title'][0] materi = Materi.objects.get(title=title) default_path = 'book-cover-placeholder.png' @@ -1370,11 +1367,11 @@ class UploadExcelPageTest(TestCase): password="kontributor") response = self.client.get("/unggah_excel/?template=1") - + self.assertEquals(response['Content-Type'],'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') self.assertEquals(response['Content-Disposition'],'attachment; filename=template.xlsx') - + @@ -1481,14 +1478,14 @@ class DeleteMateriTest(TestCase): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertEqual(response.status_code, 302) - + def test_url_soft_delete_materi_is_success_as_admin(self): self.client.login(**self.admin_credential) response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) + self.assertEqual(response.status_code, 302) self.materi1.refresh_from_db() self.assertNotEqual(self.materi1.deleted_at, None) - + def test_url_soft_delete_materi_is_success_as_superuser(self): self.client.login(**self.superuser_credential) response = self.client.get(self.url) @@ -1515,7 +1512,7 @@ class ProfilViewTest(TestCase): self.assertEqual(found.func.__name__, self.view.as_view().__name__) def _request_as_user(self, credentials): - self.client = Client() + self.client = Client() self.client.login(**credentials) return self.client.get(self.url) @@ -1557,7 +1554,7 @@ class SuntingProfilViewTest(TestCase): self.assertEqual(found.func.__name__, self.view.as_view().__name__) def _request_as_user(self, credentials): - self.client = Client() + self.client = Client() self.client.login(**credentials) return self.client.get(self.url) @@ -1938,7 +1935,7 @@ class RevisiMateriTest(TestCase): # Logout self.client.logout() - + class GenerateDummyCommandTest(TestCase): def setUp(self): @@ -2422,7 +2419,7 @@ class RatingContributorTest(TransactionTestCase): response = self.client.get(self.url) self.assertContains(response=response, text=f"Rating: {mean(avg)}", count=1) self.assertContains(response=response, text=f"oleh: {len(avg)} orang", count=1) - + def test_not_authenticated_user_should_not_able_to_add_rating(self): response_post = self.client.post(self.url, data={ "contributor":self.contributor.id, @@ -2432,11 +2429,11 @@ class RatingContributorTest(TransactionTestCase): response_get = self.client.get(self.url) self.assertEqual(response_post.status_code, 403) self.assertContains(response_get, "Kamu harus login untuk memberi rating") - + def test_not_authenticated_user_should_not_able_to_delete_rating(self): response_post = self.client.post(self.url, data={"delete":True}) self.assertEqual(response_post.status_code, 403) - + def test_authenticated_user_should_not_delete_rating_if_has_not_been_rated(self): self.client.login(**self.admin_credential) self.client.post(self.url, data={ @@ -2444,15 +2441,15 @@ class RatingContributorTest(TransactionTestCase): "user":self.admin.id, "score":3 }) - + self.assertEqual(1, RatingContributor.objects.filter(contributor=self.contributor).count()) self.client.logout() self.client.login(**self.anonymous_credential) self.client.post(self.url, data={"delete":True}) - + self.assertEqual(1, RatingContributor.objects.filter(contributor=self.contributor).count()) - + def test_authenticated_user_should_delete_rating_if_has_been_rated(self): self.client.login(**self.admin_credential) self.client.post(self.url, data={ @@ -2470,7 +2467,7 @@ class RatingContributorTest(TransactionTestCase): self.assertContains(response, 'Rating: 0') self.assertContains(response, 'oleh: 0 orang') self.assertEqual(0, RatingContributor.objects.filter(contributor=self.contributor).count()) - + def test_average_still_be_correct_when_rating_was_deleted(self): scores = [2,4] self.client.login(**self.admin_credential) @@ -2495,7 +2492,7 @@ class RatingContributorTest(TransactionTestCase): response = self.client.get(self.url) self.assertContains(response, f'Rating: {scores[0]}') self.assertContains(response, 'oleh: 1 orang') - + def test_authenticated_user_should_update_rating_if_has_been_rated(self): self.client.login(**self.anonymous_credential) self.client.post(self.url, data={ @@ -2511,7 +2508,7 @@ class RatingContributorTest(TransactionTestCase): response = self.client.get(self.url) self.assertContains(response, 'Rating: 3') self.assertContains(response, 'oleh: 1 orang') - + def test_authenticated_user_should_not_update_rating_if_has_not_been_rated(self): self.client.login(**self.anonymous_credential) response = self.client.get(self.url) @@ -2522,7 +2519,7 @@ class RatingContributorTest(TransactionTestCase): response = self.client.get(self.url) self.assertContains(response, 'Rating: 0') self.assertContains(response, 'oleh: 0 orang') - + class UserDownloadHistoryTest(TestCase): def setUp(self): @@ -2561,25 +2558,25 @@ class UserDownloadHistoryTest(TestCase): self.materi1 = Materi.objects.first() self.download_url = f"/materi/{self.materi1.id}/unduh" self.history_url = "/download-history/" - + def test_multiple_insert_download_statistic_with_user(self): DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 1) - + DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 2) - + def test_download_statistics_bound_to_specific_user(self): DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 1) - + DownloadStatistics(materi=self.materi1).save() num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 1) - + DownloadStatistics(materi=self.materi1, downloader=self.user2_anonim).save() user1_num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() user2_num_of_downloads = self.user2_anonim.riwayat_unduh.all().count() @@ -2589,14 +2586,14 @@ class UserDownloadHistoryTest(TestCase): def test_registered_user_download(self): # Login self.client.login(**self.user1_credential) - + self.client.get(self.download_url) num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 1) - + # Logout self.client.logout() - + def test_unregistered_user_download(self): self.client.get(self.download_url) downloaded_materi = self.client.session['downloaded_materi'] @@ -2614,10 +2611,10 @@ class UserDownloadHistoryTest(TestCase): self.client.get(self.download_url) num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 2) - + # Logout self.client.logout() - + def test_unregistered_user_multiple_download(self): self.client.get(self.download_url) downloaded_materi = self.client.session['downloaded_materi'] @@ -2630,27 +2627,27 @@ class UserDownloadHistoryTest(TestCase): num_of_downloads = DownloadStatistics.objects.filter( pk__in=downloaded_materi).count() self.assertEqual(num_of_downloads, 2) - + def test_registered_user_doesnt_use_session_when_download(self): # Login self.client.login(**self.user1_credential) - + self.client.get(self.download_url) self.assertFalse('downloaded_materi' in self.client.session) - + # Logout self.client.logout() - + def test_download_history_bound_to_specific_user(self): # Login Anonym 1 self.client.login(**self.user1_credential) self.client.get(self.download_url) num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() self.assertEqual(num_of_downloads, 1) - + # Logout Anonym 1 self.client.logout() - + # Unregistered User download self.client.get(self.download_url) user1_num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() @@ -2659,7 +2656,7 @@ class UserDownloadHistoryTest(TestCase): pk__in=downloaded_materi).count() self.assertEqual(user1_num_of_downloads, 1) self.assertEqual(guest_num_of_downloads, 1) - + # Login Anonym 2 self.client.login(**self.user2_credential) self.client.get(self.download_url) @@ -2668,7 +2665,7 @@ class UserDownloadHistoryTest(TestCase): self.assertEqual(user1_num_of_downloads, 1) self.assertEqual(guest_num_of_downloads, 1) self.assertEqual(user2_num_of_downloads, 1) - + # Logout Anonym 2 self.client.logout() @@ -2688,42 +2685,42 @@ class DownloadHistoryViewTest(TestCase): **self.contributor_credential, name="Kontributor", is_contributor=True ) self.client = Client() - + content1 = b"Test file" content2 = b"File Test" - + self.cover1 = SimpleUploadedFile("cover1.jpg",content1) self.content1 = SimpleUploadedFile("content1.txt",content1) - + self.cover2 = SimpleUploadedFile("cover2.jpg",content2) self.content2 = SimpleUploadedFile("content2.txt",content2) - + self.materi1 = Materi.objects.create(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover1, content=self.content1) self.materi2 = Materi.objects.create(title="Materi 2", author="Danin", uploader=self.contributor, publisher="Kelas DDP", descriptions="Deskripsi Materi 2", status="PENDING", cover=self.cover2, content=self.content2) - + self.download_url1 = f"/materi/{self.materi1.id}/unduh" self.download_url2 = f"/materi/{self.materi2.id}/unduh" self.history_url = "/download-history/" - + # Login self.client.login(**self.user_credential) def tearDown(self): # Logout self.client.logout() - + def test_allow_registered_user(self): response = self.client.get(self.history_url) self.assertEqual(response.status_code, 200) - + def test_allow_unregistered_user(self): # Forced Logout self.client.logout() - + response = self.client.get(self.history_url) self.assertEqual(response.status_code, 200) @@ -2735,14 +2732,14 @@ class DownloadHistoryViewTest(TestCase): response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') self.assertIn(self.user_anonim.name, resp_html) - + def test_registered_user_download_history_correctly_displayed(self): self.client.get(self.download_url1) self.client.get(self.download_url2) self.client.get(self.download_url1) - + jkt_timezone = timezone(TIME_ZONE) - + download_history = self.user_anonim.riwayat_unduh.all() response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') @@ -2750,19 +2747,19 @@ class DownloadHistoryViewTest(TestCase): downloaded_materi = riwayat.materi self.assertIn(downloaded_materi.title, resp_html) self.assertIn(downloaded_materi.author, resp_html) - + jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) self.assertIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - + def test_unregistered_user_download_history_correctly_displayed(self): self.client.logout() self.client.get(self.download_url1) self.client.get(self.download_url2) self.client.get(self.download_url1) - + jkt_timezone = timezone(TIME_ZONE) - + response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') for riwayat_id in self.client.session['downloaded_materi']: @@ -2770,19 +2767,19 @@ class DownloadHistoryViewTest(TestCase): downloaded_materi = riwayat.materi self.assertIn(downloaded_materi.title, resp_html) self.assertIn(downloaded_materi.author, resp_html) - + jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) self.assertIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - + def test_download_history_not_display_if_user_changed(self): self.client.get(self.download_url1) self.client.get(self.download_url2) self.client.get(self.download_url1) self.client.logout() - + jkt_timezone = timezone(TIME_ZONE) - + download_history = self.user_anonim.riwayat_unduh.all() response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') @@ -2790,23 +2787,23 @@ class DownloadHistoryViewTest(TestCase): downloaded_materi = riwayat.materi self.assertNotIn(downloaded_materi.title, resp_html) self.assertNotIn(downloaded_materi.author, resp_html) - + jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) self.assertNotIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - + def test_unregistered_user_download_history_wont_be_saved_if_user_changes(self): self.client.logout() self.client.get(self.download_url1) self.client.get(self.download_url2) self.client.get(self.download_url1) - + self.client.get(self.history_url) self.client.login(**self.user_credential) self.client.logout() self.assertFalse('downloaded_materi' in self.client.session) - + def test_download_history_sorted_by_download_time(self): # download with 1 second interval to differ download time self.client.get(self.download_url1) @@ -2816,15 +2813,15 @@ class DownloadHistoryViewTest(TestCase): self.client.get(self.download_url1) sleep(1) self.client.get(self.download_url2) - + response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') - + table_html = ("<table" + resp_html.split("<table")[1]).split("</table>")[0] + "</table>" soup = BeautifulSoup(table_html, 'html.parser') histories_html = soup.find('tbody').find_all('tr') prev_timestamp = None - + for riwayat_html in histories_html: materi_data = riwayat_html.find_all("td") date_format = "%d %B %Y %H:%M:%S" @@ -2832,7 +2829,7 @@ class DownloadHistoryViewTest(TestCase): if prev_timestamp: self.assertTrue(prev_timestamp > materi_timestamp) prev_timestamp = materi_timestamp - + def test_no_history_display_message(self): no_history_msg = "Anda belum mengunduh materi. Silahkan unduh materi yang anda butuhkan" response = self.client.get(self.history_url) @@ -2841,9 +2838,9 @@ class DownloadHistoryViewTest(TestCase): class MateriModelTest(TestCase): - + def setUp(self): - self.contributor = User.objects.create( + self.contributor = User.objects.create( email="kontributor@gov.id", password="passwordtest", name="kontributor", @@ -2930,7 +2927,7 @@ class RandomizedMateriTest(TestCase): response = Client().get("/?random=1") self.assertIn("Materi 1", response.content.decode()) self.assertIn("Materi 2", response.content.decode()) - + class YearChoicesTest(TestCase): def test_release_year_contains_the_right_current_year(self): now = dt.date.today().year @@ -2996,7 +2993,7 @@ class YTUrlVideoTest(TestCase): self.setUpImage() self.content = SimpleUploadedFile("ExampleFile221.pdf", b"Test file") self.category = Category.objects.create(id="1", name="medis", description="kategori medis") - + @override_settings(MEDIA_ROOT=tempfile.gettempdir()) def setUpImage(self): from django.core.files.uploadedfile import InMemoryUploadedFile @@ -3029,7 +3026,7 @@ class YTUrlVideoTest(TestCase): "yt_video_id":"jNwz4L9MGVY"} ) self.assertTrue(Materi.objects.get(title="Materi 1")) - + def test_upload_materi_with_invalid_yt_video_id(self): self.client.login(**self.contributor_credential) self.client.post( @@ -3039,7 +3036,7 @@ class YTUrlVideoTest(TestCase): "yt_video_id":"randomId"} ) self.assertEqual(Materi.objects.filter(title="Materi 2").count(), 0) - + def test_detail_materi_has_video_if_yt_video_id_not_empty(self): self.test_upload_materi_with_valid_yt_video_id() pk = Materi.objects.get(title="Materi 1").pk @@ -3090,7 +3087,7 @@ class ChangePasswordTest(TestCase): # Logout self.client.logout() - + class SeeRatedMateriByUser(TestCase): def setUp(self): self.client = Client() @@ -3265,28 +3262,28 @@ class PasswordValidatorPolicyTest(TestCase): self.password_length_lower_than_8 = "P4ss!" self.password_enforcing_policy = "Passw0rd!" self.validator = PasswordPolicyValidator() - + def test_using_password_no_lowercase(self): self.assertRaises(ValidationError, self.validator.validate, self.password_no_lowercase) def test_using_password_no_upprcase(self): self.assertRaises(ValidationError, self.validator.validate, self.password_no_uppercase) - + def test_using_password_no_digit(self): self.assertRaises(ValidationError, self.validator.validate, self.password_no_digit) def test_using_password_no_special_char(self): self.assertRaises(ValidationError, self.validator.validate, self.password_no_special_char) - + def test_using_password_with_length_less_than_8(self): self.assertRaises(ValidationError, self.validator.validate, self.password_length_lower_than_8) - + def test_using_password_using_correct_policy(self): self.assertEquals(self.validator.validate(self.password_enforcing_policy), None) - + class LandingPageNavbarTest(TestCase): - + def setUp(self): self.client = Client() self.contributor_credential = { @@ -3445,3 +3442,4 @@ class MateriRecommendationTest(TestCase): response = Client().get("/?recommendation=1") list = [int(id) for id in re.findall(r"Materi\s(\d+)[^\d]", response.content.decode())] self.assertEqual(list, [1, 2]) + diff --git a/app/urls.py b/app/urls.py index 06e7d42410e9289b3f1342eb6cf58d6daa10e202..a8c7281cbdd6821bf7eace5f939520e099f53ad5 100644 --- a/app/urls.py +++ b/app/urls.py @@ -41,7 +41,4 @@ urlpatterns = [ path("password_success/", views.password_success, name="password_success"), path("given-rating/", views.see_given_rating, name="see_given_rating"), path("submit-visitor/", SubmitVisitorView.as_view(), name="submit-visitor"), - path(r'subscribe/', views.subscribe, name='subscribe'), - path(r'subscribeform/', views.subscribeform, name='subscribeform'), - path(r'subscription_confirmation/', views.subscription_confirmation, name='subscription_confirmation'), ] diff --git a/app/utils/email_utility.py b/app/utils/email_utility.py deleted file mode 100644 index bc720758597e59a51e26a060f58838a2a17ef60d..0000000000000000000000000000000000000000 --- a/app/utils/email_utility.py +++ /dev/null @@ -1,90 +0,0 @@ -import logging, traceback -from django.urls import reverse -import requests -from django.template.loader import get_template -from django.utils.html import strip_tags -from django.conf import settings -import smtplib -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText -import email -import email.mime.application -from django.utils.html import strip_tags - - -def send_email(data): - try: - url = "https://api.mailgun.net/v3/<domain-name>/messages" - status = requests.post( - url, - auth=("api", settings.MAILGUN_API_KEY), - data={"from": "OKI <https://app.mailgun.com/app/sending/domains/sandbox34675edbad2a4ab08e896c3bd80524ec.mailgun.org>", - "to": [data["email"]], - "subject": data["subject"], - "text": data["plain_text"], - "html": data["html_text"]} - ) - logging.getLogger("info").info("Mail sent to " + data["email"] + ". status: " + str(status)) - return status - except Exception as e: - logging.getLogger("error").error(traceback.format_exc()) - return False - - -def send_subscription_email(email, subscription_confirmation_url): - data = dict() - data["confirmation_url"] = subscription_confirmation_url - data["subject"] = "Please Confirm The Subscription" - data["email"] = email - template = get_template("app/emails/subscription.html") - data["html_text"] = template.render(data) - data["plain_text"] = strip_tags(data["html_text"]) - return send_email(data) - - -def send_gmail(email, subscription_confirmation_url): - # create message - msg = MIMEMultipart('alternative') - msg['Subject'] = "Please verify your mail" - msg['From'] = "pmplmailer@gmail.com" - msg['To'] = email - - # create body - html_text = '<div style="border:1px solid black">Thanks for subscribing to Us. Please click this link to activate your subscription : ' + subscription_confirmation_url + '</div>' - plain_text = strip_tags(html_text) - - # Create the body of the message (a plain-text and an HTML version). - # Record the MIME types of both parts - text/plain and text/html. - part1 = MIMEText(plain_text, 'plain') - part2 = MIMEText(html_text, 'html') - - # Attach image if any - - # Attach parts into message container. - # According to RFC 2046, the last part of a multipart message, in this case - # the HTML message, is best and preferred. - msg.attach(part1) - msg.attach(part2) - - # Send the message via local SMTP server. - host = "smtp.gmail.com" - port = 587 - mail = smtplib.SMTP(host, port, timeout=60) - mail.ehlo() - mail.starttls() - - # Add recepiens, cc or bcc if any - recepient = [msg["To"]] - - # username and password of gmail id which will be used to send email - username = "pmplmailer@gmail.com" - password = "asdf1234$" - - # login using credentials - mail.login(username, password) - - # send email - mail.sendmail(msg["From"], recepient, msg.as_string()) - mail.quit() - - return "\nSent\n" \ No newline at end of file diff --git a/app/utils/encryption_util.py b/app/utils/encryption_util.py deleted file mode 100644 index a448767e066acceda561a4a48cc602628db41148..0000000000000000000000000000000000000000 --- a/app/utils/encryption_util.py +++ /dev/null @@ -1,37 +0,0 @@ -from cryptography.fernet import Fernet -import base64 -import logging -import traceback -from django.conf import settings - -#this is your "password/ENCRYPT_KEY". keep it in settings.py file -#key = Fernet.generate_key() - -def encrypt(txt): - try: - # convert integer etc to string first - txt = str(txt) - # get the key from settings - cipher_suite = Fernet(settings.ENCRYPT_KEY) # key should be byte - # #input should be byte, so convert the text to byte - encrypted_text = cipher_suite.encrypt(txt.encode('ascii')) - # encode to urlsafe base64 format - encrypted_text = base64.urlsafe_b64encode(encrypted_text).decode("ascii") - return encrypted_text - except Exception as e: - # log the error if any - logging.getLogger("error_logger").error(traceback.format_exc()) - return None - - -def decrypt(txt): - try: - # base64 decode - txt = base64.urlsafe_b64decode(txt) - cipher_suite = Fernet(settings.ENCRYPT_KEY) - decoded_text = cipher_suite.decrypt(txt).decode("ascii") - return decoded_text - except Exception as e: - # log the error - logging.getLogger("error_logger").error(traceback.format_exc()) - return None \ No newline at end of file diff --git a/app/views.py b/app/views.py index 306e84073b13dea436e90faa2952bafcb618f81c..a0062ed070c2065cc77c3e37757c749b70f470d1 100644 --- a/app/views.py +++ b/app/views.py @@ -1,9 +1,5 @@ import mimetypes import os -import re -import time -import logging -import traceback from io import BytesIO import django @@ -19,7 +15,8 @@ from django.core.paginator import Paginator from django.db.models import Q, Avg from django.http import (Http404, HttpResponse, HttpResponseRedirect, JsonResponse) -from django.shortcuts import get_object_or_404, redirect, render +from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import render from django.template import loader from django.urls import reverse from django.urls import reverse_lazy @@ -37,10 +34,6 @@ from app.models import ( SubmitVisitor ) from authentication.models import User -from app.utils.encryption_util import encrypt, decrypt -from app.utils.email_utility import send_subscription_email, send_gmail -from app.models import SubscribeModel -from datetime import datetime from .services import DafterKatalogService, DetailMateriService, LikeDislikeService, MateriFieldValidationHelperService, \ DownloadViewMateriHelperService, UploadMateriService, EditProfileService, RevisiMateriService, \ DownloadHistoryService, GoogleDriveUploadService @@ -212,7 +205,7 @@ class DetailMateri(TemplateView): from_email = getattr(settings, 'EMAIL_HOST_USER'), recipient_list = [materi_uploader.email,], fail_silently = False, - ) + ) elif (review_text != None): review = Review.objects.create( review=review_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj @@ -292,98 +285,6 @@ def add_rating_materi(request): ) return JsonResponse({"success": False, "msg": "Forbidden"}, status=403) -def subscribeform(request): - return render(request, 'subscribe.html', ) - -def subscribe(request): - post_data = request.POST.copy() - email = post_data.get("email", None) - - error_msg = validate_email(email) - if error_msg: - messages.error(request, error_msg) - return HttpResponseRedirect(reverse('subscribe')) - - token = encrypt(email + "_" + str(time.time())) - subscription_confirmation_url = request.build_absolute_uri( reverse('subscription_confirmation')) + "?token=" + token - status = send_gmail(email, subscription_confirmation_url) - save_status = save_email(email) - - if save_status: - token = encrypt(email + "_" + str(time.time())) - subscription_confirmation_url = request.build_absolute_uri(reverse('subscription_confirmation')) + "?token=" + token - status = send_gmail(email, subscription_confirmation_url) - if not status: - SubscribeModel.objects.get(email=email).delete() - logging.getLogger("info").info( - "Deleted the record from Subscribe table for " + email + " as email sending failed. status: " + str( - status)) - else: - msg = "Mail sent to email Id '" + email + "'. Please confirm your subscription by clicking on " \ - "confirmation link provided in email. " \ - "Please check your spam folder as well." - messages.success(request, msg) - return HttpResponse(msg) - else: - msg = "Some error occurred. Please try in some time. Meanwhile we are looking into it." - messages.error(request, msg) - return HttpResponse(msg) - return HttpResponseRedirect(reverse('subscribeform')) - -def subscription_confirmation(request): - if "POST" == request.method: - raise Http404 - - token = request.GET.get("token", None) - - if not token: - logging.getLogger("warning").warning("Invalid Link ") - messages.error(request, "Invalid Link") - return HttpResponseRedirect(reverse('subscribeform')) - - token = decrypt(token) - if token: - token = token.split("_") - email = token[0] - print(email) - initiate_time = token[1] # time when email was sent , in epoch format. can be used for later calculations - try: - subscribe_model_instance = SubscribeModel.objects.get(email=email) - subscribe_model_instance.status = "CONFIRMED" - subscribe_model_instance.updated_date = datetime.today() - subscribe_model_instance.save() - messages.success(request, "Subscription Confirmed. Thank you.") - except Exception as e: - logging.getLogger("warning").warning(traceback.format_exc()) - messages.error(request, "Invalid Link") - else: - logging.getLogger("warning").warning("Invalid token ") - messages.error(request, "Invalid Link") - - return HttpResponse('<h1>Thank you for subscribing us</h1>') - -def validate_email(email): - if email is None: - return "Email is required." - elif not re.match(r"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", email): - return "Invalid Email Address." - else: - return None - -def save_email(email): - try: - subscribe_model_instance = SubscribeModel.objects.get(email=email) - except Exception as e: - subscribe_model_instance = SubscribeModel() - - - # does not matter if already subscribed or not...resend the email - subscribe_model_instance.email = email - subscribe_model_instance.status = "SUBSCRIBED" - subscribe_model_instance.created_date = datetime.today() - subscribe_model_instance.updated_date = datetime.today() - subscribe_model_instance.save() - return True def download_materi(request, pk): @@ -751,7 +652,6 @@ class RevisiMateriView(TemplateView): return self.render_to_response(context) - def pages(request): context = {} # All resource paths end in .html. diff --git a/authentication/migrations/0001_initial.py b/authentication/migrations/0001_initial.py index 8dd6568cd24f5cf72e9aba257659da57907aa573..b28fe9c3d35bef40e5c1a2e04b5c1acbc47333fd 100644 --- a/authentication/migrations/0001_initial.py +++ b/authentication/migrations/0001_initial.py @@ -1,8 +1,9 @@ -# Generated by Django 3.1 on 2020-10-30 15:29 +# Generated by Django 3.0.3 on 2020-05-08 14:42 -import authentication.models -from django.db import migrations, models import django.utils.timezone +from django.db import migrations, models + +import authentication.models class Migration(migrations.Migration): @@ -10,41 +11,53 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), + ('auth', '0011_update_proxy_permissions'), ] operations = [ migrations.CreateModel( name='User', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('id', models.AutoField(auto_created=True, + primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField( + max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField( + blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, + help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('first_name', models.CharField(blank=True, + max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, + max_length=150, verbose_name='last name')), + ('is_staff', models.BooleanField(default=False, + help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField( + default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField( + default=django.utils.timezone.now, verbose_name='date joined')), ('email', models.EmailField(max_length=254, unique=True)), - ('username', models.CharField(blank=True, default='', max_length=150)), + ('username', models.CharField( + blank=True, default='', max_length=150)), ('name', models.CharField(max_length=150)), ('is_admin', models.BooleanField(default=False)), ('is_contributor', models.BooleanField(default=False)), ('instansi', models.CharField(max_length=240)), - ('nik', models.CharField(max_length=16)), + ('nik', models.CharField(max_length=240)), ('alamat', models.CharField(max_length=240)), ('nomor_telpon', models.CharField(max_length=240)), ('linkedin', models.URLField(blank=True, default='')), ('facebook', models.URLField(blank=True, default='')), ('twitter', models.URLField(blank=True, default='')), ('instagram', models.URLField(blank=True, default='')), - ('biography', models.TextField(blank=True, default='', max_length=200)), - ('default_profile_picture', models.BooleanField(blank=True, default=False)), - ('profile_picture', models.ImageField(default='default-image.jpg', upload_to='')), - ('is_subscribing_to_material_comments', models.BooleanField(default=True)), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ('biography', models.TextField( + blank=True, default='', max_length=200)), + ('profile_picture', models.ImageField( + default='https://ibb.co/gv9YHt4', upload_to='profile_picture/')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', + related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', + related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ 'verbose_name': 'user', diff --git a/authentication/migrations/0002_auto_20200518_1752.py b/authentication/migrations/0002_auto_20200518_1752.py new file mode 100644 index 0000000000000000000000000000000000000000..8e88a1b0ce600471b466fc503131e56fd6defd54 --- /dev/null +++ b/authentication/migrations/0002_auto_20200518_1752.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2020-05-18 10:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='profile_picture', + field=models.ImageField(default='https://i.ibb.co/9wgPzyZ/default-image.png', upload_to='profile_picture/'), + ), + ] diff --git a/authentication/migrations/0003_auto_20200519_1012.py b/authentication/migrations/0003_auto_20200519_1012.py new file mode 100644 index 0000000000000000000000000000000000000000..b705ff097ac330024e85c1b8c97daf8890e7a54e --- /dev/null +++ b/authentication/migrations/0003_auto_20200519_1012.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2020-05-19 03:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0002_auto_20200518_1752'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='default_profile_picture', + field=models.URLField(blank=True, default="https://i.ibb.co/9wgPzyZ/default-image.png'"), + ), + migrations.AlterField( + model_name='user', + name='profile_picture', + field=models.ImageField(upload_to='', verbose_name=models.URLField(blank=True, default="https://i.ibb.co/9wgPzyZ/default-image.png'")), + ), + ] diff --git a/authentication/migrations/0004_auto_20200519_1020.py b/authentication/migrations/0004_auto_20200519_1020.py new file mode 100644 index 0000000000000000000000000000000000000000..255dcf75f6a117a94a61e45177b7e4f257a1afc3 --- /dev/null +++ b/authentication/migrations/0004_auto_20200519_1020.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2020-05-19 03:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0003_auto_20200519_1012'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='default_profile_picture', + field=models.BooleanField(blank=True, default=False), + ), + migrations.AlterField( + model_name='user', + name='profile_picture', + field=models.ImageField(upload_to='', verbose_name=models.BooleanField(blank=True, default=False)), + ), + ] diff --git a/authentication/migrations/0005_auto_20200519_1021.py b/authentication/migrations/0005_auto_20200519_1021.py new file mode 100644 index 0000000000000000000000000000000000000000..05bf864c6833afd6496877d76da9a976f7add55f --- /dev/null +++ b/authentication/migrations/0005_auto_20200519_1021.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2020-05-19 03:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0004_auto_20200519_1020'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='profile_picture', + field=models.ImageField(default='default-image.jpg', upload_to=''), + ), + ] diff --git a/authentication/migrations/0006_auto_20200929_2125.py b/authentication/migrations/0006_auto_20200929_2125.py new file mode 100644 index 0000000000000000000000000000000000000000..a2c2da4f14cc46dadd6f038686ae09c7205e6c72 --- /dev/null +++ b/authentication/migrations/0006_auto_20200929_2125.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-09-29 14:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0005_auto_20200519_1021'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='first_name', + field=models.CharField(blank=True, max_length=150, verbose_name='first name'), + ), + ] diff --git a/authentication/migrations/0007_auto_20201009_1415.py b/authentication/migrations/0007_auto_20201009_1415.py new file mode 100644 index 0000000000000000000000000000000000000000..012a5c89e717087a23903de27bbadbdf8798d63e --- /dev/null +++ b/authentication/migrations/0007_auto_20201009_1415.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-09 07:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0006_auto_20200929_2125'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='nik', + field=models.CharField(max_length=16), + ), + ] diff --git a/authentication/migrations/0008_user_is_subscribing_to_material_comments.py b/authentication/migrations/0008_user_is_subscribing_to_material_comments.py new file mode 100644 index 0000000000000000000000000000000000000000..2348d49d3ce1c3cbe3b11628b81dde0ad5be4478 --- /dev/null +++ b/authentication/migrations/0008_user_is_subscribing_to_material_comments.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-29 12:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0007_auto_20201009_1415'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='is_subscribing_to_material_comments', + field=models.BooleanField(default=True), + ), + ] diff --git a/digipus/settings.py b/digipus/settings.py index 3fc4cad5a64dc14ba4badf26c09479b5dc7be212..884c3e67cf7924e4165161d8d50a3ce04361a306 100644 --- a/digipus/settings.py +++ b/digipus/settings.py @@ -189,5 +189,4 @@ EMAIL_PORT = config('EMAIL_PORT', default=587) # use Google Mail SMTP as default EMAIL_HOST_USER = config('EMAIL_HOST_USER', default="pmplclass2020@gmail.com") EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default="pmpldigipusemail") EMAIL_USE_TLS = True -EMAIL_USE_SSL = False -ENCRYPT_KEY = b'YVLSFH4WgxkLgCOmCBchVmahU_VIF2xPFdD7GUTsvgY=' +EMAIL_USE_SSL = False \ No newline at end of file diff --git a/forum/migrations/0001_initial.py b/forum/migrations/0001_initial.py index 652260331742b31ca6bacb8926451651385c17b3..09be1531345689e50d9940908018970274ada73f 100644 --- a/forum/migrations/0001_initial.py +++ b/forum/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1 on 2020-10-30 15:30 +# Generated by Django 3.1 on 2020-10-06 14:39 from django.conf import settings from django.db import migrations, models @@ -11,7 +11,6 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('app', '0001_initial'), ] operations = [ @@ -20,10 +19,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.TextField()), - ('description', models.TextField(blank=True, default='')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('materi', models.ManyToManyField(blank=True, to='app.Materi')), + ('description', models.TextField(default='')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), @@ -32,10 +28,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('description', models.TextField(default='')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), ('discussion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.discussion')), - ('materi', models.ManyToManyField(blank=True, to='app.Materi')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), diff --git a/forum/migrations/0002_auto_20201007_1903.py b/forum/migrations/0002_auto_20201007_1903.py new file mode 100644 index 0000000000000000000000000000000000000000..f26c6bac7c379bbb8dc5bb85ecbb59bb0e4b8e0c --- /dev/null +++ b/forum/migrations/0002_auto_20201007_1903.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1 on 2020-10-07 12:03 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + dependencies = [ + ('forum', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='discussion', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + migrations.AddField( + model_name='discussion', + name='updated_at', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/forum/migrations/0003_auto_20201008_2056.py b/forum/migrations/0003_auto_20201008_2056.py new file mode 100644 index 0000000000000000000000000000000000000000..dab5b854233c101e4563576f554eacb33b0365e9 --- /dev/null +++ b/forum/migrations/0003_auto_20201008_2056.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1 on 2020-10-08 13:56 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + dependencies = [ + ('forum', '0002_auto_20201007_1903'), + ] + + operations = [ + migrations.AddField( + model_name='discussioncomment', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + migrations.AddField( + model_name='discussioncomment', + name='updated_at', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/forum/migrations/0004_discussion_materi.py b/forum/migrations/0004_discussion_materi.py new file mode 100644 index 0000000000000000000000000000000000000000..8cbd9bd33e85ad3e50b4021d38ecc61d6afeebed --- /dev/null +++ b/forum/migrations/0004_discussion_materi.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-08 18:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('app', '0015_reqmaterial'), + ('forum', '0003_auto_20201008_2056'), + ] + + operations = [ + migrations.AddField( + model_name='discussion', + name='materi', + field=models.ManyToManyField(blank=True, null=True, to='app.Materi'), + ), + ] diff --git a/forum/migrations/0005_auto_20201009_0138.py b/forum/migrations/0005_auto_20201009_0138.py new file mode 100644 index 0000000000000000000000000000000000000000..c4fc40216dcc5203cd5f094eac30a507e281ea11 --- /dev/null +++ b/forum/migrations/0005_auto_20201009_0138.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-10-08 18:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('app', '0015_reqmaterial'), + ('forum', '0004_discussion_materi'), + ] + + operations = [ + migrations.AlterField( + model_name='discussion', + name='materi', + field=models.ManyToManyField(blank=True, to='app.Materi'), + ), + ] diff --git a/forum/migrations/0006_auto_20201009_0625.py b/forum/migrations/0006_auto_20201009_0625.py new file mode 100644 index 0000000000000000000000000000000000000000..3e59801201877f0ae3fa0d9ca0972d8aad393c17 --- /dev/null +++ b/forum/migrations/0006_auto_20201009_0625.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1 on 2020-10-08 23:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('app', '0015_reqmaterial'), + ('forum', '0005_auto_20201009_0138'), + ] + + operations = [ + migrations.AddField( + model_name='discussioncomment', + name='materi', + field=models.ManyToManyField(blank=True, to='app.Materi'), + ), + migrations.AlterField( + model_name='discussion', + name='description', + field=models.TextField(blank=True, default=''), + ), + ] diff --git a/news/migrations/0001_initial.py b/news/migrations/0001_initial.py index ed7921e164b76563aa96c5b5d43cf0260e5f7b1a..7c584641a29f5191a19848e13e52ed48722d8ff4 100644 --- a/news/migrations/0001_initial.py +++ b/news/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1 on 2020-10-30 15:30 +# Generated by Django 3.1 on 2020-10-03 07:47 from django.db import migrations, models