Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0

Merge branch 'dev' into filelist-fetching

Cette révision appartient à :
kilo 2017-11-24 12:34:42 +01:00 révisé par GitHub
révision 0cf75e345a
Signature inconnue de Forgejo
ID de la clé GPG: 4AEE18F83AFDEB23
27 fichiers modifiés avec 238 ajouts et 97 suppressions

30
CODE_OF_CONDUCT.md Fichier normal
Voir le fichier

@ -0,0 +1,30 @@
**You have been visited by the CoC(K)**
_.+._
(^\/^\/^)
\@☆@☆@/
CoC(k) {_____}
Code Of Conduct Killer _oOPPYbo.
_,ooO8O' `Ob
_,ooOPP"' Ob dO
_oooOP"'' `Oo. ,O[
Ob _,ooOPP'' `YYboOP
`O[ _ooOP"'' _,oOPP"'
YOooooOP' _ooOP"'
'' ,ooOP''
,odPP''
_,oOP'
ooOP"'
_oOP'o
,OP YOL
,O. ,OP Yb contribute code or you're a racist
dO' " Yb get offended as a responsible adult
]O. dO spread this like happy herpes
Ob _,o. dOP
`Ooo___ooOP'`YbooodPP just imagine what would happen
'`"""'' `''' if we all decided to understand
Sweet blessing be upon you but **ONLY** if comment `ebin` to this commit.

Voir le fichier

@ -39,6 +39,7 @@ func getTorrentList(c *gin.Context) (torrents []models.Torrent, createdAsTime ti
title = "Sukebei Pantsu"
}
pagenum := 1
if page == "" && offset > 0 { // first page for offset is 0
pagenum = offset + 1
@ -86,7 +87,12 @@ func getTorrentList(c *gin.Context) (torrents []models.Torrent, createdAsTime ti
user = 0
}
_, torrents, _, err = search.AuthorizedQuery(c, pagenum, currentUser.CurrentOrJanitor(uint(user)), currentUser.CurrentOrJanitor(uint(user)))
var searchParam search.TorrentParam
searchParam, torrents, _, err = search.AuthorizedQuery(c, pagenum, currentUser.CurrentOrJanitor(uint(user)), currentUser.CurrentOrJanitor(uint(user)))
if searchParam.NameLike != "" {
title += " - " + searchParam.NameLike
}
return
}

Voir le fichier

@ -9,11 +9,10 @@ import (
"github.com/NyaaPantsu/nyaa/controllers/router"
"github.com/NyaaPantsu/nyaa/models/comments"
"github.com/NyaaPantsu/nyaa/models/torrents"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/utils/captcha"
"github.com/NyaaPantsu/nyaa/utils/filelist"
msg "github.com/NyaaPantsu/nyaa/utils/messages"
"github.com/NyaaPantsu/nyaa/utils/sanitize"
"github.com/NyaaPantsu/nyaa/templates"
"github.com/gin-gonic/gin"
)
@ -39,6 +38,9 @@ func PostCommentHandler(c *gin.Context) {
if currentUser.IsBanned() {
messages.AddErrorT("errors", "account_banned")
}
if torrent.Status == models.TorrentStatusBlocked && !currentUser.CurrentOrJanitor(torrent.UploaderID) {
messages.AddErrorT("errors", "torrent_locked")
}
content := sanitize.Sanitize(c.PostForm("comment"), "comment")
userID := currentUser.ID
@ -60,12 +62,5 @@ func PostCommentHandler(c *gin.Context) {
}
}
captchaID := ""
//Generate a captcha
if currentUser.NeedsCaptcha() {
captchaID = captcha.GetID()
}
folder := filelist.FileListToFolder(torrent.FileList, "root")
templates.Torrent(c, torrent.ToJSON(), folder, captchaID)
ViewHandler(c)
}

Voir le fichier

@ -313,7 +313,11 @@ func (t *Torrent) ToJSON() TorrentJSON {
}
for _, c := range t.Comments {
if c.User != nil {
commentsJSON = append(commentsJSON, CommentJSON{Username: c.User.Username, UserID: int(c.User.ID), UserStatus: c.User.GetRole(), Content: sanitize.MarkdownToHTML(c.Content), Date: c.CreatedAt.UTC(), UserAvatar: c.User.MD5})
role := c.User.GetRole()
if t.UploaderID == c.User.ID && !c.User.IsBanned() {
role = "userstatus_uploader"
}
commentsJSON = append(commentsJSON, CommentJSON{Username: c.User.Username, UserID: int(c.User.ID), UserStatus: role, Content: sanitize.MarkdownToHTML(c.Content), Date: c.CreatedAt.UTC(), UserAvatar: c.User.MD5})
} else {
commentsJSON = append(commentsJSON, CommentJSON{})
}

Voir le fichier

@ -37,13 +37,11 @@ func NewTorrentEvent(user *models.User, torrent *models.Torrent) error {
url := "/view/" + strconv.FormatUint(uint64(torrent.ID), 10)
if user.ID > 0 && config.Get().Users.DefaultUserSettings["new_torrent"] { // If we are a member and notifications for new torrents are enabled
user.GetFollowers() // We populate the liked field for users
if len(user.Followers) > 0 { // If we are followed by at least someone
for _, follower := range user.Followers {
follower.ParseSettings() // We need to call it before checking settings
if follower.Settings.Get("new_torrent") {
T, _, _ := publicSettings.TfuncAndLanguageWithFallback(follower.Language, follower.Language) // We need to send the notification to every user in their language
notifications.NotifyUser(&follower, torrent.Identifier(), fmt.Sprintf(T("new_torrent_uploaded"), torrent.Name, user.Username), url, follower.Settings.Get("new_torrent_email"))
}
for _, follower := range user.Followers {
follower.ParseSettings() // We need to call it before checking settings
if follower.Settings.Get("new_torrent") {
T, _, _ := publicSettings.TfuncAndLanguageWithFallback(follower.Language, follower.Language) // We need to send the notification to every user in their language
notifications.NotifyUser(&follower, torrent.Identifier(), fmt.Sprintf(T("new_torrent_uploaded"), torrent.Name, user.Username), url, follower.Settings.Get("new_torrent_email"))
}
}
}

Voir le fichier

@ -260,17 +260,19 @@ func (u *User) ToJSON() UserJSON {
}
// GetLikings : Gets who is followed by the user
func (u *User) GetLikings() {
func (u *User) GetLikings() int {
var liked []User
ORM.Joins("JOIN user_follows on user_follows.following=?", u.ID).Where("users.user_id = user_follows.user_id").Group("users.user_id").Find(&liked)
u.Likings = liked
return len(u.Likings)
}
// GetFollowers : Gets who is following the user
func (u *User) GetFollowers() {
func (u *User) GetFollowers() int {
var likings []User
ORM.Joins("JOIN user_follows on user_follows.user_id=?", u.ID).Where("users.user_id = user_follows.following").Group("users.user_id").Find(&likings)
u.Followers = likings
return len(u.Followers)
}
// SetFollow : Makes a user follow another
@ -278,6 +280,7 @@ func (u *User) SetFollow(follower *User) {
if follower.ID > 0 && u.ID > 0 {
var userFollows = UserFollows{UserID: u.ID, FollowerID: follower.ID}
ORM.Create(&userFollows)
u.Likings = append(u.Likings, *follower)
}
}
@ -286,6 +289,15 @@ func (u *User) RemoveFollow(follower *User) {
if follower.ID > 0 && u.ID > 0 {
var userFollows = UserFollows{UserID: u.ID, FollowerID: follower.ID}
ORM.Delete(&userFollows)
for i, followr := range u.Likings {
if followr.ID == follower.ID {
u.Likings[i] = u.Likings[len(u.Likings)-1]
// The very last follower will take the place of the one that is getting deleted in the array
u.Likings = u.Likings[:len(u.Likings)-1]
// We now proceed to delete the very last array element since it got copied to another position
return
}
}
}
}

Voir le fichier

@ -452,8 +452,12 @@ select.form-input {
margin-bottom: 0;
width: 85px!important;
}
.refine-container-2 [name="hash"] {
float: right;
width: 187px!important;
}
.refine-date {
width: 98px!important;
width: 135px!important;
}
.categories a {
@ -462,7 +466,7 @@ select.form-input {
padding: 10px 5px;
}
#announce {
.announce {
margin-bottom: 4px;
padding: 7px 10px;
background-color: #D9EDF7;
@ -470,7 +474,7 @@ select.form-input {
border-radius: 7px;
}
#announce:before {
.announce:before {
content: "!";
vertical-align: middle;
float: left;
@ -478,6 +482,13 @@ select.form-input {
font-size: 2.2em;
font-weight: bold;
}
.announcement-content :first-child {
margin-top: 0;
}
.announcement-content :last-child {
margin-bottom: 0;
}
.results {
padding: 0!important;
@ -857,6 +868,9 @@ html, body {
float: none!important;
max-width: none;
}
.refine-container-2 [name="hash"] {
float: none;
}
.upload-form-table .table-checkboxes {
padding: 3px 0!important;
width: 100%;

Voir le fichier

@ -767,14 +767,9 @@ span.tag {
.torrent-info-data #subscribe-link::before, .torrent-info-data #subscribe-link:: after {
color: #111111;
}
.content > p:first-child+div.centered+div.refine+div #reportPopup {
top: 145px;
}
.content > p:first-child+div#announce+div.refine+div #reportPopup {
top: 110px;
}
.content > div#announce:first-child+div.refine+div #reportPopup {
top: 65px;
.box {
position: relative;
}
#reportPopup {
text-decoration: underline dotted;
@ -783,8 +778,8 @@ span.tag {
background: none;
color: #106655!important;
position: absolute;
top: 103px;
right: 11px;
top: 6px;
right: 0;
}
.comment-content :first-child {
margin-top: 5px;

Voir le fichier

@ -163,7 +163,7 @@ td.tr-le, .error-text {
background-size: 100%;
}
#announce {
.announce {
color: #3a4249;
background-color: #fff5e7;
border-color: #ecd2ae;

Voir le fichier

@ -238,7 +238,7 @@ a.form-input[class*="btn"]:hover {
background: #cc4f4f;
}
#announce {
.announce {
color: #3a4249;
background-color: #F4E0C9;
border-color: #ae875b;

Voir le fichier

@ -7,7 +7,7 @@
<form style="text-align:left;padding-left:10px;padding-right:10px;" method="POST" action="{{ if Form.ID > 0}}?id={{ Form.ID }}{{end}}">
<div class="form-group">
<label for="message">{{ T("message")}}</label>
<textarea name="message" id="message" class="form-input up-input" placeholder="{{ T("message")}}" required>{{Form.Message}}</textarea>
<textarea name="message" id="message" class="form-input up-input markdown-container" placeholder="{{ T("message")}}" required>{{Form.Message}}</textarea>
{{ yield errors(name="Message")}}
</div>
<div class="form-group">
@ -19,3 +19,7 @@
</form>
</div>
{{end}}
{{ block footer_js()}}
<script type="text/javascript" src="{{ URL.Parse("/js/simplemde.min.js") }}"></script>
<script type="text/javascript">new SimpleMDE({ element: document.getElementById("message"), spellChecker: false, showIcons: [ "strikethrough", "code", "table", "horizontal-rule" ] });</script>
{{end}}

Voir le fichier

@ -99,7 +99,7 @@ var deleteButtons = document.querySelectorAll("button.form-input.btn-red")
e.preventDefault()
if(needConfirmation && !confirm("Are you sure?")) {
return
} else if(!needConfirmation) {
} else {
var form = this.parentNode
var formInputs = form.querySelectorAll('input')
var query = ""

Voir le fichier

@ -55,12 +55,12 @@ func NewSearchForm(c *gin.Context) SearchForm {
ShowRefine: false,
SizeType: sizeType,
User: c.Query("user"),
UserName: "",
UserName: "",
DateType: c.Query("dateType"),
MinSize: c.Query("minSize"), // We need to overwrite the value here, since size are formatted
MaxSize: c.Query("maxSize"), // We need to overwrite the value here, since size are formatted
FromDate: c.Query("fromDate"), // We need to overwrite the value here, since we can have toDate instead and date are formatted
ToDate: c.Query("toDate"), // We need to overwrite the value here, since date are formatted
SearchURL: "/search",
SearchURL: "/search",
}
}

Voir le fichier

@ -12,7 +12,7 @@
{{ block content_body_base()}}
{{ if isset(Infos["system"])}}
{{ range Infos["system"]}}
<div id="announce"><span style="font-weight:bold;">{{T("announcement")}}</span><br>{{ .|raw }}</div>
<div class="announce"><b>{{T("announcement")}}</b><br><span class="announcement-content">{{ .|raw }}</span></div>
{{ end }}
{{ end }}
{{ yield search_refine(url=URL.Parse(Search.SearchURL)) }}

Voir le fichier

@ -55,7 +55,6 @@
<input class="form-input refine-date" name="fromDate" type="text" value="{{Search.FromDate}}" placeholder="YYYY/MM/DD"/>
{{ T("to")}}
<input class="form-input refine-date spacing" size="7" name="toDate" type="text" value="{{Search.ToDate}}" placeholder="YYYY/MM/DD"/>
{{ T("exclude_user") }}: <input type="text" name="nuserID" placeholder="UserID" value="" class="form-input refine-userid" style="width: 62px;">
</span>
<span class="form-refine" style="margin-bottom: 2px;">
<span class="spacing">{{T("sort_by")}}</span>
@ -71,6 +70,7 @@
<option value="true">{{T("ascending")}}</option>
<option value="false" {{if !Search.Order}}selected{{end}}>{{T("descending")}}</option>
</select>
{{ T("exclude_user") }}: <input type="text" name="nuserID" placeholder="UserID" value="" class="form-input refine-userid" style="width: 62px;">
</span>
</div>
<div class="refine-container-2">
@ -83,7 +83,7 @@
{{end}}
</select>
<span style="margin: 0 5px;">Hash:</span>
<input type="text" name="hash" placeholder="Torrent hash" class="form-input" value="" style="width: 218px!important">
<input type="text" name="hash" placeholder="Torrent hash" class="form-input">
</span>
<span class="form-refine">
<span class="spacing">Tags:</span>

Voir le fichier

@ -1,6 +1,6 @@
{{ extends "layouts/index_site" }}
{{ import "layouts/partials/helpers/search" }}
{{block title()}}{{if Search.UserName != ""}}{{Search.UserName}}{{else if Search.NameLike != ""}}{{Search.NameLike}}{{else if Search.Category != ""}}{{T(GetCategoryName(Search.Category))}}{{else}}{{ T("home")}}{{end}}{{end}}
{{block title()}}{{GenSearchName(Search, URL.String(), T)}}{{end}}
{{block contclass()}}{{if User.IsModerator() }}content-admin{{end}}{{end}}
{{block content_body()}}
{{ if OldNav || Theme == "classic"}}

Voir le fichier

@ -66,27 +66,6 @@
<td class="table-input-label"><label for="desc">{{ T("torrent_description")}}</label></td>
<td class="table-input markdown-container"><textarea name="desc" id="desc" class="form-input up-input" style="height: 10rem;">{{Form.Description}}</textarea></td>
</tr>
<tr class="hidden">
<td class="table-input-label"><label for="anidex_api">Upload to Anidex:</label></td>
<td class="table-input">
<div class="checkbox-container"><input disabled type="checkbox" value="" name="anidex_upload" id="anidex_upload" {{if User.AnidexAPIToken != ""}}checked disabled{{end}} class="form-torrent"/></div>
<input disabled name="anidex_api" id="anidex_api" placeholder="Coming soon... (hopefully)" class="form-input up-input" type="text" value="{{User.AnidexAPIToken}}"/>
</td>
</tr>
<tr class="hidden">
<td class="table-input-label"><label for="nyaasi_api">Upload to Nyaa.si:</label></td>
<td class="table-input">
<div class="checkbox-container"><input disabled type="checkbox" value="" name="nyaasi_upload" id="nyaasi_upload" {{if User.NyaasiAPIToken != ""}}checked disabled{{end}} class="form-torrent"/></div>
<input disabled name="nyaasi_api" id="nyaasi_api" placeholder="Coming soon... (hopefully)" class="form-input up-input" type="text" value="{{User.NyaasiAPIToken}}"/>
</td>
</tr>
<tr class="hidden">
<td class="table-input-label"><label for="tokyot_api">Upload to TokyoTosho:</label></td>
<td class="table-input">
<div class="checkbox-container"><input disabled type="checkbox" value="" name="tokyot_upload" id="tokyot_upload" {{if User.TokyoTAPIToken != ""}}checked disabled{{end}} class="form-torrent"/></div>
<input disabled name="tokyot_api" id="tokyot_api" placeholder="Coming soon... (hopefully)" class="form-input up-input" type="text" value="{{User.TokyoTAPIToken }}"/>
</td>
</tr>
<tr>
<td class="table-input-label">{{ T("torrent_tags")}}:</td>
<td class="table-input">

Voir le fichier

@ -155,6 +155,23 @@
</table>
</div>
<div class="torrent-buttons">
{{ if User.IsModerator() }}
<form enctype="multipart/form-data" method="POST" action="{{ if !Sukebei()}}{{Config.WebAddress.Sukebei}}/upload{{else}}{{Config.WebAddress.Nyaa}}/upload{{end}}" id="copy-torrent">
{{ yield csrf_field()}}
<input type="hidden" name="name" value="{{Torrent.Name}}">
<input type="hidden" name="magnet" value="{{Torrent.Magnet}}">
<input type="hidden" name="c" value="{{Torrent.Category}}_{{Torrent.SubCategory}}">
<input type="hidden" name="desc" value="{{Torrent.Description}}">
<input type="hidden" name="hidden" value="{{Torrent.Hidden}}">
<input type="hidden" name="remake" value="{{Torrent.Status == 2}}">
<input type="hidden" name="website_link" value="{{Torrent.WebsiteLink}}">
<input type="hidden" name="filesize" value="{{Torrent.Filesize}}">
{{ range _, lang := Torrent.Languages}}
<input type="hidden" name="languages" value="{{lang}}">
{{end}}
<input type="submit" class="form-input btn-blue" style="float: right;" value="Upload to {{if Sukebei()}}Nyaa{{else}}Sukebei{{end}}">
</form>
{{end}}
<a href="{{Torrent.Magnet}}" class="form-input btn-green download" style="float:left;height: auto;margin-right: 0.5em;">
<div class="icon-magnet"></div>{{ T("magnet_link")}}
</a>

Voir le fichier

@ -1,6 +1,6 @@
{{ extends "layouts/profile" }}
{{ import "layouts/partials/menu/profile" }}
{{block title()}}{{ T("profile_edit_page", User.Username) }}{{end}}
{{block title()}}{{ T("my_notifications") }}{{end}}
{{ block profile_navigation()}}{{ yield profile_menu(route="profile") }}{{end}}
{{block profile_content()}}
<table class="notification-table">

Voir le fichier

@ -188,7 +188,7 @@ func userProfileBase(c *gin.Context, templateName string, userProfile *models.Us
}
variables.Set("UserProfile", userProfile)
variables.Set("NbTorrents", []int64{int64(nbTorrents),uploadedSize})
variables.Set("NbTorrents", []int64{int64(nbTorrents), uploadedSize})
Render(c, path.Join(SiteDir, "user", templateName), variables)
}

Voir le fichier

@ -42,6 +42,7 @@ func templateFunctions(vars jet.VarMap) jet.VarMap {
vars.Set("CategoryName", categoryName)
vars.Set("GetCategoryName", GetCategoryName)
vars.Set("GetTorrentLanguages", torrentLanguages.GetTorrentLanguages)
vars.Set("GenSearchName", GenSearchName)
vars.Set("LanguageName", languageName)
vars.Set("LanguageNameFromCode", languageNameFromCode)
vars.Set("fileSize", fileSize)
@ -346,7 +347,7 @@ func torrentFileExists(hash string, TorrentLink string) bool {
return true
}
Openfile, err := os.Open(fmt.Sprintf("%s%c%s.torrent", config.Get().Torrents.FileStorage, os.PathSeparator, hash))
if err != nil {
if err != nil || len(TorrentLink) == 0 {
//File doesn't exist
return false
}
@ -451,3 +452,19 @@ func formatDate(Date time.Time, short bool) string {
return fmt.Sprintf("%d/%d/%d, %d:%.2d:%.2d AM UTC+0", Date.Month(), Date.Day(), Date.Year(), Date.Hour(), Date.Minute(), Date.Second())
}
}
func GenSearchName(Search SearchForm, currentURL string, T publicSettings.TemplateTfunc) string {
if currentURL == "/" {
return string(T("home"))
}
if Search.UserName != "" {
return Search.UserName
}
if Search.NameSearch != "" {
return Search.NameSearch
}
if Search.Category != "" {
return string(T(GetCategoryName(Search.Category)))
}
return string(T("search"))
}

Voir le fichier

@ -830,6 +830,54 @@ func testFormatDate(t *testing.T) {
}
}
}
func testGenSearchName(t *testing.T) {
var tests = []struct {
Search SearchForm
currentURL string
Expected string
}{
{
Search: SearchForm{},
currentURL: "/",
Expected: "home",
},
{
Search: SearchForm{},
currentURL: "/search",
Expected: "search",
},
{
Search: SearchForm{UserName: "yiiT"},
currentURL: "/username/yiiT/search",
Expected: "yiiT",
},
{
Search: SearchForm{Category: "3_"},
currentURL: "/search?c=3_",
Expected: "anime",
},
{
Search: SearchForm{Category: "3_12"},
currentURL: "/search?c=3_12",
Expected: "anime_amv",
},
}
for _, test := range tests {
Ts, _, err := publicSettings.TfuncAndLanguageWithFallback("en-us")
if err != nil {
t.Error("Couldn't load language files!")
}
var T publicSettings.TemplateTfunc
T = func(id string, args ...interface{}) template.HTML {
return template.HTML(fmt.Sprintf(Ts(id), args...))
}
value := GenSearchName(test.Search, test.currentURL, T)
if value != test.Expected {
t.Errorf("Unexpected value from the function GenSearchName, got '%s' wanted '%s'", value, test.Expected)
}
}
}
func mockupTemplateT(t *testing.T) publicSettings.TemplateTfunc {
conf := config.Get().I18n

Voir le fichier

@ -9,7 +9,7 @@
},
{
"id": "no_cp",
"translation": "児童ポルノ禁止 (ロリはこれに含まれません)"
"translation": "児童ポルノ禁止 (ロリは OK)"
},
{
"id": "asia",
@ -1525,7 +1525,7 @@
},
{
"id": "activity_list",
"translation": "アクティビティー一覧"
"translation": "アクティビティー 一覧"
},
{
"id": "activities",
@ -1553,7 +1553,7 @@
},
{
"id": "error_less_date",
"translation": "%s は現在の日付およびより小さくなければなりません"
"translation": "%s は現在の日時より小さくなければなりません"
},
{
"id": "error_less_array",
@ -1569,11 +1569,11 @@
},
{
"id": "error_less_equal_date",
"translation": "%s は現在の日付および以下でなければなりません"
"translation": "%s は現在の日時以下でなければなりません"
},
{
"id": "error_greater_date",
"translation": "%s は現在の日付およびより大きくなければなりません"
"translation": "%s は現在の日時より大きくなければなりません"
},
{
"id": "error_greater_length",
@ -1585,7 +1585,7 @@
},
{
"id": "error_greater_equal_date",
"translation": "%s は現在の日付および以上でなければなりません"
"translation": "%s は現在の日時以上でなければなりません"
},
{
"id": "error_max_field",
@ -1689,7 +1689,7 @@
},
{
"id": "error_contains",
"translation": "%s にはテキスト '%s' が含まれている必要があります"
"translation": "%s には文字列 '%s' が含まれている必要があります"
},
{
"id": "error_contains_any",
@ -1765,7 +1765,7 @@
},
{
"id": "sort_by",
"translation": "ソート:"
"translation": "並べ替え:"
},
{
"id": "ascending",
@ -1913,7 +1913,7 @@
},
{
"id": "torrent_cat_is_english",
"translation": "Torrent カテゴリーは英語への翻訳となっていますが、言語が英語になっていません。英語に変更しました"
"translation": "Torrent カテゴリーは英語翻訳となっていますが、言語が英語になっていません。英語に変更しました"
},
{
"id": "torrent_cat_not_english",
@ -1921,7 +1921,7 @@
},
{
"id": "torrent_magnet_invalid",
"translation": "magnet リンクをパースできません。お確かめください"
"translation": "magnet リンクをパースできません。ご確認ください"
},
{
"id": "torrent_hash_invalid",
@ -1961,7 +1961,7 @@
},
{
"id": "reupload",
"translation": "欠落した、もしくは関のない追加ファイルを含む、他のユーザーの Torrent の再アップロード"
"translation": "欠落した、もしくは関のない追加ファイルを含む、他のユーザーの Torrent の再アップロード"
},
{
"id": "red",
@ -1981,11 +1981,11 @@
},
{
"id": "faq_ads_explanation",
"translation": "これは決して軽率な判断ではなく、皆様から寄せられたご意見を徹底的に検討したものです。しかしながら、最終的にこれが pantsu に資金を供給し、継続的な活動を保証する唯一の持続可能な解決策であると感じています。<br/>私たちは資金の調達源について考えてきましたが、他に資金の調達に近づく選択肢はありません。<br>その結果、A-ADS の広告が私たちとユーザーにとって最良の選択であると判断しました。これらの広告は、シンプルで邪魔にならず、決してサイトのユーザーエクスペリエンスを阻害するものではなく、いかなる形態のトラッキングも含まれません。"
"translation": "これは決して軽率な判断ではなく、皆様から寄せられたご意見を徹底的に検討したものです。しかしながら、最終的にこれが pantsu に資金を供給し、継続的な活動を保証する唯一の持続可能な解決策であると感じています。<br/>私たちは資金の調達源について考えてきましたが、他に資金の調達に近づく選択肢はありません。<br>そして、A-ADS の広告が私たちとユーザーにとって最良の選択であると判断しました。これらの広告は、シンプルで邪魔にならず、決してサイトのユーザーエクスペリエンスを阻害するものではなく、いかなる形態のトラッキングも含まれません。"
},
{
"id": "torrent_preview",
"translation": "Torrent プレビュー"
"translation": "Torrent プレビュー"
},
{
"id": "announcement",
@ -2173,7 +2173,7 @@
},
{
"id": "related_to",
"translation": "以下に関連:"
"translation": "関連項目:"
},
{
"id": "expire",

Voir le fichier

@ -6,6 +6,7 @@ import (
"github.com/NyaaPantsu/nyaa/models/notifications"
"github.com/NyaaPantsu/nyaa/utils/publicSettings"
"github.com/NyaaPantsu/nyaa/utils/sanitize"
"github.com/gin-gonic/gin"
"github.com/nicksnyder/go-i18n/i18n"
)
@ -34,7 +35,7 @@ func GetMessages(c *gin.Context) *Messages {
mes := &Messages{make(map[string][]string), make(map[string][]string), c, T}
announcements, _ := notifications.CheckAnnouncement()
for _, announcement := range announcements {
mes.AddInfo("system", announcement.Content)
mes.AddInfo("system", string(sanitize.MarkdownToHTML(announcement.Content)))
}
c.Set(MessagesKey, mes)
return mes

Voir le fichier

@ -32,7 +32,7 @@ func (d *DateFilter) ParseOld(s string, dateType string) bool {
}
// Parse parses a date to a datefilter object and return true if it succeeded
// This functions accept only date formatted in this way YYYY/MM/DD
// This function accept dates formatted in these way YYYY/MM/DD AND YYYY-MM-DD
func (d *DateFilter) Parse(s string) bool {
if s == "" {
*d = ""
@ -40,8 +40,11 @@ func (d *DateFilter) Parse(s string) bool {
}
date, err := time.Parse("2006/01/02", s)
if err != nil {
*d = ""
return false
date, err = time.Parse("2006-01-02", s)
if err != nil {
*d = ""
return false
}
}
*d = DateFilter(date.Format("2006-01-02"))
return true

Voir le fichier

@ -40,6 +40,7 @@ type TorrentParam struct {
ToDate DateFilter
NotNull string // csv
NameLike string // csv
NameSearch string //Contains what NameLike contains but without the excluded keywords, not used for search, just for page title
Languages publicSettings.Languages
MinSize SizeBytes
MaxSize SizeBytes
@ -117,6 +118,12 @@ func (p *TorrentParam) FromRequest(c *gin.Context) {
// Search by name
// We take the search arguments from "q" in url
p.NameLike = strings.TrimSpace(c.Query("q"))
for _, word := range strings.Fields(p.NameLike) {
if word[0] != '-' {
p.NameSearch += word + " "
}
}
// Maximum results returned
// We take the maxximum results to display from "limit" in url
@ -252,8 +259,10 @@ func (p *TorrentParam) toESQuery(c *gin.Context) *Query {
if p.Status != ShowAll {
query.Append(p.Status.ToESQuery())
} else if !p.Locked {
query.Append(fmt.Sprintf("!(status:%d)", 5))
}
if !p.Locked {
//query.Append("!status:5")
//This line breaks ES but this check is needed
}
@ -410,7 +419,8 @@ func (p *TorrentParam) toDBQuery(c *gin.Context) *Query {
}
if p.Status != 0 {
query.Append(p.Status.ToDBQuery())
} else if !p.Locked {
}
if !p.Locked {
query.Append("status IS NOT ?", 5)
}
@ -452,6 +462,12 @@ func (p *TorrentParam) toDBQuery(c *gin.Context) *Query {
querySplit := strings.Fields(p.NameLike)
for _, word := range querySplit {
if word[0] == '-' && len(word) > 1 {
//Exclude words starting with -
query.Append("torrent_name NOT "+searchOperator, "%"+word[1:]+"%")
continue
}
firstRune, _ := utf8.DecodeRuneInString(word)
if len(word) == 1 && unicode.IsPunct(firstRune) {
// some queries have a single punctuation character
@ -525,5 +541,6 @@ func (p *TorrentParam) Clone() TorrentParam {
Languages: p.Languages,
MinSize: p.MinSize,
MaxSize: p.MaxSize,
Locked: p.Locked,
}
}

Voir le fichier

@ -33,6 +33,7 @@ func TestTorrentParam_FromRequest(t *testing.T) {
c = mockRequest(t, "/?fromID=3&q=xx&c=_")
torrentParam.FromRequest(c)
defTorrent.FromID, defTorrent.NameLike = 3, "xx"
defTorrent.NameSearch = "xx "
assert.Equal(defTorrent, torrentParam)
}
@ -57,14 +58,14 @@ func TestTorrentParam_ToESQuery(t *testing.T) {
Test TorrentParam
Expected string
}{
{TorrentParam{}, "!(status:5)"},
{TorrentParam{NameLike: "lol"}, "!(status:5)"},
{TorrentParam{NameLike: "lol", FromID: 12}, "!(status:5) id:>12"},
{TorrentParam{NameLike: "lol", FromID: 12, FromDate: DateFilter("2017-08-01"), ToDate: DateFilter("2017-08-05")}, "!(status:5) id:>12 date: [2017-08-01 2017-08-05]"},
{TorrentParam{NameLike: "lol", FromID: 12, ToDate: DateFilter("2017-08-05")}, "!(status:5) id:>12 date: [* 2017-08-05]"},
{TorrentParam{NameLike: "lol", FromID: 12, FromDate: DateFilter("2017-08-01")}, "!(status:5) id:>12 date: [2017-08-01 *]"},
{TorrentParam{NameLike: "lol", FromID: 12, Category: Categories{&Category{3, 12}}}, "(category: 3 AND sub_category: 12) !(status:5) id:>12"},
{TorrentParam{NameLike: "lol", FromID: 12, Category: Categories{&Category{3, 12}, &Category{3, 12}}}, "((category: 3 AND sub_category: 12) OR (category: 3 AND sub_category: 12)) !(status:5) id:>12"},
{TorrentParam{}, ""},
{TorrentParam{NameLike: "lol"}, ""},
{TorrentParam{NameLike: "lol", FromID: 12}, "id:>12"},
{TorrentParam{NameLike: "lol", FromID: 12, FromDate: DateFilter("2017-08-01"), ToDate: DateFilter("2017-08-05")}, "id:>12 date: [2017-08-01 2017-08-05]"},
{TorrentParam{NameLike: "lol", FromID: 12, ToDate: DateFilter("2017-08-05")}, "id:>12 date: [* 2017-08-05]"},
{TorrentParam{NameLike: "lol", FromID: 12, FromDate: DateFilter("2017-08-01")}, "id:>12 date: [2017-08-01 *]"},
{TorrentParam{NameLike: "lol", FromID: 12, Category: Categories{&Category{3, 12}}}, "(category: 3 AND sub_category: 12) id:>12"},
{TorrentParam{NameLike: "lol", FromID: 12, Category: Categories{&Category{3, 12}, &Category{3, 12}}}, "((category: 3 AND sub_category: 12) OR (category: 3 AND sub_category: 12)) id:>12"},
}
for _, test := range tests {