Changed file structure #2

Closed
olived wants to merge 4 commits from olived:go-lang-standard into main
13 changed files with 315 additions and 108 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/tmp
/uploads/*

1
api/Admin.go Normal file
View File

@@ -0,0 +1 @@
package api

58
api/FileHandlers.go Normal file
View File

@@ -0,0 +1,58 @@
package api
import (
"encoding/json"
"net/http"
"os"
"path/filepath"
)
type FileData struct {
ImageNames []string
SpicyImageNames []string
AsciiFiles []AsciiEntry
}
type AsciiEntry struct {
Name string
FontSize int
}
const staticDir = "static"
// move FileData and AsciiEntry here if you want, or leave in main.go
func FileHandler(w http.ResponseWriter, r *http.Request) {
data := FileData{
ImageNames: []string{},
SpicyImageNames: []string{},
AsciiFiles: []AsciiEntry{},
}
files, _ := os.ReadDir(filepath.Join(staticDir, "images"))
for _, file := range files {
fileName := file.Name()
data.ImageNames = append(data.ImageNames, filepath.Join(staticDir, "images", fileName))
}
files, _ = os.ReadDir(filepath.Join("uploads"))
for _, file := range files {
fileName := file.Name()
data.ImageNames = append(data.ImageNames, filepath.Join("uploads", fileName))
}
files, _ = os.ReadDir(filepath.Join(staticDir, "spicy"))
for _, file := range files {
fileName := file.Name()
data.SpicyImageNames = append(data.SpicyImageNames, filepath.Join(staticDir, "spicy", fileName))
}
files, _ = os.ReadDir(filepath.Join(staticDir, "ascii_art"))
for _, file := range files {
fileName := file.Name()
data.AsciiFiles = append(data.AsciiFiles,
AsciiEntry{Name: filepath.Join(staticDir, "ascii_art", fileName), FontSize: 12},
)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}

36
api/UploadHandlers.go Normal file
View File

@@ -0,0 +1,36 @@
package api
import (
"fmt"
"io"
"net/http"
"os"
)
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
file, header, err := r.FormFile("image") // "image" is the name of the file input
if err != nil {
http.Error(w, "Error retrieving file", http.StatusBadRequest)
return
}
defer file.Close()
dst, err := os.Create("./uploads/" + header.Filename)
if err != nil {
http.Error(w, "Error creating file on server", http.StatusInternalServerError)
return
}
defer dst.Close()
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, "Error saving file", http.StatusInternalServerError)
return
}
fmt.Fprint(w, "<script>location.href = '/admin/'</script>")
fmt.Fprintf(w, "Image uploaded successfully: %s", header.Filename)
}

28
main.go
View File

@@ -1,23 +1,24 @@
package main
import (
"Advertisement_Panel/src"
"Advertisement_Panel/api"
"fmt"
"html/template"
"net/http"
)
var templ *template.Template
var templates *template.Template
func main() {
templ, _ = template.ParseGlob("templates/*.html")
templates, _ = template.ParseGlob("website/templates/*.html")
fmt.Print("Now running server!\n")
// Serves index
http.HandleFunc("/", index_handler)
// Serves json for html to find file names
http.HandleFunc("/files", src.FileHandler)
http.HandleFunc("/files", api.FileHandler)
// Serves ascii page
http.HandleFunc("/ascii", ascii_handler)
@@ -25,14 +26,29 @@ func main() {
// Serves images
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("./uploads"))))
// Serves administration page
http.HandleFunc("/admin/", admin_handler)
// Handles image upload
http.HandleFunc("/upload", api.UploadHandler)
fmt.Print("Webserver running on http://localhost:8080\n")
// Serves what ever the user is requesting base on above urls
http.ListenAndServe(":8080", nil)
}
func index_handler(w http.ResponseWriter, r *http.Request) {
templ.ExecuteTemplate(w, "images.html", nil)
templates.ExecuteTemplate(w, "images.html", nil)
}
func ascii_handler(w http.ResponseWriter, r *http.Request) {
templ.ExecuteTemplate(w, "ascii.html", nil)
templates.ExecuteTemplate(w, "ascii.html", nil)
}
func admin_handler(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "admin.html", nil)
}

View File

@@ -1,69 +0,0 @@
package src
import (
"encoding/json"
"net/http"
"os"
"path/filepath"
"strings"
)
const staticDir = "static"
type FileData struct {
ImageNames []string
SpicyImageNames []string
AsciiFiles []AsciiEntry
}
type AsciiEntry struct {
Name string
FontSize int
}
// move FileData and AsciiEntry here if you want, or leave in main.go
func FileHandler(w http.ResponseWriter, r *http.Request) {
data := FileData{
ImageNames: []string{},
SpicyImageNames: []string{},
AsciiFiles: []AsciiEntry{},
}
dirs, err := os.ReadDir(staticDir)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, dir := range dirs {
dirName := dir.Name()
if strings.EqualFold(dirName, "images") {
files, _ := os.ReadDir(filepath.Join(staticDir, dirName))
for _, file := range files {
fileName := file.Name()
data.ImageNames = append(data.ImageNames, filepath.Join(staticDir, dirName, fileName))
}
} else if strings.EqualFold(dirName, "spicy") {
files, _ := os.ReadDir(filepath.Join(staticDir, dirName))
for _, file := range files {
fileName := file.Name()
data.SpicyImageNames = append(data.SpicyImageNames, filepath.Join(staticDir, dirName, fileName))
}
} else if strings.EqualFold(dirName, "ascii_art") {
files, _ := os.ReadDir(filepath.Join(staticDir, dirName))
for _, file := range files {
fileName := file.Name()
data.AsciiFiles = append(data.AsciiFiles,
AsciiEntry{Name: filepath.Join(staticDir, dirName, fileName), FontSize: 12},
)
}
}
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}

67
static/css/admin.css Normal file
View File

@@ -0,0 +1,67 @@
body {
font-family: Arial, sans-serif;
width: 100vw;
height: 100vh;
background: #101010;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.container {
background: #212121;
padding: 24px 32px;
border-radius: 8px;
max-width: 400px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.active {
background-color: #007bff;
color: white;
}
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
max-width: 400px;
background: #121212;
}
nav {
padding: 10px 18px;
border-radius: 8px;
width: 100%;
box-shadow: 0 2px 8px rgba(0,0,0,0.08)
}
h2 {
margin-bottom: 20px;
color: #ccc;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
input[type="file"] {
margin-bottom: 16px;
}
button[type="submit"] {
background: #007bff;
color: #fff;
border: none;
padding: 10px 18px;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
button:hover {
background: #0056b3;
}
.preview {
margin-top: 16px;
max-width: 100%;
max-height: 200px;
display: none;
border: 1px solid #ddd;
border-radius: 4px;
}

22
static/css/global.css Normal file
View File

@@ -0,0 +1,22 @@
body {
margin: 0;
background: black;
display: flex;
justify-content: center;
align-items: center;
color: white;
height: 100vh;
cursor: none;
}
pre {
white-space: pre;
font-family: monospace;
font-size: 14px;
line-height: 1.2;
}
img {
max-width: 100%;
max-height: 100%;
}

71
static/js/admin.js Normal file
View File

@@ -0,0 +1,71 @@
const imageInput = document.getElementById('imageInput');
const preview = document.getElementById('preview');
let currentFile = null;
imageInput.addEventListener('change', function() {
currentFile = this.files[0];
if (currentFile) {
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
preview.style.display = 'block';
}
reader.readAsDataURL(currentFile);
} else {
preview.style.display = 'none';
}
});
document.getElementById('imageForm').addEventListener('submit', function(e) {
e.preventDefault();
// Add your upload logic here
const formData = new FormData();
formData.append('image', currentFile);
if (!currentFile) {
alert('Please select an image to upload.');
return;
}
fetch('/upload', {
method: 'POST',
body: formData
}).then(response => response.text())
.then(data => {
console.log(data);
alert('Image uploaded successfully!');
window.location.reload();
})
.catch(error => {
console.error('Error:', error);
alert('Error uploading image.');
});
});
function openTab(evt, tabNumber) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tab-container");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tab-button");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
console.log("tab-"+tabNumber);
let currentTab = document.getElementById('tab-'+(tabNumber))
if (currentTab) {
currentTab.style.display = "block";
} else throw new Error("Tab not found: " + tabNumber);
currentTab.style.display = "block";
evt.currentTarget.className += " active";
}

BIN
uploads/DSC_0094.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Admin</title>
<link rel="stylesheet" href="/static/css/admin.css">
</head>
<body>
<main>
<nav>
<button class="tab-button" id="button-1" onclick="openTab(event, 1)">Image Upload</button>
<button class="tab-button" id="button-2" onclick="openTab(event, 2)">null</button>
</nav>
<div class="tab-container" id="tab-1">
<div class="container">
<h2>Add New Image</h2>
<form id="imageForm" enctype="multipart/form-data">
<label for="imageInput">Select Image:</label>
<input type="file" id="imageInput" name="image" accept="image/*" required><br>
<button type="submit" style="width: 100%;">Upload</button>
</form>
<img id="preview" class="preview" alt="Image Preview">
</div>
</div>
<div class="tab-container" id="tab-2">
</div>
</main>
<script src="/static/js/admin.js"></script>
</body>
</html>

View File

@@ -5,24 +5,7 @@
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="/static/images/pvv_logo.png">
<title>ASCII</title>
<style>
body {
margin: 0;
background: black;
display: flex;
justify-content: center;
align-items: center;
color: white;
height: 100vh;
}
pre {
white-space: pre;
font-family: monospace;
font-size: 14px;
line-height: 1.2;
}
</style>
<link rel="stylesheet" href="/static/css/global.css">
</head>
<body>

View File

@@ -4,22 +4,8 @@
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="/static/images/pvv_logo.png">
<link rel="stylesheet" href="/static/css/global.css">
<title>IMAGES</title>
<style>
body {
margin: 0;
background: black;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
img {
max-width: 100%;
max-height: 100%;
}
</style>
</head>
<body>
@@ -35,6 +21,9 @@
index = (index + 1) % images.length;
document.getElementById("images").src = images[index];
}, 1000);
setTimeout(() => {
window.location.reload();
}, images.length*2*1000);
});
</script>
</body>