Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ redis:
sleep 3

migrate:
alembic upgrade head
source ./venv/bin/activate && alembic upgrade head
37 changes: 37 additions & 0 deletions migrations/versions/41e3e1eb6c9d_remove_union_member.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""remove union_member

Revision ID: 41e3e1eb6c9d
Revises: a68c6bb2972c
Create Date: 2025-10-07 19:40:11.770337

"""

import sqlalchemy as sa
from alembic import op


revision = '41e3e1eb6c9d'
down_revision = 'a68c6bb2972c'
branch_labels = None
depends_on = None


def upgrade():
op.drop_constraint('file_owner_id_fkey', 'file', type_='foreignkey')
op.drop_constraint('print_fact_owner_id_fkey', 'print_fact', type_='foreignkey')
op.drop_table('union_member')
op.alter_column('file', 'source', existing_type=sa.VARCHAR(), nullable=False)


def downgrade():
op.alter_column('file', 'source', existing_type=sa.VARCHAR(), nullable=True)
op.create_table(
'union_member',
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
sa.Column('surname', sa.VARCHAR(), autoincrement=False, nullable=False),
sa.Column('union_number', sa.VARCHAR(), autoincrement=False, nullable=True),
sa.Column('student_number', sa.VARCHAR(), autoincrement=False, nullable=True),
sa.PrimaryKeyConstraint('id', name='union_member_pkey'),
)
op.create_foreign_key('file_owner_id_fkey', 'file', 'union_member', ['owner_id'], ['id'])
op.create_foreign_key('print_fact_owner_id_fkey', 'print_fact', 'union_member', ['owner_id'], ['id'])
20 changes: 3 additions & 17 deletions print_service/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from sqlalchemy import Column, DateTime, Integer, String
from sqlalchemy.ext.declarative import as_declarative
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.orm import Mapped, relationship
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql.sqltypes import Boolean

Expand All @@ -15,25 +15,13 @@ class Model:
pass


class UnionMember(Model):
__tablename__ = 'union_member'

id: Mapped[int] = mapped_column(Integer, primary_key=True)
surname: Mapped[str] = mapped_column(String, nullable=False)
union_number: Mapped[str] = mapped_column(String, nullable=True)
student_number: Mapped[str] = mapped_column(String, nullable=True)

files: Mapped[list[File]] = relationship('File', back_populates='owner')
print_facts: Mapped[list[PrintFact]] = relationship('PrintFact', back_populates='owner')


class File(Model):
__tablename__ = 'file'

id: Mapped[int] = Column(Integer, primary_key=True)
pin: Mapped[str] = Column(String, nullable=False)
file: Mapped[str] = Column(String, nullable=False)
owner_id: Mapped[int] = Column(Integer, ForeignKey('union_member.id'), nullable=False)
owner_id: Mapped[int] = Column(Integer, nullable=False)
option_pages: Mapped[str] = Column(String)
option_copies: Mapped[int] = Column(Integer)
option_two_sided: Mapped[bool] = Column(Boolean)
Expand All @@ -44,7 +32,6 @@ class File(Model):
number_of_pages: Mapped[int] = Column(Integer)
source: Mapped[str] = Column(String, default='unknown', nullable=False)

owner: Mapped[UnionMember] = relationship('UnionMember', back_populates='files')
print_facts: Mapped[list[PrintFact]] = relationship('PrintFact', back_populates='file')

@property
Expand Down Expand Up @@ -84,9 +71,8 @@ class PrintFact(Model):

id: Mapped[int] = Column(Integer, primary_key=True)
file_id: Mapped[int] = Column(Integer, ForeignKey('file.id'), nullable=False)
owner_id: Mapped[int] = Column(Integer, ForeignKey('union_member.id'), nullable=False)
owner_id: Mapped[int] = Column(Integer, nullable=False)
created_at: Mapped[datetime] = Column(DateTime, nullable=False, default=datetime.utcnow)

owner: Mapped[UnionMember] = relationship('UnionMember', back_populates='print_facts')
file: Mapped[File] = relationship('File', back_populates='print_facts')
sheets_used: Mapped[int] = Column(Integer)
2 changes: 1 addition & 1 deletion print_service/routes/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from auth_lib.fastapi import UnionAuth
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, Depends
from redis import Redis

from print_service.exceptions import TerminalTokenNotFound
Expand Down
2 changes: 0 additions & 2 deletions print_service/routes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from print_service.routes.admin import router as admin_router
from print_service.routes.file import router as file_router
from print_service.routes.qrprint import router as qrprint_router
from print_service.routes.user import router as user_router
from print_service.settings import Settings, get_settings


Expand Down Expand Up @@ -40,7 +39,6 @@
)


app.include_router(user_router, prefix='', tags=['User'])
app.include_router(file_router, prefix='/file', tags=['File'])
app.include_router(qrprint_router, prefix='/qr', tags=['File'])
app.include_router(admin_router, prefix='/admin', tags=['Admin'])
Expand Down
1 change: 0 additions & 1 deletion print_service/routes/exc_handlers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import requests.models
import starlette.requests
from starlette.responses import JSONResponse

Expand Down
45 changes: 5 additions & 40 deletions print_service/routes/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
import aiofiles.os
from auth_lib.fastapi import UnionAuth
from fastapi import APIRouter, File, UploadFile
from fastapi.exceptions import HTTPException
from fastapi.params import Depends
from fastapi_sqlalchemy import db
from pydantic import Field, field_validator
from sqlalchemy import func, or_
from sqlalchemy import func

from print_service.base import StatusResponseModel
from print_service.exceptions import (
Expand All @@ -19,16 +18,12 @@
InvalidPageRequest,
InvalidType,
IsCorrupted,
NotInUnion,
PINGenerateError,
PINNotFound,
TooLargeSize,
TooManyPages,
UnprocessableFileInstance,
UserNotFound,
)
from print_service.models import File as FileModel
from print_service.models import UnionMember
from print_service.schema import BaseModel
from print_service.settings import Settings, get_settings
from print_service.utils import checking_for_pdf, generate_filename, generate_pin, get_file
Expand Down Expand Up @@ -60,16 +55,6 @@ def validate_pages(cls, value: str):


class SendInput(BaseModel):
surname: str | None = Field(
default=None,
description='Фамилия',
example='Иванов',
)
number: str | None = Field(
default=None,
description='Номер профсоюзного или студенческого билетов',
example='1015000',
)
filename: str = Field(
description='Название файла',
example='filename.pdf',
Expand Down Expand Up @@ -112,41 +97,21 @@ class ReceiveOutput(BaseModel):
)
async def send(
inp: SendInput,
user_auth=Depends(UnionAuth(allow_none=True)),
settings: Settings = Depends(get_settings),
user_auth=Depends(UnionAuth(scopes=["print.service.use"])),
):
"""Получить пин код для загрузки и скачивания файла.

Scopes: `["print.service.use"]`

Полученный пин-код можно использовать в методах POST и GET `/file/{pin}`.
"""
user = db.session.query(UnionMember)
if not settings.ALLOW_STUDENT_NUMBER:
user = user.filter(UnionMember.union_number != None)

if (inp.number is not None) and (inp.surname is not None):
user = user.filter(
or_(
func.upper(UnionMember.student_number) == inp.number.upper(),
func.upper(UnionMember.union_number) == inp.number.upper(),
),
func.upper(UnionMember.surname) == inp.surname.upper(),
)

else:
if not "print.file.send" in [scope["name"] for scope in user_auth.get('session_scopes')]:
raise NotInUnion()

user = user.one_or_none()

if user is None:
raise NotInUnion()
try:
pin = generate_pin(db.session)
except RuntimeError:
raise PINGenerateError()
filename = generate_filename(inp.filename)
file_model = FileModel(pin=pin, file=filename, source=inp.source)
file_model.owner = user
file_model.owner_id = user_auth['id']
file_model.option_copies = inp.options.copies
file_model.option_pages = inp.options.pages
file_model.option_two_sided = inp.options.two_sided
Expand Down
132 changes: 0 additions & 132 deletions print_service/routes/user.py

This file was deleted.

2 changes: 1 addition & 1 deletion print_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import List

from auth_lib.fastapi import UnionAuthSettings
from pydantic import AnyUrl, ConfigDict, DirectoryPath, PostgresDsn, RedisDsn
from pydantic import ConfigDict, DirectoryPath, PostgresDsn, RedisDsn
from pydantic_settings import BaseSettings


Expand Down
3 changes: 0 additions & 3 deletions print_service/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import io
import math
import random
import re
from datetime import date, datetime, timedelta
from os.path import abspath, exists

from fastapi import File
from fastapi.exceptions import HTTPException
from PyPDF4 import PdfFileReader
from sqlalchemy import func
from sqlalchemy.orm.session import Session
Expand All @@ -20,7 +18,6 @@
from print_service.models import File
from print_service.models import File as FileModel
from print_service.models import PrintFact
from print_service.routes import exc_handlers
from print_service.settings import Settings, get_settings


Expand Down
Loading