Compare commits
No commits in common. "4c904e7196fdbd62f7f03b6fcd20865b2c197b1b" and "4c01dc4ea221ac138a6937c924e038826e83757f" have entirely different histories.
4c904e7196
...
4c01dc4ea2
20
main.go
20
main.go
@ -3,19 +3,15 @@ package main
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"deadbeef.codes/steven/ynab-portfolio-monitor/ynab"
|
"deadbeef.codes/steven/ynab-portfolio-monitor/ynab"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configuredProviders []AccountProvider // Any account providers that are successfully configured get added to this slice
|
configuredProviders []AccountProvider // Any account providers that are successfully configured get added to this slice
|
||||||
ynabClient *ynab.Client // YNAB HTTP client
|
ynabClient *ynab.Client // YNAB HTTP client
|
||||||
lastRefresh time.Time // Timestamp that last data refresh ran - used for rate limiting
|
lastRefresh time.Time
|
||||||
refreshRunning *sync.Mutex // True if a refresh is currently running
|
|
||||||
t *template.Template // HTML templates in the templates directory
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Called at program startup or if SIGHUP is received
|
// Called at program startup or if SIGHUP is received
|
||||||
@ -53,13 +49,6 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to create ynab client: %v", err)
|
log.Fatalf("failed to create ynab client: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web Templates
|
|
||||||
// Parse all template files at startup
|
|
||||||
t, err = template.ParseGlob("./templates/*")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("couldn't parse HTML templates: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -73,13 +62,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func refreshData() {
|
func refreshData() {
|
||||||
refreshRunning.Lock()
|
|
||||||
defer refreshRunning.Unlock()
|
|
||||||
|
|
||||||
// Only allow a refresh at most once every 5 minutes
|
// Only allow a refresh at most once every 5 minutes
|
||||||
if time.Now().Before(lastRefresh.Add(time.Minute * 5)) {
|
if time.Now().Before(lastRefresh.Add(time.Minute * 5)) {
|
||||||
log.Printf("refresh rate limited")
|
log.Printf("refresh rate limited")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lastRefresh = time.Now()
|
lastRefresh = time.Now()
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
# Provider Packages
|
|
||||||
|
|
||||||
Provider packages are used for any integration and are found in their own sub directories. Providers must adhere to the interface speficied in accountProviders.go.
|
|
||||||
|
|
||||||
```golang
|
|
||||||
// AccountProvider is the base set of requirements to be implemented for any integration
|
|
||||||
type AccountProvider interface {
|
|
||||||
Name() string // Returns the name of the provider
|
|
||||||
Configure() error // Configures the provider for first use - if an error is returned the provider is not used
|
|
||||||
GetBalances() ([]int, []string, error) // A slice of balances, and an index mapped slice of ynab account IDs this provider handles is returned
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
By convention, these methods are implemented in a file called providerImpl.go in each of the provider packages.
|
|
||||||
|
|
||||||
The following providers are currently available:
|
|
||||||
|
|
||||||
* bitcoin
|
|
||||||
* questrade
|
|
||||||
* staticjsonFinnhub
|
|
||||||
* staticjsonYahooFinance
|
|
@ -1,3 +0,0 @@
|
|||||||
# Public
|
|
||||||
|
|
||||||
This directory is publicly accessible from the HTTP server and contains web assets such as images, css and javascript.
|
|
@ -1,3 +0,0 @@
|
|||||||
# Templates
|
|
||||||
|
|
||||||
This directory contains HTML templates used by the Go templating engine.
|
|
@ -1,22 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>YNAB Portfolio Monitor</title>
|
|
||||||
<script>
|
|
||||||
req = new XMLHttpRequest();
|
|
||||||
req.open("GET", "/status");
|
|
||||||
req.send();
|
|
||||||
req.onload = () => {
|
|
||||||
if (req.readyState == 4 && req.status == 200) {
|
|
||||||
// redirect to budget when refresh complete signal is received
|
|
||||||
window.location.href = "https://app.ynab.com/{{ .BudgetID }}"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// do some fancy preloader stuff
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Loading...</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
23
webServer.go
23
webServer.go
@ -1,11 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func webServer() {
|
func webServer() {
|
||||||
|
// Start web server
|
||||||
|
|
||||||
//Public static files
|
//Public static files
|
||||||
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("public"))))
|
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("public"))))
|
||||||
@ -13,30 +15,13 @@ func webServer() {
|
|||||||
// Page Handlers
|
// Page Handlers
|
||||||
// Anything that is responsible for the base elements of a viewable web page
|
// Anything that is responsible for the base elements of a viewable web page
|
||||||
http.HandleFunc("/", homePageHandler)
|
http.HandleFunc("/", homePageHandler)
|
||||||
http.HandleFunc("/status", statusHandler)
|
|
||||||
|
|
||||||
// Start web server
|
|
||||||
log.Print("Service listening on :8080")
|
log.Print("Service listening on :8080")
|
||||||
log.Printf("Web server unexpectedly exiting!: %v", http.ListenAndServe(":8080", nil))
|
log.Printf("Web server unexpectedly exiting!: %v", http.ListenAndServe(":8080", nil))
|
||||||
}
|
|
||||||
|
|
||||||
type homePageData struct {
|
|
||||||
BudgetID string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func homePageHandler(w http.ResponseWriter, r *http.Request) {
|
func homePageHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
go refreshData()
|
refreshData()
|
||||||
pageData := &homePageData{BudgetID: ynabClient.BudgetID}
|
http.Redirect(w, r, fmt.Sprintf("https://app.ynab.com/%s", ynabClient.BudgetID), http.StatusSeeOther)
|
||||||
err := t.ExecuteTemplate(w, "home.html", pageData)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("error executing home.html template: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//http.Redirect(w, r, fmt.Sprintf("https://app.ynab.com/%s", ynabClient.BudgetID), http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
|
|
||||||
func statusHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
refreshRunning.Lock()
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
refreshRunning.Unlock()
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user