gofmt, delete works
This commit is contained in:
parent
8f9969b4cc
commit
bc7fcdde54
|
@ -1,35 +1,35 @@
|
||||||
package categories
|
package categories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
_ "github.com/lib/pq"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Category struct {
|
type Category struct {
|
||||||
Id int
|
Id int
|
||||||
Name string
|
Name string
|
||||||
Parent sql.NullInt64
|
Parent sql.NullInt64
|
||||||
Children []*Category
|
Children []*Category
|
||||||
}
|
}
|
||||||
|
|
||||||
var CategoriesTree []*Category
|
var CategoriesTree []*Category
|
||||||
var CategoriesFlat map[int]*Category
|
var CategoriesFlat map[int]*Category
|
||||||
|
|
||||||
// Cavet: slight cheat. All parents must have Category_id < their children.
|
// Cavet: slight cheat. All parents must have Category_id < their children.
|
||||||
func LoadCategories(db *sql.DB) {
|
func LoadCategories(db *sql.DB) {
|
||||||
CategoriesTree = []*Category{}
|
CategoriesTree = []*Category{}
|
||||||
CategoriesFlat = make(map[int]*Category)
|
CategoriesFlat = make(map[int]*Category)
|
||||||
|
|
||||||
|
rows, err := db.Query("select categories.id, categories.name, categories.parent_id from categories order by coalesce(parent_id, id), parent_id is not null")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("DB Error loading Categories:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
rows, err := db.Query("select categories.id, categories.name, categories.parent_id from categories order by coalesce(parent_id, id), parent_id is not null")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("DB Error loading Categories:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
category := &Category{Children: []*Category{}}
|
category := &Category{Children: []*Category{}}
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ func LoadCategories(db *sql.DB) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CategoriesFlat[category.Id] = category
|
CategoriesFlat[category.Id] = category
|
||||||
|
|
||||||
if category.Parent.Valid {
|
if category.Parent.Valid {
|
||||||
pid := int(category.Parent.Int64)
|
pid := int(category.Parent.Int64)
|
||||||
CategoriesFlat[pid].Children = append(CategoriesFlat[pid].Children, category)
|
CategoriesFlat[pid].Children = append(CategoriesFlat[pid].Children, category)
|
||||||
} else {
|
} else {
|
||||||
CategoriesTree = append(CategoriesTree, category)
|
CategoriesTree = append(CategoriesTree, category)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func Add(db *sql.DB, name string, parent int) error {
|
||||||
_, err = db.Exec("INSERT INTO categories (name, parent_id) VALUES ($1, $2)", name, parent)
|
_, err = db.Exec("INSERT INTO categories (name, parent_id) VALUES ($1, $2)", name, parent)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Categories DB Error Add(): " , err)
|
fmt.Println("Categories DB Error Add(): ", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -67,65 +67,64 @@ func Add(db *sql.DB, name string, parent int) error {
|
||||||
// set category of news to parent
|
// set category of news to parent
|
||||||
// finallly delete
|
// finallly delete
|
||||||
func Delete(db *sql.DB, id int) error {
|
func Delete(db *sql.DB, id int) error {
|
||||||
rows, err := db.Query("SELECT parent_id FROM categories WHERE id=$1", id)
|
rows, err := db.Query("SELECT parent_id FROM categories WHERE id=$1", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Categories DB Error loading category parent id: ", err)
|
fmt.Println("Categories DB Error loading category parent id: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rows.Next() {
|
if !rows.Next() {
|
||||||
fmt.Println("Categories DB Error loading category parent id: no category")
|
fmt.Println("Categories DB Error loading category parent id: no category")
|
||||||
return errors.New("No category")
|
return errors.New("No category")
|
||||||
}
|
}
|
||||||
var parent_id sql.NullInt64
|
var parent_id sql.NullInt64
|
||||||
err = rows.Scan(&parent_id)
|
err = rows.Scan(&parent_id)
|
||||||
|
|
||||||
_, err = db.Exec("UPDATE categories SET parent_id =$2 WHERE parent_id=$1", id, parent_id)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Categories DB error changing child parent: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_, err = db.Exec("UPDATE news SET category_id =$2 WHERE category_id=$1", id, parent_id)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Categories DB error changing category of news: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.Exec("DELETE FROM categories WHERE id=$1", id)
|
_, err = db.Exec("UPDATE categories SET parent_id =$2 WHERE parent_id=$1", id, parent_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Categories DB Error Delete(): ", err)
|
fmt.Println("Categories DB error changing child parent: ", err)
|
||||||
}
|
return err
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec("UPDATE news SET category_id =$2 WHERE category_id=$1", id, parent_id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Categories DB error changing category of news: ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec("DELETE FROM categories WHERE id=$1", id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Categories DB Error Delete(): ", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (category *Category) ChangeParent(db *sql.DB, parent *Category) error {
|
func (category *Category) ChangeParent(db *sql.DB, parent *Category) error {
|
||||||
var err error
|
var err error
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
_, err = db.Exec("UPDATE categories SET parent_id = NULL WHERE id = $1", category.Id)
|
_, err = db.Exec("UPDATE categories SET parent_id = NULL WHERE id = $1", category.Id)
|
||||||
} else {
|
} else {
|
||||||
_, err = db.Exec("UPDATE categories SET parent_id = $2 WHERE id = $1", category.Id, parent.Id)
|
_, err = db.Exec("UPDATE categories SET parent_id = $2 WHERE id = $1", category.Id, parent.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Categories DB Error: ", err)
|
fmt.Println("Categories DB Error: ", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the number of parents a category has
|
// get the number of parents a category has
|
||||||
func (category *Category) Depth() int {
|
func (category *Category) Depth() int {
|
||||||
depth := 0
|
depth := 0
|
||||||
current := category
|
current := category
|
||||||
for current.Parent.Valid {
|
for current.Parent.Valid {
|
||||||
current = CategoriesFlat[int(current.Parent.Int64)]
|
current = CategoriesFlat[int(current.Parent.Int64)]
|
||||||
depth ++
|
depth++
|
||||||
}
|
}
|
||||||
return depth
|
return depth
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for templates (add form select list)
|
// Helper function for templates (add form select list)
|
||||||
func (category *Category) ToString() string {
|
func (category *Category) ToString() string {
|
||||||
return strings.Repeat("- ", category.Depth()) + category.Name
|
return strings.Repeat("- ", category.Depth()) + category.Name
|
||||||
}
|
}
|
||||||
|
|
17
main.go
17
main.go
|
@ -3,16 +3,16 @@ package main
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"flag"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VERSION = "0.1"
|
VERSION = "0.1"
|
||||||
MAX_DB_CONNS = 10 // already excessive for personal app
|
MAX_DB_CONNS = 10 // already excessive for personal app
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type Config struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
Port string
|
Port string
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -33,9 +33,9 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
config Config
|
config Config
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
store = sessions.NewCookieStore([]byte("key-store-auth-secret"))
|
store = sessions.NewCookieStore([]byte("key-store-auth-secret"))
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadConfig(env string) {
|
func loadConfig(env string) {
|
||||||
|
@ -69,13 +69,12 @@ func dbConnect() {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("transmet ", VERSION)
|
fmt.Println("transmet ", VERSION)
|
||||||
|
|
||||||
envFlag := flag.String("env", "local", "load config/{env}.json")
|
envFlag := flag.String("env", "local", "load config/{env}.json")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
|
||||||
fmt.Println("Loading...")
|
fmt.Println("Loading...")
|
||||||
|
|
||||||
loadConfig(*envFlag)
|
loadConfig(*envFlag)
|
||||||
dbConnect()
|
dbConnect()
|
||||||
initTemplates()
|
initTemplates()
|
||||||
|
|
203
news/news.go
203
news/news.go
|
@ -1,22 +1,21 @@
|
||||||
package news
|
package news
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"database/sql"
|
||||||
"database/sql"
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dballard/transmet/categories"
|
"github.com/dballard/transmet/categories"
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type News struct {
|
type News struct {
|
||||||
id int
|
id int
|
||||||
Url string
|
Url string
|
||||||
Title string
|
Title string
|
||||||
Category_id int
|
Category_id int
|
||||||
Date time.Time
|
Date time.Time
|
||||||
Notes string
|
Notes string
|
||||||
Expoerted bool
|
Expoerted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Storage Node containing:
|
/* Storage Node containing:
|
||||||
|
@ -24,55 +23,60 @@ type News struct {
|
||||||
* News children
|
* News children
|
||||||
* Category - category of this node
|
* Category - category of this node
|
||||||
* Children - sub containers: mapped to sub categories
|
* Children - sub containers: mapped to sub categories
|
||||||
*/
|
*/
|
||||||
type NewsContainer struct {
|
type NewsContainer struct {
|
||||||
Name string
|
Name string
|
||||||
News []News
|
News []News
|
||||||
Category *categories.Category
|
Category *categories.Category
|
||||||
Children map[int]*NewsContainer
|
Children map[int]*NewsContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert News item into DB
|
// Insert News item into DB
|
||||||
func (news *News) Insert(db *sql.DB) error {
|
func (news *News) Insert(db *sql.DB) error {
|
||||||
_, err := db.Exec("INSERT INTO news (url, title, category_id, notes) VALUES($1, $2, $3, $4)", news.Url, news.Title, news.Category_id, news.Notes );
|
_, err := db.Exec("INSERT INTO news (url, title, category_id, notes) VALUES($1, $2, $3, $4)", news.Url, news.Title, news.Category_id, news.Notes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error inserting news: ", err)
|
fmt.Println("Error inserting news: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Delete(db *sql.DB, id int) error {
|
func Delete(db *sql.DB, id int) error {
|
||||||
|
_, err := db.Exec("DELETE FROM news WHERE id = $1", id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error deleting news: ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func nullStringToString(str *sql.NullString) string {
|
func nullStringToString(str *sql.NullString) string {
|
||||||
if str.Valid {
|
if str.Valid {
|
||||||
return str.String
|
return str.String
|
||||||
} else {
|
} else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init and add a news container to the Data Structs
|
// Init and add a news container to the Data Structs
|
||||||
func addContainer(category_id int, flat, tree map[int]*NewsContainer) {
|
func addContainer(category_id int, flat, tree map[int]*NewsContainer) {
|
||||||
container := &NewsContainer{ Category: categories.CategoriesFlat[category_id], Name: categories.CategoriesFlat[category_id].Name, News: []News{}, Children: map[int]*NewsContainer{} }
|
container := &NewsContainer{Category: categories.CategoriesFlat[category_id], Name: categories.CategoriesFlat[category_id].Name, News: []News{}, Children: map[int]*NewsContainer{}}
|
||||||
flat[category_id] = container
|
flat[category_id] = container
|
||||||
parent := categories.CategoriesFlat[category_id].Parent
|
parent := categories.CategoriesFlat[category_id].Parent
|
||||||
if parent.Valid {
|
if parent.Valid {
|
||||||
if _, ok := flat[int(parent.Int64)]; !ok {
|
if _, ok := flat[int(parent.Int64)]; !ok {
|
||||||
addContainer(int(parent.Int64), flat, tree)
|
addContainer(int(parent.Int64), flat, tree)
|
||||||
}
|
}
|
||||||
flat[int(parent.Int64)].Children[category_id] = container
|
flat[int(parent.Int64)].Children[category_id] = container
|
||||||
} else {
|
} else {
|
||||||
tree[category_id] = container
|
tree[category_id] = container
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and return in NewsContainer format all the unexported news items
|
// Load and return in NewsContainer format all the unexported news items
|
||||||
func LoadPage(db *sql.DB, offset, amount int) ([]*News, int, error) {
|
func LoadPage(db *sql.DB, offset, amount int) ([]*News, int, error) {
|
||||||
categories.LoadCategories(db) // required by addContainer
|
categories.LoadCategories(db) // required by addContainer
|
||||||
|
|
||||||
rows, err := db.Query("SELECT id, url, title, category_id, timestamp, notes FROM news WHERE exported is null order by timestamp DESC")
|
rows, err := db.Query("SELECT id, url, title, category_id, timestamp, notes FROM news WHERE exported is null order by timestamp DESC")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -86,7 +90,7 @@ func LoadPage(db *sql.DB, offset, amount int) ([]*News, int, error) {
|
||||||
|
|
||||||
// Load and return in NewsContainer format all the unexported news items
|
// Load and return in NewsContainer format all the unexported news items
|
||||||
func Unexported(db *sql.DB) (map[int]*NewsContainer, int, error) {
|
func Unexported(db *sql.DB) (map[int]*NewsContainer, int, error) {
|
||||||
categories.LoadCategories(db) // required by addContainer
|
categories.LoadCategories(db) // required by addContainer
|
||||||
|
|
||||||
rows, err := db.Query("SELECT id, url, title, category_id, timestamp, notes FROM news WHERE exported is null order by category_id ASC")
|
rows, err := db.Query("SELECT id, url, title, category_id, timestamp, notes FROM news WHERE exported is null order by category_id ASC")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -94,92 +98,91 @@ func Unexported(db *sql.DB) (map[int]*NewsContainer, int, error) {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
return convertSqlToNewsContainer(rows)
|
return convertSqlToNewsContainer(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertSqlToNews(rows *sql.Rows) ([]*News, int, error) {
|
func convertSqlToNews(rows *sql.Rows) ([]*News, int, error) {
|
||||||
news := []*News{}
|
news := []*News{}
|
||||||
count := 0
|
count := 0
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
newsItem := &News{}
|
newsItem := &News{}
|
||||||
var url, title, notes sql.NullString
|
var url, title, notes sql.NullString
|
||||||
var category_id sql.NullInt64
|
var category_id sql.NullInt64
|
||||||
err := rows.Scan(&newsItem.id, &url, &title, &category_id, &newsItem.Date, ¬es)
|
err := rows.Scan(&newsItem.id, &url, &title, &category_id, &newsItem.Date, ¬es)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error reading news from DB: " + err.Error())
|
fmt.Println("Error reading news from DB: " + err.Error())
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
newsItem.Url = nullStringToString(&url)
|
newsItem.Url = nullStringToString(&url)
|
||||||
newsItem.Title = nullStringToString(&title)
|
newsItem.Title = nullStringToString(&title)
|
||||||
newsItem.Notes = nullStringToString(¬es)
|
newsItem.Notes = nullStringToString(¬es)
|
||||||
|
|
||||||
if category_id.Valid {
|
if category_id.Valid {
|
||||||
newsItem.Category_id = int(category_id.Int64)
|
newsItem.Category_id = int(category_id.Int64)
|
||||||
} else {
|
} else {
|
||||||
continue // needs a category id
|
continue // needs a category id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
news = append(news, newsItem)
|
||||||
news = append(news, newsItem)
|
count++
|
||||||
count++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return news, count, nil
|
return news, count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertSqlToNewsContainer(rows *sql.Rows) (map[int]*NewsContainer, int, error) {
|
func convertSqlToNewsContainer(rows *sql.Rows) (map[int]*NewsContainer, int, error) {
|
||||||
newsTree := map[int]*NewsContainer{}
|
newsTree := map[int]*NewsContainer{}
|
||||||
newsFlat := map[int]*NewsContainer{}
|
newsFlat := map[int]*NewsContainer{}
|
||||||
count := 0
|
count := 0
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
news := News{}
|
news := News{}
|
||||||
var url, title, notes sql.NullString
|
var url, title, notes sql.NullString
|
||||||
var category_id sql.NullInt64
|
var category_id sql.NullInt64
|
||||||
err := rows.Scan(&news.id, &url, &title, &category_id, &news.Date, ¬es)
|
err := rows.Scan(&news.id, &url, &title, &category_id, &news.Date, ¬es)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error reading news from DB: " + err.Error())
|
fmt.Println("Error reading news from DB: " + err.Error())
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
news.Url = nullStringToString(&url)
|
news.Url = nullStringToString(&url)
|
||||||
news.Title = nullStringToString(&title)
|
news.Title = nullStringToString(&title)
|
||||||
news.Notes = nullStringToString(¬es)
|
news.Notes = nullStringToString(¬es)
|
||||||
|
|
||||||
if category_id.Valid {
|
if category_id.Valid {
|
||||||
news.Category_id = int(category_id.Int64)
|
news.Category_id = int(category_id.Int64)
|
||||||
} else {
|
} else {
|
||||||
continue // needs a category id
|
continue // needs a category id
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := newsFlat[news.Category_id]; !ok {
|
if _, ok := newsFlat[news.Category_id]; !ok {
|
||||||
addContainer(news.Category_id, newsFlat, newsTree)
|
addContainer(news.Category_id, newsFlat, newsTree)
|
||||||
}
|
}
|
||||||
container := newsFlat[news.Category_id]
|
container := newsFlat[news.Category_id]
|
||||||
container.News = append(container.News, news)
|
container.News = append(container.News, news)
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
return newsTree, count, nil
|
return newsTree, count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper fn - formating - math
|
// Helper fn - formating - math
|
||||||
func (this *NewsContainer) HeaderDepth(start int) int {
|
func (this *NewsContainer) HeaderDepth(start int) int {
|
||||||
return start + this.Category.Depth()
|
return start + this.Category.Depth()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the current batch (news.exported is null) as exported in this batch (exported = now())
|
// Mark the current batch (news.exported is null) as exported in this batch (exported = now())
|
||||||
func MarkExported(db *sql.DB) error {
|
func MarkExported(db *sql.DB) error {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
_, err := db.Exec("UPDATE news SET exported=$1 WHERE exported is null", now)
|
_, err := db.Exec("UPDATE news SET exported=$1 WHERE exported is null", now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("DB errror: news.MarkExported():", err)
|
fmt.Println("DB errror: news.MarkExported():", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (news *News) Id() int {
|
func (news *News) Id() int {
|
||||||
return news.id
|
return news.id
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gorilla/mux"
|
"bytes"
|
||||||
"github.com/gorilla/sessions"
|
|
||||||
"net/http"
|
|
||||||
"github.com/dballard/transmet/user"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
"io/ioutil"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"strconv"
|
|
||||||
"github.com/dballard/transmet/categories"
|
"github.com/dballard/transmet/categories"
|
||||||
"github.com/dballard/transmet/news"
|
"github.com/dballard/transmet/news"
|
||||||
"bytes"
|
"github.com/dballard/transmet/user"
|
||||||
txtTemplate "text/template"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/gorilla/sessions"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
txtTemplate "text/template"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFlashes(session *sessions.Session) map[string]interface{} {
|
func GetFlashes(session *sessions.Session) map[string]interface{} {
|
||||||
|
@ -67,7 +67,7 @@ func LoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
session, _ := store.Get(r, "c_user")
|
session, _ := store.Get(r, "c_user")
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
|
|
||||||
ShowTemplate("login", w, map[string]interface{}{"flashes": flashes})
|
ShowTemplate("login", w, map[string]interface{}{"flashes": flashes})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ func LoginPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
session.Values["username"] = user.Username
|
session.Values["username"] = user.Username
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
if r.URL.Query().Get("url") != "" {
|
if r.URL.Query().Get("url") != "" {
|
||||||
http.Redirect(w, r, "/add?" + r.URL.RawQuery, http.StatusFound)
|
http.Redirect(w, r, "/add?"+r.URL.RawQuery, http.StatusFound)
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,31 +107,31 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request, user *user.User, sess
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUrlTitle(url string) string {
|
func getUrlTitle(url string) string {
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error looking up link", url, ":", err)
|
fmt.Println("Error looking up link", url, ":", err)
|
||||||
} else {
|
} else {
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error reading link", url, ":", err)
|
fmt.Println("Error reading link", url, ":", err)
|
||||||
} else {
|
} else {
|
||||||
re := regexp.MustCompile("< *[Tt][Ii][Tt][Ll][Ee] *>(.*)</ *[Tt][Ii][Tt][Ll][Ee] *>")
|
re := regexp.MustCompile("< *[Tt][Ii][Tt][Ll][Ee] *>(.*)</ *[Tt][Ii][Tt][Ll][Ee] *>")
|
||||||
title := re.FindStringSubmatch(string(body))
|
title := re.FindStringSubmatch(string(body))
|
||||||
if title != nil {
|
if title != nil {
|
||||||
return strings.TrimSpace(title[1])
|
return strings.TrimSpace(title[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?url=
|
// ?url=
|
||||||
func addFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func addFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
categories.LoadCategories(db)
|
categories.LoadCategories(db)
|
||||||
|
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
popup := session.Values["popup"]
|
popup := session.Values["popup"]
|
||||||
delete(session.Values, "popup")
|
delete(session.Values, "popup")
|
||||||
title := session.Values["title"]
|
title := session.Values["title"]
|
||||||
delete(session.Values, "title")
|
delete(session.Values, "title")
|
||||||
link := session.Values["link"]
|
link := session.Values["link"]
|
||||||
|
@ -139,239 +139,238 @@ func addFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, ses
|
||||||
description := session.Values["description"]
|
description := session.Values["description"]
|
||||||
delete(session.Values, "description")
|
delete(session.Values, "description")
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
|
|
||||||
if link != nil {
|
if link != nil {
|
||||||
//TODO category_id
|
//TODO category_id
|
||||||
ShowTemplate("add", w, map[string]interface{}{"user": user, "flashes": flashes, "categories": categories.CategoriesTree, "link": link, "title": title, "description": description, "popup": popup})
|
ShowTemplate("add", w, map[string]interface{}{"user": user, "flashes": flashes, "categories": categories.CategoriesTree, "link": link, "title": title, "description": description, "popup": popup})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = r.URL.Query().Get("url")
|
var url = r.URL.Query().Get("url")
|
||||||
reHttp := regexp.MustCompile("^https?://")
|
reHttp := regexp.MustCompile("^https?://")
|
||||||
if url != "" && ! reHttp.Match([]byte(url)) {
|
if url != "" && !reHttp.Match([]byte(url)) {
|
||||||
url = "http://" + url
|
url = "http://" + url
|
||||||
}
|
}
|
||||||
|
|
||||||
title = r.URL.Query().Get("title")
|
title = r.URL.Query().Get("title")
|
||||||
if title == "" && url != "" {
|
if title == "" && url != "" {
|
||||||
title = getUrlTitle(url)
|
title = getUrlTitle(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
popup = r.URL.Query().Get("popup")
|
popup = r.URL.Query().Get("popup")
|
||||||
|
|
||||||
ShowTemplate("add", w, map[string]interface{}{"user": user, "flashes": flashes, "link": url, "categories": categories.CategoriesTree, "title": title, "popup": popup})
|
ShowTemplate("add", w, map[string]interface{}{"user": user, "flashes": flashes, "link": url, "categories": categories.CategoriesTree, "title": title, "popup": popup})
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPostHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func addPostHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
var news news.News
|
var news news.News
|
||||||
|
|
||||||
news.Title = r.FormValue("title")
|
news.Title = r.FormValue("title")
|
||||||
news.Notes = r.FormValue("notes")
|
news.Notes = r.FormValue("notes")
|
||||||
news.Url = r.FormValue("link")
|
news.Url = r.FormValue("link")
|
||||||
popup := r.FormValue("popup")
|
popup := r.FormValue("popup")
|
||||||
category_id, err := strconv.Atoi(r.FormValue("category"))
|
category_id, err := strconv.Atoi(r.FormValue("category"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
category_id = -1
|
category_id = -1
|
||||||
}
|
}
|
||||||
news.Category_id = category_id
|
news.Category_id = category_id
|
||||||
|
|
||||||
err = (&news).Insert(db)
|
err = (&news).Insert(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error saving news: " + err.Error(), flash_err)
|
session.AddFlash("Error saving news: "+err.Error(), flash_err)
|
||||||
session.Values["title"] = news.Title
|
session.Values["title"] = news.Title
|
||||||
session.Values["link"] = news.Url
|
session.Values["link"] = news.Url
|
||||||
session.Values["notes"] = news.Notes
|
session.Values["notes"] = news.Notes
|
||||||
session.Values["popup"] = popup
|
session.Values["popup"] = popup
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/add", http.StatusFound)
|
http.Redirect(w, r, "/add", http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
// TODO auto close? redirect
|
// TODO auto close? redirect
|
||||||
session.AddFlash("Added news \""+news.Title+"\"", flash_info)
|
session.AddFlash("Added news \""+news.Title+"\"", flash_info)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
if popup == "1" {
|
if popup == "1" {
|
||||||
http.Redirect(w, r, "/added", http.StatusFound)
|
http.Redirect(w, r, "/added", http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func templateFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func templateFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
|
|
||||||
news, count, err := news.Unexported(db)
|
news, count, err := news.Unexported(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var templateBuf bytes.Buffer
|
var templateBuf bytes.Buffer
|
||||||
template, err := txtTemplate.ParseFiles("templates/html_template.txt")
|
template, err := txtTemplate.ParseFiles("templates/html_template.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error processing html_tempalte:" , err)
|
fmt.Println("Error processing html_tempalte:", err)
|
||||||
}
|
}
|
||||||
err = template.Execute(&templateBuf, map[string]interface{}{"news": news})
|
err = template.Execute(&templateBuf, map[string]interface{}{"news": news})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Exec err: ", err)
|
fmt.Println("Exec err: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowTemplate("export", w, map[string]interface{}{"user": user, "flashes": flashes, "template": &templateBuf, "count": count, "url": config.Url})
|
ShowTemplate("export", w, map[string]interface{}{"user": user, "flashes": flashes, "template": &templateBuf, "count": count, "url": config.Url})
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func exportHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
err := news.MarkExported(db)
|
err := news.MarkExported(db)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error marking last batch of news exported", flash_err)
|
session.AddFlash("Error marking last batch of news exported", flash_err)
|
||||||
} else {
|
} else {
|
||||||
session.AddFlash("Last batch of news marked exported", flash_info)
|
session.AddFlash("Last batch of news marked exported", flash_info)
|
||||||
}
|
}
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addedHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func addedHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
ShowTemplate("added", w, map[string]interface{}{"user": user, "flashes": flashes})
|
ShowTemplate("added", w, map[string]interface{}{"user": user, "flashes": flashes})
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func deleteHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
id, idErr := strconv.Atoi(r.FormValue("id"))
|
id, idErr := strconv.Atoi(r.FormValue("id"))
|
||||||
|
|
||||||
if idErr != nil {
|
if idErr != nil {
|
||||||
session.AddFlash("Invalid news to delete", flash_err)
|
session.AddFlash("Invalid news to delete", flash_err)
|
||||||
} else {
|
} else {
|
||||||
err := news.Delete(db, id)
|
err := news.Delete(db, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error commiting to Database", flash_err)
|
session.AddFlash("Error commiting to Database", flash_err)
|
||||||
} else {
|
} else {
|
||||||
session.AddFlash("Deleted news post", flash_info)
|
session.AddFlash("Deleted news post", flash_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func categoriesFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func categoriesFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
categories.LoadCategories(db)
|
categories.LoadCategories(db)
|
||||||
|
|
||||||
ShowTemplate("categories", w, map[string]interface{}{"user": user, "flashes": flashes, "categories": categories.CategoriesTree})
|
ShowTemplate("categories", w, map[string]interface{}{"user": user, "flashes": flashes, "categories": categories.CategoriesTree})
|
||||||
}
|
}
|
||||||
|
|
||||||
func categoriesPostHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func categoriesPostHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
http.Redirect(w, r, "/categories", http.StatusFound)
|
http.Redirect(w, r, "/categories", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func categoryFromReqArg(arg string) *categories.Category {
|
func categoryFromReqArg(arg string) *categories.Category {
|
||||||
if cid, err := strconv.Atoi(arg); err != nil {
|
if cid, err := strconv.Atoi(arg); err != nil {
|
||||||
return nil
|
return nil
|
||||||
} else if category, ok := categories.CategoriesFlat[cid]; !ok {
|
} else if category, ok := categories.CategoriesFlat[cid]; !ok {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return category
|
return category
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func categoryChangeParentHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func categoryChangeParentHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
categories.LoadCategories(db)
|
categories.LoadCategories(db)
|
||||||
category := categoryFromReqArg(r.FormValue("cid"))
|
category := categoryFromReqArg(r.FormValue("cid"))
|
||||||
parent := categoryFromReqArg(r.FormValue("parent"))
|
parent := categoryFromReqArg(r.FormValue("parent"))
|
||||||
|
|
||||||
if category == nil {
|
if category == nil {
|
||||||
session.AddFlash("Invalid category", flash_err)
|
session.AddFlash("Invalid category", flash_err)
|
||||||
} else if parent != nil && category.Id == parent.Id {
|
} else if parent != nil && category.Id == parent.Id {
|
||||||
session.AddFlash("Cannot set category parent to itself", flash_err)
|
session.AddFlash("Cannot set category parent to itself", flash_err)
|
||||||
} else {
|
} else {
|
||||||
err := category.ChangeParent(db, parent)
|
err := category.ChangeParent(db, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error commiting to Database", flash_err)
|
session.AddFlash("Error commiting to Database", flash_err)
|
||||||
} else {
|
} else {
|
||||||
session.AddFlash("Changed category parent", flash_info)
|
session.AddFlash("Changed category parent", flash_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/categories", http.StatusFound)
|
http.Redirect(w, r, "/categories", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func categoryAddHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func categoryAddHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
name := r.FormValue("name")
|
name := r.FormValue("name")
|
||||||
parent, perr := strconv.Atoi(r.FormValue("parent"))
|
parent, perr := strconv.Atoi(r.FormValue("parent"))
|
||||||
|
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
parent = -1
|
parent = -1
|
||||||
}
|
}
|
||||||
if name == "" {
|
if name == "" {
|
||||||
session.AddFlash("Invalid category name", flash_err)
|
session.AddFlash("Invalid category name", flash_err)
|
||||||
} else {
|
} else {
|
||||||
err := categories.Add(db, name, parent)
|
err := categories.Add(db, name, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error commiting to Database", flash_err)
|
session.AddFlash("Error commiting to Database", flash_err)
|
||||||
} else {
|
} else {
|
||||||
session.AddFlash("Added category", flash_info)
|
session.AddFlash("Added category", flash_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/categories", http.StatusFound)
|
http.Redirect(w, r, "/categories", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func categoryDeleteHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func categoryDeleteHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
id, idErr := strconv.Atoi(r.FormValue("id"))
|
id, idErr := strconv.Atoi(r.FormValue("id"))
|
||||||
|
|
||||||
if idErr != nil {
|
if idErr != nil {
|
||||||
session.AddFlash("Invalid category to delete", flash_err)
|
session.AddFlash("Invalid category to delete", flash_err)
|
||||||
} else {
|
} else {
|
||||||
err := categories.Delete(db, id)
|
err := categories.Delete(db, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.AddFlash("Error commiting to Database", flash_err)
|
session.AddFlash("Error commiting to Database", flash_err)
|
||||||
} else {
|
} else {
|
||||||
session.AddFlash("Deleted category", flash_info)
|
session.AddFlash("Deleted category", flash_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/categories", http.StatusFound)
|
http.Redirect(w, r, "/categories", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) {
|
||||||
flashes := GetFlashes(session)
|
flashes := GetFlashes(session)
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
var offset = 0
|
var offset = 0
|
||||||
var amount = 100
|
var amount = 100
|
||||||
|
|
||||||
argOffset, eOffset := strconv.Atoi(r.FormValue("offset"))
|
argOffset, eOffset := strconv.Atoi(r.FormValue("offset"))
|
||||||
if eOffset == nil {
|
if eOffset == nil {
|
||||||
offset = amount * argOffset
|
offset = amount * argOffset
|
||||||
}
|
|
||||||
|
|
||||||
news, count, err := news.LoadPage(db, offset, amount)
|
|
||||||
if err != nil {
|
|
||||||
session.AddFlash("Error loading news", flash_err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowTemplate("news", w, map[string]interface{}{"user": user, "flashes": flashes, "news": news, "count": count, "categories": categories.CategoriesFlat})
|
news, count, err := news.LoadPage(db, offset, amount)
|
||||||
|
if err != nil {
|
||||||
|
session.AddFlash("Error loading news", flash_err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowTemplate("news", w, map[string]interface{}{"user": user, "flashes": flashes, "news": news, "count": count, "categories": categories.CategoriesFlat})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServeFileHandler(res http.ResponseWriter, req *http.Request) {
|
func ServeFileHandler(res http.ResponseWriter, req *http.Request) {
|
||||||
fname := path.Base(req.URL.Path)
|
fname := path.Base(req.URL.Path)
|
||||||
http.ServeFile(res, req, "./"+fname)
|
http.ServeFile(res, req, "./"+fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init_route_handlers() {
|
func init_route_handlers() {
|
||||||
http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("js/"))))
|
http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("js/"))))
|
||||||
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("css/"))))
|
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("css/"))))
|
||||||
http.Handle("/fonts/", http.StripPrefix("/fonts", http.FileServer(http.Dir("fonts/"))))
|
http.Handle("/fonts/", http.StripPrefix("/fonts", http.FileServer(http.Dir("fonts/"))))
|
||||||
http.HandleFunc("/favicon.ico", ServeFileHandler)
|
http.HandleFunc("/favicon.ico", ServeFileHandler)
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
|
||||||
r.HandleFunc("/login", getPostHandler(LoginFormHandler, LoginPostHandler))
|
r.HandleFunc("/login", getPostHandler(LoginFormHandler, LoginPostHandler))
|
||||||
r.HandleFunc("/logout", userHandler(LogoutHandler))
|
r.HandleFunc("/logout", userHandler(LogoutHandler))
|
||||||
|
|
||||||
|
@ -382,11 +381,11 @@ func init_route_handlers() {
|
||||||
r.HandleFunc("/export-commit", userHandler(exportHandler))
|
r.HandleFunc("/export-commit", userHandler(exportHandler))
|
||||||
r.HandleFunc("/added", userHandler(addedHandler))
|
r.HandleFunc("/added", userHandler(addedHandler))
|
||||||
r.HandleFunc("/delete", userHandler(deleteHandler))
|
r.HandleFunc("/delete", userHandler(deleteHandler))
|
||||||
|
|
||||||
r.HandleFunc("/categories", getPostHandler(userHandler(categoriesFormHandler), userHandler(categoriesPostHandler)))
|
r.HandleFunc("/categories", getPostHandler(userHandler(categoriesFormHandler), userHandler(categoriesPostHandler)))
|
||||||
r.HandleFunc("/categories/change-parent", userHandler(categoryChangeParentHandler))
|
r.HandleFunc("/categories/change-parent", userHandler(categoryChangeParentHandler))
|
||||||
r.HandleFunc("/categories/add", userHandler(categoryAddHandler))
|
r.HandleFunc("/categories/add", userHandler(categoryAddHandler))
|
||||||
r.HandleFunc("/categories/delete", userHandler(categoryDeleteHandler))
|
r.HandleFunc("/categories/delete", userHandler(categoryDeleteHandler))
|
||||||
|
|
||||||
http.Handle("/", r)
|
http.Handle("/", r)
|
||||||
}
|
}
|
||||||
|
|
87
templates.go
87
templates.go
|
@ -1,81 +1,80 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/dballard/transmet/categories"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"net/http"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/dballard/transmet/categories"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
templates = map[string]*template.Template{}
|
templates = map[string]*template.Template{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// template helper function
|
// template helper function
|
||||||
func dict (values ...interface{}) (map[string]interface{}, error) {
|
func dict(values ...interface{}) (map[string]interface{}, error) {
|
||||||
if len(values)%2 != 0 {
|
if len(values)%2 != 0 {
|
||||||
return nil, errors.New("invalid dict call")
|
return nil, errors.New("invalid dict call")
|
||||||
}
|
}
|
||||||
dict := make(map[string]interface{}, len(values)/2)
|
dict := make(map[string]interface{}, len(values)/2)
|
||||||
for i := 0; i < len(values); i+=2 {
|
for i := 0; i < len(values); i += 2 {
|
||||||
key, ok := values[i].(string)
|
key, ok := values[i].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("dict keys must be strings")
|
return nil, errors.New("dict keys must be strings")
|
||||||
}
|
}
|
||||||
dict[key] = values[i+1]
|
dict[key] = values[i+1]
|
||||||
}
|
}
|
||||||
return dict, nil
|
return dict, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// string multiplication
|
// string multiplication
|
||||||
// stringTimes(3, "Foo") => "FooFooFoo"
|
// stringTimes(3, "Foo") => "FooFooFoo"
|
||||||
func stringTimes(times int, str string) string {
|
func stringTimes(times int, str string) string {
|
||||||
result := ""
|
result := ""
|
||||||
for i := 0; i < times; i ++ {
|
for i := 0; i < times; i++ {
|
||||||
result += str
|
result += str
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turns a Time into a formated string
|
// Turns a Time into a formated string
|
||||||
func dateFormat(t time.Time) string {
|
func dateFormat(t time.Time) string {
|
||||||
return t.Format("2006.01.02 15:04:05")
|
return t.Format("2006.01.02 15:04:05")
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes a category_id and returns "Root / Parent / Category"
|
// takes a category_id and returns "Root / Parent / Category"
|
||||||
func fullCategoryPath(categoriesFlat map[int]*categories.Category, category_id int) string {
|
func fullCategoryPath(categoriesFlat map[int]*categories.Category, category_id int) string {
|
||||||
var categoryNames []string = nil
|
var categoryNames []string = nil
|
||||||
for category := categoriesFlat[category_id]; category != nil; category = categoriesFlat[int(category.Parent.Int64)] {
|
for category := categoriesFlat[category_id]; category != nil; category = categoriesFlat[int(category.Parent.Int64)] {
|
||||||
categoryNames = append([]string{category.Name}, categoryNames...)
|
categoryNames = append([]string{category.Name}, categoryNames...)
|
||||||
}
|
}
|
||||||
return strings.Join(categoryNames, " / ")
|
return strings.Join(categoryNames, " / ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncate a string
|
// truncate a string
|
||||||
func truncate(str string, maxLen int) string {
|
func truncate(str string, maxLen int) string {
|
||||||
if len(str) <= maxLen {
|
if len(str) <= maxLen {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
return str[0:maxLen] + "..."
|
return str[0:maxLen] + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tempalte helper functions
|
// Tempalte helper functions
|
||||||
var funcMap = template.FuncMap {
|
var funcMap = template.FuncMap{
|
||||||
"add": func (x, y int) int { return x + y },
|
"add": func(x, y int) int { return x + y },
|
||||||
"minus": func (x, y int) int { return x - y },
|
"minus": func(x, y int) int { return x - y },
|
||||||
"dict": dict,
|
"dict": dict,
|
||||||
"stringTimes": stringTimes,
|
"stringTimes": stringTimes,
|
||||||
"dateFormat": dateFormat,
|
"dateFormat": dateFormat,
|
||||||
"fullCategoryPath": fullCategoryPath,
|
"fullCategoryPath": fullCategoryPath,
|
||||||
"truncate": truncate,
|
"truncate": truncate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func initTemplates() {
|
func initTemplates() {
|
||||||
files, _ := filepath.Glob("templates/pages/*.html")
|
files, _ := filepath.Glob("templates/pages/*.html")
|
||||||
re := regexp.MustCompile("templates/pages/(.*).html")
|
re := regexp.MustCompile("templates/pages/(.*).html")
|
||||||
|
@ -93,4 +92,4 @@ func ShowTemplate(template string, w http.ResponseWriter, data map[string]interf
|
||||||
fmt.Println("Exec err: ", err)
|
fmt.Println("Exec err: ", err)
|
||||||
}
|
}
|
||||||
// TODO: show error 500 page
|
// TODO: show error 500 page
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Username string
|
Username string
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func UsernameExists(db *sql.DB, username string) (bool, error) {
|
func UsernameExists(db *sql.DB, username string) (bool, error) {
|
||||||
|
@ -39,7 +39,7 @@ func NewUserFromAuth(db *sql.DB, username, password string) *User {
|
||||||
fmt.Println("scan err: ", err)
|
fmt.Println("scan err: ", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("no match")
|
fmt.Println("no match")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &user
|
return &user
|
||||||
|
|
Loading…
Reference in New Issue