Merge remote-tracking branch 'upstream/v2' into http-headers

This commit is contained in:
perennial
2024-02-15 19:16:02 +11:00
14 changed files with 194 additions and 279 deletions
+8
View File
@@ -34,6 +34,14 @@ func ProxyImageUrl(c *fiber.Ctx, s string) string {
return s
}
func ProxyImageUrlNoEscape(c *fiber.Ctx, s string) string {
proxy := GetImageProxy(c)
s = strings.ReplaceAll(s, `https://i.pximg.net`, "https://"+proxy)
// s = strings.ReplaceAll(s, `https:\/\/i.pximg.net`, "/proxy/i.pximg.net")
s = strings.ReplaceAll(s, `https://s.pximg.net`, "/proxy/s.pximg.net")
return s
}
func GetImageProxy(c *fiber.Ctx) string {
sess, err := Store.Get(c)
if err != nil {
+43 -18
View File
@@ -56,14 +56,18 @@ var aiTypeModel = map[aiType]string{
}
type ImageResponse struct {
Urls map[string]string `json:"urls"`
Width int `json:"width"`
Height int `json:"height"`
Urls map[string]string `json:"urls"`
}
type Image struct {
Small string `json:"thumb_mini"`
Medium string `json:"small"`
Large string `json:"regular"`
Original string `json:"original"`
Width int
Height int
Small string
Medium string
Large string
Original string
}
type Tag struct {
@@ -86,6 +90,20 @@ type UserBrief struct {
Avatar string `json:"imageBig"`
}
type ArtworkBrief struct {
ID string `json:"id"`
Title string `json:"title"`
ArtistID string `json:"userId"`
ArtistName string `json:"userName"`
ArtistAvatar string `json:"profileImageUrl"`
Thumbnail string `json:"url"`
Pages int `json:"pageCount"`
XRestrict int `json:"xRestrict"`
AiType int `json:"aiType"`
Bookmarked any `json:"bookmarkData"`
IllustType int `json:"illustType"`
}
type Illust struct {
ID string `json:"id"`
Title string `json:"title"`
@@ -94,19 +112,19 @@ type Illust struct {
UserName string `json:"userName"`
UserAccount string `json:"userAccount"`
Date time.Time `json:"uploadDate"`
Images []Image `json:"images"`
Tags []Tag `json:"tags"`
Pages int `json:"pageCount"`
Bookmarks int `json:"bookmarkCount"`
Likes int `json:"likeCount"`
Comments int `json:"commentCount"`
Views int `json:"viewCount"`
CommentDisabled int `json:"commentOff"`
SanityLevel int `json:"sl"`
XRestrict xRestrict `json:"xRestrict"`
AiType aiType `json:"aiType"`
Bookmarked any `json:"bookmarkData"`
Liked any `json:"json:"likeData"`
Images []Image
Tags []Tag `json:"tags"`
Pages int `json:"pageCount"`
Bookmarks int `json:"bookmarkCount"`
Likes int `json:"likeCount"`
Comments int `json:"commentCount"`
Views int `json:"viewCount"`
CommentDisabled int `json:"commentOff"`
SanityLevel int `json:"sl"`
XRestrict xRestrict `json:"xRestrict"`
AiType aiType `json:"aiType"`
Bookmarked any `json:"bookmarkData"`
Liked any `json:"likeData"`
User UserBrief
RecentWorks []ArtworkBrief
RelatedWorks []ArtworkBrief
@@ -154,6 +172,12 @@ func GetArtworkImages(c *fiber.Ctx, id string) ([]Image, error) {
for _, imageRaw := range resp {
var image Image
// this is the original art dimention, not the "regular" art dimension
// the image ratio of "regular" is close to Width/Height
// maybe not useful
image.Width = imageRaw.Width
image.Height = imageRaw.Height
image.Small = imageRaw.Urls["thumb_mini"]
image.Medium = imageRaw.Urls["small"]
image.Large = imageRaw.Urls["regular"]
@@ -220,6 +244,7 @@ func GetArtworkByID(c *fiber.Ctx, id string, full bool) (*Illust, error) {
var illust struct {
*Illust
// recent illustrations by same user
Recent map[int]any `json:"userIllusts"`
RawTags json.RawMessage `json:"tags"`
}
-13
View File
@@ -7,19 +7,6 @@ import (
"github.com/gofiber/fiber/v2"
)
type ArtworkBrief struct {
ID string `json:"id"`
Title string `json:"title"`
ArtistID string `json:"userId"`
ArtistName string `json:"userName"`
ArtistAvatar string `json:"profileImageUrl"`
Thumbnail string `json:"url"`
Pages int `json:"pageCount"`
XRestrict int `json:"xRestrict"`
AiType int `json:"aiType"`
Bookmarked any `json:"bookmarkData"`
}
func GetNewestArtworks(c *fiber.Ctx, worktype string, r18 string) ([]ArtworkBrief, error) {
token := session.GetToken(c)
URL := http.GetNewestArtworksURL(worktype, r18, "0")
+1
View File
@@ -20,6 +20,7 @@ type Ranking struct {
ID int `json:"illust_id"`
ArtistID int `json:"user_id"`
Rank int `json:"rank"`
IllustType string `json:"illust_type"`
} `json:"contents"`
Mode string `json:"mode"`
+1 -1
View File
@@ -64,7 +64,7 @@ func GetRankingCalendar(c *fiber.Ctx, mode string, year, month int) (template.HT
for _, a := range n.Attr {
if a.Key == "data-src" {
// adds a new link entry when the attribute matches
links = append(links, session.ProxyImageUrl(c, a.Val))
links = append(links, session.ProxyImageUrlNoEscape(c, a.Val))
}
}
}
+6 -10
View File
@@ -2,6 +2,7 @@ package pages
import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
@@ -14,7 +15,7 @@ func ArtworkMultiPage(c *fiber.Ctx) error {
param_ids := c.Params("ids")
ids := strings.Split(param_ids, ",")
artworks := make([]ArtWorkData, len(ids))
artworks := make([]*core.Illust, len(ids))
wg := sync.WaitGroup{}
wg.Add(len(ids))
@@ -28,8 +29,8 @@ func ArtworkMultiPage(c *fiber.Ctx) error {
illust, err := core.GetArtworkByID(c, id, false)
if err != nil {
artworks[i] = ArtWorkData{
Title: err.Error(),
artworks[i] = &core.Illust{
Title: err.Error(), // this might be flaky
}
return
}
@@ -39,18 +40,13 @@ func ArtworkMultiPage(c *fiber.Ctx) error {
metaDescription += "#" + i.Name + ", "
}
artworks[i] = ArtWorkData{
Illust: illust,
Title: illust.Title,
PageType: "artwork",
MetaDescription: metaDescription,
MetaImage: illust.Images[0].Original,
}
artworks[i] = illust
}(i, id)
}
wg.Wait()
return c.Render("pages/artwork-multi", fiber.Map{
"Artworks": artworks,
"Title": fmt.Sprintf("(%d images)", len(artworks)),
})
}
-8
View File
@@ -8,14 +8,6 @@ import (
"github.com/gofiber/fiber/v2"
)
type ArtWorkData struct {
Illust *core.Illust
Title string
PageType string
MetaDescription string
MetaImage string
}
func ArtworkPage(c *fiber.Ctx) error {
param_id := c.Params("id")
if _, err := strconv.Atoi(param_id); err != nil {
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="48px" height="48px"><g fill-opacity="0" fill="#000000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,256v-256h256v256z" id="bgRectangle"></path></g><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(4,4)"><path d="M22.521,29.862h-3.431c-0.886,0 -1.603,-0.718 -1.603,-1.603v-5.905c0,-0.97 0.607,-1.828 1.522,-2.151c2.225,-0.786 6.172,-3.122 6.823,-9.871c0.096,-0.996 0.911,-1.77 1.912,-1.77h6.391c0.872,0 1.579,0.707 1.579,1.579v9.302h6.468c0.886,0 1.603,0.718 1.603,1.603v7.213c0,0.886 -0.718,1.603 -1.603,1.603h-6.468v10.422c0,2.368 1.144,3.275 2.233,3.275c0.858,0 2.344,-0.375 3.437,-0.689c0.773,-0.222 1.526,0.075 1.848,0.956c0.322,0.881 2.045,5.833 2.045,5.833c0.315,0.899 -0.008,1.891 -0.787,2.44c-1.475,1.04 -4.248,2.463 -8.38,2.463c-6.418,0 -13.589,-2.852 -13.589,-13.494c0,-2.114 0,-11.206 0,-11.206z"></path></g></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+12 -12
View File
@@ -30,7 +30,7 @@
{{ end }}
</head>
<body hx-boost="true" hx-target="main" hx-select="main" hx-indicator="#loading-indicator">
<body data-hx-boost="true" data-hx-swap="outerHTML" data-hx-target="main" data-hx-select="main" data-hx-indicator="#loading-indicator">
<script>
document.body.addEventListener('htmx:beforeOnLoad', function (evt) {
evt.detail.shouldSwap = true;
@@ -54,45 +54,45 @@
<div class="sidebar">
<ul class="sidebar-list">
<a class="sidebar-item" href="/discovery">
<img src="/assets/compass.png" alt="icon" />Discovery</a
<img src="/assets/compass.png" alt="compass" />Discovery</a
>
<a class="sidebar-item" href="/ranking">
<img src="/assets/crown.png" alt="icon" />Ranking</a
<img src="/assets/crown.png" alt="crown" />Ranking</a
>
<a class="sidebar-item" href="/rankingCalendar">
<img src="/assets/calendar.png" alt="icon" />Ranking history</a
<img src="/assets/calendar.png" alt="calendar" />Ranking history</a
>
<a class="sidebar-item" href="/newest">
<img src="/assets/sparkling.png" alt="icon" />Newest</a
<img src="/assets/sparkling.png" alt="sparkling" />Newest</a
>
<br />
<a class="sidebar-item" href="/self/followingWorks">
<img src="/assets/users.png" alt="icon" />Latest by followed</a
<img src="/assets/users.png" alt="users" />Latest by followed</a
>
<a class="sidebar-item" href="/self/bookmarks">
<img src="/assets/heart.png" alt="icon" />Your bookmarks</a
<img src="/assets/heart.png" alt="heart" />Your bookmarks</a
>
<a class="sidebar-item" href="/self">
<img src="/assets/user.png" alt="icon" />Your profile</a
<img src="/assets/user.png" alt="user" />Your profile</a
>
<br />
<a class="sidebar-item" href="/settings">
<img src="/assets/settings.png" alt="icon" />Settings</a
<img src="/assets/settings.png" alt="settings" />Settings</a
>
<a class="sidebar-item" href="/about">
<img src="/assets/about.svg" alt="icon" />About</a
<img src="/assets/about.svg" alt="about" />About</a
>
<br />
<a
class="sidebar-item"
href="https://codeberg.org/vnpower/pixivfe"
>
<img src="/assets/globe.png" alt="icon" />Source code</a
<img src="/assets/globe.png" alt="globe" />Source code</a
>
</ul>
</div>
<span class="navbar-brand">
<img src="/assets/favicon.ico" alt="Icon" />
<img src="/assets/favicon.ico" alt="PixivFE icon" />
<a href="/">
<span>PixivFE</span>
</a>
+2
View File
@@ -1,3 +1,5 @@
{{ range Artworks }}
<div class="container illust">
{{ include "components/artwork" . }}
</div>
{{ end }}
+1 -109
View File
@@ -1,113 +1,5 @@
<div class="container illust" id="checkpoint">
{{ if !Illust.IsUgoira }}
<div class="illust-images">
{{ range index := Illust.Images }}
<a href="{{ .Original }}" target="_blank">
<img src="{{ .Large }}" alt="Page {{ index }}" />
</a>
{{ end }}
</div>
{{ else }}
<div class="illust-images">
<video
autoplay
loop
muted
disablepictureinpicture
playsinline
controls
poster="{{ Illust.Images[0].Large }}"
src="/proxy/ugoira.com/{{ Illust.ID }}"
>
Unable to load ugoira.
</video>
</div>
<a href="/proxy/ugoira.com/{{ Illust.ID }}"
>Download</a
>
<br />
<a href="https://ugoira.com/i/{{ Illust.ID }}"
>Go to ugoira.com for more options</a
>
{{ end }}
<div class="illust-attr">
<a href="/users/{{ Illust.User.ID }}"
><img
src="{{ Illust.User.Avatar }}"
alt="{{ Illust.User.Name }}"
class="illust-avatar"
/>
</a>
<div class="attr-wrap">
<div class="illust-title">{{ Illust.Title }}</div>
<div class="illust-author">
<a href="/users/{{ Illust.User.ID }}">{{ Illust.User.Name }}</a>
</div>
</div>
</div>
<div>
<a href="https://pixiv.net/i/{{ Illust.ID }}"
>pixiv.net/i/{{ Illust.ID }}</a
>
<br />
</div>
<div class="illust-tags">
<!--
To know if this artwork is bookmarked:
```
{{ if Illust.Bookmarked }}
<button>Unbookmark</button>
//...
{{ else }}
<button>Bookmarked</button>
//...
{{ end }}
```
Same with Illust.Liked
-->
<span class="illust-tag-attr">
<img src="/assets/eye.png" alt="Views" />
{{ Illust.Views }}
</span>
<span class="illust-tag-attr">
<img src="/assets/heart-solid.png" alt="Bookmarks" />
{{ Illust.Bookmarks }}
</span>
<span class="illust-tag-attr">
<img src="/assets/like.png" alt="Likes" />
{{ Illust.Likes }}
</span>
<span class="illust-tag-attr">
<img src="/assets/calendar.png" alt="Date" />
{{ parseTime: Illust.Date }}
</span>
</div>
<div class="illust-tags">
{{ if Illust.AiType == 2 }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">AI-generated</span>
</span>
{{ end }} {{ range Illust.Tags }} {{ if isEmphasize(.Name) }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">{{ .Name }}</span>
</span>
{{ else }}
<span class="illust-tag">
<span class="illust-tag-name"
><a href="/tags/{{ escapeString(.Name) }}">#{{ .Name }}</a></span
><span class="illust-tag-translation">{{ .TranslatedName }}</span>
</span>
{{ end }} {{ end }}
</div>
<br />
<div class="illust-description">
{{ raw: parsePixivRedirect(Illust.Description) }}
</div>
<br />
{{ include "components/artwork" Illust }}
<div class="illust-other-works">
<div class="artwork-container-header">
<a class="illust-other-works-author" href="/users/{{ Illust.User.ID }}"
+110 -107
View File
@@ -1,111 +1,114 @@
<div class="container illust">
{{ if !.Illust.IsUgoira }}
<div class="illust-images">
{{ range index := .Illust.Images }}
<a href="{{ .Original }}" target="_blank">
<img src="{{ .Large }}" alt="Page {{ index }}" />
</a>
{{ end }}
</div>
{{ if !.IsUgoira }}
<div class="illust-images">
{{ range index := .Images }}
<a href="{{ .Original }}" target="_blank">
{{ if .Width != 0 && .Height != 0 }}
<!-- todo: do not reflow the page because of loading image -->
<img src="{{ .Large }}" alt="Page {{ index }}" data-width="{{.Width}}" data-height="{{.Height}}" />
{{ else }}
<div class="illust-images">
<video
autoplay
loop
muted
disablepictureinpicture
playsinline
controls
poster="{{ .Illust.Images[0].Large }}"
src="/proxy/ugoira.com/{{ .Illust.ID }}"
>
Unable to load ugoira.
</video>
</div>
<a href="/proxy/ugoira.com/{{ .Illust.ID }}"
>Download</a
>
<br />
<a href="https://ugoira.com/i/{{ .Illust.ID }}"
>Go to ugoira.com for more options</a
>
<img src="{{ .Large }}" alt="Page {{ index }}" />
{{ end }}
<div class="illust-attr">
<a href="/users/{{ .Illust.User.ID }}"
><img
src="{{ .Illust.User.Avatar }}"
alt="{{ .Illust.User.Name }}"
class="illust-avatar"
/>
</a>
<div class="attr-wrap">
<div class="illust-title">{{ .Illust.Title }}</div>
<div class="illust-author">
<a href="/users/{{ .Illust.User.ID }}">{{ .Illust.User.Name }}</a>
</div>
</div>
</a>
{{ end }}
</div>
{{ else }}
<div class="illust-images">
<video
autoplay
loop
muted
disablepictureinpicture
playsinline
controls
poster="{{ .Images[0].Large }}"
src="/proxy/ugoira.com/{{ .ID }}"
>
Unable to load ugoira.
</video>
</div>
<a href="/proxy/ugoira.com/{{ .ID }}"
>Download</a
>
<br />
<a href="https://ugoira.com/i/{{ .ID }}"
>Go to ugoira.com for more options</a
>
{{ end }}
<div class="illust-attr">
<a href="/users/{{ .User.ID }}"
><img
src="{{ .User.Avatar }}"
alt="{{ .User.Name }}"
class="illust-avatar"
/>
</a>
<div class="attr-wrap">
<div class="illust-title">{{ .Title }}</div>
<div class="illust-author">
<a href="/users/{{ .User.ID }}">{{ .User.Name }}</a>
</div>
<div>
<a href="https://pixiv.net/i/{{ .Illust.ID }}"
>pixiv.net/i/{{ .Illust.ID }}</a
>
<br />
</div>
<div class="illust-tags">
<!--
To know if this artwork is bookmarked:
```
{{ if .Illust.Bookmarked }}
<button>Unbookmark</button>
//...
{{ else }}
<button>Bookmarked</button>
//...
{{ end }}
```
Same with .Illust.Liked
-->
<span class="illust-tag-attr">
<img src="/assets/eye.png" alt="Views" />
{{ .Illust.Views }}
</span>
<span class="illust-tag-attr">
<img src="/assets/heart-solid.png" alt="Bookmarks" />
{{ .Illust.Bookmarks }}
</span>
<span class="illust-tag-attr">
<img src="/assets/like.png" alt="Likes" />
{{ .Illust.Likes }}
</span>
<span class="illust-tag-attr">
<img src="/assets/calendar.png" alt="Date" />
{{ parseTime: .Illust.Date }}
</span>
</div>
<div class="illust-tags">
{{ if .Illust.AiType == 2 }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">AI-generated</span>
</span>
{{ end }} {{ range .Illust.Tags }} {{ if isEmphasize(.Name) }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">{{ .Name }}</span>
</span>
{{ else }}
<span class="illust-tag">
<span class="illust-tag-name"
><a href="/tags/{{ escapeString(.Name) }}">#{{ .Name }}</a></span
><span class="illust-tag-translation">{{ .TranslatedName }}</span>
</span>
{{ end }} {{ end }}
</div>
<br />
<div class="illust-description">
{{ raw: parsePixivRedirect(.Illust.Description) }}
</div>
<br />
</div>
</div>
<div>
<a href="https://pixiv.net/i/{{ .ID }}"
>pixiv.net/i/{{ .ID }}</a
>
<br />
</div>
<div class="illust-tags">
<!--
To know if this artwork is bookmarked:
```
{{ if .Bookmarked }}
<button>Unbookmark</button>
//...
{{ else }}
<button>Bookmarked</button>
//...
{{ end }}
```
Same with .Liked
-->
<span class="illust-tag-attr">
<img src="/assets/eye.png" alt="Views" />
{{ .Views }}
</span>
<span class="illust-tag-attr">
<img src="/assets/heart-solid.png" alt="Bookmarks" />
{{ .Bookmarks }}
</span>
<span class="illust-tag-attr">
<img src="/assets/like.png" alt="Likes" />
{{ .Likes }}
</span>
<span class="illust-tag-attr">
<img src="/assets/calendar.png" alt="Date" />
{{ parseTime: .Date }}
</span>
</div>
<div class="illust-tags">
{{ if .AiType == 2 }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">AI-generated</span>
</span>
{{ end }} {{ range .Tags }} {{ if isEmphasize(.Name) }}
<span class="illust-tag">
<span class="illust-tag-name" id="highlight">{{ .Name }}</span>
</span>
{{ else }}
<span class="illust-tag">
<span class="illust-tag-name"
><a href="/tags/{{ escapeString(.Name) }}">#{{ .Name }}</a></span
><span class="illust-tag-translation">{{ .TranslatedName }}</span>
</span>
{{ end }} {{ end }}
</div>
<br />
<div class="illust-description">
{{ raw: parsePixivRedirect(.Description) }}
</div>
<br />
+4 -1
View File
@@ -5,6 +5,9 @@
{{ if toInt(.Pages) > 1 }}
<div class="artwork-page-count"><span>&boxbox; {{ .Pages }}</span></div>
{{ end }}
{{ if toInt(.IllustType) == 2 }}
<div class="artwork-page-count"><span>&#9654;</span></div>
{{ end }}
</div>
<a href="/artworks/{{ .ID }}#checkpoint">
@@ -20,4 +23,4 @@
>
</div>
</div>
{{ end }}
{{ end }}
@@ -1,4 +1,5 @@
<div class="artwork-additional">
{{ if .XRestrict != 0 }}
<div class="artwork-profanity-label">
<span>{{ if .XRestrict == 1 }}R-18{{ else }}R-18G{{ end }}</span>
@@ -6,6 +7,10 @@
{{ end }} {{ if .Pages > 1 }}
<div class="artwork-page-count"><span>&boxbox; {{ .Pages }}</span></div>
{{ end }}
{{ if .IllustType == 2 }}
<div class="artwork-page-count"><span>&#9654;</span></div>
{{ end }}
</div>
<a href="/artworks/{{ .ID }}#checkpoint">
<img src="{{ .Thumbnail }}" alt="{{ .Title }}" loading="lazy" />