Files
ai-app-database/app/models/resource.py
T
huty f3bd3f68a5
CI — Docker Build & Push / Build & Push Image (push) Failing after 10m15s
新增文件夹功能
2026-04-23 15:45:28 +09:00

91 lines
3.2 KiB
Python

from datetime import datetime
from app.extensions import db
class Resource(db.Model):
__tablename__ = 'resources'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'),
nullable=False, index=True)
title = db.Column(db.String(255), nullable=False)
description = db.Column(db.Text, nullable=True)
# 资源类型: text / image / audio / video
resource_type = db.Column(db.Enum('text', 'image', 'audio', 'video'),
nullable=False, index=True)
# 来源类型: upload / url / magnet
source_type = db.Column(db.Enum('upload', 'url', 'magnet'),
nullable=False, default='upload')
# 文件信息
filename = db.Column(db.String(255), nullable=True) # 磁盘上的文件名
original_name = db.Column(db.String(255), nullable=True) # 原始文件名
file_path = db.Column(db.String(512), nullable=True) # 相对于 static 的路径
file_size = db.Column(db.BigInteger, nullable=True) # 字节
mime_type = db.Column(db.String(128), nullable=True)
# 来源 URL / 磁力链
source_url = db.Column(db.Text, nullable=True)
# 下载状态: pending / downloading / done / failed (针对 url/magnet)
download_status = db.Column(
db.Enum('pending', 'downloading', 'done', 'failed', 'na'),
nullable=False, default='na'
)
download_progress = db.Column(db.Integer, default=0) # 0-100
download_error = db.Column(db.Text, nullable=True)
tags = db.Column(db.String(512), nullable=True) # 逗号分隔
is_public = db.Column(db.Boolean, default=False)
# 所属文件夹(null = 根目录/未归档)
folder_id = db.Column(db.Integer,
db.ForeignKey('folders.id', ondelete='SET NULL'),
nullable=True, index=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
updated_at = db.Column(db.DateTime, default=datetime.utcnow,
onupdate=datetime.utcnow, nullable=False)
def __repr__(self):
return f'<Resource {self.title}>'
@property
def size_human(self):
"""返回人性化的文件大小字符串"""
if not self.file_size:
return '未知'
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if self.file_size < 1024:
return f'{self.file_size:.1f} {unit}'
self.file_size /= 1024
return f'{self.file_size:.1f} PB'
@property
def tag_list(self):
if not self.tags:
return []
return [t.strip() for t in self.tags.split(',') if t.strip()]
@property
def type_icon(self):
icons = {
'text': 'bi-file-text',
'image': 'bi-image',
'audio': 'bi-music-note-beamed',
'video': 'bi-camera-video',
}
return icons.get(self.resource_type, 'bi-file')
@property
def type_badge_color(self):
colors = {
'text': 'secondary',
'image': 'success',
'audio': 'warning',
'video': 'danger',
}
return colors.get(self.resource_type, 'secondary')