formatted

This commit is contained in:
Untone 2021-08-21 02:17:15 +03:00
parent 90c552a8f3
commit 06c8d9c66b
4 changed files with 296 additions and 300 deletions

View File

@ -1,36 +1,36 @@
# discours-backend-next # discours-backend-next
Tech stack: Tech stack:
- pyjwt - pyjwt
- redis - redis
- ariadne - ariadne
- starlette - starlette
# Local development # Local development
Install redis and pipenv first Install redis and pipenv first
``` ```
brew install redis pipenv brew install redis pipenv
brew services start redis brew services start redis
``` ```
Create certificate files Create certificate files
```sh ```sh
./create_crt.sh ./create_crt.sh
``` ```
Then run API server Then run API server
``` ```
pipenv install pipenv install
pipenv run python server.py pipenv run python server.py
``` ```
Also see `Dockerfile` Also see `Dockerfile`
# How to do an authorized request # How to do an authorized request
Put the header 'Auth' with token from signInQuery or registerQuery. Put the header 'Auth' with token from signInQuery or registerQuery.

View File

@ -1,9 +1,9 @@
## Based on ## Based on
* pyjwt - pyjwt
* [ariadne](https://github.com/mirumee/ariadne) - [ariadne](https://github.com/mirumee/ariadne)
* [aioredis](https://github.com/aio-libs/aioredis) - [aioredis](https://github.com/aio-libs/aioredis)
* [starlette](https://github.com/encode/starlette)、 - [starlette](https://github.com/encode/starlette)、
* sqlalchmy ORM - sqlalchmy ORM
token is valid for one day, user can choose to logout, logout is revoke token token is valid for one day, user can choose to logout, logout is revoke token

View File

@ -10,10 +10,10 @@ pipenv install -r requirements.txt
## Using ## Using
Put the unpacked mongodump to the `data` folder and operate with `pipenv shell && python` Put the unpacked mongodump to the `data` folder and operate with
`pipenv shell && python`
1. get old data jsons
1. get old data jsons
```py ```py
import bson2json import bson2json
@ -23,19 +23,16 @@ bson2json.json_tables() # creates all the needed data json from bson mongodump
2. migrate users 2. migrate users
```py ```sh
import json pipenv run python migrate.py users
from migrations.users import migrate ```
Note: this will create db entries and it is not tolerant to existed unique email.
data = json.loads(open('data/users.json').read()) 3. then topics and shouts
newdata = {}
for u in data: ```sh
try: pipenv run python migrate.py topics
newdata[u['_id']] = migrate(u) pipenv run python migrate.py shouts
except: ```
print('FAIL!')
print(u)
Now you got the *.dict.json files which contain all the data with old and new(!) ids.
```

View File

@ -1,242 +1,241 @@
scalar DateTime scalar DateTime
################################### Payload ################################### Payload
type Result { type Result {
error: String error: String
} }
type AuthResult { type AuthResult {
error: String error: String
token: String token: String
user: User user: User
} }
type UserResult { type UserResult {
error: String error: String
user: User user: User
} }
type MessageResult { type MessageResult {
error: String error: String
message: Message message: Message
} }
input ShoutInput { input ShoutInput {
org_id: Int! org_id: Int!
slug: String! slug: String!
body: String! body: String!
replyTo: String # another shout replyTo: String # another shout
tags: [String] # actual values tags: [String] # actual values
topics: [String] # topic-slugs topics: [String] # topic-slugs
title: String title: String
versionOf: String versionOf: String
visibleForRoles: [String] # role ids are strings visibleForRoles: [String] # role ids are strings
visibleForUsers: [Int] visibleForUsers: [Int]
} }
input ProfileInput { input ProfileInput {
email: String email: String
username: String username: String
userpic: String userpic: String
} }
type ShoutResult { type ShoutResult {
error: String error: String
shout: Shout shout: Shout
} }
################################### Mutation ################################### Mutation
type Mutation { type Mutation {
# message # message
createMessage(body: String!, replyTo: Int): MessageResult! createMessage(body: String!, replyTo: Int): MessageResult!
updateMessage(id: Int!, body: String!): MessageResult! updateMessage(id: Int!, body: String!): MessageResult!
deleteMessage(messageId: Int!): Result! deleteMessage(messageId: Int!): Result!
# auth # auth
confirmEmail(token: String!): AuthResult! confirmEmail(token: String!): AuthResult!
requestPasswordReset(email: String!): Boolean! requestPasswordReset(email: String!): Boolean!
confirmPasswordReset(token: String!): Boolean! confirmPasswordReset(token: String!): Boolean!
registerUser(email: String!, password: String!): AuthResult! registerUser(email: String!, password: String!): AuthResult!
# updatePassword(password: String!, token: String!): Token! # updatePassword(password: String!, token: String!): Token!
# invalidateAllTokens: Boolean! # invalidateAllTokens: Boolean!
# invalidateTokenById(id: Int!): Boolean! # invalidateTokenById(id: Int!): Boolean!
# requestEmailConfirmation: User! # requestEmailConfirmation: User!
# shout # shout
createShout(input: ShoutInput!): ShoutResult! createShout(input: ShoutInput!): ShoutResult!
updateShout(input: ShoutInput!): ShoutResult! updateShout(input: ShoutInput!): ShoutResult!
deleteShout(slug: String!): Result! deleteShout(slug: String!): Result!
rateShout(slug: String!, value: Int!): Result! rateShout(slug: String!, value: Int!): Result!
# user profile # user profile
# rateUser(value: Int!): Result! # rateUser(value: Int!): Result!
# updateOnlineStatus: Result! # updateOnlineStatus: Result!
updateProfile(profile: ProfileInput!): Result! updateProfile(profile: ProfileInput!): Result!
} }
################################### Query ################################### Query
type Query { type Query {
# auth # auth
isEmailFree(email: String!): Result! isEmailFree(email: String!): Result!
signIn(email: String!, password: String!): AuthResult! signIn(email: String!, password: String!): AuthResult!
signOut: Result! signOut: Result!
# user profile # user profile
getCurrentUser: UserResult! getCurrentUser: UserResult!
getUserById(id: Int!): UserResult! getUserById(id: Int!): UserResult!
# getUserRating(shout: Int): Int! # getUserRating(shout: Int): Int!
# messages # messages
getMessages(count: Int = 100, page: Int = 1): [Message!]! getMessages(count: Int = 100, page: Int = 1): [Message!]!
# shouts # shouts
# getShoutRating(shout: Int): Int! # getShoutRating(shout: Int): Int!
# shoutsByAuthor(author: Int): [Shout]! # shoutsByAuthor(author: Int): [Shout]!
# shoutsByReplyTo(shout: Int): [Shout]! # shoutsByReplyTo(shout: Int): [Shout]!
# shoutsByTags(tags: [String]): [Shout]! # shoutsByTags(tags: [String]): [Shout]!
# shoutsByTime(time: DateTime): [Shout]! # shoutsByTime(time: DateTime): [Shout]!
# getOnlineUsers: [User!]! # getOnlineUsers: [User!]!
topAuthors: [User]! topAuthors: [User]!
topShouts: [Shout]! topShouts: [Shout]!
} }
############################################ Subscription ############################################ Subscription
type Subscription { type Subscription {
messageCreated: Message! messageCreated: Message!
messageUpdated: Message! messageUpdated: Message!
messageDeleted: Message! messageDeleted: Message!
onlineUpdated: [User!]! onlineUpdated: [User!]!
shoutUpdated: Shout! shoutUpdated: Shout!
userUpdated: User! userUpdated: User!
} }
############################################ Entities ############################################ Entities
type Role { type Role {
id: Int! id: Int!
name: String! name: String!
org_id: Int! org_id: Int!
# level: Int! # 1-8 # level: Int! # 1-8
desc: String desc: String
permissions: [Int!]! permissions: [Int!]!
} }
type Rating { type Rating {
createdBy: String! createdBy: String!
value: Int! value: Int!
} }
type Notification { type Notification {
kind: String! # unique primary key kind: String! # unique primary key
template: String! template: String!
variables: [String] variables: [String]
} }
type UserNotification { type UserNotification {
id: Int! # primary key id: Int! # primary key
user: Int! user: Int!
kind: String! # NotificationTemplate.name kind: String! # NotificationTemplate.name
values: [String] values: [String]
} }
type User { type User {
username: String! # email username: String! # email
createdAt: DateTime! createdAt: DateTime!
email: String email: String
password: String password: String
oauth: String # provider:token oauth: String # provider:token
viewname: String # to display viewname: String # to display
userpic: String userpic: String
links: [String] links: [String]
emailConfirmed: Boolean # should contain all emails too # TODO: pagination here emailConfirmed: Boolean # should contain all emails too # TODO: pagination here
id: Int! id: Int!
muted: Boolean muted: Boolean
rating: Int rating: Int
roles: [Role] roles: [Role]
updatedAt: DateTime updatedAt: DateTime
wasOnlineAt: DateTime wasOnlineAt: DateTime
ratings: [Rating] ratings: [Rating]
slug: String slug: String
bio: String bio: String
notifications: [Int] notifications: [Int]
} }
type Message { type Message {
author: Int! author: Int!
body: String! body: String!
createdAt: DateTime! createdAt: DateTime!
id: Int! id: Int!
replyTo: Int replyTo: Int
updatedAt: DateTime! updatedAt: DateTime!
visibleForUsers: [Int]! visibleForUsers: [Int]!
} }
# is publication # is publication
type Shout { type Shout {
slug: String! slug: String!
authors: [Int!]! authors: [Int!]!
body: String! body: String!
org_id: Int org_id: Int
cover: String cover: String
layout: String layout: String
createdAt: DateTime! createdAt: DateTime!
updatedAt: DateTime updatedAt: DateTime
deletedAt: DateTime deletedAt: DateTime
deletedBy: Int deletedBy: Int
rating: Int rating: Int
ratigns: [Rating] ratigns: [Rating]
published: Boolean published: Boolean
publishedAt: DateTime # if there is no published field - it is not published publishedAt: DateTime # if there is no published field - it is not published
replyTo: String # another shout replyTo: String # another shout
tags: [String] # actual values tags: [String] # actual values
topics: [String] # topic-slugs, order has matter topics: [String] # topic-slugs, order has matter
title: String title: String
subtitle: String subtitle: String
versionOf: String versionOf: String
visibleForRoles: [String] # role ids are strings visibleForRoles: [String] # role ids are strings
visibleForUsers: [Int] visibleForUsers: [Int]
views: Int views: Int
} }
type Topic { type Topic {
slug: String! # ID slug: String! # ID
createdBy: Int! # User createdBy: Int! # User
createdAt: DateTime! createdAt: DateTime!
value: String value: String
desc: String desc: String
parents: [String] # NOTE: topic can have parent topics parents: [String] # NOTE: topic can have parent topics
children: [String] # and children children: [String] # and children
} }
# TODO: resolvers to add/remove topics from publication # TODO: resolvers to add/remove topics from publication
type Proposal {
type Proposal { body: String!
body: String! shout: Int!
shout: Int! range: String # full / 0:2340
range: String # full / 0:2340 author: Int!
author: Int! createdAt: DateTime!
createdAt: DateTime! }
}
type Token {
type Token { createdAt: DateTime!
createdAt: DateTime! expiresAt: DateTime
expiresAt: DateTime id: Int!
id: Int! ownerId: Int!
ownerId: Int! usedAt: DateTime
usedAt: DateTime value: String!
value: String! }
}
type Like {
type Like { author: Int!
author: Int! id: Int!
id: Int! value: Int!
value: Int! shout: Int
shout: Int user: Int
user: Int }
}