Compare commits
18 Commits
83bcf0e708
...
e6201eacef
| Author | SHA1 | Date | |
|---|---|---|---|
| e6201eacef | |||
| b0fb1b5bec | |||
| 7f4eb2e7e3 | |||
| 7252675aba | |||
| beba0e5120 | |||
| 9c3e884fd1 | |||
| 2288e70e85 | |||
| cec5fd0672 | |||
| c51bfc4603 | |||
| 08257bab25 | |||
| 036152d89e | |||
| 7c18c4811f | |||
| ab7e654f7c | |||
| 4829ce0192 | |||
| 79c44a5b0b | |||
| ee78ca96f3 | |||
| 816e9087ca | |||
| 412debc637 |
|
|
@ -6,7 +6,12 @@ a [Microsub](https://indieweb.org/Microsub) server
|
||||||
|
|
||||||
There are two methods for installing and running ekster.
|
There are two methods for installing and running ekster.
|
||||||
|
|
||||||
### Method 1: Install ekster (from source)
|
### Method 1: From binaries
|
||||||
|
|
||||||
|
Download the binaries from the [latest release](https://github.com/pstuifzand/ekster/releases/) on Github.
|
||||||
|
|
||||||
|
|
||||||
|
### Method 2: Install ekster from source with Go
|
||||||
|
|
||||||
ekster is build using [go](https://golang.org). To be able to install ekster
|
ekster is build using [go](https://golang.org). To be able to install ekster
|
||||||
you need a Go environment. Use these commands to install the programs.
|
you need a Go environment. Use these commands to install the programs.
|
||||||
|
|
@ -38,7 +43,7 @@ Start eksterd and pass the redis and port arguments.
|
||||||
You can now access `eksterd` on port `8090`. To really use it, you should proxy
|
You can now access `eksterd` on port `8090`. To really use it, you should proxy
|
||||||
`eksterd` behind a HTTP reverse proxy on port 80, or 443.
|
`eksterd` behind a HTTP reverse proxy on port 80, or 443.
|
||||||
|
|
||||||
### Method 2: Using Docker / Docker Compose
|
### Method 3: Using Docker / Docker Compose
|
||||||
|
|
||||||
It's now also possible to use docker-compose to start an ekster server. Create an empty directory.
|
It's now also possible to use docker-compose to start an ekster server. Create an empty directory.
|
||||||
Download [docker-compose.yml](https://raw.githubusercontent.com/pstuifzand/ekster/master/docker-compose.yml) from Github
|
Download [docker-compose.yml](https://raw.githubusercontent.com/pstuifzand/ekster/master/docker-compose.yml) from Github
|
||||||
|
|
|
||||||
196
cmd/ek/main.go
196
cmd/ek/main.go
|
|
@ -314,8 +314,8 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(commands) == 2 && commands[0] == "preview" {
|
if len(commands) == 2 && commands[0] == "preview" {
|
||||||
url := commands[1]
|
u := commands[1]
|
||||||
timeline, err := sub.PreviewURL(url)
|
timeline, err := sub.PreviewURL(u)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
|
|
@ -338,8 +338,8 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
|
|
||||||
if len(commands) == 3 && commands[0] == "follow" {
|
if len(commands) == 3 && commands[0] == "follow" {
|
||||||
uid := commands[1]
|
uid := commands[1]
|
||||||
url := commands[2]
|
u := commands[2]
|
||||||
_, err := sub.FollowURL(uid, url)
|
_, err := sub.FollowURL(uid, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
@ -348,8 +348,8 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
|
|
||||||
if len(commands) == 3 && commands[0] == "unfollow" {
|
if len(commands) == 3 && commands[0] == "unfollow" {
|
||||||
uid := commands[1]
|
uid := commands[1]
|
||||||
url := commands[2]
|
u := commands[2]
|
||||||
err := sub.UnfollowURL(uid, url)
|
err := sub.UnfollowURL(uid, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
@ -359,16 +359,41 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
filetype := commands[1]
|
filetype := commands[1]
|
||||||
|
|
||||||
if filetype == "opml" {
|
if filetype == "opml" {
|
||||||
|
exportOpmlFromMicrosub(sub)
|
||||||
|
} else if filetype == "json" {
|
||||||
|
exportJsonFromMicrosub(sub)
|
||||||
|
} else {
|
||||||
|
log.Fatalf("unsupported filetype %q", filetype)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(commands) == 3 && commands[0] == "import" {
|
||||||
|
filetype := commands[1]
|
||||||
|
filename := commands[2]
|
||||||
|
|
||||||
|
if filetype == "opml" {
|
||||||
|
importOpmlIntoMicrosub(sub, filename)
|
||||||
|
} else if filetype == "json" {
|
||||||
|
importJsonIntoMicrosub(sub, filename)
|
||||||
|
} else {
|
||||||
|
log.Fatalf("unsupported filetype %q", filetype)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(commands) == 1 && commands[0] == "version" {
|
||||||
|
fmt.Printf("ek %s\n", Version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func exportOpmlFromMicrosub(sub microsub.Microsub) {
|
||||||
output := opml.OPML{}
|
output := opml.OPML{}
|
||||||
output.Head.Title = "Microsub channels and feeds"
|
output.Head.Title = "Microsub channels and feeds"
|
||||||
output.Head.DateCreated = time.Now().Format(time.RFC3339)
|
output.Head.DateCreated = time.Now().Format(time.RFC3339)
|
||||||
output.Version = "1.0"
|
output.Version = "1.0"
|
||||||
|
|
||||||
channels, err := sub.ChannelsGetList()
|
channels, err := sub.ChannelsGetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
var feeds []opml.Outline
|
var feeds []opml.Outline
|
||||||
list, err := sub.FollowGetList(c.UID)
|
list, err := sub.FollowGetList(c.UID)
|
||||||
|
|
@ -392,26 +417,23 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
Outlines: feeds,
|
Outlines: feeds,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
xml, err := output.XML()
|
xml, err := output.XML()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
os.Stdout.WriteString(xml)
|
os.Stdout.WriteString(xml)
|
||||||
} else if filetype == "json" {
|
}
|
||||||
contents := Export{Version: "1.0", Generator: "ek version " + Version}
|
|
||||||
|
|
||||||
|
func exportJsonFromMicrosub(sub microsub.Microsub) {
|
||||||
|
contents := Export{Version: "1.0", Generator: "ek version " + Version}
|
||||||
channels, err := sub.ChannelsGetList()
|
channels, err := sub.ChannelsGetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
contents.Channels = append(contents.Channels, ExportChannel{UID: c.UID, Name: c.Name})
|
contents.Channels = append(contents.Channels, ExportChannel{UID: c.UID, Name: c.Name})
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.Feeds = make(map[string][]ExportFeed)
|
contents.Feeds = make(map[string][]ExportFeed)
|
||||||
|
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
list, err := sub.FollowGetList(c.UID)
|
list, err := sub.FollowGetList(c.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -425,32 +447,81 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
log.Fatalf("unsupported filetype %q", filetype)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(commands) == 3 && commands[0] == "import" {
|
func importJsonIntoMicrosub(sub microsub.Microsub, filename string) {
|
||||||
filetype := commands[1]
|
var export Export
|
||||||
filename := commands[2]
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
if filetype == "opml" {
|
log.Fatalf("can't open file %s: %s", filename, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
err = json.NewDecoder(f).Decode(&export)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error while reading %s: %s", filename, err)
|
||||||
|
}
|
||||||
channelMap := make(map[string]microsub.Channel)
|
channelMap := make(map[string]microsub.Channel)
|
||||||
|
|
||||||
channels, err := sub.ChannelsGetList()
|
channels, err := sub.ChannelsGetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("an error occurred: %s\n", err)
|
log.Fatalf("an error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
channelMap[c.Name] = c
|
channelMap[c.Name] = c
|
||||||
}
|
}
|
||||||
|
for _, c := range export.Channels {
|
||||||
|
uid := ""
|
||||||
|
|
||||||
|
if ch, e := channelMap[c.Name]; !e {
|
||||||
|
channelCreated, err := sub.ChannelsCreate(c.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("An error occurred: %q\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
uid = channelCreated.UID
|
||||||
|
log.Printf("Channel created: %s\n", c.Name)
|
||||||
|
} else {
|
||||||
|
uid = ch.UID
|
||||||
|
}
|
||||||
|
|
||||||
|
feedMap := make(map[string]bool)
|
||||||
|
|
||||||
|
feeds, err := sub.FollowGetList(uid)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("An error occurred: %q\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range feeds {
|
||||||
|
feedMap[f.URL] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, feed := range export.Feeds[uid] {
|
||||||
|
|
||||||
|
if _, e := feedMap[string(feed)]; !e {
|
||||||
|
_, err := sub.FollowURL(uid, string(feed))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("An error occurred: %q\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Printf("Feed followed: %s\n", string(feed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func importOpmlIntoMicrosub(sub microsub.Microsub, filename string) {
|
||||||
|
channelMap := make(map[string]microsub.Channel)
|
||||||
|
channels, err := sub.ChannelsGetList()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("an error occurred: %s\n", err)
|
||||||
|
}
|
||||||
|
for _, c := range channels {
|
||||||
|
channelMap[c.Name] = c
|
||||||
|
}
|
||||||
xml, err := opml.NewOPMLFromFile(filename)
|
xml, err := opml.NewOPMLFromFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("An error occurred: %s\n", err)
|
log.Fatalf("An error occurred: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range xml.Body.Outlines {
|
for _, c := range xml.Body.Outlines {
|
||||||
if c.HTMLURL != "" {
|
if c.HTMLURL != "" {
|
||||||
log.Printf("First row item has url: %s\n", c.HTMLURL)
|
log.Printf("First row item has url: %s\n", c.HTMLURL)
|
||||||
|
|
@ -502,79 +573,6 @@ func performCommands(sub microsub.Microsub, commands []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if filetype == "json" {
|
|
||||||
var export Export
|
|
||||||
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open file %s: %s", filename, err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
err = json.NewDecoder(f).Decode(&export)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("error while reading %s: %s", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
channelMap := make(map[string]microsub.Channel)
|
|
||||||
|
|
||||||
channels, err := sub.ChannelsGetList()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("an error occurred: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range channels {
|
|
||||||
channelMap[c.Name] = c
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range export.Channels {
|
|
||||||
uid := ""
|
|
||||||
|
|
||||||
if ch, e := channelMap[c.Name]; !e {
|
|
||||||
channelCreated, err := sub.ChannelsCreate(c.Name)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("An error occurred: %q\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
uid = channelCreated.UID
|
|
||||||
log.Printf("Channel created: %s\n", c.Name)
|
|
||||||
} else {
|
|
||||||
uid = ch.UID
|
|
||||||
}
|
|
||||||
|
|
||||||
feedMap := make(map[string]bool)
|
|
||||||
|
|
||||||
feeds, err := sub.FollowGetList(uid)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("An error occurred: %q\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range feeds {
|
|
||||||
feedMap[f.URL] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, feed := range export.Feeds[uid] {
|
|
||||||
|
|
||||||
if _, e := feedMap[string(feed)]; !e {
|
|
||||||
_, err := sub.FollowURL(uid, string(feed))
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("An error occurred: %q\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Printf("Feed followed: %s\n", string(feed))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.Fatalf("unsupported filetype %q", filetype)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(commands) == 1 && commands[0] == "version" {
|
|
||||||
fmt.Printf("ek %s\n", Version)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func showItem(item *microsub.Item) {
|
func showItem(item *microsub.Item) {
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,11 @@ func main() {
|
||||||
|
|
||||||
if createBackend {
|
if createBackend {
|
||||||
backend = createMemoryBackend()
|
backend = createMemoryBackend()
|
||||||
|
|
||||||
|
log.Println(`Config file "backend.json" is created in the current directory.`)
|
||||||
|
log.Println(`Update "Me" variable to your website address "https://example.com/"`)
|
||||||
|
log.Println(`Update "TokenEndpoint" variable to the address of your token endpoint "https://example.com/token"`)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ import (
|
||||||
"willnorris.com/go/microformats"
|
"willnorris.com/go/microformats"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DefaultPrio = 9999999
|
||||||
|
|
||||||
type memoryBackend struct {
|
type memoryBackend struct {
|
||||||
hubIncomingBackend
|
hubIncomingBackend
|
||||||
|
|
||||||
|
|
@ -108,23 +110,24 @@ func (b *memoryBackend) load() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *memoryBackend) refreshChannels() {
|
||||||
conn := pool.Get()
|
conn := pool.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
conn.Do("SETNX", "channel_sortorder_notifications", 1)
|
|
||||||
|
|
||||||
conn.Do("DEL", "channels")
|
conn.Do("DEL", "channels")
|
||||||
|
|
||||||
b.lock.RLock()
|
updateChannelInRedis(conn, "notifications", 1)
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
|
b.lock.RLock()
|
||||||
for uid, channel := range b.Channels {
|
for uid, channel := range b.Channels {
|
||||||
log.Printf("loading channel %s - %s\n", uid, channel.Name)
|
log.Printf("loading channel %s - %s\n", uid, channel.Name)
|
||||||
conn.Do("SADD", "channels", uid)
|
updateChannelInRedis(conn, channel.UID, DefaultPrio)
|
||||||
conn.Do("SETNX", "channel_sortorder_"+uid, 99999)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
b.lock.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *memoryBackend) save() {
|
func (b *memoryBackend) save() {
|
||||||
|
|
@ -145,6 +148,7 @@ func loadMemoryBackend() microsub.Microsub {
|
||||||
log.Printf("Error while loadingbackend: %v\n", err)
|
log.Printf("Error while loadingbackend: %v\n", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
backend.refreshChannels()
|
||||||
|
|
||||||
return backend
|
return backend
|
||||||
}
|
}
|
||||||
|
|
@ -153,25 +157,23 @@ func createMemoryBackend() microsub.Microsub {
|
||||||
backend := memoryBackend{}
|
backend := memoryBackend{}
|
||||||
backend.lock.Lock()
|
backend.lock.Lock()
|
||||||
|
|
||||||
backend.Channels = make(map[string]microsub.Channel)
|
|
||||||
backend.Feeds = make(map[string][]microsub.Feed)
|
backend.Feeds = make(map[string][]microsub.Feed)
|
||||||
channels := []microsub.Channel{
|
channels := []microsub.Channel{
|
||||||
{UID: "notifications", Name: "Notifications"},
|
{UID: "notifications", Name: "Notifications"},
|
||||||
{UID: "home", Name: "Home"},
|
{UID: "home", Name: "Home"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend.Channels = make(map[string]microsub.Channel)
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
backend.Channels[c.UID] = c
|
backend.Channels[c.UID] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
backend.NextUid = 1000000
|
backend.NextUid = 1000000
|
||||||
backend.Me = "https://example.com/"
|
backend.Me = "https://example.com/"
|
||||||
|
|
||||||
backend.lock.Unlock()
|
backend.lock.Unlock()
|
||||||
|
|
||||||
backend.save()
|
backend.save()
|
||||||
|
|
||||||
log.Println(`Config file "backend.json" is created in the current directory.`)
|
|
||||||
log.Println(`Update "Me" variable to your website address "https://example.com/"`)
|
|
||||||
log.Println(`Update "TokenEndpoint" variable to the address of your token endpoint "https://example.com/token"`)
|
|
||||||
return &backend
|
return &backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,23 +210,13 @@ func (b *memoryBackend) ChannelsGetList() ([]microsub.Channel, error) {
|
||||||
func (b *memoryBackend) ChannelsCreate(name string) (microsub.Channel, error) {
|
func (b *memoryBackend) ChannelsCreate(name string) (microsub.Channel, error) {
|
||||||
defer b.save()
|
defer b.save()
|
||||||
|
|
||||||
|
channel := b.createChannel(name)
|
||||||
|
b.setChannel(channel)
|
||||||
|
|
||||||
conn := pool.Get()
|
conn := pool.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
uid := fmt.Sprintf("%04d", b.NextUid)
|
updateChannelInRedis(conn, channel.UID, DefaultPrio)
|
||||||
channel := microsub.Channel{
|
|
||||||
UID: uid,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.Lock()
|
|
||||||
b.Channels[channel.UID] = channel
|
|
||||||
b.Feeds[channel.UID] = []microsub.Feed{}
|
|
||||||
b.NextUid++
|
|
||||||
b.lock.Unlock()
|
|
||||||
|
|
||||||
conn.Do("SADD", "channels", uid)
|
|
||||||
conn.Do("SETNX", "channel_sortorder_"+uid, 99999)
|
|
||||||
|
|
||||||
return channel, nil
|
return channel, nil
|
||||||
}
|
}
|
||||||
|
|
@ -260,8 +252,7 @@ func (b *memoryBackend) ChannelsDelete(uid string) error {
|
||||||
conn := pool.Get()
|
conn := pool.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
conn.Do("SREM", "channels", uid)
|
removeChannelFromRedis(conn, uid)
|
||||||
conn.Do("DEL", "channel_sortorder_"+uid)
|
|
||||||
|
|
||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
delete(b.Channels, uid)
|
delete(b.Channels, uid)
|
||||||
|
|
@ -836,3 +827,30 @@ func (b *memoryBackend) AddEventListener(el microsub.EventListener) error {
|
||||||
b.listeners = append(b.listeners, el)
|
b.listeners = append(b.listeners, el)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *memoryBackend) createChannel(name string) microsub.Channel {
|
||||||
|
uid := fmt.Sprintf("%012d", b.NextUid)
|
||||||
|
channel := microsub.Channel{
|
||||||
|
UID: uid,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return channel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *memoryBackend) setChannel(channel microsub.Channel) {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
b.Channels[channel.UID] = channel
|
||||||
|
b.Feeds[channel.UID] = []microsub.Feed{}
|
||||||
|
b.NextUid++
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateChannelInRedis(conn redis.Conn, uid string, prio int) {
|
||||||
|
conn.Do("SADD", "channels", uid)
|
||||||
|
conn.Do("SETNX", "channel_sortorder_"+uid, prio)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeChannelFromRedis(conn redis.Conn, uid string) {
|
||||||
|
conn.Do("SREM", "channels", uid)
|
||||||
|
conn.Do("DEL", "channel_sortorder_"+uid)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user