mirror of https://gitlab.com/ngerakines/tavern.git
parent
aa11f2ca15
commit
dd34ac6316
|
@ -23,3 +23,7 @@ func ObjectRepliesURL(domain string, objectID interface{}) string {
|
|||
func ObjectRepliesPageURL(domain string, objectID interface{}, page int) string {
|
||||
return fmt.Sprintf("https://%s/object/%s/replies?page=%d", domain, objectID, page)
|
||||
}
|
||||
|
||||
func TagURL(domain string, objectID interface{}) string {
|
||||
return fmt.Sprintf("https://%s/tag/%s", domain, objectID)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by herr at 2020-03-24 13:33:44.957849681 -0400 EDT m=+0.009274100
|
||||
// This file was generated by herr at 2020-03-25 10:47:33.846856734 -0400 EDT m=+0.008849068
|
||||
package errors
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by herr at 2020-03-24 13:33:44.982147915 -0400 EDT m=+0.033572306
|
||||
// This file was generated by herr at 2020-03-25 10:47:33.873538567 -0400 EDT m=+0.035530881
|
||||
package errors
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
<div class="row border-top mt-4">
|
||||
<div class="col">
|
||||
<p class="muted">
|
||||
Tavern is open source software. You can contribute or report issues on GitLab at
|
||||
<a href="https://gitlab.com/ngerakines/tavern">ngerakines/tavern</a> ({{ tavern_version }}).
|
||||
</p>
|
||||
<ul class="list-inline">
|
||||
<li class="list-inline-item">
|
||||
<a href="https://tavern.town/">Tavern</a> is open source software.
|
||||
</li>
|
||||
<li class="list-inline-item text-muted">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<a href="{{ url "about" }}">About</a>
|
||||
</li>
|
||||
<li class="list-inline-item text-muted">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<a href="{{ url "terms" }}">Terms</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
{{define "head"}}{{end}}
|
||||
{{define "footer_script"}}{{end}}
|
||||
{{define "content"}}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="display-1">About</h1>
|
||||
<p class="lead">
|
||||
Tavern is an open source
|
||||
<a href="{{ url "tag" "activity-pub"}}">Activity Pub</a>
|
||||
server written in
|
||||
<a href="{{ url "tag" "golang" }}">Golang</a>.
|
||||
</p>
|
||||
<p>
|
||||
This instance is administered by
|
||||
<a href="{{ .admin_user_link }}">@{{ .admin_user }}@{{ .domain }}</a>
|
||||
and has {{ .users }} users who have authored {{ .activities }} pieces of content.
|
||||
</p>
|
||||
{{ if .open_registrations }}
|
||||
<p>New accounts are welcome at this time.</p>
|
||||
{{ else }}
|
||||
<p>New accounts cannot be created at this time.</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="code-of-conduct" class="display-4">Code Of Conduct</h1>
|
||||
<p>
|
||||
The following guidelines are not a legal document, and final interpretation is up to the administration
|
||||
of {{ url }}; they are here to provide you with an insight into our content moderation policies:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<p>The following types of content will be removed from the public timeline:</p>
|
||||
<ol type="a">
|
||||
<li>
|
||||
<p>Excessive advertising</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Uncurated news bots posting from third-party news sources</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Untagged nudity, pornography and sexually explicit content, including artistic
|
||||
depictions</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Untagged gore and extremely graphic violence, including artistic depictions</p>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<p>The following types of content will be removed from the public timeline, and may result in
|
||||
account
|
||||
suspension and revocation of access to the service:</p>
|
||||
<ol type="a">
|
||||
<li>
|
||||
<p>Racism or advocation of racism</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Sexism or advocation of sexism</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Casteism or advocation of casteism</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Discrimination against gender and sexual minorities, or advocation thereof Xenophobic
|
||||
and/or
|
||||
violent nationalism</p>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<p>The following types of content are explicitly disallowed and will result in revocation of access
|
||||
to the service:</p>
|
||||
<ol type="a">
|
||||
<li>
|
||||
<p>Sexual depictions of children</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Content illegal in Germany and/or France, such as holocaust denial or Nazi symbolism</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Conduct promoting the ideology of National Socialism</p>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
<p>Any conduct intended to stalk or harass other users, or to impede other users from utilizing the
|
||||
service, or to degrade the performance of the service, or to harass other users, or to incite
|
||||
other
|
||||
users to perform any of the aforementioned actions, is also disallowed, and subject to
|
||||
punishment up
|
||||
to and including revocation of access to the service. This includes, but is not limited to, the
|
||||
following behaviors:</p>
|
||||
<ol type="a">
|
||||
<li>
|
||||
<p>Continuing to engage in conversation with a user that has specifically has requested for
|
||||
said engagement with that user to cease and desist may be considered harassment,
|
||||
regardless
|
||||
of platform-specific privacy tools employed.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Aggregating, posting, and/or disseminating a person's demographic, personal, or private
|
||||
data
|
||||
without express permission (informally called doxing or dropping dox) may be considered
|
||||
harassment.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p> Inciting users to engage another user in continued interaction or discussion after a
|
||||
user
|
||||
has requested for said engagement with that user to cease and desist (informally called
|
||||
brigading or dogpiling) may be considered harassment.</p>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
These provisions notwithstanding, the administration of the service reserves the right to revoke any
|
||||
user's access permissions, at any time, for any reason, except as limited by law.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -0,0 +1,191 @@
|
|||
{{define "head"}}{{end}}
|
||||
{{define "footer_script"}}{{end}}
|
||||
{{define "content"}}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="privacy-policy" class="display-5">Privacy Policy</h1>
|
||||
<h3>What information do we collect?</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
Basic account information: If you register on this server, you may be asked to enter a username,
|
||||
an e-mail address and a password. You may also enter additional profile information such as a
|
||||
display name and biography, and upload a profile picture and header image. The username, display
|
||||
name, biography, profile picture and header image are always listed publicly.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Posts, following and other public information: The list of people you follow is listed publicly,
|
||||
the same is true for your followers. When you submit a message, the date and time is stored as
|
||||
well as the application you submitted the message from. Messages may contain media attachments,
|
||||
such as pictures and videos. Public and unlisted posts are available publicly. When you feature
|
||||
a post on your profile, that is also publicly available information. Your posts are delivered to
|
||||
your followers, in some cases it means they are delivered to different servers and copies are
|
||||
stored there. When you delete posts, this is likewise delivered to your followers. The action of
|
||||
reblogging or favouriting another post is always public.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Direct and followers-only posts: All posts are stored and processed on the server.
|
||||
Followers-only posts are delivered to your followers and users who are mentioned in them, and
|
||||
direct posts are delivered only to users mentioned in them. In some cases it means they are
|
||||
delivered to different servers and copies are stored there. We make a good faith effort to limit
|
||||
the access to those posts only to authorized persons, but other servers may fail to do so.
|
||||
Therefore it's important to review servers your followers belong to. You may toggle an option to
|
||||
approve and reject new followers manually in the settings. Please keep in mind that the
|
||||
operators of the server and any receiving server may view such messages, and that recipients may
|
||||
screenshot, copy or otherwise re-share them. Do not share any dangerous information over
|
||||
Mastodon.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
IPs and other metadata: When you log in, we record the IP address you log in from, as well as
|
||||
the name of your browser application. All the logged in sessions are available for your review
|
||||
and revocation in the settings. The latest IP address used is stored for up to 12 months. We
|
||||
also may retain server logs which include the IP address of every request to our server.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>What do we use your information for?</h3>
|
||||
|
||||
<p>
|
||||
Any of the information we collect from you may be used in the following ways:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
To provide the core functionality of Mastodon. You can only interact with other people's content
|
||||
and post your own content when you are logged in. For example, you may follow other people to
|
||||
view their combined posts in your own personalized home timeline.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
To aid moderation of the community, for example comparing your IP address with other known ones
|
||||
to determine ban evasion or other violations.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
The email address you provide may be used to send you information, notifications about other
|
||||
people interacting with your content or sending you messages, and to respond to inquiries,
|
||||
and/or other requests or questions.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="cookie-policy" class="display-5">Cookie Policy</h1>
|
||||
<p>
|
||||
Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive
|
||||
through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if
|
||||
you have a registered account, associate it with your registered account.
|
||||
</p>
|
||||
<p>
|
||||
We use cookies to understand and save your preferences for future visits.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="data-protection-policy" class="display-5">Data Protection Policy</h1>
|
||||
<p>
|
||||
We implement a variety of security measures to maintain the safety of your personal information when you
|
||||
enter, submit, or access your personal information. Among other things, your browser session, as well as
|
||||
the traffic between your applications and the API, are secured with SSL, and your password is hashed
|
||||
using a strong one-way algorithm.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="data-retention-policy" class="display-5">Data Retention Policy</h1>
|
||||
<p>
|
||||
We will make a good faith effort to:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
Retain server logs containing the IP address of all requests to this server, in so far as such
|
||||
logs are kept, no more than 90 days.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Retain the IP addresses associated with registered users no more than 12 months.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
You can request and download an archive of your content, including your posts, media attachments,
|
||||
profile picture, and header image.
|
||||
</p>
|
||||
<p>
|
||||
You may irreversibly delete your account at any time.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="data-discolsure-policy" class="display-5">Data Disclosure Policy</h1>
|
||||
<p>
|
||||
We do not sell, trade, or otherwise transfer to outside parties your personally identifiable
|
||||
information. This does not include trusted third parties who assist us in operating our site, conducting
|
||||
our business, or servicing you, so long as those parties agree to keep this information confidential. We
|
||||
may also release your information when we believe release is appropriate to comply with the law, enforce
|
||||
our site policies, or protect ours or others rights, property, or safety.
|
||||
</p>
|
||||
<p>
|
||||
Your public content may be downloaded by other servers in the network. Your public and followers-only
|
||||
posts are delivered to the servers where your followers reside, and direct messages are delivered to the
|
||||
servers of the recipients, in so far as those followers or recipients reside on a different server than
|
||||
this.
|
||||
</p>
|
||||
<p>
|
||||
When you authorize an application to use your account, depending on the scope of permissions you
|
||||
approve, it may access your public profile information, your following list, your followers, your lists,
|
||||
all your posts, and your favourites. Applications can never access your e-mail address or password.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="child-usage-policy" class="display-5">Child Usage Policy</h1>
|
||||
<p>
|
||||
If this server is in the EU or the EEA: Our site, products and services are all directed to people who
|
||||
are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (General
|
||||
Data Protection Regulation) do not use this site.
|
||||
</p>
|
||||
<p>
|
||||
If this server is in the USA: Our site, products and services are all directed to people who are at
|
||||
least 13 years old. If you are under the age of 13, per the requirements of COPPA (Children's Online
|
||||
Privacy Protection Act) do not use this site.
|
||||
</p>
|
||||
<p>
|
||||
Law requirements can be different if this server is in another jurisdiction.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="display-5">Changes To Our Policies</h1>
|
||||
<p>
|
||||
If we decide to change our privacy policy, we will post those changes on this page.
|
||||
</p>
|
||||
<p>
|
||||
This document is CC-BY-SA. It was last updated 25 March 2020.
|
||||
</p>
|
||||
<p>
|
||||
Originally adapted from the
|
||||
<a href="https://github.com/discourse/discourse">Discourse privacy policy</a>
|
||||
and <a href="https://mastodon.social/terms">Mastodon privacy policy</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -0,0 +1,132 @@
|
|||
{{define "head"}}{{end}}
|
||||
{{define "footer_script"}}{{end}}
|
||||
{{define "content"}}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="display-1">Usage</h1>
|
||||
<p class="lead">
|
||||
This instance is a part of a distributed social media system called Activity Pub. With it, you can
|
||||
create content, follow other people, join groups, and participate in events. Most interaction occurs
|
||||
through creating notes (often referred to as "notes" and "statuses") and replying to the notes made by
|
||||
others.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 id="terms" class="display-4">Terms</h1>
|
||||
<p>
|
||||
<strong>Activity</strong> - An action taken by a user that is transmitted through the federated network
|
||||
of servers. They contain three important pieces of information: 1) The action that occurred 2) The
|
||||
person or entity that performed the action 3) The object of the action. A simplified activity would be "<strong>Nick</strong>
|
||||
<strong>created</strong> a <strong>note</strong>" where "Nick" is the actor, "created" is the action,
|
||||
and "a note" is the object.
|
||||
</p>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-3">Actor</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A JSON structure representing an entity. Actors are most often people, but can also represent
|
||||
bots, systems, organizations, and groups.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Activity</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A JSON structure representing an activity by an entity. Activity types include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Create</li>
|
||||
<li>Follow</li>
|
||||
<li>Unfollow</li>
|
||||
<li>Accept</li>
|
||||
<li>Reject</li>
|
||||
<li>Undo</li>
|
||||
<li>Delete</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Object</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A JSON structure representing a thing. Object types include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Note</li>
|
||||
<li>Article</li>
|
||||
<li>Event</li>
|
||||
<li>Location</li>
|
||||
</ul>
|
||||
<p>Additionally, objects can have meta-data associated with them.</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Attachment</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
An additional piece of information, usually a media file, transmitted with objects within
|
||||
activities.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Blurhash</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A small piece of data associated with visual media (images, videos, and documents) that allows
|
||||
the content to be blurred while previewed. Blurhash data is directly associated with
|
||||
attachments.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">HashTag</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A HashTag (or sometimes just "tag") is a piece of meta-data used to organize objects in loose
|
||||
folksonomies. HashTag data is directly associated with objects.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Mention</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>
|
||||
A Mention is a piece of meta-data used to associate a piece of content with an actor. Often,
|
||||
mentions are automatically parsed from subject references within post content, similar to how
|
||||
early Twitter users adopted "@user" references.
|
||||
</p>
|
||||
<p>
|
||||
An example would be having a note with the content "Hey @user@server, how's ya mama?".
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-3">Feed</dt>
|
||||
<dd class="col-sm-9">
|
||||
<p>A feed is a list of objects, either created locally or received from remote sources, that are
|
||||
displayed chronologically.</p>
|
||||
<p>Tavern has multiple feeds:</p>
|
||||
<ul>
|
||||
<li>
|
||||
"/feed" is the default feed. It is a paginated list of objects relevant to the logged in
|
||||
user. Items order most newest to oldest and include content from followers.
|
||||
</li>
|
||||
<li>
|
||||
"/feed/mine" is a paginated list of objects created by the logged in user ordered newest to
|
||||
oldest. This includes both public and non-public content.
|
||||
</li>
|
||||
<li>
|
||||
"/feed/local" is a paginated list of objects created by users on the local instance ordered
|
||||
newest to oldest. This is only public content.
|
||||
</li>
|
||||
<li>
|
||||
"/user/:name" is a paginated list of objects created by the specific user ordered newest to
|
||||
oldest. This is only public content.
|
||||
</li>
|
||||
<li>
|
||||
"/tag/:name" is a paginated list of objects that have the specific tag ordered newest to
|
||||
oldest. This is only public content.
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -189,7 +189,7 @@ func serverCommandAction(cliCtx *cli.Context) error {
|
|||
viewEngine.SetFileHandler(TemplateFileHandler())
|
||||
r.HTMLRender = viewEngine
|
||||
|
||||
r.Use(func(i *gin.Context) {
|
||||
r.Use(func(i *gin.Context) {
|
||||
nonce := i.GetHeader("X-Request-ID")
|
||||
if nonce != "" {
|
||||
i.Set("nonce", nonce)
|
||||
|
@ -268,6 +268,10 @@ func serverCommandAction(cliCtx *cli.Context) error {
|
|||
root.GET("/.well-known/webfinger", h.webFinger)
|
||||
root.GET("/.well-known/nodeinfo", h.nodeInfo)
|
||||
root.GET("/nodeinfo/2.0", h.nodeInfoDetails)
|
||||
|
||||
root.GET("/about", h.tavernAbout)
|
||||
root.GET("/terms", h.tavernTerms)
|
||||
root.GET("/usage", h.tavernUsage)
|
||||
}
|
||||
|
||||
apiV1 := r.Group("/api/v1")
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/ngerakines/tavern/common"
|
||||
)
|
||||
|
||||
func (h handler) tavernAbout(c *gin.Context) {
|
||||
users, err := h.storage.CountUsers(c.Request.Context())
|
||||
if err != nil {
|
||||
h.internalServerErrorJSON(c, err)
|
||||
return
|
||||
}
|
||||
activities, err := h.storage.CountObjectEvents(c.Request.Context())
|
||||
if err != nil {
|
||||
h.internalServerErrorJSON(c, err)
|
||||
return
|
||||
}
|
||||
openRegistrations := false
|
||||
c.HTML(http.StatusOK, "tavern_about", gin.H{
|
||||
"users": users,
|
||||
"activities": activities,
|
||||
"open_registrations": openRegistrations,
|
||||
"domain": h.domain,
|
||||
"admin_user": h.adminUser,
|
||||
"admin_user_link": common.ActorURL(h.domain, h.adminUser),
|
||||
})
|
||||
}
|
||||
|
||||
func (h handler) tavernTerms(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "tavern_terms", gin.H{})
|
||||
}
|
||||
|
||||
func (h handler) tavernUsage(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "tavern_usage", gin.H{})
|
||||
}
|
10
web/view.go
10
web/view.go
|
@ -159,6 +159,16 @@ func tmplUrlGen(siteBase string) func(parts ...interface{}) string {
|
|||
return fmt.Sprintf("%s/configure", siteBase)
|
||||
case "configure_user":
|
||||
return fmt.Sprintf("%s/configure/user", siteBase)
|
||||
|
||||
case "tag":
|
||||
return fmt.Sprintf("%s/tag/%s", siteBase, parts[1])
|
||||
|
||||
case "about":
|
||||
return fmt.Sprintf("%s/about", siteBase)
|
||||
case "terms":
|
||||
return fmt.Sprintf("%s/terms", siteBase)
|
||||
case "usage":
|
||||
return fmt.Sprintf("%s/usage", siteBase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue