package server import ( "context" "log/slog" ) // Лимиты медиа (AGENT.md 7.7): значения живут в настройках инстанса и меняются // в админ-панели, а обработчики загрузок спрашивают их здесь. // Пределы по умолчанию (AGENT.md 7.7): 5 МБ — аватары, баннеры и оформление, // 512 КБ — эмодзи и звуки. Администратор инстанса меняет их в админ-панели. const ( maxAvatarSize int64 = 5 << 20 maxGuildImageSize int64 = 5 << 20 maxEmojiSize int64 = 512 << 10 maxSoundSize int64 = 512 << 10 maxCosmeticSize int64 = 5 << 20 ) // mediaKind — вид загрузки, для которого действует свой лимит. type mediaKind string const ( mediaAvatar mediaKind = "avatar" mediaGuildImage mediaKind = "guild_image" mediaEmoji mediaKind = "emoji" mediaSound mediaKind = "sound" mediaCosmetic mediaKind = "cosmetic" ) // mediaLimit возвращает предел размера файла в байтах. Настройки читаются на // каждую загрузку: админ мог поменять лимит только что, а кэш настроек здесь не // нужен — запрос к базе дешёвый. func (s *Server) mediaLimit(ctx context.Context, kind mediaKind) int64 { fallback := defaultMediaLimit(kind) if s.store == nil { return fallback } settings, err := s.store.InstanceSettings(ctx) if err != nil { s.logger.WarnContext(ctx, "failed to read media limits", slog.Any("error", err)) return fallback } switch kind { case mediaAvatar: return settings.MaxAvatarSize case mediaGuildImage: return settings.MaxGuildImageSize case mediaEmoji: return settings.MaxEmojiSize case mediaSound: return settings.MaxSoundSize case mediaCosmetic: return settings.MaxCosmeticSize default: return fallback } } // defaultMediaLimit — значения по умолчанию, если настройка недоступна: // именованные константы рядом с обработчиками задают те же пределы. func defaultMediaLimit(kind mediaKind) int64 { switch kind { case mediaAvatar: return maxAvatarSize case mediaGuildImage: return maxGuildImageSize case mediaEmoji: return maxEmojiSize case mediaSound: return maxSoundSize case mediaCosmetic: return maxCosmeticSize default: return maxGuildImageSize } }