diff --git a/dbl/bin.go b/dbl/bin.go index a0479d38..b57dd155 100644 --- a/dbl/bin.go +++ b/dbl/bin.go @@ -52,26 +52,26 @@ func (d *BinDao) GenerateId() string { } func (d *BinDao) GetAll(status int) (bins []ds.Bin, err error) { - sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated, bin.created, bin.expiration, bin.deleted FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.status = $1 GROUP BY bin.id" + sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated_at, bin.created_at, bin.expired_at, bin.deleted_at FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.status = $1 GROUP BY bin.id" rows, err := d.db.Query(sqlStatement, status) if err != nil { return bins, err } for rows.Next() { var bin ds.Bin - err = rows.Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.Updated, &bin.Created, &bin.Expiration, &bin.Deleted) + err = rows.Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.UpdatedAt, &bin.CreatedAt, &bin.ExpiredAt, &bin.DeletedAt) if err != nil { return bins, err } // https://github.com/lib/pq/issues/329 - bin.Updated = bin.Updated.UTC() - bin.Created = bin.Created.UTC() - bin.Expiration = bin.Expiration.UTC() - bin.Deleted = bin.Deleted.UTC() - bin.UpdatedRelative = humanize.Time(bin.Updated) - bin.CreatedRelative = humanize.Time(bin.Created) - bin.ExpirationRelative = humanize.Time(bin.Expiration) - bin.DeletedRelative = humanize.Time(bin.Deleted) + bin.UpdatedAt = bin.UpdatedAt.UTC() + bin.CreatedAt = bin.CreatedAt.UTC() + bin.ExpiredAt = bin.ExpiredAt.UTC() + bin.DeletedAt = bin.DeletedAt.UTC() + bin.UpdatedAtRelative = humanize.Time(bin.UpdatedAt) + bin.CreatedAtRelative = humanize.Time(bin.CreatedAt) + bin.ExpiredAtRelative = humanize.Time(bin.ExpiredAt) + bin.DeletedAtRelative = humanize.Time(bin.DeletedAt) bin.BytesReadable = humanize.Bytes(bin.Bytes) bin.URL = path.Join(bin.Id) bins = append(bins, bin) @@ -79,28 +79,28 @@ func (d *BinDao) GetAll(status int) (bins []ds.Bin, err error) { return bins, nil } -func (d *BinDao) GetBinsPendingExpiration() (bins []ds.Bin, err error) { +func (d *BinDao) GetBinsPendingExpiredAt() (bins []ds.Bin, err error) { now := time.Now().UTC().Truncate(time.Microsecond) - sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated, bin.created, bin.expiration, bin.deleted FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.expiration <= $1 AND bin.status < 2 GROUP BY bin.id" + sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated_at, bin.created_at, bin.expired_at, bin.deleted_at FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.expired_at <= $1 AND bin.status < 2 GROUP BY bin.id" rows, err := d.db.Query(sqlStatement, now) if err != nil { return bins, err } for rows.Next() { var bin ds.Bin - err = rows.Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.Updated, &bin.Created, &bin.Expiration, &bin.Deleted) + err = rows.Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.UpdatedAt, &bin.CreatedAt, &bin.ExpiredAt, &bin.DeletedAt) if err != nil { return bins, err } // https://github.com/lib/pq/issues/329 - bin.Updated = bin.Updated.UTC() - bin.Created = bin.Created.UTC() - bin.Expiration = bin.Expiration.UTC() - bin.Deleted = bin.Deleted.UTC() - bin.UpdatedRelative = humanize.Time(bin.Updated) - bin.CreatedRelative = humanize.Time(bin.Created) - bin.ExpirationRelative = humanize.Time(bin.Expiration) - bin.DeletedRelative = humanize.Time(bin.Deleted) + bin.UpdatedAt = bin.UpdatedAt.UTC() + bin.CreatedAt = bin.CreatedAt.UTC() + bin.ExpiredAt = bin.ExpiredAt.UTC() + bin.DeletedAt = bin.DeletedAt.UTC() + bin.UpdatedAtRelative = humanize.Time(bin.UpdatedAt) + bin.CreatedAtRelative = humanize.Time(bin.CreatedAt) + bin.ExpiredAtRelative = humanize.Time(bin.ExpiredAt) + bin.DeletedAtRelative = humanize.Time(bin.DeletedAt) bin.BytesReadable = humanize.Bytes(bin.Bytes) bin.URL = path.Join(bin.Id) bins = append(bins, bin) @@ -111,8 +111,8 @@ func (d *BinDao) GetBinsPendingExpiration() (bins []ds.Bin, err error) { func (d *BinDao) GetById(id string) (bin ds.Bin, found bool, err error) { // Get bin info // XXX: Split into two queries for readability - sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated, bin.created, bin.expiration, bin.deleted FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.id = $1 GROUP BY bin.id LIMIT 1" - err = d.db.QueryRow(sqlStatement, id).Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.Updated, &bin.Created, &bin.Expiration, &bin.Deleted) + sqlStatement := "SELECT bin.id, bin.readonly, bin.status, bin.downloads, COALESCE(SUM(file.bytes), 0), COUNT(filename) AS files, bin.updated_at, bin.created_at, bin.expired_at, bin.deleted_at FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.id = $1 GROUP BY bin.id LIMIT 1" + err = d.db.QueryRow(sqlStatement, id).Scan(&bin.Id, &bin.Readonly, &bin.Status, &bin.Downloads, &bin.Bytes, &bin.Files, &bin.UpdatedAt, &bin.CreatedAt, &bin.ExpiredAt, &bin.DeletedAt) if err != nil { if err == sql.ErrNoRows { return bin, false, nil @@ -121,15 +121,15 @@ func (d *BinDao) GetById(id string) (bin ds.Bin, found bool, err error) { } } // https://github.com/lib/pq/issues/329 - bin.Updated = bin.Updated.UTC() - bin.Created = bin.Created.UTC() - bin.Expiration = bin.Expiration.UTC() - bin.Deleted = bin.Deleted.UTC() + bin.UpdatedAt = bin.UpdatedAt.UTC() + bin.CreatedAt = bin.CreatedAt.UTC() + bin.ExpiredAt = bin.ExpiredAt.UTC() + bin.DeletedAt = bin.DeletedAt.UTC() bin.BytesReadable = humanize.Bytes(bin.Bytes) - bin.UpdatedRelative = humanize.Time(bin.Updated) - bin.CreatedRelative = humanize.Time(bin.Created) - bin.ExpirationRelative = humanize.Time(bin.Expiration) - bin.DeletedRelative = humanize.Time(bin.Deleted) + bin.UpdatedAtRelative = humanize.Time(bin.UpdatedAt) + bin.CreatedAtRelative = humanize.Time(bin.CreatedAt) + bin.ExpiredAtRelative = humanize.Time(bin.ExpiredAt) + bin.DeletedAtRelative = humanize.Time(bin.DeletedAt) bin.URL = path.Join(bin.Id) return bin, true, nil } @@ -142,17 +142,17 @@ func (d *BinDao) Insert(bin *ds.Bin) (err error) { downloads := uint64(0) readonly := false status := 0 - bin.Expiration = bin.Expiration.UTC().Truncate(time.Microsecond) - sqlStatement := "INSERT INTO bin (id, readonly, status, downloads, updated, created, expiration, deleted) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id" - if err := d.db.QueryRow(sqlStatement, bin.Id, readonly, status, downloads, now, now, bin.Expiration, bin.Deleted).Scan(&bin.Id); err != nil { + bin.ExpiredAt = bin.ExpiredAt.UTC().Truncate(time.Microsecond) + sqlStatement := "INSERT INTO bin (id, readonly, status, downloads, updated_at, created_at, expired_at, deleted_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id" + if err := d.db.QueryRow(sqlStatement, bin.Id, readonly, status, downloads, now, now, bin.ExpiredAt, bin.DeletedAt).Scan(&bin.Id); err != nil { return err } - bin.Updated = now - bin.Created = now - bin.UpdatedRelative = humanize.Time(bin.Updated) - bin.CreatedRelative = humanize.Time(bin.Created) - bin.DeletedRelative = humanize.Time(bin.Deleted) - bin.ExpirationRelative = humanize.Time(bin.Expiration) + bin.UpdatedAt = now + bin.CreatedAt = now + bin.UpdatedAtRelative = humanize.Time(bin.UpdatedAt) + bin.CreatedAtRelative = humanize.Time(bin.CreatedAt) + bin.DeletedAtRelative = humanize.Time(bin.DeletedAt) + bin.ExpiredAtRelative = humanize.Time(bin.ExpiredAt) bin.Downloads = downloads bin.Readonly = readonly bin.Status = status @@ -162,15 +162,15 @@ func (d *BinDao) Insert(bin *ds.Bin) (err error) { func (d *BinDao) Update(bin *ds.Bin) (err error) { var id string now := time.Now().UTC().Truncate(time.Microsecond) - bin.Expiration = bin.Expiration.UTC().Truncate(time.Microsecond) - sqlStatement := "UPDATE bin SET readonly = $1, status = $2, updated = $3, expiration = $4, deleted = $5 WHERE id = $6 RETURNING id" - err = d.db.QueryRow(sqlStatement, bin.Readonly, bin.Status, now, bin.Expiration, bin.Deleted, bin.Id).Scan(&id) + bin.ExpiredAt = bin.ExpiredAt.UTC().Truncate(time.Microsecond) + sqlStatement := "UPDATE bin SET readonly = $1, status = $2, updated_at = $3, expired_at = $4, deleted_at = $5 WHERE id = $6 RETURNING id" + err = d.db.QueryRow(sqlStatement, bin.Readonly, bin.Status, now, bin.ExpiredAt, bin.DeletedAt, bin.Id).Scan(&id) if err != nil { return err } - bin.Updated = now - bin.UpdatedRelative = humanize.Time(bin.Updated) - bin.DeletedRelative = humanize.Time(bin.Deleted) + bin.UpdatedAt = now + bin.UpdatedAtRelative = humanize.Time(bin.UpdatedAt) + bin.DeletedAtRelative = humanize.Time(bin.DeletedAt) return nil } @@ -202,7 +202,7 @@ func (d *BinDao) RegisterDownload(bin *ds.Bin) (err error) { func (d *BinDao) FlagRecentlyExpiredBins() (count int64, err error) { now := time.Now().UTC().Truncate(time.Microsecond) - sqlStatement := "UPDATE bin SET status = 1 WHERE status = 0 AND expiration <= $1" + sqlStatement := "UPDATE bin SET status = 1 WHERE status = 0 AND expired_at <= $1" res, err := d.db.Exec(sqlStatement, now) if err != nil { return 0, err @@ -219,7 +219,7 @@ func (d *BinDao) FlagEmptyBins() (count int64, err error) { limit := now.Add(-5 * time.Minute) // Flag empty bins that are older than limit as pending delete - sqlStatement := "UPDATE bin SET status = 1 WHERE bin.id IN (SELECT bin.id FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.status = 0 GROUP BY bin.id HAVING COUNT(filename) = 0 AND bin.created < $1)" + sqlStatement := "UPDATE bin SET status = 1 WHERE bin.id IN (SELECT bin.id FROM bin LEFT JOIN file ON bin.id = file.bin_id WHERE bin.status = 0 GROUP BY bin.id HAVING COUNT(filename) = 0 AND bin.created_at < $1)" res, err := d.db.Exec(sqlStatement, limit) if err != nil { return 0, err diff --git a/dbl/file.go b/dbl/file.go index 5fbc8fb4..358a5154 100644 --- a/dbl/file.go +++ b/dbl/file.go @@ -46,8 +46,8 @@ func (d *FileDao) ValidateInput(file *ds.File) error { } func (d *FileDao) GetById(id int) (file ds.File, found bool, err error) { - sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, updated, created, deleted FROM file WHERE id = $1 LIMIT 1" - err = d.db.QueryRow(sqlStatement, id).Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Updated, &file.Created, &file.Deleted) + sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, updated_at, created_at, deleted_at FROM file WHERE id = $1 LIMIT 1" + err = d.db.QueryRow(sqlStatement, id).Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.UpdatedAt, &file.CreatedAt, &file.DeletedAt) if err != nil { if err == sql.ErrNoRows { return file, false, nil @@ -56,19 +56,19 @@ func (d *FileDao) GetById(id int) (file ds.File, found bool, err error) { } } // https://github.com/lib/pq/issues/329 - file.Updated = file.Updated.UTC() - file.Created = file.Created.UTC() - file.Deleted = file.Deleted.UTC() - file.UpdatedRelative = humanize.Time(file.Updated) - file.CreatedRelative = humanize.Time(file.Created) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = file.UpdatedAt.UTC() + file.CreatedAt = file.CreatedAt.UTC() + file.DeletedAt = file.DeletedAt.UTC() + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.CreatedAtRelative = humanize.Time(file.CreatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) return file, true, nil } func (d *FileDao) GetByName(bin string, filename string) (file ds.File, found bool, err error) { - sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, updated, created, deleted FROM file WHERE bin_id = $1 AND filename = $2 LIMIT 1" - err = d.db.QueryRow(sqlStatement, bin, filename).Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Updated, &file.Created, &file.Deleted) + sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, updated_at, created_at, deleted_at FROM file WHERE bin_id = $1 AND filename = $2 LIMIT 1" + err = d.db.QueryRow(sqlStatement, bin, filename).Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.UpdatedAt, &file.CreatedAt, &file.DeletedAt) if err != nil { if err == sql.ErrNoRows { return file, false, nil @@ -77,12 +77,12 @@ func (d *FileDao) GetByName(bin string, filename string) (file ds.File, found bo } } // https://github.com/lib/pq/issues/329 - file.Updated = file.Updated.UTC() - file.Created = file.Created.UTC() - file.Deleted = file.Deleted.UTC() - file.UpdatedRelative = humanize.Time(file.Updated) - file.CreatedRelative = humanize.Time(file.Created) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = file.UpdatedAt.UTC() + file.CreatedAt = file.CreatedAt.UTC() + file.DeletedAt = file.DeletedAt.UTC() + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.CreatedAtRelative = humanize.Time(file.CreatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) setCategory(&file) return file, true, nil @@ -105,43 +105,43 @@ func (d *FileDao) Insert(file *ds.File) (err error) { file.Trace = "N/A" } - sqlStatement := "INSERT INTO file (bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated, created, deleted) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id" - err = d.db.QueryRow(sqlStatement, file.Bin, file.Filename, file.Status, file.Mime, file.Bytes, file.MD5, file.SHA256, downloads, updates, file.IP, file.Trace, file.Nonce, now, now, file.Deleted).Scan(&file.Id) + sqlStatement := "INSERT INTO file (bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated_at, created_at, deleted_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id" + err = d.db.QueryRow(sqlStatement, file.Bin, file.Filename, file.Status, file.Mime, file.Bytes, file.MD5, file.SHA256, downloads, updates, file.IP, file.Trace, file.Nonce, now, now, file.DeletedAt).Scan(&file.Id) if err != nil { return err } file.Status = status file.Downloads = uint64(downloads) file.Updates = uint64(updates) - file.Updated = now - file.Created = now - file.UpdatedRelative = humanize.Time(file.Updated) - file.CreatedRelative = humanize.Time(file.Created) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = now + file.CreatedAt = now + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.CreatedAtRelative = humanize.Time(file.CreatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) setCategory(file) return nil } func (d *FileDao) GetByBin(id string, status int) (files []ds.File, err error) { - sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated, created, deleted FROM file WHERE bin_id = $1 AND status = $2 ORDER BY filename ASC" + sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated_at, created_at, deleted_at FROM file WHERE bin_id = $1 AND status = $2 ORDER BY filename ASC" rows, err := d.db.Query(sqlStatement, id, status) if err != nil { return files, err } for rows.Next() { var file ds.File - err = rows.Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Nonce, &file.Updated, &file.Created, &file.Deleted) + err = rows.Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Nonce, &file.UpdatedAt, &file.CreatedAt, &file.DeletedAt) if err != nil { return files, err } // https://github.com/lib/pq/issues/329 - file.Updated = file.Updated.UTC() - file.Created = file.Created.UTC() - file.Deleted = file.Deleted.UTC() - file.UpdatedRelative = humanize.Time(file.Updated) - file.CreatedRelative = humanize.Time(file.Created) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = file.UpdatedAt.UTC() + file.CreatedAt = file.CreatedAt.UTC() + file.DeletedAt = file.DeletedAt.UTC() + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.CreatedAtRelative = humanize.Time(file.CreatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) file.URL = path.Join(file.Bin, file.Filename) setCategory(&file) @@ -151,24 +151,24 @@ func (d *FileDao) GetByBin(id string, status int) (files []ds.File, err error) { } func (d *FileDao) GetAll(status int) (files []ds.File, err error) { - sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated, created, deleted FROM file WHERE status = $1 ORDER BY filename ASC" + sqlStatement := "SELECT id, bin_id, filename, status, mime, bytes, md5, sha256, downloads, updates, ip, trace, nonce, updated_at, created_at, deleted_at FROM file WHERE status = $1 ORDER BY filename ASC" rows, err := d.db.Query(sqlStatement, status) if err != nil { return files, err } for rows.Next() { var file ds.File - err = rows.Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Nonce, &file.Updated, &file.Created, &file.Deleted) + err = rows.Scan(&file.Id, &file.Bin, &file.Filename, &file.Status, &file.Mime, &file.Bytes, &file.MD5, &file.SHA256, &file.Downloads, &file.Updates, &file.IP, &file.Trace, &file.Nonce, &file.UpdatedAt, &file.CreatedAt, &file.DeletedAt) if err != nil { return files, err } // https://github.com/lib/pq/issues/329 - file.Updated = file.Updated.UTC() - file.Created = file.Created.UTC() - file.Deleted = file.Deleted.UTC() - file.UpdatedRelative = humanize.Time(file.Updated) - file.CreatedRelative = humanize.Time(file.Created) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = file.UpdatedAt.UTC() + file.CreatedAt = file.CreatedAt.UTC() + file.DeletedAt = file.DeletedAt.UTC() + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.CreatedAtRelative = humanize.Time(file.CreatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) setCategory(&file) files = append(files, file) @@ -179,14 +179,14 @@ func (d *FileDao) GetAll(status int) (files []ds.File, err error) { func (d *FileDao) Update(file *ds.File) (err error) { var id int now := time.Now().UTC().Truncate(time.Microsecond) - sqlStatement := "UPDATE file SET filename = $1, status = $2, mime = $3, bytes = $4, md5 = $5, sha256 = $6, nonce = $7, updates = $8, updated = $9, deleted = $10, ip = $11, trace = $12 WHERE id = $13 RETURNING id" - err = d.db.QueryRow(sqlStatement, file.Filename, file.Status, file.Mime, file.Bytes, file.MD5, file.SHA256, file.Nonce, file.Updates, now, file.Deleted, file.IP, file.Trace, file.Id).Scan(&id) + sqlStatement := "UPDATE file SET filename = $1, status = $2, mime = $3, bytes = $4, md5 = $5, sha256 = $6, nonce = $7, updates = $8, updated_at = $9, deleted_at = $10, ip = $11, trace = $12 WHERE id = $13 RETURNING id" + err = d.db.QueryRow(sqlStatement, file.Filename, file.Status, file.Mime, file.Bytes, file.MD5, file.SHA256, file.Nonce, file.Updates, now, file.DeletedAt, file.IP, file.Trace, file.Id).Scan(&id) if err != nil { return err } - file.Updated = now - file.UpdatedRelative = humanize.Time(file.Updated) - file.DeletedRelative = humanize.Time(file.Deleted) + file.UpdatedAt = now + file.UpdatedAtRelative = humanize.Time(file.UpdatedAt) + file.DeletedAtRelative = humanize.Time(file.DeletedAt) file.BytesReadable = humanize.Bytes(file.Bytes) setCategory(file) return nil diff --git a/ds/bin.go b/ds/bin.go index 002e427d..13718b38 100644 --- a/ds/bin.go +++ b/ds/bin.go @@ -5,22 +5,22 @@ import ( ) type Bin struct { - Id string `json:"id"` - Status int `json:"-"` - Readonly bool `json:"readonly"` - Downloads uint64 `json:"-"` - Bytes uint64 `json:"bytes"` - BytesReadable string `json:"bytes_readable"` - Files uint64 `json:"files"` - Updated time.Time `json:"updated"` - UpdatedRelative string `json:"updated_relative"` - Created time.Time `json:"created"` - CreatedRelative string `json:"created_relative"` - Expiration time.Time `json:"expiration"` - ExpirationRelative string `json:"expiration_relative"` - Deleted time.Time `json:"-"` - DeletedRelative string `json:"-"` - URL string `json:"-"` + Id string `json:"id"` + Status int `json:"-"` + Readonly bool `json:"readonly"` + Downloads uint64 `json:"-"` + Bytes uint64 `json:"bytes"` + BytesReadable string `json:"bytes_readable"` + Files uint64 `json:"files"` + UpdatedAt time.Time `json:"updated_at"` + UpdatedAtRelative string `json:"updated_at_relative"` + CreatedAt time.Time `json:"created_at"` + CreatedAtRelative string `json:"created_at_relative"` + ExpiredAt time.Time `json:"expired_at"` + ExpiredAtRelative string `json:"expired_at_relative"` + DeletedAt time.Time `json:"-"` + DeletedAtRelative string `json:"-"` + URL string `json:"-"` } func (b *Bin) IsReadable() bool { @@ -29,7 +29,7 @@ func (b *Bin) IsReadable() bool { return false } // Not readable if the deleted timestamp is more recent than zero - if b.Deleted.IsZero() == false { + if b.DeletedAt.IsZero() == false { return false } // Not readable if flagged as deleted @@ -52,7 +52,7 @@ func (b *Bin) IsWritable() bool { } func (b *Bin) Expired() bool { - if b.Expiration.Before(time.Now()) { + if b.ExpiredAt.Before(time.Now()) { return true } return false diff --git a/ds/file.go b/ds/file.go index 12ccd76a..54ff5000 100644 --- a/ds/file.go +++ b/ds/file.go @@ -5,33 +5,33 @@ import ( ) type File struct { - Id int `json:"-"` - Bin string `json:"-"` - Filename string `json:"filename"` - Status int `json:"-"` - Mime string `json:"content-type"` - Category string `json:"-"` - Bytes uint64 `json:"bytes"` - BytesReadable string `json:"bytes_readable"` - MD5 string `json:"md5"` - SHA256 string `json:"sha256"` - Downloads uint64 `json:"-"` - Updates uint64 `json:"updates"` - IP string `json:"-"` - Trace string `json:"-"` - Nonce []byte `json:"-"` - Updated time.Time `json:"updated"` - UpdatedRelative string `json:"updated_relative"` - Created time.Time `json:"created"` - CreatedRelative string `json:"created_relative"` - Deleted time.Time `json:"-"` - DeletedRelative string `json:"-"` - URL string `json:"-"` + Id int `json:"-"` + Bin string `json:"-"` + Filename string `json:"filename"` + Status int `json:"-"` + Mime string `json:"content-type"` + Category string `json:"-"` + Bytes uint64 `json:"bytes"` + BytesReadable string `json:"bytes_readable"` + MD5 string `json:"md5"` + SHA256 string `json:"sha256"` + Downloads uint64 `json:"-"` + Updates uint64 `json:"updates"` + IP string `json:"-"` + Trace string `json:"-"` + Nonce []byte `json:"-"` + UpdatedAt time.Time `json:"updated_at_"` + UpdatedAtRelative string `json:"updated_at__relative"` + CreatedAt time.Time `json:"created_at_"` + CreatedAtRelative string `json:"created_at__relative"` + DeletedAt time.Time `json:"-"` + DeletedAtRelative string `json:"-"` + URL string `json:"-"` } func (f *File) IsReadable() bool { // Not readable if the deleted timestamp is more recent than zero - if f.Deleted.IsZero() == false { + if f.DeletedAt.IsZero() == false { return false } // Not readable if flagged as deleted diff --git a/http_bin.go b/http_bin.go index d13156fc..9ee84b8e 100644 --- a/http_bin.go +++ b/http_bin.go @@ -104,7 +104,7 @@ func (h *HTTP) Archive(w http.ResponseWriter, r *http.Request) { for _, file := range files { header := &zip.FileHeader{} header.Name = file.Filename - header.Modified = file.Updated + header.Modified = file.UpdatedAt header.SetMode(400) // RW for the file owner ze, err := zw.CreateHeader(header) @@ -137,7 +137,7 @@ func (h *HTTP) Archive(w http.ResponseWriter, r *http.Request) { header := &tar.Header{} header.Name = file.Filename header.Size = int64(file.Bytes) - header.ModTime = file.Updated + header.ModTime = file.UpdatedAt header.Mode = 0600 // rw access for the owner if err := tw.WriteHeader(header); err != nil { @@ -190,7 +190,7 @@ func (h *HTTP) DeleteBin(w http.ResponseWriter, r *http.Request) { // Set to pending delete bin.Status = 1 - bin.Deleted = now + bin.DeletedAt = now if err := h.dao.Bin().Update(&bin); err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return diff --git a/http_file.go b/http_file.go index b817a90a..ccbf9863 100644 --- a/http_file.go +++ b/http_file.go @@ -64,8 +64,8 @@ func (h *HTTP) GetFile(w http.ResponseWriter, r *http.Request) { return } - w.Header().Set("Expires", bin.Expiration.Format(http.TimeFormat)) - w.Header().Set("Last-Modified", file.Updated.Format(http.TimeFormat)) + w.Header().Set("Expires", bin.ExpiredAt.Format(http.TimeFormat)) + w.Header().Set("Last-Modified", file.UpdatedAt.Format(http.TimeFormat)) w.Header().Set("Bin", file.Bin) w.Header().Set("Filename", file.Filename) w.Header().Set("Content-Length", fmt.Sprintf("%d", file.Bytes)) @@ -134,7 +134,7 @@ func (h *HTTP) Upload(w http.ResponseWriter, r *http.Request) { // Bin does not exist, so create it here bin = ds.Bin{} bin.Id = inputBin - bin.Expiration = time.Now().UTC().Add(h.expirationDuration) + bin.ExpiredAt = time.Now().UTC().Add(h.expirationDuration) if err := h.dao.Bin().Insert(&bin); err != nil { h.Error(w, r, fmt.Sprintf("Unable to insert bin %s: %s", inputBin, err.Error()), "Database error", 121, http.StatusInternalServerError) return @@ -263,7 +263,7 @@ func (h *HTTP) Upload(w http.ResponseWriter, r *http.Request) { // Reset the deleted status and timestamp in case the file was deleted // earlier var t time.Time - file.Deleted = t + file.DeletedAt = t file.Status = 0 file.Bytes = inputBytes @@ -302,7 +302,7 @@ func (h *HTTP) Upload(w http.ResponseWriter, r *http.Request) { } // Update bin to set the correct updated timestamp - bin.Expiration = time.Now().UTC().Add(h.expirationDuration) + bin.ExpiredAt = time.Now().UTC().Add(h.expirationDuration) if err := h.dao.Bin().Update(&bin); err != nil { fmt.Printf("Unable to update bin %s: %s\n", bin.Id, err.Error()) http.Error(w, "Errno 109", http.StatusInternalServerError) @@ -371,7 +371,7 @@ func (h *HTTP) DeleteFile(w http.ResponseWriter, r *http.Request) { // Set to pending delete file.Status = 1 - file.Deleted = now + file.DeletedAt = now if err := h.dao.File().Update(&file); err != nil { fmt.Printf("Unable to update the file (%s, %s): %s\n", inputBin, inputFilename, err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) diff --git a/http_file_test.go b/http_file_test.go index 99aac06d..22a2290b 100644 --- a/http_file_test.go +++ b/http_file_test.go @@ -187,7 +187,7 @@ func TestUploadFile(t *testing.T) { runTests(tcs, t) } -func TestUploadToDeletedBin(t *testing.T) { +func TestUploadToDeletedAtBin(t *testing.T) { tcs := []TestCase{ { Description: "Create file to set up test case", diff --git a/http_index.go b/http_index.go index 98f3eab8..b2d77ce1 100644 --- a/http_index.go +++ b/http_index.go @@ -20,7 +20,7 @@ func (h *HTTP) Index(w http.ResponseWriter, r *http.Request) { data.Page = "front" bin := &ds.Bin{} - bin.Expiration = time.Now().UTC().Add(h.expirationDuration) + bin.ExpiredAt = time.Now().UTC().Add(h.expirationDuration) err := h.dao.Bin().Insert(bin) if err != nil { fmt.Printf("Unable to insert new bin: %s\n", err.Error()) diff --git a/http_test.go b/http_test.go index a11ac29f..30dca5da 100644 --- a/http_test.go +++ b/http_test.go @@ -15,7 +15,7 @@ import ( ) const ( - testExpiration = 5 + testExpiredAt = 5 testHTTPHost = "localhost" testHTTPPort = 8080 testDbName = "db" @@ -72,7 +72,7 @@ func TestMain(m *testing.M) { staticBox := rice.MustFindBox("static") templateBox := rice.MustFindBox("templates") h := &HTTP{ - expiration: testExpiration, + expiration: testExpiredAt, httpHost: testHTTPHost, httpPort: testHTTPPort, staticBox: staticBox, diff --git a/schema.sql b/schema.sql index 35a97916..44f04518 100644 --- a/schema.sql +++ b/schema.sql @@ -2,10 +2,10 @@ id VARCHAR(64) NOT NULL PRIMARY KEY, readonly BOOLEAN NOT NULL, status INT NOT NULL, - updated TIMESTAMP NOT NULL, - created TIMESTAMP NOT NULL, - expiration TIMESTAMP NOT NULL, - deleted TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL, + expired_at TIMESTAMP NOT NULL, + deleted_at TIMESTAMP NOT NULL, downloads BIGINT NOT NULL ); @@ -23,9 +23,9 @@ CREATE TABLE file ( ip VARCHAR(128) NOT NULL, trace TEXT NOT NULL, nonce VARCHAR(128) NOT NULL, - updated TIMESTAMP NOT NULL, - created TIMESTAMP NOT NULL, - deleted TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL, + deleted_at TIMESTAMP NOT NULL, UNIQUE(bin_id, filename) ); diff --git a/templates/bin.tpl b/templates/bin.tpl index e6b7ff6e..1cd9ddf7 100644 --- a/templates/bin.tpl +++ b/templates/bin.tpl @@ -62,13 +62,13 @@ {{ $numfiles := .Files | len }}

- The bin {{ .Bin.Id }} was created {{ .Bin.CreatedRelative }} + The bin {{ .Bin.Id }} was created {{ .Bin.CreatedAtRelative }} - {{- if ne .Bin.CreatedRelative .Bin.UpdatedRelative -}} - , updated {{ .Bin.UpdatedRelative }} + {{- if ne .Bin.CreatedAtRelative .Bin.UpdatedAtRelative -}} + , updated {{ .Bin.UpdatedAtRelative }} {{ end }} - and it expires {{ .Bin.ExpirationRelative }}. + and it expires {{ .Bin.ExpiredAtRelative }}. It contains {{ .Files | len }} {{ if eq $numfiles 0 }}files.{{ end }} @@ -143,7 +143,7 @@ {{ .BytesReadable }} - {{ .UpdatedRelative }} + {{ .UpdatedAtRelative }}

@@ -394,7 +394,7 @@ ({{ .Bytes }} bytes) - {{ if ne .Created .Updated }} + {{ if ne .CreatedAt .UpdatedAt }}
Update count
{{ .Updates }} @@ -402,23 +402,23 @@
Last updated
- {{ .UpdatedRelative }} - ({{ .Updated.Format "2006-01-02 15:04:05 UTC" }}) + {{ .UpdatedAtRelative }} + ({{ .UpdatedAt.Format "2006-01-02 15:04:05 UTC" }})
{{ end }}
Created
- {{ .CreatedRelative }} - ({{ .Created.Format "2006-01-02 15:04:05 UTC" }}) + {{ .CreatedAtRelative }} + ({{ .CreatedAt.Format "2006-01-02 15:04:05 UTC" }})
Expires
- {{ if $.Bin.ExpirationRelative }} - {{ $.Bin.ExpirationRelative }} + {{ if $.Bin.ExpiredAtRelative }} + {{ $.Bin.ExpiredAtRelative }} {{ end }} - ({{ $.Bin.Expiration.Format "2006-01-02 15:04:05 UTC" }}) + ({{ $.Bin.ExpiredAt.Format "2006-01-02 15:04:05 UTC" }})
diff --git a/templates/dashboard.tpl b/templates/dashboard.tpl index 3efd5ab0..aae60608 100644 --- a/templates/dashboard.tpl +++ b/templates/dashboard.tpl @@ -71,7 +71,7 @@ {{ range $index, $value := .Bins.PendingDelete }} {{ .Id }} - {{ .UpdatedRelative }} + {{ .UpdatedAtRelative }} {{ .BytesReadable }} {{ .Files }} @@ -97,7 +97,7 @@ {{ range $index, $value := .Bins.Available }} {{ .Id }} - {{ .UpdatedRelative }} + {{ .UpdatedAtRelative }} {{ .BytesReadable }} {{ .Files }} diff --git a/templates/index.tpl b/templates/index.tpl index 39fdc312..7478e3ac 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -52,7 +52,7 @@ Convenient file sharing without registration. Simply upload files and share the URL. The files will expire automatically - {{ .Bin.ExpirationRelative }}. + {{ .Bin.ExpiredAtRelative }}.

1. diff --git a/templates/terms.tpl b/templates/terms.tpl index 70b2c2b4..5c269a38 100644 --- a/templates/terms.tpl +++ b/templates/terms.tpl @@ -14,7 +14,37 @@ {{template "topbar" .}}

Terms and conditions

-

Text goes here.

+

These terms and conditions ("Agreement") sets forth the general terms and conditions of your use of this website ("Website" or "Service") and any of its related products and services (collectively, "Services"). This Agreement is legally binding between you ("User", "you" or "your") and this Website operator ("Operator", "we", "us" or "our"). By accessing and using the Website and Services, you acknowledge that you have read, understood, and agree to be bound by the terms of this Agreement. If you are entering into this Agreement on behalf of a business or other legal entity, you represent that you have the authority to bind such entity to this Agreement, in which case the terms "User", "you" or "your" shall refer to such entity. If you do not have such authority, or if you do not agree with the terms of this Agreement, you must not accept this Agreement and may not access and use the Website and Services. You acknowledge that this Agreement is a contract between you and the Operator, even though it is electronic and is not physically signed by you, and it governs your use of the Website and Services.

+ +

User content

+ +

We do not own any data, information or material (collectively, "Content") that you submit on the Website in the course of using the Service. You shall have sole responsibility for the accuracy, quality, integrity, legality, reliability, appropriateness, and intellectual property ownership or right to use of all submitted Content. We may, but have no obligation to, monitor and review the Content on the Website submitted or created using our Services by you. You grant us permission to access, copy, distribute, store, transmit, reformat, display and perform the Content you upload solely as required for the purpose of providing the Services to you. Without limiting any of those representations or warranties, we have the right, though not the obligation, to, in our own sole discretion, refuse or remove any Content at any time.

+ +

Backups

+ +

We are not responsible for the Content residing on the Website. In no event shall we be held liable for any loss of any Content. It is your sole responsibility to maintain appropriate backup of your Content. Notwithstanding the foregoing, on some occasions and in certain circumstances, with absolutely no obligation, we may be able to restore some or all of your data that has been deleted as of a certain date and time when we may have backed up data for our own purposes. We make no guarantee that the data you need will be available.

+ +

Prohibited uses

+ +

In addition to other terms as set forth in the Agreement, you are prohibited from using the Website and Services or Content: (a) for any unlawful purpose; (b) to solicit others to perform or participate in any unlawful acts; (c) to violate any international, federal, provincial or state regulations, rules, laws, or local ordinances; (d) to infringe upon or violate our intellectual property rights or the intellectual property rights of others; (e) to harass, abuse, insult, harm, defame, slander, disparage, intimidate, or discriminate based on gender, sexual orientation, religion, ethnicity, race, age, national origin, or disability; (f) to submit false or misleading information; (g) to upload or transmit viruses or any other type of malicious code that will or may be used in any way that will affect the functionality or operation of the Website and Services, third party products and services, or the Internet; (h) to spam, phish, pharm, pretext, spider, crawl, or scrape; (i) for any obscene or immoral purpose; or (j) to interfere with or circumvent the security features of the Website and Services, third party products and services, or the Internet. We reserve the right to terminate your use of the Website and Services for violating any of the prohibited uses.

+ +

Limitation of liability

+ +

In no event will the Operator be liable to any person for any indirect, incidental, special, punitive, cover or consequential damages (including, without limitation, damages for lost profits, revenue, sales, goodwill, use of content, impact on business, business interruption, loss of anticipated savings, loss of business opportunity) however caused, under any theory of liability, including, without limitation, contract, tort, warranty, breach of statutory duty, negligence or otherwise, even if the liable party has been advised as to the possibility of such damages or could have foreseen such damages.

+ +

Changes and amendments

+ +

We reserve the right to modify this Agreement or its terms relating to the Website and Services at any time, effective upon posting of an updated version of this Agreement on the Website. When we do, we will revise the updated date at the bottom of this page. Continued use of the Website and Services after any such changes shall constitute your consent to such changes. Policy was created with WebsitePolicies.

+ +

Acceptance of these terms

+ +

You acknowledge that you have read this Agreement and agree to all its terms and conditions. By accessing and using the Website and Services you agree to be bound by this Agreement. If you do not agree to abide by the terms of this Agreement, you are not authorized to access or use the Website and Services.

+ +

Contacting us

+ +

If you have any questions about this Agreement, please contact us.

+ +

This document was last updated on September 8, 2020

{{ template "footer" . }}