Started working on V2 rework
|
@ -1,5 +0,0 @@
|
||||||
dev
|
|
||||||
.gitignore
|
|
||||||
LICENSE
|
|
||||||
README.md
|
|
||||||
dist/main.db
|
|
12
.env.example
|
@ -9,15 +9,3 @@ DOMAIN_BASE=http://localhost:8080
|
||||||
CACHE_MAP_LIMIT=15
|
CACHE_MAP_LIMIT=15
|
||||||
# Maximum API call requests to the API, this will ban the api for 5 minutes after requesting more than API_RATE_LIMIT in 5 minutes.
|
# Maximum API call requests to the API, this will ban the api for 5 minutes after requesting more than API_RATE_LIMIT in 5 minutes.
|
||||||
API_BAN_LIMIT=300
|
API_BAN_LIMIT=300
|
||||||
|
|
||||||
# Optional database driver, you can just ignore and use sqlite
|
|
||||||
# ! Warning: Sqlite not implemented yet
|
|
||||||
DATABASE_DRIVER=mariadb
|
|
||||||
|
|
||||||
# Mysql database connetion details, fill these in if you chose mysql above.
|
|
||||||
MYSQL_ROOT_PASSWORD=example-dev
|
|
||||||
MYSQL_DATABASE=freepad
|
|
||||||
MYSQL_USER=freepad
|
|
||||||
MYSQL_PASSWORD=example-dev
|
|
||||||
MYSQL_URL=mariadb
|
|
||||||
MYSQL_PORT=3306
|
|
|
@ -2,7 +2,3 @@ dev/*
|
||||||
!dev/.keep
|
!dev/.keep
|
||||||
.env
|
.env
|
||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
# Ignore the database file
|
|
||||||
dist/main.db
|
|
||||||
dist/freepad
|
|
||||||
dist/freepad
|
|
||||||
|
|
15
Dockerfile
|
@ -1,15 +0,0 @@
|
||||||
FROM alpine
|
|
||||||
|
|
||||||
LABEL version="1.5.1"
|
|
||||||
|
|
||||||
# Copy the distribution files
|
|
||||||
COPY ./dist /app
|
|
||||||
|
|
||||||
# Make /app the work directory
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Expose the listening port
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
# Run the program
|
|
||||||
ENTRYPOINT ["./freepad"]
|
|
|
@ -8,7 +8,7 @@ Quickly create "pads" and share with others
|
||||||
[![demo](https://img.shields.io/badge/Demo-Check%20out%20the%20functionality-orange)](https://pad.justkato.me/)
|
[![demo](https://img.shields.io/badge/Demo-Check%20out%20the%20functionality-orange)](https://pad.justkato.me/)
|
||||||
![MariaDB](https://img.shields.io/badge/MariaDB-003545?style=for-the-badge&logo=mariadb&logoColor=white)
|
![MariaDB](https://img.shields.io/badge/MariaDB-003545?style=for-the-badge&logo=mariadb&logoColor=white)
|
||||||
|
|
||||||
# **FreePad**
|
# **FreePad V2**
|
||||||
**FreePad** is a simple `Go` project to help you juggle temporary notes that you might wanna pass from one device to another, or from a person to another with memorable and easy to communicate online "Pads".
|
**FreePad** is a simple `Go` project to help you juggle temporary notes that you might wanna pass from one device to another, or from a person to another with memorable and easy to communicate online "Pads".
|
||||||
|
|
||||||
The project is absolutely free to use, you can extend the code and even contribute, I am more than happy to be corrected in my horrible beginner code.
|
The project is absolutely free to use, you can extend the code and even contribute, I am more than happy to be corrected in my horrible beginner code.
|
||||||
|
|
15
build.sh
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
|
|
||||||
echo "Removing old";
|
|
||||||
rm dist/freepad;
|
|
||||||
|
|
||||||
# Remember current path
|
|
||||||
MYDIR=`pwd`;
|
|
||||||
# Go into src
|
|
||||||
cd src;
|
|
||||||
# Build
|
|
||||||
echo "Building..."
|
|
||||||
GIN_MODE=release CGO_ENABLED=0 GOOS=linux GIN_MODE=release go build -a -installsuffix cgo -o ../dist/freepad .
|
|
||||||
# Go back!
|
|
||||||
cd $MYDIR;
|
|
|
@ -1 +0,0 @@
|
||||||
DROP TABLE IF EXISTS t_posts;
|
|
|
@ -1,12 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS `t_posts` (
|
|
||||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` VARCHAR(256) NOT NULL DEFAULT '' COLLATE 'latin1_swedish_ci',
|
|
||||||
`content` MEDIUMTEXT NOT NULL COLLATE 'latin1_swedish_ci',
|
|
||||||
`ts` DATETIME NOT NULL DEFAULT current_timestamp(),
|
|
||||||
`ts_updated` DATETIME NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
|
||||||
UNIQUE INDEX `name` (`name`) USING BTREE
|
|
||||||
)
|
|
||||||
COLLATE='latin1_swedish_ci'
|
|
||||||
ENGINE=InnoDB
|
|
||||||
;
|
|
|
@ -1 +0,0 @@
|
||||||
DROP table t_posts;
|
|
|
@ -1,6 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS "t_posts" (
|
|
||||||
"id" INTEGER,
|
|
||||||
"name" TEXT,
|
|
||||||
"content" TEXT,
|
|
||||||
PRIMARY KEY("id" AUTOINCREMENT)
|
|
||||||
);
|
|
|
@ -1,38 +0,0 @@
|
||||||
version: '3.4'
|
|
||||||
services:
|
|
||||||
|
|
||||||
freepad:
|
|
||||||
build: .
|
|
||||||
networks:
|
|
||||||
- backend
|
|
||||||
environment:
|
|
||||||
- DOMAIN_BASE=http://localhost:8888
|
|
||||||
- MYSQL_URL=mariadb
|
|
||||||
- MYSQL_ROOT_PASSWORD
|
|
||||||
- MYSQL_DATABASE
|
|
||||||
- MYSQL_USER
|
|
||||||
- MYSQL_PASSWORD
|
|
||||||
- MYSQL_PORT
|
|
||||||
depends_on:
|
|
||||||
- mariadb
|
|
||||||
ports:
|
|
||||||
- 8888:8080
|
|
||||||
|
|
||||||
mariadb:
|
|
||||||
image: mariadb:10.2
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD
|
|
||||||
- MYSQL_DATABASE
|
|
||||||
- MYSQL_USER
|
|
||||||
- MYSQL_PASSWORD
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- backend
|
|
||||||
volumes:
|
|
||||||
- ./dev/mariadb:/var/lib/mysql
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
|
|
||||||
networks:
|
|
||||||
backend:
|
|
||||||
driver: bridge
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_, isDevelopment := os.LookupEnv("DEV_MODE")
|
||||||
|
if isDevelopment {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the router
|
||||||
|
router := gin.Default()
|
||||||
|
|
||||||
|
router.Run(":8080")
|
||||||
|
|
||||||
|
}
|
23
rundev.sh
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Removing old";
|
|
||||||
rm dist/freepad;
|
|
||||||
|
|
||||||
source ../.env
|
|
||||||
# Yeah, this is my solution
|
|
||||||
export DOMAIN_BASE CACHE_MAP_LIMIT API_BAN_LIMIT DATABASE_DRIVER MYSQL_ROOT_PASSWORD MYSQL_DATABASE MYSQL_USER MYSQL_PASSWORD MYSQL_URL MYSQL_PORT IS_DEV
|
|
||||||
|
|
||||||
# Remember current path
|
|
||||||
MYDIR=`pwd`;
|
|
||||||
# Go into src
|
|
||||||
cd src;
|
|
||||||
# Build
|
|
||||||
echo "Building..."
|
|
||||||
|
|
||||||
go build -o ../dist/freepad .
|
|
||||||
# Go back!
|
|
||||||
cd $MYDIR;
|
|
||||||
|
|
||||||
cd dist
|
|
||||||
|
|
||||||
./freepad && cd $MYDIR;
|
|
|
@ -1,122 +0,0 @@
|
||||||
package post
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/JustKato/FreePad/helper"
|
|
||||||
"github.com/JustKato/FreePad/models/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
var postList []*Post = []*Post{}
|
|
||||||
|
|
||||||
var postMap map[string]Post = make(map[string]Post)
|
|
||||||
|
|
||||||
func GetPostList() []*Post {
|
|
||||||
return postList
|
|
||||||
}
|
|
||||||
|
|
||||||
func Retrieve(name string) (*Post, error) {
|
|
||||||
|
|
||||||
if len(name) < 1 {
|
|
||||||
return nil, errors.New("the name of the post must contain at least 1 character")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(name) > 256 {
|
|
||||||
return nil, errors.New("the name of the post must not exceed 256 characters")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we have the post cached
|
|
||||||
if val, ok := postMap[name]; ok {
|
|
||||||
return &val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the post to the database
|
|
||||||
db, err := database.GetConn()
|
|
||||||
if err != nil {
|
|
||||||
println("Erorr", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
sql := `SELECT p.name, p.content FROM freepad.t_posts p WHERE p.name = ? LIMIT 1;`
|
|
||||||
s, err := db.Prepare(sql)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := s.Query(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
anyLeft := rows.Next()
|
|
||||||
if !anyLeft {
|
|
||||||
return nil, errors.New("could not find the requested post")
|
|
||||||
}
|
|
||||||
|
|
||||||
foundPost := Post{
|
|
||||||
Name: "",
|
|
||||||
Content: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = rows.Scan(&foundPost.Name, &foundPost.Content)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &foundPost, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Create(name string, content string) (*Post, error) {
|
|
||||||
|
|
||||||
if len(name) < 1 {
|
|
||||||
return nil, errors.New("the name of the post must contain at least 1 character")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(name) > 256 {
|
|
||||||
return nil, errors.New("the name of the post must not exceed 256 characters")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(content) > 16777200 {
|
|
||||||
return nil, errors.New("provided content is too long, please do not exceed ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the post
|
|
||||||
myPost := Post{
|
|
||||||
Name: name,
|
|
||||||
Content: content,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we can cache this element
|
|
||||||
if len(postMap) > helper.GetCacheMapLimit() {
|
|
||||||
// Reset Cache
|
|
||||||
postMap = make(map[string]Post)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the post by name
|
|
||||||
postMap[name] = myPost
|
|
||||||
|
|
||||||
// Add the post to the database
|
|
||||||
db, err := database.GetConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
sql := `REPLACE INTO freepad.t_posts (name, content) VALUES (?, ?)`
|
|
||||||
s, err := db.Prepare(sql)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.Exec(myPost.Name, myPost.Content)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the post
|
|
||||||
return &myPost, nil
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package post
|
|
||||||
|
|
||||||
type Post struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package helper
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/ulule/limiter/v3"
|
|
||||||
"github.com/ulule/limiter/v3/drivers/store/memory"
|
|
||||||
|
|
||||||
mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BindRateLimiter(router *gin.RouterGroup) {
|
|
||||||
// Setup rate limitng
|
|
||||||
rate := limiter.Rate{
|
|
||||||
Period: 5 * time.Minute,
|
|
||||||
Limit: 150,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the memory storage
|
|
||||||
store := memory.NewStore()
|
|
||||||
|
|
||||||
// Generate the middleware
|
|
||||||
middleware := mgin.NewMiddleware(limiter.New(store, rate))
|
|
||||||
|
|
||||||
// Use the middleware
|
|
||||||
router.Use(middleware)
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package helper
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetDomainBase() string {
|
|
||||||
domainBase, domainExists := os.LookupEnv("DOMAIN_BASE")
|
|
||||||
|
|
||||||
if !domainExists {
|
|
||||||
os.Setenv("DOMAIN_BASE", "http://localhost:8080")
|
|
||||||
domainBase = "http://localhost:8080"
|
|
||||||
}
|
|
||||||
|
|
||||||
return domainBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCacheMapLimit() int {
|
|
||||||
cacheMapLimit, domainExists := os.LookupEnv("CACHE_MAP_LIMIT")
|
|
||||||
|
|
||||||
if !domainExists {
|
|
||||||
os.Setenv("CACHE_MAP_LIMIT", "25")
|
|
||||||
cacheMapLimit = "25"
|
|
||||||
}
|
|
||||||
|
|
||||||
rez, err := strconv.Atoi(cacheMapLimit)
|
|
||||||
if err != nil {
|
|
||||||
return 25
|
|
||||||
}
|
|
||||||
|
|
||||||
return rez
|
|
||||||
}
|
|
45
src/main.go
|
@ -1,45 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/JustKato/FreePad/models/database"
|
|
||||||
"github.com/JustKato/FreePad/routes"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
_, isDevelopment := os.LookupEnv("IS_DEV")
|
|
||||||
if isDevelopment {
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the router
|
|
||||||
router := gin.Default()
|
|
||||||
|
|
||||||
// Read HTML Templates
|
|
||||||
router.LoadHTMLGlob("templates/**/*.html")
|
|
||||||
|
|
||||||
// Load in static path
|
|
||||||
router.Static("/static", "static/")
|
|
||||||
|
|
||||||
// Add Routes
|
|
||||||
routes.HomeRoutes(router)
|
|
||||||
// Bind /api
|
|
||||||
routes.ApiRoutes(router.Group("/api"))
|
|
||||||
|
|
||||||
// TODO: Sockets: https://gist.github.com/supanadit/f6de65fc5896e8bb0c4656e451387d0f
|
|
||||||
|
|
||||||
// Try and run migrations
|
|
||||||
err := database.MigrateMysql()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error")
|
|
||||||
fmt.Println(err)
|
|
||||||
fmt.Println("Error")
|
|
||||||
}
|
|
||||||
|
|
||||||
router.Run(":8080")
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Declare the default database driver
|
|
||||||
const defaultDatabaseDriver string = "sqlite"
|
|
||||||
|
|
||||||
// Declare the valid database drivers
|
|
||||||
var validDatabaseDrivers []string = []string{"sqlite", "mysql"}
|
|
||||||
|
|
||||||
// Get the database type to use
|
|
||||||
func getDbType() string {
|
|
||||||
// Grab the environment variable
|
|
||||||
db, test := os.LookupEnv(`DATABASE_DRIVER`)
|
|
||||||
|
|
||||||
// Check if the test has failed
|
|
||||||
if !test {
|
|
||||||
return defaultDatabaseDriver
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range validDatabaseDrivers {
|
|
||||||
// Check if the provided database corresponds to this entry
|
|
||||||
if v == db {
|
|
||||||
// This is a valid database type
|
|
||||||
return db
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No matches
|
|
||||||
return defaultDatabaseDriver
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetConn() (*sql.DB, error) {
|
|
||||||
|
|
||||||
// TODO: Implement sqlite properly.
|
|
||||||
return GetMysqlConn()
|
|
||||||
|
|
||||||
// Check what kind of database we are looking for
|
|
||||||
// dbConnType := getDbType()
|
|
||||||
|
|
||||||
// if dbConnType == `mysql` {
|
|
||||||
// return GetMysqlConn()
|
|
||||||
// } else {
|
|
||||||
// return GetLiteConn()
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSqliteDatabasePath() string {
|
|
||||||
return "main.db"
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetLiteConn() (*sql.DB, error) {
|
|
||||||
// Declare the database file name
|
|
||||||
dbFile := GetSqliteDatabasePath()
|
|
||||||
|
|
||||||
db, err := sql.Open("sqlite3", dbFile)
|
|
||||||
if err != nil {
|
|
||||||
println("Error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return db, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetMysqlString() string {
|
|
||||||
|
|
||||||
user := os.Getenv("MYSQL_USER")
|
|
||||||
password := os.Getenv("MYSQL_PASSWORD")
|
|
||||||
dburl := os.Getenv("MYSQL_URL")
|
|
||||||
dbname := os.Getenv("MYSQL_DATABASE")
|
|
||||||
|
|
||||||
return fmt.Sprintf("mysql://%s:%s@tcp(%s:3306)/%s", user, password, dburl, dbname)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetMysqlConn() (*sql.DB, error) {
|
|
||||||
|
|
||||||
user := os.Getenv("MYSQL_USER")
|
|
||||||
password := os.Getenv("MYSQL_PASSWORD")
|
|
||||||
dburl := os.Getenv("MYSQL_URL")
|
|
||||||
dbname := os.Getenv("MYSQL_DATABASE")
|
|
||||||
|
|
||||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", user, password, dburl, dbname))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set options
|
|
||||||
db.SetConnMaxLifetime(time.Minute * 5)
|
|
||||||
db.SetMaxOpenConns(10)
|
|
||||||
db.SetMaxIdleConns(10)
|
|
||||||
|
|
||||||
return db, nil
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/golang-migrate/migrate/v4"
|
|
||||||
|
|
||||||
_ "github.com/golang-migrate/migrate/v4/database/mysql"
|
|
||||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MigrateMysql() error {
|
|
||||||
|
|
||||||
m, err := migrate.New(
|
|
||||||
"file://db/migrations/",
|
|
||||||
GetMysqlString(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Migrate
|
|
||||||
err = m.Up()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run migrations to ensure tables exist
|
|
||||||
func MigrationUpdate() *migrate.Logger {
|
|
||||||
// Get the path to the sqlite database
|
|
||||||
databasePath := fmt.Sprintf("sqlite://%s", GetSqliteDatabasePath())
|
|
||||||
|
|
||||||
// Try and create a new migration
|
|
||||||
m, err := migrate.New(
|
|
||||||
"file://../db/migrations_sqlite",
|
|
||||||
databasePath,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// End the whole thing if migrations fail
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the update
|
|
||||||
err = m.Up()
|
|
||||||
m.Run()
|
|
||||||
|
|
||||||
m.Force(1)
|
|
||||||
|
|
||||||
return &m.Log
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"github.com/JustKato/FreePad/controllers/post"
|
|
||||||
"github.com/JustKato/FreePad/helper"
|
|
||||||
"github.com/JustKato/FreePad/models/database"
|
|
||||||
"github.com/JustKato/FreePad/types"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/skip2/go-qrcode"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ApiRoutes(route *gin.RouterGroup) {
|
|
||||||
|
|
||||||
// Bind the rate limiter
|
|
||||||
helper.BindRateLimiter(route)
|
|
||||||
|
|
||||||
route.POST("/post", func(ctx *gin.Context) {
|
|
||||||
// Get the name of the post
|
|
||||||
postName := ctx.PostForm("name")
|
|
||||||
// Get the content of the post
|
|
||||||
postContent := ctx.PostForm("content")
|
|
||||||
|
|
||||||
// Try and run migrations
|
|
||||||
err := database.MigrateMysql()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error")
|
|
||||||
fmt.Println(err)
|
|
||||||
fmt.Println("Error")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create my post
|
|
||||||
myPost, err := post.Create(postName, postContent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error", err)
|
|
||||||
ctx.JSON(400, types.FreeError{
|
|
||||||
Error: err.Error(),
|
|
||||||
Message: "There has been an error processing your request",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"message": "Post succesfully created",
|
|
||||||
"post": myPost,
|
|
||||||
"link": fmt.Sprintf("%s/%s", helper.GetDomainBase(), url.QueryEscape(myPost.Name)),
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
route.GET("/post", func(ctx *gin.Context) {
|
|
||||||
// Get the name of the post
|
|
||||||
postName := ctx.PostForm("name")
|
|
||||||
|
|
||||||
myPost, err := post.Retrieve(postName)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error", err)
|
|
||||||
ctx.JSON(400, types.FreeError{
|
|
||||||
Error: err.Error(),
|
|
||||||
Message: "There has been an error processing your request",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the post list
|
|
||||||
ctx.JSON(200, myPost)
|
|
||||||
})
|
|
||||||
|
|
||||||
route.GET("/posts", func(ctx *gin.Context) {
|
|
||||||
// Return the post list
|
|
||||||
ctx.JSON(200, post.GetPostList())
|
|
||||||
})
|
|
||||||
|
|
||||||
// Add in health checks
|
|
||||||
route.GET("/health", healthCheck)
|
|
||||||
|
|
||||||
route.POST("/qr", func(ctx *gin.Context) {
|
|
||||||
|
|
||||||
// Get the name of the post
|
|
||||||
link := ctx.PostForm("link")
|
|
||||||
|
|
||||||
// store the png somewhere
|
|
||||||
var png []byte
|
|
||||||
|
|
||||||
// Encode the link into a qr code
|
|
||||||
png, err := qrcode.Encode(link, qrcode.High, 512)
|
|
||||||
if err != nil {
|
|
||||||
ctx.JSON(200, types.FreeError{
|
|
||||||
Error: fmt.Sprint(err),
|
|
||||||
Message: "Failed to convert qr Code",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the png to the response
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"message": "Succesfully generated the QR",
|
|
||||||
"qr": "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(png),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func healthCheck(ctx *gin.Context) {
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"message": "Healthy",
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/JustKato/FreePad/controllers/post"
|
|
||||||
"github.com/JustKato/FreePad/helper"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func HomeRoutes(router *gin.Engine) {
|
|
||||||
|
|
||||||
router.GET("/", func(c *gin.Context) {
|
|
||||||
c.HTML(200, "index.html", gin.H{
|
|
||||||
"title": "HomePage",
|
|
||||||
"domain_base": helper.GetDomainBase(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.GET("/:post", func(c *gin.Context) {
|
|
||||||
// Get the post we are looking for.
|
|
||||||
postName := c.Param("post")
|
|
||||||
|
|
||||||
// Try and get this post's data
|
|
||||||
postData, err := post.Retrieve(postName)
|
|
||||||
if err != nil {
|
|
||||||
postData = &post.Post{
|
|
||||||
Name: postName,
|
|
||||||
Content: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.HTML(200, "page.html", gin.H{
|
|
||||||
"title": postName,
|
|
||||||
"post_content": postData.Content,
|
|
||||||
"domain_base": helper.GetDomainBase(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package types
|
|
||||||
|
|
||||||
type FreeError struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 780 B After Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 1021 B After Width: | Height: | Size: 1021 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |