Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0
* Add new followers directly to user.Followers

* Update user.go

* Remove useless condition

* Query an update of user followers if at 0 when looking at his profile

* Fix comment not appearing until you refreshed the torrent page

* call ViewHandler so that comments visually update properly

* Remove now useless imports

* Add "uploader" userstatus in comment

* GetLikings() & GetFollowers() now return count too

* Don't update follower count here

* Update follower count directly here

* show liking count

* Update user.go

* Update profile.jet.html

* Update torrentParam.go

* Fix locked torrents that were shown even when they should not

* Update torrentParam_test.go

* remove inline styling

* Update main.css

* Update upload.jet.html

* Update main.css

* Update tomorrow.css

* Update classic.css

* Update classic_colors.css

* Update index_site.jet.html

* Make announcements support markdown

* Add markdown form to announcement creation

* fix "report" text position

* Add exclude search option to exclude words

* Make sure the "NameLike" value is the search query because we edit it during a search

* Show search content in page title for /feed too

* rollback

* Add "Search" variable that shows exactly what is being searched

* Use "Search.Search" variable here instead of NameLike because NameLike is edited

* Update torrentParam_test.go

* Update torrentParam.go

* remove redundant spaces from NameLike

* Update torrentParam.go

* Update torrentParam.go

* Update torrentParam.go

* Update torrentParam.go

* turn date input into type date

* bigger date inputs

* add support for YYYY-MM-DD dates

* rollback this change

* rollback

* Update search.jet.html

* Update helpers.go

* Update template_functions.go

* Update torrentParam.go

* only uploader & staff can comment on locked torrents

* Add "Upload to Nyaa/Sukebei" button for mods

* Update torrentlist.jet.html

* Update view.jet.html

* Update view.jet.html

* fix wrong page title for notifications page
Cette révision appartient à :
kilo 2017-11-20 02:13:00 +01:00 révisé par ewhal
Parent d4114640df
révision 0a765b5589
23 fichiers modifiés avec 121 ajouts et 84 suppressions

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

@ -312,7 +312,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

@ -52,10 +52,9 @@
</span>
<span class="form-refine">
<span class="spacing">{{ T("from")}}</span>
<input class="form-input refine-date" name="fromDate" type="text" value="{{Search.FromDate}}" placeholder="YYYY/MM/DD"/>
<input class="form-input refine-date" name="fromDate" type="date" 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;">
<input class="form-input refine-date spacing" size="7" name="toDate" type="date" value="{{Search.ToDate}}" placeholder="YYYY/MM/DD"/>
</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

@ -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

@ -180,7 +180,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

@ -346,7 +346,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
}

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

@ -252,8 +252,9 @@ 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")
}
@ -410,7 +411,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 +454,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 +533,6 @@ func (p *TorrentParam) Clone() TorrentParam {
Languages: p.Languages,
MinSize: p.MinSize,
MaxSize: p.MaxSize,
Locked: p.Locked,
}
}

Voir le fichier

@ -57,14 +57,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{}, "!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"},
}
for _, test := range tests {