system

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2026 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Overview

Package system 提供系统信息 HTTP 处理器

Package system i18n 设置处理器

Package system 提供系统信息模块

Package system 系统模块

Package system 提供系统信息服务

Package system i18n 服务

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InvalidateI18nCache

func InvalidateI18nCache()

InvalidateI18nCache 清除 i18n 缓存

Types

type CPUInfo

type CPUInfo struct {
	ModelName   string  `json:"model_name"`
	Cores       int     `json:"cores"`   // 物理核心数
	Threads     int     `json:"threads"` // 逻辑核心数
	MHz         float64 `json:"mhz"`
	CacheSize   int32   `json:"cache_size"`  // KB
	Usage       float64 `json:"usage"`       // 百分比
	Temperature int     `json:"temperature"` // 摄氏度,-1 表示不可用
}

CPUInfo CPU 信息

type DeviceInfo

type DeviceInfo struct {
	OSVersion   string   `json:"os_version"`
	DeviceName  string   `json:"device_name"`
	DeviceModel string   `json:"device_model"`
	DeviceSN    string   `json:"device_sn"`
	LanIPv4     []string `json:"lan_ipv4"`
	MacAddress  string   `json:"mac_address"`
	Initialized bool     `json:"initialized"`
	Port        int      `json:"port"`
}

DeviceInfo 设备信息

type DiskInfo

type DiskInfo struct {
	Path        string  `json:"path"`
	Total       uint64  `json:"total"` // 字节
	Used        uint64  `json:"used"`
	Free        uint64  `json:"free"`
	UsedPercent float64 `json:"used_percent"`
	FSType      string  `json:"fs_type"`
	MountPoint  string  `json:"mount_point"`
}

DiskInfo 磁盘信息

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler HTTP 处理器

func NewHandler

func NewHandler(service *Service) *Handler

NewHandler 创建处理器

func (*Handler) DetectRegion

func (h *Handler) DetectRegion(c *gin.Context)

DetectRegion 检测用户区域 @Summary 检测用户区域 @Tags system @Produce json @Success 200 {object} map[string]string @Router /api/v1/system/i18n/detect [get]

func (*Handler) DisableSSH

func (h *Handler) DisableSSH(c *gin.Context)

DisableSSH 禁用 SSH 服务 @Summary 禁用 SSH 服务 @Tags system @Produce json @Success 200 {object} response @Router /api/v1/system/ssh/disable [post]

func (*Handler) EnableSSH

func (h *Handler) EnableSSH(c *gin.Context)

EnableSSH 启用 SSH 服务 @Summary 启用 SSH 服务 @Tags system @Produce json @Success 200 {object} response @Router /api/v1/system/ssh/enable [post]

func (*Handler) GetAllDisks

func (h *Handler) GetAllDisks(c *gin.Context)

GetAllDisks 获取所有磁盘信息 @Summary 获取所有磁盘信息 @Tags system @Produce json @Success 200 {array} DiskInfo @Router /api/v1/system/disks [get]

func (*Handler) GetCPUInfo

func (h *Handler) GetCPUInfo(c *gin.Context)

GetCPUInfo 获取 CPU 信息 @Summary 获取 CPU 信息 @Tags system @Produce json @Success 200 {object} CPUInfo @Router /api/v1/system/cpu [get]

func (*Handler) GetDeviceInfo

func (h *Handler) GetDeviceInfo(c *gin.Context)

GetDeviceInfo 获取设备信息 @Summary 获取设备信息 @Tags system @Produce json @Success 200 {object} DeviceInfo @Router /api/v1/system/device [get]

func (*Handler) GetDiskInfo

func (h *Handler) GetDiskInfo(c *gin.Context)

GetDiskInfo 获取磁盘信息 @Summary 获取磁盘信息 @Tags system @Produce json @Param path query string false "磁盘路径" @Success 200 {object} DiskInfo @Router /api/v1/system/disk [get]

func (*Handler) GetHealthStatus

func (h *Handler) GetHealthStatus(c *gin.Context)

GetHealthStatus 获取健康状态 @Summary 获取系统健康状态 @Tags system @Produce json @Success 200 {object} HealthStatus @Router /api/v1/system/health [get]

func (*Handler) GetI18nOptions

func (h *Handler) GetI18nOptions(c *gin.Context)

GetI18nOptions 获取 i18n 选项(语言、区域、镜像列表) @Summary 获取国际化选项 @Tags system @Produce json @Success 200 {object} MirrorOptionsResponse @Router /api/v1/system/i18n/options [get]

func (*Handler) GetI18nSettings

func (h *Handler) GetI18nSettings(c *gin.Context)

GetI18nSettings 获取 i18n 设置 @Summary 获取国际化设置 @Tags system @Produce json @Success 200 {object} I18nSettingsResponse @Router /api/v1/system/i18n [get]

func (*Handler) GetLogs

func (h *Handler) GetLogs(c *gin.Context)

GetLogs 获取日志 @Summary 获取系统日志 @Tags system @Produce json @Param lines query int false "行数" default(100) @Success 200 {array} string @Router /api/v1/system/logs [get]

func (*Handler) GetMemoryInfo

func (h *Handler) GetMemoryInfo(c *gin.Context)

GetMemoryInfo 获取内存信息 @Summary 获取内存信息 @Tags system @Produce json @Success 200 {object} MemoryInfo @Router /api/v1/system/memory [get]

func (*Handler) GetNetwork

func (h *Handler) GetNetwork(c *gin.Context)

GetNetwork 获取网络信息(包含接口和统计) @Summary 获取网络信息 @Tags system @Produce json @Success 200 {object} NetworkInfo @Router /api/v1/system/network [get]

func (*Handler) GetNetworkInterfaces

func (h *Handler) GetNetworkInterfaces(c *gin.Context)

GetNetworkInterfaces 获取网络接口 @Summary 获取网络接口 @Tags system @Produce json @Param physical query bool false "仅物理网卡" @Success 200 {array} NetworkInterface @Router /api/v1/system/network/interfaces [get]

func (*Handler) GetNetworkStats

func (h *Handler) GetNetworkStats(c *gin.Context)

GetNetworkStats 获取网络统计 @Summary 获取网络统计 @Tags system @Produce json @Success 200 {array} NetworkStats @Router /api/v1/system/network/stats [get]

func (*Handler) GetProxyConfig

func (h *Handler) GetProxyConfig(c *gin.Context)

GetProxyConfig 获取代理配置 @Summary 获取代理配置 @Tags system @Produce json @Success 200 {object} model.SystemProxyConfig @Router /api/v1/system/proxy [get]

func (*Handler) GetRemoteAccessSettings

func (h *Handler) GetRemoteAccessSettings(c *gin.Context)

GetRemoteAccessSettings 获取远程访问设置 @Summary 获取远程访问设置 @Tags system @Produce json @Success 200 {object} RemoteAccessSettings @Router /api/v1/system/security/remote-access [get]

func (*Handler) GetResourceUsage

func (h *Handler) GetResourceUsage(c *gin.Context)

GetResourceUsage 获取资源使用情况 @Summary 获取当前资源使用情况 @Tags system @Produce json @Success 200 {object} ResourceUsage @Router /api/v1/system/usage [get]

func (*Handler) GetSSHStatus

func (h *Handler) GetSSHStatus(c *gin.Context)

GetSSHStatus 获取 SSH 服务状态 @Summary 获取 SSH 服务状态 @Tags system @Produce json @Success 200 {object} SSHStatus @Router /api/v1/system/ssh [get]

func (*Handler) GetSystemInfo

func (h *Handler) GetSystemInfo(c *gin.Context)

GetSystemInfo 获取系统信息 @Summary 获取系统信息 @Tags system @Produce json @Success 200 {object} SystemInfo @Router /api/v1/system/info [get]

func (*Handler) GetTimeZone

func (h *Handler) GetTimeZone(c *gin.Context)

GetTimeZone 获取时区 @Summary 获取时区信息 @Tags system @Produce json @Success 200 {object} TimeZoneInfo @Router /api/v1/system/timezone [get]

func (*Handler) GetTopProcesses

func (h *Handler) GetTopProcesses(c *gin.Context)

GetTopProcesses 获取进程列表 @Summary 获取 CPU/内存占用最高的进程 @Tags system @Produce json @Param limit query int false "返回数量" default(10) @Param sort query string false "排序字段" Enums(cpu, memory) @Success 200 {array} ProcessInfo @Router /api/v1/system/processes [get]

func (*Handler) PreviewRegionSwitch

func (h *Handler) PreviewRegionSwitch(c *gin.Context)

PreviewRegionSwitch 预览区域切换影响 @Summary 预览区域切换 @Tags system @Accept json @Produce json @Param body body RegionSwitchPreviewRequest true "切换请求" @Success 200 {object} RegionSwitchPreviewResponse @Router /api/v1/system/i18n/preview-switch [post]

func (*Handler) Reboot

func (h *Handler) Reboot(c *gin.Context)

Reboot 重启系统 @Summary 重启系统 @Tags system @Produce json @Success 200 {object} response @Router /api/v1/system/reboot [post]

func (*Handler) RegisterRoutes

func (h *Handler) RegisterRoutes(group *gin.RouterGroup)

RegisterRoutes 注册路由

func (*Handler) SaveProxyConfig

func (h *Handler) SaveProxyConfig(c *gin.Context)

SaveProxyConfig 保存代理配置 @Summary 保存代理配置 @Tags system @Accept json @Produce json @Param config body model.SystemProxyConfig true "代理配置" @Success 200 {object} response @Router /api/v1/system/proxy [post]

func (*Handler) SetSSHAutoStart

func (h *Handler) SetSSHAutoStart(c *gin.Context)

SetSSHAutoStart 设置 SSH 开机自启 @Summary 设置 SSH 开机自启 @Tags system @Accept json @Produce json @Success 200 {object} response @Router /api/v1/system/ssh/autostart [post]

func (*Handler) Shutdown

func (h *Handler) Shutdown(c *gin.Context)

Shutdown 关机 @Summary 关闭系统 @Tags system @Produce json @Success 200 {object} response @Router /api/v1/system/shutdown [post]

func (*Handler) TestProxy

func (h *Handler) TestProxy(c *gin.Context)

TestProxy 测试代理连接 @Summary 测试代理连接 @Tags system @Accept json @Produce json @Param request body model.ProxyTestRequest true "测试请求" @Success 200 {object} model.ProxyTestResponse @Router /api/v1/system/proxy/test [post]

func (*Handler) UpdateI18nSettings

func (h *Handler) UpdateI18nSettings(c *gin.Context)

UpdateI18nSettings 更新 i18n 设置 @Summary 更新国际化设置 @Tags system @Accept json @Produce json @Param body body I18nSettingsRequest true "设置" @Success 200 {object} I18nSettingsResponse @Router /api/v1/system/i18n [put]

func (*Handler) UpdateRemoteAccessSettings

func (h *Handler) UpdateRemoteAccessSettings(c *gin.Context)

UpdateRemoteAccessSettings 更新远程访问设置 @Summary 更新远程访问设置 @Tags system @Accept json @Produce json @Param request body UpdateRemoteAccessRequest true "更新请求" @Success 200 {object} response @Router /api/v1/system/security/remote-access [put]

type HealthStatus

type HealthStatus struct {
	Status      string            `json:"status"` // healthy, warning, critical
	Checks      map[string]string `json:"checks"` // 各项检查结果
	LastChecked time.Time         `json:"last_checked"`
}

HealthStatus 健康状态

type I18nSettingsData

type I18nSettingsData struct {
	Region      string            `json:"region"`
	Mirrors     map[string]string `json:"mirrors"`      // service -> "follow" | "cn" | "intl" | "custom"
	CustomURLs  map[string]string `json:"custom_urls"`  // service -> custom URL
	LyricSource string            `json:"lyric_source"` // "follow" | source id
}

I18nSettingsData i18n 设置数据(language 由前端管理,不在后端存储)

type I18nSettingsRequest

type I18nSettingsRequest struct {
	Region      string            `json:"region" binding:"omitempty"`
	Mirrors     map[string]string `json:"mirrors,omitempty"`
	LyricSource string            `json:"lyric_source,omitempty"`
}

I18nSettingsRequest i18n 设置请求

type I18nSettingsResponse

type I18nSettingsResponse struct {
	Region         string            `json:"region"`
	DetectedRegion string            `json:"detected_region"`
	Mirrors        map[string]string `json:"mirrors"`
	LyricSource    string            `json:"lyric_source"`
}

I18nSettingsResponse i18n 设置响应

type LogEntry

type LogEntry struct {
	Timestamp time.Time `json:"timestamp"`
	Level     string    `json:"level"`
	Message   string    `json:"message"`
	Source    string    `json:"source"`
}

LogEntry 日志条目

type MemoryInfo

type MemoryInfo struct {
	Total       uint64  `json:"total"` // 字节
	Used        uint64  `json:"used"`
	Free        uint64  `json:"free"`
	Available   uint64  `json:"available"`
	UsedPercent float64 `json:"used_percent"`
	SwapTotal   uint64  `json:"swap_total"`
	SwapUsed    uint64  `json:"swap_used"`
	SwapFree    uint64  `json:"swap_free"`
}

MemoryInfo 内存信息

type MirrorOption

type MirrorOption struct {
	Name     string `json:"name"`
	URL      string `json:"url"`
	Priority int    `json:"priority,omitempty"`
}

MirrorOption 镜像选项

type MirrorOptionsResponse

type MirrorOptionsResponse struct {
	Languages    []i18n.LanguageOption                `json:"languages"`
	Regions      []i18n.RegionOption                  `json:"regions"`
	Mirrors      map[string]map[string][]MirrorOption `json:"mirrors"`
	LyricSources map[string][]i18n.LyricSource        `json:"lyric_sources"`
	Services     []MirrorServiceInfo                  `json:"services"`
}

MirrorOptionsResponse 镜像选项响应

type MirrorServiceInfo

type MirrorServiceInfo struct {
	ID   string            `json:"id"`
	Name map[string]string `json:"name"`
}

MirrorServiceInfo 镜像服务信息

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module 系统模块实现

func New

func New() *Module

New 创建模块实例

func NewModule

func NewModule() *Module

NewModule 创建系统模块(别名)

func (*Module) Dependencies

func (m *Module) Dependencies() []string

Dependencies 返回依赖的模块

func (*Module) GetService

func (m *Module) GetService() *Service

GetService 获取服务实例

func (*Module) ID

func (m *Module) ID() string

ID 返回模块唯一标识

func (*Module) Init

func (m *Module) Init(ctx *module.Context) error

Init 初始化模块

func (*Module) Name

func (m *Module) Name() string

Name 返回模块名称

func (*Module) RegisterRoutes

func (m *Module) RegisterRoutes(router *gin.RouterGroup)

RegisterRoutes 注册路由

func (*Module) Start

func (m *Module) Start() error

Start 启动模块

func (*Module) Stop

func (m *Module) Stop() error

Stop 停止模块

func (*Module) Version

func (m *Module) Version() string

Version 返回模块版本

type NetworkInterface

type NetworkInterface struct {
	Name       string   `json:"name"`
	MacAddress string   `json:"mac_address"`
	IPv4       []string `json:"ipv4"`
	IPv6       []string `json:"ipv6"`
	BytesSent  uint64   `json:"bytes_sent"`
	BytesRecv  uint64   `json:"bytes_recv"`
	State      string   `json:"state"` // up, down
}

NetworkInterface 网络接口信息

type NetworkStats

type NetworkStats struct {
	Interface   string `json:"interface"`
	BytesSent   uint64 `json:"bytes_sent"`
	BytesRecv   uint64 `json:"bytes_recv"`
	PacketsSent uint64 `json:"packets_sent"`
	PacketsRecv uint64 `json:"packets_recv"`
	ErrorsIn    uint64 `json:"errors_in"`
	ErrorsOut   uint64 `json:"errors_out"`
}

NetworkStats 网络统计

type PowerInfo

type PowerInfo struct {
	CPUPower   string `json:"cpu_power,omitempty"`
	BatteryPct int    `json:"battery_pct,omitempty"` // -1 表示无电池
	IsCharging bool   `json:"is_charging,omitempty"`
}

PowerInfo 电源信息

type ProcessInfo

type ProcessInfo struct {
	PID        int32   `json:"pid"`
	Name       string  `json:"name"`
	CPUPercent float64 `json:"cpu_percent"`
	MemPercent float32 `json:"mem_percent"`
	Status     string  `json:"status"`
	Username   string  `json:"username"`
	CreateTime int64   `json:"create_time"`
}

ProcessInfo 进程信息

type RegionSwitchItem

type RegionSwitchItem struct {
	Service     string            `json:"service"`
	ServiceName map[string]string `json:"service_name"`
	CurrentURL  string            `json:"current_url"`
	NewURL      string            `json:"new_url"`
	Enabled     bool              `json:"enabled"`
}

RegionSwitchItem 区域切换项

type RegionSwitchPreviewRequest

type RegionSwitchPreviewRequest struct {
	FromRegion string `json:"from_region" binding:"required"`
	ToRegion   string `json:"to_region" binding:"required"`
}

RegionSwitchPreview 区域切换预览

type RegionSwitchPreviewResponse

type RegionSwitchPreviewResponse struct {
	Items []RegionSwitchItem `json:"items"`
}

RegionSwitchPreviewResponse 区域切换预览响应

type RemoteAccessSettings

type RemoteAccessSettings struct {
	SSHEnabled      bool `json:"ssh_enabled"`
	SSHRunning      bool `json:"ssh_running"`
	SSHPort         int  `json:"ssh_port"`
	TerminalEnabled bool `json:"terminal_enabled"`
}

RemoteAccessSettings 远程访问设置

type ResourceUsage

type ResourceUsage struct {
	Timestamp   time.Time `json:"timestamp"`
	CPUUsage    float64   `json:"cpu_usage"`
	MemoryUsage float64   `json:"memory_usage"`
	DiskUsage   float64   `json:"disk_usage"`
	NetworkRx   uint64    `json:"network_rx"` // bytes/s
	NetworkTx   uint64    `json:"network_tx"` // bytes/s
}

ResourceUsage 资源使用情况(用于实时监控)

type SSHStatus

type SSHStatus struct {
	Running bool   `json:"running"`
	Enabled bool   `json:"enabled"`
	Port    int    `json:"port"`
	Message string `json:"message,omitempty"`
}

SSHStatus SSH 服务状态

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service 系统信息服务

func NewService

func NewService(logger *zap.Logger, version, dataPath string) *Service

NewService 创建系统服务

func (*Service) DisableSSH

func (s *Service) DisableSSH(ctx context.Context) error

DisableSSH 禁用 SSH 服务

func (*Service) EnableSSH

func (s *Service) EnableSSH(ctx context.Context) error

EnableSSH 启用 SSH 服务

func (*Service) GetAllDisks

func (s *Service) GetAllDisks(ctx context.Context) ([]DiskInfo, error)

GetAllDisks 获取所有磁盘信息

func (*Service) GetCPUInfo

func (s *Service) GetCPUInfo(ctx context.Context) (*CPUInfo, error)

GetCPUInfo 获取 CPU 信息

func (*Service) GetCPUTemperature

func (s *Service) GetCPUTemperature(ctx context.Context) (float64, error)

GetCPUTemperature 获取 CPU 温度

func (*Service) GetDeviceInfo

func (s *Service) GetDeviceInfo(ctx context.Context) (*DeviceInfo, error)

GetDeviceInfo 获取设备信息

func (*Service) GetDiskInfo

func (s *Service) GetDiskInfo(ctx context.Context, path string) (*DiskInfo, error)

GetDiskInfo 获取磁盘信息

func (*Service) GetHealthStatus

func (s *Service) GetHealthStatus(ctx context.Context) *HealthStatus

GetHealthStatus 获取健康状态

func (*Service) GetI18nSettings

func (s *Service) GetI18nSettings() (*I18nSettingsResponse, error)

GetI18nSettings 获取 i18n 设置

func (*Service) GetLogs

func (s *Service) GetLogs(ctx context.Context, logFile string, lines int) ([]string, error)

GetLogs 获取系统日志

func (*Service) GetMacAddress

func (s *Service) GetMacAddress(ctx context.Context) (string, error)

GetMacAddress 获取 MAC 地址

func (*Service) GetMemoryInfo

func (s *Service) GetMemoryInfo(ctx context.Context) (*MemoryInfo, error)

GetMemoryInfo 获取内存信息

func (*Service) GetMirrorURL

func (s *Service) GetMirrorURL(service string) string

GetMirrorURL 获取指定服务的当前镜像 URL

func (*Service) GetNetworkInterfaces

func (s *Service) GetNetworkInterfaces(ctx context.Context, physicalOnly bool) ([]NetworkInterface, error)

GetNetworkInterfaces 获取网络接口列表

func (*Service) GetNetworkStats

func (s *Service) GetNetworkStats(ctx context.Context) ([]NetworkStats, error)

GetNetworkStats 获取网络统计

func (*Service) GetProxyConfig

func (s *Service) GetProxyConfig(ctx context.Context) (*model.SystemProxyConfig, error)

GetProxyConfig 获取代理配置

func (*Service) GetRemoteAccessSettings

func (s *Service) GetRemoteAccessSettings(ctx context.Context) (*RemoteAccessSettings, error)

GetRemoteAccessSettings 获取远程访问设置

func (*Service) GetResourceUsage

func (s *Service) GetResourceUsage(ctx context.Context) (*ResourceUsage, error)

GetResourceUsage 获取当前资源使用情况

func (*Service) GetSSHStatus

func (s *Service) GetSSHStatus(ctx context.Context) (*SSHStatus, error)

GetSSHStatus 获取 SSH 服务状态

func (*Service) GetSystemInfo

func (s *Service) GetSystemInfo(ctx context.Context) (*SystemInfo, error)

GetSystemInfo 获取系统信息

func (*Service) GetTimeZone

func (s *Service) GetTimeZone(ctx context.Context) *TimeZoneInfo

GetTimeZone 获取时区

func (*Service) GetTopProcesses

func (s *Service) GetTopProcesses(ctx context.Context, limit int, sortBy string) ([]ProcessInfo, error)

GetTopProcesses 获取 CPU/内存占用最高的进程

func (*Service) IsTerminalEnabled

func (s *Service) IsTerminalEnabled() bool

IsTerminalEnabled 检查终端是否启用

func (*Service) PreviewRegionSwitch

func (s *Service) PreviewRegionSwitch(fromRegion, toRegion string) []RegionSwitchItem

PreviewRegionSwitch 预览区域切换

func (*Service) Reboot

func (s *Service) Reboot(ctx context.Context) error

Reboot 重启系统

func (*Service) SaveProxyConfig

func (s *Service) SaveProxyConfig(ctx context.Context, config *model.SystemProxyConfig) error

SaveProxyConfig 保存代理配置

func (*Service) SetEventBus

func (s *Service) SetEventBus(eventBus module.EventBus)

SetEventBus 设置事件总线

func (*Service) SetSSHAutoStart

func (s *Service) SetSSHAutoStart(ctx context.Context, enabled bool) error

SetSSHAutoStart 设置 SSH 开机自启

func (*Service) SetSSHEnabled

func (s *Service) SetSSHEnabled(ctx context.Context, enabled bool) error

SetSSHEnabled 设置 SSH 启用状态

func (*Service) SetTerminalEnabled

func (s *Service) SetTerminalEnabled(ctx context.Context, enabled bool) error

SetTerminalEnabled 设置终端启用状态

func (*Service) Shutdown

func (s *Service) Shutdown(ctx context.Context) error

Shutdown 关机

func (*Service) TestProxy

TestProxy 测试代理连接

func (*Service) UpdateI18nSettings

func (s *Service) UpdateI18nSettings(req I18nSettingsRequest) (*I18nSettingsResponse, error)

UpdateI18nSettings 更新 i18n 设置

type SystemInfo

type SystemInfo struct {
	Hostname      string `json:"hostname"`
	OS            string `json:"os"`
	Platform      string `json:"platform"`
	Arch          string `json:"arch"`
	KernelVersion string `json:"kernel_version"`
	Uptime        uint64 `json:"uptime"`    // 秒
	BootTime      uint64 `json:"boot_time"` // Unix 时间戳
	Procs         uint64 `json:"procs"`     // 进程数
}

SystemInfo 系统信息

type TimeZoneInfo

type TimeZoneInfo struct {
	Name   string `json:"name"`
	Offset int    `json:"offset"` // UTC 偏移(秒)
}

TimeZoneInfo 时区信息

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL