Skip to content

Commit

Permalink
notification email, dates, localization
Browse files Browse the repository at this point in the history
  • Loading branch information
LobbyLobster committed Oct 25, 2023
1 parent ac20b9f commit 73c74c0
Show file tree
Hide file tree
Showing 16 changed files with 514 additions and 280 deletions.
2 changes: 1 addition & 1 deletion api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func InitServer() {
log.Error(err)
}

controller.InitLocalizer()
internal.InitLocalizer()

gin.SetMode(gin.ReleaseMode)
router := gin.Default()
Expand Down
3 changes: 2 additions & 1 deletion controller/admin_controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"imap-sync/internal"
"net/http"

"github.com/gin-gonic/gin"
Expand All @@ -20,5 +21,5 @@ func HandleAdmin(ctx *gin.Context) {
return
}

ctx.HTML(200, "admin.html", Data["admin"])
ctx.HTML(200, "admin.html", internal.Data["admin"])
}
6 changes: 5 additions & 1 deletion controller/log_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"imap-sync/internal"
"net/http"
"strconv"
"time"

"github.com/gin-gonic/gin"
)
Expand All @@ -24,5 +25,8 @@ func HandleGetLog(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "log_window.html", gin.H{"log": "failed to get log"})
return
}
ctx.HTML(200, "log_window.html", gin.H{"log": logfile})

startedAt := time.Unix(task.StartedAt, 0)
endedAt := time.Unix(task.EndedAt, 0)
ctx.HTML(200, "log_window.html", gin.H{"log": logfile, "start": startedAt.Local(), "end": endedAt.Local()})
}
6 changes: 2 additions & 4 deletions controller/login_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ func HandleLogin(ctx *gin.Context) {
store := ginsession.FromContext(ctx)
_, ok := store.Get("user")
if ok {
// User is not logged in, redirect them to the login page
ctx.Redirect(http.StatusTemporaryRedirect, "/")
ctx.Redirect(http.StatusMovedPermanently, "/admin")
return
}

ctx.HTML(200, "login.html", Data["login"])
ctx.HTML(200, "login.html", internal.Data["login"])
}

type user struct {
Expand Down
4 changes: 2 additions & 2 deletions controller/root_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func HandleRoot(ctx *gin.Context) {
}{
SourceDetails: sourceDetails,
DestinationDetails: destinationDetails,
Text: Data["index"],
Table: Data["table"],
Text: internal.Data["index"],
Table: internal.Data["table"],
}
ctx.HTML(200, "index.html", data)
}
51 changes: 41 additions & 10 deletions internal/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"flag"
"fmt"
"reflect"
"time"

_ "github.com/mattn/go-sqlite3"
"golang.org/x/crypto/bcrypt"
Expand Down Expand Up @@ -52,6 +53,8 @@ func InitDb() error {
destination_account VARCHAR(64) NULL,
destination_server VARCHAR(64) NULL,
destination_password VARCHAR(64) NULL,
started_at INTEGER NULL,
ended_at INTEGER NULL,
status VARCHAR(64) NULL,
logfile VARCHAR(64) NULL
);
Expand Down Expand Up @@ -141,13 +144,13 @@ func AddTaskToDB(task *Task) error {
}
defer db.Close()

stmt, err := db.Prepare("INSERT INTO tasks(source_account, source_server, source_password, destination_account, destination_server, destination_password, status, logfile) VALUES(?, ?, ?, ?, ?, ?, ?, ?)")
stmt, err := db.Prepare("INSERT INTO tasks(source_account, source_server, source_password, destination_account, destination_server, destination_password, started_at, ended_at, status, logfile) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
if err != nil {
return fmt.Errorf("error preparing statement: %w", err)
}
defer stmt.Close()

_, err = stmt.Exec(task.SourceAccount, task.SourceServer, task.SourcePassword, task.DestinationAccount, task.DestinationServer, task.DestinationPassword, task.Status, task.LogFile)
_, err = stmt.Exec(task.SourceAccount, task.SourceServer, task.SourcePassword, task.DestinationAccount, task.DestinationServer, task.DestinationPassword, task.StartedAt, task.EndedAt, task.Status, task.LogFile)
if err != nil {
return fmt.Errorf("error executing statement: %w", err)
}
Expand All @@ -163,17 +166,45 @@ func updateTaskStatus(task *Task, status string) error {
}
defer db.Close()

stmt, err := db.Prepare("UPDATE tasks SET status = ? WHERE id = ?")
if err != nil {
return fmt.Errorf("error preparing statement: %w", err)
}
defer stmt.Close()
var stmt *sql.Stmt
timeUnix := time.Now().Unix()

_, err = stmt.Exec(status, task.ID)
if err != nil {
return fmt.Errorf("error executing statement: %w", err)
if status == "In Progress" {
stmt, err = db.Prepare("UPDATE tasks SET started_at = ?, status = ? WHERE id = ?")
if err != nil {
return fmt.Errorf("error preparing statement: %w", err)
}
_, err = stmt.Exec(timeUnix, status, task.ID)
if err != nil {
return fmt.Errorf("error executing statement: %w", err)
}
task.StartedAt = timeUnix
} else {
if task.Status == "In Progress" {
stmt, err = db.Prepare("UPDATE tasks SET ended_at = ?, status = ? WHERE id = ?")
if err != nil {
return fmt.Errorf("error preparing statement: %w", err)
}
_, err = stmt.Exec(timeUnix, status, task.ID)
if err != nil {
return fmt.Errorf("error executing statement: %w", err)
}
task.EndedAt = timeUnix
} else {
stmt, err = db.Prepare("UPDATE tasks SET status = ? WHERE id = ?")
if err != nil {
return fmt.Errorf("error preparing statement: %w", err)
}
_, err = stmt.Exec(status, task.ID)
if err != nil {
return fmt.Errorf("error executing statement: %w", err)
}

}
}

defer stmt.Close()

task.Status = status

return nil
Expand Down
18 changes: 17 additions & 1 deletion controller/localization.go → internal/localization.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package controller
package internal

import "flag"

Expand All @@ -17,6 +17,7 @@ func InitLocalizer() {
"destination_details": "Destination Details",
"server": "Server",
"account": "Account",
"account_name": "Username",
"password": "Password",
"validate": "Validate Credentials",
"sync": "Start Synchronization",
Expand All @@ -29,6 +30,7 @@ func InitLocalizer() {
"password": "Password",
},
"admin": {
"queue": "Queue",
"index": "Index",
"source_server": "Source Server",
"source_account": "Source Account",
Expand All @@ -46,6 +48,12 @@ func InitLocalizer() {
"status": "Status",
"actions": "Actions",
},
"notify": {
"success": "Successful",
"success_msg": " successfully synchronized.",
"fail": "Failed",
"fail_msg": " failed synchronizztion.",
},
}
case "tr":
Data = map[string]map[string]string{
Expand All @@ -54,6 +62,7 @@ func InitLocalizer() {
"destination_details": "Hedef Bilgileri",
"server": "Sunucu",
"account": "Hesap",
"account_name": "Kullanıcı Adı",
"password": "Parola",
"validate": "Bilgileri Doğrula",
"sync": "Senkronizasyonu Başlat",
Expand All @@ -66,6 +75,7 @@ func InitLocalizer() {
"password": "Parola",
},
"admin": {
"queue": "İşlem Kuyruğu",
"index": "Sıra",
"source_server": "Kaynak Sunucu",
"source_account": "Kaynak Hesap",
Expand All @@ -83,6 +93,12 @@ func InitLocalizer() {
"status": "Durum",
"actions": "Eylemler",
},
"notify": {
"success": "Başarılı",
"success_msg": " mail adresleri arasındaki senkronizasyon başarıyla tamamlandı.",
"fail": "Başarısız",
"fail_msg": " mail adresleri arasındaki senkronizasyon başarısız oldu.",
},
}
}
}
51 changes: 37 additions & 14 deletions internal/notify.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
package internal

import (
"flag"
"net/smtp"
"strings"
)

func Email(creds Credentials) error {
var (
smtpHost = flag.String("smtpHost", "", "SMTP server")
smtpPort = flag.String("smtpPort", "", "SMTP port")
from = flag.String("from", "", "SMTP mail sender")
smtpUsername = flag.String("smtpUser", "", "SMTP username")
smtpPassword = flag.String("smtpPass", "", "SMTP password")
)

func Notify(task *Task, isSuccessful bool) {
if !isSuccessful {
err := sendMmail([]string{task.SourceAccount, task.DestinationAccount}, Data["notify"]["fail"], Data["notify"]["fail_msg"])
if err != nil {
log.Info(err)
}
} else {
err := sendMmail([]string{task.SourceAccount, task.DestinationAccount}, Data["notify"]["success"], Data["notify"]["success_msg"])
if err != nil {
log.Info(err)
}
}
}

smtpHost := ""
smtpPort := ""
from := ""
username := ""
password := ""
to := creds.Account
subject := ""
message := ""
func sendMmail(accounts []string, status string, text string) error {
toHeader := strings.Join(accounts, ",")
subject := "Monomail-sync " + status
message := accounts[0] + " - " + accounts[1] + text

auth := smtp.CRAMMD5Auth(username, password)
auth := smtp.CRAMMD5Auth(*smtpUsername, *smtpPassword)

msg := []byte("From: " + from + "\r\n" +
"To: " + to + "\r\n" +
"Subject: [" + "" + "] " + subject + "\r\n\r\n" +
msg := []byte("From: " + *from + "\r\n" +
"To: " + toHeader + "\r\n" +
"Subject: " + subject + "\r\n\r\n" +
message + "\r\n")

return smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, msg)
err := smtp.SendMail(*smtpHost+":"+*smtpPort, auth, *from, accounts, msg)
if err != nil {
log.Debug(err)
return err
}
return nil
}
13 changes: 8 additions & 5 deletions internal/pagination.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ type Pagination struct {

func GetPagination(index int) []Pagination {
pages := []Pagination{}
startPage := index - 2
endPage := index + 2
startPage := index - 5
endPage := index + 5

if startPage < 1 {
startPage = 1
}

if endPage > queue.Len()/PageSize {
endPage = queue.Len() / PageSize
if queue.Len()%PageSize != 0 {
endPage++
}
}

if (index <= 2 || index >= endPage-2 || index == endPage || index == endPage-1) && endPage-startPage+1 < 5 && endPage < queue.Len()/PageSize {
endPage = startPage + 4
}
// if (index <= 2 || index >= endPage-2 || index == endPage || index == endPage-1) && endPage-startPage+1 < 5 && endPage < queue.Len()/PageSize {
// endPage = startPage + 4
// }

for i := startPage; i <= endPage; i++ {
pages = append(pages, Pagination{
Expand Down
2 changes: 2 additions & 0 deletions internal/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type Task struct {
DestinationServer string
DestinationPassword string
Status string
StartedAt int64
EndedAt int64
LogFile string
}

Expand Down
4 changes: 4 additions & 0 deletions internal/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,17 @@ func syncIMAP(ctx context.Context, details *Task) error {
return fmt.Errorf("failed to terminate imapsync process: %w", err)
}
updateTaskStatus(details, "Cancelled")
Notify(details, false)
return ctx.Err()
case err := <-done:
if err != nil {
updateTaskStatus(details, "Error")

Notify(details, false)
return fmt.Errorf("error running imapsync: %w", err)
}
updateTaskStatus(details, "Done")
Notify(details, true)
return nil
}
}
4 changes: 2 additions & 2 deletions internal/sync_loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func processPendingTasks() {
ctx, cancel = context.WithCancel(context.Background())
syncIMAP(ctx, task)

// simulateTask(task)
time.Sleep(1000 * time.Millisecond)
// simulateTask(task)
// time.Sleep(1000 * time.Millisecond)
}
}

Expand Down
2 changes: 1 addition & 1 deletion templates/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<!-- Table for showing the queue -->
<div class="container p-4 mx-auto flex gap-4">
<div class=" flex w-full overflow-x-auto flex-col">
<h2 class="text-4xl m-2">Queue</h2>
<h2 class="text-4xl m-2">{{index . "queue"}}</h2>

<!-- Page controls -->
<div id="pagination" class="pagination m-2" hx-get="/api/pagination?page=1" hx-trigger="load"></div>
Expand Down
Loading

0 comments on commit 73c74c0

Please sign in to comment.