mirror of
https://github.com/Forceu/Gokapi.git
synced 2026-05-04 05:21:10 -05:00
Added option to disable upload and time limit during upload #13
This commit is contained in:
@@ -60,7 +60,12 @@ func updateConfig(settings *models.Configuration, env *environment.Environment)
|
||||
// < v1.5.0
|
||||
if settings.ConfigVersion < 11 {
|
||||
legacyConfig := loadLegacyConfigPreDb(env)
|
||||
datastorage.SaveUploadDefaults(legacyConfig.DefaultDownloads, legacyConfig.DefaultExpiry, legacyConfig.DefaultPassword)
|
||||
uploadValues := models.LastUploadValues{
|
||||
Downloads: legacyConfig.DefaultDownloads,
|
||||
TimeExpiry: legacyConfig.DefaultExpiry,
|
||||
Password: legacyConfig.DefaultPassword,
|
||||
}
|
||||
datastorage.SaveUploadDefaults(uploadValues)
|
||||
|
||||
for _, hotlink := range legacyConfig.Hotlinks {
|
||||
datastorage.SaveHotlink(models.File{Id: hotlink.FileId, HotlinkId: hotlink.Id})
|
||||
|
||||
@@ -17,9 +17,7 @@ const prefixApiKey = "apikey:id:"
|
||||
const prefixFile = "file:id:"
|
||||
const prefixHotlink = "hotlink:id:"
|
||||
const prefixSessions = "session:id:"
|
||||
const idDefaultDownloads = "default:downloads"
|
||||
const idDefaultExpiry = "default:expiry"
|
||||
const idDefaultPassword = "default:password"
|
||||
const idLastUploadConfig = "default:lastupload"
|
||||
|
||||
const maxKeySize = 96
|
||||
|
||||
@@ -39,7 +37,7 @@ func Init(dbPath string) {
|
||||
// GetLengthAvailable returns the maximum length for a key name
|
||||
func GetLengthAvailable() int {
|
||||
maxLength := 0
|
||||
for _, key := range []string{prefixApiKey, prefixFile, prefixHotlink, prefixSessions, idDefaultDownloads, idDefaultExpiry, idDefaultPassword} {
|
||||
for _, key := range []string{prefixApiKey, prefixFile, prefixHotlink, prefixSessions, idLastUploadConfig} {
|
||||
length := len(key)
|
||||
if length > maxLength {
|
||||
maxLength = length
|
||||
@@ -242,37 +240,34 @@ func SaveSession(id string, session models.Session, expiry time.Duration) {
|
||||
|
||||
// GetUploadDefaults returns the last used setting for amount of downloads allowed, last expiry in days and
|
||||
// a password for the file
|
||||
func GetUploadDefaults() (int, int, string) {
|
||||
downloads := 1
|
||||
expiry := 14
|
||||
password := ""
|
||||
if database.Has([]byte(idDefaultDownloads)) {
|
||||
bufByte, err := database.Get([]byte(idDefaultDownloads))
|
||||
helper.Check(err)
|
||||
downloads = byteToInt(bufByte)
|
||||
func GetUploadDefaults() models.LastUploadValues {
|
||||
defaultValues := models.LastUploadValues{
|
||||
Downloads: 1,
|
||||
TimeExpiry: 14,
|
||||
Password: "",
|
||||
UnlimitedDownload: false,
|
||||
UnlimitedTime: false,
|
||||
}
|
||||
if database.Has([]byte(idDefaultExpiry)) {
|
||||
bufByte, err := database.Get([]byte(idDefaultExpiry))
|
||||
result := models.LastUploadValues{}
|
||||
if database.Has([]byte(idLastUploadConfig)) {
|
||||
value, err := database.Get([]byte(idLastUploadConfig))
|
||||
helper.Check(err)
|
||||
expiry = byteToInt(bufByte)
|
||||
}
|
||||
if database.Has([]byte(idDefaultPassword)) {
|
||||
buf, err := database.Get([]byte(idDefaultPassword))
|
||||
buf := bytes.NewBuffer(value)
|
||||
dec := gob.NewDecoder(buf)
|
||||
err = dec.Decode(&result)
|
||||
helper.Check(err)
|
||||
password = string(buf)
|
||||
return result
|
||||
}
|
||||
return downloads, expiry, password
|
||||
return defaultValues
|
||||
}
|
||||
|
||||
// SaveUploadDefaults saves the last used setting for an upload
|
||||
func SaveUploadDefaults(downloads, expiry int, password string) {
|
||||
err := database.Put([]byte(idDefaultDownloads), intToByte(downloads))
|
||||
func SaveUploadDefaults(values models.LastUploadValues) {
|
||||
var buf bytes.Buffer
|
||||
enc := gob.NewEncoder(&buf)
|
||||
err := enc.Encode(values)
|
||||
helper.Check(err)
|
||||
err = database.Put([]byte(idDefaultExpiry), intToByte(expiry))
|
||||
helper.Check(err)
|
||||
err = database.Put([]byte(idDefaultPassword), []byte(password))
|
||||
helper.Check(err)
|
||||
err = database.Sync()
|
||||
err = database.Put([]byte(idLastUploadConfig), buf.Bytes())
|
||||
helper.Check(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -149,16 +149,26 @@ func TestSession(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUploadDefaults(t *testing.T) {
|
||||
downloads, expiry, password := GetUploadDefaults()
|
||||
test.IsEqualInt(t, downloads, 1)
|
||||
test.IsEqualInt(t, expiry, 14)
|
||||
test.IsEqualString(t, password, "")
|
||||
defaults := GetUploadDefaults()
|
||||
test.IsEqualInt(t, defaults.Downloads, 1)
|
||||
test.IsEqualInt(t, defaults.TimeExpiry, 14)
|
||||
test.IsEqualString(t, defaults.Password, "")
|
||||
test.IsEqualBool(t, defaults.UnlimitedDownload, false)
|
||||
test.IsEqualBool(t, defaults.UnlimitedTime, false)
|
||||
|
||||
SaveUploadDefaults(20, 30, "abcd")
|
||||
downloads, expiry, password = GetUploadDefaults()
|
||||
test.IsEqualInt(t, downloads, 20)
|
||||
test.IsEqualInt(t, expiry, 30)
|
||||
test.IsEqualString(t, password, "abcd")
|
||||
SaveUploadDefaults(models.LastUploadValues{
|
||||
Downloads: 20,
|
||||
TimeExpiry: 30,
|
||||
Password: "abcd",
|
||||
UnlimitedDownload: true,
|
||||
UnlimitedTime: true,
|
||||
})
|
||||
defaults = GetUploadDefaults()
|
||||
test.IsEqualInt(t, defaults.Downloads, 20)
|
||||
test.IsEqualInt(t, defaults.TimeExpiry, 30)
|
||||
test.IsEqualString(t, defaults.Password, "abcd")
|
||||
test.IsEqualBool(t, defaults.UnlimitedDownload, true)
|
||||
test.IsEqualBool(t, defaults.UnlimitedTime, true)
|
||||
}
|
||||
|
||||
func TestBinaryConversion(t *testing.T) {
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestEnvLoad(t *testing.T) {
|
||||
test.IsEqualInt(t, env.LengthId, 5)
|
||||
os.Setenv("GOKAPI_LENGTH_ID", "80")
|
||||
env = New()
|
||||
test.IsEqualInt(t, env.LengthId, 79)
|
||||
test.IsEqualInt(t, env.LengthId, 78)
|
||||
os.Unsetenv("GOKAPI_LENGTH_ID")
|
||||
env = New()
|
||||
os.Setenv("GOKAPI_LENGTH_ID", "15")
|
||||
|
||||
@@ -19,6 +19,14 @@ type Configuration struct {
|
||||
MaxFileSizeMB int `json:"MaxFileSizeMB"`
|
||||
}
|
||||
|
||||
type LastUploadValues struct {
|
||||
Downloads int
|
||||
TimeExpiry int
|
||||
Password string
|
||||
UnlimitedDownload bool
|
||||
UnlimitedTime bool
|
||||
}
|
||||
|
||||
// ToJson returns an idented JSon representation
|
||||
func (c Configuration) ToJson() []byte {
|
||||
result, err := json.MarshalIndent(c, "", " ")
|
||||
|
||||
@@ -18,6 +18,8 @@ type File struct {
|
||||
HotlinkId string `json:"HotlinkId"`
|
||||
ContentType string `json:"ContentType"`
|
||||
AwsBucket string `json:"AwsBucket"`
|
||||
UnlimitedDownloads bool `json:"UnlimitedDownloads"`
|
||||
UnlimitedTime bool `json:"UnlimitedTime"`
|
||||
}
|
||||
|
||||
// ToJsonResult converts the file info to a json String used for returning a result for an upload
|
||||
|
||||
@@ -21,5 +21,5 @@ func TestToJsonResult(t *testing.T) {
|
||||
HotlinkId: "hotlinkid",
|
||||
ContentType: "text/html",
|
||||
}
|
||||
test.IsEqualString(t, file.ToJsonResult("serverurl/"), `{"Result":"OK","FileInfo":{"Id":"testId","Name":"testName","Size":"10 B","SHA256":"sha256","ExpireAt":50,"ExpireAtString":"future","DownloadsRemaining":1,"PasswordHash":"pwhash","HotlinkId":"hotlinkid","ContentType":"text/html","AwsBucket":""},"Url":"serverurl/d?id=","HotlinkUrl":"serverurl/hotlink/"}`)
|
||||
test.IsEqualString(t, file.ToJsonResult("serverurl/"), `{"Result":"OK","FileInfo":{"Id":"testId","Name":"testName","Size":"10 B","SHA256":"sha256","ExpireAt":50,"ExpireAtString":"future","DownloadsRemaining":1,"PasswordHash":"pwhash","HotlinkId":"hotlinkid","ContentType":"text/html","AwsBucket":"","UnlimitedDownloads":false,"UnlimitedTime":false},"Url":"serverurl/d?id=","HotlinkUrl":"serverurl/hotlink/"}`)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package models
|
||||
|
||||
// UploadRequest is used to set an upload request
|
||||
type UploadRequest struct {
|
||||
AllowedDownloads int
|
||||
Expiry int
|
||||
ExpiryTimestamp int64
|
||||
Password string
|
||||
ExternalUrl string
|
||||
MaxMemory int
|
||||
DataDir string
|
||||
AllowedDownloads int
|
||||
Expiry int
|
||||
ExpiryTimestamp int64
|
||||
Password string
|
||||
ExternalUrl string
|
||||
MaxMemory int
|
||||
DataDir string
|
||||
UnlimitedDownload bool
|
||||
UnlimitedTime bool
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ func NewFile(fileContent io.Reader, fileHeader *multipart.FileHeader, uploadRequ
|
||||
DownloadsRemaining: uploadRequest.AllowedDownloads,
|
||||
PasswordHash: configuration.HashPassword(uploadRequest.Password, true),
|
||||
ContentType: fileHeader.Header.Get("Content-Type"),
|
||||
UnlimitedTime: uploadRequest.UnlimitedTime,
|
||||
UnlimitedDownloads: uploadRequest.UnlimitedDownload,
|
||||
}
|
||||
addHotlink(&file)
|
||||
if aws.IsAvailable() {
|
||||
@@ -143,7 +145,7 @@ func GetFile(id string) (models.File, bool) {
|
||||
if !ok {
|
||||
return emptyResult, false
|
||||
}
|
||||
if file.ExpireAt < time.Now().Unix() || file.DownloadsRemaining < 1 {
|
||||
if isExpiredFile(file, time.Now().Unix()) {
|
||||
return emptyResult, false
|
||||
}
|
||||
if !FileExists(file, configuration.Get().DataDir) {
|
||||
@@ -227,7 +229,7 @@ func CleanUp(periodic bool) {
|
||||
wasItemDeleted := false
|
||||
for key, element := range datastorage.GetAllMetadata() {
|
||||
fileExists := FileExists(element, configuration.Get().DataDir)
|
||||
if (element.ExpireAt < timeNow || element.DownloadsRemaining < 1 || !fileExists) && !downloadstatus.IsCurrentlyDownloading(element) {
|
||||
if !fileExists || isExpiredFileWithoutDownload(element, timeNow) {
|
||||
deleteFile := true
|
||||
for _, secondLoopElement := range datastorage.GetAllMetadata() {
|
||||
if element.Id != secondLoopElement.Id && element.SHA256 == secondLoopElement.SHA256 {
|
||||
@@ -253,6 +255,18 @@ func CleanUp(periodic bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func isExpiredFile(file models.File, timeNow int64) bool {
|
||||
return (file.ExpireAt < timeNow && !file.UnlimitedTime) ||
|
||||
(file.DownloadsRemaining < 1 && !file.UnlimitedDownloads)
|
||||
}
|
||||
|
||||
func isExpiredFileWithoutDownload(file models.File, timeNow int64) bool {
|
||||
if downloadstatus.IsCurrentlyDownloading(file) {
|
||||
return false
|
||||
}
|
||||
return isExpiredFile(file, timeNow)
|
||||
}
|
||||
|
||||
func deleteSource(file models.File, dataDir string) {
|
||||
var err error
|
||||
if file.AwsBucket != "" {
|
||||
|
||||
@@ -112,8 +112,24 @@ func TestNewFile(t *testing.T) {
|
||||
test.IsEqualInt(t, retrievedFile.DownloadsRemaining, 1)
|
||||
test.IsEqualInt(t, len(retrievedFile.Id), 20)
|
||||
test.IsEqualInt(t, int(retrievedFile.ExpireAt), 2147483600)
|
||||
test.IsEqualBool(t, file.UnlimitedTime, false)
|
||||
test.IsEqualBool(t, file.UnlimitedDownloads, false)
|
||||
idNewFile = file.Id
|
||||
|
||||
request.UnlimitedDownload = true
|
||||
file, err = NewFile(bytes.NewReader(content), &header, request)
|
||||
test.IsEqualBool(t, file.UnlimitedTime, false)
|
||||
test.IsEqualBool(t, file.UnlimitedDownloads, true)
|
||||
request.UnlimitedDownload = false
|
||||
request.UnlimitedTime = true
|
||||
file, err = NewFile(bytes.NewReader(content), &header, request)
|
||||
test.IsEqualBool(t, file.UnlimitedTime, true)
|
||||
test.IsEqualBool(t, file.UnlimitedDownloads, false)
|
||||
request.UnlimitedDownload = true
|
||||
file, err = NewFile(bytes.NewReader(content), &header, request)
|
||||
test.IsEqualBool(t, file.UnlimitedTime, true)
|
||||
test.IsEqualBool(t, file.UnlimitedDownloads, true)
|
||||
|
||||
createBigFile("bigfile", 20)
|
||||
bigFile, _ := os.Open("bigfile")
|
||||
mimeHeader = make(textproto.MIMEHeader)
|
||||
@@ -249,6 +265,8 @@ func TestCleanUp(t *testing.T) {
|
||||
test.IsEqualString(t, files["wefffewhtrhhtrhtrhtr"].Name, "smallfile3")
|
||||
test.IsEqualString(t, files["n1tSTAGj8zan9KaT4u6p"].Name, "picture.jpg")
|
||||
test.IsEqualString(t, files["deletedfile123456789"].Name, "DeletedFile")
|
||||
test.IsEqualString(t, files["unlimitedDownload"].Name, "unlimitedDownload")
|
||||
test.IsEqualString(t, files["unlimitedTime"].Name, "unlimitedTime")
|
||||
test.FileExists(t, "test/data/2341354656543213246465465465432456898794")
|
||||
|
||||
CleanUp(false)
|
||||
@@ -259,6 +277,8 @@ func TestCleanUp(t *testing.T) {
|
||||
test.IsEqualString(t, files["Wzol7LyY2QVczXynJtVo"].Name, "smallfile2")
|
||||
test.IsEqualString(t, files["e4TjE7CokWK0giiLNxDL"].Name, "smallfile2")
|
||||
test.IsEqualString(t, files["wefffewhtrhhtrhtrhtr"].Name, "smallfile3")
|
||||
test.IsEqualString(t, files["unlimitedDownload"].Name, "unlimitedDownload")
|
||||
test.IsEqualString(t, files["unlimitedTime"].Name, "unlimitedTime")
|
||||
test.IsEqualString(t, files["n1tSTAGj8zan9KaT4u6p"].Name, "picture.jpg")
|
||||
|
||||
file, _ := GetFile("n1tSTAGj8zan9KaT4u6p")
|
||||
|
||||
@@ -34,7 +34,13 @@ func Create(initFiles bool) {
|
||||
os.WriteFile(configFile, configTestFile, 0777)
|
||||
datastorage.Init("./test/filestorage.db")
|
||||
writeTestSessions()
|
||||
datastorage.SaveUploadDefaults(3, 20, "123")
|
||||
datastorage.SaveUploadDefaults(models.LastUploadValues{
|
||||
Downloads: 3,
|
||||
TimeExpiry: 20,
|
||||
Password: "123",
|
||||
UnlimitedDownload: false,
|
||||
UnlimitedTime: false,
|
||||
})
|
||||
writeTestFiles()
|
||||
datastorage.SaveHotlink(models.File{Id: "n1tSTAGj8zan9KaT4u6p", HotlinkId: "PhSs6mFtf8O5YGlLMfNw9rYXx9XRNkzCnJZpQBi7inunv3Z4A.jpg", ExpireAt: time.Now().Add(time.Hour).Unix()})
|
||||
writeApiKeyys()
|
||||
@@ -46,6 +52,7 @@ func Create(initFiles bool) {
|
||||
os.WriteFile("test/data/c4f9375f9834b4e7f0a528cc65c055702bf5f24a", []byte("456"), 0777)
|
||||
os.WriteFile("test/data/e017693e4a04a59d0b0f400fe98177fe7ee13cf7", []byte("789"), 0777)
|
||||
os.WriteFile("test/data/2341354656543213246465465465432456898794", []byte("abc"), 0777)
|
||||
os.WriteFile("test/data/unlimtedtest", []byte("def"), 0777)
|
||||
os.WriteFile("test/fileupload.jpg", []byte("abc"), 0777)
|
||||
}
|
||||
}
|
||||
@@ -270,6 +277,28 @@ func writeTestFiles() {
|
||||
ContentType: "application/octet-stream",
|
||||
AwsBucket: "gokapi-test",
|
||||
})
|
||||
datastorage.SaveMetaData(models.File{
|
||||
Id: "unlimitedDownload",
|
||||
Name: "unlimitedDownload",
|
||||
Size: "8 B",
|
||||
SHA256: "unlimtedtest",
|
||||
ExpireAt: 2147483646,
|
||||
ExpireAtString: "2021-05-04 15:19",
|
||||
DownloadsRemaining: 0,
|
||||
ContentType: "text/html",
|
||||
UnlimitedDownloads: true,
|
||||
})
|
||||
datastorage.SaveMetaData(models.File{
|
||||
Id: "unlimitedTime",
|
||||
Name: "unlimitedTime",
|
||||
Size: "8 B",
|
||||
SHA256: "unlimtedtest",
|
||||
ExpireAt: 0,
|
||||
ExpireAtString: "2021-05-04 15:19",
|
||||
DownloadsRemaining: 1,
|
||||
ContentType: "text/html",
|
||||
UnlimitedTime: true,
|
||||
})
|
||||
}
|
||||
|
||||
var configTestFile = []byte(`{
|
||||
|
||||
@@ -326,19 +326,21 @@ type DownloadView struct {
|
||||
|
||||
// UploadView contains parameters for the admin menu template
|
||||
type UploadView struct {
|
||||
Items []models.File
|
||||
ApiKeys []models.ApiKey
|
||||
Url string
|
||||
HotlinkUrl string
|
||||
TimeNow int64
|
||||
DefaultDownloads int
|
||||
DefaultExpiry int
|
||||
DefaultPassword string
|
||||
IsAdminView bool
|
||||
IsMainView bool
|
||||
IsApiView bool
|
||||
MaxFileSize int
|
||||
IsLogoutAvailable bool
|
||||
Items []models.File
|
||||
ApiKeys []models.ApiKey
|
||||
Url string
|
||||
HotlinkUrl string
|
||||
TimeNow int64
|
||||
IsAdminView bool
|
||||
IsMainView bool
|
||||
IsApiView bool
|
||||
MaxFileSize int
|
||||
IsLogoutAvailable bool
|
||||
DefaultDownloads int
|
||||
DefaultExpiry int
|
||||
DefaultPassword string
|
||||
DefaultUnlimitedDownload bool
|
||||
DefaultUnlimitedTime bool
|
||||
}
|
||||
|
||||
// Converts the globalConfig variable to an UploadView struct to pass the infos to
|
||||
@@ -381,7 +383,12 @@ func (u *UploadView) convertGlobalConfig(isMainView bool) *UploadView {
|
||||
u.IsMainView = isMainView
|
||||
u.MaxFileSize = configuration.Get().MaxFileSizeMB
|
||||
u.IsLogoutAvailable = authentication.IsLogoutAvailable()
|
||||
u.DefaultDownloads, u.DefaultExpiry, u.DefaultPassword = datastorage.GetUploadDefaults()
|
||||
defaultValues := datastorage.GetUploadDefaults()
|
||||
u.DefaultDownloads = defaultValues.Downloads
|
||||
u.DefaultExpiry = defaultValues.TimeExpiry
|
||||
u.DefaultPassword = defaultValues.Password
|
||||
u.DefaultUnlimitedDownload = defaultValues.UnlimitedDownload
|
||||
u.DefaultUnlimitedTime = defaultValues.UnlimitedTime
|
||||
return u
|
||||
}
|
||||
|
||||
|
||||
@@ -47,26 +47,39 @@ func parseConfig(values formOrHeader, setNewDefaults bool) models.UploadRequest
|
||||
password := values.Get("password")
|
||||
allowedDownloadsInt, err := strconv.Atoi(allowedDownloads)
|
||||
if err != nil {
|
||||
previous, _, _ := datastorage.GetUploadDefaults()
|
||||
allowedDownloadsInt = previous
|
||||
previousValues := datastorage.GetUploadDefaults()
|
||||
allowedDownloadsInt = previousValues.Downloads
|
||||
}
|
||||
expiryDaysInt, err := strconv.Atoi(expiryDays)
|
||||
if err != nil {
|
||||
_, previous, _ := datastorage.GetUploadDefaults()
|
||||
expiryDaysInt = previous
|
||||
previousValues := datastorage.GetUploadDefaults()
|
||||
expiryDaysInt = previousValues.TimeExpiry
|
||||
}
|
||||
|
||||
unlimitedDownload := values.Get("isUnlimitedDownload") == "true"
|
||||
unlimitedTime := values.Get("isUnlimitedTime") == "true"
|
||||
|
||||
if setNewDefaults {
|
||||
datastorage.SaveUploadDefaults(allowedDownloadsInt, expiryDaysInt, password)
|
||||
values := models.LastUploadValues{
|
||||
Downloads: allowedDownloadsInt,
|
||||
TimeExpiry: expiryDaysInt,
|
||||
Password: password,
|
||||
UnlimitedDownload: unlimitedDownload,
|
||||
UnlimitedTime: unlimitedTime,
|
||||
}
|
||||
datastorage.SaveUploadDefaults(values)
|
||||
}
|
||||
settings := configuration.Get()
|
||||
return models.UploadRequest{
|
||||
AllowedDownloads: allowedDownloadsInt,
|
||||
Expiry: expiryDaysInt,
|
||||
ExpiryTimestamp: time.Now().Add(time.Duration(expiryDaysInt) * time.Hour * 24).Unix(),
|
||||
Password: password,
|
||||
ExternalUrl: settings.ServerUrl,
|
||||
MaxMemory: settings.MaxMemory,
|
||||
DataDir: settings.DataDir,
|
||||
AllowedDownloads: allowedDownloadsInt,
|
||||
Expiry: expiryDaysInt,
|
||||
ExpiryTimestamp: time.Now().Add(time.Duration(expiryDaysInt) * time.Hour * 24).Unix(),
|
||||
Password: password,
|
||||
ExternalUrl: settings.ServerUrl,
|
||||
MaxMemory: settings.MaxMemory,
|
||||
DataDir: settings.DataDir,
|
||||
UnlimitedTime: unlimitedTime,
|
||||
UnlimitedDownload: unlimitedDownload,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,16 +35,16 @@ func TestParseConfig(t *testing.T) {
|
||||
password: "123",
|
||||
}
|
||||
config := parseConfig(data, false)
|
||||
downloads, _, _ := datastorage.GetUploadDefaults()
|
||||
defaults := datastorage.GetUploadDefaults()
|
||||
test.IsEqualInt(t, config.AllowedDownloads, 9)
|
||||
test.IsEqualString(t, config.Password, "123")
|
||||
test.IsEqualInt(t, config.Expiry, 5)
|
||||
|
||||
test.IsEqualInt(t, downloads, 3)
|
||||
test.IsEqualInt(t, defaults.Downloads, 3)
|
||||
config = parseConfig(data, true)
|
||||
downloads, _, _ = datastorage.GetUploadDefaults()
|
||||
test.IsEqualInt(t, downloads, 9)
|
||||
datastorage.SaveUploadDefaults(3, 20, "")
|
||||
defaults = datastorage.GetUploadDefaults()
|
||||
test.IsEqualInt(t, defaults.Downloads, 9)
|
||||
datastorage.SaveUploadDefaults(models.LastUploadValues{Downloads: 3, TimeExpiry: 20})
|
||||
data.allowedDownloads = ""
|
||||
data.expiryDays = "invalid"
|
||||
config = parseConfig(data, false)
|
||||
|
||||
@@ -65,6 +65,10 @@ a:hover {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.form-control:disabled {
|
||||
background: #bababa;
|
||||
}
|
||||
.break {
|
||||
flex-basis: 100%;
|
||||
height: 0;
|
||||
|
||||
@@ -18,6 +18,8 @@ Dropzone.options.uploaddropzone = {
|
||||
formData.append("allowedDownloads", document.getElementById("allowedDownloads").value);
|
||||
formData.append("expiryDays", document.getElementById("expiryDays").value);
|
||||
formData.append("password", document.getElementById("password").value);
|
||||
formData.append("isUnlimitedDownload", !document.getElementById("enableDownloadLimit").checked);
|
||||
formData.append("isUnlimitedTime", !document.getElementById("enableTimeLimit").checked);
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -33,6 +35,16 @@ document.onpaste = function(event){
|
||||
}
|
||||
|
||||
|
||||
function checkBoxChanged(checkBox, correspondingInput) {
|
||||
let disable = !checkBox.checked;
|
||||
|
||||
if (disable) {
|
||||
document.getElementById(correspondingInput).setAttribute("disabled", "");
|
||||
} else {
|
||||
document.getElementById(correspondingInput).removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
function parseData(data) {
|
||||
if (!data) return {"Result":"error"};
|
||||
if (typeof data === 'object') return data;
|
||||
@@ -64,8 +76,16 @@ function addRow(jsonText) {
|
||||
}
|
||||
cell1.innerText = item.Name;
|
||||
cell2.innerText = item.Size;
|
||||
cell3.innerText = item.DownloadsRemaining;
|
||||
cell4.innerText = item.ExpireAtString;
|
||||
if (item.UnlimitedDownloads) {
|
||||
cell3.innerText = "Unlimited";
|
||||
} else {
|
||||
cell3.innerText = item.DownloadsRemaining;
|
||||
}
|
||||
if (item.UnlimitedTime) {
|
||||
cell4.innerText = "Unlimited";
|
||||
} else {
|
||||
cell4.innerText = item.ExpireAtString;
|
||||
}
|
||||
cell5.innerHTML = '<a target="_blank" style="color: inherit" href="'+jsonObject.Url+item.Id+'">'+jsonObject.Url+item.Id+'</a>'+lockIcon;
|
||||
|
||||
let buttons = "<button type=\"button\" data-clipboard-text=\""+jsonObject.Url+item.Id+"\" class=\"copyurl btn btn-outline-light btn-sm\">Copy URL</button> ";
|
||||
|
||||
@@ -14,18 +14,21 @@
|
||||
<div class="container-md">
|
||||
<div class="row">
|
||||
<div class="form-group col">
|
||||
<input class="form-check-input" type="checkbox" name="enableDownloadLimit" id="enableDownloadLimit" onchange="checkBoxChanged(this, 'allowedDownloads')" value="" aria-label="Enable Download Limit" {{ if not .DefaultUnlimitedDownload }} checked {{ end }}>
|
||||
<label class="control-label small" for="allowedDownloads">Allowed downloads</label>
|
||||
<input type="number" class="form-control admin-input" value="{{ .DefaultDownloads }}" name="allowedDownloads" id="allowedDownloads" min="1"/>
|
||||
<input type="number" class="form-control admin-input" value="{{ .DefaultDownloads }}" name="allowedDownloads" id="allowedDownloads" min="1" {{ if .DefaultUnlimitedDownload }} disabled {{ end }}/>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
<div class="form-group col">
|
||||
<input class="form-check-input" type="checkbox" name="enableTimeLimit" id="enableTimeLimit" onchange="checkBoxChanged(this, 'expiryDays')" value="" aria-label="Enable Time Limit" {{ if not .DefaultUnlimitedTime }} checked {{ end }}>
|
||||
<label class="control-label small" for="expiryDays">Expiry in days</label>
|
||||
<input type="number" class="form-control admin-input" value="{{ .DefaultExpiry }}" name="expiryDays" id="expiryDays" min="1"/>
|
||||
<input type="number" class="form-control admin-input" value="{{ .DefaultExpiry }}" name="expiryDays" id="expiryDays" min="1" {{ if .DefaultUnlimitedTime }} disabled {{ end }}/>
|
||||
</div>
|
||||
<div class="break"></div>
|
||||
<div class="form-group col">
|
||||
<input class="form-check-input" type="checkbox" name="enablePassword" id="enablePassword" onchange="checkBoxChanged(this, 'password')" value="" aria-label="Enable Password Protection" {{ if ne .DefaultPassword "" }} checked {{ end }}>
|
||||
<label class="control-label small" for="password">Password</label>
|
||||
<input class="form-control admin-input" value="{{ .DefaultPassword }}" name="password" id="password" placeholder="None"/>
|
||||
<input class="form-control admin-input" value="{{ .DefaultPassword }}" name="password" id="password" placeholder="None" {{ if eq .DefaultPassword "" }} disabled {{ end }}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,8 +52,16 @@
|
||||
<tr>
|
||||
<td scope="col">{{ .Name }}</td>
|
||||
<td scope="col">{{ .Size }}</td>
|
||||
{{ if .UnlimitedDownloads }}
|
||||
<td scope="col">Unlimited</td>
|
||||
{{ else }}
|
||||
<td scope="col">{{ .DownloadsRemaining }}</td>
|
||||
{{ end }}
|
||||
{{ if .UnlimitedTime }}
|
||||
<td scope="col">Unlimited</td>
|
||||
{{ else }}
|
||||
<td scope="col">{{ .ExpireAtString }}</td>
|
||||
{{ end }}
|
||||
<td scope="col"><a target="_blank" href="{{ $.Url }}{{ .Id }}">{{ $.Url }}{{ .Id }}</a>{{ if ne .PasswordHash "" }} 🔒{{ end }}</td>
|
||||
<td scope="col"><button type="button" data-clipboard-text="{{ $.Url }}{{ .Id }}" class="copyurl btn btn-outline-light btn-sm">Copy URL</button>
|
||||
{{ if ne .HotlinkId "" }}
|
||||
@@ -70,7 +81,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./js/admin.js?v=6"></script>
|
||||
<script src="./js/admin.js?v=7"></script>
|
||||
<script>
|
||||
Dropzone.options.uploaddropzone["maxFilesize"] = {{ .MaxFileSize }};
|
||||
</script>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link href="css/cover.css?v=3" rel="stylesheet">
|
||||
<link href="css/cover.css?v=4" rel="stylesheet">
|
||||
{{ if .IsAdminView }}
|
||||
<title>{{template "app_name"}} Admin</title>
|
||||
<link href="./assets/dist/css/dropzone.min.css" rel="stylesheet">
|
||||
|
||||
Reference in New Issue
Block a user