mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Create hash id from feed parameters
This commit is contained in:
@@ -21,7 +21,7 @@ type PgStorage struct {
|
|||||||
|
|
||||||
func (p *PgStorage) CreateFeed(feed *Feed) error {
|
func (p *PgStorage) CreateFeed(feed *Feed) error {
|
||||||
feed.LastAccess = time.Now().UTC()
|
feed.LastAccess = time.Now().UTC()
|
||||||
_, err := p.db.Model(feed).Insert()
|
_, err := p.db.Model(feed).OnConflict("DO NOTHING").Insert()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create feed")
|
return errors.Wrap(err, "failed to create feed")
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,31 @@ func TestCreate(t *testing.T) {
|
|||||||
require.True(t, feed.Id > 0)
|
require.True(t, feed.Id > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateDuplicate(t *testing.T) {
|
||||||
|
feed := &Feed{
|
||||||
|
HashId: "123",
|
||||||
|
URL: "http://youtube.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
client := createClient(t)
|
||||||
|
err := client.CreateFeed(feed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Ensure 1 record
|
||||||
|
count, err := client.db.Model(&Feed{}).Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, count)
|
||||||
|
|
||||||
|
// Insert duplicated feed
|
||||||
|
err = client.CreateFeed(feed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Check no duplicates inserted
|
||||||
|
count, err = client.db.Model(&Feed{}).Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, count)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetFeed(t *testing.T) {
|
func TestGetFeed(t *testing.T) {
|
||||||
feed := &Feed{
|
feed := &Feed{
|
||||||
HashId: "xyz",
|
HashId: "xyz",
|
||||||
@@ -57,16 +82,6 @@ func TestUpdateLastAccess(t *testing.T) {
|
|||||||
require.True(t, last.LastAccess.Unix() > lastAccess.Unix())
|
require.True(t, last.LastAccess.Unix() > lastAccess.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUniqueHashId(t *testing.T) {
|
|
||||||
client := createClient(t)
|
|
||||||
|
|
||||||
err := client.CreateFeed(&Feed{HashId: "xyz", URL: "url"})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = client.CreateFeed(&Feed{HashId: "xyz", URL: "url"})
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
const TestDatabaseConnectionUrl = "postgres://postgres:@localhost/podsync?sslmode=disable"
|
const TestDatabaseConnectionUrl = "postgres://postgres:@localhost/podsync?sslmode=disable"
|
||||||
|
|
||||||
func createClient(t *testing.T) *PgStorage {
|
func createClient(t *testing.T) *PgStorage {
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package id
|
package id
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hash/fnv"
|
||||||
|
|
||||||
|
"github.com/mxpv/podsync/web/pkg/database"
|
||||||
hd "github.com/speps/go-hashids"
|
hd "github.com/speps/go-hashids"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,9 +17,24 @@ type hashId struct {
|
|||||||
hid *hd.HashID
|
hid *hd.HashID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hashId) Encode(x ...int) (string, error) {
|
func hashString(s string) int {
|
||||||
var d []int
|
h := fnv.New32a()
|
||||||
return h.hid.Encode(append(d, x...))
|
h.Write([]byte(s))
|
||||||
|
return int(h.Sum32())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *hashId) Encode(feed *database.Feed) (string, error) {
|
||||||
|
// Don't create duplicate urls for same playlist/settings
|
||||||
|
// https://github.com/podsync/issues/issues/6
|
||||||
|
numbers := []int{
|
||||||
|
hashString(feed.UserId),
|
||||||
|
hashString(feed.URL),
|
||||||
|
feed.PageSize,
|
||||||
|
hashString(string(feed.Quality)),
|
||||||
|
hashString(string(feed.Format)),
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.hid.Encode(numbers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIdGenerator() (*hashId, error) {
|
func NewIdGenerator() (*hashId, error) {
|
||||||
@@ -24,10 +42,6 @@ func NewIdGenerator() (*hashId, error) {
|
|||||||
data.MinLength = minLength
|
data.MinLength = minLength
|
||||||
data.Salt = salt
|
data.Salt = salt
|
||||||
data.Alphabet = alphabet
|
data.Alphabet = alphabet
|
||||||
hid, err := hd.NewWithData(data)
|
hid := hd.NewWithData(data)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &hashId{hid}, nil
|
return &hashId{hid}, nil
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,35 @@
|
|||||||
package id
|
package id
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mxpv/podsync/web/pkg/database"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEncode(t *testing.T) {
|
func TestEncode(t *testing.T) {
|
||||||
hid, err := NewIdGenerator()
|
hid, err := NewIdGenerator()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
hash, err := hid.Encode(1)
|
feed := &database.Feed{
|
||||||
|
UserId: "1",
|
||||||
|
URL: "https://www.youtube.com/channel/UC2yTVSttx7lxAOAzx1opjoA",
|
||||||
|
PageSize: 10,
|
||||||
|
Quality: database.HighQuality,
|
||||||
|
Format: database.AudioFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
hash1, err := hid.Encode(feed)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, hash)
|
require.NotEmpty(t, hash1)
|
||||||
|
|
||||||
|
// Ensure we have same hash for same feed/parameters
|
||||||
|
hash2, err := hid.Encode(feed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, hash1, hash2)
|
||||||
|
|
||||||
|
feed.UserId = ""
|
||||||
|
hash3, err := hid.Encode(feed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEqual(t, hash1, hash3)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user