Initial commit
This commit is contained in:
commit
19843f416f
7 changed files with 418 additions and 0 deletions
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
|||
module github.com/ejv2/pajen-site
|
||||
|
||||
go 1.21.5
|
46
index.css
Normal file
46
index.css
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* index.css - Pajenerator stylesheet
|
||||
*/
|
||||
|
||||
body {
|
||||
font: 1.2em/1.62 sans-serif;
|
||||
margin: 1em auto;
|
||||
padding:0 .62em 3.24em;
|
||||
}
|
||||
|
||||
header {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
padding: 4px;
|
||||
min-width: 75%;
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
|
||||
font-weight: bold;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: rgb(25, 135, 84);
|
||||
padding: 6px;
|
||||
margin-top: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
cursor: not-allowed;
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
input.highlight {
|
||||
border: solid medium rgb(13, 202, 240);
|
||||
}
|
||||
|
||||
.loading {
|
||||
cursor: wait !important;
|
||||
}
|
25
index.gohtml
Normal file
25
index.gohtml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pajenerator - The Indian Name Generator!</title>
|
||||
|
||||
<link rel="stylesheet" href="/index.css" />
|
||||
<script src="/index.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="onready()">
|
||||
<center>
|
||||
<header>
|
||||
<h1>Pajenerator - The Indian Name Generator</h1>
|
||||
<hr>
|
||||
</header>
|
||||
|
||||
<label for="name-box">Your randomly generated Indian name is:</label>
|
||||
<br>
|
||||
<input type="text" placeholder="Pajeet" name="name-box" id="name-box" readonly>
|
||||
<br>
|
||||
<button onclick="generate()" id="btn">Do the needful</button>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
123
index.js
Normal file
123
index.js
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* index.js - Pajenerator client code
|
||||
*/
|
||||
|
||||
// State
|
||||
var generating = false;
|
||||
var names = [];
|
||||
var flashcount = 0;
|
||||
var flashinterval;
|
||||
|
||||
// Needed elements
|
||||
let root;
|
||||
let btn;
|
||||
let out;
|
||||
|
||||
function onready()
|
||||
{
|
||||
root = document.querySelector("html")
|
||||
btn = document.querySelector("#btn");
|
||||
out = document.querySelector("#name-box");
|
||||
}
|
||||
|
||||
// Returns the names from the API - as many as are configured.
|
||||
function get_names(onget)
|
||||
{
|
||||
const error_response = ["Errar", "Prablem"];
|
||||
const uri = "/api";
|
||||
let req = new XMLHttpRequest();
|
||||
|
||||
req.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status != 200) {
|
||||
onget(error_response);
|
||||
}
|
||||
|
||||
try {
|
||||
let arr = JSON.parse(this.responseText)
|
||||
onget(arr);
|
||||
} catch {
|
||||
console.log("bad json: "+this.responseText)
|
||||
onget(error_response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.open("GET", uri, true);
|
||||
req.send();
|
||||
}
|
||||
|
||||
/*
|
||||
* 0.2x + 0.2e^(x-27)
|
||||
* where:
|
||||
* x - nth iteration
|
||||
* returns - time in seconds
|
||||
*/
|
||||
function timeout(i)
|
||||
{
|
||||
return (0.2*i) + (0.2*Math.exp(i - 27));
|
||||
}
|
||||
|
||||
function cleanup_generate()
|
||||
{
|
||||
// Reset button text (partially)
|
||||
btn.textContent = "Do the needful";
|
||||
btn.disabled = true;
|
||||
// Reset cursor
|
||||
root.classList.remove("loading");
|
||||
btn.classList.remove("loading");
|
||||
out.classList.remove("loading");
|
||||
|
||||
flashinterval = setInterval(() => {
|
||||
out.classList.toggle("highlight");
|
||||
if (flashcount++ >= 6) {
|
||||
flashcount = 0;
|
||||
generating = false;
|
||||
names = [];
|
||||
|
||||
clearInterval(flashinterval);
|
||||
|
||||
out.classList.remove("highlight");
|
||||
btn.disabled = false;
|
||||
}
|
||||
}, 500)
|
||||
|
||||
}
|
||||
|
||||
function run_generate()
|
||||
{
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
setTimeout(() => {
|
||||
out.value = names[i];
|
||||
if (i == names.length - 1) {
|
||||
cleanup_generate();
|
||||
}
|
||||
}, 1000*timeout(i));
|
||||
}
|
||||
}
|
||||
|
||||
function pull_names(arr)
|
||||
{
|
||||
names = names.concat(arr);
|
||||
if (names.length >= 30) {
|
||||
run_generate();
|
||||
} else {
|
||||
get_names(pull_names)
|
||||
}
|
||||
}
|
||||
|
||||
function generate()
|
||||
{
|
||||
if (generating)
|
||||
return;
|
||||
generating = true;
|
||||
|
||||
// Button text
|
||||
btn.textContent = "Ok sar...!";
|
||||
// Cursors
|
||||
root.classList.add("loading");
|
||||
btn.classList.add("loading");
|
||||
out.classList.add("loading");
|
||||
|
||||
get_names(pull_names);
|
||||
}
|
79
main.go
Normal file
79
main.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Server configs.
|
||||
var (
|
||||
listenAddr = flag.String("listen", "0.0.0.0:80", "Listen address for server, in the form addr:port")
|
||||
scriptPath = flag.String("script", "./pajen.pl", "The relative path to pajen.pl. Must be executable!")
|
||||
apiQty = flag.Int("quantity", 5, "The number of names returned at a time from the API")
|
||||
)
|
||||
|
||||
var (
|
||||
pajen *Pajen
|
||||
indexTmpl = template.Must(template.ParseFiles("index.gohtml"))
|
||||
)
|
||||
|
||||
func handleRoot(w http.ResponseWriter, r *http.Request) {
|
||||
if r.RequestURI != "/" {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("404 not found"))
|
||||
return
|
||||
}
|
||||
|
||||
indexTmpl.Execute(w, nil)
|
||||
}
|
||||
|
||||
func handleAPI(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" || r.RequestURI != "/api" {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("404 not found"))
|
||||
return
|
||||
}
|
||||
|
||||
a := make([]string, 0, *apiQty)
|
||||
for i := 0; i < *apiQty; i++ {
|
||||
a = append(a, <-pajen.Chan)
|
||||
}
|
||||
|
||||
b, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
b, _ = json.Marshal(map[string]any{
|
||||
"status": "Failed",
|
||||
"error": err,
|
||||
})
|
||||
}
|
||||
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Println("Starting pajen.pl frontend - the famous indian name generator")
|
||||
flag.Parse()
|
||||
|
||||
p, err := NewPajen(*scriptPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pajen = p
|
||||
|
||||
http.HandleFunc("/", handleRoot)
|
||||
http.HandleFunc("/api", handleAPI)
|
||||
http.HandleFunc("/index.css", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "index.css")
|
||||
})
|
||||
http.HandleFunc("/index.js", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "index.js")
|
||||
})
|
||||
|
||||
if err := http.ListenAndServe(*listenAddr, nil); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
72
pajen.go
Normal file
72
pajen.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pajen represents an instance of the pajen.pl script running in infinite
|
||||
// generation mode.
|
||||
type Pajen struct {
|
||||
Chan chan string
|
||||
|
||||
proc *exec.Cmd
|
||||
out io.ReadCloser
|
||||
}
|
||||
|
||||
// NewPajen starts the pajen script at the path given.
|
||||
func NewPajen(path string) (*Pajen, error) {
|
||||
p := new(Pajen)
|
||||
|
||||
p.proc = exec.Command("/usr/bin/perl", path, "-i")
|
||||
p.proc.Stdin = p
|
||||
|
||||
pi, err := p.proc.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pajen: pipe pajen.pl: %w", err)
|
||||
}
|
||||
p.out = pi
|
||||
p.proc.Stderr = p.proc.Stdout
|
||||
|
||||
p.Chan = make(chan string)
|
||||
|
||||
if err := p.proc.Start(); err != nil {
|
||||
return nil, fmt.Errorf("pajen: start pajen.pl: %w", err)
|
||||
}
|
||||
|
||||
go p.run()
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Read feeds constant newlines to the program.
|
||||
func (r *Pajen) Read(b []byte) (int, error) {
|
||||
if len(b) < 1 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return copy(b, []byte("\n")), nil
|
||||
}
|
||||
|
||||
func (r *Pajen) run() {
|
||||
buf := make([]byte, 255)
|
||||
|
||||
for {
|
||||
_, err := r.out.Read(buf)
|
||||
if err != nil {
|
||||
log.Println("pajen read error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
wk := string(buf)
|
||||
lines := strings.Split(wk, "\n")
|
||||
|
||||
for _, l := range lines {
|
||||
if l != "" && l != "\n" {
|
||||
r.Chan <- l
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
pajen.pl
Executable file
70
pajen.pl
Executable file
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/perl
|
||||
# Pajeet name generator (pajen.pl)
|
||||
# Written by Ethan Marshall - 2024
|
||||
# Material from https://desu-usergeneratedcontent.xyz/g/image/1705/80/1705808467048.png
|
||||
|
||||
use strict;
|
||||
use diagnostics;
|
||||
use warnings;
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
# Generated names consist of a prefix followed by a suffix
|
||||
our @prefixes = (
|
||||
"Pa",
|
||||
"Ra",
|
||||
"Ab",
|
||||
"A",
|
||||
"Na",
|
||||
"Vi",
|
||||
"Pra",
|
||||
"Ku",
|
||||
"Gi",
|
||||
"Ha",
|
||||
"San",
|
||||
"Bel"
|
||||
);
|
||||
|
||||
our @suffixes = (
|
||||
"jeet",
|
||||
"kesh",
|
||||
"hul",
|
||||
"jeesh",
|
||||
"jesh",
|
||||
"mit",
|
||||
"mit",
|
||||
"hesh",
|
||||
"raj",
|
||||
"nil",
|
||||
"jith",
|
||||
"tik"
|
||||
);
|
||||
|
||||
sub fatal {
|
||||
printf("%s\n", $_[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub usage {
|
||||
fatal("Usage: pajen [-n count] [-ihu]")
|
||||
}
|
||||
|
||||
# Command line options
|
||||
my $count = 1;
|
||||
my $infinite = '';
|
||||
GetOptions(
|
||||
'number=i' => \$count,
|
||||
"infinite" => \$infinite,
|
||||
"help|usage" => sub { usage() }
|
||||
) or usage();
|
||||
|
||||
for (my $i = 0; $i < $count || $infinite; $i++) {
|
||||
my $prefix = int(rand(@prefixes));
|
||||
my $suffix = int(rand(@suffixes));
|
||||
|
||||
printf("%s%s\n", $prefixes[$prefix], $suffixes[$suffix]);
|
||||
|
||||
if ($infinite) {
|
||||
(<stdin> eq "q\n") && exit(0);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue