refactored
This commit is contained in:
parent
158cb20717
commit
8aec6c6e07
|
@ -1,15 +0,0 @@
|
||||||
FROM python:3.8
|
|
||||||
|
|
||||||
EXPOSE 8081
|
|
||||||
|
|
||||||
RUN /usr/local/bin/python -m pip install --upgrade pip
|
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
|
||||||
|
|
||||||
COPY requirements.txt ./
|
|
||||||
|
|
||||||
RUN set -ex && pip install -r requirements.txt
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
CMD ["python", "server.py", "inbox"]
|
|
|
@ -1,21 +1,17 @@
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from graphql import GraphQLResolveInfo
|
from graphql import GraphQLResolveInfo
|
||||||
from jwt import DecodeError, ExpiredSignatureError
|
from jwt import DecodeError, ExpiredSignatureError
|
||||||
from starlette.authentication import AuthenticationBackend
|
from starlette.authentication import AuthenticationBackend
|
||||||
from starlette.requests import HTTPConnection
|
from starlette.requests import HTTPConnection
|
||||||
|
|
||||||
from auth.credentials import AuthCredentials, AuthUser
|
from auth.credentials import AuthCredentials, AuthUser
|
||||||
from auth.jwtcodec import JWTCodec
|
from auth.jwtcodec import JWTCodec
|
||||||
from auth.authorize import Authorize, TokenStorage
|
from auth.authorize import Authorize, TokenStorage
|
||||||
from exceptions import InvalidToken, OperationNotAllowed
|
from base.exceptions import InvalidToken
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from storages.users import UserStorage
|
from storages.users import UserStorage
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from redis import redis
|
|
||||||
from settings import JWT_AUTH_HEADER, EMAIL_TOKEN_LIFE_SPAN
|
from settings import JWT_AUTH_HEADER, EMAIL_TOKEN_LIFE_SPAN
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from auth.jwtcodec import JWTCodec
|
from auth.jwtcodec import JWTCodec
|
||||||
from redis import redis
|
from base.redis import redis
|
||||||
from settings import JWT_LIFE_SPAN
|
from settings import JWT_LIFE_SPAN
|
||||||
from auth.validations import User
|
from auth.validations import User
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from typing import List, Optional, Text
|
from typing import List, Optional, Text
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import requests
|
import requests
|
||||||
from starlette.responses import RedirectResponse
|
from starlette.responses import RedirectResponse
|
||||||
from starlette.exceptions import HTTPException
|
|
||||||
|
|
||||||
from auth.authenticate import EmailAuthenticate, ResetPassword
|
from auth.authenticate import EmailAuthenticate, ResetPassword
|
||||||
|
from base.orm import local_session
|
||||||
from settings import BACKEND_URL, MAILGUN_API_KEY, MAILGUN_DOMAIN, RESET_PWD_URL, \
|
from settings import BACKEND_URL, MAILGUN_API_KEY, MAILGUN_DOMAIN, RESET_PWD_URL, \
|
||||||
CONFIRM_EMAIL_URL, ERROR_URL_ON_FRONTEND
|
CONFIRM_EMAIL_URL, ERROR_URL_ON_FRONTEND
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from auth.password import Password
|
from auth.password import Password
|
||||||
from exceptions import InvalidPassword, ObjectNotExist
|
from base.exceptions import InvalidPassword, ObjectNotExist
|
||||||
from orm import User as OrmUser
|
from orm import User as OrmUser
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from auth.validations import User
|
from auth.validations import User
|
||||||
|
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
from authlib.integrations.starlette_client import OAuth
|
from authlib.integrations.starlette_client import OAuth
|
||||||
from starlette.responses import RedirectResponse
|
from starlette.responses import RedirectResponse
|
||||||
|
|
||||||
from urllib.parse import quote_plus
|
|
||||||
|
|
||||||
from auth.authorize import Authorize
|
from auth.authorize import Authorize
|
||||||
from auth.identity import Identity
|
from auth.identity import Identity
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import aioredis
|
import aioredis
|
||||||
|
|
||||||
from settings import REDIS_URL
|
from settings import REDIS_URL
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,3 +50,9 @@ if __name__ == '__main__':
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
asyncio.run(test())
|
asyncio.run(test())
|
||||||
|
|
||||||
|
|
||||||
|
redis = Redis()
|
||||||
|
|
||||||
|
__all__ = ['redis']
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
from importlib import import_module
|
|
||||||
|
|
||||||
from ariadne import load_schema_from_path, make_executable_schema
|
|
||||||
|
|
||||||
from ariadne.asgi import GraphQL
|
|
||||||
from starlette.applications import Starlette
|
|
||||||
from starlette.middleware import Middleware
|
|
||||||
from starlette.middleware.authentication import AuthenticationMiddleware
|
|
||||||
from starlette.middleware.sessions import SessionMiddleware
|
|
||||||
from starlette.routing import Route
|
|
||||||
|
|
||||||
from auth.authenticate import JWTAuthenticate
|
|
||||||
from redis import redis
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from resolvers_base import resolvers
|
|
||||||
import inbox_resolvers.inbox
|
|
||||||
|
|
||||||
schema = make_executable_schema(load_schema_from_path("inbox_schema.graphql"), resolvers)
|
|
||||||
|
|
||||||
middleware = [
|
|
||||||
Middleware(AuthenticationMiddleware, backend=JWTAuthenticate()),
|
|
||||||
Middleware(SessionMiddleware, secret_key="!secret")
|
|
||||||
]
|
|
||||||
|
|
||||||
async def start_up():
|
|
||||||
await redis.connect()
|
|
||||||
|
|
||||||
async def shutdown():
|
|
||||||
await redis.disconnect()
|
|
||||||
|
|
||||||
app = Starlette(debug=True, on_startup=[start_up], on_shutdown=[shutdown], middleware=middleware)
|
|
||||||
app.mount("/", GraphQL(schema, debug=True))
|
|
|
@ -1,87 +0,0 @@
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
################################### Payload
|
|
||||||
|
|
||||||
type Result {
|
|
||||||
error: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type MessageResult {
|
|
||||||
error: String
|
|
||||||
message: Message
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MessageStatus {
|
|
||||||
NEW
|
|
||||||
UPDATED
|
|
||||||
DELETED
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChatUpdatedResult {
|
|
||||||
error: String
|
|
||||||
status: MessageStatus
|
|
||||||
message: Message
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateChatResult {
|
|
||||||
chatId: String
|
|
||||||
error: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type EnterChatResult {
|
|
||||||
chat: Chat
|
|
||||||
messages: [Message]
|
|
||||||
error: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserChatsResult {
|
|
||||||
error: String
|
|
||||||
chats: [String]
|
|
||||||
}
|
|
||||||
|
|
||||||
################################### Mutation
|
|
||||||
|
|
||||||
type Mutation {
|
|
||||||
# message
|
|
||||||
createChat(description: String): CreateChatResult!
|
|
||||||
createMessage(chatId: String!, body: String!, replyTo: Int): MessageResult!
|
|
||||||
updateMessage(chatId: String!, id: Int!, body: String!): MessageResult!
|
|
||||||
deleteMessage(chatId: String!, id: Int!): Result!
|
|
||||||
|
|
||||||
markAsRead(chatId: String!, ids: [Int]!): Result!
|
|
||||||
}
|
|
||||||
|
|
||||||
################################### Query
|
|
||||||
|
|
||||||
type Query {
|
|
||||||
userChats: UserChatsResult!
|
|
||||||
enterChat(chatId: String!, size: Int = 50): EnterChatResult!
|
|
||||||
getMessages(chatId: String!, size: Int!, page: Int!): [Message]!
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################ Subscription
|
|
||||||
|
|
||||||
type Subscription {
|
|
||||||
chatUpdated(chatId: String!): ChatUpdatedResult!
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################ Entities
|
|
||||||
|
|
||||||
|
|
||||||
type Message {
|
|
||||||
author: String!
|
|
||||||
chatRoom: Int!
|
|
||||||
body: String!
|
|
||||||
createdAt: DateTime!
|
|
||||||
id: Int!
|
|
||||||
replyTo: Int
|
|
||||||
updatedAt: DateTime!
|
|
||||||
visibleForUsers: [Int]!
|
|
||||||
}
|
|
||||||
|
|
||||||
type Chat {
|
|
||||||
id: Int!
|
|
||||||
createdAt: DateTime!
|
|
||||||
updatedAt: DateTime!
|
|
||||||
description: String
|
|
||||||
}
|
|
4
main.py
4
main.py
|
@ -9,8 +9,8 @@ from starlette.routing import Route
|
||||||
from auth.authenticate import JWTAuthenticate
|
from auth.authenticate import JWTAuthenticate
|
||||||
from auth.oauth import oauth_login, oauth_authorize
|
from auth.oauth import oauth_login, oauth_authorize
|
||||||
from auth.email import email_authorize
|
from auth.email import email_authorize
|
||||||
from redis import redis
|
from base.redis import redis
|
||||||
from resolvers.base import resolvers
|
from base.resolvers import resolvers
|
||||||
from resolvers.zine import ShoutsCache
|
from resolvers.zine import ShoutsCache
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
# from storages.gittask import GitTask
|
# from storages.gittask import GitTask
|
||||||
|
|
180
nginx.conf
180
nginx.conf
|
@ -1,180 +0,0 @@
|
||||||
|
|
||||||
#user nobody;
|
|
||||||
worker_processes 1;
|
|
||||||
|
|
||||||
#error_log logs/error.log;
|
|
||||||
#error_log logs/error.log notice;
|
|
||||||
error_log error.log info;
|
|
||||||
|
|
||||||
#pid logs/nginx.pid;
|
|
||||||
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
# '$status $body_bytes_sent "$http_referer" '
|
|
||||||
# '"$http_user_agent" "$http_x_forwarded_for"';
|
|
||||||
|
|
||||||
#access_log logs/access.log main;
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
#tcp_nopush on;
|
|
||||||
|
|
||||||
#keepalive_timeout 0;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
#gzip on;
|
|
||||||
|
|
||||||
map $http_origin $allow_origin {
|
|
||||||
~^https?://(.*\.)?localhost:3000|new.discours.io|discours.io()(:\d+)?$ $http_origin;
|
|
||||||
default "";
|
|
||||||
}
|
|
||||||
|
|
||||||
upstream discoursio-api-8080 {
|
|
||||||
server 0.0.0.0:8080;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen localhost:8000;
|
|
||||||
#server_name localhost;
|
|
||||||
#charset koi8-r;
|
|
||||||
# access_log logs/host.access.log main;
|
|
||||||
|
|
||||||
#location / {
|
|
||||||
# root html;
|
|
||||||
# index index.html index.htm;
|
|
||||||
#}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
gzip on;
|
|
||||||
gzip_min_length 1100;
|
|
||||||
gzip_buffers 4 32k;
|
|
||||||
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_comp_level 6;
|
|
||||||
|
|
||||||
proxy_pass http://discoursio-api-8080;
|
|
||||||
http2_push_preload on;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_read_timeout 60s;
|
|
||||||
proxy_buffer_size 4096;
|
|
||||||
proxy_buffering on;
|
|
||||||
proxy_buffers 8 4096;
|
|
||||||
proxy_busy_buffers_size 8192;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $http_connection;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Request-Start $msec;
|
|
||||||
|
|
||||||
|
|
||||||
if ($request_method = 'OPTIONS') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
|
||||||
#
|
|
||||||
# Custom headers and headers various browsers *should* be OK with but aren't
|
|
||||||
#
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
|
||||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
|
||||||
#
|
|
||||||
# Tell client that this pre-flight info is valid for 20 days
|
|
||||||
#
|
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
|
||||||
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
|
||||||
add_header 'Content-Length' 0;
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request_method = 'POST') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request_method = 'GET') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*:' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
||||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
||||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# redirect server error pages to the static page /50x.html
|
|
||||||
#
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
|
|
||||||
#
|
|
||||||
#location ~ \.php$ {
|
|
||||||
# proxy_pass http://127.0.0.1;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
|
|
||||||
#
|
|
||||||
#location ~ \.php$ {
|
|
||||||
# root html;
|
|
||||||
# fastcgi_pass 127.0.0.1:9000;
|
|
||||||
# fastcgi_index index.php;
|
|
||||||
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
|
|
||||||
# include fastcgi_params;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# deny access to .htaccess files, if Apache's document root
|
|
||||||
# concurs with nginx's one
|
|
||||||
#
|
|
||||||
#location ~ /\.ht {
|
|
||||||
# deny all;
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# another virtual host using mix of IP-, name-, and port-based configuration
|
|
||||||
#
|
|
||||||
#server {
|
|
||||||
# listen 8000;
|
|
||||||
# listen somename:8080;
|
|
||||||
# server_name somename alias another.alias;
|
|
||||||
|
|
||||||
# location / {
|
|
||||||
# root html;
|
|
||||||
# index index.html index.htm;
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
|
|
||||||
|
|
||||||
# HTTPS server
|
|
||||||
#
|
|
||||||
#server {
|
|
||||||
# listen 443 ssl;
|
|
||||||
# server_name localhost;
|
|
||||||
|
|
||||||
# ssl_certificate cert.pem;
|
|
||||||
# ssl_certificate_key cert.key;
|
|
||||||
|
|
||||||
# ssl_session_cache shared:SSL:1m;
|
|
||||||
# ssl_session_timeout 5m;
|
|
||||||
|
|
||||||
# ssl_ciphers HIGH:!aNULL:!MD5;
|
|
||||||
# ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# location / {
|
|
||||||
# root html;
|
|
||||||
# index index.html index.htm;
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
include servers/*;
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@ from orm.reaction import Reaction
|
||||||
from storages.topics import TopicStorage
|
from storages.topics import TopicStorage
|
||||||
from storages.users import UserStorage
|
from storages.users import UserStorage
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
from orm.base import Base, engine, local_session
|
from base.orm import Base, engine, local_session
|
||||||
|
|
||||||
__all__ = ["User", "Role", "Operation", "Permission", \
|
__all__ = ["User", "Role", "Operation", "Permission", \
|
||||||
"Community", "Shout", "Topic", "TopicFollower", \
|
"Community", "Shout", "Topic", "TopicFollower", \
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, String, ForeignKey, DateTime
|
from sqlalchemy import Column, String, ForeignKey, DateTime
|
||||||
from orm.base import Base, local_session
|
from base.orm import Base, local_session
|
||||||
|
|
||||||
class CommunityFollower(Base):
|
class CommunityFollower(Base):
|
||||||
__tablename__ = 'community_followers'
|
__tablename__ = 'community_followers'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from sqlalchemy import Column, String, JSON as JSONType
|
from sqlalchemy import Column, String, JSON as JSONType
|
||||||
from orm.base import Base
|
from base.orm import Base
|
||||||
|
|
||||||
class Notification(Base):
|
class Notification(Base):
|
||||||
__tablename__ = 'notification'
|
__tablename__ = 'notification'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import warnings
|
import warnings
|
||||||
from sqlalchemy import String, Column, ForeignKey, UniqueConstraint, TypeDecorator
|
from sqlalchemy import String, Column, ForeignKey, UniqueConstraint, TypeDecorator
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from orm.base import Base, REGISTRY, engine, local_session
|
from base.orm import Base, REGISTRY, engine, local_session
|
||||||
from orm.community import Community
|
from orm.community import Community
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, String, ForeignKey, DateTime
|
from sqlalchemy import Column, String, ForeignKey, DateTime
|
||||||
from orm.base import Base, local_session
|
from base.orm import Base, local_session
|
||||||
import enum
|
import enum
|
||||||
from sqlalchemy import Enum
|
from sqlalchemy import Enum
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
|
|
|
@ -6,7 +6,7 @@ from orm.topic import Topic, ShoutTopic
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from storages.reactions import ReactionsStorage
|
from storages.reactions import ReactionsStorage
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
from orm.base import Base
|
from base.orm import Base
|
||||||
|
|
||||||
|
|
||||||
class ShoutReactionsFollower(Base):
|
class ShoutReactionsFollower(Base):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, String, ForeignKey, DateTime, JSON as JSONType
|
from sqlalchemy import Column, String, ForeignKey, DateTime, JSON as JSONType
|
||||||
from orm.base import Base
|
from base.orm import Base
|
||||||
|
|
||||||
class ShoutTopic(Base):
|
class ShoutTopic(Base):
|
||||||
__tablename__ = 'shout_topic'
|
__tablename__ = 'shout_topic'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType
|
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from orm.base import Base, local_session
|
from base.orm import Base, local_session
|
||||||
from orm.rbac import Role
|
from orm.rbac import Role
|
||||||
from storages.roles import RoleStorage
|
from storages.roles import RoleStorage
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
from redis.client import Redis
|
|
||||||
|
|
||||||
redis = Redis()
|
|
||||||
|
|
||||||
__all__ = ['redis']
|
|
|
@ -11,6 +11,9 @@ from resolvers.editor import create_shout, delete_shout, update_shout
|
||||||
from resolvers.community import create_community, delete_community, get_community, get_communities
|
from resolvers.community import create_community, delete_community, get_community, get_communities
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"follow",
|
||||||
|
"unfollow",
|
||||||
|
|
||||||
# auth
|
# auth
|
||||||
"login",
|
"login",
|
||||||
"register",
|
"register",
|
||||||
|
|
|
@ -7,10 +7,10 @@ from auth.identity import Identity
|
||||||
from auth.password import Password
|
from auth.password import Password
|
||||||
from auth.email import send_confirm_email, send_auth_email, send_reset_password_email
|
from auth.email import send_confirm_email, send_auth_email, send_reset_password_email
|
||||||
from orm import User, Role
|
from orm import User, Role
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from resolvers.profile import get_user_info
|
from resolvers.profile import get_user_info
|
||||||
from exceptions import InvalidPassword, InvalidToken
|
from base.exceptions import InvalidPassword, InvalidToken
|
||||||
from settings import JWT_AUTH_HEADER
|
from settings import JWT_AUTH_HEADER
|
||||||
|
|
||||||
@mutation.field("confirmEmail")
|
@mutation.field("confirmEmail")
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from resolvers.base import mutation
|
from base.resolvers import mutation
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
|
|
||||||
@mutation.field("inviteAuthor")
|
@mutation.field("inviteAuthor")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from orm.community import Community, CommunityFollower
|
from orm.community import Community, CommunityFollower
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from orm import Shout
|
from orm import Shout
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.rbac import Resource
|
from orm.rbac import Resource
|
||||||
from orm.shout import ShoutAuthor, ShoutTopic
|
from orm.shout import ShoutAuthor, ShoutTopic
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from resolvers.base import mutation
|
from base.resolvers import mutation
|
||||||
from resolvers.reactions import reactions_follow, reactions_unfollow
|
from resolvers.reactions import reactions_follow, reactions_unfollow
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from sqlalchemy import and_, desc, query
|
from sqlalchemy import and_, desc, query
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
from resolvers_base import mutation, query, subscription
|
from base.resolvers import mutation, query, subscription
|
||||||
|
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
|
|
||||||
import asyncio, uuid, json
|
import asyncio, uuid, json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from base.redis import redis
|
||||||
from redis import redis
|
|
||||||
|
|
||||||
class ChatFollowing:
|
class ChatFollowing:
|
||||||
queue = asyncio.Queue()
|
queue = asyncio.Queue()
|
|
@ -2,13 +2,13 @@ from orm.user import User, UserRole, Role, UserRating, AuthorFollower
|
||||||
from storages.users import UserStorage
|
from storages.users import UserStorage
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.topic import Topic, TopicFollower
|
from orm.topic import Topic, TopicFollower
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from resolvers.community import get_followed_communities
|
from resolvers.community import get_followed_communities
|
||||||
from resolvers.reactions import get_shout_reactions
|
from resolvers.reactions import get_shout_reactions
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from inbox_resolvers.inbox import get_inbox_counter
|
from resolvers.inbox import get_inbox_counter
|
||||||
from sqlalchemy import and_, desc
|
from sqlalchemy import and_, desc
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
from sqlalchemy import and_, desc, func, select
|
|
||||||
from sqlalchemy.orm import selectinload, joinedload
|
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.shout import Shout, ShoutReactionsFollower
|
from orm.shout import ShoutReactionsFollower
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from storages.reactions import ReactionsStorage
|
from storages.reactions import ReactionsStorage
|
||||||
from storages.shoutscache import ShoutsCache
|
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
from typing import List
|
|
||||||
|
|
||||||
def reactions_follow(user, slug, auto=False):
|
def reactions_follow(user, slug, auto=False):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
|
|
|
@ -3,8 +3,8 @@ from storages.topics import TopicStorage
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
from storages.topicstat import TopicStat
|
from storages.topicstat import TopicStat
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from resolvers.base import mutation, query
|
from base.resolvers import mutation, query
|
||||||
from storages.shoutscache import ShoutsCache
|
from storages.shoutscache import ShoutsCache
|
||||||
from storages.viewed import ViewedStorage
|
from storages.viewed import ViewedStorage
|
||||||
from resolvers.profile import author_follow, author_unfollow
|
from resolvers.profile import author_follow, author_unfollow
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
from ariadne import MutationType, QueryType, SubscriptionType, ScalarType
|
|
||||||
|
|
||||||
|
|
||||||
query = QueryType()
|
|
||||||
mutation = MutationType()
|
|
||||||
subscription = SubscriptionType()
|
|
||||||
|
|
||||||
|
|
||||||
datetime_scalar = ScalarType("DateTime")
|
|
||||||
|
|
||||||
@datetime_scalar.serializer
|
|
||||||
def serialize_datetime(value):
|
|
||||||
return value.isoformat()
|
|
||||||
|
|
||||||
resolvers = [query, mutation, subscription, datetime_scalar]
|
|
|
@ -2,19 +2,43 @@ scalar DateTime
|
||||||
|
|
||||||
################################### Payload ###################################
|
################################### Payload ###################################
|
||||||
|
|
||||||
type CurrentUserInfo {
|
type MessageResult {
|
||||||
inbox: Int
|
error: String
|
||||||
topics: [String]!
|
message: Message
|
||||||
authors: [String]!
|
}
|
||||||
reactions: [String]!
|
|
||||||
communities: [String]!
|
enum MessageStatus {
|
||||||
|
NEW
|
||||||
|
UPDATED
|
||||||
|
DELETED
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatUpdatedResult {
|
||||||
|
error: String
|
||||||
|
status: MessageStatus
|
||||||
|
message: Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateChatResult {
|
||||||
|
chatId: String
|
||||||
|
error: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnterChatResult {
|
||||||
|
chat: Chat
|
||||||
|
messages: [Message]
|
||||||
|
error: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserChatsResult {
|
||||||
|
error: String
|
||||||
|
chats: [String]
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthResult {
|
type AuthResult {
|
||||||
error: String
|
error: String
|
||||||
token: String
|
token: String
|
||||||
user: User
|
user: User
|
||||||
info: CurrentUserInfo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result {
|
type Result {
|
||||||
|
@ -101,6 +125,13 @@ enum FollowingEntity {
|
||||||
################################### Mutation
|
################################### Mutation
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
# inbox
|
||||||
|
createChat(description: String): CreateChatResult!
|
||||||
|
createMessage(chatId: String!, body: String!, replyTo: Int): MessageResult!
|
||||||
|
updateMessage(chatId: String!, id: Int!, body: String!): MessageResult!
|
||||||
|
deleteMessage(chatId: String!, id: Int!): Result!
|
||||||
|
markAsRead(chatId: String!, ids: [Int]!): Result!
|
||||||
|
|
||||||
# auth
|
# auth
|
||||||
confirmEmail(token: String!): AuthResult!
|
confirmEmail(token: String!): AuthResult!
|
||||||
registerUser(email: String!, password: String): AuthResult!
|
registerUser(email: String!, password: String): AuthResult!
|
||||||
|
@ -155,6 +186,10 @@ type Mutation {
|
||||||
################################### Query
|
################################### Query
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
|
# inbox
|
||||||
|
userChats: UserChatsResult!
|
||||||
|
enterChat(chatId: String!, size: Int = 50): EnterChatResult!
|
||||||
|
getMessages(chatId: String!, size: Int!, page: Int!): [Message]!
|
||||||
|
|
||||||
# auth
|
# auth
|
||||||
isEmailUsed(email: String!): Boolean!
|
isEmailUsed(email: String!): Boolean!
|
||||||
|
@ -212,6 +247,7 @@ type Query {
|
||||||
############################################ Subscription
|
############################################ Subscription
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
|
chatUpdated(chatId: String!): ChatUpdatedResult!
|
||||||
onlineUpdated: [User!]!
|
onlineUpdated: [User!]!
|
||||||
shoutUpdated: Shout!
|
shoutUpdated: Shout!
|
||||||
userUpdated: User!
|
userUpdated: User!
|
||||||
|
@ -395,3 +431,21 @@ type Token {
|
||||||
usedAt: DateTime
|
usedAt: DateTime
|
||||||
value: String!
|
value: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Message {
|
||||||
|
author: String!
|
||||||
|
chatRoom: Int!
|
||||||
|
body: String!
|
||||||
|
createdAt: DateTime!
|
||||||
|
id: Int!
|
||||||
|
replyTo: Int
|
||||||
|
updatedAt: DateTime!
|
||||||
|
visibleForUsers: [Int]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Chat {
|
||||||
|
id: Int!
|
||||||
|
createdAt: DateTime!
|
||||||
|
updatedAt: DateTime!
|
||||||
|
description: String
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from settings import PORT, INBOX_SERVICE_PORT
|
from settings import PORT
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -16,8 +16,5 @@ if __name__ == '__main__':
|
||||||
("Access-Control-Allow-Credentials", "true")
|
("Access-Control-Allow-Credentials", "true")
|
||||||
]
|
]
|
||||||
uvicorn.run("main:app", host="localhost", port=8080, headers=headers) #, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True)
|
uvicorn.run("main:app", host="localhost", port=8080, headers=headers) #, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True)
|
||||||
elif inbox_service:
|
|
||||||
print("INBOX SERVICE")
|
|
||||||
uvicorn.run("inbox_main:app", host="0.0.0.0", port=INBOX_SERVICE_PORT)
|
|
||||||
else :
|
else :
|
||||||
uvicorn.run("main:app", host="0.0.0.0", port=PORT)
|
uvicorn.run("main:app", host="0.0.0.0", port=PORT)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from sqlalchemy import and_, desc, func
|
from sqlalchemy import and_, desc, func
|
||||||
from sqlalchemy.orm import selectinload, joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.reaction import Reaction, ReactionKind
|
from orm.reaction import Reaction, ReactionKind
|
||||||
from orm.topic import ShoutTopic, Topic
|
from orm.topic import ShoutTopic
|
||||||
|
|
||||||
|
|
||||||
def kind_to_rate(kind) -> int:
|
def kind_to_rate(kind) -> int:
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from orm.rbac import Role
|
from orm.rbac import Role
|
||||||
|
|
||||||
class RoleStorage:
|
class RoleStorage:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.shout import ShoutAuthor
|
from orm.shout import ShoutAuthor
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import asyncio
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from sqlalchemy import and_, desc, func, select
|
from sqlalchemy import and_, desc, func, select
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout
|
||||||
from storages.reactions import ReactionsStorage
|
from storages.reactions import ReactionsStorage
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from orm.base import local_session
|
from base.orm import local_session
|
||||||
from storages.shoutauthor import ShoutAuthorStorage
|
from storages.shoutauthor import ShoutAuthorStorage
|
||||||
from orm.topic import ShoutTopic, TopicFollower
|
from orm.topic import ShoutTopic, TopicFollower
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
from orm.user import User
|
from orm.user import User
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy import Column, DateTime, ForeignKey, Integer
|
from sqlalchemy import Column, DateTime, ForeignKey, Integer
|
||||||
from sqlalchemy.orm.attributes import flag_modified
|
from sqlalchemy.orm.attributes import flag_modified
|
||||||
from orm.base import Base, local_session
|
from base.orm import Base, local_session
|
||||||
|
|
||||||
|
|
||||||
class ViewedByDay(Base):
|
class ViewedByDay(Base):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user