You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.2 KiB

package main
import (
"fmt"
"strings"
"git.kiefte.eu/lapingvino/infodump/message"
shell "github.com/ipfs/go-ipfs-api"
)
// A menu for the several parts of Sync:
// saving messages to the local database
// reading messages from the local database
// reading messages from the network
// writing messages to the network
func SyncMenu() {
// Present the user with a menu
Menu([]MenuElements{
{"Save Messages to Database", SaveMessagesToDatabase},
{"Read Messages from Database", ReadMessagesFromDatabase},
{"Read Messages from Network", ReadMessagesFromNetwork},
{"Write Messages to Network", WriteMessagesToNetwork},
{"Back", func() {}},
})
}
// Implementing the Sync Menu options
// SaveMessagesToDatabase, ReadMessagesFromDatabase, ReadMessagesFromNetwork and WriteMessagesToNetwork
// SaveMessagesToDatabase saves the messages in LocalMessages to the database
func SaveMessagesToDatabase() {
// Update the database with the messages in LocalMessages
db := GetDatabase()
// Put the messages in the database
LocalMessages.Each(func(m *message.Message) {
_, err := db.Exec("INSERT INTO messages(hash, message, nonce, timestamp) VALUES(?,?,?,?)", m.Stamp(), m.Message, m.Nonce, m.Timestamp)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Message", m.Stamp(), "saved to database")
}
})
}
// ReadMessagesFromDatabase reads the messages from the database and adds them to LocalMessages
func ReadMessagesFromDatabase() {
// Get the messages from the database
messages := GetMessagesFromDatabase(GetDatabase())
// Add the messages to LocalMessages
LocalMessages.AddMany(messages)
}
// ReadMessagesFromNetwork reads the messages from the IPFS network and adds them to LocalMessages
func ReadMessagesFromNetwork() {
// Ask for a CID from the user and get the messages from the IPFS network
// Add the messages to LocalMessages
fmt.Println("Enter the CID of the messages to read: ")
cid := Readline()
messages, err := message.MessagesFromIPFS(cid)
if err != nil {
fmt.Println(err)
} else {
LocalMessages.AddMany(messages)
}
}
// WriteMessagesToNetwork writes the messages in LocalMessages to the IPFS network
func WriteMessagesToNetwork() {
// Create an IPFS shell to later publish the messages to via PubSub
myIPFS := shell.NewShell(message.IPFSGateway)
// Add the messages to the IPFS network
cid, err := LocalMessages.AddToIPFS()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Messages synced to IPFS: ", cid)
}
// Publish the CID of LocalMessages to the OLN tag
err = myIPFS.PubSubPublish("OLN", cid)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Published CID", cid, "to the main network")
}
// Define what is considered a tag by regex
tagDefinition := []string{
// Hashtags
"#[a-zA-Z0-9]+",
// Mentions
"@[a-zA-Z0-9]+",
// Links
"https?://[a-zA-Z0-9./]+",
}
// Split each message on spaces and map the resulting strings
// to the message stamp
messages := make(map[string][]*message.Message)
LocalMessages.Each(func(m *message.Message) {
tags := strings.Split(m.Message, " ")
itertags:
for _, tag := range tags {
// Check if the tag matches any of the tag definitions
// if not, continue to the next tag
for _, regex := range tagDefinition {
if !strings.Contains(tag, regex) {
continue itertags
}
}
// If the tag matches any of the tag definitions,
// add the message to the messages map
messages[tag] = append(messages[tag], m)
}
})
// Create a new set of messages per tag and send them over PubSub
// Per message, invoke Add on the tags map entry
tags := make(map[string]*message.Messages)
for tag, messages := range messages {
if tags[tag] == nil {
tags[tag] = &message.Messages{}
}
for _, m := range messages {
tags[tag].Add(m)
}
// Publish the messages to the IPFS network and get a CID
cid, err := tags[tag].AddToIPFS()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Messages synced to IPFS: ", cid)
}
// Publish the messages via PubSub on the IPFS shell
err = myIPFS.PubSubPublish("oln-"+tag, cid)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Messages published to the rest of the network for tag: ", tag)
}
}
}