Skip to content

Commit

Permalink
Initial support for subpath go-shiori#39
Browse files Browse the repository at this point in the history
  • Loading branch information
RadhiFadlillah committed Oct 7, 2019
1 parent 3077c7f commit 99d2793
Show file tree
Hide file tree
Showing 13 changed files with 299 additions and 211 deletions.
29 changes: 28 additions & 1 deletion internal/cmd/serve.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"strings"

"github.com/go-shiori/shiori/internal/webserver"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand All @@ -18,15 +20,40 @@ func serveCmd() *cobra.Command {

cmd.Flags().IntP("port", "p", 8080, "Port used by the server")
cmd.Flags().StringP("address", "a", "", "Address the server listens to")
cmd.Flags().StringP("webroot", "r", "/", "Root path that used by server")

return cmd
}

func serveHandler(cmd *cobra.Command, args []string) {
// Get flags value
port, _ := cmd.Flags().GetInt("port")
address, _ := cmd.Flags().GetString("address")
rootPath, _ := cmd.Flags().GetString("webroot")

// Validate root path
if rootPath == "" {
rootPath = "/"
}

if !strings.HasPrefix(rootPath, "/") {
rootPath = "/" + rootPath
}

if !strings.HasSuffix(rootPath, "/") {
rootPath += "/"
}

// Start server
serverConfig := webserver.Config{
DB: db,
DataDir: dataDir,
ServerAddress: address,
ServerPort: port,
RootPath: rootPath,
}

err := webserver.ServeApp(db, dataDir, address, port)
err := webserver.ServeApp(serverConfig)
if err != nil {
logrus.Fatalf("Server error: %v\n", err)
}
Expand Down
39 changes: 20 additions & 19 deletions internal/view/content.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,53 @@
<html lang="en">

<head>
<title>$$.Title$$ - Shiori - Bookmarks Manager</title>
<base href="$$.RootPath$$">
<title>$$.Book.Title$$ - Shiori - Bookmarks Manager</title>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="/res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="/res/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="res/favicon.ico">

<link href="/css/source-sans-pro.min.css" rel="stylesheet">
<link href="/css/stylesheet.css" rel="stylesheet">
<link href="/css/custom-dialog.css" rel="stylesheet">
<link href="/css/bookmark-item.css" rel="stylesheet">
<link href="css/source-sans-pro.min.css" rel="stylesheet">
<link href="css/stylesheet.css" rel="stylesheet">
<link href="css/custom-dialog.css" rel="stylesheet">
<link href="css/bookmark-item.css" rel="stylesheet">

<script src="/js/dayjs.min.js"></script>
<script src="/js/vue.min.js"></script>
<script src="js/dayjs.min.js"></script>
<script src="js/vue.min.js"></script>
</head>

<body class="night">
<div id="content-scene" :class="{night: appOptions.nightMode}">
<div id="header">
<p id="metadata" v-cloak>Added {{localtime()}}</p>
<p id="title">$$.Title$$</p>
<p id="title">$$.Book.Title$$</p>
<div id="links">
<a href="$$.URL$$" target="_blank" rel="noopener">View Original</a>
$$if .HasArchive$$
<a href="/bookmark/$$.ID$$/archive">View Archive</a>
<a href="$$.Book.URL$$" target="_blank" rel="noopener">View Original</a>
$$if .Book.HasArchive$$
<a href="bookmark/$$.Book.ID$$/archive">View Archive</a>
$$end$$
</div>
</div>
<div id="content" v-pre>
$$html .HTML$$
$$html .Book.HTML$$
</div>
</div>

<script type="module">
// Create initial variable
import basePage from "/js/page/base.js";
import basePage from "./js/page/base.js";

new Vue({
el: '#content-scene',
mixins: [basePage],
data: {
modified: "$$.Modified$$"
modified: "$$.Book.Modified$$"
},
methods: {
localtime() {
Expand Down
54 changes: 27 additions & 27 deletions internal/view/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@
<html lang="en">

<head>
<base href="$$.$$">
<title>Shiori - Bookmarks Manager</title>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="/res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="/res/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="res/favicon.ico">

<link href="/css/source-sans-pro.min.css" rel="stylesheet">
<link href="/css/fontawesome.min.css" rel="stylesheet">
<link href="/css/stylesheet.css" rel="stylesheet">
<link href="/css/custom-dialog.css" rel="stylesheet">
<link href="/css/bookmark-item.css" rel="stylesheet">
<link href="css/source-sans-pro.min.css" rel="stylesheet">
<link href="css/fontawesome.min.css" rel="stylesheet">
<link href="css/stylesheet.css" rel="stylesheet">
<link href="css/custom-dialog.css" rel="stylesheet">
<link href="css/bookmark-item.css" rel="stylesheet">

<script src="/js/vue.min.js"></script>
<script src="/js/url.min.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/url.min.js"></script>
</head>

<body class="night">
Expand Down Expand Up @@ -84,22 +85,21 @@
secondText: "No",
mainClick: () => {
this.dialog.loading = true;
fetch("/api/logout", { method: "post" })
.then(response => {
if (!response.ok) throw response;
return response;
fetch(new URL("api/logout", document.baseURI), {
method: "post"
}).then(response => {
if (!response.ok) throw response;
return response;
}).then(() => {
localStorage.removeItem("shiori-account");
document.cookie = "session-id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
location.href = new URL("login", document.baseURI);
}).catch(err => {
this.dialog.loading = false;
this.getErrorMessage(err).then(msg => {
this.showErrorDialog(msg);
})
.then(() => {
localStorage.removeItem("shiori-account");
document.cookie = "session-id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
location.href = "/login";
})
.catch(err => {
this.dialog.loading = false;
this.getErrorMessage(err).then(msg => {
this.showErrorDialog(msg);
})
});
});
}
});
},
Expand Down
10 changes: 7 additions & 3 deletions internal/view/js/component/bookmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ export default {
},
computed: {
mainURL() {
if (this.hasContent) return `/bookmark/${this.id}/content`;
else if (this.hasArchive) return `/bookmark/${this.id}/archive`;
else return this.url;
if (this.hasContent) {
return new URL(`bookmark/${this.id}/content`, document.baseURI);
} else if (this.hasArchive) {
return new URL(`bookmark/${this.id}/archive`, document.baseURI);
} else {
return this.url;
}
},
hostnameURL() {
var url = new URL(this.url);
Expand Down
4 changes: 2 additions & 2 deletions internal/view/js/page/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default {
}
},
isSessionError(err) {
switch (err.replace(/\(\d+\)/g, "").trim().toLowerCase()) {
switch (err.toString().replace(/\(\d+\)/g, "").trim().toLowerCase()) {
case "session is not exist":
case "session has been expired":
return true
Expand All @@ -101,7 +101,7 @@ export default {
mainClick: () => {
this.dialog.visible = false;
if (sessionError) {
var loginUrl = new Url("/login");
var loginUrl = new Url("login", document.baseURI);
loginUrl.query.dst = window.location.href;

document.cookie = "session-id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
Expand Down
18 changes: 9 additions & 9 deletions internal/view/js/page/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export default {
keyword = keyword.trim().replace(/\s+/g, " ");

// Prepare URL for API
var url = new URL("/api/bookmarks", document.URL);
var url = new URL("api/bookmarks", document.baseURI);
url.search = new URLSearchParams({
keyword: keyword,
tags: tags.join(","),
Expand Down Expand Up @@ -228,7 +228,7 @@ export default {
page: this.page
};

var url = new Url("/");
var url = new Url(document.baseURI);
url.hash = "home";
url.clearQuery();
if (this.page > 1) url.query.page = this.page;
Expand All @@ -239,7 +239,7 @@ export default {

// Fetch tags if requested
if (fetchTags) {
return fetch("/api/tags");
return fetch(new URL("api/tags", document.baseURI));
} else {
this.loading = false;
throw skipFetchTags;
Expand Down Expand Up @@ -408,7 +408,7 @@ export default {
};

this.dialog.loading = true;
fetch("/api/bookmarks", {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "post",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
Expand Down Expand Up @@ -497,7 +497,7 @@ export default {

// Send data
this.dialog.loading = true;
fetch("/api/bookmarks", {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "put",
body: JSON.stringify(book),
headers: { "Content-Type": "application/json" }
Expand Down Expand Up @@ -552,7 +552,7 @@ export default {
secondText: "No",
mainClick: () => {
this.dialog.loading = true;
fetch("/api/bookmarks", {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "delete",
body: JSON.stringify(ids),
headers: { "Content-Type": "application/json" },
Expand Down Expand Up @@ -622,7 +622,7 @@ export default {
};

this.dialog.loading = true;
fetch("/api/cache", {
fetch(new URL("api/cache", document.baseURI), {
method: "put",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
Expand Down Expand Up @@ -700,7 +700,7 @@ export default {
}

this.dialog.loading = true;
fetch("/api/bookmarks/tags", {
fetch(new URL("api/bookmarks/tags", document.baseURI), {
method: "put",
body: JSON.stringify(request),
headers: { "Content-Type": "application/json" },
Expand Down Expand Up @@ -766,7 +766,7 @@ export default {
};

this.dialog.loading = true;
fetch("/api/tag", {
fetch(new URL("api/tag", document.baseURI), {
method: "PUT",
body: JSON.stringify(newData),
headers: { "Content-Type": "application/json" },
Expand Down
6 changes: 3 additions & 3 deletions internal/view/js/page/setting.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default {
if (this.loading) return;

this.loading = true;
fetch("/api/accounts")
fetch(new URL("api/accounts", document.baseURI))
.then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -163,7 +163,7 @@ export default {
}

this.dialog.loading = true;
fetch("/api/accounts", {
fetch(new URL("api/accounts", document.baseURI), {
method: "post",
body: JSON.stringify(request),
headers: {
Expand Down Expand Up @@ -246,7 +246,7 @@ export default {
}

this.dialog.loading = true;
fetch("/api/accounts", {
fetch(new URL("api/accounts", document.baseURI), {
method: "put",
body: JSON.stringify(request),
headers: {
Expand Down
25 changes: 13 additions & 12 deletions internal/view/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
<html lang="en">

<head>
<base href="$$.$$">
<title>Login - Shiori</title>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="/res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="/res/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="res/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="res/apple-touch-icon-144x144.png">
<link rel="icon" type="image/png" href="res/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="res/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/x-icon" href="res/favicon.ico">

<link href="/css/source-sans-pro.min.css" rel="stylesheet">
<link href="/css/fontawesome.min.css" rel="stylesheet">
<link href="/css/stylesheet.css" rel="stylesheet">
<link href="css/source-sans-pro.min.css" rel="stylesheet">
<link href="css/fontawesome.min.css" rel="stylesheet">
<link href="css/stylesheet.css" rel="stylesheet">

<script src="/js/vue.min.js"></script>
<script src="/js/url.min.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/url.min.js"></script>
</head>

<body>
Expand Down Expand Up @@ -82,7 +83,7 @@

// Send request
this.loading = true;
fetch("/api/login", {
fetch(new URL("api/login", document.baseURI), {
method: "post",
body: JSON.stringify({
username: this.username,
Expand All @@ -106,7 +107,7 @@
dstPage = "";
}

var newUrl = new Url(dstUrl || "/");
var newUrl = new Url(dstUrl || document.baseURI);
newUrl.hash = dstPage;
location.href = newUrl;
}).catch(err => {
Expand Down
Loading

0 comments on commit 99d2793

Please sign in to comment.