Compare commits
12 commits
main
...
dependenci
| Author | SHA1 | Date | |
|---|---|---|---|
| d7b9006c64 | |||
| c268768187 | |||
| d02aa74413 | |||
| 2bb5e4f66f | |||
| 491e566566 | |||
| 6cef4c9fe5 | |||
| e93a323959 | |||
| 2879bc8305 | |||
| 89efdb30fd | |||
| 28df757ea8 | |||
| 841ca7d674 | |||
| 2f22e635b3 |
50 changed files with 11613 additions and 16845 deletions
11
.babelrc
11
.babelrc
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"presets": ["@babel/preset-env"],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-runtime",
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-transform-react-jsx",
|
||||
"@babel/plugin-syntax-function-bind",
|
||||
"@babel/plugin-proposal-function-bind",
|
||||
["@babel/plugin-proposal-class-properties", {loose: true}],
|
||||
]
|
||||
}
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -1,5 +1,17 @@
|
|||
# Changelog
|
||||
|
||||
## 0.5.0
|
||||
|
||||
- Require python 3.11
|
||||
- Require node 18 (current LTS)
|
||||
- Upgrade webpack 4 -> 5
|
||||
- Updated python dependencies
|
||||
- `django` `3.2` -> `4.2`
|
||||
- `psycopg` `2.9.x` -> `3.1.x`
|
||||
- `python-dotenv` `2.9.x` -> `3.1.x`
|
||||
- migrated from `python-memcached` to `pymemcache`
|
||||
- removed `drf-yasg`
|
||||
|
||||
## 0.4.2
|
||||
|
||||
- Set `SECURE_PROXY_SSL_HEADER` setting for production
|
||||
|
|
|
|||
12
babel.config.js
Normal file
12
babel.config.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', { targets: { node: 'current' } }],
|
||||
'@babel/preset-react',
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-syntax-function-bind',
|
||||
'@babel/plugin-proposal-function-bind',
|
||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||
],
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# stage 1
|
||||
FROM python:3.9-bullseye as backend
|
||||
FROM python:3.11-bookworm as backend
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
vim \
|
||||
|
|
@ -18,7 +18,7 @@ RUN pip install -r requirements/base.txt
|
|||
|
||||
|
||||
# stage 2
|
||||
FROM node:16-bullseye AS frontend-build
|
||||
FROM node:lts-bookworm AS frontend-build
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
|
|
@ -28,15 +28,15 @@ WORKDIR /app
|
|||
|
||||
COPY ./*.json ./*.js ./.babelrc /app/
|
||||
|
||||
RUN npm ci
|
||||
RUN npm ci --include=dev
|
||||
|
||||
COPY ./src /app/src
|
||||
|
||||
RUN npm run build
|
||||
RUN npm run build:prod
|
||||
|
||||
|
||||
# stage 3
|
||||
FROM python:3.9-bullseye as production
|
||||
FROM python:3.11-bookworm as production
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
postgresql-client \
|
||||
|
|
@ -51,7 +51,7 @@ 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/lib/python3.11 /usr/local/lib/python3.11
|
||||
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
|
||||
|
||||
COPY ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh
|
||||
|
|
@ -81,7 +81,7 @@ RUN python src/manage.py collectstatic --noinput
|
|||
|
||||
|
||||
# (optional) stage 4
|
||||
FROM python:3.9-bullseye as development
|
||||
FROM python:3.11-bookworm as development
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
vim \
|
||||
|
|
@ -96,7 +96,7 @@ 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/lib/python3.11 /usr/local/lib/python3.11
|
||||
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
|
||||
COPY --from=backend /app/src/ /app/src/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
FROM node:16-bullseye
|
||||
FROM node:lts-bookworm
|
||||
|
||||
WORKDIR /app
|
||||
RUN mkdir /app/src
|
||||
|
||||
COPY package*.json webpack.*.js .babelrc /app/
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY ./src /app/src
|
||||
RUN npm ci --include=dev
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
static:
|
||||
stage: build
|
||||
image: node:16-bullseye
|
||||
image: node:lts-bookworm
|
||||
before_script:
|
||||
- npm install
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
python-linting:
|
||||
stage: lint
|
||||
image: python:3.9-bullseye
|
||||
image: python:3.11-bookworm
|
||||
before_script:
|
||||
- pip install -r requirements/ci.txt
|
||||
script:
|
||||
|
|
@ -14,7 +14,7 @@ python-linting:
|
|||
|
||||
javascript-linting:
|
||||
stage: lint
|
||||
image: node:16-bullseye
|
||||
image: node:lts-bookworm
|
||||
before_script:
|
||||
- npm install
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ python-tests:
|
|||
services:
|
||||
- postgres:15
|
||||
- memcached:1.5.22
|
||||
image: python:3.9-bullseye
|
||||
image: python:3.11-bookworm
|
||||
before_script:
|
||||
- pip install -r requirements/ci.txt
|
||||
script:
|
||||
|
|
@ -12,7 +12,7 @@ python-tests:
|
|||
|
||||
javascript-tests:
|
||||
stage: test
|
||||
image: node:16-bullseye
|
||||
image: node:lts-bookworm
|
||||
before_script:
|
||||
- npm install
|
||||
script:
|
||||
|
|
|
|||
27750
package-lock.json
generated
27750
package-lock.json
generated
File diff suppressed because it is too large
Load diff
60
package.json
60
package.json
|
|
@ -1,20 +1,20 @@
|
|||
{
|
||||
"name": "newsreader",
|
||||
"version": "0.4.2",
|
||||
"version": "0.5.0",
|
||||
"description": "Application for viewing RSS feeds",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "npx prettier \"src/newsreader/js/**/*.js\" --check",
|
||||
"format": "npx prettier \"src/newsreader/js/**/*.js\" --write",
|
||||
"build": "npx webpack --config webpack.dev.babel.js",
|
||||
"build:watch": "npx webpack --config webpack.dev.babel.js --watch",
|
||||
"build:prod": "npx webpack --config webpack.prod.babel.js",
|
||||
"test": "npx jest",
|
||||
"lint": "prettier \"src/newsreader/js/**/*.js\" --check",
|
||||
"format": "prettier \"src/newsreader/js/**/*.js\" --write",
|
||||
"build": "webpack --config webpack.dev.babel.js",
|
||||
"build:watch": "webpack --config webpack.dev.babel.js --watch",
|
||||
"build:prod": "webpack --config webpack.prod.babel.js",
|
||||
"test": "jest",
|
||||
"test:watch": "npm test -- --watch"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "[git@git.fudiggity.nl:5000]:sonny/newsreader.git"
|
||||
"url": "git@git.fudiggity.nl:sonny/newsreader.git"
|
||||
},
|
||||
"author": "Sonny",
|
||||
"license": "GPL-3.0-or-later",
|
||||
|
|
@ -29,35 +29,33 @@
|
|||
"redux-thunk": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.13",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.13",
|
||||
"@babel/plugin-proposal-function-bind": "^7.12.13",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-syntax-function-bind": "^7.12.13",
|
||||
"@babel/plugin-transform-react-jsx": "^7.12.13",
|
||||
"@babel/plugin-transform-runtime": "^7.12.15",
|
||||
"@babel/preset-env": "^7.12.13",
|
||||
"@babel/register": "^7.12.13",
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"@babel/core": "^7.22.9",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-proposal-function-bind": "^7.22.5",
|
||||
"@babel/plugin-syntax-function-bind": "^7.22.5",
|
||||
"@babel/plugin-transform-runtime": "^7.22.9",
|
||||
"@babel/preset-env": "^7.22.9",
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"@babel/register": "^7.22.5",
|
||||
"@babel/runtime": "^7.22.6",
|
||||
"babel-jest": "^29.6.2",
|
||||
"babel-loader": "^9.1.3",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
"fetch-mock": "^8.3.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"jest": "^24.9.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"jest": "^29.6.2",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"node-fetch": "^2.6.1",
|
||||
"prettier": "^1.19.1",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0",
|
||||
"redux-mock-store": "^1.5.4",
|
||||
"sass": "^1.52.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"style-loader": "^1.3.0",
|
||||
"sass": "^1.64.2",
|
||||
"sass-loader": "^13.3.2",
|
||||
"style-loader": "^3.3.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-merge": "^4.2.2"
|
||||
"webpack": "5.88.x",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,31 @@
|
|||
[project]
|
||||
name = 'newsreader'
|
||||
version = '0.4.2'
|
||||
version = '0.5.0'
|
||||
authors = [{name = 'Sonny', email= 'sonnyba871@gmail.com'}]
|
||||
license = {text = 'GPL-3.0'}
|
||||
requires-python = '>=3.11'
|
||||
dependencies = [
|
||||
'django~=3.2',
|
||||
'django~=4.2.0',
|
||||
'celery~=5.0',
|
||||
'psycopg2',
|
||||
'psycopg~=3.1.10',
|
||||
|
||||
'django-axes',
|
||||
'django-axes~=6.0.4',
|
||||
'django-celery-beat~=2.5.0',
|
||||
'django-registration-redux~=2.7',
|
||||
'django-rest-framework',
|
||||
'drf-yasg',
|
||||
'django-registration-redux~=2.12.0',
|
||||
'djangorestframework~=3.14.0',
|
||||
|
||||
'python-memcached',
|
||||
'python-dotenv~=0.12',
|
||||
'pymemcache~=4.0.0',
|
||||
'python-dotenv~=1.0.0',
|
||||
|
||||
'ftfy~=5.8',
|
||||
'ftfy~=6.1.1',
|
||||
|
||||
'requests',
|
||||
'requests_oauthlib',
|
||||
'requests~=2.31.0',
|
||||
'requests_oauthlib~=1.3.1',
|
||||
|
||||
'feedparser',
|
||||
'bleach',
|
||||
'beautifulsoup4',
|
||||
'lxml'
|
||||
'feedparser~=6.0.10',
|
||||
'bleach~=6.0.0',
|
||||
'beautifulsoup4~=4.12.2',
|
||||
'lxml~=4.9.2'
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
|
|
@ -47,4 +46,4 @@ development = [
|
|||
|
||||
ci = ['coverage>=5.3.1']
|
||||
|
||||
production = ['gunicorn~=20.0', 'sentry-sdk~=1.0']
|
||||
production = ['gunicorn~=21.2.0', 'sentry-sdk~=1.26.0']
|
||||
|
|
|
|||
|
|
@ -36,13 +36,12 @@ click-repl==0.3.0
|
|||
# via celery
|
||||
cron-descriptor==1.4.0
|
||||
# via django-celery-beat
|
||||
django==3.2.19
|
||||
django==4.2.4
|
||||
# via
|
||||
# django-axes
|
||||
# django-celery-beat
|
||||
# django-timezone-field
|
||||
# djangorestframework
|
||||
# drf-yasg
|
||||
# newsreader (pyproject.toml)
|
||||
django-axes==6.0.4
|
||||
# via newsreader (pyproject.toml)
|
||||
|
|
@ -50,35 +49,27 @@ 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
|
||||
ftfy==6.1.1
|
||||
# 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
|
||||
psycopg==3.1.10
|
||||
# via newsreader (pyproject.toml)
|
||||
pymemcache==4.0.0
|
||||
# via newsreader (pyproject.toml)
|
||||
python-crontab==2.7.1
|
||||
# via django-celery-beat
|
||||
|
|
@ -86,18 +77,12 @@ python-dateutil==2.8.2
|
|||
# via
|
||||
# celery
|
||||
# python-crontab
|
||||
python-dotenv==0.21.1
|
||||
# via newsreader (pyproject.toml)
|
||||
python-memcached==1.59
|
||||
python-dotenv==1.0.0
|
||||
# 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)
|
||||
|
|
@ -110,7 +95,6 @@ six==1.16.0
|
|||
# via
|
||||
# bleach
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
soupsieve==2.4.1
|
||||
# via beautifulsoup4
|
||||
sqlparse==0.4.4
|
||||
|
|
@ -119,12 +103,11 @@ typing-extensions==4.6.3
|
|||
# via
|
||||
# asgiref
|
||||
# kombu
|
||||
# psycopg
|
||||
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
|
||||
|
|
|
|||
|
|
@ -81,14 +81,13 @@ cron-descriptor==1.4.0
|
|||
# -r requirements/base.txt
|
||||
# -r requirements/testing.txt
|
||||
# django-celery-beat
|
||||
django==3.2.19
|
||||
django==4.2.4
|
||||
# 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
|
||||
|
|
@ -102,22 +101,12 @@ 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)
|
||||
|
|
@ -137,7 +126,7 @@ freezegun==1.2.2
|
|||
# via
|
||||
# -r requirements/testing.txt
|
||||
# newsreader (pyproject.toml)
|
||||
ftfy==5.9
|
||||
ftfy==6.1.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -146,11 +135,6 @@ idna==3.4
|
|||
# -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
|
||||
|
|
@ -175,10 +159,8 @@ oauthlib==3.2.2
|
|||
# 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
|
||||
|
|
@ -192,7 +174,7 @@ prompt-toolkit==3.0.38
|
|||
# -r requirements/base.txt
|
||||
# -r requirements/testing.txt
|
||||
# click-repl
|
||||
psycopg2==2.9.6
|
||||
psycopg==3.1.10
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -200,6 +182,10 @@ pyflakes==3.0.1
|
|||
# via
|
||||
# -r requirements/testing.txt
|
||||
# autoflake
|
||||
pymemcache==4.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-crontab==2.7.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -213,11 +199,7 @@ python-dateutil==2.8.2
|
|||
# faker
|
||||
# freezegun
|
||||
# python-crontab
|
||||
python-dotenv==0.21.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-memcached==1.59
|
||||
python-dotenv==1.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -225,15 +207,8 @@ 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
|
||||
|
|
@ -254,7 +229,6 @@ six==1.16.0
|
|||
# -r requirements/testing.txt
|
||||
# bleach
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
soupsieve==2.4.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -281,17 +255,13 @@ typing-extensions==4.6.3
|
|||
# asgiref
|
||||
# black
|
||||
# kombu
|
||||
# psycopg
|
||||
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
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ cron-descriptor==1.4.0
|
|||
# -r requirements/base.txt
|
||||
# -r requirements/testing.txt
|
||||
# django-celery-beat
|
||||
django==3.2.19
|
||||
django==4.2.4
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# django-axes
|
||||
|
|
@ -91,7 +91,6 @@ django==3.2.19
|
|||
# django-extensions
|
||||
# django-timezone-field
|
||||
# djangorestframework
|
||||
# drf-yasg
|
||||
# newsreader (pyproject.toml)
|
||||
django-axes==6.0.4
|
||||
# via
|
||||
|
|
@ -109,22 +108,12 @@ 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)
|
||||
|
|
@ -144,7 +133,7 @@ freezegun==1.2.2
|
|||
# via
|
||||
# -r requirements/testing.txt
|
||||
# newsreader (pyproject.toml)
|
||||
ftfy==5.9
|
||||
ftfy==6.1.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -153,11 +142,6 @@ idna==3.4
|
|||
# -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
|
||||
|
|
@ -182,11 +166,9 @@ oauthlib==3.2.2
|
|||
# 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
|
||||
|
|
@ -202,7 +184,7 @@ prompt-toolkit==3.0.38
|
|||
# -r requirements/base.txt
|
||||
# -r requirements/testing.txt
|
||||
# click-repl
|
||||
psycopg2==2.9.6
|
||||
psycopg==3.1.10
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -210,6 +192,10 @@ pyflakes==3.0.1
|
|||
# via
|
||||
# -r requirements/testing.txt
|
||||
# autoflake
|
||||
pymemcache==4.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
pyproject-hooks==1.0.0
|
||||
# via build
|
||||
python-crontab==2.7.1
|
||||
|
|
@ -225,11 +211,7 @@ python-dateutil==2.8.2
|
|||
# faker
|
||||
# freezegun
|
||||
# python-crontab
|
||||
python-dotenv==0.21.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-memcached==1.59
|
||||
python-dotenv==1.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -237,15 +219,8 @@ 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
|
||||
|
|
@ -266,7 +241,6 @@ six==1.16.0
|
|||
# -r requirements/testing.txt
|
||||
# bleach
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
soupsieve==2.4.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -296,17 +270,13 @@ typing-extensions==4.6.3
|
|||
# asgiref
|
||||
# black
|
||||
# kombu
|
||||
# psycopg
|
||||
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
|
||||
|
|
|
|||
|
|
@ -61,14 +61,13 @@ cron-descriptor==1.4.0
|
|||
# via
|
||||
# -r requirements/base.txt
|
||||
# django-celery-beat
|
||||
django==3.2.19
|
||||
django==4.2.4
|
||||
# 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
|
||||
|
|
@ -82,20 +81,11 @@ 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)
|
||||
|
|
@ -103,20 +93,16 @@ feedparser==6.0.10
|
|||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
ftfy==5.9
|
||||
ftfy==6.1.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
gunicorn==20.1.0
|
||||
gunicorn==21.2.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
|
||||
|
|
@ -130,14 +116,16 @@ oauthlib==3.2.2
|
|||
# -r requirements/base.txt
|
||||
# requests-oauthlib
|
||||
packaging==23.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# drf-yasg
|
||||
# via gunicorn
|
||||
prompt-toolkit==3.0.38
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# click-repl
|
||||
psycopg2==2.9.6
|
||||
psycopg==3.1.10
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
pymemcache==4.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -150,25 +138,15 @@ python-dateutil==2.8.2
|
|||
# -r requirements/base.txt
|
||||
# celery
|
||||
# python-crontab
|
||||
python-dotenv==0.21.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-memcached==1.59
|
||||
python-dotenv==1.0.0
|
||||
# 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
|
||||
|
|
@ -189,7 +167,6 @@ six==1.16.0
|
|||
# -r requirements/base.txt
|
||||
# bleach
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
soupsieve==2.4.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -203,15 +180,12 @@ typing-extensions==4.6.3
|
|||
# -r requirements/base.txt
|
||||
# asgiref
|
||||
# kombu
|
||||
# psycopg
|
||||
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
|
||||
|
|
|
|||
|
|
@ -65,14 +65,13 @@ cron-descriptor==1.4.0
|
|||
# via
|
||||
# -r requirements/base.txt
|
||||
# django-celery-beat
|
||||
django==3.2.19
|
||||
django==4.2.4
|
||||
# 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
|
||||
|
|
@ -86,20 +85,11 @@ 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)
|
||||
|
|
@ -113,7 +103,7 @@ feedparser==6.0.10
|
|||
# newsreader (pyproject.toml)
|
||||
freezegun==1.2.2
|
||||
# via newsreader (pyproject.toml)
|
||||
ftfy==5.9
|
||||
ftfy==6.1.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
|
|
@ -121,10 +111,6 @@ 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
|
||||
|
|
@ -142,10 +128,7 @@ oauthlib==3.2.2
|
|||
# -r requirements/base.txt
|
||||
# requests-oauthlib
|
||||
packaging==23.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# black
|
||||
# drf-yasg
|
||||
# via black
|
||||
pathspec==0.11.1
|
||||
# via black
|
||||
platformdirs==3.8.0
|
||||
|
|
@ -154,12 +137,16 @@ prompt-toolkit==3.0.38
|
|||
# via
|
||||
# -r requirements/base.txt
|
||||
# click-repl
|
||||
psycopg2==2.9.6
|
||||
psycopg==3.1.10
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
pyflakes==3.0.1
|
||||
# via autoflake
|
||||
pymemcache==4.0.0
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-crontab==2.7.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -171,25 +158,15 @@ python-dateutil==2.8.2
|
|||
# faker
|
||||
# freezegun
|
||||
# python-crontab
|
||||
python-dotenv==0.21.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
# newsreader (pyproject.toml)
|
||||
python-memcached==1.59
|
||||
python-dotenv==1.0.0
|
||||
# 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
|
||||
|
|
@ -208,7 +185,6 @@ six==1.16.0
|
|||
# -r requirements/base.txt
|
||||
# bleach
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
soupsieve==2.4.1
|
||||
# via
|
||||
# -r requirements/base.txt
|
||||
|
|
@ -229,15 +205,12 @@ typing-extensions==4.6.3
|
|||
# asgiref
|
||||
# black
|
||||
# kombu
|
||||
# psycopg
|
||||
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
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django import forms
|
|||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
|
||||
from django.contrib.auth.forms import UserChangeForm
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from newsreader.accounts.models import User
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
|
@ -19,7 +19,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
|
|||
DJANGO_PROJECT_DIR = os.path.join(BASE_DIR, "src", "newsreader")
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
||||
# SECURITY WARNING: don"t run with debug turned on in production!
|
||||
DEBUG = False
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ INSTALLED_APPS = [
|
|||
"django.forms",
|
||||
# third party apps
|
||||
"rest_framework",
|
||||
"drf_yasg",
|
||||
"celery",
|
||||
"django_celery_beat",
|
||||
"registration",
|
||||
|
|
@ -91,7 +90,7 @@ TEMPLATES = [
|
|||
WSGI_APPLICATION = "newsreader.wsgi.application"
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
|
|
@ -107,17 +106,17 @@ DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
|||
|
||||
CACHES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
||||
"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
|
||||
"LOCATION": "memcached:11211",
|
||||
},
|
||||
"axes": {
|
||||
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
|
||||
"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
|
||||
"LOCATION": "memcached:11211",
|
||||
},
|
||||
}
|
||||
|
||||
# Logging
|
||||
# https://docs.djangoproject.com/en/2.2/topics/logging/#configuring-logging
|
||||
# https://docs.djangoproject.com/en/4.2/topics/logging/#configuring-logging
|
||||
LOGGING = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
|
|
@ -172,7 +171,7 @@ LOGGING = {
|
|||
}
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
|
||||
|
|
@ -188,7 +187,7 @@ AUTH_USER_MODEL = "accounts.User"
|
|||
LOGIN_REDIRECT_URL = "/"
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "Europe/Amsterdam"
|
||||
|
|
@ -197,12 +196,12 @@ USE_L10N = True
|
|||
USE_TZ = True
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
STATICFILES_DIRS = [os.path.join(DJANGO_PROJECT_DIR, "static")]
|
||||
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-STATICFILES_FINDERS
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#std:setting-STATICFILES_FINDERS
|
||||
STATICFILES_FINDERS = [
|
||||
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||
|
|
|
|||
|
|
@ -17,17 +17,6 @@ EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
|||
|
||||
AXES_ENABLED = False
|
||||
|
||||
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
|
||||
VERSION = get_current_version()
|
||||
ENVIRONMENT = "gitlab"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|||
|
||||
ALLOWED_HOSTS = ["127.0.0.1", "localhost", "rss.fudiggity.nl", "django"]
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = ["https://rss.fudiggity.nl"]
|
||||
|
||||
ADMINS = [
|
||||
("", email)
|
||||
for email in os.getenv("ADMINS", "").split(",")
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ import logging
|
|||
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import timedelta
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
|
||||
from feedparser import parse
|
||||
|
||||
from newsreader.news.collection.base import (
|
||||
|
|
@ -58,7 +57,7 @@ class FeedBuilder(PostBuilder):
|
|||
"published_parsed": "publication_date",
|
||||
"author": "author",
|
||||
}
|
||||
tz = pytz.timezone(self.stream.rule.timezone)
|
||||
tz = ZoneInfo(self.stream.rule.timezone)
|
||||
data = {"rule_id": self.stream.rule.pk}
|
||||
|
||||
for field, model_field in field_mapping.items():
|
||||
|
|
|
|||
|
|
@ -1,19 +1,30 @@
|
|||
from datetime import timezone as python_timezone
|
||||
from zoneinfo import available_timezones
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.core.forms import CheckboxInput
|
||||
from newsreader.news.collection.forms.base import CollectionRuleForm
|
||||
from newsreader.news.collection.models import CollectionRule
|
||||
|
||||
|
||||
def get_timezones():
|
||||
return [
|
||||
(
|
||||
_timezone,
|
||||
_timezone,
|
||||
)
|
||||
for _timezone in available_timezones()
|
||||
]
|
||||
|
||||
|
||||
class FeedForm(CollectionRuleForm):
|
||||
timezone = forms.ChoiceField(
|
||||
widget=forms.Select(attrs={"size": len(pytz.all_timezones)}),
|
||||
choices=((timezone, timezone) for timezone in pytz.all_timezones),
|
||||
widget=forms.Select(attrs={"size": len(get_timezones())}),
|
||||
choices=get_timezones(),
|
||||
help_text=_("The timezone which the feed uses"),
|
||||
initial=pytz.utc,
|
||||
initial=python_timezone.utc,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import timezone
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
from newsreader.news.collection.forms.base import CollectionRuleForm
|
||||
from newsreader.news.collection.models import CollectionRule
|
||||
|
|
@ -36,7 +36,7 @@ class SubRedditForm(CollectionRuleForm):
|
|||
instance = super().save(commit=False)
|
||||
|
||||
instance.type = RuleTypeChoices.subreddit
|
||||
instance.timezone = str(pytz.utc)
|
||||
instance.timezone = str(timezone.utc)
|
||||
|
||||
if commit:
|
||||
instance.save()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from datetime import timezone
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
from newsreader.news.collection.forms.base import CollectionRuleForm
|
||||
from newsreader.news.collection.models import CollectionRule
|
||||
|
|
@ -21,7 +21,7 @@ class TwitterTimelineForm(CollectionRuleForm):
|
|||
instance = super().save(commit=False)
|
||||
|
||||
instance.type = RuleTypeChoices.twitter_timeline
|
||||
instance.timezone = str(pytz.utc)
|
||||
instance.timezone = str(timezone.utc)
|
||||
instance.url = f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name={instance.screen_name}&tweet_mode=extended"
|
||||
|
||||
if commit:
|
||||
|
|
|
|||
|
|
@ -1,13 +1,24 @@
|
|||
from datetime import timezone
|
||||
from zoneinfo import available_timezones
|
||||
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.core.models import TimeStampedModel
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
|
||||
|
||||
def get_timezones():
|
||||
return [
|
||||
(
|
||||
_timezone,
|
||||
_timezone,
|
||||
)
|
||||
for _timezone in available_timezones()
|
||||
]
|
||||
|
||||
|
||||
class CollectionRuleQuerySet(models.QuerySet):
|
||||
def enabled(self):
|
||||
return self.filter(enabled=True)
|
||||
|
|
@ -26,9 +37,9 @@ class CollectionRule(TimeStampedModel):
|
|||
favicon = models.URLField(blank=True, null=True)
|
||||
|
||||
timezone = models.CharField(
|
||||
choices=((timezone, timezone) for timezone in pytz.all_timezones),
|
||||
choices=get_timezones(),
|
||||
max_length=100,
|
||||
default=str(pytz.utc),
|
||||
default=str(timezone.utc),
|
||||
)
|
||||
|
||||
category = models.ForeignKey(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import logging
|
|||
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timezone as _timezone
|
||||
from html import unescape
|
||||
from json.decoder import JSONDecodeError
|
||||
from urllib.parse import urlencode
|
||||
|
|
@ -12,7 +13,6 @@ from django.core.cache import cache
|
|||
from django.utils import timezone
|
||||
from django.utils.html import format_html
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
from newsreader.news.collection.base import (
|
||||
|
|
@ -215,7 +215,8 @@ class RedditBuilder(PostBuilder):
|
|||
|
||||
try:
|
||||
parsed_date = datetime.fromtimestamp(entry_data["created_utc"])
|
||||
created_date = pytz.utc.localize(parsed_date)
|
||||
|
||||
created_date = parsed_date.replace(tzinfo=_timezone.utc)
|
||||
except (OverflowError, OSError) as e:
|
||||
raise BuilderParseException(payload=entry) from e
|
||||
except KeyError as e:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.mail import send_mail
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import requests
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import json
|
||||
|
||||
from datetime import date, datetime, time
|
||||
from datetime import date, datetime, time, timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.accounts.tests.factories import UserFactory
|
||||
from newsreader.news.collection.tests.factories import FeedFactory
|
||||
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||
|
|
@ -154,21 +152,21 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
title="I'm the first post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), timezone.utc
|
||||
),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the second post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), timezone.utc
|
||||
),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the third post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), timezone.utc
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
from datetime import datetime
|
||||
from datetime import timezone as _timezone
|
||||
from unittest.mock import Mock
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from newsreader.news.collection.feed import FeedBuilder
|
||||
|
|
@ -35,7 +34,7 @@ class FeedBuilderTestCase(TestCase):
|
|||
post = posts[0]
|
||||
|
||||
publication_date = datetime(
|
||||
2019, 5, 20, hour=16, minute=32, second=38, tzinfo=pytz.utc
|
||||
2019, 5, 20, hour=16, minute=32, second=38, tzinfo=_timezone.utc
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
|
|
@ -59,7 +58,7 @@ class FeedBuilderTestCase(TestCase):
|
|||
post = posts[1]
|
||||
|
||||
publication_date = datetime(
|
||||
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=pytz.utc
|
||||
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=_timezone.utc
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
|
|
@ -94,7 +93,7 @@ class FeedBuilderTestCase(TestCase):
|
|||
post = posts[0]
|
||||
|
||||
publication_date = datetime(
|
||||
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=pytz.utc
|
||||
2019, 5, 20, hour=16, minute=7, second=37, tzinfo=_timezone.utc
|
||||
)
|
||||
|
||||
self.assertEqual(post.publication_date, publication_date)
|
||||
|
|
@ -109,7 +108,7 @@ class FeedBuilderTestCase(TestCase):
|
|||
post = posts[1]
|
||||
|
||||
publication_date = datetime(
|
||||
2019, 5, 20, hour=12, minute=19, second=19, tzinfo=pytz.utc
|
||||
2019, 5, 20, hour=12, minute=19, second=19, tzinfo=_timezone.utc
|
||||
)
|
||||
|
||||
self.assertEqual(post.publication_date, publication_date)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import date, datetime, time
|
||||
from datetime import timezone as _timezone
|
||||
from time import struct_time
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from newsreader.news.collection.exceptions import (
|
||||
|
|
@ -100,7 +99,7 @@ class FeedCollectorTestCase(TestCase):
|
|||
def test_forbidden(self):
|
||||
self.mocked_fetch.side_effect = StreamForbiddenException
|
||||
|
||||
old_run = pytz.utc.localize(datetime(2019, 10, 30, 12, 30))
|
||||
old_run = datetime(2019, 10, 30, 12, 30, tzinfo=_timezone.utc)
|
||||
rule = FeedFactory(last_run=old_run)
|
||||
|
||||
collector = FeedCollector()
|
||||
|
|
@ -130,7 +129,7 @@ class FeedCollectorTestCase(TestCase):
|
|||
self.assertEquals(rule.succeeded, False)
|
||||
self.assertEquals(rule.error, "Stream timed out")
|
||||
self.assertEquals(
|
||||
rule.last_run, pytz.utc.localize(datetime(2019, 10, 30, 12, 30))
|
||||
rule.last_run, datetime(2019, 10, 30, 12, 30, tzinfo=_timezone.utc)
|
||||
)
|
||||
|
||||
def test_duplicates(self):
|
||||
|
|
@ -139,7 +138,7 @@ class FeedCollectorTestCase(TestCase):
|
|||
rule = FeedFactory()
|
||||
|
||||
aware_datetime = build_publication_date(
|
||||
struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), pytz.utc
|
||||
struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), _timezone.utc
|
||||
)
|
||||
|
||||
first_post = FeedPostFactory(
|
||||
|
|
@ -152,7 +151,7 @@ class FeedCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
aware_datetime = build_publication_date(
|
||||
struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), pytz.utc
|
||||
struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), _timezone.utc
|
||||
)
|
||||
|
||||
second_post = FeedPostFactory(
|
||||
|
|
@ -165,7 +164,7 @@ class FeedCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
aware_datetime = build_publication_date(
|
||||
struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), pytz.utc
|
||||
struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), _timezone.utc
|
||||
)
|
||||
|
||||
third_post = FeedPostFactory(
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from unittest.mock import Mock
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.news.collection.reddit import RedditBuilder
|
||||
from newsreader.news.collection.tests.factories import SubredditFactory
|
||||
from newsreader.news.collection.tests.reddit.builder.mocks import *
|
||||
|
|
@ -59,7 +57,7 @@ class RedditBuilderTestCase(TestCase):
|
|||
"https://www.reddit.com/r/linux/comments/hm0qct/linux_experiencesrants_or_educationcertifications/",
|
||||
)
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 7, 6, 6, 11, 22))
|
||||
post.publication_date, datetime(2020, 7, 6, 6, 11, 22, tzinfo=timezone.utc)
|
||||
)
|
||||
|
||||
def test_empty_data(self):
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import datetime
|
||||
from datetime import timezone as _timezone
|
||||
from unittest.mock import patch
|
||||
from uuid import uuid4
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
from newsreader.news.collection.exceptions import (
|
||||
StreamDeniedException,
|
||||
|
|
@ -82,7 +81,8 @@ class RedditCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 7, 11, 22, 23, 24))
|
||||
post.publication_date,
|
||||
datetime(2020, 7, 11, 22, 23, 24, tzinfo=_timezone.utc),
|
||||
)
|
||||
|
||||
self.assertEquals(post.author, "HannahB888")
|
||||
|
|
@ -99,7 +99,8 @@ class RedditCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 7, 12, 10, 29, 10))
|
||||
post.publication_date,
|
||||
datetime(2020, 7, 12, 10, 29, 10, tzinfo=_timezone.utc),
|
||||
)
|
||||
|
||||
self.assertEquals(post.author, "Sebaron")
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from unittest.mock import Mock
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
import pytz
|
||||
|
||||
from ftfy import fix_text
|
||||
|
||||
from newsreader.news.collection.tests.factories import TwitterTimelineFactory
|
||||
|
|
@ -69,7 +67,7 @@ class TwitterBuilderTestCase(TestCase):
|
|||
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291528756373286914"
|
||||
)
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 8, 7, 0, 17, 5))
|
||||
post.publication_date, datetime(2020, 8, 7, 0, 17, 5, tzinfo=timezone.utc)
|
||||
)
|
||||
|
||||
post = posts["1288550304095416320"]
|
||||
|
|
@ -85,7 +83,7 @@ class TwitterBuilderTestCase(TestCase):
|
|||
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1288550304095416320"
|
||||
)
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 7, 29, 19, 1, 47))
|
||||
post.publication_date, datetime(2020, 7, 29, 19, 1, 47, tzinfo=timezone.utc)
|
||||
)
|
||||
|
||||
# note that only one media type can be uploaded to an Tweet
|
||||
|
|
@ -114,7 +112,7 @@ class TwitterBuilderTestCase(TestCase):
|
|||
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1269039237166321664"
|
||||
)
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 6, 5, 22, 51, 46))
|
||||
post.publication_date, datetime(2020, 6, 5, 22, 51, 46, tzinfo=timezone.utc)
|
||||
)
|
||||
|
||||
self.assertInHTML(
|
||||
|
|
@ -179,7 +177,7 @@ class TwitterBuilderTestCase(TestCase):
|
|||
post.url, f"{TWITTER_URL}/RobertsSpaceInd/status/1291080532361527296"
|
||||
)
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 8, 5, 18, 36, 0))
|
||||
post.publication_date, datetime(2020, 8, 5, 18, 36, 0, tzinfo=timezone.utc)
|
||||
)
|
||||
|
||||
self.assertIn(full_text, post.body)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import datetime
|
||||
from datetime import timezone as _timezone
|
||||
from unittest.mock import Mock, patch
|
||||
from uuid import uuid4
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
|
||||
from freezegun import freeze_time
|
||||
from ftfy import fix_text
|
||||
|
||||
|
|
@ -67,7 +66,8 @@ class TwitterCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 9, 18, 20, 32, 22))
|
||||
post.publication_date,
|
||||
datetime(2020, 9, 18, 20, 32, 22, tzinfo=_timezone.utc),
|
||||
)
|
||||
|
||||
title = truncate_text(
|
||||
|
|
@ -89,7 +89,8 @@ class TwitterCollectorTestCase(TestCase):
|
|||
)
|
||||
|
||||
self.assertEquals(
|
||||
post.publication_date, pytz.utc.localize(datetime(2020, 9, 18, 18, 50, 11))
|
||||
post.publication_date,
|
||||
datetime(2020, 9, 18, 18, 50, 11, tzinfo=_timezone.utc),
|
||||
)
|
||||
|
||||
body = fix_text(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from datetime import timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from django_celery_beat.models import PeriodicTask
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
|
|
@ -21,7 +21,7 @@ class FeedCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
self.form_data.update(
|
||||
name="new rule",
|
||||
url="https://www.rss.com/rss",
|
||||
timezone=pytz.utc,
|
||||
timezone=str(timezone.utc),
|
||||
category=str(self.category.pk),
|
||||
)
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ class FeedCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
|
||||
self.assertEquals(rule.type, RuleTypeChoices.feed)
|
||||
self.assertEquals(rule.url, "https://www.rss.com/rss")
|
||||
self.assertEquals(rule.timezone, str(pytz.utc))
|
||||
self.assertEquals(rule.timezone, str(timezone.utc))
|
||||
self.assertEquals(rule.favicon, None)
|
||||
self.assertEquals(rule.category.pk, self.category.pk)
|
||||
self.assertEquals(rule.user.pk, self.user.pk)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
from datetime import timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
from newsreader.news.collection.models import CollectionRule
|
||||
from newsreader.news.collection.reddit import REDDIT_API_URL, REDDIT_URL
|
||||
|
|
@ -38,7 +38,7 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
|
||||
self.assertEquals(rule.type, RuleTypeChoices.subreddit)
|
||||
self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww")
|
||||
self.assertEquals(rule.timezone, str(pytz.utc))
|
||||
self.assertEquals(rule.timezone, str(timezone.utc))
|
||||
self.assertEquals(rule.favicon, None)
|
||||
self.assertEquals(rule.category.pk, self.category.pk)
|
||||
self.assertEquals(rule.user.pk, self.user.pk)
|
||||
|
|
@ -70,7 +70,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
"name": self.rule.name,
|
||||
"url": self.rule.url,
|
||||
"category": str(self.category.pk),
|
||||
"timezone": pytz.utc,
|
||||
"timezone": str(timezone.utc),
|
||||
"reddit_allow_nfsw": False,
|
||||
"reddit_allow_spoiler": False,
|
||||
"reddit_allow_viewed": True,
|
||||
|
|
@ -125,7 +125,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
|
||||
self.assertEquals(rule.type, RuleTypeChoices.subreddit)
|
||||
self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww")
|
||||
self.assertEquals(rule.timezone, str(pytz.utc))
|
||||
self.assertEquals(rule.timezone, str(timezone.utc))
|
||||
self.assertEquals(rule.favicon, None)
|
||||
self.assertEquals(rule.category.pk, self.category.pk)
|
||||
self.assertEquals(rule.user.pk, self.user.pk)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from datetime import timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from django_celery_beat.models import PeriodicTask
|
||||
|
||||
from newsreader.news.collection.choices import RuleTypeChoices
|
||||
|
|
@ -37,7 +37,7 @@ class TwitterTimelineCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
rule.url,
|
||||
f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=RobertsSpaceInd&tweet_mode=extended",
|
||||
)
|
||||
self.assertEquals(rule.timezone, str(pytz.utc))
|
||||
self.assertEquals(rule.timezone, str(timezone.utc))
|
||||
self.assertEquals(rule.favicon, None)
|
||||
self.assertEquals(rule.category.pk, self.category.pk)
|
||||
self.assertEquals(rule.user.pk, self.user.pk)
|
||||
|
|
@ -70,7 +70,7 @@ class TwitterTimelineUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
"name": self.rule.name,
|
||||
"screen_name": self.rule.screen_name,
|
||||
"category": str(self.category.pk),
|
||||
"timezone": pytz.utc,
|
||||
"timezone": str(timezone.utc),
|
||||
}
|
||||
|
||||
def test_name_change(self):
|
||||
|
|
@ -123,7 +123,7 @@ class TwitterTimelineUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
|||
self.rule.url,
|
||||
f"{TWITTER_API_URL}/statuses/user_timeline.json?screen_name=CyberpunkGame&tweet_mode=extended",
|
||||
)
|
||||
self.assertEquals(self.rule.timezone, str(pytz.utc))
|
||||
self.assertEquals(self.rule.timezone, str(timezone.utc))
|
||||
self.assertEquals(self.rule.favicon, None)
|
||||
self.assertEquals(self.rule.category.pk, self.category.pk)
|
||||
self.assertEquals(self.rule.user.pk, self.user.pk)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,14 @@ import logging
|
|||
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime
|
||||
from datetime import timezone as _timezone
|
||||
from json import JSONDecodeError
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail
|
||||
from django.utils import timezone
|
||||
from django.utils.html import format_html, urlize
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
import pytz
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from ftfy import fix_text
|
||||
from requests_oauthlib import OAuth1 as OAuth
|
||||
|
|
@ -82,9 +81,11 @@ class TwitterBuilder(PostBuilder):
|
|||
Post, "title", self.sanitize_fragment(data["full_text"])
|
||||
)
|
||||
|
||||
publication_date = pytz.utc.localize(
|
||||
datetime.strptime(data["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
|
||||
parsed_date = datetime.strptime(
|
||||
data["created_at"], "%a %b %d %H:%M:%S +0000 %Y"
|
||||
)
|
||||
|
||||
publication_date = parsed_date.replace(tzinfo=_timezone.utc)
|
||||
except KeyError as e:
|
||||
raise BuilderMissingDataException(payload=data) from e
|
||||
except (OverflowError, OSError) as e:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import datetime
|
||||
from datetime import timezone as _timezone
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models.fields import CharField, TextField
|
||||
from django.utils import timezone
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
from requests.exceptions import RequestException
|
||||
|
|
@ -22,7 +22,7 @@ def build_publication_date(dt, tz):
|
|||
except (TypeError, ValueError):
|
||||
return timezone.now()
|
||||
|
||||
return published_parsed.astimezone(pytz.utc)
|
||||
return published_parsed.astimezone(_timezone.utc)
|
||||
|
||||
|
||||
def fetch(url, auth=None, headers={}):
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import json
|
||||
|
||||
from django.urls import reverse_lazy
|
||||
from zoneinfo import available_timezones
|
||||
|
||||
import pytz
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from django_celery_beat.models import IntervalSchedule, PeriodicTask
|
||||
|
||||
|
|
@ -25,7 +25,9 @@ class CollectionRuleDetailMixin:
|
|||
context_data = super().get_context_data(**kwargs)
|
||||
|
||||
categories = Category.objects.filter(user=self.request.user).order_by("name")
|
||||
timezones = [timezone for timezone in pytz.all_timezones]
|
||||
|
||||
_available_timezones = available_timezones()
|
||||
timezones = [timezone for timezone in _available_timezones]
|
||||
|
||||
context_data["categories"] = categories
|
||||
context_data["timezones"] = timezones
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import filters
|
||||
from rest_framework.compat import coreapi, coreschema
|
||||
|
|
@ -25,8 +25,8 @@ class ReadFilter(filters.BaseFilterBackend):
|
|||
required=False,
|
||||
location="query",
|
||||
schema=coreschema.String(
|
||||
title=force_text(self.query_param),
|
||||
description=force_text(_("Wether posts should be read or not")),
|
||||
title=force_str(self.query_param),
|
||||
description=force_str(_("Wether posts should be read or not")),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
@ -52,8 +52,8 @@ class SavedFilter(filters.BaseFilterBackend):
|
|||
required=False,
|
||||
location="query",
|
||||
schema=coreschema.String(
|
||||
title=force_text(self.query_param),
|
||||
description=force_text(_("Wether posts should be saved or not")),
|
||||
title=force_str(self.query_param),
|
||||
description=force_str(_("Wether posts should be saved or not")),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import json
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.accounts.tests.factories import UserFactory
|
||||
from newsreader.news.collection.tests.factories import FeedFactory
|
||||
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||
|
|
@ -29,15 +27,15 @@ class CategoryListViewTestCase(TestCase):
|
|||
def test_ordering(self):
|
||||
categories = [
|
||||
CategoryFactory(
|
||||
created=datetime(2019, 5, 20, 16, 7, 37, tzinfo=pytz.utc),
|
||||
created=datetime(2019, 5, 20, 16, 7, 37, tzinfo=timezone.utc),
|
||||
user=self.user,
|
||||
),
|
||||
CategoryFactory(
|
||||
created=datetime(2019, 7, 20, 18, 7, 37, tzinfo=pytz.utc),
|
||||
created=datetime(2019, 7, 20, 18, 7, 37, tzinfo=timezone.utc),
|
||||
user=self.user,
|
||||
),
|
||||
CategoryFactory(
|
||||
created=datetime(2019, 7, 20, 16, 7, 37, tzinfo=pytz.utc),
|
||||
created=datetime(2019, 7, 20, 16, 7, 37, tzinfo=timezone.utc),
|
||||
user=self.user,
|
||||
),
|
||||
]
|
||||
|
|
@ -430,12 +428,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second Reuters post",
|
||||
rule=reuters_rule,
|
||||
publication_date=datetime(2019, 5, 21, 15, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 21, 15, tzinfo=timezone.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First Reuters post",
|
||||
rule=reuters_rule,
|
||||
publication_date=datetime(2019, 5, 20, 12, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 12, tzinfo=timezone.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -443,12 +441,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second Guardian post",
|
||||
rule=guardian_rule,
|
||||
publication_date=datetime(2019, 5, 21, 14, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 21, 14, tzinfo=timezone.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First Guardian post",
|
||||
rule=guardian_rule,
|
||||
publication_date=datetime(2019, 5, 20, 11, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 11, tzinfo=timezone.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -456,12 +454,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second BBC post",
|
||||
rule=bbc_rule,
|
||||
publication_date=datetime(2019, 5, 21, 16, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 21, 16, tzinfo=timezone.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First BBC post",
|
||||
rule=bbc_rule,
|
||||
publication_date=datetime(2019, 5, 20, 13, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 13, tzinfo=timezone.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.accounts.tests.factories import UserFactory
|
||||
from newsreader.news.collection.tests.factories import FeedFactory
|
||||
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||
|
|
@ -32,17 +30,17 @@ class PostListViewTestCase(TestCase):
|
|||
FeedPostFactory(
|
||||
title="I'm the first post",
|
||||
rule=rule,
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 38, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 38, tzinfo=timezone.utc),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the second post",
|
||||
rule=rule,
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 37, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 37, tzinfo=timezone.utc),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the third post",
|
||||
rule=rule,
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 36, tzinfo=pytz.utc),
|
||||
publication_date=datetime(2019, 5, 20, 16, 7, 36, tzinfo=timezone.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from datetime import timezone
|
||||
|
||||
import factory
|
||||
import factory.fuzzy
|
||||
import pytz
|
||||
|
||||
from newsreader.accounts.tests.factories import UserFactory
|
||||
from newsreader.news.collection.reddit import REDDIT_API_URL
|
||||
|
|
@ -19,7 +20,7 @@ class PostFactory(factory.django.DjangoModelFactory):
|
|||
title = factory.Faker("sentence")
|
||||
body = factory.Faker("paragraph")
|
||||
author = factory.Faker("name")
|
||||
publication_date = factory.Faker("date_time_this_year", tzinfo=pytz.utc)
|
||||
publication_date = factory.Faker("date_time_this_year", tzinfo=timezone.utc)
|
||||
url = factory.Faker("url")
|
||||
remote_identifier = factory.Faker("uuid4")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
$fa-font-path: '/static/fonts';
|
||||
$fa-font-path: '~@fortawesome/fontawesome-free/webfonts';
|
||||
|
||||
@import '@fortawesome/fontawesome-free/scss/fontawesome';
|
||||
@import '@fortawesome/fontawesome-free/scss/solid';
|
||||
@import '@fortawesome/fontawesome-free/scss/regular';
|
||||
@import '~@fortawesome/fontawesome-free/scss/fontawesome';
|
||||
@import '~@fortawesome/fontawesome-free/scss/regular';
|
||||
@import '~@fortawesome/fontawesome-free/scss/brands';
|
||||
@import '~@fortawesome/fontawesome-free/scss/solid';
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
<link type="image/png" href="{% static 'favicon.png' %}" rel="shortcut icon" />
|
||||
<link type="image/png" href="{% static 'images/favicon.png' %}" rel="shortcut icon" />
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Newreader</title>
|
||||
<link type="image/png" href="{% static 'favicon.png' %}" rel="shortcut icon" />
|
||||
<link type="image/png" href="{% static 'images/favicon.png' %}" rel="shortcut icon" />
|
||||
{% block head %}
|
||||
<link href="{% static 'css/main.css' %}" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,6 @@ from django.contrib import admin
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.urls import include, path
|
||||
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.views import get_schema_view
|
||||
|
||||
from newsreader.accounts.urls import urlpatterns as login_urls
|
||||
from newsreader.news.core.views import NewsView
|
||||
from newsreader.news.urls import endpoints as news_endpoints
|
||||
|
|
@ -14,16 +11,12 @@ from newsreader.news.urls import urlpatterns as news_patterns
|
|||
|
||||
api_patterns = [path("api/", include((news_endpoints, "news")))]
|
||||
|
||||
schema_info = openapi.Info(title="Newsreader API", default_version="v1")
|
||||
schema_view = get_schema_view(schema_info, patterns=api_patterns)
|
||||
|
||||
urlpatterns = [
|
||||
path("", login_required(NewsView.as_view()), name="index"),
|
||||
path("", include((news_patterns, "news"))),
|
||||
path("", include((api_patterns, "api"))),
|
||||
path("accounts/", include((login_urls, "accounts")), name="accounts"),
|
||||
path("admin/", admin.site.urls, name="admin"),
|
||||
path("api/", schema_view.with_ui("swagger"), name="api"),
|
||||
path("api/auth/", include("rest_framework.urls"), name="rest_framework"),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { resolve } from 'path';
|
||||
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
||||
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import CopyPlugin from 'copy-webpack-plugin';
|
||||
|
||||
export default {
|
||||
resolve: { extensions: ['.js', '.scss'] },
|
||||
|
|
@ -10,6 +11,7 @@ export default {
|
|||
output: {
|
||||
path: resolve(__dirname, 'src', 'newsreader', 'static'),
|
||||
filename: 'js/[name].bundle.js',
|
||||
clean: true,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -23,26 +25,30 @@ export default {
|
|||
use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|woff|woff2)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'fonts',
|
||||
publicPath: '/static/fonts/',
|
||||
},
|
||||
test: /\.(ttf|woff|woff2|eot|otf)$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'fonts/[name][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(png|svg|jpg|jpeg)$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'images/[name][ext]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'css/main.css',
|
||||
allChunks: true,
|
||||
}),
|
||||
new CleanWebpackPlugin({
|
||||
cleanOnceBeforeBuildPatterns: ['js', 'css', 'fonts'],
|
||||
cleanAfterEveryBuildPatterns: ['!fonts/**'],
|
||||
new MiniCssExtractPlugin({ filename: 'css/main.css' }),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: './src/newsreader/assets/images/favicon.png',
|
||||
to: 'images/',
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue