fix it more

This commit is contained in:
iacore
2024-08-27 13:49:13 +00:00
committed by VnPower
parent cf6c17c3fe
commit ad057345e9
37 changed files with 573 additions and 539 deletions
+8 -8
View File
@@ -21,12 +21,12 @@ var (
stopChan chan struct{}
)
func InitializeProxyChecker(c context.Context) {
func InitializeProxyChecker(r context.Context) {
stopChan = make(chan struct{})
StartProxyChecker(c)
StartProxyChecker(r)
}
func StartProxyChecker(c context.Context) {
func StartProxyChecker(r context.Context) {
go func() {
for {
select {
@@ -34,7 +34,7 @@ func StartProxyChecker(c context.Context) {
log.Println("Stopping proxy checker...")
return
default:
checkProxies(c)
checkProxies(r)
if t := GlobalServerConfig.ProxyCheckInterval; t > 0 {
time.Sleep(t)
} else {
@@ -50,7 +50,7 @@ func StopProxyChecker() {
close(stopChan)
}
func checkProxies(c context.Context) {
func checkProxies(r context.Context) {
logln("Starting proxy check...")
var wg sync.WaitGroup
var mutex sync.Mutex
@@ -62,7 +62,7 @@ func checkProxies(c context.Context) {
wg.Add(1)
go func(proxyURL string) {
defer wg.Done()
isWorking, resp := testProxy(c, proxyURL)
isWorking, resp := testProxy(r, proxyURL)
status := ""
if resp != nil {
status = resp.Status
@@ -83,13 +83,13 @@ func checkProxies(c context.Context) {
updateWorkingProxies(newWorkingProxies)
}
func testProxy(c context.Context, proxyBaseURL string) (bool, *http.Response) {
func testProxy(r context.Context, proxyBaseURL string) (bool, *http.Response) {
client := &http.Client{Timeout: proxyCheckTimeout}
fullURL := fmt.Sprintf("%s%s", strings.TrimRight(proxyBaseURL, "/"), testImagePath)
logf("Testing proxy %s with full URL: %s", proxyBaseURL, fullURL)
req, err := http.NewRequestWithContext(c, "GET", fullURL, nil)
req, err := http.NewRequestWithContext(r, "GET", fullURL, nil)
if err != nil {
logf("Error creating request for proxy %s: %v", proxyBaseURL, err)
return false, nil
+20 -20
View File
@@ -131,16 +131,16 @@ type Illust struct {
BookmarkID string
}
func GetUserBasicInformation(c *http.Request, id string) (UserBrief, error) {
func GetUserBasicInformation(r *http.Request, id string) (UserBrief, error) {
var user UserBrief
URL := GetUserInformationURL(id)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return user, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &user)
if err != nil {
@@ -150,17 +150,17 @@ func GetUserBasicInformation(c *http.Request, id string) (UserBrief, error) {
return user, nil
}
func GetArtworkImages(c *http.Request, id string) ([]Image, error) {
func GetArtworkImages(r *http.Request, id string) ([]Image, error) {
var resp []ImageResponse
var images []Image
URL := GetArtworkImagesURL(id)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &resp)
if err != nil {
@@ -188,18 +188,18 @@ func GetArtworkImages(c *http.Request, id string) ([]Image, error) {
return images, nil
}
func GetArtworkComments(c *http.Request, id string) ([]Comment, error) {
func GetArtworkComments(r *http.Request, id string) ([]Comment, error) {
var body struct {
Comments []Comment `json:"comments"`
}
URL := GetArtworkCommentsURL(id)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &body)
if err != nil {
@@ -209,7 +209,7 @@ func GetArtworkComments(c *http.Request, id string) ([]Comment, error) {
return body.Comments, nil
}
func GetRelatedArtworks(c *http.Request, id string) ([]ArtworkBrief, error) {
func GetRelatedArtworks(r *http.Request, id string) ([]ArtworkBrief, error) {
var body struct {
Illusts []ArtworkBrief `json:"illusts"`
}
@@ -217,12 +217,12 @@ func GetRelatedArtworks(c *http.Request, id string) ([]ArtworkBrief, error) {
// TODO: keep the hard-coded limit?
URL := GetArtworkRelatedURL(id, 96)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &body)
if err != nil {
@@ -232,11 +232,11 @@ func GetRelatedArtworks(c *http.Request, id string) ([]ArtworkBrief, error) {
return body.Illusts, nil
}
func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
func GetArtworkByID(r *http.Request, id string, full bool) (*Illust, error) {
URL := GetArtworkInformationURL(id)
token := session.GetPixivToken(c)
response, err := UnwrapWebAPIRequest(c.Context(), URL, token)
token := session.GetPixivToken(r)
response, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return nil, err
}
@@ -270,7 +270,7 @@ func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
go func() {
// Get illust images
defer wg.Done()
images, err := GetArtworkImages(c, id)
images, err := GetArtworkImages(r, id)
if err != nil {
cerr <- err
@@ -283,7 +283,7 @@ func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
// Get basic user information (the URL above does not contain avatars)
defer wg.Done()
var err error
userInfo, err := GetUserBasicInformation(c, illust.UserID)
userInfo, err := GetUserBasicInformation(r, illust.UserID)
if err != nil {
cerr <- err
return
@@ -340,7 +340,7 @@ func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
idsString += fmt.Sprintf("&ids[]=%d", ids[i])
}
recent, err := GetUserArtworks(c, illust.UserID, idsString)
recent, err := GetUserArtworks(r, illust.UserID, idsString)
if err != nil {
cerr <- err
return
@@ -356,7 +356,7 @@ func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
go func() {
defer wg.Done()
var err error
related, err := GetRelatedArtworks(c, id)
related, err := GetRelatedArtworks(r, id)
if err != nil {
cerr <- err
return
@@ -370,7 +370,7 @@ func GetArtworkByID(c *http.Request, id string, full bool) (*Illust, error) {
return
}
var err error
comments, err := GetArtworkComments(c, id)
comments, err := GetArtworkComments(r, id)
if err != nil {
cerr <- err
return
+9 -9
View File
@@ -5,22 +5,22 @@ import (
"codeberg.org/vnpower/pixivfe/v2/session"
"github.com/goccy/go-json"
"net/http"
"github.com/tidwall/gjson"
"net/http"
)
func GetDiscoveryArtwork(c *http.Request, mode string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(c)
func GetDiscoveryArtwork(r *http.Request, mode string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(r)
URL := GetDiscoveryURL(mode, 100)
var artworks []ArtworkBrief
resp, err := UnwrapWebAPIRequest(c.Context(), URL, token)
resp, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
if !gjson.Valid(resp) {
return nil, fmt.Errorf("Invalid JSON: %v", resp)
}
@@ -34,18 +34,18 @@ func GetDiscoveryArtwork(c *http.Request, mode string) ([]ArtworkBrief, error) {
return artworks, nil
}
func GetDiscoveryNovels(c *http.Request, mode string) ([]NovelBrief, error) {
token := session.GetPixivToken(c)
func GetDiscoveryNovels(r *http.Request, mode string) ([]NovelBrief, error) {
token := session.GetPixivToken(r)
URL := GetDiscoveryNovelURL(mode, 100)
var novels []NovelBrief
resp, err := UnwrapWebAPIRequest(c.Context(), URL, token)
resp, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
if !gjson.Valid(resp) {
return nil, fmt.Errorf("Invalid JSON: %v", resp)
}
+4 -4
View File
@@ -5,8 +5,8 @@ import (
"codeberg.org/vnpower/pixivfe/v2/session"
"github.com/goccy/go-json"
"net/http"
"github.com/tidwall/gjson"
"net/http"
)
type Pixivision struct {
@@ -31,7 +31,7 @@ type LandingArtworks struct {
RecommendByTags []RecommendedTags
}
func GetLanding(c *http.Request, mode string) (*LandingArtworks, error) {
func GetLanding(r *http.Request, mode string) (*LandingArtworks, error) {
var pages struct {
Pixivision []Pixivision `json:"pixivision"`
Follow []int `json:"follow"`
@@ -51,12 +51,12 @@ func GetLanding(c *http.Request, mode string) (*LandingArtworks, error) {
var landing LandingArtworks
resp, err := UnwrapWebAPIRequest(c.Context(), URL, "")
resp, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return &landing, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
if !gjson.Valid(resp) {
return nil, fmt.Errorf("Invalid JSON: %v", resp)
+4 -4
View File
@@ -6,8 +6,8 @@ import (
"net/http"
)
func GetNewestArtworks(c *http.Request, worktype string, r18 string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(c)
func GetNewestArtworks(r *http.Request, worktype string, r18 string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(r)
URL := GetNewestArtworksURL(worktype, r18, "0")
var body struct {
@@ -15,11 +15,11 @@ func GetNewestArtworks(c *http.Request, worktype string, r18 string) ([]ArtworkB
// LastId string
}
resp, err := UnwrapWebAPIRequest(c.Context(), URL, token)
resp, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
err = json.Unmarshal([]byte(resp), &body)
if err != nil {
+66 -66
View File
@@ -11,30 +11,30 @@ import (
)
type Novel struct {
Bookmarks int `json:"bookmarkCount"`
CommentCount int `json:"commentCount"`
MarkerCount int `json:"markerCount"`
CreateDate time.Time `json:"createDate"`
UploadDate time.Time `json:"uploadDate"`
Description string `json:"description"`
ID string `json:"id"`
Title string `json:"title"`
Likes int `json:"likeCount"`
Pages int `json:"pageCount"`
UserID string `json:"userId"`
UserName string `json:"userName"`
Views int `json:"viewCount"`
IsOriginal bool `json:"isOriginal"`
IsBungei bool `json:"isBungei"`
XRestrict int `json:"xRestrict"`
Restrict int `json:"restrict"`
Content string `json:"content"`
CoverURL string `json:"coverUrl"`
IsBookmarkable bool `json:"isBookmarkable"`
BookmarkData any `json:"bookmarkData"`
LikeData bool `json:"likeData"`
PollData any `json:"pollData"`
Marker any `json:"marker"`
Bookmarks int `json:"bookmarkCount"`
CommentCount int `json:"commentCount"`
MarkerCount int `json:"markerCount"`
CreateDate time.Time `json:"createDate"`
UploadDate time.Time `json:"uploadDate"`
Description string `json:"description"`
ID string `json:"id"`
Title string `json:"title"`
Likes int `json:"likeCount"`
Pages int `json:"pageCount"`
UserID string `json:"userId"`
UserName string `json:"userName"`
Views int `json:"viewCount"`
IsOriginal bool `json:"isOriginal"`
IsBungei bool `json:"isBungei"`
XRestrict int `json:"xRestrict"`
Restrict int `json:"restrict"`
Content string `json:"content"`
CoverURL string `json:"coverUrl"`
IsBookmarkable bool `json:"isBookmarkable"`
BookmarkData any `json:"bookmarkData"`
LikeData bool `json:"likeData"`
PollData any `json:"pollData"`
Marker any `json:"marker"`
Tags struct {
AuthorID string `json:"authorId"`
IsLocked bool `json:"isLocked"`
@@ -43,9 +43,9 @@ type Novel struct {
} `json:"tags"`
Writable bool `json:"writable"`
} `json:"tags"`
SeriesNavData any `json:"seriesNavData"`
HasGlossary bool `json:"hasGlossary"`
IsUnlisted bool `json:"isUnlisted"`
SeriesNavData any `json:"seriesNavData"`
HasGlossary bool `json:"hasGlossary"`
IsUnlisted bool `json:"isUnlisted"`
// seen values: zh-cn, ja
Language string `json:"language"`
CommentOff int `json:"commentOff"`
@@ -62,43 +62,43 @@ type Novel struct {
}
type NovelBrief struct {
ID string `json:"id"`
Title string `json:"title"`
XRestrict int `json:"xRestrict"`
Restrict int `json:"restrict"`
CoverURL string `json:"url"`
Tags []string `json:"tags"`
UserID string `json:"userId"`
UserName string `json:"userName"`
UserAvatar string `json:"profileImageUrl"`
TextCount int `json:"textCount"`
WordCount int `json:"wordCount"`
ReadingTime int `json:"readingTime"`
Description string `json:"description"`
IsBookmarkable bool `json:"isBookmarkable"`
BookmarkData any `json:"bookmarkData"`
Bookmarks int `json:"bookmarkCount"`
IsOriginal bool `json:"isOriginal"`
CreateDate time.Time `json:"createDate"`
UpdateDate time.Time `json:"updateDate"`
IsMasked bool `json:"isMasked"`
SeriesID string `json:"seriesId"`
SeriesTitle string `json:"seriesTitle"`
IsUnlisted bool `json:"isUnlisted"`
AiType int `json:"aiType"`
Genre string `json:"genre"`
ID string `json:"id"`
Title string `json:"title"`
XRestrict int `json:"xRestrict"`
Restrict int `json:"restrict"`
CoverURL string `json:"url"`
Tags []string `json:"tags"`
UserID string `json:"userId"`
UserName string `json:"userName"`
UserAvatar string `json:"profileImageUrl"`
TextCount int `json:"textCount"`
WordCount int `json:"wordCount"`
ReadingTime int `json:"readingTime"`
Description string `json:"description"`
IsBookmarkable bool `json:"isBookmarkable"`
BookmarkData any `json:"bookmarkData"`
Bookmarks int `json:"bookmarkCount"`
IsOriginal bool `json:"isOriginal"`
CreateDate time.Time `json:"createDate"`
UpdateDate time.Time `json:"updateDate"`
IsMasked bool `json:"isMasked"`
SeriesID string `json:"seriesId"`
SeriesTitle string `json:"seriesTitle"`
IsUnlisted bool `json:"isUnlisted"`
AiType int `json:"aiType"`
Genre string `json:"genre"`
}
func GetNovelByID(c *http.Request, id string) (Novel, error) {
func GetNovelByID(r *http.Request, id string) (Novel, error) {
var novel Novel
URL := GetNovelURL(id)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return novel, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &novel)
if err != nil {
@@ -106,21 +106,21 @@ func GetNovelByID(c *http.Request, id string) (Novel, error) {
}
// Novel embedded illusts
r := regexp.MustCompile("\\[pixivimage:(\\d+.\\d+)\\]")
d := regexp.MustCompile("\\d+.\\d+")
t := regexp.MustCompile(`\"original\":\"(.+?)\"`)
re_r := regexp.MustCompile("\\[pixivimage:(\\d+.\\d+)\\]")
re_d := regexp.MustCompile("\\d+.\\d+")
re_t := regexp.MustCompile(`\"original\":\"(.+?)\"`)
novel.Content = r.ReplaceAllStringFunc(novel.Content, func(s string) string {
illustid := d.FindString(s)
novel.Content = re_r.ReplaceAllStringFunc(novel.Content, func(s string) string {
illustid := re_d.FindString(s)
URL := GetInsertIllustURL(novel.ID, illustid)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return "Cannot insert illust" + illustid
}
url := t.FindString(response)
url = session.ProxyImageUrl(c, url[11:]) // truncate the "original":
url := re_t.FindString(response)
url = session.ProxyImageUrl(r, url[11:]) // truncate the "original":
return fmt.Sprintf(`<img src=%s alt="%s"/>`, url, s)
})
@@ -128,7 +128,7 @@ func GetNovelByID(c *http.Request, id string) (Novel, error) {
return novel, nil
}
func GetNovelRelated(c *http.Request, id string) ([]NovelBrief, error) {
func GetNovelRelated(r *http.Request, id string) ([]NovelBrief, error) {
var novels struct {
List []NovelBrief `json:"novels"`
}
@@ -136,11 +136,11 @@ func GetNovelRelated(c *http.Request, id string) ([]NovelBrief, error) {
// hard-coded value, may change
URL := GetNovelRelatedURL(id, 50)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return novels.List, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &novels)
if err != nil {
+4 -4
View File
@@ -7,8 +7,8 @@ import (
"net/http"
)
func GetNewestFromFollowing(c *http.Request, mode, page string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(c)
func GetNewestFromFollowing(r *http.Request, mode, page string) ([]ArtworkBrief, error) {
token := session.GetPixivToken(r)
URL := GetNewestFromFollowingURL(mode, page)
var body struct {
@@ -19,11 +19,11 @@ func GetNewestFromFollowing(c *http.Request, mode, page string) ([]ArtworkBrief,
Artworks []ArtworkBrief `json:"illust"`
}
resp, err := UnwrapWebAPIRequest(c.Context(), URL, token)
resp, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
err = json.Unmarshal([]byte(resp), &body)
if err != nil {
+3 -3
View File
@@ -34,16 +34,16 @@ type Ranking struct {
NextDate string
}
func GetRanking(c *http.Request, mode, content, date, page string) (Ranking, error) {
func GetRanking(r *http.Request, mode, content, date, page string) (Ranking, error) {
URL := GetRankingURL(mode, content, date, page)
var ranking Ranking
resp := WebAPIRequest(c.Context(), URL, "")
resp := WebAPIRequest(r.Context(), URL, "")
if !resp.Ok {
return ranking, errors.New(resp.Message)
}
proxiedResp := session.ProxyImageUrl(c, resp.Body)
proxiedResp := session.ProxyImageUrl(r, resp.Body)
err := json.Unmarshal([]byte(proxiedResp), &ranking)
if err != nil {
+7 -7
View File
@@ -34,15 +34,15 @@ func get_weekday(n time.Weekday) int {
// note(@iacore):
// so the funny thing about Pixiv is that they will return this month's data for a request of a future date
// is it a bug or a feature?
func GetRankingCalendar(c *http.Request, mode string, year, month int) (template.HTML, error) {
token := session.GetPixivToken(c)
func GetRankingCalendar(r *http.Request, mode string, year, month int) (template.HTML, error) {
token := session.GetPixivToken(r)
URL := GetRankingCalendarURL(mode, year, month)
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return template.HTML(""), err
}
req = req.WithContext(c.Context())
req = req.WithContext(r.Context())
req.Header.Add("User-Agent", "Mozilla/5.0")
req.Header.Add("Cookie", "PHPSESSID="+token)
// req.AddCookie(&http.Cookie{
@@ -70,19 +70,19 @@ func GetRankingCalendar(c *http.Request, mode string, year, month int) (template
for _, a := range n.Attr {
if a.Key == "data-src" {
// adds a new link entry when the attribute matches
links = append(links, session.ProxyImageUrlNoEscape(c, a.Val))
links = append(links, session.ProxyImageUrlNoEscape(r, a.Val))
}
}
}
// traverses the HTML of the webpage from the first child node
for c := n.FirstChild; c != nil; c = c.NextSibling {
link(c)
for r := n.FirstChild; r != nil; r = r.NextSibling {
link(r)
}
}
link(doc)
// now := c.Context().Time()
// now := r.Context().Time()
// yearNow := now.Year()
// monthNow := now.Month()
lastMonth := time.Date(year, time.Month(month), 0, 0, 0, 0, 0, time.UTC)
+6 -6
View File
@@ -71,17 +71,17 @@ func (s SearchPageSettings) ReturnMap() map[string]string {
}
}
func GetTagData(c *http.Request, name string) (TagDetail, error) {
func GetTagData(r *http.Request, name string) (TagDetail, error) {
var tag TagDetail
URL := GetTagDetailURL(name)
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return tag, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
err = json.Unmarshal([]byte(response), &tag)
if err != nil {
@@ -91,14 +91,14 @@ func GetTagData(c *http.Request, name string) (TagDetail, error) {
return tag, nil
}
func GetSearch(c *http.Request, settings SearchPageSettings) (*SearchResult, error) {
func GetSearch(r *http.Request, settings SearchPageSettings) (*SearchResult, error) {
URL := GetSearchArtworksURL(settings.ReturnMap())
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
response = session.ProxyImageUrl(c, response)
response = session.ProxyImageUrl(r, response)
// IDK how to do better than this lol
temp := strings.ReplaceAll(string(response), `"illust"`, `"works"`)
+35 -35
View File
@@ -43,17 +43,17 @@ type FrequentTag struct {
}
type User struct {
ID string `json:"userId"`
Name string `json:"name"`
Avatar string `json:"imageBig"`
Following int `json:"following"`
MyPixiv int `json:"mypixivCount"`
Comment template.HTML `json:"commentHtml"`
Webpage string `json:"webpage"`
SocialRaw json.RawMessage `json:"social"`
Artworks []ArtworkBrief `json:"artworks"`
Novels []NovelBrief `json:"novels"`
Background map[string]any `json:"background"`
ID string `json:"userId"`
Name string `json:"name"`
Avatar string `json:"imageBig"`
Following int `json:"following"`
MyPixiv int `json:"mypixivCount"`
Comment template.HTML `json:"commentHtml"`
Webpage string `json:"webpage"`
SocialRaw json.RawMessage `json:"social"`
Artworks []ArtworkBrief `json:"artworks"`
Novels []NovelBrief `json:"novels"`
Background map[string]any `json:"background"`
ArtworksCount int
FrequentTags []FrequentTag
Social map[string]map[string]string
@@ -73,7 +73,7 @@ func (s *User) ParseSocial() error {
return nil
}
func GetFrequentTags(c *http.Request, ids string, category UserArtCategory) ([]FrequentTag, error) {
func GetFrequentTags(r *http.Request, ids string, category UserArtCategory) ([]FrequentTag, error) {
var tags []FrequentTag
var URL string
@@ -83,7 +83,7 @@ func GetFrequentTags(c *http.Request, ids string, category UserArtCategory) ([]F
URL = GetFrequentNovelTagsURL(ids)
}
response, err := UnwrapWebAPIRequest(c.Context(), URL, "")
response, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
@@ -96,16 +96,16 @@ func GetFrequentTags(c *http.Request, ids string, category UserArtCategory) ([]F
return tags, nil
}
func GetUserArtworks(c *http.Request, id, ids string) ([]ArtworkBrief, error) {
func GetUserArtworks(r *http.Request, id, ids string) ([]ArtworkBrief, error) {
var works []ArtworkBrief
URL := GetUserFullArtworkURL(id, ids)
resp, err := UnwrapWebAPIRequest(c.Context(), URL, "")
resp, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
var body struct {
Illusts map[int]json.RawMessage `json:"works"`
@@ -130,17 +130,17 @@ func GetUserArtworks(c *http.Request, id, ids string) ([]ArtworkBrief, error) {
return works, nil
}
func GetUserNovels(c *http.Request, id, ids string) ([]NovelBrief, error) {
func GetUserNovels(r *http.Request, id, ids string) ([]NovelBrief, error) {
// VnPower: we can merge this function into GetUserArtworks, but I want to make things simple for now
var works []NovelBrief
URL := GetUserFullNovelURL(id, ids)
resp, err := UnwrapWebAPIRequest(c.Context(), URL, "")
resp, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
var body struct {
Novels map[int]json.RawMessage `json:"works"`
@@ -165,10 +165,10 @@ func GetUserNovels(c *http.Request, id, ids string) ([]NovelBrief, error) {
return works, nil
}
func GetUserArtworksID(c *http.Request, id string, category UserArtCategory, page int) (string, int, error) {
func GetUserArtworksID(r *http.Request, id string, category UserArtCategory, page int) (string, int, error) {
URL := GetUserArtworksURL(id)
resp, err := UnwrapWebAPIRequest(c.Context(), URL, "")
resp, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return "", -1, err
}
@@ -248,19 +248,19 @@ func GetUserArtworksID(c *http.Request, id string, category UserArtCategory, pag
return idsString, count, nil
}
func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page int, getTags bool) (User, error) {
func GetUserArtwork(r *http.Request, id string, category UserArtCategory, page int, getTags bool) (User, error) {
var user User
token := session.GetPixivToken(c)
token := session.GetPixivToken(r)
URL := GetUserInformationURL(id)
resp, err := UnwrapWebAPIRequest(c.Context(), URL, token)
resp, err := UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return user, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
err = json.Unmarshal([]byte(resp), &user)
if err != nil {
@@ -269,7 +269,7 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
if category == UserArt_Bookmarks {
// Bookmarks
works, count, err := GetUserBookmarks(c, id, "show", page)
works, count, err := GetUserBookmarks(r, id, "show", page)
if err != nil {
return user, err
}
@@ -279,14 +279,14 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
// Public bookmarks count
user.ArtworksCount = count
} else if category == UserArt_Novel {
ids, count, err := GetUserArtworksID(c, id, category, page)
ids, count, err := GetUserArtworksID(r, id, category, page)
if err != nil {
return user, err
}
if count > 0 {
// Check if the user has artworks available or not
works, err := GetUserNovels(c, id, ids)
works, err := GetUserNovels(r, id, ids)
if err != nil {
return user, err
}
@@ -300,7 +300,7 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
user.Novels = works
if getTags {
user.FrequentTags, err = GetFrequentTags(c, ids, category)
user.FrequentTags, err = GetFrequentTags(r, ids, category)
if err != nil {
return user, err
}
@@ -310,14 +310,14 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
// Artworks count
user.ArtworksCount = count
} else {
ids, count, err := GetUserArtworksID(c, id, category, page)
ids, count, err := GetUserArtworksID(r, id, category, page)
if err != nil {
return user, err
}
if count > 0 {
// Check if the user has artworks available or not
works, err := GetUserArtworks(c, id, ids)
works, err := GetUserArtworks(r, id, ids)
if err != nil {
return user, err
}
@@ -331,7 +331,7 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
user.Artworks = works
if getTags {
user.FrequentTags, err = GetFrequentTags(c, ids, category)
user.FrequentTags, err = GetFrequentTags(r, ids, category)
if err != nil {
return user, err
}
@@ -354,16 +354,16 @@ func GetUserArtwork(c *http.Request, id string, category UserArtCategory, page i
return user, nil
}
func GetUserBookmarks(c *http.Request, id, mode string, page int) ([]ArtworkBrief, int, error) {
func GetUserBookmarks(r *http.Request, id, mode string, page int) ([]ArtworkBrief, int, error) {
page--
URL := GetUserBookmarksURL(id, mode, page)
resp, err := UnwrapWebAPIRequest(c.Context(), URL, "")
resp, err := UnwrapWebAPIRequest(r.Context(), URL, "")
if err != nil {
return nil, -1, err
}
resp = session.ProxyImageUrl(c, resp)
resp = session.ProxyImageUrl(r, resp)
var body struct {
Artworks []json.RawMessage `json:"works"`
+5 -1
View File
@@ -15,8 +15,12 @@
net/http handlers don't return errors. We have to make our own ServeMux that allows functions to return `error`, possibly.
net/http expects handlers to panic on error, while we don't panic. We need to log the errors anyway.
Idea: we create a compat layer of {w, r} that has the same API as *fiber.Ctx.
## Tips
To access `/:abc`, use `r.PathValue("abc")`.
Idea: we create a compat layer of {w, r} that has the same API as *fiber.Ctx.
Want to associate arbitrary value with a request? Use `r.Context.Value()`.
+1
View File
@@ -19,6 +19,7 @@ require (
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gorilla/mux v1.8.1
github.com/stretchr/testify v1.9.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
+2
View File
@@ -22,6 +22,8 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/playwright-community/playwright-go v0.4501.1 h1:kz8SIfR6nEI8blk77nTVD0K5/i37QP5rY/o8a1fG+4c=
+50 -42
View File
@@ -17,16 +17,8 @@ import (
"codeberg.org/vnpower/pixivfe/v2/core"
"codeberg.org/vnpower/pixivfe/v2/routes"
"codeberg.org/vnpower/pixivfe/v2/session"
// "codeberg.org/vnpower/pixivfe/v2/utils/kmutex"
// "github.com/CloudyKit/jet/v6"
// "github.com/goccy/go-json"
// "net/http"
// "net/http/middleware/cache"
// "net/http/middleware/compress"
// "net/http/middleware/limiter"
// "net/http/middleware/logger"
// "net/http/middleware/recover"
// fiber_utils "net/http/utils"
"github.com/gorilla/mux"
)
func CanRequestSkipLimiter(r *http.Request) bool {
@@ -44,6 +36,18 @@ func CanRequestSkipLogger(r *http.Request) bool {
strings.HasPrefix(path, "/proxy/i.pximg.net/")
}
type UserContext struct {
err error
}
type userContextKey struct{}
var UserContextKey = userContextKey{}
func GetUserContext(r *http.Request) *UserContext {
return r.Context().Value(UserContextKey).(*UserContext)
}
func main() {
config.GlobalServerConfig.InitializeConfig()
if config.GlobalServerConfig.InDevelopment {
@@ -60,7 +64,7 @@ func main() {
// EnableTrustedProxyCheck: true,
// TrustedProxies: []string{"0.0.0.0/0"},
// ProxyHeader: fiber.HeaderXForwardedFor,
// ErrorHandler: func(c *http.Request, err error) error {
// ErrorHandler: func(r *http.Request, err error) error {
// log.Println(err)
// // Status code defaults to 500
@@ -73,10 +77,10 @@ func main() {
// // }
// // Send custom error page
// c.Status(code)
// err = routes.Render(c, routes.Data_error{Title: "Error", Error: err})
// r.Status(code)
// err = routes.Render(w, r, routes.Data_error{Title: "Error", Error: err})
// if err != nil {
// return c.Status(code).SendString(fmt.Sprintf("Internal Server Error: %s", err))
// return r.Status(code).SendString(fmt.Sprintf("Internal Server Error: %s", err))
// }
// return nil
@@ -91,23 +95,23 @@ func main() {
// Expiration: 30 * time.Second,
// Max: config.GlobalServerConfig.RequestLimit,
// LimiterMiddleware: limiter.SlidingWindow{},
// LimitReached: func(c *http.Request) error {
// LimitReached: func(r *http.Request) error {
// // limit response throughput by pacing, since not every bot reads X-RateLimit-*
// // on limit reached, they just have to wait
// // the design of this means that if they send multiple requests when reaching rate limit, they will wait even longer (since `retryAfter` is calculated before anything has slept)
// retryAfter_s := c.GetRespHeader(fiber.HeaderRetryAfter)
// retryAfter_s := r.GetRespHeader(fiber.HeaderRetryAfter)
// retryAfter, err := strconv.ParseUint(retryAfter_s, 10, 64)
// if err != nil {
// log.Panicf("response header 'RetryAfter' should be a number: %v", err)
// }
// requestIP := c.IP()
// requestIP := r.IP()
// refcount := keyedSleepingSpot.Lock(requestIP)
// defer keyedSleepingSpot.Unlock(requestIP)
// if refcount >= 4 { // on too much concurrent requests
// // todo: maybe blackhole `requestIP` here
// log.Println("Limit Reached (Hard)!", requestIP)
// // close the connection immediately
// _ = c.Context().Conn().Close()
// _ = r.Context().Conn().Close()
// return nil
// }
@@ -116,11 +120,11 @@ func main() {
// // todo: close this connection when this IP reaches hard limit
// dur := time.Duration(retryAfter) * time.Second
// log.Println("Limit Reached (Soft)! Sleeping for ", dur)
// ctx, cancel := context.WithTimeout(c.Context(), dur)
// ctx, cancel := context.WithTimeout(r.Context(), dur)
// defer cancel()
// <-ctx.Done()
// return c.Next()
// return r.Next()
// },
// }))
// }
@@ -129,23 +133,23 @@ func main() {
// if !config.GlobalServerConfig.InDevelopment {
// server.Use(cache.New(
// cache.Config{
// Next: func(c *http.Request) bool {
// resp_code := c.Response().StatusCode()
// Next: func(r *http.Request) bool {
// resp_code := r.Response().StatusCode()
// if resp_code < 200 || resp_code >= 300 {
// return true
// }
// // Disable cache for settings page
// return strings.Contains(c.Path(), "/settings") || c.Path() == "/"
// return strings.Contains(r.Path(), "/settings") || r.Path() == "/"
// },
// Expiration: 5 * time.Minute,
// CacheControl: true,
// StoreResponseHeaders: true,
// KeyGenerator: func(c *http.Request) string {
// key := fiber_utils.CopyString(c.OriginalURL())
// KeyGenerator: func(r *http.Request) string {
// key := fiber_utils.CopyString(r.OriginalURL())
// for _, cookieName := range session.AllCookieNames {
// cookieValue := session.GetCookie(c, cookieName)
// cookieValue := session.GetCookie(r, cookieName)
// if cookieValue != "" {
// key += "\x00\x00"
// key += string(cookieName)
@@ -162,9 +166,12 @@ func main() {
router := defineRoutes()
main_handler := func(w http.ResponseWriter, r *http.Request) {
// set user context
r = r.WithContext(context.WithValue(r.Context(), UserContextKey, &UserContext{}))
start_time := time.Now()
setGlobalHeaders(r)
setGlobalHeaders(w)
router.ServeHTTP(w, r)
@@ -185,10 +192,10 @@ func main() {
method := r.Method
path := r.URL.Path
status := r.Response.Status
err := GetUserContext(r).err
log.Printf("%v +%v %v %v %v %v {todo: print error (where is error?)}", time, latency, ip, method, path, status)
log.Printf("%v +%v %v %v %v %v %v", time, latency, ip, method, path, status, err)
}
}
// Initialize and start the proxy checker
@@ -233,10 +240,8 @@ func main() {
http.Serve(l, http.HandlerFunc(main_handler))
}
// todo: if this doesn't work, need to use `w.Header()`
func setGlobalHeaders(r *http.Request) {
// Respond with global HTTP headers
header := r.Response.Header
func setGlobalHeaders(w http.ResponseWriter) {
header := w.Header()
header.Add("X-Frame-Options", "DENY")
// use this if need iframe: `X-Frame-Options: SAMEORIGIN`
header.Add("X-Content-Type-Options", "nosniff")
@@ -250,8 +255,8 @@ func setGlobalHeaders(r *http.Request) {
func serveFile(filename string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, filename) }
}
func defineRoutes() http.ServeMux {
router := http.ServeMux{}
func defineRoutes() *mux.Router {
router := mux.NewRouter()
router.HandleFunc("/favicon.ico", serveFile("./assets/img/favicon.ico"))
router.HandleFunc("/robots.txt", serveFile("./assets/robots.txt"))
@@ -259,11 +264,8 @@ func defineRoutes() http.ServeMux {
router.Handle("/css/", http.FileServer(http.Dir("./assets/css")))
router.Handle("/js/", http.FileServer(http.Dir("./assets/js")))
// server.Use(recover.New(recover.Config{EnableStackTrace: config.GlobalServerConfig.InDevelopment}))
// // Routes
// server.Get("/", routes.IndexPage)
// Routes
router.Get("/").Handler(CatchError(routes.IndexPage))
// server.Get("/about", routes.AboutPage)
// server.Get("/newest", routes.NewestPage)
// server.Get("/discovery", routes.DiscoveryPage)
@@ -303,8 +305,8 @@ func defineRoutes() http.ServeMux {
// server.Post("/tags", routes.AdvancedTagPost)
// // Legacy illust URL
// server.Get("/member_illust.php", func(c *http.Request) error {
// return c.Redirect("/artworks/" + c.Query("illust_id"))
// server.Get("/member_illust.php", func(r *http.Request) error {
// return r.Redirect("/artworks/" + r.Query("illust_id"))
// })
// // Proxy routes
@@ -315,3 +317,9 @@ func defineRoutes() http.ServeMux {
return router
}
func CatchError(handler func(w http.ResponseWriter, r routes.CompatRequest) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
GetUserContext(r).err = handler(w, routes.CompatRequest{Request: r})
}
}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"net/http"
)
func AboutPage(c *http.Request) error {
return Render(c, Data_about{
func AboutPage(w http.ResponseWriter, r CompatRequest) error {
return Render(w, r, Data_about{
Time: config.GlobalServerConfig.StartingTime,
Version: config.GlobalServerConfig.Version,
ImageProxy: config.GlobalServerConfig.ProxyServer.String(),
+23 -23
View File
@@ -11,14 +11,14 @@ import (
"github.com/tidwall/gjson"
)
func pixivPostRequest(c *http.Request, url, payload, token, csrf string, isJSON bool) error {
func pixivPostRequest(r *fiber.Ctx, url, payload, token, csrf string, isJSON bool) error {
requestBody := []byte(payload)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
if err != nil {
return err
}
req = req.WithContext(c.Context())
req = req.WithContext(r.Context())
req.Header.Add("User-Agent", "Mozilla/5.0")
req.Header.Add("Accept", "application/json")
req.Header.Add("Cookie", "PHPSESSID="+token)
@@ -59,15 +59,15 @@ func pixivPostRequest(c *http.Request, url, payload, token, csrf string, isJSON
return nil
}
func AddBookmarkRoute(c *http.Request) error {
token := session.GetPixivToken(c)
csrf := session.GetCookie(c, session.Cookie_CSRF)
func AddBookmarkRoute(w http.ResponseWriter, r CompatRequest) error {
token := session.GetPixivToken(r)
csrf := session.GetCookie(r, session.Cookie_CSRF)
if token == "" || csrf == "" {
return PromptUserToLoginPage(c)
return PromptUserToLoginPage(r)
}
id := c.Params("id")
id := r.Params("id")
if id == "" {
return errors.New("No ID provided.")
}
@@ -79,22 +79,22 @@ func AddBookmarkRoute(c *http.Request) error {
"comment": "",
"tags": []
}`, id)
if err := pixivPostRequest(c, URL, payload, token, csrf, true); err != nil {
if err := pixivPostRequest(r, URL, payload, token, csrf, true); err != nil {
return err
}
return c.SendString("Success")
return r.SendString("Success")
}
func DeleteBookmarkRoute(c *http.Request) error {
token := session.GetPixivToken(c)
csrf := session.GetCookie(c, session.Cookie_CSRF)
func DeleteBookmarkRoute(w http.ResponseWriter, r CompatRequest) error {
token := session.GetPixivToken(r)
csrf := session.GetCookie(r, session.Cookie_CSRF)
if token == "" || csrf == "" {
return PromptUserToLoginPage(c)
return PromptUserToLoginPage(r)
}
id := c.Params("id")
id := r.Params("id")
if id == "" {
return errors.New("No ID provided.")
}
@@ -102,31 +102,31 @@ func DeleteBookmarkRoute(c *http.Request) error {
// You can't unlike
URL := "https://www.pixiv.net/ajax/illusts/bookmarks/delete"
payload := fmt.Sprintf(`bookmark_id=%s`, id)
if err := pixivPostRequest(c, URL, payload, token, csrf, false); err != nil {
if err := pixivPostRequest(r, URL, payload, token, csrf, false); err != nil {
return err
}
return c.SendString("Success")
return r.SendString("Success")
}
func LikeRoute(c *http.Request) error {
token := session.GetPixivToken(c)
csrf := session.GetCookie(c, session.Cookie_CSRF)
func LikeRoute(w http.ResponseWriter, r CompatRequest) error {
token := session.GetPixivToken(r)
csrf := session.GetCookie(r, session.Cookie_CSRF)
if token == "" || csrf == "" {
return PromptUserToLoginPage(c)
return PromptUserToLoginPage(r)
}
id := c.Params("id")
id := r.Params("id")
if id == "" {
return errors.New("No ID provided.")
}
URL := "https://www.pixiv.net/ajax/illusts/like"
payload := fmt.Sprintf(`{"illust_id": "%s"}`, id)
if err := pixivPostRequest(c, URL, payload, token, csrf, true); err != nil {
if err := pixivPostRequest(r, URL, payload, token, csrf, true); err != nil {
return err
}
return c.SendString("Success")
return r.SendString("Success")
}
+7 -7
View File
@@ -8,13 +8,13 @@ import (
"net/http"
)
func ArtworkPage(c *http.Request) error {
id := c.Params("id")
func ArtworkPage(w http.ResponseWriter, r CompatRequest) error {
id := r.Params("id")
if _, err := strconv.Atoi(id); err != nil {
return fmt.Errorf("Invalid ID: %s", id)
}
illust, err := core.GetArtworkByID(c, id, true)
illust, err := core.GetArtworkByID(r, id, true)
if err != nil {
return err
}
@@ -26,10 +26,10 @@ func ArtworkPage(c *http.Request) error {
// monkey patching. assuming illust.Images[_].Large is used
for _, img := range illust.Images {
PreloadImage(c, img.Large)
PreloadImage(r, img.Large)
}
return Render(c, Data_artwork{
return Render(w, r, Data_artwork{
Illust: *illust,
Title: illust.Title,
MetaDescription: metaDescription,
@@ -39,6 +39,6 @@ func ArtworkPage(c *http.Request) error {
})
}
func PreloadImage(c *http.Request, url string) {
c.Response().Header.Add("Link", fmt.Sprintf("<%s>; rel=preload; as=image", url))
func PreloadImage(r *fiber.Ctx, url string) {
r.Response().Header.Add("Link", fmt.Sprintf("<%s>; rel=preload; as=image", url))
}
+7 -7
View File
@@ -10,19 +10,19 @@ import (
"net/http"
)
func ArtworkMultiPage(c *http.Request) error {
ids_ := c.Params("ids")
func ArtworkMultiPage(w http.ResponseWriter, r CompatRequest) error {
ids_ := r.Params("ids")
ids := strings.Split(ids_, ",")
artworks := make([]core.Illust, len(ids))
wg := sync.WaitGroup{}
// // gofiber/fasthttp's API is trash
// // i can't replace c.Context() with this
// // i can't replace r.Context() with this
// // so i guess we will have to wait for network traffic to finish on error
// ctx, cancel := context.WithCancel(c.Context())
// ctx, cancel := context.WithCancel(r.Context())
// defer cancel()
// c.SetUserContext(ctx)
// r.SetUserContext(ctx)
var err_global error = nil
for i, id := range ids {
if _, err := strconv.Atoi(id); err != nil {
@@ -34,7 +34,7 @@ func ArtworkMultiPage(c *http.Request) error {
go func(i int, id string) {
defer wg.Done()
illust, err := core.GetArtworkByID(c, id, false)
illust, err := core.GetArtworkByID(r, id, false)
if err != nil {
artworks[i] = core.Illust{
Title: err.Error(), // this might be flaky
@@ -58,7 +58,7 @@ func ArtworkMultiPage(c *http.Request) error {
return err_global
}
return Render(c, Data_artworkMulti{
return Render(w, r, Data_artworkMulti{
Artworks: artworks,
Title: fmt.Sprintf("(%d images)", len(artworks)),
})
+60
View File
@@ -0,0 +1,60 @@
package routes
import (
"net/http"
"net/url"
"github.com/gorilla/mux"
)
type CompatRequest struct {
*http.Request
}
func (r CompatRequest) BaseURL() string {
return (&url.URL{
Scheme: r.URL.Scheme,
Opaque: r.URL.Opaque,
User: r.URL.User,
Host: r.URL.Host,
}).String()
}
func (r CompatRequest) OriginalURL() string {
return (&url.URL{
Path: r.URL.Path,
RawPath: r.URL.RawPath,
OmitHost: r.URL.OmitHost,
ForceQuery: r.URL.ForceQuery,
RawQuery: r.URL.RawQuery,
Fragment: r.URL.Fragment,
RawFragment: r.URL.RawFragment,
}).String()
}
func (r CompatRequest) PageURL() string {
return r.URL.String()
}
func (r CompatRequest) Query(name string, defaultValue ...string) string {
if v := r.URL.Query().Get(name); v != "" {
return v
} else {
if len(defaultValue) == 0 {
return ""
} else {
return defaultValue[0]
}
}
}
// get path segment. no idea why it's called "params"
func (r CompatRequest) Params(name string, defaultValue ...string) string {
if v := mux.Vars(r.Request)[name]; v != "" {
return v
} else {
if len(defaultValue) == 0 {
return ""
} else {
return defaultValue[0]
}
}
}
+8 -8
View File
@@ -6,26 +6,26 @@ import (
"net/http"
)
func DiscoveryPage(c *http.Request) error {
mode := c.Query("mode", "safe")
func DiscoveryPage(w http.ResponseWriter, r CompatRequest) error {
mode := r.Query("mode", "safe")
works, err := core.GetDiscoveryArtwork(c, mode)
works, err := core.GetDiscoveryArtwork(r, mode)
if err != nil {
return err
}
urlc := utils.PartialURL{Path: "discovery", Query: map[string]string{"mode": mode}}
return Render(c, Data_discovery{Artworks: works, Title: "Discovery", Queries: urlc})
return Render(w, r, Data_discovery{Artworks: works, Title: "Discovery", Queries: urlc})
}
func NovelDiscoveryPage(c *http.Request) error {
mode := c.Query("mode", "safe")
func NovelDiscoveryPage(w http.ResponseWriter, r CompatRequest) error {
mode := r.Query("mode", "safe")
works, err := core.GetDiscoveryNovels(c, mode)
works, err := core.GetDiscoveryNovels(r, mode)
if err != nil {
return err
}
return Render(c, Data_novelDiscovery{Novels: works, Title: "Discovery"})
return Render(w, r, Data_novelDiscovery{Novels: works, Title: "Discovery"})
}
+17 -16
View File
@@ -1,46 +1,47 @@
package routes
import (
"net/http"
"codeberg.org/vnpower/pixivfe/v2/core"
"codeberg.org/vnpower/pixivfe/v2/session"
"net/http"
)
func IndexPage(c *http.Request) error {
func IndexPage(w http.ResponseWriter, r CompatRequest) error {
// If token is set, do the landing request...
if token := session.GetPixivToken(c); token != "" {
mode := c.Query("mode", "all")
if token := session.GetPixivToken(r); token != "" {
mode := r.Query("mode", "all")
works, err := core.GetLanding(c, mode)
works, err := core.GetLanding(r, mode)
if err != nil {
return err
}
return Render(c, Data_index{
Title: "Landing",
Data: *works,
return Render(w, r, Data_index{
Title: "Landing",
Data: *works,
LoggedIn: true,
})
}
// ...otherwise, default to today's illustration ranking
works, err := core.GetRanking(c, "daily", "illust", "", "1")
works, err := core.GetRanking(r, "daily", "illust", "", "1")
if err != nil {
return err
}
return Render(c, Data_index{
return Render(w, r, Data_index{
Title: "Landing",
NoTokenData: works,
LoggedIn: false,
LoggedIn: false,
})
}
func Oembed(c *http.Request) error {
pageURL := c.BaseURL()
artistName := c.Query("a", "")
artistURL := c.Query("u", "")
func Oembed(w http.ResponseWriter, r CompatRequest) error {
pageURL := r.BaseURL()
artistName := r.Query("a", "")
artistURL := r.Query("u", "")
data := fiber.Map{
"version": "1.0",
@@ -51,5 +52,5 @@ func Oembed(c *http.Request) error {
"author_url": artistURL,
}
return c.JSON(data)
return r.JSON(data)
}
+5 -5
View File
@@ -5,15 +5,15 @@ import (
"net/http"
)
func NewestPage(c *http.Request) error {
worktype := c.Query("type", "illust")
func NewestPage(w http.ResponseWriter, r CompatRequest) error {
worktype := r.Query("type", "illust")
r18 := c.Query("r18", "false")
r18 := r.Query("r18", "false")
works, err := core.GetNewestArtworks(c, worktype, r18)
works, err := core.GetNewestArtworks(r, worktype, r18)
if err != nil {
return err
}
return Render(c, Data_newest{Items: works, Title: "Newest works"})
return Render(w, r, Data_newest{Items: works, Title: "Newest works"})
}
+14 -8
View File
@@ -10,31 +10,37 @@ import (
"net/http"
)
func NovelPage(c *http.Request) error {
id := c.Params("id")
func NovelPage(w http.ResponseWriter, r CompatRequest) error {
id := r.Params("id")
if _, err := strconv.Atoi(id); err != nil {
return fmt.Errorf("Invalid ID: %s", id)
}
novel, err := core.GetNovelByID(c, id)
novel, err := core.GetNovelByID(r, id)
if err != nil {
return err
}
related, err := core.GetNovelRelated(c, id)
related, err := core.GetNovelRelated(r, id)
if err != nil {
return err
}
user, err := core.GetUserBasicInformation(c, novel.UserID)
user, err := core.GetUserBasicInformation(r, novel.UserID)
if err != nil {
return err
}
fontType := session.GetCookie(c, session.Cookie_NovelFontType, "gothic")
viewMode := session.GetCookie(c, session.Cookie_NovelViewMode, strconv.Itoa(novel.Settings.ViewMode))
fontType := session.GetCookie(r, session.Cookie_NovelFontType)
if fontType == "" {
fontType = "gothic"
}
viewMode := session.GetCookie(r, session.Cookie_NovelViewMode)
if viewMode == "" {
viewMode = strconv.Itoa(novel.Settings.ViewMode)
}
// println("fontType", fontType)
return Render(c, Data_novel{Novel: novel, NovelRelated: related, User: user, Title: novel.Title, FontType: fontType, ViewMode: viewMode, Language: strings.ToLower(novel.Language)})
return Render(w, r, Data_novel{Novel: novel, NovelRelated: related, User: user, Title: novel.Title, FontType: fontType, ViewMode: viewMode, Language: strings.ToLower(novel.Language)})
}
+18 -18
View File
@@ -9,55 +9,55 @@ import (
"codeberg.org/vnpower/pixivfe/v2/session"
)
func PromptUserToLoginPage(c *http.Request) error {
c.Status(http.StatusUnauthorized)
return Render(c, Data_unauthorized{})
func PromptUserToLoginPage(w http.ResponseWriter, r CompatRequest) error {
r.Status(http.StatusUnauthorized)
return Render(w, r, Data_unauthorized{})
}
func LoginUserPage(c *http.Request) error {
token := session.GetPixivToken(c)
func LoginUserPage(w http.ResponseWriter, r CompatRequest) error {
token := session.GetPixivToken(r)
if token == "" {
return PromptUserToLoginPage(c)
return PromptUserToLoginPage(r)
}
// The left part of the token is the member ID
userId := strings.Split(token, "_")
c.Redirect("/users/" + userId[0])
r.Redirect("/users/" + userId[0])
return nil
}
func LoginBookmarkPage(c *http.Request) error {
token := session.GetPixivToken(c)
func LoginBookmarkPage(w http.ResponseWriter, r CompatRequest) error {
token := session.GetPixivToken(r)
if token == "" {
return PromptUserToLoginPage(c)
return PromptUserToLoginPage(r)
}
// The left part of the token is the member ID
userId := strings.Split(token, "_")
c.Redirect("/users/" + userId[0] + "/bookmarks#checkpoint")
r.Redirect("/users/" + userId[0] + "/bookmarks#checkpoint")
return nil
}
func FollowingWorksPage(c *http.Request) error {
if token := session.GetPixivToken(c); token == "" {
return PromptUserToLoginPage(c)
func FollowingWorksPage(w http.ResponseWriter, r CompatRequest) error {
if token := session.GetPixivToken(r); token == "" {
return PromptUserToLoginPage(r)
}
mode := c.Query("mode", "all")
page := c.Query("page", "1")
mode := r.Query("mode", "all")
page := r.Query("page", "1")
pageInt, err := strconv.Atoi(page)
if err != nil {
return err
}
works, err := core.GetNewestFromFollowing(c, mode, page)
works, err := core.GetNewestFromFollowing(r, mode, page)
if err != nil {
return err
}
return Render(c, Data_following{Title: "Following works", Mode: mode, Artworks: works, CurPage: page, Page: pageInt})
return Render(w, r, Data_following{Title: "Following works", Mode: mode, Artworks: works, CurPage: page, Page: pageInt})
}
+9 -11
View File
@@ -7,33 +7,31 @@ import (
"net/http"
)
func PixivisionHomePage(c *http.Request) error {
// Note: don't process images here?
func PixivisionHomePage(w http.ResponseWriter, r CompatRequest) error {
data, err := pixivision.GetHomepage()
if err != nil {
return err
}
for i := range data {
data[i].Thumbnail = session.ProxyImageUrlNoEscape(c, data[i].Thumbnail)
data[i].Thumbnail = session.ProxyImageUrlNoEscape(r, data[i].Thumbnail)
}
return Render(c, Data_pixivision_index{Data: data})
return Render(w, r, Data_pixivision_index{Data: data})
}
func PixivisionArticlePage(c *http.Request) error {
// Note: don't process images here?
id := c.Params("id")
func PixivisionArticlePage(w http.ResponseWriter, r CompatRequest) error {
id := r.Params("id")
data, err := pixivision.GetArticle(id)
if err != nil {
return err
}
data.Thumbnail = session.ProxyImageUrlNoEscape(c, data.Thumbnail)
data.Thumbnail = session.ProxyImageUrlNoEscape(r, data.Thumbnail)
for i := range data.Items {
data.Items[i].Image = session.ProxyImageUrlNoEscape(c, data.Items[i].Image)
data.Items[i].Avatar = session.ProxyImageUrlNoEscape(c, data.Items[i].Avatar)
data.Items[i].Image = session.ProxyImageUrlNoEscape(r, data.Items[i].Image)
data.Items[i].Avatar = session.ProxyImageUrlNoEscape(r, data.Items[i].Avatar)
}
return Render(c, Data_pixivision_article{Article: data})
return Render(w, r, Data_pixivision_article{Article: data})
}
+19 -54
View File
@@ -6,78 +6,43 @@ import (
"net/http"
)
func SPximgProxy(c *http.Request) error {
URL := fmt.Sprintf("https://s.pximg.net/%s", c.Params("*"))
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return err
}
req = req.WithContext(c.Context())
func makeRequest(w http.ResponseWriter, req *http.Request) error {
// Make the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
c.Set("Content-Type", resp.Header.Get("Content-Type"))
return c.Send([]byte(body))
_, err = io.Copy(w, resp.Body)
return err
}
func IPximgProxy(c *http.Request) error {
URL := fmt.Sprintf("https://i.pximg.net/%s", c.Params("*"))
func SPximgProxy(w http.ResponseWriter, r CompatRequest) error {
URL := fmt.Sprintf("https://s.pximg.net/%s", r.Params("*"))
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return err
}
return makeRequest(w, req.WithContext(r.Context()))
}
func IPximgProxy(w http.ResponseWriter, r CompatRequest) error {
URL := fmt.Sprintf("https://i.pximg.net/%s", r.Params("*"))
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return err
}
req = req.WithContext(c.Context())
req.Header.Add("Referer", "https://www.pixiv.net/")
// Make the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
c.Set("Content-Type", resp.Header.Get("Content-Type"))
return c.Send([]byte(body))
return makeRequest(w, req.WithContext(r.Context()))
}
func UgoiraProxy(c *http.Request) error {
URL := fmt.Sprintf("https://ugoira.com/api/mp4/%s", c.Params("*"))
func UgoiraProxy(w http.ResponseWriter, r CompatRequest) error {
URL := fmt.Sprintf("https://ugoira.com/api/mp4/%s", r.Params("*"))
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return err
}
req = req.WithContext(c.Context())
// Make the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
c.Set("Content-Type", resp.Header.Get("Content-Type"))
return c.Send([]byte(body))
return makeRequest(w, req.WithContext(r.Context()))
}
+7 -7
View File
@@ -7,21 +7,21 @@ import (
"net/http"
)
func RankingPage(c *http.Request) error {
mode := c.Query("mode", "daily")
content := c.Query("content", "all")
date := c.Query("date", "")
func RankingPage(w http.ResponseWriter, r CompatRequest) error {
mode := r.Query("mode", "daily")
content := r.Query("content", "all")
date := r.Query("date", "")
page := c.Query("page", "1")
page := r.Query("page", "1")
pageInt, err := strconv.Atoi(page)
if err != nil {
return err
}
works, err := core.GetRanking(c, mode, content, date, page)
works, err := core.GetRanking(r, mode, content, date, page)
if err != nil {
return err
}
return Render(c, Data_rank{Title: "Ranking", Page: pageInt, PageLimit: 10, Date: date, Data: works})
return Render(w, r, Data_rank{Title: "Ranking", Page: pageInt, PageLimit: 10, Date: date, Data: works})
}
+10 -10
View File
@@ -33,11 +33,11 @@ func parseDate(t time.Time) DateWrap {
return d
}
func RankingCalendarPicker(c *http.Request) error {
mode := c.FormValue("mode", "daily")
date := c.FormValue("date", "")
func RankingCalendarPicker(w http.ResponseWriter, r CompatRequest) error {
mode := r.FormValue("mode", "daily")
date := r.FormValue("date", "")
return c.RedirectToRoute("/rankingCalendar", fiber.Map{
return r.RedirectToRoute("/rankingCalendar", fiber.Map{
"queries": map[string]string{
"mode": mode,
"date": date,
@@ -45,9 +45,9 @@ func RankingCalendarPicker(c *http.Request) error {
})
}
func RankingCalendarPage(c *http.Request) error {
mode := c.Query("mode", "daily")
date := c.Query("date", "")
func RankingCalendarPage(w http.ResponseWriter, r CompatRequest) error {
mode := r.Query("mode", "daily")
date := r.Query("date", "")
var year int
var month int
@@ -64,7 +64,7 @@ func RankingCalendarPage(c *http.Request) error {
return err
}
} else {
now := c.Context().Time()
now := r.Context().Time()
year = now.Year()
month = int(now.Month())
}
@@ -73,10 +73,10 @@ func RankingCalendarPage(c *http.Request) error {
monthBefore := realDate.AddDate(0, -1, 0)
monthAfter := realDate.AddDate(0, 1, 0)
render, err := core.GetRankingCalendar(c, mode, year, month)
render, err := core.GetRankingCalendar(r, mode, year, month)
if err != nil {
return err
}
return Render(c, Data_rankingCalendar{Title: "Ranking calendar", Render: render, Mode: mode, Year: year, MonthBefore: parseDate(monthBefore), MonthAfter: parseDate(monthAfter), ThisMonth: parseDate(realDate)})
return Render(w, r, Data_rankingCalendar{Title: "Ranking calendar", Render: render, Mode: mode, Year: year, MonthBefore: parseDate(monthBefore), MonthAfter: parseDate(monthAfter), ThisMonth: parseDate(realDate)})
}
+7 -21
View File
@@ -33,10 +33,9 @@ func InitTemplatingEngine(DisableCache bool) {
}
}
func Render[T any](w http.ResponseWriter, r *http.Request, data T) error {
// Pass in values that we want to be available to all pages here
r.Response.Header.Set("content-type", "text/html; charset=utf-8")
// render the template selected based on the name of type `T`
func Render[T any](w http.ResponseWriter, r CompatRequest, data T) error {
w.Header().Set("content-type", "text/html; charset=utf-8")
return RenderInner(w, GetTemplatingVariables(r), data)
}
@@ -56,25 +55,12 @@ func RenderInner[T any](w io.Writer, variables jet.VarMap, data T) error {
return template.Execute(w, variables, data)
}
func GetTemplatingVariables(r *http.Request) jet.VarMap {
func GetTemplatingVariables(r CompatRequest) jet.VarMap {
// Pass in values that we want to be available to all pages here
token := session.GetPixivToken(r)
baseURL := (&url.URL{
Scheme: r.URL.Scheme,
Opaque: r.URL.Opaque,
User: r.URL.User,
Host: r.URL.Host,
}).String()
originalURL := (&url.URL{
Path: r.URL.Path,
RawPath: r.URL.RawPath,
OmitHost: r.URL.OmitHost,
ForceQuery: r.URL.ForceQuery,
RawQuery: r.URL.RawQuery,
Fragment: r.URL.Fragment,
RawFragment: r.URL.RawFragment,
}).String()
pageURL := r.URL.String()
baseURL := r.BaseURL()
originalURL := r.OriginalURL()
pageURL := r.PageURL()
cookies := map[string]string{}
for _, name := range session.AllCookieNames {
+1 -1
View File
@@ -47,7 +47,7 @@ type Data_userAtom struct {
}
type Data_index struct {
Title string
LoggedIn bool
LoggedIn bool
Data core.LandingArtworks
NoTokenData core.Ranking
}
+50 -54
View File
@@ -17,13 +17,12 @@ import (
// todo: allow clear proxy
// todo: allow clear all settings
func setToken(c *http.Request) error {
// Parse the value from the form
token := c.FormValue("token")
func setToken(w http.ResponseWriter, r CompatRequest) error {
token := r.FormValue("token")
if token != "" {
URL := httpc.GetNewestFromFollowingURL("all", "1")
_, err := httpc.UnwrapWebAPIRequest(c.Context(), URL, token)
_, err := httpc.UnwrapWebAPIRequest(r.Context(), URL, token)
if err != nil {
return errors.New("Cannot authorize with supplied token.")
}
@@ -34,7 +33,7 @@ func setToken(c *http.Request) error {
if err != nil {
return err
}
req = req.WithContext(c.Context())
req = req.WithContext(r.Context())
req.Header.Add("User-Agent", "Mozilla/5.0")
req.AddCookie(&http.Cookie{
Name: "PHPSESSID",
@@ -60,81 +59,80 @@ func setToken(c *http.Request) error {
}
// Set the token
session.SetCookie(c, session.Cookie_Token, token)
session.SetCookie(c, session.Cookie_CSRF, csrf)
session.SetCookie(w, session.Cookie_Token, token)
session.SetCookie(w, session.Cookie_CSRF, csrf)
return nil
}
return errors.New("You submitted an empty/invalid form.")
}
func setImageServer(c *http.Request) error {
// Parse the value from the form
token := c.FormValue("image-proxy")
func setImageServer(w http.ResponseWriter, r CompatRequest) error {
token := r.FormValue("image-proxy")
if token != "" {
session.SetCookie(c, session.Cookie_ImageProxy, token)
session.SetCookie(w, session.Cookie_ImageProxy, token)
} else {
session.ClearCookie(c, session.Cookie_ImageProxy)
session.ClearCookie(r, session.Cookie_ImageProxy)
}
return nil
}
func setNovelFontType(c *http.Request) error {
fontType := c.FormValue("font-type")
func setNovelFontType(w http.ResponseWriter, r CompatRequest) error {
fontType := r.FormValue("font-type")
if fontType != "" {
session.SetCookie(c, session.Cookie_NovelFontType, fontType)
session.SetCookie(w, session.Cookie_NovelFontType, fontType)
}
return nil
}
func setNovelViewMode(c *http.Request) error {
viewMode := c.FormValue("view-mode")
func setNovelViewMode(w http.ResponseWriter, r CompatRequest) error {
viewMode := r.FormValue("view-mode")
if viewMode != "" {
session.SetCookie(c, session.Cookie_NovelViewMode, viewMode)
session.SetCookie(w, session.Cookie_NovelViewMode, viewMode)
}
return nil
}
func setThumbnailToNewTab(c *http.Request) error {
ttnt := c.FormValue("ttnt")
func setThumbnailToNewTab(w http.ResponseWriter, r CompatRequest) error {
ttnt := r.FormValue("ttnt")
if ttnt == "_blank" || ttnt == "_self" {
session.SetCookie(c, session.Cookie_ThumbnailToNewTab, ttnt)
session.SetCookie(w, session.Cookie_ThumbnailToNewTab, ttnt)
}
return nil
}
func setArtworkPreview(c *http.Request) error {
value := c.FormValue("app")
func setArtworkPreview(w http.ResponseWriter, r CompatRequest) error {
value := r.FormValue("app")
if value == "cover" || value == "button" || value == "" {
session.SetCookie(c, session.Cookie_ArtworkPreview, value)
session.SetCookie(w, session.Cookie_ArtworkPreview, value)
}
return nil
}
func setLogout(c *http.Request) error {
session.ClearCookie(c, session.Cookie_Token)
session.ClearCookie(c, session.Cookie_CSRF)
func setLogout(w http.ResponseWriter, r CompatRequest) error {
session.ClearCookie(r, session.Cookie_Token)
session.ClearCookie(r, session.Cookie_CSRF)
return nil
}
func setCookie(c *http.Request) error {
key := c.FormValue("key")
value := c.FormValue("value")
func setCookie(w http.ResponseWriter, r CompatRequest) error {
key := r.FormValue("key")
value := r.FormValue("value")
for _, cookie_name := range session.AllCookieNames {
if string(cookie_name) == key {
session.SetCookie(c, cookie_name, value)
session.SetCookie(w, cookie_name, value)
return nil
}
}
return fmt.Errorf("Invalid Cookie Name: %s", key)
}
func setRawCookie(c *http.Request) error {
raw := c.FormValue("raw")
func setRawCookie(w http.ResponseWriter, r CompatRequest) error {
raw := r.FormValue("raw")
lines := strings.Split(raw, "\n")
for _, line := range lines {
@@ -150,48 +148,46 @@ func setRawCookie(c *http.Request) error {
continue
}
session.SetCookie(c, name, value)
session.SetCookie(w, name, value)
}
return nil
}
func resetAll(c *http.Request) error {
session.ClearAllCookies(c)
func resetAll(w http.ResponseWriter, r CompatRequest) error {
session.ClearAllCookies(w)
return nil
}
func SettingsPage(c *http.Request) error {
return Render(c, Data_settings{WorkingProxyList: config.GetWorkingProxies(), ProxyList: config.BuiltinProxyList})
func SettingsPage(w http.ResponseWriter, r CompatRequest) error {
return Render(w, r, Data_settings{WorkingProxyList: config.GetWorkingProxies(), ProxyList: config.BuiltinProxyList})
}
func SettingsPost(c *http.Request) error {
// NOTE: VnPower: Future maintainers should leave this function alone.
t := c.Params("type")
noredirect := c.FormValue("noredirect", "") == ""
func SettingsPost(w http.ResponseWriter, r CompatRequest) error {
t := r.Params("type")
noredirect := r.FormValue("noredirect", "") == ""
var err error
switch t {
case "imageServer":
err = setImageServer(c)
err = setImageServer(r)
case "token":
err = setToken(c)
err = setToken(r)
case "logout":
err = setLogout(c)
err = setLogout(r)
case "reset-all":
err = resetAll(c)
err = resetAll(r)
case "novelFontType":
err = setNovelFontType(c)
err = setNovelFontType(r)
case "thumbnailToNewTab":
err = setThumbnailToNewTab(c)
err = setThumbnailToNewTab(r)
case "novelViewMode":
err = setNovelViewMode(c)
err = setNovelViewMode(r)
case "artworkPreview":
err = setArtworkPreview(c)
err = setArtworkPreview(r)
case "set-cookie":
err = setCookie(c)
err = setCookie(r)
case "raw":
err = setRawCookie(c)
err = setRawCookie(r)
default:
err = errors.New("No such setting is available.")
}
@@ -204,5 +200,5 @@ func SettingsPost(c *http.Request) error {
return nil
}
return c.Redirect("/settings", http.StatusSeeOther)
return r.Redirect("/settings", http.StatusSeeOther)
}
+32 -33
View File
@@ -9,14 +9,14 @@ import (
"codeberg.org/vnpower/pixivfe/v2/utils"
)
func TagPage(c *http.Request) error {
param := c.Params("name", c.Query("name"))
func TagPage(w http.ResponseWriter, r CompatRequest) error {
param := r.Params("name", r.Query("name"))
name, err := url.PathUnescape(param)
if err != nil {
return err
}
page := c.Query("page", "1")
page := r.Query("page", "1")
pageInt, err := strconv.Atoi(page)
if err != nil {
return err
@@ -26,51 +26,50 @@ func TagPage(c *http.Request) error {
// I made a struct type just to manage the queries
queries := core.SearchPageSettings{
Name: name,
Category: c.Query("category", "artworks"),
Order: c.Query("order", "date_d"),
Mode: c.Query("mode", "safe"),
Ratio: c.Query("ratio", ""),
Wlt: c.Query("wlt", ""),
Wgt: c.Query("wgt", ""),
Hlt: c.Query("hlt", ""),
Hgt: c.Query("hgt", ""),
Tool: c.Query("tool", ""),
Scd: c.Query("scd", ""),
Ecd: c.Query("ecd", ""),
Category: r.Query("category", "artworks"),
Order: r.Query("order", "date_d"),
Mode: r.Query("mode", "safe"),
Ratio: r.Query("ratio", ""),
Wlt: r.Query("wlt", ""),
Wgt: r.Query("wgt", ""),
Hlt: r.Query("hlt", ""),
Hgt: r.Query("hgt", ""),
Tool: r.Query("tool", ""),
Scd: r.Query("scd", ""),
Ecd: r.Query("ecd", ""),
Page: page,
}
tag, err := core.GetTagData(c, name)
tag, err := core.GetTagData(r, name)
if err != nil {
return err
}
result, err := core.GetSearch(c, queries)
result, err := core.GetSearch(r, queries)
if err != nil {
return err
}
urlc := utils.PartialURL{Path: "tags", Query: queries.ReturnMap()}
return Render(c, Data_tag{Title: "Results for " + name, Tag: tag, Data: *result, QueriesC: urlc, TrueTag: param, Page: pageInt})
return Render(w, r, Data_tag{Title: "Results for " + name, Tag: tag, Data: *result, QueriesC: urlc, TrueTag: param, Page: pageInt})
}
func AdvancedTagPost(c *http.Request) error {
return c.RedirectToRoute("/tags", fiber.Map{
func AdvancedTagPost(w http.ResponseWriter, r CompatRequest) error {
return r.RedirectToRoute("/tags", fiber.Map{
"queries": map[string]string{
"name": c.Query("name", c.FormValue("name")),
"category": c.Query("category", "artworks"),
"order": c.Query("order", "date_d"),
"mode": c.Query("mode", "safe"),
"ratio": c.Query("ratio"),
"page": c.Query("page", "1"),
"wlt": c.Query("wlt", c.FormValue("wlt")),
"wgt": c.Query("wgt", c.FormValue("wgt")),
"hlt": c.Query("hlt", c.FormValue("hlt")),
"hgt": c.Query("hgt", c.FormValue("hgt")),
"tool": c.Query("tool", c.FormValue("tool")),
"scd": c.Query("scd", c.FormValue("scd")),
"ecd": c.Query("ecd", c.FormValue("ecd")),
"name": r.Query("name", r.FormValue("name")),
"category": r.Query("category", "artworks"),
"order": r.Query("order", "date_d"),
"mode": r.Query("mode", "safe"),
"ratio": r.Query("ratio"),
"page": r.Query("page", "1"),
"wlt": r.Query("wlt", r.FormValue("wlt")),
"wgt": r.Query("wgt", r.FormValue("wgt")),
"hlt": r.Query("hlt", r.FormValue("hlt")),
"hgt": r.Query("hgt", r.FormValue("hgt")),
"tool": r.Query("tool", r.FormValue("tool")),
"scd": r.Query("scd", r.FormValue("scd")),
"ecd": r.Query("ecd", r.FormValue("ecd")),
},
}, http.StatusFound)
}
+13 -13
View File
@@ -16,24 +16,24 @@ type userPageData struct {
page int
}
func fetchData(c *http.Request, getTags bool) (userPageData, error) {
id := c.Params("id")
func fetchData(r *fiber.Ctx, getTags bool) (userPageData, error) {
id := r.Params("id")
if _, err := strconv.Atoi(id); err != nil {
return userPageData{}, err
}
category := core.UserArtCategory(c.Params("category", string(core.UserArt_Any)))
category := core.UserArtCategory(r.Params("category", string(core.UserArt_Any)))
err := category.Validate()
if err != nil {
return userPageData{}, err
}
page_param := c.Query("page", "1")
page_param := r.Query("page", "1")
page, err := strconv.Atoi(page_param)
if err != nil {
return userPageData{}, err
}
user, err := core.GetUserArtwork(c, id, category, page, getTags)
user, err := core.GetUserArtwork(r, id, category, page, getTags)
if err != nil {
return userPageData{}, err
}
@@ -53,25 +53,25 @@ func fetchData(c *http.Request, getTags bool) (userPageData, error) {
return userPageData{user, category, pageLimit, page}, nil
}
func UserPage(c *http.Request) error {
data, err := fetchData(c, true)
func UserPage(w http.ResponseWriter, r CompatRequest) error {
data, err := fetchData(r, true)
if err != nil {
return err
}
return Render(c, Data_user{Title: data.user.Name, User: data.user, Category: data.category, PageLimit: data.pageLimit, Page: data.page, MetaImage: data.user.BackgroundImage})
return Render(w, r, Data_user{Title: data.user.Name, User: data.user, Category: data.category, PageLimit: data.pageLimit, Page: data.page, MetaImage: data.user.BackgroundImage})
}
func UserAtomFeed(c *http.Request) error {
data, err := fetchData(c, false)
func UserAtomFeed(w http.ResponseWriter, r CompatRequest) error {
data, err := fetchData(r, false)
if err != nil {
return err
}
c.Context().SetContentType("application/atom+xml")
w.Header().Set("content-type", "application/atom+xml")
return Render(c, Data_userAtom{
URL: string(c.Request().RequestURI()),
return Render(w, r, Data_userAtom{
URL: r.RequestURI,
Title: data.user.Name,
User: data.user,
Category: data.category,
+14 -1
View File
@@ -102,7 +102,7 @@ rules:
exclude:
- "render_types.go"
fix: |
Render(c, Data_$NAME{$...INSIDE})
Render(w, r, Data_$NAME{$...INSIDE})
- id: rule-8
message: "c.Render"
languages: [go]
@@ -117,3 +117,16 @@ rules:
paths:
exclude:
- "render.go"
- id: rule-9
message: "still using *fiber.Ctx"
languages: [go]
severity: INFO
patterns:
- pattern: |
func $NAME(c *fiber.Ctx) error {
$...I
}
fix: |
func $NAME(w http.ResponseWriter, r *http.Request) error {
$...I
}
+12 -12
View File
@@ -9,12 +9,12 @@ import (
config "codeberg.org/vnpower/pixivfe/v2/config"
)
func GetPixivToken(c *http.Request) string {
return GetCookie(c, Cookie_Token)
func GetPixivToken(r *http.Request) string {
return GetCookie(r, Cookie_Token)
}
func GetImageProxy(c *http.Request) url.URL {
value := GetCookie(c, Cookie_ImageProxy)
func GetImageProxy(r *http.Request) url.URL {
value := GetCookie(r, Cookie_ImageProxy)
if value == "" {
// fall through to default case
} else {
@@ -28,29 +28,29 @@ func GetImageProxy(c *http.Request) url.URL {
return config.GlobalServerConfig.ProxyServer
}
func ProxyImageUrl(c *http.Request, s string) string {
proxyOrigin := GetImageProxyPrefix(c)
func ProxyImageUrl(r *http.Request, s string) string {
proxyOrigin := GetImageProxyPrefix(r)
s = strings.ReplaceAll(s, `https:\/\/i.pximg.net`, proxyOrigin)
// 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 ProxyImageUrlNoEscape(c *http.Request, s string) string {
proxyOrigin := GetImageProxyPrefix(c)
func ProxyImageUrlNoEscape(r *http.Request, s string) string {
proxyOrigin := GetImageProxyPrefix(r)
s = strings.ReplaceAll(s, `https://i.pximg.net`, proxyOrigin)
// 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 GetImageProxyOrigin(c *http.Request) string {
url := GetImageProxy(c)
func GetImageProxyOrigin(r *http.Request) string {
url := GetImageProxy(r)
return urlAuthority(url)
}
func GetImageProxyPrefix(c *http.Request) string {
url := GetImageProxy(c)
func GetImageProxyPrefix(r *http.Request) string {
url := GetImageProxy(r)
return urlAuthority(url) + url.Path
// note: not sure if url.EscapedPath() is useful here. go's standard library is trash at handling URL (:// should be part of the scheme)
}
+14 -19
View File
@@ -37,35 +37,31 @@ var AllCookieNames []CookieName = []CookieName{
Cookie_ShowArtAI,
}
func GetCookie(c *http.Request, name CookieName, defaultValue ...string) string {
//return c.Cookies(string(name), defaultValue...)
if cookie, err := c.Cookie(string(name)); err != nil {
return cookie.Value
func GetCookie(r *http.Request, name CookieName) string {
cookie, err := r.Cookie(string(name))
if err != nil {
return ""
}
// TODO: Hard-coded?
return defaultValue[0]
return cookie.Value
}
func SetCookie(c *http.Request, name CookieName, value string) {
cookie := http.Cookie{
func SetCookie(w http.ResponseWriter, name CookieName, value string) {
http.SetCookie(w, &http.Cookie{
Name: string(name),
Value: value,
Path: "/",
// expires in 30 days from now
// Expires: c.Context().Time().Add(30 * (24 * time.Hour)),
Expires: time.Now().Add(30 * (24 * time.Hour)),
Expires: r.Context().Time().Add(30 * (24 * time.Hour)),
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteStrictMode, // bye-bye cross site forgery
}
c.AddCookie(&cookie)
})
}
var CookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
func ClearCookie(c *http.Request, name CookieName) {
cookie := http.Cookie{
func ClearCookie(w http.ResponseWriter, name CookieName) {
http.SetCookie(w, &http.Cookie{
Name: string(name),
Value: "",
Path: "/",
@@ -74,12 +70,11 @@ func ClearCookie(c *http.Request, name CookieName) {
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteStrictMode,
}
c.AddCookie(&cookie)
})
}
func ClearAllCookies(c *http.Request) {
func ClearAllCookies(w http.ResponseWriter) {
for _, name := range AllCookieNames {
ClearCookie(c, name)
ClearCookie(w, name)
}
}