Compare commits
No commits in common. "29e1e11c63283c80aa142ac38de2d2d68830c721" and "b345b0e467446872b7d6ed203bdb11903d9d6bbb" have entirely different histories.
29e1e11c63
...
b345b0e467
11
INSTALL.md
11
INSTALL.md
@ -1,11 +0,0 @@
|
|||||||
# Installation
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ git clone git://git.chaotic.ninja/yakumo_izuru/mai
|
|
||||||
$ cd mai
|
|
||||||
$ make
|
|
||||||
# make PREFIX=/usr/local install
|
|
||||||
```
|
|
||||||
* Read the [mai.ini(5)](mai.ini.5) manual page
|
|
||||||
* Use any web server than is able to reverse proxy, like [Apache](https://httpd.apache.org), [h2o](https://h2o.examp1e.net), or [NGINX](https://www.nginx.com).
|
|
||||||
* Examples are provided on the repository
|
|
@ -1,6 +0,0 @@
|
|||||||
# List of known instances
|
|
||||||
|
|
||||||
| Name | Cloudflare? | Country | URL | Engines supported |
|
|
||||||
|---------------------------------------------|-------------|---------|--------------------------|-------------------|
|
|
||||||
| Chaotic Ninja Communication Network Limited | No | Germany | https://tr.chaotic.ninja | Google, Reverso |
|
|
||||||
| | | | | |
|
|
9
LEGAL.md
9
LEGAL.md
@ -1,9 +0,0 @@
|
|||||||
Mai does not host any content. All content shown on any Mai instances is from [Google Translate](https://translate.google.com), [Reverso](https://www.reverso.net/), and [LibreTranslate](https://libretranslate.com)
|
|
||||||
|
|
||||||
Mai is not affiliated with none of the above, which this program relays.
|
|
||||||
|
|
||||||
Trademarks belong to their respective owners.
|
|
||||||
Google Translate is a trademark of [Google LLC](https://www.google.com). Reverso is a trademark of Reverso, et cetera.
|
|
||||||
|
|
||||||
The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect.
|
|
||||||
|
|
8
Makefile
8
Makefile
@ -1,10 +1,10 @@
|
|||||||
|
GO ?= go
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
GOFLAGS ?= -v -ldflags "-w -X `go list`.Version=${VERSION} -X `go list`.Commit=${COMMIT}"
|
GOFLAGS ?= -v -ldflags "-w -X `${GO} list`.Version=${VERSION}"
|
||||||
VERSION = `git describe --abbrev=0 --tags 2>/dev/null || echo "VERSION"`
|
VERSION ?= 2025.04.17
|
||||||
COMMIT = `git rev-parse --short HEAD || echo "COMMIT"`
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build ${GOFLAGS} ./cmd/mai
|
${GO} build ${GOFLAGS} ./cmd/mai
|
||||||
clean:
|
clean:
|
||||||
rm -f mai
|
rm -f mai
|
||||||
install:
|
install:
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"marisa.chaotic.ninja/mai"
|
"mahou-no-mori.yakumo.dev/mai"
|
||||||
"marisa.chaotic.ninja/mai/engines"
|
"mahou-no-mori.yakumo.dev/mai/engines"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/favicon"
|
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||||
@ -24,36 +24,38 @@ import (
|
|||||||
)
|
)
|
||||||
var (
|
var (
|
||||||
configfile string
|
configfile string
|
||||||
groupname string
|
verbose bool
|
||||||
username string
|
|
||||||
)
|
)
|
||||||
var conf struct {
|
var conf struct {
|
||||||
danmaku int
|
group string
|
||||||
listen string
|
listen string
|
||||||
staticpath string
|
requests int
|
||||||
tmplpath string
|
static string
|
||||||
|
templates string
|
||||||
|
user string
|
||||||
}
|
}
|
||||||
func MaiSkipLimiter(c *fiber.Ctx) bool {
|
func MaiSkipLimiter(c *fiber.Ctx) bool {
|
||||||
// Paths listed here are not considered for rate limiting
|
// Paths listed here are not considered for rate limiting
|
||||||
path := c.Path()
|
path := c.Path()
|
||||||
return strings.HasPrefix(path, "/static") ||
|
return strings.HasPrefix(path, "/static")
|
||||||
strings.HasPrefix(path, "/docs")
|
|
||||||
}
|
}
|
||||||
func main() {
|
func main() {
|
||||||
parseFlags()
|
parseFlags()
|
||||||
|
|
||||||
|
conf.listen = "127.0.0.1:5000"
|
||||||
|
conf.requests = 5
|
||||||
|
conf.static = "./static"
|
||||||
|
conf.templates = "./views"
|
||||||
|
|
||||||
if configfile != "" {
|
if configfile != "" {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Reading configuration from %s", configfile)
|
||||||
|
}
|
||||||
readConf(configfile)
|
readConf(configfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default settings
|
if conf.user != "" {
|
||||||
conf.danmaku = 10
|
uid, gid, err := usergroupids(conf.user, conf.group)
|
||||||
conf.listen = "127.0.0.1:5000"
|
|
||||||
conf.staticpath = "./static"
|
|
||||||
conf.tmplpath = "./views"
|
|
||||||
|
|
||||||
if username != "" {
|
|
||||||
uid, gid, err := usergroupids(username, groupname)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -61,7 +63,7 @@ func main() {
|
|||||||
syscall.Setgid(gid)
|
syscall.Setgid(gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
engine := html.New(conf.tmplpath, ".html")
|
engine := html.New(conf.templates, ".html")
|
||||||
engine.AddFunc("inc", func(i int) int { return i + 1 })
|
engine.AddFunc("inc", func(i int) int { return i + 1 })
|
||||||
|
|
||||||
server := fiber.New(
|
server := fiber.New(
|
||||||
@ -85,7 +87,7 @@ func main() {
|
|||||||
|
|
||||||
server.Use(favicon.New(
|
server.Use(favicon.New(
|
||||||
favicon.Config{
|
favicon.Config{
|
||||||
File: conf.staticpath + "/favicon.ico",
|
File: conf.static + "/favicon.ico",
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ func main() {
|
|||||||
|
|
||||||
server.Use(limiter.New(limiter.Config{
|
server.Use(limiter.New(limiter.Config{
|
||||||
Next: MaiSkipLimiter,
|
Next: MaiSkipLimiter,
|
||||||
Max: conf.danmaku,
|
Max: conf.requests,
|
||||||
Expiration: 30 * time.Second,
|
Expiration: 30 * time.Second,
|
||||||
LimiterMiddleware: limiter.SlidingWindow{},
|
LimiterMiddleware: limiter.SlidingWindow{},
|
||||||
LimitReached: func(c *fiber.Ctx) error {
|
LimitReached: func(c *fiber.Ctx) error {
|
||||||
@ -296,7 +298,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
server.Get("/toomanyrequests", func(c *fiber.Ctx) error {
|
server.Get("/toomanyrequests", func(c *fiber.Ctx) error {
|
||||||
return c.SendFile(conf.tmplpath + "/429.html")
|
return c.SendFile(conf.templates + "/429.html")
|
||||||
return c.SendStatus(429)
|
return c.SendStatus(429)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -325,13 +327,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
return c.Redirect("/")
|
return c.Redirect("/")
|
||||||
})
|
})
|
||||||
server.Static("/static", conf.staticpath, fiber.Static{
|
server.Static("/static", conf.static, fiber.Static{
|
||||||
Compress: true,
|
|
||||||
ByteRange: true,
|
ByteRange: true,
|
||||||
Browse: true,
|
Browse: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
server.Static("/docs", "./docs", fiber.Static{})
|
|
||||||
|
|
||||||
server.Listen(conf.listen)
|
server.Listen(conf.listen)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
func parseFlags() {
|
func parseFlags() {
|
||||||
flag.StringVar(&configfile, "f", "", "Configuration file")
|
flag.StringVar(&configfile, "f", "", "Configuration file")
|
||||||
flag.StringVar(&username, "u", "", "Sets the user to which privilege dropping is done")
|
flag.BoolVar(&verbose, "v", false, "Be verbose")
|
||||||
flag.StringVar(&groupname, "g", "", "Sets the group to which privilege dropping is done")
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,13 @@ func readConf(file string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conf.danmaku, _ = cfg.Section("mai").Key("danmaku").Int()
|
|
||||||
conf.listen = cfg.Section("mai").Key("listen").String()
|
|
||||||
conf.staticpath = cfg.Section("mai").Key("static").String()
|
|
||||||
conf.tmplpath = cfg.Section("mai").Key("templates").String()
|
|
||||||
|
|
||||||
|
conf.group = cfg.Section("mai").Key("group").String()
|
||||||
|
conf.listen = cfg.Section("http").Key("listen").String()
|
||||||
|
conf.requests, _ = cfg.Section("http").Key("requests").Int()
|
||||||
|
conf.static = cfg.Section("paths").Key("static").String()
|
||||||
|
conf.templates = cfg.Section("paths").Key("templates").String()
|
||||||
|
conf.user = cfg.Section("mai").Key("user").String()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "//W3C DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="/docs/style.css">
|
|
||||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
|
||||||
<meta name="author" content="Izuru Yakumo">
|
|
||||||
<title>API Documentation | Mai</title>
|
|
||||||
</head>
|
|
||||||
<body id="body">
|
|
||||||
<h1>API documentation</h1>
|
|
||||||
<table border="1" align="center">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="get">[GET] /api/translate</h2>
|
|
||||||
<h2 class="post">[POST] /api/translate</h2>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>Translation endpoint, input must be URL-encoded (e.g. multi-byte characters, words separated by space)</p>
|
|
||||||
<h3>Arguments</h3>
|
|
||||||
<ul>
|
|
||||||
<li>engine</li>
|
|
||||||
<li>from</li>
|
|
||||||
<li>text</li>
|
|
||||||
<li>to</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="get">[GET] /api/source_languages</h2>
|
|
||||||
<h2 class="get">[GET] /api/target_languages</h2>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>Get a JSON array of supported source and target languages for a particular engine</p>
|
|
||||||
<h3>Arguments</h3>
|
|
||||||
<ul>
|
|
||||||
<li>engine</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="get">[GET] /api/tts</h2>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>Obtain text-to-speech audio files from an engine, provided said engine supports them</p>
|
|
||||||
<h3>Arguments</h3>
|
|
||||||
<ul>
|
|
||||||
<li>engine</li>
|
|
||||||
<li>lang</li>
|
|
||||||
<li>text</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="get">[GET] /robots.txt</h2>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="post">[POST] /switchlanguages</h2>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>Switch between source and target languages, as long as the source language isn't "auto"</p>
|
|
||||||
<p>Must only be called inside the form interface</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<h2 class="get">[GET] /version</h2>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>Return the software version as a JSON array</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="/docs/style.css">
|
|
||||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
|
||||||
<meta name="author" content="Izuru Yakumo">
|
|
||||||
<title>Mai | Documentation</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<tr><td>
|
|
||||||
<table border="1" align="left">
|
|
||||||
<tr>
|
|
||||||
<td><a href="/docs/api">API</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</tr></td>
|
|
||||||
<tr><td>
|
|
||||||
<table border="1" align="center">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>Welcome to Mai's documentation!<p>
|
|
||||||
<p>See the menu for the available entries</p>
|
|
||||||
<p>Anything else is covered by the man pages</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
body {
|
|
||||||
background-color: #f8cfd2;
|
|
||||||
color: rgb(206, 147, 191);
|
|
||||||
}
|
|
||||||
|
|
||||||
a, a:visited {
|
|
||||||
color: rgb(206, 147, 191);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (prefers-color-scheme: dark) {
|
|
||||||
body {
|
|
||||||
background-color: #700000;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
a, a:visited {
|
|
||||||
color: #18c018;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-color: white;
|
|
||||||
}
|
|
19
example/mai.apache.conf
Normal file
19
example/mai.apache.conf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName mai.example.com
|
||||||
|
ServerAlias mai.example.com
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteCond %{SERVER_NAME} =mai.example.com
|
||||||
|
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
|
||||||
|
</VirtualHost>
|
||||||
|
<VirtualHost *:443>
|
||||||
|
ServerName mai.example.com
|
||||||
|
ServerAlias mai.example.com
|
||||||
|
SSLEngine on
|
||||||
|
SSLCertificateFile /usr/pkg/etc/letsencrypt/live/example.com/fullchain.pem
|
||||||
|
SSLCertificateKeyFile /usr/pkg/etc/letsencrypt/live/example.com/privkey.pem
|
||||||
|
ProxyRequests off
|
||||||
|
ProxyPass / http://127.0.0.1:5000/
|
||||||
|
ProxyPassReverse / http://127.0.0.1:5000/
|
||||||
|
ProxyPreserveHost On
|
||||||
|
</VirtualHost>
|
||||||
|
|
@ -1,4 +1,19 @@
|
|||||||
|
[http]
|
||||||
|
# TCP socket to listen on.
|
||||||
|
# Must not be already used by something else.
|
||||||
|
listen = 127.0.0.1:5000
|
||||||
|
# How many requests per minute are allowed
|
||||||
|
# before a rate-limit happens.
|
||||||
|
requests = 10
|
||||||
[mai]
|
[mai]
|
||||||
listen = "127.0.0.1:5000"
|
# Drop privilege to the user and group specified.
|
||||||
rootdir = "./static"
|
# When only the user is specified, the default group of the user will
|
||||||
tmplpath = "./views"
|
# be used.
|
||||||
|
#
|
||||||
|
# user = www
|
||||||
|
# group = www
|
||||||
|
[paths]
|
||||||
|
# Where to locate resources such as CSS, etc
|
||||||
|
static = ./static
|
||||||
|
# Where to locate the pages to be served
|
||||||
|
templates = ./views
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name mai.example.com;
|
server_name mai.example.org;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
@ -11,7 +11,7 @@ server {
|
|||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
listen [::]:443 ssl;
|
listen [::]:443 ssl;
|
||||||
server_name mai.example.com;
|
server_name mai.example.org;
|
||||||
|
|
||||||
ssl_certificate /path/to/fullchain.pem;
|
ssl_certificate /path/to/fullchain.pem;
|
||||||
ssl_certificate_key /path/to/privkey.pem;
|
ssl_certificate_key /path/to/privkey.pem;
|
||||||
|
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
|||||||
module marisa.chaotic.ninja/mai
|
module mahou-no-mori.yakumo.dev/mai
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
|
40
mai.ini.5
40
mai.ini.5
@ -1,40 +0,0 @@
|
|||||||
.Dd $Mdocdate$
|
|
||||||
.Dt MAI.INI 5
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm mai.ini
|
|
||||||
.Nd Configuration file for Mai
|
|
||||||
.Sh OPTIONS
|
|
||||||
.Ss [mai] section
|
|
||||||
.Bl -tag -width 11n
|
|
||||||
.It danmaku (int)
|
|
||||||
Control the maximum amount of requests
|
|
||||||
before a ratelimit happens
|
|
||||||
.It listen (string)
|
|
||||||
HTTP port for the server to listen.
|
|
||||||
Default is "localhost:5000"
|
|
||||||
.It static (string)
|
|
||||||
Directory where the static resources are located.
|
|
||||||
Default is "./static"
|
|
||||||
.It templates (string)
|
|
||||||
Directory where the templates are located.
|
|
||||||
Default is "./views"
|
|
||||||
.El
|
|
||||||
.Sh ENVIRONMENT
|
|
||||||
.Bl -tag -width 11n
|
|
||||||
.It Ev MAI_LIBRETRANSLATE_INSTANCE
|
|
||||||
LibreTranslate instance to use, it's required for the engine to work.
|
|
||||||
.It Ev MAI_LIBRETRANSLATE_API
|
|
||||||
LibreTranslate API key for the above setting, it may or
|
|
||||||
may not be required, depending on the instance.
|
|
||||||
.El
|
|
||||||
.Sh FILES
|
|
||||||
.Pa /usr/local/etc/mai/mai.ini
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr mai 1
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An fattalion
|
|
||||||
.An metalune
|
|
||||||
.An ManeraKai Lk https://manerakai.com
|
|
||||||
.Sh MAINTAINERS
|
|
||||||
.An Izuru Yakumo Aq Mt yakumo.izuru@chaotic.ninja
|
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# $TheSupernovaDuo$
|
# $YakumoLabs$
|
||||||
#
|
#
|
||||||
# PROVIDE: mai
|
# PROVIDE: mai
|
||||||
# REQUIRE: DAEMON NETWORKING syslog
|
# REQUIRE: DAEMON NETWORKING syslog
|
||||||
|
10
rc.d/NetBSD
10
rc.d/NetBSD
@ -1,21 +1,19 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# $TheSupernovaDuo$
|
# $YakumoLabs$
|
||||||
#
|
#
|
||||||
# PROVIDE: mai
|
# PROVIDE: mai
|
||||||
# REQUIRE: NETWORKING DAEMON
|
# REQUIRE: NETWORKING DAEMON
|
||||||
# BEFORE: LOGIN
|
|
||||||
# KEYWORD: shutdown
|
|
||||||
|
|
||||||
$_rc_subr_loaded . /etc/rc.subr
|
$_rc_subr_loaded . /etc/rc.subr
|
||||||
|
|
||||||
name="mai"
|
name="mai"
|
||||||
rcvar=$name
|
rcvar=$name
|
||||||
command="/usr/pkg/bin/mai"
|
command="/usr/local/bin/mai"
|
||||||
command_args="-f /usr/pkg/etc/mai/mai.ini -u www -g www"
|
command_args="-f /usr/local/etc/mai/mai.ini"
|
||||||
pidfile="/var/run/${name}.pid"
|
pidfile="/var/run/${name}.pid"
|
||||||
start_cmd="mai_start"
|
start_cmd="mai_start"
|
||||||
|
|
||||||
required_files="/usr/pkg/etc/mai/mai.ini"
|
required_files="/usr/local/etc/mai/mai.ini"
|
||||||
|
|
||||||
mai_start() {
|
mai_start() {
|
||||||
$command $command_args
|
$command $command_args
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/bin/ksh
|
#!/bin/ksh
|
||||||
# $TheSupernovaDuo$
|
# $YakumoLabs$
|
||||||
|
|
||||||
daemon="/usr/local/bin/mai"
|
daemon="/usr/local/bin/mai"
|
||||||
daemon_flags="-f /usr/local/etc/mai/mai.ini -u www -g www"
|
daemon_flags="-f /usr/local/etc/mai/mai.ini"
|
||||||
|
|
||||||
. /etc/rc.d/rc.subr
|
. /etc/rc.d/rc.subr
|
||||||
|
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini -g www -u www
|
# $YakumoLabs$
|
||||||
|
cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini
|
||||||
cwd: /usr/local/share/mai
|
cwd: /usr/local/share/mai
|
||||||
|
13
rc.d/mai.service
Normal file
13
rc.d/mai.service
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# $YakumoLabs$
|
||||||
|
[Unit]
|
||||||
|
Description=Mai
|
||||||
|
Documentation=https://suzunaan.yakumo.dev/mai
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
ExecStart=/usr/local/bin/mai -f /usr/local/etc/mai/mai.ini
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
4
rc.d/mokou.conf
Normal file
4
rc.d/mokou.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# $YakumoLabs$
|
||||||
|
description=Mai
|
||||||
|
exec=/usr/bin/env daemonize -p /var/run/mai.pid /usr/local/bin/mai -f /usr/local/etc/mai.ini
|
||||||
|
pidfile=/var/run/mai.pid
|
4
rc.d/s6
Normal file
4
rc.d/s6
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/command/execlineb -P
|
||||||
|
# $YakumoLabs$
|
||||||
|
/usr/local/bin/mai
|
||||||
|
-f /usr/local/etc/mai/mai.ini
|
@ -7,12 +7,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
// Version release version
|
// Version release version
|
||||||
Version = "0.0.1"
|
Version = "0.0.1"
|
||||||
|
|
||||||
// Commit will be overwritten automatically by the build system
|
|
||||||
Commit = "HEAD"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FullVersion display the full version and build
|
// FullVersion display the full version and build
|
||||||
func FullVersion() string {
|
func FullVersion() string {
|
||||||
return fmt.Sprintf("%s@%s", Version, Commit)
|
return fmt.Sprintf("%s", Version)
|
||||||
}
|
}
|
||||||
|
@ -126,12 +126,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<br><br><br><br><br>
|
<br><br><br><br><br>
|
||||||
<footer class="center">
|
<footer class="center">
|
||||||
<p>
|
<a href="https://suzunaan.yakumo.dev/mai">Hosted on Suzunaan Software Library</a>
|
||||||
<a href="https://git.chaotic.ninja/yakumo.izuru/mai">Source code</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A <a href="https://mirage.h0stname.net">Mirage AIB</a> project
|
|
||||||
</p>
|
|
||||||
</footer>
|
</footer>
|
||||||
<script src="/static/script.js"></script>
|
<script src="/static/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user