Feat: download file from single file share

This commit is contained in:
HFO4
2020-01-28 12:41:00 +08:00
parent 0977b36f8b
commit 7f0feebf42
13 changed files with 199 additions and 8 deletions

View File

@@ -25,10 +25,11 @@ type Group struct {
// GroupOption 用户组其他配置
type GroupOption struct {
ArchiveDownloadEnabled bool `json:"archive_download"`
ArchiveTaskEnabled bool `json:"archive_task"`
OneTimeDownloadEnabled bool `json:"one_time_download"`
ShareDownloadEnabled bool `json:"share_download"`
ArchiveDownloadEnabled bool `json:"archive_download,omitempty"`
ArchiveTaskEnabled bool `json:"archive_task,omitempty"`
OneTimeDownloadEnabled bool `json:"one_time_download,omitempty"`
ShareDownloadEnabled bool `json:"share_download,omitempty"`
ShareFreeEnabled bool `json:"share_free,omitempty"`
}
// GetAria2Option 获取用户离线下载设备

View File

@@ -108,6 +108,7 @@ solid #e9e9e9;"bgcolor="#fff"><tbody><tr style="font-family: 'Helvetica Neue',He
{Name: "upload_session_timeout", Value: `86400`, Type: "timeout"},
{Name: "slave_api_timeout", Value: `60`, Type: "timeout"},
{Name: "onedrive_monitor_timeout", Value: `600`, Type: "timeout"},
{Name: "share_download_session_timeout", Value: `2073600`, Type: "timeout"},
{Name: "onedrive_callback_check", Value: `20`, Type: "timeout"},
{Name: "onedrive_chunk_retries", Value: `1`, Type: "retry"},
{Name: "allowdVisitorDownload", Value: `false`, Type: "share"},
@@ -185,6 +186,7 @@ func addDefaultGroups() {
OptionsSerialized: GroupOption{
ArchiveDownloadEnabled: true,
ArchiveTaskEnabled: true,
ShareDownloadEnabled: true,
},
}
if err := DB.Create(&defaultAdminGroup).Error; err != nil {

View File

@@ -1,6 +1,9 @@
package model
import (
"errors"
"fmt"
"github.com/HFO4/cloudreve/pkg/cache"
"github.com/HFO4/cloudreve/pkg/hashid"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/jinzhu/gorm"
@@ -86,6 +89,14 @@ func (share *Share) GetCreator() *User {
return &share.User
}
// GetSource 返回源对象
func (share *Share) GetSource() interface{} {
if share.IsDir {
return share.GetSourceFolder()
}
return share.GetSourceFile()
}
// GetSourceFolder 获取源目录
func (share *Share) GetSourceFolder() *Folder {
if share.Folder.ID == 0 {
@@ -107,3 +118,69 @@ func (share *Share) GetSourceFile() *File {
}
return &share.File
}
// CanBeDownloadBy 返回此分享是否可以被给定用户下载
func (share *Share) CanBeDownloadBy(user *User) error {
// 用户组权限
if !user.Group.OptionsSerialized.ShareDownloadEnabled {
if user.IsAnonymous() {
return errors.New("未登录用户无法下载")
}
return errors.New("您当前的用户组无权下载")
}
// 需要积分但未登录
if share.Score > 0 && user.IsAnonymous() {
return errors.New("未登录用户无法下载")
}
return nil
}
// WasDownloadedBy 返回分享是否已被用户下载过
func (share *Share) WasDownloadedBy(user *User) bool {
_, exist := cache.Get(fmt.Sprintf("share_%d_%d", share.ID, user.ID))
return exist
}
// DownloadBy 增加下载次数、检查积分等,匿名用户不会缓存
func (share *Share) DownloadBy(user *User) error {
if !share.WasDownloadedBy(user) {
if err := share.Purchase(user); err != nil {
return err
}
share.Downloaded()
if !user.IsAnonymous() {
cache.Set(fmt.Sprintf("share_%d_%d", share.ID, user.ID), true,
GetIntSetting("share_download_session_timeout", 2073600))
}
}
return nil
}
// Purchase 使用积分购买分享
func (share *Share) Purchase(user *User) error {
// 不需要付积分
if share.Score == 0 || user.Group.OptionsSerialized.ShareFreeEnabled {
return nil
}
ok := user.PayScore(share.Score)
if !ok {
return errors.New("积分不足")
}
return nil
}
// Viewed 增加访问次数
func (share *Share) Viewed() {
share.Views++
DB.Model(share).UpdateColumn("views", gorm.Expr("views + ?", 1))
}
// Downloaded 增加下载次数
func (share *Share) Downloaded() {
share.Downloads++
DB.Model(share).UpdateColumn("downloads", gorm.Expr("downloads + ?", 1))
}

View File

@@ -39,6 +39,7 @@ type User struct {
Avatar string
Options string `json:"-",gorm:"size:4096"`
Authn string `gorm:"size:8192"`
Score int
// 关联模型
Group Group `gorm:"association_autoupdate:false"`
@@ -93,6 +94,20 @@ func (user *User) IncreaseStorage(size uint64) bool {
return false
}
// PayScore 扣除积分,返回是否成功
// todo 测试
func (user *User) PayScore(score int) bool {
if score == 0 {
return true
}
if score <= user.Score {
user.Score -= score
DB.Model(user).UpdateColumn("score", gorm.Expr("score - ?", score))
return true
}
return false
}
// IncreaseStorageWithoutCheck 忽略可用容量,增加用户已用容量
func (user *User) IncreaseStorageWithoutCheck(size uint64) {
if size == 0 {