This commit is contained in:
illyum 2024-09-03 23:36:25 -06:00
commit ddac93a550
2 changed files with 37 additions and 503 deletions

View File

@ -1 +1,37 @@
Just a little for mmaker tool (not safe!!!)
# Just a little for mmaker tool (not safe!!!)
### Pages:
- / | Place to fill out answers
- /manage | Place to manage questions
- /admin | Place to view submited answers
## Cloning the repo:
clone with
```bash
http://proudcircle.xyz/illyum/FormMaker.git
```
cd into the `FormMaker` folder.
Run
```bash
go mod tidy
```
Then you can either use
```bash
go build .
```
to build the binary.
\- or -
```bash
go run .
```
to run the app (This will also produce a binary in a hiden file on your system)
### Limitations:
- Text answers only (ASCI)
- No account authorization (ANYONE can view /admin & /manage)
#### Storage
The site uses an sqlite database in the folder of the app (will be automatically generated). Answers and questions will both be written to this database.

View File

@ -1,502 +0,0 @@
--- O:\Web Development\ErgosThing\admin.html ---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin - Submissions</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<h1>Submitted Answers</h1>
<table>
<tr>
<th>Question</th>
<th>Answer</th>
</tr>
{{range .}}
<tr>
<td>{{.QuestionText}}</td>
<td>{{.Answer}}</td>
</tr>
{{else}}
<tr>
<td colspan="2">No submissions found.</td>
</tr>
{{end}}
</table>
</div>
</body>
</html>
END --- O:\Web Development\ErgosThing\admin.html
--- O:\Web Development\ErgosThing\go.mod ---
module ergosthing
go 1.23.0
require github.com/mattn/go-sqlite3 v1.14.22
END --- O:\Web Development\ErgosThing\go.mod
--- O:\Web Development\ErgosThing\go.sum ---
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
END --- O:\Web Development\ErgosThing\go.sum
--- O:\Web Development\ErgosThing\index.html ---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<h1>Submit Your Information</h1>
<form action="/submit" method="post">
{{range .}}
<label>{{.QuestionText}}:</label>
<input type="{{.QuestionType}}" name="custom_{{.ID}}" required><br><br>
{{end}}
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
END --- O:\Web Development\ErgosThing\index.html
--- O:\Web Development\ErgosThing\main.go ---
package main
import (
"database/sql"
"fmt"
"html/template"
"log"
"net/http"
_ "github.com/mattn/go-sqlite3"
)
type Question struct {
ID int
QuestionText string
QuestionType string
}
var db *sql.DB
func renderForm(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query("SELECT question_text, question_type FROM questions ORDER BY question_order")
if err != nil {
log.Printf("Error fetching questions: %v\n", err)
http.Error(w, "Failed to fetch form questions", http.StatusInternalServerError)
return
}
defer rows.Close()
var questions []Question
for rows.Next() {
var question Question
err := rows.Scan(&question.QuestionText, &question.QuestionType)
if err != nil {
log.Printf("Error scanning question: %v\n", err)
continue
}
questions = append(questions, question)
}
tmpl := template.Must(template.ParseFiles("index.html"))
tmpl.Execute(w, questions)
}
func handleFormSubmit(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
r.ParseForm()
rows, err := db.Query("SELECT id FROM questions")
if err != nil {
log.Printf("Error fetching questions: %v\n", err)
http.Error(w, "Failed to fetch questions", http.StatusInternalServerError)
return
}
defer rows.Close()
var questionID int
for rows.Next() {
err := rows.Scan(&questionID)
if err != nil {
log.Printf("Error scanning question ID: %v\n", err)
continue
}
fieldName := fmt.Sprintf("custom_%d", questionID)
fieldValue := r.FormValue(fieldName)
if fieldValue != "" {
insertQuery := `INSERT INTO answers (question_id, answer) VALUES (?, ?)`
_, err = db.Exec(insertQuery, questionID, fieldValue)
if err != nil {
log.Printf("Error saving answer: %v\n", err)
http.Error(w, "Failed to save answer", http.StatusInternalServerError)
return
}
} else {
log.Printf("No answer found for question %d", questionID)
}
}
fmt.Fprintf(w, "Thank you for your submission!")
}
func handleAdmin(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query(`
SELECT q.question_text, a.answer
FROM answers a
JOIN questions q ON a.question_id = q.id
ORDER BY q.question_order
`)
if err != nil {
log.Printf("Error fetching submissions: %v\n", err)
http.Error(w, "Failed to fetch submissions", http.StatusInternalServerError)
return
}
defer rows.Close()
var submissions []struct {
QuestionText string
Answer string
}
for rows.Next() {
var submission struct {
QuestionText string
Answer string
}
err := rows.Scan(&submission.QuestionText, &submission.Answer)
if err != nil {
log.Printf("Error scanning submission: %v\n", err)
continue
}
submissions = append(submissions, submission)
}
tmpl := template.Must(template.ParseFiles("admin.html"))
tmpl.Execute(w, submissions)
}
func handleAddQuestion(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
r.ParseForm()
questionText := r.FormValue("question_text")
insertQuery := `INSERT INTO questions (question_text, question_type, question_order) VALUES (?, 'text', (SELECT IFNULL(MAX(question_order), 0) + 1 FROM questions));`
_, err := db.Exec(insertQuery, questionText)
if err != nil {
log.Printf("Error adding new question: %v\n", err)
http.Error(w, "Failed to add question", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/manage", http.StatusSeeOther)
}
func handleManage(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query("SELECT id, question_text, question_type FROM questions ORDER BY question_order")
if err != nil {
log.Printf("Error fetching questions: %v\n", err)
http.Error(w, "Failed to fetch questions", http.StatusInternalServerError)
return
}
defer rows.Close()
var questions []Question
for rows.Next() {
var question Question
err := rows.Scan(&question.ID, &question.QuestionText, &question.QuestionType)
if err != nil {
log.Printf("Error scanning question: %v\n", err)
continue
}
questions = append(questions, question)
}
if len(questions) == 0 {
log.Println("No questions found")
}
tmpl := template.Must(template.ParseFiles("manage.html"))
err = tmpl.Execute(w, questions)
if err != nil {
log.Printf("Error executing template: %v\n", err)
}
}
func handleRemoveQuestion(w http.ResponseWriter, r *http.Request) {
questionID := r.URL.Query().Get("id")
deleteQuery := `DELETE FROM questions WHERE id = ?`
_, err := db.Exec(deleteQuery, questionID)
if err != nil {
log.Printf("Error removing question: %v\n", err)
http.Error(w, "Failed to remove question", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/manage", http.StatusSeeOther)
}
func main() {
var err error
db, err = sql.Open("sqlite3", "./formdata.db")
if err != nil {
log.Fatal(err)
}
createTableQueries := `
CREATE TABLE IF NOT EXISTS questions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
question_text TEXT NOT NULL,
question_type TEXT NOT NULL DEFAULT 'text',
question_order INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS answers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
question_id INTEGER NOT NULL,
answer TEXT NOT NULL,
FOREIGN KEY (question_id) REFERENCES questions(id)
);
`
_, err = db.Exec(createTableQueries)
if err != nil {
log.Fatal(err)
return
}
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.HandleFunc("/", renderForm)
http.HandleFunc("/submit", handleFormSubmit)
http.HandleFunc("/admin", handleAdmin)
http.HandleFunc("/manage", handleManage)
http.HandleFunc("/manage/add", handleAddQuestion)
http.HandleFunc("/manage/remove", handleRemoveQuestion)
fmt.Println("Server started at :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
END --- O:\Web Development\ErgosThing\main.go
--- O:\Web Development\ErgosThing\manage.html ---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Questions</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<h1>Manage Questions</h1>
<h2>Add New Question</h2>
<form action="/manage/add" method="post">
<label for="question_text">Question Text:</label>
<input type="text" id="question_text" name="question_text" required><br><br>
<input type="submit" value="Add Question">
</form>
<h2>Existing Questions</h2>
<table>
<tr>
<th>Question Text</th>
<th>Actions</th>
</tr>
{{range .}}
<tr>
<td>{{.QuestionText}}</td>
<td><a href="/manage/remove?id={{.ID}}">Remove</a></td>
</tr>
{{else}}
<tr>
<td colspan="2">No questions found.</td>
</tr>
{{end}}
</table>
</div>
</body>
</html>
END --- O:\Web Development\ErgosThing\manage.html
--- O:\Web Development\ErgosThing\typer.py ---
import os
import sys
from pathspec import PathSpec
from pathspec.patterns import GitWildMatchPattern
def load_gitignore_patterns(gitignore_file):
with open(gitignore_file, 'r') as f:
lines = f.readlines()
spec = PathSpec.from_lines(GitWildMatchPattern, lines)
return spec
def print_file_content(file_path, output_file):
with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
content = file.read()
output = f"\n--- {file_path} ---\n{content}\nEND --- {file_path}\n"
print(output)
with open(output_file, 'a', encoding='utf-8') as out_file:
out_file.write(output)
def walk_and_print(directory, spec, gitignore_path, output_file, exclude_cmakelists):
# Overwrite the output file if it exists
if os.path.exists(output_file):
os.remove(output_file)
for root, dirs, files in os.walk(directory):
# Always ignore 'assets' and 'art' directories
dirs[:] = [d for d in dirs if d not in ('assets', 'art') and not spec.match_file(os.path.relpath(os.path.join(root, d), directory))]
files = [f for f in files if not spec.match_file(os.path.relpath(os.path.join(root, f), directory))]
if exclude_cmakelists:
files = [f for f in files if f != 'CMakeLists.txt']
for file_name in files:
file_path = os.path.join(root, file_name)
# Exclude the .gitignore file itself from being printed
if os.path.abspath(file_path) != os.path.abspath(gitignore_path):
print_file_content(file_path, output_file)
if __name__ == "__main__":
current_directory = os.getcwd()
gitignore_path = os.path.join(current_directory, '.gitignore')
output_file_path = os.path.join(current_directory, 'output.txt')
exclude_cmakelists = '-nocmake' in sys.argv
if os.path.exists(gitignore_path):
spec = load_gitignore_patterns(gitignore_path)
else:
spec = PathSpec([]) # Empty spec if no .gitignore is found
walk_and_print(current_directory, spec, gitignore_path, output_file_path, exclude_cmakelists)
END --- O:\Web Development\ErgosThing\typer.py
--- O:\Web Development\ErgosThing\static\style.css ---
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 0;
}
.container {
width: 80%;
margin: 0 auto;
padding: 20px;
background-color: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-top: 50px;
border-radius: 10px;
}
h1 {
text-align: center;
color: #333;
}
form {
margin: 20px 0;
}
form label {
display: block;
margin-bottom: 10px;
font-weight: bold;
color: #555;
}
form input[type="text"], form input[type="email"], form textarea {
width: 100%;
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
}
form input[type="submit"] {
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
form input[type="submit"]:hover {
background-color: #218838;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 10px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
td {
background-color: white;
}
a {
color: #007bff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
END --- O:\Web Development\ErgosThing\static\style.css