diff options
author | Joop Kiefte <ikojba@gmail.com> | 2021-12-13 22:29:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-13 22:29:14 +0000 |
commit | 4d42a08a166ddd71037c546c78b035b96890f2fa (patch) | |
tree | 14cb8016f8628aa2b927206b10c36d0f66448f28 | |
parent | afdcbec2147b9bfc54334955dab825cba625423b (diff) |
Spread command over seperate files
-rw-r--r-- | db.go | 168 | ||||
-rw-r--r-- | ipfs.go | 32 | ||||
-rw-r--r-- | localmessages.go | 91 | ||||
-rw-r--r-- | main.go | 373 | ||||
-rw-r--r-- | sync.go | 66 | ||||
-rw-r--r-- | tags.go | 56 |
6 files changed, 413 insertions, 373 deletions
@@ -0,0 +1,168 @@ +package main + +import ( + "database/sql" + "fmt" + "os" + + _ "modernc.org/sqlite" + + shell "github.com/ipfs/go-ipfs-api" + + "git.kiefte.eu/lapingvino/infodump/message" +) + +var DatabasePath = "infodump.db" +var DB *sql.DB + +// StartOLNListener starts a PubSub listener that listens for messages from the network +// and adds them to LocalMessages +// For this it uses the IPFS gateway and listens on the topic "OLN", as well as +// the list of followed tags from the database +func StartOLNListener() { + // Get the IPFS gateway + gateway := message.IPFSGateway + // Get the database + db := GetDatabase() + // Get the list of followed tags + followedTags := GetFollowedTags(db) + // Create a new IPFS client + myIPFS := shell.NewShell(gateway) + var subs []*shell.PubSubSubscription + olnsub, err := myIPFS.PubSubSubscribe("OLN") + if err != nil { + fmt.Println(err) + return + } + subs = append(subs, olnsub) + for _, tag := range followedTags { + tagssub, err := myIPFS.PubSubSubscribe("oln-" + tag) + if err != nil { + fmt.Println(err) + } else { + subs = append(subs, tagssub) + } + } + // Start a goroutine for each of the subscriptions in subs, + // read the CID from the Next method, look up the CID on IPFS, + // read this in via message.MessagesFromIPFS and add the message to LocalMessages + for _, sub := range subs { + go func(sub *shell.PubSubSubscription) { + for { + msg, err := sub.Next() + if err != nil { + fmt.Println(err) + return + } + msgs, err := message.MessagesFromIPFS(string(msg.Data)) + if err != nil { + fmt.Println(err) + return + } + LocalMessages.AddMany(msgs) + } + }(sub) + } +} + +// GetDatabase checks if DB is already set and opened, if not it Sets the database first +func GetDatabase() *sql.DB { + if DB == nil { + fmt.Println("Database not set, setting database...") + SetDatabase() + } + return DB +} + +func GetMessagesFromDatabase(db *sql.DB) *message.Messages { + // Get all messages from the database + rows, err := db.Query("SELECT hash, message, nonce, timestamp FROM messages") + if err != nil { + fmt.Println(err) + } + defer rows.Close() + // Create a new Messages object + msgs := message.Messages{} + // Loop through all messages + fmt.Println("Getting messages from database...") + for rows.Next() { + var hash, msg string + var nonce int + var timestamp int64 + // Get the values from the database + err := rows.Scan(&hash, &msg, &nonce, ×tamp) + if err != nil { + fmt.Println(err) + } + fmt.Println("Got message from database:", hash) + + // Create a new message object + m := message.Message{ + Message: msg, + Nonce: nonce, + Timestamp: timestamp, + } + // Add the message to the Messages object + fmt.Println("Adding message to Messages object...") + msgs.Add(&m) + } + return &msgs +} + +func InitDatabase(db *sql.DB) { + var err error + // Create the table "messages" + _, err = db.Exec("CREATE TABLE messages(hash TEXT PRIMARY KEY, message TEXT, nonce INTEGER, timestamp INTEGER)") + if err != nil { + fmt.Println(err) + } + // Create the table "followed_tags" + _, err = db.Exec("CREATE TABLE followed_tags(tag TEXT)") + if err != nil { + fmt.Println(err) + } +} + +// SetDatabase configures DB to be the database to use +// The name used is DatabasePath, but the user will be asked if this correct or if they want to change it +// If the database is already set, it will ask the user if they want to overwrite it +// If the database is not set, it will ask the user if they want to create it +// If the database is set but it doesn't contain the tables "messages" and "followed_tags", +// it will create them +func SetDatabase() { + // First check if the user is okay with the database path + fmt.Println("Database path: ", DatabasePath) + fmt.Println("Is this correct? (y/n)") + answer := Readline() + if answer == "n" { + fmt.Println("Enter the database path: ") + DatabasePath = Readline() + } + // Open the database + db, err := sql.Open("sqlite", DatabasePath) + if err != nil { + fmt.Println(err) + return + } + // Check if the database is already set + if DB != nil { + fmt.Println("Database already set, overwrite? (y/n)") + answer := Readline() + if answer == "n" { + return + } + } + // Check if the database exists + if _, err := os.Stat(DatabasePath); os.IsNotExist(err) { + fmt.Println("Database does not exist, create? (y/n)") + answer := Readline() + if answer == "n" { + return + } + } + // Set the database + DB = db + // Check if the database contains the tables "messages" and "followed_tags" + // If not, create them + InitDatabase(DB) +} @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + + "git.kiefte.eu/lapingvino/infodump/message" + shell "github.com/ipfs/go-ipfs-api" +) + +func TestIPFSGateway(gateway string) error { + // Test the IPFS gateway + fmt.Println("Testing IPFS gateway...") + ipfs := shell.NewShell(gateway) + _, err := ipfs.ID() + return err +} + +func SetIPFSGateway() { + // Set the IPFS gateway + fmt.Println("Enter the IPFS gateway: ") + var gateway string + fmt.Scanln(&gateway) + // Test the IPFS gateway + err := TestIPFSGateway(gateway) + if err != nil { + fmt.Println(err) + return + } else { + fmt.Println("IPFS gateway set to: ", gateway) + message.IPFSGateway = gateway + } +} diff --git a/localmessages.go b/localmessages.go new file mode 100644 index 0000000..4b18b24 --- /dev/null +++ b/localmessages.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + "time" + + "git.kiefte.eu/lapingvino/infodump/message" +) + +var LocalMessages = message.Messages{} +var MessageCache string + +// ReadMessages shows the messages in LocalMessages sorted by importance, 10 at a time +func ReadMessages() { + // Use LocalMessages to get the messages and get the sorted list of messages + // through the MessageList method + msgs := LocalMessages.MessageList() + // Loop through the messages and print them + for i, m := range msgs { + fmt.Println(m) + if i%10 == 9 { + fmt.Println("Press enter to continue... Type anything to stop") + contp := Readline() + if contp != "" { + return + } + } + } +} + +func WriteMessage() { + // Get a message and an urgency from the user. + // The urgency is used to set the strength of the Proof of Work + // If there is a message in the MessageCache, ask the user if they want to use it + // If there is no message in the MessageCache, ask the user to write a message + var m string + if MessageCache != "" { + fmt.Println("You wrote a message before that you didn't send yet. Do you want to use that message?") + fmt.Println("The message is:", MessageCache) + fmt.Println("Type 'yes' to use the message, or anything else to write a new message") + usep := Readline() + if usep == "yes" { + fmt.Println("Using message from cache") + m = MessageCache + } else { + fmt.Println("Writing new message") + m = usep + } + } else { + fmt.Println("Write a message:") + m = Readline() + } + fmt.Println("Enter an urgency (higher is stronger but takes longer to produce): ") + var urgency int + fmt.Scanln(&urgency) + fmt.Println("How many seconds should we wait for the POW to be done? (default is 5): ") + var powtime int + fmt.Scanln(&powtime) + if powtime == 0 { + powtime = 5 + } + // Create a new message object + msg, err := message.New(m, urgency, time.Now().Unix(), time.Duration(powtime)*time.Second) + if err != nil { + fmt.Println(err) + fmt.Println("Want to try again with another urgency or timeout? (y/n)") + contp := Readline() + if contp == "y" { + MessageCache = m + WriteMessage() + } + return + } + // MessageCache can be discarded after this point + MessageCache = "" + // Add the message to LocalMessages + LocalMessages.Add(msg) + + // Ask if the user wants to write another message or save the messages to the database + fmt.Println("Do you want to write another message? (y/n)") + contp := Readline() + if contp == "y" { + WriteMessage() + } else { + fmt.Println("Do you want to save the messages to the database? (y/n)") + contp := Readline() + if contp == "y" { + SaveMessagesToDatabase() + } + } +} @@ -3,23 +3,14 @@ package main import ( "bufio" - "database/sql" "fmt" "net/url" "os" - "strings" - "time" "git.kiefte.eu/lapingvino/infodump/message" - shell "github.com/ipfs/go-ipfs-api" _ "modernc.org/sqlite" ) -var LocalMessages = message.Messages{} -var DatabasePath = "infodump.db" -var DB *sql.DB -var MessageCache string - // Readline reads from a buffered stdin and returns the line func Readline() string { reader := bufio.NewReader(os.Stdin) @@ -112,367 +103,3 @@ func SettingsMenu() { {"Back", func() {}}, }) } - -// 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() {}}, - }) -} - -// StartOLNListener starts a PubSub listener that listens for messages from the network -// and adds them to LocalMessages -// For this it uses the IPFS gateway and listens on the topic "OLN", as well as -// the list of followed tags from the database -func StartOLNListener() { - // Get the IPFS gateway - gateway := message.IPFSGateway - // Get the database - db := GetDatabase() - // Get the list of followed tags - followedTags := GetFollowedTags(db) - // Create a new IPFS client - myIPFS := shell.NewShell(gateway) - var subs []*shell.PubSubSubscription - olnsub, err := myIPFS.PubSubSubscribe("OLN") - if err != nil { - fmt.Println(err) - return - } - subs = append(subs, olnsub) - for _, tag := range followedTags { - tagssub, err := myIPFS.PubSubSubscribe("oln-" + tag) - if err != nil { - fmt.Println(err) - } else { - subs = append(subs, tagssub) - } - } - // Start a goroutine for each of the subscriptions in subs, - // read the CID from the Next method, look up the CID on IPFS, - // read this in via message.MessagesFromIPFS and add the message to LocalMessages - for _, sub := range subs { - go func(sub *shell.PubSubSubscription) { - for { - msg, err := sub.Next() - if err != nil { - fmt.Println(err) - return - } - msgs, err := message.MessagesFromIPFS(string(msg.Data)) - if err != nil { - fmt.Println(err) - return - } - LocalMessages.AddMany(msgs) - } - }(sub) - } -} - -// GetDatabase checks if DB is already set and opened, if not it Sets the database first -func GetDatabase() *sql.DB { - if DB == nil { - fmt.Println("Database not set, setting database...") - SetDatabase() - } - return DB -} - -func GetMessagesFromDatabase(db *sql.DB) *message.Messages { - // Get all messages from the database - rows, err := db.Query("SELECT hash, message, nonce, timestamp FROM messages") - if err != nil { - fmt.Println(err) - } - defer rows.Close() - // Create a new Messages object - msgs := message.Messages{} - // Loop through all messages - fmt.Println("Getting messages from database...") - for rows.Next() { - var hash, msg string - var nonce int - var timestamp int64 - // Get the values from the database - err := rows.Scan(&hash, &msg, &nonce, ×tamp) - if err != nil { - fmt.Println(err) - } - fmt.Println("Got message from database:", hash) - - // Create a new message object - m := message.Message{ - Message: msg, - Nonce: nonce, - Timestamp: timestamp, - } - // Add the message to the Messages object - fmt.Println("Adding message to Messages object...") - msgs.Add(&m) - } - return &msgs -} - -// ReadMessages shows the messages in LocalMessages sorted by importance, 10 at a time -func ReadMessages() { - // Use LocalMessages to get the messages and get the sorted list of messages - // through the MessageList method - msgs := LocalMessages.MessageList() - // Loop through the messages and print them - for i, m := range msgs { - fmt.Println(m) - if i%10 == 9 { - fmt.Println("Press enter to continue... Type anything to stop") - contp := Readline() - if contp != "" { - return - } - } - } -} - -func WriteMessage() { - // Get a message and an urgency from the user. - // The urgency is used to set the strength of the Proof of Work - // If there is a message in the MessageCache, ask the user if they want to use it - // If there is no message in the MessageCache, ask the user to write a message - var m string - if MessageCache != "" { - fmt.Println("You wrote a message before that you didn't send yet. Do you want to use that message?") - fmt.Println("The message is:", MessageCache) - fmt.Println("Type 'yes' to use the message, or anything else to write a new message") - usep := Readline() - if usep == "yes" { - fmt.Println("Using message from cache") - m = MessageCache - } else { - fmt.Println("Writing new message") - m = usep - } - } else { - fmt.Println("Write a message:") - m = Readline() - } - fmt.Println("Enter an urgency (higher is stronger but takes longer to produce): ") - var urgency int - fmt.Scanln(&urgency) - fmt.Println("How many seconds should we wait for the POW to be done? (default is 5): ") - var powtime int - fmt.Scanln(&powtime) - if powtime == 0 { - powtime = 5 - } - // Create a new message object - msg, err := message.New(m, urgency, time.Now().Unix(), time.Duration(powtime)*time.Second) - if err != nil { - fmt.Println(err) - fmt.Println("Want to try again with another urgency or timeout? (y/n)") - contp := Readline() - if contp == "y" { - MessageCache = m - WriteMessage() - } - return - } - // MessageCache can be discarded after this point - MessageCache = "" - // Add the message to LocalMessages - LocalMessages.Add(msg) - - // Ask if the user wants to write another message or save the messages to the database - fmt.Println("Do you want to write another message? (y/n)") - contp := Readline() - if contp == "y" { - WriteMessage() - } else { - fmt.Println("Do you want to save the messages to the database? (y/n)") - contp := Readline() - if contp == "y" { - SaveMessagesToDatabase() - } - } -} - -// 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() { - // Get the messages from the IPFS network - // TODO: Implement this -} - -// WriteMessagesToNetwork writes the messages in LocalMessages to the IPFS network -func WriteMessagesToNetwork() { - // 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) - } -} - -func TestIPFSGateway(gateway string) error { - // Test the IPFS gateway - fmt.Println("Testing IPFS gateway...") - ipfs := shell.NewShell(gateway) - _, err := ipfs.ID() - return err -} - -func SetIPFSGateway() { - // Set the IPFS gateway - fmt.Println("Enter the IPFS gateway: ") - var gateway string - fmt.Scanln(&gateway) - // Test the IPFS gateway - err := TestIPFSGateway(gateway) - if err != nil { - fmt.Println(err) - return - } else { - fmt.Println("IPFS gateway set to: ", gateway) - message.IPFSGateway = gateway - } -} - -func InitDatabase(db *sql.DB) { - var err error - // Create the table "messages" - _, err = db.Exec("CREATE TABLE messages(hash TEXT PRIMARY KEY, message TEXT, nonce INTEGER, timestamp INTEGER)") - if err != nil { - fmt.Println(err) - } - // Create the table "followed_tags" - _, err = db.Exec("CREATE TABLE followed_tags(tag TEXT)") - if err != nil { - fmt.Println(err) - } -} - -// SetDatabase configures DB to be the database to use -// The name used is DatabasePath, but the user will be asked if this correct or if they want to change it -// If the database is already set, it will ask the user if they want to overwrite it -// If the database is not set, it will ask the user if they want to create it -// If the database is set but it doesn't contain the tables "messages" and "followed_tags", -// it will create them -func SetDatabase() { - // First check if the user is okay with the database path - fmt.Println("Database path: ", DatabasePath) - fmt.Println("Is this correct? (y/n)") - answer := Readline() - if answer == "n" { - fmt.Println("Enter the database path: ") - DatabasePath = Readline() - } - // Open the database - db, err := sql.Open("sqlite", DatabasePath) - if err != nil { - fmt.Println(err) - return - } - // Check if the database is already set - if DB != nil { - fmt.Println("Database already set, overwrite? (y/n)") - answer := Readline() - if answer == "n" { - return - } - } - // Check if the database exists - if _, err := os.Stat(DatabasePath); os.IsNotExist(err) { - fmt.Println("Database does not exist, create? (y/n)") - answer := Readline() - if answer == "n" { - return - } - } - // Set the database - DB = db - // Check if the database contains the tables "messages" and "followed_tags" - // If not, create them - InitDatabase(DB) -} - -func ConfigureFollowedTags() { - db := GetDatabase() - fmt.Println("At the moment you follow the following tags:") - // Get the tags that the user is following - tags := GetFollowedTags(db) - // Show the tags - for _, tag := range tags { - fmt.Print(tag, " ") - } - fmt.Println() - fmt.Println("Enter the tags you want to follow, separated by spaces\nTo remove tags, prefix them with a minus sign: ") - newtags := Readline() - // Split the tags into an array and insert them into database DB - // using table "followed_tags" - tagArray := strings.Split(newtags, " ") - for _, tag := range tagArray { - tag = strings.Trim(tag, " \n") - if !strings.HasPrefix(tag, "-") { - _, err := db.Exec("INSERT INTO followed_tags(tag) VALUES(?)", tag) - if err != nil { - fmt.Println(err) - } - } else { - _, err := db.Exec("DELETE FROM followed_tags WHERE tag=?", tag[1:]) - if err != nil { - fmt.Println(err) - } - } - } -} - -func GetFollowedTags(db *sql.DB) []string { - // Get the tags from the database - rows, err := db.Query("SELECT tag FROM followed_tags") - if err != nil { - fmt.Println(err) - } - var tags []string - for rows.Next() { - var tag string - err = rows.Scan(&tag) - if err != nil { - fmt.Println(err) - } - tags = append(tags, tag) - } - return tags -} @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + + "git.kiefte.eu/lapingvino/infodump/message" +) + +// 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() { + // Get the messages from the IPFS network + // TODO: Implement this +} + +// WriteMessagesToNetwork writes the messages in LocalMessages to the IPFS network +func WriteMessagesToNetwork() { + // 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) + } +} @@ -0,0 +1,56 @@ +package main + +import ( + "database/sql" + "fmt" + "strings" +) + +func ConfigureFollowedTags() { + db := GetDatabase() + fmt.Println("At the moment you follow the following tags:") + // Get the tags that the user is following + tags := GetFollowedTags(db) + // Show the tags + for _, tag := range tags { + fmt.Print(tag, " ") + } + fmt.Println() + fmt.Println("Enter the tags you want to follow, separated by spaces\nTo remove tags, prefix them with a minus sign: ") + newtags := Readline() + // Split the tags into an array and insert them into database DB + // using table "followed_tags" + tagArray := strings.Split(newtags, " ") + for _, tag := range tagArray { + tag = strings.Trim(tag, " \n") + if !strings.HasPrefix(tag, "-") { + _, err := db.Exec("INSERT INTO followed_tags(tag) VALUES(?)", tag) + if err != nil { + fmt.Println(err) + } + } else { + _, err := db.Exec("DELETE FROM followed_tags WHERE tag=?", tag[1:]) + if err != nil { + fmt.Println(err) + } + } + } +} + +func GetFollowedTags(db *sql.DB) []string { + // Get the tags from the database + rows, err := db.Query("SELECT tag FROM followed_tags") + if err != nil { + fmt.Println(err) + } + var tags []string + for rows.Next() { + var tag string + err = rows.Scan(&tag) + if err != nil { + fmt.Println(err) + } + tags = append(tags, tag) + } + return tags +} |