Fakultas Ilmu Komputer UI

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • pmpl/class-project/marjinal-digipus
  • ppl-fasilkom-ui/2020/ppl-c/diskominfo-depok-digipus/marjinal-digipus
2 results
Select Git revision
Show changes
Commits on Source (482)
Showing
with 981 additions and 29 deletions
# Created by https://www.gitignore.io/api/venv,django,python,visualstudiocode
# Edit at https://www.gitignore.io/?templates=venv,django,python,visualstudiocode
### Django ###
*.log
*.pot
*.pyc
__pycache__/
local_settings.py
db.sqlite3
db.sqlite3-journal
media
*/__pycache__/*
/static/
media/
.coverage
virtualenv
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
# in your Git repository. Update and uncomment the following line accordingly.
# <django-project-name>/staticfiles/
### Django.Python Stack ###
# Byte-compiled / optimized / DLL files
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
.pip_cache
pylint
coverage.svg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
### Python ###
# Byte-compiled / optimized / DLL files
# C extensions
# Distribution / packaging
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
# Installer logs
# Unit test / coverage reports
# Translations
# Scrapy stuff:
# Sphinx documentation
# PyBuilder
# pyenv
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# celery beat schedule file
# SageMath parsed files
# Spyder project settings
# Rope project settings
# Mr Developer
# mkdocs documentation
# mypy
# Pyre type checker
### venv ###
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
pyvenv.cfg
# .env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
pip-selfcheck.json
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.vscode/
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
# End of https://www.gitignore.io/api/venv,django,python,visualstudiocode
#misc
__pycache__/
db.sqlite3
.coverage
htmlcov/
flowchart/
client_secrets.json
# Pycharm IDE
.idea
# MacOS
.DS_Store
...@@ -11,6 +11,11 @@ local_settings.py ...@@ -11,6 +11,11 @@ local_settings.py
db.sqlite3 db.sqlite3
db.sqlite3-journal db.sqlite3-journal
media media
*/__pycache__/*
/static/
media/
.coverage
virtualenv
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
# in your Git repository. Update and uncomment the following line accordingly. # in your Git repository. Update and uncomment the following line accordingly.
...@@ -44,6 +49,9 @@ share/python-wheels/ ...@@ -44,6 +49,9 @@ share/python-wheels/
.installed.cfg .installed.cfg
*.egg *.egg
MANIFEST MANIFEST
.pip_cache
pylint
coverage.svg
# PyInstaller # PyInstaller
# Usually these files are written by a python script from a template # Usually these files are written by a python script from a template
...@@ -171,6 +179,7 @@ dmypy.json ...@@ -171,6 +179,7 @@ dmypy.json
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
pyvenv.cfg pyvenv.cfg
.env .env
.env.db
.venv .venv
env/ env/
venv/ venv/
...@@ -185,6 +194,7 @@ pip-selfcheck.json ...@@ -185,6 +194,7 @@ pip-selfcheck.json
!.vscode/tasks.json !.vscode/tasks.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
.vscode/
### VisualStudioCode Patch ### ### VisualStudioCode Patch ###
# Ignore all local history of files # Ignore all local history of files
...@@ -196,4 +206,13 @@ pip-selfcheck.json ...@@ -196,4 +206,13 @@ pip-selfcheck.json
__pycache__/ __pycache__/
db.sqlite3 db.sqlite3
.coverage .coverage
htmlcov/ htmlcov/
\ No newline at end of file flowchart/
client_secrets.json
# Pycharm IDE
.idea
# MacOS
.DS_Store
*.bak
\ No newline at end of file
...@@ -3,12 +3,57 @@ stages: ...@@ -3,12 +3,57 @@ stages:
- sonarqube - sonarqube
- deploy - deploy
pylint:
image: farhanazmi/digipus-base
stage: test
script:
- mkdir ./pylint
- git ls-files | grep -v 'migrations' | grep -v 'settings.py' | grep -v 'manage.py' | grep -E '.py$' | xargs pylint -E --load-plugins=pylint_django --output-format=text --score=yes | tee ./pylint/pylint.log || pylint-exit $?
- PYLINT_SCORE=$(sed -n 's/^Your code has been rated at \([-0-9.]*\)\/.*/\1/p' ./pylint/pylint.log)
- anybadge --label=Pylint --file=pylint/pylint.svg --value=$PYLINT_SCORE 2=red 4=orange 8=yellow 10=green
- echo "Pylint score is $PYLINT_SCORE"
artifacts:
paths:
- ./pylint/
.development:
variables:
IMAGE_SCOPE_TAG: "$CI_COMMIT_BRANCH"
except:
- master
environment: development
.production:
variables:
IMAGE_SCOPE_TAG: stable
only:
- master
environment: production
.docker-image:
stage: deploy
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [ "" ]
variables:
CONTEXT: $CI_PROJECT_DIR
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --context ${CONTEXT} --dockerfile ${CONTEXT}/Dockerfile --destination ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG} --destination ${CI_REGISTRY_IMAGE}:${IMAGE_SCOPE_TAG}
UnitTest: UnitTest:
image: python:3.7 services:
- postgres:alpine
variables:
POSTGRES_DB: gitlab_test
POSTGRES_USER: gitlab_test
POSTGRES_PASSWORD: SebuahPassword
image: farhanazmi/digipus-base
stage: test stage: test
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/' coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
before_script: before_script:
- pip install -r requirements.txt - export DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB
- python manage.py makemigrations - python manage.py makemigrations
- python manage.py migrate - python manage.py migrate
- python manage.py collectstatic --no-input - python manage.py collectstatic --no-input
...@@ -22,9 +67,7 @@ UnitTest: ...@@ -22,9 +67,7 @@ UnitTest:
- coverage.xml - coverage.xml
SonarScanner: SonarScanner:
image: image: addianto/sonar-scanner-cli:latest
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
stage: sonarqube stage: sonarqube
script: script:
- sonar-scanner - sonar-scanner
...@@ -33,37 +76,35 @@ SonarScanner: ...@@ -33,37 +76,35 @@ SonarScanner:
-Dsonar.branch.name=$CI_COMMIT_REF_NAME -Dsonar.branch.name=$CI_COMMIT_REF_NAME
-Dsonar.projectKey=$SONARQUBE_PROJECT_KEY -Dsonar.projectKey=$SONARQUBE_PROJECT_KEY
Staging: Deployment:
image: ruby:2.4 image: ruby:2.4
stage: deploy stage: deploy
only: only:
refs: refs:
- staging - master
when: manual
allow_failure: true
before_script: before_script:
- gem install dpl - gem install dpl
- wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh - wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
script: script:
- dpl --provider=heroku --app=$HEROKU_APPNAME_STAGING --api-key=$HEROKU_APIKEY - dpl --provider=heroku --strategy=git --app=$HEROKU_APPNAME_STAGING --api-key=$HEROKU_APIKEY
- export HEROKU_API_KEY=$HEROKU_APIKEY - export HEROKU_API_KEY=$HEROKU_APIKEY
- heroku run --app $HEROKU_APPNAME_STAGING migrate - heroku run --app $HEROKU_APPNAME_STAGING migrate
environment: environment:
name: staging name: staging
url: $HEROKU_APP_HOST_STAGING url: $HEROKU_APP_HOST_STAGING
Dev Docker Image:
# Deployment: extends:
# image: ruby:2.4 - .docker-image
# stage: deploy - .development
# only: allow_failure: true
# refs: when: manual
# - master
# before_script: Prod Docker Image:
# - gem install dpl extends:
# - wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh - .docker-image
# script: - .production
# - dpl --provider=heroku --app=$HEROKU_APPNAME --api-key=$HEROKU_APIKEY when: manual
# - export HEROKU_API_KEY=$HEROKU_APIKEY allow_failure: true
# - heroku run --app $HEROKU_APPNAME migrate \ No newline at end of file
# environment:
# name: production
# url: $HEROKU_APP_HOST
{
"python.pythonPath": "env\\Scripts\\python.exe"
}
\ No newline at end of file
# BUILDER
FROM python:3.7-slim as builder
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install --no-install-recommends gcc python3-dev libpq-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY . .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
# FINAL
FROM python:3.7-slim
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install --no-install-recommends gcc python3-dev libpq-dev
RUN mkdir -p /home/digipus
ENV APP_HOME=/home/digipus/
RUN mkdir $APP_HOME/staticfiles
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME
COPY . .
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*
EXPOSE 8000
VOLUME ["/home/digipus/staticfiles", "/home/digipus/mediafiles"]
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "digipus.wsgi:application", "--reload"]
FROM python:3.7-slim
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install --no-install-recommends gcc python3-dev libpq-dev git-all \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
RUN pip install -r requirements.txt
CMD [ "python" ]
\ No newline at end of file
# Digipus
## Pipeline Status
[![pipeline status](https://gitlab.cs.ui.ac.id/pmpl/class-project/marjinal-digipus/badges/master/pipeline.svg)](https://gitlab.cs.ui.ac.id/pmpl/class-project/marjinal-digipus/commits/master)
[![coverage report](https://gitlab.cs.ui.ac.id/pmpl/class-project/marjinal-digipus/badges/master/coverage.svg)](https://gitlab.cs.ui.ac.id/pmpl/class-project/marjinal-digipus/commits/master)
## Table of Contents
- [Description](#description)
- [Initial Setup](#initial-setup)
- [Running Development Environment](#running-development-environment)
- [Running Development Environment with Docker Compose](#running-development-environment-with-docker-compose)
- [Contributors](#contributors)
## Description
### Abstract
Digipus is a system application that can accommodate archiving educational material from regional
apparatus, academics, and practitioners, and organizing it properly so that it becomes material for
increasing knowledge and skills for the community at large.
There are three personas here, Admin, Contributor, and User (General Public). As admins, they monitor
contributors and material uploaded by contributors by rejecting or approving uploaded material.
As contributors, they can upload a material. And as a user, they can look at the material uploaded by contributor.
### Feature
Feature that already in this project.
Admin:
1. Login/Register as an admin.
2. Approve/Reject a material.
3. Configuration category and criteria of material.
4. Manage contributor.
5. Manage admin.
6. Edit profile.
Contributor:
1. Login/Register as an admin.
2. Upload a material.
3. Edit profile.
4. Look at statistic comments.
User:
1. Look on a material.
2. Give comment.
3. Download or read materials.
## Initial Setup
This project uses Python 3 with Django Framework. You need to install the required
dependencies prior to building and contributing to the project.
- [Python 3.6 or newer](https://www.python.org/downloads/release/) and `pip` package
manager.
> Note: We recommend using _virtual environment_ to isolate project-specific
> Python packages from system-level packages. You can install and use
> [`virtualenv`](https://virtualenv.pypa.io/en/stable/) package to create the
> virtual environment for this project.
- PostgreSQL.
To verify your Python is installed. Make sure
the interpreter can be invoked from the shell. For example,
in `bash` shell (macOS or GNU/Linux-based OS):
```bash
$ python3 --version
Python 3.8.2
$ pip3 --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
```
This project uses PostgreSQL as the database. So, add these lines to `.env` to
setup your local database-related environment variables:
```bash
IS_LOCAL=True
DB_NAME=marjinal
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=localhost
DB_PORT=5432
```
You can adjust `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST`, and `DB_PORT`
based on your local configuration.
Furthermore, this project utilizes Django's mail engine to send notification email
for contributors that're subscribing to new comments on their uploaded materials.
The codebase already have a class email configured as a default sender email, but you can use your own too.
To do so, please configure your `.env` to have these values:
```bash
EMAIL_HOST_USER=<your-email>@gmail.com
EMAIL_HOST_PASSWORD=<your-email-password>
```
> Note:
> Be informed that only **Google Mail accounts** that can be used, since the default SMTP server host & port are Google's.
>
> Your email also have to have [`Less secure app access` turned **on**](https://www.google.com/settings/security/lesssecureapps).
> [Reference](https://stackoverflow.com/a/26852782)
>
> If you want to use other SMTP server, please configure through env var `EMAIL_HOST` and `EMAIL_PORT`.
After you clone this repository, let's make sure you installed all requirements, migrate, and collect static.
```bash
pip3 install -r requirements.txt
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py collectstatic --no-input
```
## Running Development Environment
To run the server:
```bash
python3 manage.py runserver
```
You can see the app running by going to `http://127.0.0.1:8000/` via your browser.
To run the test:
```bash
python3 manage.py test
```
To see your coverage:
```bash
coverage run --include="./*" --omit="manage.py,digipus/*,env/*" manage.py test
coverage report -m
```
You can load an some initial data with this command:
```bash
python3 manage.py loaddata */fixtures/initial.json
```
## Running Development Environment with Docker Compose
Requires [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/).
If you have already created a `.env` file, adjust its content to:
```bash
SECRET_KEY=place-your-secret-key-here
IS_LOCAL=True
DB_NAME=marjinal
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=db
DB_PORT=5432
```
Create a `.env.db` file, fill its content with:
```bash
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=marjinal
```
To build and run the containers:
```bash
docker-compose up -d --build
```
To run the containers without rebuilding them first:
```bash
docker-compose up -d
```
To stop the containers:
```bash
docker-compose down
```
To run any command related to the DIGIPUS container:
```bash
docker-compose exec digipus <command>
```
For example, to migrate the database:
```bash
docker-compose exec digipus python manage.py migrate
```
To run any command related to the database container:
```bash
docker-compose exec db <command>
```
For example, to run `psql`:
```bash
docker-compose exec db psql -U postgres
```
## Contributors
This repository is one of the projects from the Software Project course.
Contributor: Marjinal x Diskominfo Depok
* Lecturer : Dr. Ade Azurat
* Scrum Master: Kemas Khaidar Ali
* Product Owner: Fadhlillah Zata R.
* Developer:
* I Gusti Putu Agastya Indrayana - 1706074940
* Igor Lestin Sianipar - 1706023372
* Mika Dabelza Abi - 1706022842
* Samuel Dimas Partogi - 1706074915
* Saul Andre Lumban Gaol - 1706023555
from django.apps import AppConfig
class AdministrationConfig(AppConfig):
name = "administration"
from django.utils import timezone
from dateutil.relativedelta import relativedelta
LONG_MONTH = ['', 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember']
BASE_PERIODE = [
("", "Pilih"),
('-----', (
("LAST_WEEK", "7 Hari Terakhir"),
("LAST_MONTH", "30 Hari Terakhir"),
("LAST_QUARTER", "90 Hari Terakhir"),
("LAST_YEAR", "365 Hari Terakhir"),
("ALL_TIME", "Semua waktu")
)),
]
def generate_periode_choices():
periode = BASE_PERIODE
now = timezone.now()
# Month
month_choice = []
month_choice.append(("CURRENT_MONTH",LONG_MONTH[now.month]))
for i in range(1,3):
month = (now-relativedelta(months=i))
month_choice.append((f"MINUS_{i}_MONTH",LONG_MONTH[month.month]))
month_choice = ('-----', tuple(month_choice))
periode.append(month_choice)
# Year
year_choice = []
year_choice.append(("CURRENT_YEAR",now.year))
for i in range(1,3):
year = (now-relativedelta(years=i))
year_choice.append((f"MINUS_{i}_YEAR",year.year))
year_choice = ('-----', tuple(year_choice))
periode.append(year_choice)
return tuple(periode)
[
{
"model": "administration.verificationsetting",
"pk": 1,
"fields": {
"title": "Kriteria 1",
"description": "Materi Harus memenuhi kriteria 1",
"archived": false
}
},
{
"model": "administration.verificationsetting",
"pk": 2,
"fields": {
"title": "Kriteria 2",
"description": "Materi Harus memenuhi kriteria 2",
"archived": false
}
},
{
"model": "administration.verificationsetting",
"pk": 3,
"fields": {
"title": "Kriteria 3",
"description": "Materi Harus memenuhi kriteria 3",
"archived": false
}
}
]
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column, Reset, ButtonHolder, Button
from crispy_forms.bootstrap import InlineCheckboxes
from django import forms
from administration.choices import generate_periode_choices
from administration.models import VerificationSetting
from app.models import Category
from authentication.models import User
def generate_category_choices():
categories = Category.objects.all()
category_choices = [(i.id, i.name) for i in categories]
return category_choices
class DateInput(forms.DateInput):
input_type = 'date'
class CategoryForm(forms.ModelForm):
class Meta:
model = Category
fields = ["name", "description"]
def __init__(self, *args, **kwargs):
super(CategoryForm, self).__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs["class"] = "form-control mb-2 p-1 col col-md-8 col-lg-6 rounded-lg rounded-sm"
if field_name == "description":
field.widget.attrs["placeholder"] = "Deskripsi"
field.widget.attrs["rows"] = "3"
else:
field.widget.attrs["placeholder"] = "Nama Kategori"
class VerificationSettingForm(forms.ModelForm):
class Meta:
model = VerificationSetting
fields = ["title", "description"]
def __init__(self, *args, **kwargs):
super(VerificationSettingForm, self).__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs["class"] = "form-control mb-2 p-1 col col-md-8 col-lg-6 rounded-lg rounded-sm"
if field_name == "description":
field.widget.attrs["rows"] = "3"
field.widget.attrs["placeholder"] = "Deskripsi"
else:
field.widget.attrs["placeholder"] = "Judul Verifikasi"
class RegistrasiAdminForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ["name", "instansi", "nik", "alamat", "email", "nomor_telpon"]
def __init__(self, *args, **kwargs):
super(RegistrasiAdminForm, self).__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs["class"] = "form-control"
if field_name == "password1" or field_name == "password2":
field.widget.attrs["type"] = "password"
self.fields["name"].required = True
self.fields["password"].required = True
self.fields["password2"].required = True
def clean_password(self):
password = self.data.get("password")
password2 = self.data.get("password2")
if password != password2:
raise forms.ValidationError("Password tidak sama")
return password
def clean_email(self):
email = self.cleaned_data.get("email")
if not User.objects.filter(email=email).exists():
return email
raise forms.ValidationError(
"Email sudah digunakan untuk mendaftar akun.")
class PeriodForm(forms.Form):
period = forms.ChoiceField(
choices=generate_periode_choices(), label="Periode", required=False)
start_date = forms.DateField(
widget=DateInput, label="Waktu mulai", required=False)
end_date = forms.DateField(
widget=DateInput, label="Waktu selesai", required=False)
categories = forms.MultipleChoiceField(
label="Kategori", required=False, choices=generate_category_choices)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs['class'] = 'form-control'
period_css_class = 'form-group col-md-4 mb-0'
self.helper = FormHelper()
self.helper.attrs["name"] = "filter-form"
self.helper.form_method = 'get'
self.helper.layout = Layout(
Row(
Column('period', css_class=period_css_class),
Column('start_date', css_class=period_css_class),
Column('end_date', css_class=period_css_class),
css_class='form-row'
),
InlineCheckboxes('categories'),
Row(
ButtonHolder(Submit('submit', 'Filter')),
ButtonHolder(Button('reset_form', 'Hapus filter'), css_class ="btn-warning")
)
)
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date is not None and end_date is None:
self.add_error("end_date",
"masukan waktu selesai")
if start_date is None and end_date is not None:
self.add_error("start_date",
"masukan waktu mulai")
if start_date is not None and end_date is not None and start_date > end_date:
self.add_error("end_date",
"waktu selesai sebelum waktu mulai")
class EditAdminStatusForm(forms.ModelForm):
is_active = forms.BooleanField(required=False)
class Meta:
model = User
fields = ["is_active"]
def __init__(self, *args, **kwargs):
super(EditAdminStatusForm, self).__init__(*args, **kwargs)
class EditKontributorStatusForm(forms.ModelForm):
is_active = forms.BooleanField(required=False)
class Meta:
model = User
fields = ["is_active"]
def __init__(self, *args, **kwargs):
super(EditKontributorStatusForm, self).__init__(*args, **kwargs)
# Generated by Django 3.0.3 on 2020-05-08 14:42
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='VerificationReport',
fields=[
('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='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)),
],
),
]
# 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'),
),
]
# 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),
),
]
# 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),
),
]
# 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)),
],
),
]
# 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),
),
]
# 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 = [
]
# 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(),
),
]