Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
confused-Techie committed Nov 29, 2021
0 parents commit 9ff4530
Show file tree
Hide file tree
Showing 25 changed files with 1,617 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Ignore the output of installers
installer/Output
# Ignore my json file since it'll contain personal data
list.json
# Ignore dev-docs
DEV-docs
224 changes: 224 additions & 0 deletions GoPage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package main

import (
model "github.com/GoPage/model"
config "github.com/GoPage/config"
"fmt"
"log"
"net/http"
"html/template"
"strconv"
"os"
"io/ioutil"
"encoding/json"
"github.com/spf13/viper"
)

func checkError(err error) {
if err != nil {
fmt.Println(err)
}
}

func checkFormValue(w http.ResponseWriter, r *http.Request, forms ...string) (res bool, errStr string) {
for _, form := range forms {
if r.FormValue(form) == "" {
return false, "All Forms must be completed!"
}
}
return true, ""
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
au := model.Home()
t, err := template.ParseFiles(viper.GetString("directories.templates") + "/homePage.html")
checkError(err)
t.Execute(w, au)
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
updateItem := &model.Item{}

resBool, errStr := checkFormValue(w, r, "friendlyName", "link", "category")
if resBool == false {
t, err := template.ParseFiles(viper.GetString("directories.templates") + "/error.html")
checkError(err)
t.Execute(w, errStr)
return
}

updateItem.FriendlyName = r.FormValue("friendlyName")
updateItem.Link = r.FormValue("link")
updateItem.Category = r.FormValue("category")

a, errr := strconv.Atoi(r.FormValue("id"))
checkError(errr)
updateItem.Id = a
var err error

// open file
file, err := os.OpenFile(viper.GetString("directories.data"), os.O_RDWR, 0644)
checkError(err)
defer file.Close()

b, err := ioutil.ReadAll(file)
var allItms model.AllItems
err = json.Unmarshal(b, &allItms.Items)
checkError(err)

for i, itm := range allItms.Items {
if itm.Id == updateItem.Id {
allItms.Items[i].FriendlyName = updateItem.FriendlyName
allItms.Items[i].Link = updateItem.Link
allItms.Items[i].Category = updateItem.Category
}
}

newItemBytes, err := json.MarshalIndent(&allItms.Items, "", " ")
checkError(err)
ioutil.WriteFile(viper.GetString("directories.data"), newItemBytes, 0666)
http.Redirect(w, r, "/", 301)
}

func deleteHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Path[len("/delete/"):]
i, err := strconv.Atoi(id)
if err != nil {
fmt.Println(err)
os.Exit(2)
}

// open file with items
file, err := os.OpenFile(viper.GetString("directories.data"), os.O_RDWR|os.O_APPEND, 0666)
defer file.Close()

// read file and unmarshall json to []items
b, err := ioutil.ReadAll(file)
var alItms model.AllItems
err = json.Unmarshal(b, &alItms.Items)
checkError(err)

for u, itm := range alItms.Items {
if itm.Id == i {
alItms.Items = append(alItms.Items[:u], alItms.Items[u+1:]...)
}
}

newItemBytes, err := json.MarshalIndent(&alItms.Items, "", " ")
checkError(err)
ioutil.WriteFile(viper.GetString("directories.data"), newItemBytes, 0666)
http.Redirect(w, r, "/", 301)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Path[len("/edit/"):]
i, err := strconv.Atoi(id)
if err != nil {
fmt.Println(err)
os.Exit(2)
}

au := model.Singleton(i)
t, err := template.ParseFiles(viper.GetString("directories.templates") + "/editPage.html")
checkError(err)
t.Execute(w, au)
}

func newHandler(w http.ResponseWriter, r *http.Request) {
//creating new instance and checking method
newItem := &model.Item{}
if r.Method == "GET" {
t, _ := template.ParseFiles(viper.GetString("directories.templates") + "/newItem.html")
t.Execute(w, nil)
} else {
resBool, errStr := checkFormValue(w, r, "friendlyName", "link", "category")
if resBool == false {
t, err := template.ParseFiles(viper.GetString("directories.templates") + "/error.html")
checkError(err)
t.Execute(w, errStr)
return
}

newItem.FriendlyName = r.FormValue("friendlyName")
newItem.Link = r.FormValue("link")
newItem.Category = r.FormValue("category")
var err error
//open file
file, err := os.OpenFile(viper.GetString("directories.data"), os.O_RDWR, 0644)
checkError(err)
defer file.Close()

//read file and unmarshall json file to slice of users
b, err := ioutil.ReadAll(file)
var alItms model.AllItems
err = json.Unmarshal(b, &alItms.Items)
checkError(err)
max := 0

// generation of id(last id at the json file+1)
for _, itm := range alItms.Items {
if itm.Id > max {
max = itm.Id
}
}
id := max + 1
newItem.Id = id

// appending newItem to slice of all Items and rewrite json file
alItms.Items = append(alItms.Items, newItem)
newItemBytes, err := json.MarshalIndent(&alItms.Items, "", " ")
checkError(err)
ioutil.WriteFile(viper.GetString("directories.data"), newItemBytes, 0666)
http.Redirect(w, r, "/", 301)
}
}

func apiItemsHandler(w http.ResponseWriter, r *http.Request) {
file, err := os.OpenFile(viper.GetString("directories.data"), os.O_RDWR, 0644)
checkError(err)
defer
file.Close()

b, err := ioutil.ReadAll(file)
var alItms model.AllItems
err = json.Unmarshal(b, &alItms.Items)
checkError(err)

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(alItms.Items)
}

func main() {
// Here we can add all viper configuration file/env file setup
// this will grab the proper config location, home of windows or linux, or if dev flag used the local dir
workEnv := config.DetermineEnv()

fmt.Println("Reading Config: \t", workEnv)

// this will then try to grab the config data
config, err := config.LoadConfig(workEnv)
if err != nil {
log.Fatal("Cannot load Config: ", err)
}

// Reading variables using the model. This is for dev purposes
fmt.Println("Server Port: \t", config.Server.Port)

http.HandleFunc("/", homeHandler)

http.HandleFunc("/update/", updateHandler)
http.HandleFunc("/delete/", deleteHandler)
http.HandleFunc("/edit/", editHandler)
http.HandleFunc("/new/", newHandler)

// now to allow static file serving for css and js assets
fs := http.FileServer(http.Dir(viper.GetString("directories.staticAssets")))
http.Handle("/assets/", http.StripPrefix("/assets/", fs))

// For the proper filtering of items, and hopeful searching, here will be an api call for js to get all items as json
http.HandleFunc("/api/items", apiItemsHandler)

// We are wrapping the listen in log.Fatal since it will only ever return an error, but otherwise nil
log.Fatal(http.ListenAndServe(":" + viper.GetString("server.port"), nil))
}
63 changes: 63 additions & 0 deletions assets/css/form.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
body {

background-color: #1a1a1a;
color: white;
}

input[type=text] {
background-color: #2b2b2b;
color: white;
width: 50%;
box-sizing: border-box;
padding: 10px 2px;
margin: 2px 0;
border-radius: 4px;
}

input[type=url] {
background-color: #2b2b2b;
color: white;
width: 50%;
box-sizing: border-box;
padding: 10px 2px;
margin: 2px 0;
border-radius: 4px;
}

input[type=url]:invalid {
background-color: #b01919;
font-weight: bold;
}

input[type=submit] {
background-color: #661294;
border: none;
color: white;
padding: 10px;
/*margin: 2px 0;*/
border-radius: 4px;
cursor: pointer;
width: 25%;
}

.goBack {
background-color: #261499;
border: none;
color: white;
padding: 10px;
border-radius: 4px;
cursor: pointer;
width: 25%;
}

.readonly_id {
display: none;
}

.full_form {
text-align: center;
}

h2 {
text-align: center;
}
Loading

0 comments on commit 9ff4530

Please sign in to comment.