0.4.0
This commit is contained in:
parent
6b2c4996d5
commit
8e7b059ad3
97 changed files with 15077 additions and 6892 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -115,7 +115,7 @@ celerybeat-schedule
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
.env
|
*.env
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ stages:
|
||||||
- test
|
- test
|
||||||
- lint
|
- lint
|
||||||
- release
|
- release
|
||||||
- deploy
|
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||||
|
|
@ -17,9 +16,8 @@ variables:
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_COMMIT_REF_SLUG"
|
key: "$CI_COMMIT_REF_SLUG"
|
||||||
paths:
|
paths:
|
||||||
- .venv/
|
- env/
|
||||||
- .cache/pip
|
- .cache/pip
|
||||||
- .cache/poetry
|
|
||||||
- node_modules/
|
- node_modules/
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
|
@ -27,4 +25,3 @@ include:
|
||||||
- local: '/gitlab-ci/test.yml'
|
- local: '/gitlab-ci/test.yml'
|
||||||
- local: '/gitlab-ci/lint.yml'
|
- local: '/gitlab-ci/lint.yml'
|
||||||
- local: '/gitlab-ci/release.yml'
|
- local: '/gitlab-ci/release.yml'
|
||||||
- local: '/gitlab-ci/deploy.yml'
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
- Add Makefile & use `pip-tools` to generate dependencies
|
||||||
|
- Add `pyproject.toml`
|
||||||
|
- Update dependencies
|
||||||
|
- Update docker-compose setup
|
||||||
|
- Default to `newsreader.conf.docker` settings module
|
||||||
|
- Add scroll to top/bottom buttons
|
||||||
|
|
||||||
## 0.3.13.8
|
## 0.3.13.8
|
||||||
|
|
||||||
- Update dependencies
|
- Update dependencies
|
||||||
|
|
|
||||||
45
Makefile
Normal file
45
Makefile
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Note: run this file from within your virtualenv!
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Build dependencies
|
||||||
|
build:
|
||||||
|
pip-compile \
|
||||||
|
--resolver=backtracking \
|
||||||
|
--output-file=requirements/base.txt \
|
||||||
|
pyproject.toml
|
||||||
|
|
||||||
|
# testing
|
||||||
|
pip-compile \
|
||||||
|
--resolver=backtracking \
|
||||||
|
--extra=testing \
|
||||||
|
--output-file=requirements/testing.txt \
|
||||||
|
requirements/base.txt \
|
||||||
|
pyproject.toml
|
||||||
|
|
||||||
|
# development
|
||||||
|
pip-compile \
|
||||||
|
--resolver=backtracking \
|
||||||
|
--extra=testing \
|
||||||
|
--extra=development \
|
||||||
|
--output-file=requirements/development.txt \
|
||||||
|
requirements/base.txt \
|
||||||
|
requirements/testing.txt \
|
||||||
|
pyproject.toml
|
||||||
|
|
||||||
|
# ci
|
||||||
|
pip-compile \
|
||||||
|
--resolver=backtracking \
|
||||||
|
--extra=testing \
|
||||||
|
--extra=ci \
|
||||||
|
--output-file=requirements/ci.txt \
|
||||||
|
requirements/base.txt \
|
||||||
|
requirements/testing.txt \
|
||||||
|
pyproject.toml
|
||||||
|
|
||||||
|
# production
|
||||||
|
pip-compile \
|
||||||
|
--resolver=backtracking \
|
||||||
|
--extra=production \
|
||||||
|
--output-file=requirements/production.txt \
|
||||||
|
requirements/base.txt \
|
||||||
|
pyproject.toml
|
||||||
5
bin/docker-entrypoint.sh
Executable file
5
bin/docker-entrypoint.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
python /app/src/manage.py migrate
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
22
config/nginx/conf.d/local.conf
Normal file
22
config/nginx/conf.d/local.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
upstream gunicorn {
|
||||||
|
server django:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access_log;
|
||||||
|
error_log /var/log/nginx/error_log;
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
root /app;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://gunicorn;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_redirect off;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
docker-compose.development.yml
Normal file
34
docker-compose.development.yml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
version: "3.6"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
static-files:
|
||||||
|
node-modules:
|
||||||
|
|
||||||
|
services:
|
||||||
|
celery:
|
||||||
|
build:
|
||||||
|
target: development
|
||||||
|
volumes:
|
||||||
|
- ./src/:/app/src
|
||||||
|
|
||||||
|
django:
|
||||||
|
build:
|
||||||
|
target: development
|
||||||
|
command: python /app/src/manage.py runserver 0.0.0.0:8000
|
||||||
|
ports:
|
||||||
|
- "${DJANGO_PORT:-8000}:8000"
|
||||||
|
volumes:
|
||||||
|
- ./src:/app/src
|
||||||
|
- static-files:/app/src/newsreader/static
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
webpack:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./docker/webpack
|
||||||
|
command: npm run build:watch
|
||||||
|
volumes:
|
||||||
|
- ./src/:/app/src
|
||||||
|
- static-files:/app/src/newsreader/static
|
||||||
|
- node-modules:/app/node_modules
|
||||||
19
docker-compose.production.yml
Normal file
19
docker-compose.production.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
version: "3.6"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
logs:
|
||||||
|
static-files:
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:1.23
|
||||||
|
depends_on:
|
||||||
|
django:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
# Note that --env-file should be used to set these correctly
|
||||||
|
- "${NGINX_HTTP_PORT:-80}:80"
|
||||||
|
volumes:
|
||||||
|
- ./config/nginx/conf.d:/etc/nginx/conf.d
|
||||||
|
- logs:/var/log/nginx
|
||||||
|
- static-files:/app/static
|
||||||
|
|
@ -1,62 +1,102 @@
|
||||||
version: "3"
|
version: "3.6"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
logs:
|
||||||
|
media:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
static-files:
|
static-files:
|
||||||
node-modules:
|
|
||||||
|
x-db-env: &db-env
|
||||||
|
POSTGRES_HOST:
|
||||||
|
POSTGRES_PORT:
|
||||||
|
POSTGRES_DB:
|
||||||
|
POSTGRES_USER:
|
||||||
|
POSTGRES_PASSWORD:
|
||||||
|
|
||||||
|
x-django-env: &django-env
|
||||||
|
<<: *db-env
|
||||||
|
DJANGO_SECRET_KEY:
|
||||||
|
DJANGO_SETTINGS_MODULE:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
db:
|
db:
|
||||||
image: postgres
|
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: "newsreader"
|
<<: *db-env
|
||||||
POSTGRES_USER: "newsreader"
|
image: postgres:15
|
||||||
POSTGRES_PASSWORD: "newsreader"
|
healthcheck:
|
||||||
|
# Note that --env-file should be used to set these correctly
|
||||||
|
test: /usr/bin/pg_isready --username="${POSTGRES_USER}" --dbname="${POSTGRES_DB}"
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
volumes:
|
volumes:
|
||||||
- postgres-data:/var/lib/postgresql/data
|
- postgres-data:/var/lib/postgresql/data
|
||||||
|
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
image: rabbitmq:3.7
|
image: rabbitmq:3.12
|
||||||
|
|
||||||
memcached:
|
memcached:
|
||||||
image: memcached:1.6
|
image: memcached:1.6
|
||||||
ports:
|
|
||||||
- "11211:11211"
|
|
||||||
entrypoint:
|
entrypoint:
|
||||||
- memcached
|
- memcached
|
||||||
- -m 64
|
- -m 64
|
||||||
|
|
||||||
celery:
|
celery:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./docker/django
|
dockerfile: ./docker/django
|
||||||
command: celery worker -n worker1@%h -n worker2@%h --app newsreader --loglevel INFO --concurrency 2 --workdir /app/src/ --beat --scheduler django
|
target: production
|
||||||
|
args:
|
||||||
|
<<: *django-env
|
||||||
environment:
|
environment:
|
||||||
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker
|
<<: *django-env
|
||||||
|
command: |
|
||||||
|
celery --app newsreader
|
||||||
|
--workdir /app/src/
|
||||||
|
worker --loglevel INFO
|
||||||
|
--concurrency 2
|
||||||
|
--beat
|
||||||
|
--scheduler django
|
||||||
|
-n worker1@%h
|
||||||
|
-n worker2@%h
|
||||||
depends_on:
|
depends_on:
|
||||||
- rabbitmq
|
rabbitmq:
|
||||||
- memcached
|
condition: service_started
|
||||||
|
memcached:
|
||||||
|
condition: service_started
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
django:
|
||||||
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- logs:/app/logs
|
||||||
|
|
||||||
django:
|
django:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./docker/django
|
dockerfile: ./docker/django
|
||||||
command: python /app/src/manage.py runserver 0.0.0.0:8000
|
target: production
|
||||||
|
args:
|
||||||
|
<<: *django-env
|
||||||
environment:
|
environment:
|
||||||
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker
|
<<: *django-env
|
||||||
ports:
|
entrypoint: /app/bin/docker-entrypoint.sh
|
||||||
- "8000:8000"
|
command: |
|
||||||
|
gunicorn --bind 0.0.0.0:8000
|
||||||
|
--workers 3
|
||||||
|
--chdir /app/src/
|
||||||
|
newsreader.wsgi:application
|
||||||
|
healthcheck:
|
||||||
|
test: /usr/bin/curl --fail http://django:8000 || exit 1
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
memcached:
|
||||||
- memcached
|
condition: service_started
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- logs:/app/logs
|
||||||
- static-files:/app/src/newsreader/static
|
- media:/app/media
|
||||||
stdin_open: true
|
- static-files:/app/static
|
||||||
tty: true
|
|
||||||
webpack:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./docker/webpack
|
|
||||||
command: npm run build:watch
|
|
||||||
volumes:
|
|
||||||
- .:/app
|
|
||||||
- static-files:/app/src/newsreader/static
|
|
||||||
- node-modules:/app/node_modules
|
|
||||||
|
|
|
||||||
108
docker/django
108
docker/django
|
|
@ -1,10 +1,108 @@
|
||||||
FROM python:3.7-buster
|
# stage 1
|
||||||
|
FROM python:3.9-bullseye as backend
|
||||||
|
|
||||||
RUN pip install poetry
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
vim \
|
||||||
|
curl \
|
||||||
|
gettext \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY poetry.lock pyproject.toml /app/
|
RUN mkdir /app/src
|
||||||
|
RUN mkdir /app/logs
|
||||||
|
RUN mkdir /app/media
|
||||||
|
|
||||||
RUN poetry config virtualenvs.create false && poetry install --no-interaction --extras sentry
|
COPY ./requirements /app/requirements
|
||||||
|
|
||||||
COPY . /app/
|
RUN pip install -r requirements/base.txt
|
||||||
|
|
||||||
|
|
||||||
|
# stage 2
|
||||||
|
FROM node:16-bullseye AS frontend-build
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ./*.json ./*.js ./.babelrc /app/
|
||||||
|
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY ./src /app/src
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
|
||||||
|
# stage 3
|
||||||
|
FROM python:3.9-bullseye as production
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
postgresql-client \
|
||||||
|
vim \
|
||||||
|
curl \
|
||||||
|
gettext \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN mkdir /app/logs
|
||||||
|
RUN mkdir /app/media
|
||||||
|
RUN mkdir /app/bin
|
||||||
|
|
||||||
|
COPY --from=backend /usr/local/lib/python3.9 /usr/local/lib/python3.9
|
||||||
|
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
|
||||||
|
|
||||||
|
COPY ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh
|
||||||
|
|
||||||
|
COPY --from=frontend-build /app/src/newsreader/static /app/src/newsreader/static
|
||||||
|
|
||||||
|
COPY ./src /app/src
|
||||||
|
|
||||||
|
COPY ./requirements /app/requirements
|
||||||
|
|
||||||
|
RUN pip install -r requirements/production.txt
|
||||||
|
|
||||||
|
RUN useradd -M -u 1000 newsreader
|
||||||
|
RUN chown -R newsreader:newsreader /app
|
||||||
|
|
||||||
|
USER newsreader
|
||||||
|
|
||||||
|
ARG POSTGRES_HOST
|
||||||
|
ARG POSTGRES_PORT
|
||||||
|
ARG POSTGRES_DB
|
||||||
|
ARG POSTGRES_USER
|
||||||
|
ARG POSTGRES_PASSWORD
|
||||||
|
ARG DJANGO_SECRET_KEY
|
||||||
|
ARG DJANGO_SETTINGS_MODULE
|
||||||
|
|
||||||
|
RUN python src/manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
|
||||||
|
# (optional) stage 4
|
||||||
|
FROM python:3.9-bullseye as development
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
vim \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN mkdir /app/logs
|
||||||
|
RUN mkdir /app/media
|
||||||
|
RUN mkdir /app/bin
|
||||||
|
|
||||||
|
COPY ./requirements /app/requirements
|
||||||
|
COPY ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh
|
||||||
|
COPY --from=backend /usr/local/lib/python3.9 /usr/local/lib/python3.9
|
||||||
|
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
|
||||||
|
COPY --from=backend /app/src/ /app/src/
|
||||||
|
|
||||||
|
RUN pip install -r requirements/development.txt
|
||||||
|
|
||||||
|
RUN useradd -M -u 1000 newsreader
|
||||||
|
RUN chown -R newsreader:newsreader /app
|
||||||
|
|
||||||
|
USER newsreader
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
FROM node:12
|
FROM node:16-bullseye
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
RUN mkdir /app/src
|
||||||
|
|
||||||
COPY package.json package-lock.json /app/
|
COPY package*.json webpack.*.js .babelrc /app/
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
COPY . /app/
|
COPY ./src /app/src
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
static:
|
static:
|
||||||
stage: build
|
stage: build
|
||||||
image: node:12
|
image: node:16-bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- npm install
|
- npm install
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
deploy:
|
|
||||||
stage: deploy
|
|
||||||
image: python:3.7
|
|
||||||
environment:
|
|
||||||
name: production
|
|
||||||
url: rss.fudiggity.nl
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_TAG
|
|
||||||
before_script:
|
|
||||||
- pip install ansible --quiet
|
|
||||||
- git clone https://git.fudiggity.nl/ansible/newsreader.git deployment --branch master
|
|
||||||
- cd deployment
|
|
||||||
- ansible-galaxy install -r requirements.yml
|
|
||||||
- mkdir /root/.ssh && echo "$DEPLOY_HOST_KEY" > /root/.ssh/known_hosts
|
|
||||||
- echo "$DEPLOY_KEY" > deploy_key && chmod 0600 deploy_key
|
|
||||||
- echo "$VAULT_PASSWORD" > vault
|
|
||||||
script:
|
|
||||||
- >
|
|
||||||
ansible-playbook playbook.yml
|
|
||||||
--private-key deploy_key
|
|
||||||
--vault-password-file vault
|
|
||||||
--extra-vars "app_branch=$CI_COMMIT_TAG"
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
python-linting:
|
python-linting:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: python:3.7
|
image: python:3.9-bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- pip install poetry --quiet
|
- pip install -r requirements/ci.txt
|
||||||
- poetry config cache-dir ~/.cache/poetry
|
|
||||||
- poetry config virtualenvs.in-project true
|
|
||||||
- poetry install --no-interaction --quiet
|
|
||||||
script:
|
script:
|
||||||
- poetry run isort src/ --check-only --recursive
|
- isort src/ --check-only
|
||||||
- poetry run black src/ --line-length 88 --check
|
- black src/ --line-length 88 --check
|
||||||
- poetry run autoflake src/ --check --recursive --remove-all-unused-imports --ignore-init-module-imports
|
- autoflake src/ --check --recursive --remove-all-unused-imports --ignore-init-module-imports
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- development
|
- development
|
||||||
|
|
@ -17,7 +14,7 @@ python-linting:
|
||||||
|
|
||||||
javascript-linting:
|
javascript-linting:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: node:12
|
image: node:16-bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- npm install
|
- npm install
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,17 @@ python-tests:
|
||||||
stage: test
|
stage: test
|
||||||
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
|
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
|
||||||
services:
|
services:
|
||||||
- postgres:11
|
- postgres:15
|
||||||
- memcached:1.5.22
|
- memcached:1.5.22
|
||||||
image: python:3.7
|
image: python:3.9-bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- pip install poetry --quiet
|
- pip install -r requirements/ci.txt
|
||||||
- poetry config cache-dir .cache/poetry
|
|
||||||
- poetry config virtualenvs.in-project true
|
|
||||||
- poetry install --no-interaction --quiet --extras sentry
|
|
||||||
script:
|
script:
|
||||||
- poetry run coverage run src/manage.py test newsreader
|
- coverage run ./src/manage.py test newsreader
|
||||||
- poetry run coverage report
|
|
||||||
|
|
||||||
javascript-tests:
|
javascript-tests:
|
||||||
stage: test
|
stage: test
|
||||||
image: node:12
|
image: node:16-bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- npm install
|
- npm install
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
13348
package-lock.json
generated
13348
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -48,11 +48,11 @@
|
||||||
"jest": "^24.9.0",
|
"jest": "^24.9.0",
|
||||||
"mini-css-extract-plugin": "^0.9.0",
|
"mini-css-extract-plugin": "^0.9.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"node-sass": "^4.14.1",
|
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"react": "^16.14.0",
|
"react": "^16.14.0",
|
||||||
"react-dom": "^16.14.0",
|
"react-dom": "^16.14.0",
|
||||||
"redux-mock-store": "^1.5.4",
|
"redux-mock-store": "^1.5.4",
|
||||||
|
"sass": "^1.52.1",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"style-loader": "^1.3.0",
|
"style-loader": "^1.3.0",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
|
|
|
||||||
1298
poetry.lock
generated
1298
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,46 +1,50 @@
|
||||||
[tool.poetry]
|
[project]
|
||||||
name = "newsreader"
|
name = 'newsreader'
|
||||||
version = "0.3.13.8"
|
version = '0.4.0.0'
|
||||||
description = "Webapplication for reading RSS feeds"
|
authors = [{name = 'Sonny', email= 'sonnyba871@gmail.com'}]
|
||||||
authors = ["Sonny <sonnyba871@gmail.com>"]
|
license = {text = 'GPL-3.0'}
|
||||||
license = "GPL-3.0"
|
requires-python = '>=3.11'
|
||||||
|
dependencies = [
|
||||||
|
'django~=3.2',
|
||||||
|
'celery~=5.0',
|
||||||
|
'psycopg2',
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
'django-axes',
|
||||||
python = "^3.7"
|
'django-celery-beat~=2.5.0',
|
||||||
bleach = "^3.1.4"
|
'django-registration-redux~=2.7',
|
||||||
Django = "^3.2"
|
'django-rest-framework',
|
||||||
celery = "^4.4.2"
|
'drf-yasg',
|
||||||
beautifulsoup4 = "^4.9.0"
|
|
||||||
django-axes = "^5.3.1"
|
|
||||||
django-celery-beat = "^2.0.0"
|
|
||||||
djangorestframework = "^3.11.0"
|
|
||||||
drf-yasg = "^1.17.1"
|
|
||||||
django-registration-redux = "^2.7"
|
|
||||||
lxml = "^4.5.0"
|
|
||||||
feedparser = "^5.2.1"
|
|
||||||
python-memcached = "^1.59"
|
|
||||||
requests = "^2.23.0"
|
|
||||||
psycopg2-binary = "^2.8.5"
|
|
||||||
gunicorn = "^20.0.4"
|
|
||||||
python-dotenv = "^0.12.0"
|
|
||||||
sentry-sdk = {version = "^1.0.0", optional = true}
|
|
||||||
ftfy = "^5.8"
|
|
||||||
requests_oauthlib = "^1.3.0"
|
|
||||||
|
|
||||||
[tool.poetry.extras]
|
'python-memcached',
|
||||||
sentry = ["sentry_sdk"]
|
'python-dotenv~=0.12',
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
'ftfy~=5.8',
|
||||||
factory-boy = "^2.12.0"
|
|
||||||
freezegun = "^0.3.15"
|
|
||||||
django-debug-toolbar = "^2.2"
|
|
||||||
django-extensions = "^2.2.9"
|
|
||||||
black = "19.3b0"
|
|
||||||
isort = "4.3.21"
|
|
||||||
autoflake = "1.3.1"
|
|
||||||
tblib = "1.6.0"
|
|
||||||
coverage = "^5.1"
|
|
||||||
|
|
||||||
[build-system]
|
'requests',
|
||||||
requires = ["poetry>=1.0.10"]
|
'requests_oauthlib',
|
||||||
build-backend = "poetry.masonry.api"
|
|
||||||
|
'feedparser',
|
||||||
|
'bleach',
|
||||||
|
'beautifulsoup4',
|
||||||
|
'lxml'
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
testing = [
|
||||||
|
'factory-boy',
|
||||||
|
'freezegun',
|
||||||
|
'black',
|
||||||
|
'isort',
|
||||||
|
'autoflake',
|
||||||
|
'tblib',
|
||||||
|
]
|
||||||
|
|
||||||
|
development = [
|
||||||
|
'pip-tools>=6.13.0',
|
||||||
|
'django-debug-toolbar',
|
||||||
|
'django-extensions',
|
||||||
|
]
|
||||||
|
|
||||||
|
ci = ['coverage>=5.3.1']
|
||||||
|
|
||||||
|
production = ['gunicorn~=20.0', 'sentry-sdk~=1.0']
|
||||||
|
|
|
||||||
143
requirements/base.txt
Normal file
143
requirements/base.txt
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.9
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile --output-file=requirements/base.txt --resolver=backtracking pyproject.toml
|
||||||
|
#
|
||||||
|
amqp==5.1.1
|
||||||
|
# via kombu
|
||||||
|
asgiref==3.7.2
|
||||||
|
# via django
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
billiard==4.1.0
|
||||||
|
# via celery
|
||||||
|
bleach==6.0.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
celery==5.3.1
|
||||||
|
# via
|
||||||
|
# django-celery-beat
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
certifi==2023.5.7
|
||||||
|
# via requests
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
# via requests
|
||||||
|
click==8.1.3
|
||||||
|
# via
|
||||||
|
# celery
|
||||||
|
# click-didyoumean
|
||||||
|
# click-plugins
|
||||||
|
# click-repl
|
||||||
|
click-didyoumean==0.3.0
|
||||||
|
# via celery
|
||||||
|
click-plugins==1.1.1
|
||||||
|
# via celery
|
||||||
|
click-repl==0.3.0
|
||||||
|
# via celery
|
||||||
|
cron-descriptor==1.4.0
|
||||||
|
# via django-celery-beat
|
||||||
|
django==3.2.19
|
||||||
|
# via
|
||||||
|
# django-axes
|
||||||
|
# django-celery-beat
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-axes==6.0.4
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-celery-beat==2.5.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-registration-redux==2.12
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-rest-framework==0.1.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-timezone-field==5.1
|
||||||
|
# via django-celery-beat
|
||||||
|
djangorestframework==3.14.0
|
||||||
|
# via
|
||||||
|
# django-rest-framework
|
||||||
|
# drf-yasg
|
||||||
|
drf-yasg==1.21.6
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
feedparser==6.0.10
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
ftfy==5.9
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
idna==3.4
|
||||||
|
# via requests
|
||||||
|
inflection==0.5.1
|
||||||
|
# via drf-yasg
|
||||||
|
kombu==5.3.1
|
||||||
|
# via celery
|
||||||
|
lxml==4.9.2
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
oauthlib==3.2.2
|
||||||
|
# via requests-oauthlib
|
||||||
|
packaging==23.1
|
||||||
|
# via drf-yasg
|
||||||
|
prompt-toolkit==3.0.38
|
||||||
|
# via click-repl
|
||||||
|
psycopg2==2.9.6
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
python-crontab==2.7.1
|
||||||
|
# via django-celery-beat
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
# via
|
||||||
|
# celery
|
||||||
|
# python-crontab
|
||||||
|
python-dotenv==0.21.1
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
python-memcached==1.59
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
pytz==2023.3
|
||||||
|
# via
|
||||||
|
# django
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
pyyaml==6.0
|
||||||
|
# via drf-yasg
|
||||||
|
requests==2.31.0
|
||||||
|
# via
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
# requests-oauthlib
|
||||||
|
requests-oauthlib==1.3.1
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
# via feedparser
|
||||||
|
six==1.16.0
|
||||||
|
# via
|
||||||
|
# bleach
|
||||||
|
# python-dateutil
|
||||||
|
# python-memcached
|
||||||
|
soupsieve==2.4.1
|
||||||
|
# via beautifulsoup4
|
||||||
|
sqlparse==0.4.4
|
||||||
|
# via django
|
||||||
|
typing-extensions==4.6.3
|
||||||
|
# via
|
||||||
|
# asgiref
|
||||||
|
# kombu
|
||||||
|
tzdata==2023.3
|
||||||
|
# via
|
||||||
|
# celery
|
||||||
|
# django-celery-beat
|
||||||
|
uritemplate==4.1.1
|
||||||
|
# via drf-yasg
|
||||||
|
urllib3==2.0.3
|
||||||
|
# via requests
|
||||||
|
vine==5.0.0
|
||||||
|
# via
|
||||||
|
# amqp
|
||||||
|
# celery
|
||||||
|
# kombu
|
||||||
|
wcwidth==0.2.6
|
||||||
|
# via
|
||||||
|
# ftfy
|
||||||
|
# prompt-toolkit
|
||||||
|
webencodings==0.5.1
|
||||||
|
# via bleach
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
# setuptools
|
||||||
320
requirements/ci.txt
Normal file
320
requirements/ci.txt
Normal file
|
|
@ -0,0 +1,320 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.9
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile --extra=ci --extra=testing --output-file=requirements/ci.txt --resolver=backtracking pyproject.toml requirements/base.txt requirements/testing.txt
|
||||||
|
#
|
||||||
|
amqp==5.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# kombu
|
||||||
|
asgiref==3.7.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
autoflake==2.2.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
billiard==4.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
black==23.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
bleach==6.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
celery==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
certifi==2023.5.7
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
click==8.1.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
# celery
|
||||||
|
# click-didyoumean
|
||||||
|
# click-plugins
|
||||||
|
# click-repl
|
||||||
|
click-didyoumean==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
click-plugins==1.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
click-repl==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
coverage==7.2.7
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
cron-descriptor==1.4.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
django==3.2.19
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-axes
|
||||||
|
# django-celery-beat
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-axes==6.0.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-celery-beat==2.5.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-registration-redux==2.12
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-rest-framework==0.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-timezone-field==5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
djangorestframework==3.14.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-rest-framework
|
||||||
|
# drf-yasg
|
||||||
|
drf-yasg==1.21.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
factory-boy==3.2.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
faker==18.11.2
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# factory-boy
|
||||||
|
feedparser==6.0.10
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
freezegun==1.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
ftfy==5.9
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
idna==3.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
inflection==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
isort==5.12.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
kombu==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
lxml==4.9.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
oauthlib==3.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests-oauthlib
|
||||||
|
packaging==23.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
# drf-yasg
|
||||||
|
pathspec==0.11.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
platformdirs==3.8.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
prompt-toolkit==3.0.38
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# click-repl
|
||||||
|
psycopg2==2.9.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pyflakes==3.0.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# autoflake
|
||||||
|
python-crontab==2.7.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
# faker
|
||||||
|
# freezegun
|
||||||
|
# python-crontab
|
||||||
|
python-dotenv==0.21.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
python-memcached==1.59
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pytz==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
pyyaml==6.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
requests==2.31.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
# requests-oauthlib
|
||||||
|
requests-oauthlib==1.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# feedparser
|
||||||
|
six==1.16.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# bleach
|
||||||
|
# python-dateutil
|
||||||
|
# python-memcached
|
||||||
|
soupsieve==2.4.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# beautifulsoup4
|
||||||
|
sqlparse==0.4.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
tblib==2.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
tomli==2.0.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# autoflake
|
||||||
|
# black
|
||||||
|
typing-extensions==4.6.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# asgiref
|
||||||
|
# black
|
||||||
|
# kombu
|
||||||
|
tzdata==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
# django-celery-beat
|
||||||
|
uritemplate==4.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
urllib3==2.0.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
vine==5.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# amqp
|
||||||
|
# celery
|
||||||
|
# kombu
|
||||||
|
wcwidth==0.2.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# ftfy
|
||||||
|
# prompt-toolkit
|
||||||
|
webencodings==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# bleach
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
# setuptools
|
||||||
338
requirements/development.txt
Normal file
338
requirements/development.txt
Normal file
|
|
@ -0,0 +1,338 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.9
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile --extra=development --extra=testing --output-file=requirements/development.txt --resolver=backtracking pyproject.toml requirements/base.txt requirements/testing.txt
|
||||||
|
#
|
||||||
|
amqp==5.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# kombu
|
||||||
|
asgiref==3.7.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
autoflake==2.2.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
billiard==4.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
black==23.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
bleach==6.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
build==0.10.0
|
||||||
|
# via pip-tools
|
||||||
|
celery==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
certifi==2023.5.7
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
click==8.1.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
# celery
|
||||||
|
# click-didyoumean
|
||||||
|
# click-plugins
|
||||||
|
# click-repl
|
||||||
|
# pip-tools
|
||||||
|
click-didyoumean==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
click-plugins==1.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
click-repl==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
cron-descriptor==1.4.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
django==3.2.19
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-axes
|
||||||
|
# django-celery-beat
|
||||||
|
# django-debug-toolbar
|
||||||
|
# django-extensions
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-axes==6.0.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-celery-beat==2.5.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-debug-toolbar==4.1.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-extensions==3.2.3
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
django-registration-redux==2.12
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-rest-framework==0.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-timezone-field==5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
djangorestframework==3.14.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-rest-framework
|
||||||
|
# drf-yasg
|
||||||
|
drf-yasg==1.21.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
factory-boy==3.2.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
faker==18.11.2
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# factory-boy
|
||||||
|
feedparser==6.0.10
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
freezegun==1.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
ftfy==5.9
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
idna==3.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
inflection==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
isort==5.12.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
kombu==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
lxml==4.9.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
oauthlib==3.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests-oauthlib
|
||||||
|
packaging==23.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
# build
|
||||||
|
# drf-yasg
|
||||||
|
pathspec==0.11.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
pip-tools==6.13.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
platformdirs==3.8.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# black
|
||||||
|
prompt-toolkit==3.0.38
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# click-repl
|
||||||
|
psycopg2==2.9.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pyflakes==3.0.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# autoflake
|
||||||
|
pyproject-hooks==1.0.0
|
||||||
|
# via build
|
||||||
|
python-crontab==2.7.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django-celery-beat
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
# faker
|
||||||
|
# freezegun
|
||||||
|
# python-crontab
|
||||||
|
python-dotenv==0.21.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
python-memcached==1.59
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pytz==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
pyyaml==6.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
requests==2.31.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
# requests-oauthlib
|
||||||
|
requests-oauthlib==1.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# feedparser
|
||||||
|
six==1.16.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# bleach
|
||||||
|
# python-dateutil
|
||||||
|
# python-memcached
|
||||||
|
soupsieve==2.4.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# beautifulsoup4
|
||||||
|
sqlparse==0.4.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# django
|
||||||
|
# django-debug-toolbar
|
||||||
|
tblib==2.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
tomli==2.0.1
|
||||||
|
# via
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# autoflake
|
||||||
|
# black
|
||||||
|
# build
|
||||||
|
# pyproject-hooks
|
||||||
|
typing-extensions==4.6.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# asgiref
|
||||||
|
# black
|
||||||
|
# kombu
|
||||||
|
tzdata==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# celery
|
||||||
|
# django-celery-beat
|
||||||
|
uritemplate==4.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# drf-yasg
|
||||||
|
urllib3==2.0.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# requests
|
||||||
|
vine==5.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# amqp
|
||||||
|
# celery
|
||||||
|
# kombu
|
||||||
|
wcwidth==0.2.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# ftfy
|
||||||
|
# prompt-toolkit
|
||||||
|
webencodings==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# -r requirements/testing.txt
|
||||||
|
# bleach
|
||||||
|
wheel==0.40.0
|
||||||
|
# via pip-tools
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
# pip
|
||||||
|
# setuptools
|
||||||
237
requirements/production.txt
Normal file
237
requirements/production.txt
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.9
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile --extra=production --output-file=requirements/production.txt --resolver=backtracking pyproject.toml requirements/base.txt
|
||||||
|
#
|
||||||
|
amqp==5.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# kombu
|
||||||
|
asgiref==3.7.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
billiard==4.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
bleach==6.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
celery==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
certifi==2023.5.7
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
# sentry-sdk
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
click==8.1.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
# click-didyoumean
|
||||||
|
# click-plugins
|
||||||
|
# click-repl
|
||||||
|
click-didyoumean==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
click-plugins==1.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
click-repl==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
cron-descriptor==1.4.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
django==3.2.19
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-axes
|
||||||
|
# django-celery-beat
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-axes==6.0.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-celery-beat==2.5.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-registration-redux==2.12
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-rest-framework==0.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-timezone-field==5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
djangorestframework==3.14.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-rest-framework
|
||||||
|
# drf-yasg
|
||||||
|
drf-yasg==1.21.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
feedparser==6.0.10
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
ftfy==5.9
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
gunicorn==20.1.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
idna==3.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
inflection==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
kombu==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
lxml==4.9.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
oauthlib==3.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests-oauthlib
|
||||||
|
packaging==23.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
prompt-toolkit==3.0.38
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# click-repl
|
||||||
|
psycopg2==2.9.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
python-crontab==2.7.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
# python-crontab
|
||||||
|
python-dotenv==0.21.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
python-memcached==1.59
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pytz==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
pyyaml==6.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
requests==2.31.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
# requests-oauthlib
|
||||||
|
requests-oauthlib==1.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
sentry-sdk==1.26.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# feedparser
|
||||||
|
six==1.16.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# bleach
|
||||||
|
# python-dateutil
|
||||||
|
# python-memcached
|
||||||
|
soupsieve==2.4.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# beautifulsoup4
|
||||||
|
sqlparse==0.4.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
typing-extensions==4.6.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# asgiref
|
||||||
|
# kombu
|
||||||
|
tzdata==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
# django-celery-beat
|
||||||
|
uritemplate==4.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
urllib3==2.0.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
# sentry-sdk
|
||||||
|
vine==5.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# amqp
|
||||||
|
# celery
|
||||||
|
# kombu
|
||||||
|
wcwidth==0.2.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# ftfy
|
||||||
|
# prompt-toolkit
|
||||||
|
webencodings==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# bleach
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
# setuptools
|
||||||
262
requirements/testing.txt
Normal file
262
requirements/testing.txt
Normal file
|
|
@ -0,0 +1,262 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.9
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile --extra=testing --output-file=requirements/testing.txt --resolver=backtracking pyproject.toml requirements/base.txt
|
||||||
|
#
|
||||||
|
amqp==5.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# kombu
|
||||||
|
asgiref==3.7.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
autoflake==2.2.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
billiard==4.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
black==23.3.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
bleach==6.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
celery==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
certifi==2023.5.7
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
click==8.1.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# black
|
||||||
|
# celery
|
||||||
|
# click-didyoumean
|
||||||
|
# click-plugins
|
||||||
|
# click-repl
|
||||||
|
click-didyoumean==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
click-plugins==1.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
click-repl==0.3.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
cron-descriptor==1.4.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
django==3.2.19
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-axes
|
||||||
|
# django-celery-beat
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-axes==6.0.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-celery-beat==2.5.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-registration-redux==2.12
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-rest-framework==0.1.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
django-timezone-field==5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
djangorestframework==3.14.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-rest-framework
|
||||||
|
# drf-yasg
|
||||||
|
drf-yasg==1.21.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
factory-boy==3.2.1
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
faker==18.11.2
|
||||||
|
# via factory-boy
|
||||||
|
feedparser==6.0.10
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
freezegun==1.2.2
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
ftfy==5.9
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
idna==3.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
inflection==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
isort==5.12.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
kombu==5.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
lxml==4.9.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
# via black
|
||||||
|
oauthlib==3.2.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests-oauthlib
|
||||||
|
packaging==23.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# black
|
||||||
|
# drf-yasg
|
||||||
|
pathspec==0.11.1
|
||||||
|
# via black
|
||||||
|
platformdirs==3.8.0
|
||||||
|
# via black
|
||||||
|
prompt-toolkit==3.0.38
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# click-repl
|
||||||
|
psycopg2==2.9.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pyflakes==3.0.1
|
||||||
|
# via autoflake
|
||||||
|
python-crontab==2.7.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django-celery-beat
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
# faker
|
||||||
|
# freezegun
|
||||||
|
# python-crontab
|
||||||
|
python-dotenv==0.21.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
python-memcached==1.59
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
pytz==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
# django-timezone-field
|
||||||
|
# djangorestframework
|
||||||
|
# drf-yasg
|
||||||
|
pyyaml==6.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
requests==2.31.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
# requests-oauthlib
|
||||||
|
requests-oauthlib==1.3.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# newsreader (pyproject.toml)
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# feedparser
|
||||||
|
six==1.16.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# bleach
|
||||||
|
# python-dateutil
|
||||||
|
# python-memcached
|
||||||
|
soupsieve==2.4.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# beautifulsoup4
|
||||||
|
sqlparse==0.4.4
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# django
|
||||||
|
tblib==2.0.0
|
||||||
|
# via newsreader (pyproject.toml)
|
||||||
|
tomli==2.0.1
|
||||||
|
# via
|
||||||
|
# autoflake
|
||||||
|
# black
|
||||||
|
typing-extensions==4.6.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# asgiref
|
||||||
|
# black
|
||||||
|
# kombu
|
||||||
|
tzdata==2023.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# celery
|
||||||
|
# django-celery-beat
|
||||||
|
uritemplate==4.1.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# drf-yasg
|
||||||
|
urllib3==2.0.3
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# requests
|
||||||
|
vine==5.0.0
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# amqp
|
||||||
|
# celery
|
||||||
|
# kombu
|
||||||
|
wcwidth==0.2.6
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# ftfy
|
||||||
|
# prompt-toolkit
|
||||||
|
webencodings==0.5.1
|
||||||
|
# via
|
||||||
|
# -r requirements/base.txt
|
||||||
|
# bleach
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
# setuptools
|
||||||
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "newsreader.conf.dev")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "newsreader.conf.docker")
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0001_initial")]
|
dependencies = [("accounts", "0001_initial")]
|
||||||
|
|
||||||
operations = [migrations.RemoveField(model_name="user", name="username")]
|
operations = [migrations.RemoveField(model_name="user", name="username")]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import newsreader.accounts.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0002_remove_user_username")]
|
dependencies = [("accounts", "0002_remove_user_username")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0003_auto_20190714_1417")]
|
dependencies = [("accounts", "0003_auto_20190714_1417")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0004_auto_20190714_1501")]
|
dependencies = [("accounts", "0004_auto_20190714_1501")]
|
||||||
|
|
||||||
operations = [migrations.RemoveField(model_name="user", name="task_interval")]
|
operations = [migrations.RemoveField(model_name="user", name="task_interval")]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0005_remove_user_task_interval")]
|
dependencies = [("accounts", "0005_remove_user_task_interval")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0006_auto_20191116_1253")]
|
dependencies = [("accounts", "0006_auto_20191116_1253")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ def update_task_name(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0007_auto_20191116_1255")]
|
dependencies = [("accounts", "0007_auto_20191116_1255")]
|
||||||
|
|
||||||
operations = [migrations.RunPython(update_task_name)]
|
operations = [migrations.RunPython(update_task_name)]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("django_celery_beat", "0012_periodictask_expire_seconds"),
|
("django_celery_beat", "0012_periodictask_expire_seconds"),
|
||||||
("accounts", "0008_auto_20200422_2243"),
|
("accounts", "0008_auto_20200422_2243"),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0009_auto_20200524_1218")]
|
dependencies = [("accounts", "0009_auto_20200524_1218")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0010_auto_20200603_2230")]
|
dependencies = [("accounts", "0010_auto_20200603_2230")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0011_auto_20200913_2101")]
|
dependencies = [("accounts", "0011_auto_20200913_2101")]
|
||||||
|
|
||||||
operations = [migrations.RemoveField(model_name="user", name="task")]
|
operations = [migrations.RemoveField(model_name="user", name="task")]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0012_remove_user_task")]
|
dependencies = [("accounts", "0012_remove_user_task")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0013_user_auto_mark_read")]
|
dependencies = [("accounts", "0013_user_auto_mark_read")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0014_auto_20201218_2216")]
|
dependencies = [("accounts", "0014_auto_20201218_2216")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounts", "0015_auto_20201219_1330")]
|
dependencies = [("accounts", "0015_auto_20201219_1330")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
from django.contrib.auth import views as django_views
|
from django.contrib.auth import views as django_views
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
from newsreader.news.collection.reddit import (
|
|
||||||
get_reddit_access_token,
|
|
||||||
get_reddit_authorization_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# PasswordResetView sends the mail
|
# PasswordResetView sends the mail
|
||||||
# PasswordResetDoneView shows a success message for the above
|
# PasswordResetDoneView shows a success message for the above
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,6 @@ from django.views.generic import TemplateView
|
||||||
|
|
||||||
from registration.backends.default import views as registration_views
|
from registration.backends.default import views as registration_views
|
||||||
|
|
||||||
from newsreader.news.collection.reddit import (
|
|
||||||
get_reddit_access_token,
|
|
||||||
get_reddit_authorization_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# RegistrationView shows a registration form and sends the email
|
# RegistrationView shows a registration form and sends the email
|
||||||
# RegistrationCompleteView shows after filling in the registration form
|
# RegistrationCompleteView shows after filling in the registration form
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,6 @@ from django.views.generic.edit import FormView, ModelFormMixin
|
||||||
|
|
||||||
from newsreader.accounts.forms import UserSettingsForm
|
from newsreader.accounts.forms import UserSettingsForm
|
||||||
from newsreader.accounts.models import User
|
from newsreader.accounts.models import User
|
||||||
from newsreader.news.collection.reddit import (
|
|
||||||
get_reddit_access_token,
|
|
||||||
get_reddit_authorization_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsView(ModelFormMixin, FormView):
|
class SettingsView(ModelFormMixin, FormView):
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import os
|
||||||
from celery import Celery
|
from celery import Celery
|
||||||
|
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "newsreader.conf.dev")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "newsreader.conf.docker")
|
||||||
|
|
||||||
app = Celery("newsreader")
|
app = Celery("newsreader")
|
||||||
app.config_from_object("django.conf:settings", namespace="CELERY")
|
app.config_from_object("django.conf:settings", namespace="CELERY")
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ DJANGO_PROJECT_DIR = os.path.join(BASE_DIR, "src", "newsreader")
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||||
# SECURITY WARNING: don"t run with debug turned on in production!
|
# SECURITY WARNING: don"t run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = False
|
||||||
|
|
||||||
ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
|
ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
|
||||||
INTERNAL_IPS = ["127.0.0.1", "localhost"]
|
INTERNAL_IPS = ["127.0.0.1", "localhost"]
|
||||||
|
|
@ -50,6 +50,8 @@ INSTALLED_APPS = [
|
||||||
"newsreader.news.collection",
|
"newsreader.news.collection",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
AUTHENTICATION_BACKENDS = [
|
||||||
"axes.backends.AxesBackend",
|
"axes.backends.AxesBackend",
|
||||||
"django.contrib.auth.backends.ModelBackend",
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
|
|
@ -93,10 +95,11 @@ WSGI_APPLICATION = "newsreader.wsgi.application"
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
"default": {
|
"default": {
|
||||||
"ENGINE": "django.db.backends.postgresql",
|
"ENGINE": "django.db.backends.postgresql",
|
||||||
"HOST": os.environ.get("POSTGRES_HOST", ""),
|
"HOST": os.environ["POSTGRES_HOST"],
|
||||||
"NAME": os.environ.get("POSTGRES_NAME", "newsreader"),
|
"PORT": os.environ["POSTGRES_PORT"],
|
||||||
"USER": os.environ.get("POSTGRES_USER"),
|
"NAME": os.environ["POSTGRES_DB"],
|
||||||
"PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
|
"USER": os.environ["POSTGRES_USER"],
|
||||||
|
"PASSWORD": os.environ["POSTGRES_PASSWORD"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,11 +108,11 @@ DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
||||||
"LOCATION": "localhost:11211",
|
"LOCATION": "memcached:11211",
|
||||||
},
|
},
|
||||||
"axes": {
|
"axes": {
|
||||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
||||||
"LOCATION": "localhost:11211",
|
"LOCATION": "memcached:11211",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,43 +131,43 @@ LOGGING = {
|
||||||
"format": "[{server_time}] {message}",
|
"format": "[{server_time}] {message}",
|
||||||
"style": "{",
|
"style": "{",
|
||||||
},
|
},
|
||||||
"syslog": {
|
|
||||||
"class": "logging.Formatter",
|
|
||||||
"format": "[newsreader] {message}",
|
|
||||||
"style": "{",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"handlers": {
|
"handlers": {
|
||||||
"console": {
|
"console": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"filters": ["require_debug_true"],
|
|
||||||
"class": "logging.StreamHandler",
|
"class": "logging.StreamHandler",
|
||||||
"formatter": "timestamped",
|
"formatter": "timestamped",
|
||||||
},
|
},
|
||||||
|
"file": {
|
||||||
|
"level": "DEBUG",
|
||||||
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
|
"filename": BASE_DIR / "logs" / "newsreader.log",
|
||||||
|
"backupCount": 5,
|
||||||
|
"maxBytes": 50000000, # 50 mB
|
||||||
|
"formatter": "timestamped",
|
||||||
|
},
|
||||||
"celery": {
|
"celery": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"filters": ["require_debug_false"],
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
"class": "logging.handlers.SysLogHandler",
|
"filename": BASE_DIR / "logs" / "celery.log",
|
||||||
"formatter": "syslog",
|
"backupCount": 5,
|
||||||
"address": "/dev/log",
|
"maxBytes": 50000000, # 50 mB
|
||||||
},
|
"formatter": "timestamped",
|
||||||
"syslog": {
|
|
||||||
"level": "ERROR",
|
|
||||||
"filters": ["require_debug_false"],
|
|
||||||
"class": "logging.handlers.SysLogHandler",
|
|
||||||
"formatter": "syslog",
|
|
||||||
"address": "/dev/log",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"loggers": {
|
"loggers": {
|
||||||
"django": {"handlers": ["console", "syslog"], "level": "INFO"},
|
"django": {"handlers": ["console"], "level": "INFO"},
|
||||||
"django.server": {
|
"django.server": {
|
||||||
"handlers": ["console", "syslog"],
|
"handlers": ["console"],
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"propagate": False,
|
"propagate": False,
|
||||||
},
|
},
|
||||||
"celery": {"handlers": ["celery", "console"], "level": "INFO"},
|
"celery.task": {"handlers": ["console", "celery"], "level": "INFO"},
|
||||||
"newsreader": {"handlers": ["syslog", "console"], "level": "INFO"},
|
"newsreader": {
|
||||||
|
"handlers": ["console", "file"],
|
||||||
|
"level": "DEBUG",
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,9 +211,6 @@ STATICFILES_FINDERS = [
|
||||||
# Email
|
# Email
|
||||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||||
|
|
||||||
# Project settings
|
|
||||||
ENVIRONMENT = "development"
|
|
||||||
|
|
||||||
# Reddit integration
|
# Reddit integration
|
||||||
REDDIT_CLIENT_ID = "CLIENT_ID"
|
REDDIT_CLIENT_ID = "CLIENT_ID"
|
||||||
REDDIT_CLIENT_SECRET = "CLIENT_SECRET"
|
REDDIT_CLIENT_SECRET = "CLIENT_SECRET"
|
||||||
|
|
@ -251,7 +251,9 @@ SWAGGER_SETTINGS = {
|
||||||
|
|
||||||
# Celery
|
# Celery
|
||||||
# https://docs.celeryproject.org/en/stable/userguide/configuration.html
|
# https://docs.celeryproject.org/en/stable/userguide/configuration.html
|
||||||
|
# Note that celery settings are prefix with CELERY. See src/newsreader/celery.py.
|
||||||
CELERY_WORKER_HIJACK_ROOT_LOGGER = False
|
CELERY_WORKER_HIJACK_ROOT_LOGGER = False
|
||||||
|
CELERY_BROKER_URL = "amqp://guest@rabbitmq:5672"
|
||||||
|
|
||||||
REGISTRATION_OPEN = True
|
REGISTRATION_OPEN = True
|
||||||
REGISTRATION_AUTO_LOGIN = True
|
REGISTRATION_AUTO_LOGIN = True
|
||||||
|
|
@ -261,7 +263,6 @@ ACCOUNT_ACTIVATION_DAYS = 7
|
||||||
SENTRY_CONFIG = {
|
SENTRY_CONFIG = {
|
||||||
"dsn": os.environ.get("SENTRY_DSN"),
|
"dsn": os.environ.get("SENTRY_DSN"),
|
||||||
"send_default_pii": False,
|
"send_default_pii": False,
|
||||||
"environment": ENVIRONMENT,
|
|
||||||
"integrations": [DjangoIntegration(), CeleryIntegration()]
|
"integrations": [DjangoIntegration(), CeleryIntegration()]
|
||||||
if DjangoIntegration and CeleryIntegration
|
if DjangoIntegration and CeleryIntegration
|
||||||
else [],
|
else [],
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ AXES_FAILURE_LIMIT = 50
|
||||||
AXES_COOLOFF_TIME = None
|
AXES_COOLOFF_TIME = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .local import * # noqa
|
|
||||||
|
|
||||||
# Optionally use sentry integration
|
# Optionally use sentry integration
|
||||||
from sentry_sdk import init as sentry_init
|
from sentry_sdk import init as sentry_init
|
||||||
|
|
||||||
|
from .local import * # noqa
|
||||||
|
|
||||||
SENTRY_CONFIG.update({"release": VERSION})
|
SENTRY_CONFIG.update({"release": VERSION})
|
||||||
|
|
||||||
sentry_init(**SENTRY_CONFIG)
|
sentry_init(**SENTRY_CONFIG)
|
||||||
|
|
|
||||||
|
|
@ -2,34 +2,21 @@ from .base import * # isort:skip
|
||||||
from .version import get_current_version
|
from .version import get_current_version
|
||||||
|
|
||||||
|
|
||||||
SECRET_KEY = "=q(ztyo)b6noom#a164g&s9vcj1aawa^g#ing_ir99=_zl4g&$"
|
ALLOWED_HOSTS = ["django", "127.0.0.1"]
|
||||||
|
|
||||||
INSTALLED_APPS += ["debug_toolbar", "django_extensions"]
|
INSTALLED_APPS += ["debug_toolbar", "django_extensions"]
|
||||||
|
|
||||||
MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
|
MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
|
||||||
|
|
||||||
|
LOGGING["loggers"].update(
|
||||||
|
{
|
||||||
|
"celery.task": {"handlers": ["console", "celery"], "level": "DEBUG"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||||
|
|
||||||
DATABASES = {
|
DEBUG = True
|
||||||
"default": {
|
|
||||||
"ENGINE": "django.db.backends.postgresql",
|
|
||||||
"NAME": "newsreader",
|
|
||||||
"USER": "newsreader",
|
|
||||||
"PASSWORD": "newsreader",
|
|
||||||
"HOST": "db",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CACHES = {
|
|
||||||
"default": {
|
|
||||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
|
||||||
"LOCATION": "memcached:11211",
|
|
||||||
},
|
|
||||||
"axes": {
|
|
||||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
|
||||||
"LOCATION": "memcached:11211",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
# Project settings
|
# Project settings
|
||||||
VERSION = get_current_version()
|
VERSION = get_current_version()
|
||||||
|
|
@ -40,16 +27,12 @@ ENVIRONMENT = "docker"
|
||||||
AXES_FAILURE_LIMIT = 50
|
AXES_FAILURE_LIMIT = 50
|
||||||
AXES_COOLOFF_TIME = None
|
AXES_COOLOFF_TIME = None
|
||||||
|
|
||||||
# Celery
|
|
||||||
# https://docs.celeryproject.org/en/latest/userguide/configuration.html
|
|
||||||
CELERY_BROKER_URL = "amqp://guest:guest@rabbitmq:5672//"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .local import * # noqa
|
|
||||||
|
|
||||||
# Optionally use sentry integration
|
# Optionally use sentry integration
|
||||||
from sentry_sdk import init as sentry_init
|
from sentry_sdk import init as sentry_init
|
||||||
|
|
||||||
|
from .local import * # noqa
|
||||||
|
|
||||||
SENTRY_CONFIG.update({"release": VERSION, "environment": ENVIRONMENT})
|
SENTRY_CONFIG.update({"release": VERSION, "environment": ENVIRONMENT})
|
||||||
|
|
||||||
sentry_init(**SENTRY_CONFIG)
|
sentry_init(**SENTRY_CONFIG)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,16 @@ from .base import * # isort:skip
|
||||||
from .version import get_current_version
|
from .version import get_current_version
|
||||||
|
|
||||||
|
|
||||||
SECRET_KEY = "29%lkw+&n%^w4k#@_db2mo%*tc&xzb)x7xuq*(0$eucii%4r0c"
|
del LOGGING["handlers"]["file"]
|
||||||
|
del LOGGING["handlers"]["celery"]
|
||||||
|
|
||||||
|
LOGGING["loggers"].update(
|
||||||
|
{
|
||||||
|
"celery.task": {"handlers": ["console"], "level": "DEBUG"},
|
||||||
|
"newsreader": {"handlers": ["console"], "level": "INFO"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,13 @@ from .base import * # isort:skip
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
ALLOWED_HOSTS = ["rss.fudiggity.nl"]
|
ALLOWED_HOSTS = ["127.0.0.1", "localhost", "rss.fudiggity.nl", "django"]
|
||||||
ADMINS = [
|
ADMINS = [
|
||||||
("", email)
|
("", email)
|
||||||
for email in os.getenv("ADMINS", "").split(",")
|
for email in os.getenv("ADMINS", "").split(",")
|
||||||
if os.environ.get("ADMINS")
|
if os.environ.get("ADMINS")
|
||||||
]
|
]
|
||||||
|
|
||||||
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
|
|
||||||
|
|
||||||
DATABASES = {
|
|
||||||
"default": {
|
|
||||||
"ENGINE": "django.db.backends.postgresql",
|
|
||||||
"HOST": os.environ["POSTGRES_HOST"],
|
|
||||||
"PORT": os.environ["POSTGRES_PORT"],
|
|
||||||
"NAME": os.environ["POSTGRES_NAME"],
|
|
||||||
"USER": os.environ["POSTGRES_USER"],
|
|
||||||
"PASSWORD": os.environ["POSTGRES_PASSWORD"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
1068
src/newsreader/fixtures/fixture.json
Normal file
1068
src/newsreader/fixtures/fixture.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
||||||
function isCSSVariablesSupported() {
|
const isCSSVariablesSupported = () => {
|
||||||
return window.CSS && window.CSS.supports('color', 'var(--fake-color');
|
return window.CSS && window.CSS.supports('color', 'var(--fake-color');
|
||||||
}
|
};
|
||||||
|
|
||||||
function changeTheme(e) {
|
const changeTheme = event => {
|
||||||
const currentPref = sessionStorage.getItem('t-dark');
|
const currentPref = sessionStorage.getItem('t-dark');
|
||||||
const isDark = currentPref && currentPref === 'true' ? true : false;
|
const isDark = currentPref && currentPref === 'true' ? true : false;
|
||||||
|
|
||||||
|
|
@ -14,12 +14,12 @@ function changeTheme(e) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sessionStorage.setItem('t-dark', !isDark);
|
sessionStorage.setItem('t-dark', !isDark);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function prefersDarkTheme() {
|
const getThemePreference = () => {
|
||||||
try {
|
try {
|
||||||
const currentPref = sessionStorage.getItem('t-dark');
|
const currentPref = sessionStorage.getItem('t-dark');
|
||||||
|
|
||||||
|
|
@ -33,12 +33,12 @@ function prefersDarkTheme() {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function toggleDarkTheme(isDark) {
|
const toggleDarkTheme = isDark => {
|
||||||
if (isDark) {
|
if (isDark) {
|
||||||
document.documentElement.classList.add('dark-theme');
|
document.documentElement.classList.add('dark-theme');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -47,30 +47,30 @@ function toggleDarkTheme(isDark) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sessionStorage.setItem('t-dark', isDark);
|
sessionStorage.setItem('t-dark', isDark);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function initThemeSelector() {
|
const initThemeSelector = () => {
|
||||||
const themeButton = document.getElementsByClassName('theme-switcher')[0];
|
const themeButton = document.getElementsByClassName('theme-switcher')[0];
|
||||||
const mqPrefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');
|
const prefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
|
||||||
if (prefersDarkTheme()) {
|
if (getThemePreference()) {
|
||||||
toggleDarkTheme(true);
|
toggleDarkTheme(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
themeButton.addEventListener('click', changeTheme);
|
themeButton.addEventListener('click', changeTheme);
|
||||||
|
|
||||||
mqPrefersDarkTheme.addListener(mq => {
|
prefersDarkTheme.addListener(mediaQuery => {
|
||||||
toggleDarkTheme(mq.matches);
|
toggleDarkTheme(mediaQuery.matches);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function init() {
|
const init = () => {
|
||||||
if (isCSSVariablesSupported()) {
|
if (isCSSVariablesSupported()) {
|
||||||
initThemeSelector();
|
initThemeSelector();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { isEqual } from 'lodash';
|
||||||
|
|
||||||
import { fetchCategories } from './actions/categories';
|
import { fetchCategories } from './actions/categories';
|
||||||
|
|
||||||
|
import ScrollTop from './components/ScrollTop.js';
|
||||||
import Sidebar from './components/sidebar/Sidebar.js';
|
import Sidebar from './components/sidebar/Sidebar.js';
|
||||||
import PostList from './components/postlist/PostList.js';
|
import PostList from './components/postlist/PostList.js';
|
||||||
import PostModal from './components/PostModal.js';
|
import PostModal from './components/PostModal.js';
|
||||||
|
|
@ -41,6 +42,8 @@ class App extends React.Component {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<ScrollTop />
|
||||||
|
|
||||||
{this.props.error && (
|
{this.props.error && (
|
||||||
<Messages messages={[{ type: 'error', text: this.props.error.message }]} />
|
<Messages messages={[{ type: 'error', text: this.props.error.message }]} />
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
40
src/newsreader/js/pages/homepage/components/ScrollTop.js
Normal file
40
src/newsreader/js/pages/homepage/components/ScrollTop.js
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default class ScrollTop extends React.Component {
|
||||||
|
scrollListener = ::this.scrollListener;
|
||||||
|
|
||||||
|
state = { showTop: false, showBottom: false };
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('scroll', this.scrollListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollListener() {
|
||||||
|
const showBottom = window.innerHeight + window.scrollY < document.body.offsetHeight;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
showTop: window.pageYOffset > 0 ? true : false,
|
||||||
|
showBottom: showBottom,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="scroll-to-top">
|
||||||
|
{this.state.showTop && (
|
||||||
|
<i
|
||||||
|
className="scroll-to-top__icon scroll-to-top__icon--top"
|
||||||
|
onClick={() => window.scrollTo(0, 0)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{this.state.showBottom && (
|
||||||
|
<i
|
||||||
|
className="scroll-to-top__icon scroll-to-top__icon--bottom"
|
||||||
|
onClick={() => window.scrollTo(0, document.body.scrollHeight)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,13 +21,10 @@ class PostList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScrollHeight(e) {
|
checkScrollHeight(e) {
|
||||||
const currentHeight = window.scrollY + window.innerHeight;
|
const postList = document.body.querySelector('.posts__list');
|
||||||
const totalHeight = document.body.offsetHeight;
|
|
||||||
|
|
||||||
const currentPercentage = (currentHeight / totalHeight) * 100;
|
|
||||||
|
|
||||||
if (this.props.next && !this.props.lastReached) {
|
if (this.props.next && !this.props.lastReached) {
|
||||||
if (currentPercentage > 60 && !this.props.isFetching) {
|
if (window.scrollY + window.innerHeight >= postList.offsetHeight) {
|
||||||
this.paginate();
|
this.paginate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,7 @@ from rest_framework.generics import (
|
||||||
)
|
)
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from newsreader.core.pagination import (
|
from newsreader.core.pagination import CursorPagination
|
||||||
CursorPagination,
|
|
||||||
LargeResultSetPagination,
|
|
||||||
ResultSetPagination,
|
|
||||||
)
|
|
||||||
from newsreader.news.collection.models import CollectionRule
|
from newsreader.news.collection.models import CollectionRule
|
||||||
from newsreader.news.collection.serializers import RuleSerializer
|
from newsreader.news.collection.serializers import RuleSerializer
|
||||||
from newsreader.news.core.filters import ReadFilter
|
from newsreader.news.core.filters import ReadFilter
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ from newsreader.news.collection.base import (
|
||||||
)
|
)
|
||||||
from newsreader.news.collection.choices import RuleTypeChoices
|
from newsreader.news.collection.choices import RuleTypeChoices
|
||||||
from newsreader.news.collection.exceptions import (
|
from newsreader.news.collection.exceptions import (
|
||||||
StreamDeniedException,
|
|
||||||
StreamException,
|
StreamException,
|
||||||
StreamNotFoundException,
|
StreamNotFoundException,
|
||||||
StreamParseException,
|
StreamParseException,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0002_auto_20190714_1036")]
|
dependencies = [("collection", "0002_auto_20190714_1036")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0003_auto_20190714_1417")]
|
dependencies = [("collection", "0003_auto_20190714_1417")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0004_auto_20190714_1422")]
|
dependencies = [("collection", "0004_auto_20190714_1422")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
("collection", "0005_auto_20200303_1932"),
|
("collection", "0005_auto_20200303_1932"),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0006_auto_20200412_1955")]
|
dependencies = [("collection", "0006_auto_20200412_1955")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0007_collectionrule_enabled")]
|
dependencies = [("collection", "0007_collectionrule_enabled")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0008_collectionrule_type")]
|
dependencies = [("collection", "0008_collectionrule_type")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0009_auto_20200807_2030")]
|
dependencies = [("collection", "0009_auto_20200807_2030")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0010_auto_20200913_2101")]
|
dependencies = [("collection", "0010_auto_20200913_2101")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0011_auto_20200913_2157")]
|
dependencies = [("collection", "0011_auto_20200913_2157")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0012_auto_20201219_1331")]
|
dependencies = [("collection", "0012_auto_20201219_1331")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ def reset_default_downvotes(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0013_auto_20201219_1345")]
|
dependencies = [("collection", "0013_auto_20201219_1345")]
|
||||||
|
|
||||||
operations = [migrations.RunPython(reset_default_downvotes)]
|
operations = [migrations.RunPython(reset_default_downvotes)]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("collection", "0014_auto_20201219_1346")]
|
dependencies = [("collection", "0014_auto_20201219_1346")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,6 @@ from newsreader.news.collection.base import (
|
||||||
Scheduler,
|
Scheduler,
|
||||||
)
|
)
|
||||||
from newsreader.news.collection.choices import RuleTypeChoices
|
from newsreader.news.collection.choices import RuleTypeChoices
|
||||||
from newsreader.news.collection.constants import (
|
|
||||||
WHITELISTED_ATTRIBUTES,
|
|
||||||
WHITELISTED_TAGS,
|
|
||||||
)
|
|
||||||
from newsreader.news.collection.exceptions import (
|
from newsreader.news.collection.exceptions import (
|
||||||
BuilderDuplicateException,
|
BuilderDuplicateException,
|
||||||
BuilderException,
|
BuilderException,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from newsreader.news.collection.exceptions import (
|
from newsreader.news.collection.exceptions import (
|
||||||
StreamDeniedException,
|
StreamDeniedException,
|
||||||
StreamException,
|
|
||||||
StreamForbiddenException,
|
StreamForbiddenException,
|
||||||
StreamNotFoundException,
|
StreamNotFoundException,
|
||||||
StreamParseException,
|
StreamParseException,
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ from freezegun import freeze_time
|
||||||
|
|
||||||
from newsreader.news.collection.exceptions import (
|
from newsreader.news.collection.exceptions import (
|
||||||
StreamDeniedException,
|
StreamDeniedException,
|
||||||
StreamException,
|
|
||||||
StreamForbiddenException,
|
StreamForbiddenException,
|
||||||
StreamNotFoundException,
|
StreamNotFoundException,
|
||||||
StreamParseException,
|
|
||||||
StreamTimeOutException,
|
StreamTimeOutException,
|
||||||
)
|
)
|
||||||
from newsreader.news.collection.feed import FeedCollector
|
from newsreader.news.collection.feed import FeedCollector
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ simple_mock_parsed = {
|
||||||
"updated": "Sun, 12 Jul 2020 17:21:20 GMT",
|
"updated": "Sun, 12 Jul 2020 17:21:20 GMT",
|
||||||
"updated_parsed": struct_time((2020, 7, 12, 17, 21, 20, 6, 194, 0)),
|
"updated_parsed": struct_time((2020, 7, 12, 17, 21, 20, 6, 194, 0)),
|
||||||
},
|
},
|
||||||
|
"headers": {},
|
||||||
"namespaces": {
|
"namespaces": {
|
||||||
"": "http://www.w3.org/2005/Atom",
|
"": "http://www.w3.org/2005/Atom",
|
||||||
"content": "http://purl.org/rss/1.0/modules/content/",
|
"content": "http://purl.org/rss/1.0/modules/content/",
|
||||||
|
|
|
||||||
|
|
@ -193,3 +193,35 @@ class TwitterClientTestCase(TestCase):
|
||||||
|
|
||||||
self.assertIsNone(user.twitter_oauth_token)
|
self.assertIsNone(user.twitter_oauth_token)
|
||||||
self.assertIsNone(user.twitter_oauth_token_secret)
|
self.assertIsNone(user.twitter_oauth_token_secret)
|
||||||
|
|
||||||
|
def test_client_does_not_reset_token(self):
|
||||||
|
"""
|
||||||
|
The user's token and refresh token should not be reset when an generic
|
||||||
|
exception is caught
|
||||||
|
"""
|
||||||
|
user = UserFactory(
|
||||||
|
twitter_oauth_token=str(uuid4()), twitter_oauth_token_secret=str(uuid4())
|
||||||
|
)
|
||||||
|
timeline = TwitterTimelineFactory(user=user)
|
||||||
|
|
||||||
|
response = Mock(json=lambda: {"errors": [{"code": 100}]})
|
||||||
|
|
||||||
|
self.mocked_read.side_effect = StreamException(
|
||||||
|
message="Generic message", response=response
|
||||||
|
)
|
||||||
|
|
||||||
|
with TwitterClient([timeline]) as client:
|
||||||
|
for data, stream in client:
|
||||||
|
with self.subTest(data=data, stream=stream):
|
||||||
|
self.assertIsNone(data)
|
||||||
|
self.assertIsNone(stream)
|
||||||
|
self.assertEquals(stream.rule.error, "")
|
||||||
|
self.assertEquals(stream.rule.succeeded, False)
|
||||||
|
|
||||||
|
self.mocked_read.assert_called()
|
||||||
|
|
||||||
|
user.refresh_from_db()
|
||||||
|
timeline.refresh_from_db()
|
||||||
|
|
||||||
|
self.assertIsNotNone(user.twitter_oauth_token)
|
||||||
|
self.assertIsNotNone(user.twitter_oauth_token_secret)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ from newsreader.news.collection.exceptions import (
|
||||||
StreamNotFoundException,
|
StreamNotFoundException,
|
||||||
StreamParseException,
|
StreamParseException,
|
||||||
StreamTimeOutException,
|
StreamTimeOutException,
|
||||||
StreamTooManyException,
|
|
||||||
)
|
)
|
||||||
from newsreader.news.collection.tests.factories import TwitterTimelineFactory
|
from newsreader.news.collection.tests.factories import TwitterTimelineFactory
|
||||||
from newsreader.news.collection.tests.twitter.stream.mocks import simple_mock
|
from newsreader.news.collection.tests.twitter.stream.mocks import simple_mock
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ from newsreader.news.collection.exceptions import (
|
||||||
BuilderException,
|
BuilderException,
|
||||||
BuilderMissingDataException,
|
BuilderMissingDataException,
|
||||||
BuilderParseException,
|
BuilderParseException,
|
||||||
StreamDeniedException,
|
|
||||||
StreamException,
|
StreamException,
|
||||||
StreamNotFoundException,
|
StreamNotFoundException,
|
||||||
StreamParseException,
|
StreamParseException,
|
||||||
|
|
@ -250,39 +249,41 @@ class TwitterClient(PostClient):
|
||||||
try:
|
try:
|
||||||
response_data = e.response.json()
|
response_data = e.response.json()
|
||||||
except JSONDecodeError:
|
except JSONDecodeError:
|
||||||
|
logger.exception("Could not parse json for request")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if "errors" in response_data:
|
if "errors" in response_data:
|
||||||
errors = response_data["errors"]
|
errors = response_data["errors"]
|
||||||
token_expired = any(error["code"] == 89 for error in errors)
|
token_expired = any(error["code"] == 89 for error in errors)
|
||||||
|
|
||||||
try:
|
if token_expired:
|
||||||
import sentry_sdk
|
try:
|
||||||
|
import sentry_sdk
|
||||||
|
|
||||||
with sentry_sdk.push_scope() as scope:
|
with sentry_sdk.push_scope() as scope:
|
||||||
scope.set_extra("content", response_data)
|
scope.set_extra("content", response_data)
|
||||||
sentry_sdk.capture_message(
|
sentry_sdk.capture_message(
|
||||||
"Twitter authentication credentials reset"
|
"Twitter authentication credentials reset"
|
||||||
)
|
)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
stream.rule.user.twitter_oauth_token = None
|
stream.rule.user.twitter_oauth_token = None
|
||||||
stream.rule.user.twitter_oauth_token_secret = None
|
stream.rule.user.twitter_oauth_token_secret = None
|
||||||
stream.rule.user.save()
|
stream.rule.user.save()
|
||||||
|
|
||||||
message = _(
|
message = _(
|
||||||
"Your Twitter account credentials have expired. Re-authenticate in"
|
"Your Twitter account credentials have expired. Re-authenticate in"
|
||||||
" the settings page to keep retrieving Twitter specific information"
|
" the settings page to keep retrieving Twitter specific information"
|
||||||
" from your account."
|
" from your account."
|
||||||
)
|
)
|
||||||
|
|
||||||
send_mail(
|
send_mail(
|
||||||
"Twitter account needs re-authentication",
|
"Twitter account needs re-authentication",
|
||||||
message,
|
message,
|
||||||
None,
|
None,
|
||||||
[stream.rule.user.email],
|
[stream.rule.user.email],
|
||||||
)
|
)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,7 @@ from django.views.generic.edit import CreateView, FormView, UpdateView
|
||||||
from django_celery_beat.models import IntervalSchedule
|
from django_celery_beat.models import IntervalSchedule
|
||||||
|
|
||||||
from newsreader.news.collection.choices import RuleTypeChoices
|
from newsreader.news.collection.choices import RuleTypeChoices
|
||||||
from newsreader.news.collection.forms import (
|
from newsreader.news.collection.forms import FeedForm, OPMLImportForm
|
||||||
CollectionRuleBulkForm,
|
|
||||||
FeedForm,
|
|
||||||
OPMLImportForm,
|
|
||||||
)
|
|
||||||
from newsreader.news.collection.models import CollectionRule
|
from newsreader.news.collection.models import CollectionRule
|
||||||
from newsreader.news.collection.views.base import (
|
from newsreader.news.collection.views.base import (
|
||||||
CollectionRuleDetailMixin,
|
CollectionRuleDetailMixin,
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,7 @@ from django.views.generic.edit import FormView
|
||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
|
|
||||||
from newsreader.news.collection.forms import CollectionRuleBulkForm
|
from newsreader.news.collection.forms import CollectionRuleBulkForm
|
||||||
from newsreader.news.collection.views.base import (
|
from newsreader.news.collection.views.base import CollectionRuleViewMixin
|
||||||
CollectionRuleDetailMixin,
|
|
||||||
CollectionRuleViewMixin,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionRuleListView(CollectionRuleViewMixin, ListView):
|
class CollectionRuleListView(CollectionRuleViewMixin, ListView):
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ from rest_framework import status
|
||||||
from rest_framework.generics import (
|
from rest_framework.generics import (
|
||||||
GenericAPIView,
|
GenericAPIView,
|
||||||
ListAPIView,
|
ListAPIView,
|
||||||
ListCreateAPIView,
|
|
||||||
RetrieveUpdateAPIView,
|
RetrieveUpdateAPIView,
|
||||||
RetrieveUpdateDestroyAPIView,
|
RetrieveUpdateDestroyAPIView,
|
||||||
get_object_or_404,
|
get_object_or_404,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0001_initial")]
|
dependencies = [("core", "0001_initial")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0002_auto_20190714_1425")]
|
dependencies = [("core", "0002_auto_20190714_1425")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
("core", "0003_post_read"),
|
("core", "0003_post_read"),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
("core", "0004_auto_20191116_1315"),
|
("core", "0004_auto_20191116_1315"),
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0005_auto_20200412_1955")]
|
dependencies = [("core", "0005_auto_20200412_1955")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0006_auto_20200524_1218")]
|
dependencies = [("core", "0006_auto_20200524_1218")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0007_auto_20200706_2312")]
|
dependencies = [("core", "0007_auto_20200706_2312")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ from newsreader.news.core.views import (
|
||||||
CategoryCreateView,
|
CategoryCreateView,
|
||||||
CategoryListView,
|
CategoryListView,
|
||||||
CategoryUpdateView,
|
CategoryUpdateView,
|
||||||
NewsView,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,4 @@
|
||||||
@import './post-message/index';
|
@import './post-message/index';
|
||||||
@import './posts/index';
|
@import './posts/index';
|
||||||
@import './posts-info/index';
|
@import './posts-info/index';
|
||||||
|
@import './scroll-to-top/index';
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,6 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
.scroll-to-top {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
right: 15%;
|
||||||
|
bottom: 0;
|
||||||
|
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
font-style: initial;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
background-color: var(--lightest-accent-color);
|
||||||
|
|
||||||
|
&--top:before {
|
||||||
|
@include font-awesome;
|
||||||
|
|
||||||
|
content: "\f062";
|
||||||
|
}
|
||||||
|
|
||||||
|
&--bottom:before {
|
||||||
|
@include font-awesome;
|
||||||
|
|
||||||
|
content: "\f063";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/newsreader/scss/components/scroll-to-top/index.scss
Normal file
1
src/newsreader/scss/components/scroll-to-top/index.scss
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
@import './scroll-to-top';
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from django.core.cache import cache
|
from time import monotonic
|
||||||
|
|
||||||
from celery.five import monotonic
|
from django.core.cache import cache
|
||||||
|
|
||||||
|
|
||||||
LOCK_EXPIRE = 60 * 10 # 10 minutes
|
LOCK_EXPIRE = 60 * 10 # 10 minutes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue