379 lines
12 KiB
Python
379 lines
12 KiB
Python
from datetime import datetime
|
|
from typing import List, Optional
|
|
from sqlalchemy import create_engine, String, select, ForeignKey
|
|
from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column, relationship
|
|
import strawberry
|
|
import json
|
|
import uvicorn
|
|
from fastapi import FastAPI
|
|
from strawberry.fastapi import GraphQLRouter
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
from strawberry.scalars import JSON
|
|
from xmlrpc.client import ServerProxy
|
|
from config import Config
|
|
|
|
|
|
def connect():
|
|
return create_engine(Config.db_connection_string, echo=True)
|
|
|
|
|
|
def exec_function(function: str, **kwargs):
|
|
proxy = ServerProxy(Config.enserver_url)
|
|
result = proxy.__getattr__(function)(kwargs)
|
|
return result
|
|
|
|
|
|
@strawberry.type
|
|
class UsersGQL:
|
|
users: JSON
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
def tow(day: int, hour: int, minute: int):
|
|
return minute + hour * 60 + day * 60 * 24
|
|
|
|
|
|
class User(Base):
|
|
__tablename__ = 'users'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
username: Mapped[str]
|
|
passwd: Mapped[str]
|
|
bndname: Mapped[str]
|
|
newbnd: Mapped[bool]
|
|
active: Mapped[bool]
|
|
upstream: Mapped[bool]
|
|
|
|
profiles: Mapped[List['Profile']] = relationship(
|
|
back_populates='user', cascade='all, delete-orphan'
|
|
)
|
|
|
|
income_branches: Mapped[List['IncomeBranch']] = relationship(
|
|
back_populates='user', cascade='all, delete-orphan'
|
|
)
|
|
|
|
schedule: Mapped[List['Schedule']] = relationship(
|
|
back_populates='user', cascade='all, delete-orphan'
|
|
)
|
|
|
|
queue: Mapped[List['Queue']] = relationship(
|
|
back_populates='user', cascade='all, delete-orphan'
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
return f'User(id={self.id!r}, username={self.username!r}, password={self.passwd!r}, newbnd={self.newbnd})'
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
'id': self.id,
|
|
'username': self.username,
|
|
'bndname': self.bndname,
|
|
'newbnd': self.newbnd,
|
|
'active': self.active,
|
|
'upstream': self.upstream,
|
|
'profiles': [x.to_dict() for x in self.profiles],
|
|
'schedule': [x.to_dict() for x in self.schedule],
|
|
'queue': [x.to_dict() for x in self.queue],
|
|
'income_branches': [x.to_dict() for x in self.income_branches],
|
|
}
|
|
|
|
def is_active_now(self):
|
|
if not len(self.schedule):
|
|
return True
|
|
dt = datetime.now()
|
|
curr_tow = tow(dt.weekday(), dt.hour, dt.minute)
|
|
for x in self.schedule:
|
|
if (tow(x.day_start, x.hour_start, x.minute_start) <= curr_tow
|
|
<= tow(x.day_end, x.hour_end, x.minute_end)):
|
|
return True
|
|
return False
|
|
|
|
|
|
class Profile(Base):
|
|
__tablename__ = 'profiles'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
|
|
scheme: Mapped[str]
|
|
branch: Mapped[str] = mapped_column(String, nullable=True)
|
|
json: Mapped[str] = mapped_column(String, nullable=True)
|
|
|
|
user: Mapped['User'] = relationship(back_populates='profiles')
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
'id': self.id,
|
|
'scheme': self.scheme,
|
|
'branch': self.branch,
|
|
'json': self.json,
|
|
}
|
|
|
|
|
|
class IncomeBranch(Base):
|
|
__tablename__ = 'income_branches'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
|
|
scheme: Mapped[str]
|
|
branch: Mapped[str]
|
|
local_scheme: Mapped[str]
|
|
|
|
user: Mapped['User'] = relationship(back_populates='income_branches')
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
'id': self.id,
|
|
'scheme': self.scheme,
|
|
'branch': self.branch,
|
|
'local_scheme': self.local_scheme,
|
|
}
|
|
|
|
|
|
class Schedule(Base):
|
|
__tablename__ = 'schedule'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
|
|
day_start: Mapped[int]
|
|
hour_start: Mapped[int]
|
|
minute_start: Mapped[int]
|
|
day_end: Mapped[int]
|
|
hour_end: Mapped[int]
|
|
minute_end: Mapped[int]
|
|
|
|
user: Mapped['User'] = relationship(back_populates='schedule')
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
'id': self.id,
|
|
'day_start': self.day_start,
|
|
'hour_start': self.hour_start,
|
|
'minute_start': self.minute_start,
|
|
'day_end': self.day_end,
|
|
'hour_end': self.hour_end,
|
|
'minute_end': self.minute_end,
|
|
}
|
|
|
|
|
|
class Queue(Base):
|
|
__tablename__ = 'queue'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
|
|
commit_id: Mapped[str]
|
|
schema: Mapped[str]
|
|
|
|
user: Mapped['User'] = relationship(back_populates='queue')
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
'id': self.id,
|
|
'bnd': self.user.bndname,
|
|
'commit_id': self.commit_id,
|
|
'schema': self.schema,
|
|
}
|
|
|
|
|
|
class Schemas(Base):
|
|
__tablename__ = 'schemas'
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
schema: Mapped[str]
|
|
schema_type: Mapped[str]
|
|
|
|
|
|
@strawberry.type
|
|
class Query:
|
|
@strawberry.field()
|
|
def users(self) -> UsersGQL:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
stmt = select(User)
|
|
return UsersGQL(users=[json.dumps(user.to_dict()) for user in session.scalars(stmt)])
|
|
|
|
@strawberry.field()
|
|
def user(self, id: int) -> UsersGQL:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
return UsersGQL(users=json.dumps(session.query(User).filter(User.id == id).one_or_none().to_dict()))
|
|
|
|
@strawberry.field()
|
|
def queue(self) -> UsersGQL:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
stmt = select(Queue)
|
|
return UsersGQL(users=[json.dumps(queue.to_dict()) for queue in session.scalars(stmt)])
|
|
|
|
|
|
@strawberry.type
|
|
class Mutation:
|
|
@strawberry.mutation
|
|
def update_user(self, id_: int, bndname: str, newbnd: bool, active: bool, upstream: bool, passwd: str,
|
|
username: str) -> bool:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
user = session.query(User).get(id_)
|
|
user.username = username
|
|
user.bndname = bndname
|
|
user.newbnd = newbnd
|
|
user.active = active
|
|
user.upstream = upstream
|
|
user.passwd = passwd
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def create_user(self, username: str, passwd: str) -> int:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
user = User(username=username, passwd=passwd, bndname=username, active=False, newbnd=True, upstream=False)
|
|
session.add_all([user])
|
|
session.commit()
|
|
return user.id
|
|
|
|
@strawberry.mutation
|
|
def update_profile(self, id_: int, scheme: str, json: str) -> bool:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
profile = session.query(Profile).get(id_)
|
|
profile.scheme = scheme
|
|
profile.json = json
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def create_profile(self, user_id: int, schema: str, branch: str, json: str) -> int:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
user = session.query(User).get(user_id)
|
|
if not user:
|
|
return 0
|
|
profile = Profile(user_id=user_id, scheme=schema, branch=branch, json=json)
|
|
session.add_all([profile])
|
|
session.commit()
|
|
return profile.id
|
|
|
|
@strawberry.mutation
|
|
def update_schedule(self, id_: int, day_start: int, day_end: int, hour_start: int, hour_end: int,
|
|
minute_start: int, minute_end: int) -> bool:
|
|
sync_engine = connect()
|
|
with Session(sync_engine) as session:
|
|
schedule = session.query(Schedule).get(id_)
|
|
schedule.day_start = day_start
|
|
schedule.day_end = day_end
|
|
schedule.hour_start = hour_start
|
|
schedule.hour_end = hour_end
|
|
schedule.minute_start = minute_start
|
|
schedule.minute_end = minute_end
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def create_schedule(self, user_id: int, day_start: int, day_end: int, hour_start: int, hour_end: int,
|
|
minute_start: int, minute_end: int) -> int:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
user = session.query(User).get(user_id)
|
|
if not user:
|
|
return 0
|
|
schedule = Schedule(user_id=user_id, day_start=day_start, day_end=day_end, hour_start=hour_start,
|
|
hour_end=hour_end, minute_start=minute_start, minute_end=minute_end)
|
|
session.add_all([schedule])
|
|
session.commit()
|
|
return schedule.id
|
|
|
|
@strawberry.mutation
|
|
def remove_user(self, id_: int) -> bool:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
user = session.query(User).get(id_)
|
|
if user:
|
|
session.delete(user)
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def remove_profile(self, id_: int) -> bool:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
profile = session.query(Profile).get(id_)
|
|
if profile:
|
|
session.delete(profile)
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def remove_schedule(self, id_: int) -> bool:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
schedule = session.query(Schedule).get(id_)
|
|
if schedule:
|
|
session.delete(schedule)
|
|
session.commit()
|
|
return True
|
|
|
|
@strawberry.mutation
|
|
def send_commit(self, bndname: str, schema: str, commit_id: str) -> bool:
|
|
sync_engine = connect()
|
|
with (Session(sync_engine) as session):
|
|
user = session.query(User).filter(User.bndname == bndname).one_or_none()
|
|
if user:
|
|
queue = Queue(
|
|
user_id=user.id,
|
|
commit_id=commit_id,
|
|
schema=schema,
|
|
)
|
|
session.add(queue)
|
|
session.commit()
|
|
return True
|
|
|
|
|
|
def init():
|
|
sync_engine = connect()
|
|
Base.metadata.drop_all(sync_engine)
|
|
Base.metadata.create_all(sync_engine)
|
|
with Session(sync_engine) as session:
|
|
bnd127 = User(
|
|
username="bnd127",
|
|
passwd="gost_2012$a742ec53198ec2a5027086fba8814a89982a57112d1a72d02260161108f39b50",
|
|
bndname="bnd127",
|
|
newbnd=True,
|
|
active=True,
|
|
upstream=False
|
|
)
|
|
bnd128 = User(
|
|
username="bnd128",
|
|
passwd="gost_2012$a742ec53198ec2a5027086fba8814a89982a57112d1a72d02260161108f39b50",
|
|
bndname="bnd128",
|
|
newbnd=True,
|
|
active=True,
|
|
upstream=False
|
|
)
|
|
session.add_all([bnd127, bnd128])
|
|
session.commit()
|
|
|
|
|
|
def main():
|
|
# init()
|
|
uvicorn.run("main:app", port=9000, log_level="info", host='0.0.0.0')
|
|
|
|
|
|
schema = strawberry.Schema(query=Query, mutation=Mutation)
|
|
|
|
graphql_app = GraphQLRouter(schema, graphiql=True)
|
|
|
|
app = FastAPI(root_path="/graphql")
|
|
app.add_middleware(CORSMiddleware,
|
|
allow_origins=['http://127.0.0.1:3000', 'http://localhost:3000', 'http://10.10.8.24:3000'],
|
|
allow_credentials=True,
|
|
allow_methods=['*'],
|
|
allow_headers=['*']
|
|
)
|
|
app.include_router(graphql_app, prefix='/graphql')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|