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

Fix bug, remove literals (#629)

* Use ModeratorDir variable

* Rename cookieHelper to cookie_helper for consistency

* Use named constant instead of literals

* Fix ability to upload when uploads are disabled

The old code let people upload under the right conditions when uploads
were disabled. (ie: User is banned and config.AdminAreStillAllowedTo is
false)

* Increase timeout (fixes #517)

* Fix inconsistent indentation *.{js, css} (fix #583)

* Fix negative page

Temporary fix. The issue was that going to a negative page caused the
sql query to have a negative offset. This caused an error in the
database query.

We need to cleanup this code, but this will work for now.

* Fix wrong PG_DATA directory due to upgrade to 9.6

* Add server status link to FAQ

* Fix failing tests

* Clarify group_vars/all and hosts doc

* Add a wrapper to protect /mod route

* Fix login page not showing form errors
Cette révision appartient à :
tomleb 2017-05-19 19:10:16 -04:00 révisé par ewhal
Parent 9ca99aae8a
révision 7eee47b0d3
35 fichiers modifiés avec 721 ajouts et 682 suppressions

Voir le fichier

@ -91,5 +91,9 @@ Access the website by going to [localhost:9999](http://localhost:9999).
# LICENSE
This project is licensed under the MIT License - see the LICENSE.md file for details
# Contributing
Use tabs for css and js files.
# Disclaimer
We take no legal responsibility for anything this code is used for. This is purely an educational proof of concept.

Voir le fichier

@ -13,7 +13,7 @@ const (
// LastOldTorrentID is the highest torrent ID
// that was copied from the original Nyaa
LastOldTorrentID = 923000
TableName = "torrents"
TorrentsTableName = "torrents"
CommentsTableName = "comments"
// for sukebei
//TableName = "sukebei_torrents"

Voir le fichier

@ -69,8 +69,13 @@ volumes.
> caching will be done. Ansible assume you have a user on the remote that has
> sudo (no password).
You'll have to change a few variables in [hosts](host) and maybe tweak a few in
[group_vars/all](group_vars/all).
You'll have to change a few variables in [hosts](host). Replace the host:ip
address to the host:ip of the target server. You can also change the user
ansible uses to connect to the server. The user needs to have sudo ALL.
You'll also maybe have to tweak a few variables in
[group_vars/all](group_vars/all) such as the database password, etc (but should
probably be left like this).
### Setup server playbook
@ -149,5 +154,5 @@ You can now tests the playbooks.
## TODOs
- Delete .torrents after X days
- Add public keys to db (?)
- Show public keys and link to .torrents on the website
- Show public keys and link to .torrents on the website
- Tuning elasticsearch indexing / analyzer

Voir le fichier

@ -13,7 +13,7 @@ pcp_socket_dir = '/tmp'
backend_hostname0 = 'localhost'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/var/lib/pgsql/data'
backend_data_directory0 = '/var/lib/pgsql/9.6/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
# Controls various backend behavior
# ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER

Voir le fichier

@ -32,8 +32,8 @@ func RunServer(conf *config.Config) {
// Set up server,
srv := &http.Server{
WriteTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
ReadTimeout: 10 * time.Second,
}
l, err := network.CreateHTTPListener(conf)
log.CheckError(err)

Voir le fichier

@ -13,6 +13,13 @@ import (
"time"
)
const (
TorrentStatusNormal = 1
TorrentStatusRemake = 2
TorrentStatusTrusted = 3
TorrentStatusAPlus = 4
)
type Feed struct {
ID int
Name string
@ -76,7 +83,23 @@ func (t Torrent) Size() (s int) {
}
func (t Torrent) TableName() string {
return config.TableName
return config.TorrentsTableName
}
func (t Torrent) IsNormal() bool {
return t.Status == TorrentStatusNormal
}
func (t Torrent) IsRemake() bool {
return t.Status == TorrentStatusRemake
}
func (t Torrent) IsTrusted() bool {
return t.Status == TorrentStatusTrusted
}
func (t Torrent) IsAPlus() bool {
return t.Status == TorrentStatusAPlus
}
/* We need a JSON object instead of a Gorm structure because magnet URLs are
@ -154,7 +177,7 @@ func (t *Torrent) ToJSON() TorrentJSON {
}
// Sort file list by lowercase filename
slice.Sort(fileListJSON, func (i, j int) bool {
slice.Sort(fileListJSON, func(i, j int) bool {
return strings.ToLower(fileListJSON[i].Path) < strings.ToLower(fileListJSON[j].Path)
})

Voir le fichier

@ -4,17 +4,24 @@ import (
"time"
)
const (
UserStatusBanned = -1
UserStatusMember = 0
UserStatusTrusted = 1
UserStatusModerator = 2
)
type User struct {
ID uint `gorm:"column:user_id;primary_key"`
Username string `gorm:"column:username"`
Password string `gorm:"column:password"`
Email string `gorm:"column:email"`
Status int `gorm:"column:status"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
ApiToken string `gorm:"column:api_token"`
ApiTokenExpiry time.Time `gorm:"column:api_token_expiry"`
Language string `gorm:"column:language"`
ID uint `gorm:"column:user_id;primary_key"`
Username string `gorm:"column:username"`
Password string `gorm:"column:password"`
Email string `gorm:"column:email"`
Status int `gorm:"column:status"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
ApiToken string `gorm:"column:api_token"`
ApiTokenExpiry time.Time `gorm:"column:api_token_expiry"`
Language string `gorm:"column:language"`
// TODO: move this to PublicUser
LikingCount int `json:"likingCount" gorm:"-"`
@ -50,6 +57,19 @@ func (u User) Size() (s int) {
return
}
func (u User) IsBanned() bool {
return u.Status == UserStatusBanned
}
func (u User) IsMember() bool {
return u.Status == UserStatusMember
}
func (u User) IsTrusted() bool {
return u.Status == UserStatusTrusted
}
func (u User) IsModerator() bool {
return u.Status == UserStatusModerator
}
type PublicUser struct {
User *User
}

Voir le fichier

@ -1,35 +1,35 @@
/*Don't make changes to layout here, only colours*/
/* Torrent status colors */
.remake {
background-color: #473e50; /*270,13%,28%*/
background-color: #473e50; /*270,13%,28%*/
}
.trusted {
background-color: #395045; /*150,17%,27%*/
background-color: #395045; /*150,17%,27%*/
}
.aplus {
background-color: #3c5b71; /*205,30%,34%*/
background-color: #3c5b71; /*205,30%,34%*/
}
.remake a {
color: #cfc2dc; /*270,26%,81%*/
color: #cfc2dc; /*270,26%,81%*/
}
.trusted a {
color: #bde0db; /*170,36%,81%*/
color: #bde0db; /*170,36%,81%*/
}
.remake a:hover {
color: #cf9fff;
color: #cf9fff;
}
.trusted a:hover {
color: #6ae3d1;
color: #6ae3d1;
}
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
border-color: hsla(200,60%,70%,0.15);
border-color: hsla(200,60%,70%,0.15);
}
.pagination > li > a,
.pagination > li > span {
color: #fff;
background-color: #b294bb;
border-color: #b294bb;
color: #fff;
background-color: #b294bb;
border-color: #b294bb;
}
.pagination > .active > a,
@ -38,14 +38,14 @@
.pagination > .active > span,
.pagination > .active > span:focus,
.pagination > .active > span:hover {
background-color: #a2c9dd;
border-color: #a2c9dd;
background-color: #a2c9dd;
border-color: #a2c9dd;
}
#mainmenu {
background: #263238;
color: #f2f2f2;
border: 0px solid #263238;
background: #263238;
color: #f2f2f2;
border: 0px solid #263238;
}
#mainmenu a {
@ -53,7 +53,7 @@
}
#container {
background-color: #29363d;
background-color: #29363d;
}
#mascot {
@ -61,15 +61,15 @@
}
body {
background-color:#282A2E;
color: #eff5f5;
background-color:#282A2E;
color: #eff5f5;
}
.pagination > .active > a {
background: #ececec;
border-color: #ececec;
color: #337ab7; /* restore usual text color */
background: #ececec;
border-color: #ececec;
color: #337ab7; /* restore usual text color */
}
/* Links, Text */
@ -81,18 +81,18 @@ a:hover {
text-shadow: 1px 1px 0 #000;
}
.btn-success {
color: #fff;
background-color: #b294bb;
border-color: #b294bb;
color: #fff;
background-color: #b294bb;
border-color: #b294bb;
}
:target {
background-color: #b294bb;
background-color: #b294bb;
}
.form-control, pre {
color: #fff;
background-color: #29363d
color: #fff;
background-color: #29363d
}
/* style the dropdown member menu */
@ -105,54 +105,54 @@ a:hover {
/* Profile Content */
.profile-content {
background: #29363d;
background: #29363d;
}
/* Night mode switcher */
#mainmenu a.nightswitch {
background-image: url(/img/moon.png);
background-image: url(/img/moon.png);
}
/* Force images on description to fit width */
#description img {
display: block;
max-width: 100%;
height: auto;
display: block;
max-width: 100%;
height: auto;
}
/* fix dark-on-dark */
.captcha-container img {
background: #fff;
border-radius: .4em .4em 0 0;
border-bottom: .5em solid #fff;
margin-bottom: -.5em;
background: #fff;
border-radius: .4em .4em 0 0;
border-bottom: .5em solid #fff;
margin-bottom: -.5em;
}
.modal-content {
background: #29363d;
background: #29363d;
}
.modal-content .close {
color: #fff;
color: #fff;
}
.text-error {
background: #29363d;
color: #cf9fff;
background: #29363d;
color: #cf9fff;
}
/*Comments*/
.commentList .commentData {
color: #fff;
color: #fff;
}
.commentList .commentBody {
background: #29363d;
color: #fff;
background: #29363d;
color: #fff;
}
textarea.torrent-desc {
background: none;
background: none;
}
.md-editor>textarea:focus {
background: none;
}
background: none;
}

Voir le fichier

@ -1,100 +1,100 @@
/* Torrent status colors */
.remake {
background-color: rgb(240, 176, 128);
background-color: rgb(240, 176, 128);
}
.trusted {
background-color: #a3e9a4;
background-color: #a3e9a4;
}
.aplus {
background-color: #81d3fa;
background-color: #81d3fa;
}
.container.remake {
box-shadow: 0px 0px 30px 10px rgba(240, 176, 128, 0.6);
box-shadow: 0px 0px 30px 10px rgba(240, 176, 128, 0.6);
}
.row.remake {
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
}
.container.trusted {
box-shadow: 0px 0px 30px 10px rgba(163, 233, 164, 0.6);
box-shadow: 0px 0px 30px 10px rgba(163, 233, 164, 0.6);
}
.row.trusted {
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
}
.container.aplus {
box-shadow: 0px 0px 30px 10px rgba(129, 211, 250, 0.6);
box-shadow: 0px 0px 30px 10px rgba(129, 211, 250, 0.6);
}
.row.aplus {
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
margin-bottom: 0.5rem;
color: rgb(119, 94, 140);
padding:2px 0;
}
/* modified copy of NyaaTorrent theme */
#mainmenu, #mainmenu .dropdown-menu{
background: #263238;
color: white;
background: #263238;
color: white;
}
#mainmenu {
position: fixed;
width: 100%;
z-index: 4;
border: 0px solid white;
position: fixed;
width: 100%;
z-index: 4;
border: 0px solid white;
}
#mainmenu a {
background: none;
color: white;
background: none;
color: white;
}
#mainmenu .divider {
background: black;
background: black;
}
#container {
padding-top: 1.25em;
background: white;
padding-top: 1.25em;
background: white;
}
#mascot {
background-image: url(/img/renchon.png);
width: 125px;
height: 169px;
position: fixed;
bottom: 0px;
left: 2%;
position: fixed;
bottom: 0px;
left: 2%;
}
/* This used to avoid usage of Javascript for switching images. */
body {
background-color: #ececec;
color: #111111;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #ececec;
color: #111111;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.torrentNav {
text-align: center;
text-align: center;
}
.pagination > .active > a {
background: #ececec;
border-color: #ececec;
color: #337ab7; /* restore usual text color */
background: #ececec;
border-color: #ececec;
color: #337ab7; /* restore usual text color */
}
/* Links, Text */
a {
color: #106655;
text-decoration : none;
color: #106655;
text-decoration : none;
}
.download-btn {
font-size: 24px;
font-size: 24px;
}
.table-borderless > tbody > tr > td,
@ -103,69 +103,69 @@ a {
.table-borderless > tfoot > tr > th,
.table-borderless > thead > tr > td,
.table-borderless > thead > tr > th {
border: none;
border: none;
}
td {
text-overflow: ellipsis;
text-overflow: ellipsis;
}
.torrent-info .name {
font-weight: bold;
overflow: hidden;
padding-bottom: 3px;
padding-top: 3px;
word-wrap: break-word;
font-weight: bold;
overflow: hidden;
padding-bottom: 3px;
padding-top: 3px;
word-wrap: break-word;
}
.torrent-hash {
font-family: monospace;
font-family: monospace;
}
.comment-row td:first-of-type {
vertical-align: top;
text-align: left;
color:#bbb;
vertical-align: top;
text-align: left;
color:#bbb;
}
/* Table style & fixes */
.table > tbody > tr > th, .nowrap {
white-space: nowrap;
white-space: nowrap;
}
.table > tbody > tr > td {
/* fix bootstrap uglyness */
vertical-align: middle;
/* fix bootstrap uglyness */
vertical-align: middle;
}
.table > tbody > tr > th, .table > tbody > tr > td {
padding: 4px;
padding: 4px;
}
.captcha-container {
display: grid;
grid-template-rows: auto;
grid-template-columns: 240px;
display: grid;
grid-template-rows: auto;
grid-template-columns: 240px;
}
.custom-table-hover > tbody > tr:hover {
opacity: 0.82;
opacity: 0.82;
}
.comment-row {
border-top: 1px solid #ddd;
border-top: 1px solid #ddd;
}
th a:hover {
text-decoration: none;
text-decoration: none;
}
.sortarrowleft {
letter-spacing: -0.6rem;
letter-spacing: -0.6rem;
}
.sortarrowdim {
opacity: 0.25;
opacity: 0.25;
}
div.container div.blockBody:nth-of-type(2) table{table-layout:fixed;}
@ -176,272 +176,272 @@ div.container div.blockBody:nth-of-type(2) table tr:first-of-type th:last-of-typ
/* Mobile-friendly main table */
@media only screen and (max-width: 700px) {
table, thead, tbody, tr {
display: block;
}
table, thead, tbody, tr {
display: block;
}
th {
display: none;
}
th {
display: none;
}
td {
display: inline-block;
}
td {
display: inline-block;
}
td:nth-of-type(1), td:nth-of-type(2) {
display: block;
}
td:nth-of-type(1), td:nth-of-type(2) {
display: block;
}
.table > tbody > tr > td {
border: none;
}
.table > tbody > tr > td {
border: none;
}
}
/* Credit to bootsnipp.com for the css for the color graph */
.colorgraph {
height: 5px;
border-top: 0;
background: #c4e17f;
border-radius: 5px;
background-image: -webkit-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: -moz-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: -o-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: linear-gradient(to right, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
height: 5px;
border-top: 0;
background: #c4e17f;
border-radius: 5px;
background-image: -webkit-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: -moz-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: -o-linear-gradient(left, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
background-image: linear-gradient(to right, #c4e17f, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fecf71 25%, #fecf71 37.5%, #f0776c 37.5%, #f0776c 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cde 62.5%, #c49cde 75%, #669ae1 75%, #669ae1 87.5%, #62c2e4 87.5%, #62c2e4);
}
.center-image {
max-width: 100%;
max-height: 80vh;
max-width: 100%;
max-height: 80vh;
}
/* the curved edges triggered my autism */
.navbar {
border-radius: 0px;
border-radius: 0px;
}
/* the logo needs some space */
.navbar-logo {
margin-right: 10px;
margin-right: 10px;
}
:target {
background-color: #e5eecc;
background-color: #e5eecc;
}
#mainmenu button .search_text {
display: none;
display: none;
}
#mainmenu .navbar-form select.form-control
{
width: 12rem;
width: 12rem;
}
#mainmenu .navbar-form select.form-control#max
{
width: 6rem;
width: 6rem;
}
.special-img
{
position: relative;
top: -5px;
float: left;
left: -5px;
position: relative;
top: -5px;
float: left;
left: -5px;
}
#mainmenu .badgemenu .profile-image {
line-height: 35px;
line-height: 35px;
}
#mainmenu .navbar-header, #mainmenu .navbar-nav, #mainmenu .navbar-form {
padding-top: 10px;
padding-top: 10px;
}
#mainmenu .badgemenu {
padding-top: 0;
margin-right: -50px; /* don't ask */
padding-top: 0;
margin-right: -50px; /* don't ask */
}
/* PROFILE PAGE */
/* Profile container */
.profile {
margin: 20px 0;
margin: 20px 0;
}
/* Profile sidebar */
.profile-sidebar {
padding: 20px 0 10px 0;
background: #182430;
padding: 20px 0 10px 0;
background: #182430;
}
.profile-userpic img {
float: none;
margin: 0 auto;
width: 50%;
height: 50%;
-webkit-border-radius: 50% !important;
-moz-border-radius: 50% !important;
border-radius: 50% !important;
float: none;
margin: 0 auto;
width: 50%;
height: 50%;
-webkit-border-radius: 50% !important;
-moz-border-radius: 50% !important;
border-radius: 50% !important;
}
.profile-usertitle {
text-align: center;
margin-top: 20px;
text-align: center;
margin-top: 20px;
}
.profile-usertitle-name {
color: #5a7391;
font-size: 16px;
font-weight: 600;
margin-bottom: 7px;
color: #5a7391;
font-size: 16px;
font-weight: 600;
margin-bottom: 7px;
}
.profile-usertitle-job {
text-transform: uppercase;
color: #5b9bd1;
font-size: 12px;
font-weight: 600;
margin-bottom: 15px;
text-transform: uppercase;
color: #5b9bd1;
font-size: 12px;
font-weight: 600;
margin-bottom: 15px;
}
.profile-userbuttons {
text-align: center;
margin-top: 10px;
text-align: center;
margin-top: 10px;
}
.profile-userbuttons .btn {
text-transform: uppercase;
font-size: 11px;
font-weight: 600;
padding: 6px 15px;
margin-right: 5px;
text-transform: uppercase;
font-size: 11px;
font-weight: 600;
padding: 6px 15px;
margin-right: 5px;
}
.profile-userbuttons .btn:last-child {
margin-right: 0px;
margin-right: 0px;
}
.profile-usermenu {
margin-top: 30px;
margin-top: 30px;
}
.profile-usermenu ul li {
border-bottom: 1px solid #f0f4f7;
border-bottom: 1px solid #f0f4f7;
}
.profile-usermenu ul li:last-child {
border-bottom: none;
border-bottom: none;
}
.profile-usermenu ul li a {
color: #93a3b5;
font-size: 14px;
font-weight: 400;
color: #93a3b5;
font-size: 14px;
font-weight: 400;
}
.profile-usermenu ul li a i {
margin-right: 8px;
font-size: 14px;
margin-right: 8px;
font-size: 14px;
}
.profile-usermenu ul li a:hover {
background-color: #fafcfd;
color: #5b9bd1;
background-color: #fafcfd;
color: #5b9bd1;
}
.profile-usermenu ul li.active {
border-bottom: none;
border-bottom: none;
}
.profile-usermenu ul li.active a {
color: #5b9bd1;
background-color: #f6f9fb;
border-left: 2px solid #5b9bd1;
margin-left: -2px;
color: #5b9bd1;
background-color: #f6f9fb;
border-left: 2px solid #5b9bd1;
margin-left: -2px;
}
/* Profile Content */
.profile-content {
padding: 20px;
background: #fff;
min-height: 460px;
padding: 20px;
background: #fff;
min-height: 460px;
}
/* Night mode switcher */
#mainmenu a.nightswitch {
background: transparent url(/img/sun.png) no-repeat;
background-size: 24px;
margin-top: 10px;
margin-left: 3px;
width: 24px;
background: transparent url(/img/sun.png) no-repeat;
background-size: 24px;
margin-top: 10px;
margin-left: 3px;
width: 24px;
}
footer {
text-align: center;
padding-bottom: 2rem;
font-size: 2rem;
font-family: cursive;
color: #616161;
text-shadow: -1px -1px #999999;
text-align: center;
padding-bottom: 2rem;
font-size: 2rem;
font-family: cursive;
color: #616161;
text-shadow: -1px -1px #999999;
}
select#bottom_language_selector {
width: 20%;
margin: auto;
margin-bottom: 2rem;
width: 20%;
margin: auto;
margin-bottom: 2rem;
}
/* Force images on description to fit width */
#description img {
display: block;
max-width: 100%;
height: auto;
display: block;
max-width: 100%;
height: auto;
}
/* Psuedo green-text fuckery. */
#comments blockquote {
color: #789922;
color: #789922;
}
#comments blockquote:before {
content: ">";
content: ">";
}
.completed {
font-size: 2rem;
font-weight: bold;
text-align: center;
font-size: 2rem;
font-weight: bold;
text-align: center;
}
.proSeedBar {
width:100%; height: 0.5rem; overflow: hidden;
width:100%; height: 0.5rem; overflow: hidden;
}
.proSeedBar .seeds {
background: green;
height: 0.5rem;
background: green;
height: 0.5rem;
}
.proSeedBar .leechs {
height: 0.5rem;
background: red;
position: relative;
top: -0.5rem;
float: right;
height: 0.5rem;
background: red;
position: relative;
top: -0.5rem;
float: right;
}
.comment-date {
font-size: smaller;
width: auto; /* Undo bootstrap's fixed width */
font-size: smaller;
width: auto; /* Undo bootstrap's fixed width */
}
.text-error {
background: white;
color: #cf9fff;
background: white;
color: #cf9fff;
}
/* Wordbreak fix*/
.break {
word-break: break-all;
hyphens: auto;
word-break: break-all;
hyphens: auto;
}
.filelist-control {
@ -453,39 +453,39 @@ select#bottom_language_selector {
}
.filelist-control[aria-expanded="true"]::before {
content: "\25BC ";
content: "\25BC ";
}
/*Comments*/
.commentList::before,
.commentList::after {
content: "";
display: table;
clear: both;
content: "";
display: table;
clear: both;
}
.commentList ul {
list-style-type: none;
padding: 0;
list-style-type: none;
padding: 0;
}
.commentList img {
opacity: 1;
filter: Alpha(opacity=100);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
opacity: 1;
filter: Alpha(opacity=100);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
}
.commentList img.avatar {
position: relative;
float: left;
margin-left: 0;
margin-top: 0;
width: 65px;
height: 65px;
position: relative;
float: left;
margin-left: 0;
margin-top: 0;
width: 65px;
height: 65px;
}
.commentList .commentBody {
@ -500,77 +500,77 @@ select#bottom_language_selector {
}
.commentList .commentBody > .row > div {
word-wrap: break-word;
word-wrap: break-word;
}
.commentList .commentData {
font-size: 13px;
margin-bottom: 10px !important;
border-bottom: 1px solid #eee;
height: 2.2em;
font-size: 13px;
margin-bottom: 10px !important;
border-bottom: 1px solid #eee;
height: 2.2em;
}
.commentList ul.comments ul{
list-style-type: none;
padding: 0;
margin-left: 85px;
list-style-type: none;
padding: 0;
margin-left: 85px;
}
.commentList h3 {
margin-bottom: 40px;
font-size: 26px;
line-height: 30px;
font-weight: 800;
margin-bottom: 40px;
font-size: 26px;
line-height: 30px;
font-weight: 800;
}
.comment {
padding: 1em;
width: 75%;
margin-left: 12%;
padding: 1em;
width: 75%;
margin-left: 12%;
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
.comment {
width: 100%;
margin-left: 0;
}
.comment {
width: 100%;
margin-left: 0;
}
}
@media (max-width: 995px) {
.navbar-header {
float: none;
}
.navbar-left,.navbar-right {
float: none !important;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-fixed-top {
.navbar-header {
float: none;
}
.navbar-left,.navbar-right {
float: none !important;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-fixed-top {
top: 0;
border-width: 0 0 1px;
}
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
margin-top: 7.5px;
}
.navbar-nav>li {
float: none;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
.collapse.in{
display:block !important;
float: none;
}
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
.collapse.in{
display:block !important;
}
}

Voir le fichier

@ -4,29 +4,29 @@ function loadLanguages() {
if (xhr.readyState == 4 && xhr.status == 200) {
var selector = document.getElementById("bottom_language_selector");
selector.hidden = false
/* Response format is
* { "current": "(user current language)",
* "languages": {
* "(language_code)": "(language_name"),
* }} */
var response = JSON.parse(xhr.responseText);
/* Response format is
* { "current": "(user current language)",
* "languages": {
* "(language_code)": "(language_name"),
* }} */
var response = JSON.parse(xhr.responseText);
for (var language in response.languages) {
if (!response.languages.hasOwnProperty(language)) continue;
var opt = document.createElement("option")
opt.value = language
opt.innerHTML = response.languages[language]
if (language == response.current) {
opt.selected = true
}
opt.value = language
opt.innerHTML = response.languages[language]
if (language == response.current) {
opt.selected = true
}
selector.appendChild(opt)
}
}
}
xhr.open("GET", "/language", true)
xhr.setRequestHeader("Content-Type", "application/json")
xhr.send()
xhr.setRequestHeader("Content-Type", "application/json")
xhr.send()
}
loadLanguages();

Voir le fichier

@ -1,11 +1,11 @@
function toggleNightMode() {
var night = localStorage.getItem("night");
if(night == "true") {
document.getElementsByTagName("head")[0].removeChild(darkStyleLink);
} else {
document.getElementsByTagName("head")[0].appendChild(darkStyleLink);
}
localStorage.setItem("night", (night == "true") ? "false" : "true");
var night = localStorage.getItem("night");
if(night == "true") {
document.getElementsByTagName("head")[0].removeChild(darkStyleLink);
} else {
document.getElementsByTagName("head")[0].appendChild(darkStyleLink);
}
localStorage.setItem("night", (night == "true") ? "false" : "true");
}
// Used by spoiler tags
@ -41,17 +41,17 @@ $(".date-comments").each(function(index, el) {
});
/*Fixed-Navbar offset fix*/
window.onload = function() {
var shiftWindow = function() { scrollBy(0, -70) };
if (location.hash) shiftWindow();
window.addEventListener("hashchange", shiftWindow);
var shiftWindow = function() { scrollBy(0, -70) };
if (location.hash) shiftWindow();
window.addEventListener("hashchange", shiftWindow);
};
$('#mascot').bind('touchstart mousedown click', function(e){
var night = localStorage.getItem("night");
if(night == "true") {
if(night == "true") {
$('#explosion')[0].play();
} else {
} else {
$('#nyaapassu')[0].play();
}
});
}
});

Voir le fichier

@ -1,67 +1,67 @@
$(function () {
$('.button-checkbox').each(function () {
$('.button-checkbox').each(function () {
// Settings
var $widget = $(this),
$button = $widget.find('button'),
$checkbox = $widget.find('input:checkbox'),
color = $button.data('color'),
settings = {
on: {
icon: 'glyphicon glyphicon-check'
},
off: {
icon: 'glyphicon glyphicon-unchecked'
}
};
// Settings
var $widget = $(this),
$button = $widget.find('button'),
$checkbox = $widget.find('input:checkbox'),
color = $button.data('color'),
settings = {
on: {
icon: 'glyphicon glyphicon-check'
},
off: {
icon: 'glyphicon glyphicon-unchecked'
}
};
// Event Handlers
$button.on('click', function () {
$checkbox.prop('checked', !$checkbox.is(':checked'));
$checkbox.triggerHandler('change');
updateDisplay();
});
$checkbox.on('change', function () {
updateDisplay();
});
// Event Handlers
$button.on('click', function () {
$checkbox.prop('checked', !$checkbox.is(':checked'));
$checkbox.triggerHandler('change');
updateDisplay();
});
$checkbox.on('change', function () {
updateDisplay();
});
// Actions
function updateDisplay() {
$checkbox.addClass("hidden")
$button.removeClass("hidden")
var isChecked = $checkbox.is(':checked');
// Actions
function updateDisplay() {
$checkbox.addClass("hidden")
$button.removeClass("hidden")
var isChecked = $checkbox.is(':checked');
// Set the button's state
$button.data('state', (isChecked) ? "on" : "off");
// Set the button's state
$button.data('state', (isChecked) ? "on" : "off");
// Set the button's icon
$button.find('.state-icon')
.removeClass()
.addClass('state-icon ' + settings[$button.data('state')].icon);
// Set the button's icon
$button.find('.state-icon')
.removeClass()
.addClass('state-icon ' + settings[$button.data('state')].icon);
// Update the button's color
if (isChecked) {
$button
.removeClass('btn-default')
.addClass('btn-' + color + ' active');
}
else {
$button
.removeClass('btn-' + color + ' active')
.addClass('btn-default');
}
}
// Update the button's color
if (isChecked) {
$button
.removeClass('btn-default')
.addClass('btn-' + color + ' active');
}
else {
$button
.removeClass('btn-' + color + ' active')
.addClass('btn-default');
}
}
// Initialization
function init() {
// Initialization
function init() {
updateDisplay();
updateDisplay();
// Inject the icon if applicable
if ($button.find('.state-icon').length == 0) {
$button.prepend('<i class="state-icon ' + settings[$button.data('state')].icon + '"></i>');
}
}
init();
});
});
// Inject the icon if applicable
if ($button.find('.state-icon').length == 0) {
$button.prepend('<i class="state-icon ' + settings[$button.data('state')].icon + '"></i>');
}
}
init();
});
});

Voir le fichier

@ -1,7 +1,7 @@
(function() {
var torrent = $("input[name=torrent]"),
magnet = $("input[name=magnet]"),
name = $("input[name=name]");
magnet = $("input[name=magnet]"),
name = $("input[name=name]");
torrent.on("change", function() {
if (torrent.val() == "") {

Voir le fichier

@ -14,6 +14,7 @@ import (
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service"
"github.com/NyaaPantsu/nyaa/service/api"
"github.com/NyaaPantsu/nyaa/service/upload"
"github.com/NyaaPantsu/nyaa/service/torrent"
"github.com/NyaaPantsu/nyaa/util"
"github.com/NyaaPantsu/nyaa/util/log"
@ -36,7 +37,7 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
if req.MaxPerPage == 0 {
req.MaxPerPage = config.TorrentsPerPage
}
if req.Page == 0 {
if req.Page <= 0 {
req.Page = 1
}
@ -60,6 +61,10 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if req.Page <= 0 {
NotFoundHandler(w, r)
return
}
}
}
@ -101,22 +106,12 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
user := model.User{}
db.ORM.Where("api_token = ?", token).First(&user) //i don't like this
if config.UploadsDisabled {
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
}
if !uploadService.IsUploadEnabled(user) {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
}
if user.ID == 0 {
http.Error(w, apiService.ErrApiKey.Error(), http.StatusUnauthorized)
return
@ -194,20 +189,10 @@ func ApiUpdateHandler(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
user := model.User{}
db.ORM.Where("api_token = ?", token).First(&user) //i don't like this
if config.UploadsDisabled {
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
}
if !uploadService.IsUploadEnabled(user) {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
}
contentType := r.Header.Get("Content-Type")

Voir le fichier

@ -37,6 +37,10 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if pagenum <= 0 {
NotFoundHandler(w, r)
return
}
}
search := common.SearchParam{

Voir le fichier

@ -15,7 +15,6 @@ import (
"github.com/NyaaPantsu/nyaa/service/torrent"
"github.com/NyaaPantsu/nyaa/service/user"
form "github.com/NyaaPantsu/nyaa/service/user/form"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/log"
"github.com/NyaaPantsu/nyaa/util/search"
@ -107,178 +106,149 @@ func NewPanelSearchForm() SearchForm {
}
func IndexModPanel(w http.ResponseWriter, r *http.Request) {
// FIXME WrapModHandler already get user from db
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
offset := 10
offset := 10
torrents, _, _ := torrentService.GetAllTorrents(offset, 0)
users, _ := userService.RetrieveUsersForAdmin(offset, 0)
comments, _ := commentService.GetAllComments(offset, 0, "", "")
torrentReports, _, _ := reportService.GetAllTorrentReports(offset, 0)
torrents, _, _ := torrentService.GetAllTorrents(offset, 0)
users, _ := userService.RetrieveUsersForAdmin(offset, 0)
comments, _ := commentService.GetAllComments(offset, 0, "", "")
torrentReports, _, _ := reportService.GetAllTorrentReports(offset, 0)
languages.SetTranslationFromRequest(panelIndex, r)
htv := PanelIndexVbs{torrents, model.TorrentReportsToJSON(torrentReports), users, comments, NewPanelSearchForm(), currentUser, r.URL}
err := panelIndex.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
languages.SetTranslationFromRequest(panelIndex, r)
htv := PanelIndexVbs{torrents, model.TorrentReportsToJSON(torrentReports), users, comments, NewPanelSearchForm(), currentUser, r.URL}
err := panelIndex.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
func TorrentsListPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
vars := mux.Vars(r)
page := vars["page"]
vars := mux.Vars(r)
page := vars["page"]
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
offset := 100
searchParam, torrents, _, err := search.SearchByQuery(r, pagenum)
searchForm := SearchForm{
SearchParam: searchParam,
Category: searchParam.Category.String(),
ShowItemsPerPage: true,
}
languages.SetTranslationFromRequest(panelTorrentList, r)
htv := PanelTorrentListVbs{torrents, searchForm, Navigation{int(searchParam.Max), offset, pagenum, "mod_tlist_page"}, currentUser, r.URL}
err = panelTorrentList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
offset := 100
searchParam, torrents, _, err := search.SearchByQuery(r, pagenum)
searchForm := SearchForm{
SearchParam: searchParam,
Category: searchParam.Category.String(),
ShowItemsPerPage: true,
}
languages.SetTranslationFromRequest(panelTorrentList, r)
navigation := Navigation{int(searchParam.Max), offset, pagenum, "mod_tlist_page"}
ptlv := PanelTorrentListVbs{torrents, searchForm, navigation, currentUser, r.URL}
err = panelTorrentList.ExecuteTemplate(w, "admin_index.html", ptlv)
log.CheckError(err)
}
func TorrentReportListPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
vars := mux.Vars(r)
page := vars["page"]
vars := mux.Vars(r)
page := vars["page"]
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
offset := 100
torrentReports, nbReports, _ := reportService.GetAllTorrentReports(offset, (pagenum-1)*offset)
reportJSON := model.TorrentReportsToJSON(torrentReports)
languages.SetTranslationFromRequest(panelTorrentReportList, r)
htv := PanelTorrentReportListVbs{reportJSON, NewSearchForm(), Navigation{nbReports, offset, pagenum, "mod_trlist_page"}, currentUser, r.URL}
err = panelTorrentReportList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
offset := 100
torrentReports, nbReports, _ := reportService.GetAllTorrentReports(offset, (pagenum-1)*offset)
reportJSON := model.TorrentReportsToJSON(torrentReports)
languages.SetTranslationFromRequest(panelTorrentReportList, r)
navigation := Navigation{nbReports, offset, pagenum, "mod_trlist_page"}
ptrlv := PanelTorrentReportListVbs{reportJSON, NewSearchForm(), navigation, currentUser, r.URL}
err = panelTorrentReportList.ExecuteTemplate(w, "admin_index.html", ptrlv)
log.CheckError(err)
}
func UsersListPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
vars := mux.Vars(r)
page := vars["page"]
vars := mux.Vars(r)
page := vars["page"]
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
offset := 100
users, nbUsers := userService.RetrieveUsersForAdmin(offset, (pagenum-1)*offset)
languages.SetTranslationFromRequest(panelUserList, r)
htv := PanelUserListVbs{users, NewSearchForm(), Navigation{nbUsers, offset, pagenum, "mod_ulist_page"}, currentUser, r.URL}
err = panelUserList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
offset := 100
users, nbUsers := userService.RetrieveUsersForAdmin(offset, (pagenum-1)*offset)
languages.SetTranslationFromRequest(panelUserList, r)
htv := PanelUserListVbs{users, NewSearchForm(), Navigation{nbUsers, offset, pagenum, "mod_ulist_page"}, currentUser, r.URL}
err = panelUserList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
func CommentsListPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
vars := mux.Vars(r)
page := vars["page"]
vars := mux.Vars(r)
page := vars["page"]
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
offset := 100
userid := r.URL.Query().Get("userid")
var conditions string
var values []interface{}
if userid != "" {
conditions = "user_id = ?"
values = append(values, userid)
}
comments, nbComments := commentService.GetAllComments(offset, (pagenum-1)*offset, conditions, values...)
languages.SetTranslationFromRequest(panelCommentList, r)
htv := PanelCommentListVbs{comments, NewSearchForm(), Navigation{nbComments, offset, pagenum, "mod_clist_page"}, currentUser, r.URL}
err = panelCommentList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
offset := 100
userid := r.URL.Query().Get("userid")
var conditions string
var values []interface{}
if userid != "" {
conditions = "user_id = ?"
values = append(values, userid)
}
comments, nbComments := commentService.GetAllComments(offset, (pagenum-1)*offset, conditions, values...)
languages.SetTranslationFromRequest(panelCommentList, r)
htv := PanelCommentListVbs{comments, NewSearchForm(), Navigation{nbComments, offset, pagenum, "mod_clist_page"}, currentUser, r.URL}
err = panelCommentList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
id := r.URL.Query().Get("id")
torrent, _ := torrentService.GetTorrentById(id)
languages.SetTranslationFromRequest(panelTorrentEd, r)
torrentJson := torrent.ToJSON()
uploadForm := NewUploadForm()
uploadForm.Name = torrentJson.Name
uploadForm.Category = torrentJson.Category + "_" + torrentJson.SubCategory
uploadForm.Status = torrentJson.Status
uploadForm.Description = string(torrentJson.Description)
htv := PanelTorrentEdVbs{uploadForm, NewPanelSearchForm(), currentUser, form.NewErrors(), form.NewInfos(), r.URL}
err := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
id := r.URL.Query().Get("id")
torrent, _ := torrentService.GetTorrentById(id)
languages.SetTranslationFromRequest(panelTorrentEd, r)
torrentJson := torrent.ToJSON()
uploadForm := NewUploadForm()
uploadForm.Name = torrentJson.Name
uploadForm.Category = torrentJson.Category + "_" + torrentJson.SubCategory
uploadForm.Status = torrentJson.Status
uploadForm.Description = string(torrentJson.Description)
htv := PanelTorrentEdVbs{uploadForm, NewPanelSearchForm(), currentUser, form.NewErrors(), form.NewInfos(), r.URL}
err := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if !userPermission.HasAdmin(currentUser) {
http.Error(w, "admins only", http.StatusForbidden)
return
}
var uploadForm UploadForm
id := r.URL.Query().Get("id")
err := form.NewErrors()
@ -308,61 +278,42 @@ func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
}
func CommentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
id := r.URL.Query().Get("id")
if userPermission.HasAdmin(currentUser) {
_ = form.NewErrors()
_, _ = userService.DeleteComment(id)
url, _ := Router.Get("mod_clist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
_ = form.NewErrors()
_, _ = userService.DeleteComment(id)
url, _ := Router.Get("mod_clist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
func TorrentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
id := r.URL.Query().Get("id")
if userPermission.HasAdmin(currentUser) {
_ = form.NewErrors()
_, _ = torrentService.DeleteTorrent(id)
_ = form.NewErrors()
_, _ = torrentService.DeleteTorrent(id)
//delete reports of torrent
whereParams := serviceBase.CreateWhereParams("torrent_id = ?", id)
reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0)
for _, report := range reports {
reportService.DeleteTorrentReport(report.ID)
}
url, _ := Router.Get("mod_tlist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
} else {
http.Error(w, "admins only", http.StatusForbidden)
//delete reports of torrent
whereParams := serviceBase.CreateWhereParams("torrent_id = ?", id)
reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0)
for _, report := range reports {
reportService.DeleteTorrentReport(report.ID)
}
url, _ := Router.Get("mod_tlist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
func TorrentReportDeleteModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
id := r.URL.Query().Get("id")
fmt.Println(id)
idNum, _ := strconv.ParseUint(id, 10, 64)
_ = form.NewErrors()
_, _ = reportService.DeleteTorrentReport(uint(idNum))
id := r.URL.Query().Get("id")
fmt.Println(id)
idNum, _ := strconv.ParseUint(id, 10, 64)
_ = form.NewErrors()
_, _ = reportService.DeleteTorrentReport(uint(idNum))
url, _ := Router.Get("mod_trlist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
url, _ := Router.Get("mod_trlist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
func TorrentReassignModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if !userPermission.HasAdmin(currentUser) {
http.Error(w, "admins only", http.StatusForbidden)
return
}
languages.SetTranslationFromRequest(panelTorrentReassign, r)
htv := PanelTorrentReassignVbs{ReassignForm{}, NewPanelSearchForm(), currentUser, form.NewErrors(), form.NewInfos(), r.URL}
@ -372,10 +323,6 @@ func TorrentReassignModPanel(w http.ResponseWriter, r *http.Request) {
func TorrentPostReassignModPanel(w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if !userPermission.HasAdmin(currentUser) {
http.Error(w, "admins only", http.StatusForbidden)
return
}
var rForm ReassignForm
err := form.NewErrors()
infos := form.NewInfos()

Voir le fichier

@ -66,23 +66,26 @@ func init() {
Router.HandleFunc("/user/{id}/{username}/feed", RSSHandler).Name("feed_user")
Router.HandleFunc("/user/{id}/{username}/feed/{page}", RSSHandler).Name("feed_user_page")
Router.HandleFunc("/mod", IndexModPanel).Name("mod_index")
Router.HandleFunc("/mod/torrents", TorrentsListPanel).Name("mod_tlist")
Router.HandleFunc("/mod/torrents/{page}", TorrentsListPanel).Name("mod_tlist_page")
Router.HandleFunc("/mod/reports", TorrentReportListPanel).Name("mod_trlist")
Router.HandleFunc("/mod/reports/{page}", TorrentReportListPanel).Name("mod_trlist_page")
Router.HandleFunc("/mod/users", UsersListPanel).Name("mod_ulist")
Router.HandleFunc("/mod/users/{page}", UsersListPanel).Name("mod_ulist_page")
Router.HandleFunc("/mod/comments", CommentsListPanel).Name("mod_clist")
Router.HandleFunc("/mod/comments/{page}", CommentsListPanel).Name("mod_clist_page")
Router.HandleFunc("/mod/comment", CommentsListPanel).Name("mod_cedit") // TODO
Router.HandleFunc("/mod/torrent/", TorrentEditModPanel).Name("mod_tedit").Methods("GET")
Router.HandleFunc("/mod/torrent/", TorrentPostEditModPanel).Name("mod_ptedit").Methods("POST")
Router.HandleFunc("/mod/torrent/delete", TorrentDeleteModPanel).Name("mod_tdelete")
Router.HandleFunc("/mod/report/delete", TorrentReportDeleteModPanel).Name("mod_trdelete")
Router.HandleFunc("/mod/comment/delete", CommentDeleteModPanel).Name("mod_cdelete")
Router.HandleFunc("/mod/reassign", TorrentReassignModPanel).Name("mod_treassign").Methods("GET")
Router.HandleFunc("/mod/reassign", TorrentPostReassignModPanel).Name("mod_treassign").Methods("POST")
// INFO Everything under /mod should be wrapped by WrapModHandler. This make
// sure the page is only accessible by moderators
// TODO Find a native mux way to add a 'prehook' for route /mod
Router.HandleFunc("/mod", WrapModHandler(IndexModPanel)).Name("mod_index")
Router.HandleFunc("/mod/torrents", WrapModHandler(TorrentsListPanel)).Name("mod_tlist")
Router.HandleFunc("/mod/torrents/{page}", WrapModHandler(TorrentsListPanel)).Name("mod_tlist_page")
Router.HandleFunc("/mod/reports", WrapModHandler(TorrentReportListPanel)).Name("mod_trlist")
Router.HandleFunc("/mod/reports/{page}", WrapModHandler(TorrentReportListPanel)).Name("mod_trlist_page")
Router.HandleFunc("/mod/users", WrapModHandler(UsersListPanel)).Name("mod_ulist")
Router.HandleFunc("/mod/users/{page}", WrapModHandler(UsersListPanel)).Name("mod_ulist_page")
Router.HandleFunc("/mod/comments", WrapModHandler(CommentsListPanel)).Name("mod_clist")
Router.HandleFunc("/mod/comments/{page}", WrapModHandler(CommentsListPanel)).Name("mod_clist_page")
Router.HandleFunc("/mod/comment", WrapModHandler(CommentsListPanel)).Name("mod_cedit") // TODO
Router.HandleFunc("/mod/torrent/", WrapModHandler(TorrentEditModPanel)).Name("mod_tedit").Methods("GET")
Router.HandleFunc("/mod/torrent/", WrapModHandler(TorrentPostEditModPanel)).Name("mod_ptedit").Methods("POST")
Router.HandleFunc("/mod/torrent/delete", WrapModHandler(TorrentDeleteModPanel)).Name("mod_tdelete")
Router.HandleFunc("/mod/report/delete", WrapModHandler(TorrentReportDeleteModPanel)).Name("mod_trdelete")
Router.HandleFunc("/mod/comment/delete", WrapModHandler(CommentDeleteModPanel)).Name("mod_cdelete")
Router.HandleFunc("/mod/reassign", WrapModHandler(TorrentReassignModPanel)).Name("mod_treassign").Methods("GET")
Router.HandleFunc("/mod/reassign", WrapModHandler(TorrentPostReassignModPanel)).Name("mod_treassign").Methods("POST")
//reporting a torrent
Router.HandleFunc("/report/{id}", ReportTorrentHandler).Methods("POST").Name("post_comment")

Voir le fichier

@ -26,6 +26,10 @@ func RSSHandler(w http.ResponseWriter, r *http.Request) {
util.SendError(w, err, 400)
return
}
if pagenum <= 0 {
NotFoundHandler(w, r)
return
}
}
if userID != "" {

Voir le fichier

@ -25,6 +25,10 @@ func SearchHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if pagenum <= 0 {
NotFoundHandler(w, r)
return
}
}
searchParam, torrents, nbTorrents, err := search.SearchByQuery(r, pagenum)

Voir le fichier

@ -5,8 +5,11 @@ import (
"path/filepath"
)
// FIXME This should be a constant, but then the tests fails
var TemplateDir = "templates"
const ModeratorDir = "admin"
var homeTemplate,
searchTemplate,
faqTemplate,
@ -125,37 +128,37 @@ func ReloadTemplates() {
templateLoader{
templ: &panelTorrentList,
name: "torrentlist",
file: filepath.Join("admin", "torrentlist.html"),
file: filepath.Join(ModeratorDir, "torrentlist.html"),
},
templateLoader{
templ: &panelUserList,
name: "userlist",
file: filepath.Join("admin", "userlist.html"),
file: filepath.Join(ModeratorDir, "userlist.html"),
},
templateLoader{
templ: &panelCommentList,
name: "commentlist",
file: filepath.Join("admin", "commentlist.html"),
file: filepath.Join(ModeratorDir, "commentlist.html"),
},
templateLoader{
templ: &panelIndex,
name: "indexPanel",
file: filepath.Join("admin", "panelindex.html"),
file: filepath.Join(ModeratorDir, "panelindex.html"),
},
templateLoader{
templ: &panelTorrentEd,
name: "torrent_ed",
file: filepath.Join("admin", "paneltorrentedit.html"),
file: filepath.Join(ModeratorDir, "paneltorrentedit.html"),
},
templateLoader{
templ: &panelTorrentReportList,
name: "torrent_report",
file: filepath.Join("admin", "torrent_report.html"),
file: filepath.Join(ModeratorDir, "torrent_report.html"),
},
templateLoader{
templ: &panelTorrentReassign,
name: "torrent_reassign",
file: filepath.Join("admin", "reassign.html"),
file: filepath.Join(ModeratorDir, "reassign.html"),
},
}
@ -164,7 +167,6 @@ func ReloadTemplates() {
}
templs := make([]templateLoader, 0, len(modTempls)+len(pubTempls))
templs = append(templs, pubTempls...)
templs = append(templs, modTempls...)
@ -173,5 +175,4 @@ func ReloadTemplates() {
t = template.Must(t.ParseGlob(filepath.Join(TemplateDir, "_*.html")))
*templ.templ = t
}
}

Voir le fichier

@ -45,8 +45,8 @@ var FuncMap = template.FuncMap{
},
"genSearchWithOrdering": func(currentUrl url.URL, sortBy string) template.URL {
values := currentUrl.Query()
order := false //Default is DESC
sort := "2" //Default is Date (Actually ID, but Date is the same thing)
order := false //Default is DESC
sort := "2" //Default is Date (Actually ID, but Date is the same thing)
if _, ok := values["order"]; ok {
order, _ = strconv.ParseBool(values["order"][0])
@ -54,7 +54,7 @@ var FuncMap = template.FuncMap{
if _, ok := values["sort"]; ok {
sort = values["sort"][0]
}
if sort == sortBy {
order = !order //Flip order by repeat-clicking
} else {
@ -132,7 +132,7 @@ var FuncMap = template.FuncMap{
return template.HTML(ret)
},
"Sukebei": func() bool {
if config.TableName == "sukebei_torrents" {
if config.TorrentsTableName == "sukebei_torrents" {
return true
} else {
return false

Voir le fichier

@ -10,24 +10,17 @@ import (
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service/captcha"
"github.com/NyaaPantsu/nyaa/service/upload"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/gorilla/mux"
)
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if config.UploadsDisabled {
user := GetUser(r)
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
}
user := GetUser(r)
if !uploadService.IsUploadEnabled(*user) {
http.Error(w, "Error uploads are disabled", http.StatusBadRequest)
return
}
if r.Method == "POST" {
@ -58,15 +51,15 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
status := 1 // normal
status := model.TorrentStatusNormal
if uploadForm.Remake { // overrides trusted
status = 2
} else if user.Status == 1 {
status = 3 // mark as trusted if user is trusted
status = model.TorrentStatusRemake
} else if user.IsTrusted() {
status = model.TorrentStatusTrusted
}
var sameTorrents int
db.ORM.Model(&model.Torrent{}).Table(config.TableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
db.ORM.Model(&model.Torrent{}).Table(config.TorrentsTableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
if sameTorrents == 0 {
// add to db and redirect
torrent := model.Torrent{
@ -79,7 +72,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
Filesize: uploadForm.Filesize,
Description: uploadForm.Description,
UploaderID: user.ID}
db.ORM.Table(config.TableName).Create(&torrent)
db.ORM.Table(config.TorrentsTableName).Create(&torrent)
// add filelist to files db, if we have one
if len(uploadForm.FileList) > 0 {

Voir le fichier

@ -46,8 +46,8 @@ func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
loginForm := form.LoginForm{}
modelHelper.BindValueForm(&loginForm, r)
languages.SetTranslationFromRequest(viewLoginTemplate, r)
ulfv := UserLoginFormVariables{
LoginForm: loginForm,
FormErrors: form.NewErrors(),
@ -286,9 +286,15 @@ func UserLoginPostHandler(w http.ResponseWriter, r *http.Request) {
url, _ := Router.Get("home").URL()
http.Redirect(w, r, url.String(), http.StatusSeeOther)
}
}
if len(err) > 0 {
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
htv := UserLoginFormVariables{b, err, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
errorTmpl := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
if errorTmpl != nil {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
}
}
}
// Logout

Voir le fichier

@ -2,6 +2,8 @@ package router
import (
"net/http"
"github.com/NyaaPantsu/nyaa/service/user/permission"
)
type wrappedResponseWriter struct {
@ -47,3 +49,16 @@ func (wh *wrappedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func wrapHandler(handler http.Handler) http.Handler {
return &wrappedHandler{handler}
}
// Make sure the user is a moderator, otherwise return forbidden
// TODO Clean this
func WrapModHandler(handler func (w http.ResponseWriter, r *http.Request)) (func (w http.ResponseWriter, r *http.Request)) {
return func (w http.ResponseWriter, r *http.Request) {
currentUser := GetUser(r)
if userPermission.HasAdmin(currentUser) {
handler(w, r)
} else {
http.Error(w, "admins only", http.StatusForbidden)
}
}
}

Voir le fichier

@ -181,7 +181,7 @@ func (sc *Scraper) Scrape(packets uint) {
now := time.Now().Add(0 - sc.interval)
// only scrape torretns uploaded within 90 days
oldest := now.Add(0 - (time.Hour * 24 * 90))
rows, err := db.ORM.Raw("SELECT torrent_id, torrent_hash FROM "+config.TableName+" WHERE ( last_scrape IS NULL OR last_scrape < ? ) AND date > ? ORDER BY torrent_id DESC LIMIT ?", now, oldest, packets*ScrapesPerPacket).Rows()
rows, err := db.ORM.Raw("SELECT torrent_id, torrent_hash FROM "+config.TorrentsTableName+" WHERE ( last_scrape IS NULL OR last_scrape < ? ) AND date > ? ORDER BY torrent_id DESC LIMIT ?", now, oldest, packets*ScrapesPerPacket).Rows()
if err == nil {
counter := 0
var scrape [ScrapesPerPacket]model.Torrent

Voir le fichier

@ -54,8 +54,8 @@ func (t *Transaction) handleScrapeReply(data []byte) {
}
}
const pgQuery = "UPDATE " + config.TableName + " SET seeders = $1 , leechers = $2 , completed = $3 , last_scrape = $4 WHERE torrent_id = $5"
const sqliteQuery = "UPDATE " + config.TableName + " SET seeders = ? , leechers = ? , completed = ? , last_scrape = ? WHERE torrent_id = ?"
const pgQuery = "UPDATE " + config.TorrentsTableName + " SET seeders = $1 , leechers = $2 , completed = $3 , last_scrape = $4 WHERE torrent_id = $5"
const sqliteQuery = "UPDATE " + config.TorrentsTableName + " SET seeders = ? , leechers = ? , completed = ? , last_scrape = ? WHERE torrent_id = ?"
// Sync syncs models with database
func (t *Transaction) Sync() (err error) {

Voir le fichier

@ -233,9 +233,9 @@ func (fetcher *MetainfoFetcher) fillQueue() {
var params serviceBase.WhereParams
if len(excludedIDS) > 0 {
params = serviceBase.CreateWhereParams("((filesize IS NULL OR filesize = 0) OR ("+config.TableName+".torrent_id NOT IN (SELECT files.torrent_id FROM files WHERE files.torrent_id = "+config.TableName+".torrent_id))) AND date > ? AND torrent_id NOT IN (?)", oldest, excludedIDS)
params = serviceBase.CreateWhereParams("((filesize IS NULL OR filesize = 0) OR ("+config.TorrentsTableName+".torrent_id NOT IN (SELECT files.torrent_id FROM files WHERE files.torrent_id = "+config.TorrentsTableName+".torrent_id))) AND date > ? AND torrent_id NOT IN (?)", oldest, excludedIDS)
} else {
params = serviceBase.CreateWhereParams("((filesize IS NULL OR filesize = 0) OR ("+config.TableName+".torrent_id NOT IN (SELECT files.torrent_id FROM files WHERE files.torrent_id = "+config.TableName+".torrent_id))) AND date > ?", oldest)
params = serviceBase.CreateWhereParams("((filesize IS NULL OR filesize = 0) OR ("+config.TorrentsTableName+".torrent_id NOT IN (SELECT files.torrent_id FROM files WHERE files.torrent_id = "+config.TorrentsTableName+".torrent_id))) AND date > ?", oldest)
}
dbTorrents, err := torrentService.GetTorrentsOrderByNoCount(&params, "", fetcher.queueSize, 0)

Voir le fichier

@ -24,7 +24,7 @@ func GetFeeds() (result []model.Feed, err error) {
result = make([]model.Feed, 0, 50)
rows, err := db.ORM.DB().
Query(
"SELECT `torrent_id` AS `id`, `torrent_name` AS `name`, `torrent_hash` AS `hash`, `timestamp` FROM `" + config.TableName +
"SELECT `torrent_id` AS `id`, `torrent_name` AS `name`, `torrent_hash` AS `hash`, `timestamp` FROM `" + config.TorrentsTableName +
"` ORDER BY `timestamp` desc LIMIT 50")
if err != nil {
return nil, err
@ -53,7 +53,7 @@ func GetTorrentById(id string) (torrent model.Torrent, err error) {
return
}
tmp := db.ORM.Table(config.TableName).Where("torrent_id = ?", id).Preload("Comments").Preload("FileList")
tmp := db.ORM.Table(config.TorrentsTableName).Where("torrent_id = ?", id).Preload("Comments").Preload("FileList")
err = tmp.Error
if err != nil {
return
@ -91,7 +91,7 @@ func GetTorrentById(id string) (torrent model.Torrent, err error) {
// won't fetch user or comments
func GetRawTorrentById(id uint) (torrent model.Torrent, err error) {
err = nil
if db.ORM.Table(config.TableName).Table(config.TableName).Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
if db.ORM.Table(config.TorrentsTableName).Table(config.TorrentsTableName).Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
err = errors.New("Article is not found.")
}
return
@ -122,7 +122,7 @@ func getTorrentsOrderBy(parameters *serviceBase.WhereParams, orderBy string, lim
conditions := strings.Join(conditionArray, " AND ")
if countAll {
// FIXME: `deleted_at IS NULL` is duplicate in here because GORM handles this for us
err = db.ORM.Model(&torrents).Table(config.TableName).Where(conditions, params...).Count(&count).Error
err = db.ORM.Model(&torrents).Table(config.TorrentsTableName).Where(conditions, params...).Count(&count).Error
if err != nil {
return
}
@ -130,7 +130,7 @@ func getTorrentsOrderBy(parameters *serviceBase.WhereParams, orderBy string, lim
// TODO: Vulnerable to injections. Use query builder. (is it?)
// build custom db query for performance reasons
dbQuery := "SELECT * FROM " + config.TableName
dbQuery := "SELECT * FROM " + config.TorrentsTableName
if conditions != "" {
dbQuery = dbQuery + " WHERE " + conditions
}
@ -177,17 +177,17 @@ func GetAllTorrentsDB() ([]model.Torrent, int, error) {
func DeleteTorrent(id string) (int, error) {
var torrent model.Torrent
if db.ORM.Table(config.TableName).First(&torrent, id).RecordNotFound() {
if db.ORM.Table(config.TorrentsTableName).First(&torrent, id).RecordNotFound() {
return http.StatusNotFound, errors.New("Torrent is not found.")
}
if db.ORM.Table(config.TableName).Delete(&torrent).Error != nil {
if db.ORM.Table(config.TorrentsTableName).Delete(&torrent).Error != nil {
return http.StatusInternalServerError, errors.New("Torrent is not deleted.")
}
return http.StatusOK, nil
}
func UpdateTorrent(torrent model.Torrent) (int, error) {
if db.ORM.Table(config.TableName).Save(torrent).Error != nil {
if db.ORM.Table(config.TorrentsTableName).Save(torrent).Error != nil {
return http.StatusInternalServerError, errors.New("Torrent is not updated.")
}

Voir le fichier

@ -2,6 +2,9 @@ package uploadService
import (
"strings"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/model"
)
func CheckTrackers(trackers []string) bool {
@ -36,3 +39,16 @@ func CheckTrackers(trackers []string) bool {
}
return numGood > 0
}
func IsUploadEnabled(u model.User) bool {
if config.UploadsDisabled {
if config.AdminsAreStillAllowedTo && u.IsModerator() {
return true
}
if config.TrustedUsersAreStillAllowedTo && u.IsTrusted() {
return true
}
return false
}
return true
}

Voir le fichier

@ -79,7 +79,7 @@ func SetCookieHandler(w http.ResponseWriter, email string, pass string) (int, er
if err != nil {
return http.StatusUnauthorized, errors.New("Password incorrect")
}
if user.Status == -1 {
if user.IsBanned() {
return http.StatusUnauthorized, errors.New("Account banned")
}
@ -135,7 +135,7 @@ func CurrentUser(r *http.Request) (model.User, error) {
return user, errors.New("User not found")
}
if user.Status == -1 {
if user.IsBanned() {
// recheck as user might've been banned in the meantime
return user, errors.New("Account banned")
}

Voir le fichier

@ -8,7 +8,7 @@ import (
// HasAdmin checks that user has an admin permission.
func HasAdmin(user *model.User) bool {
return user.Status == 2
return user.IsModerator()
}
// CurrentOrAdmin check that user has admin permission or user is the current user.
@ -25,18 +25,18 @@ func CurrentUserIdentical(user *model.User, userID uint) bool {
func NeedsCaptcha(user *model.User) bool {
// Trusted members & Moderators don't
return !(user.Status == 1 || user.Status == 2)
return !(user.IsTrusted() || user.IsModerator())
}
func GetRole(user *model.User) string {
switch user.Status {
case -1:
case model.UserStatusBanned:
return "Banned"
case 0:
case model.UserStatusMember:
return "Member"
case 1:
case model.UserStatusTrusted:
return "Trusted Member"
case 2:
case model.UserStatusModerator:
return "Moderator"
}
return "Member"

Voir le fichier

@ -129,7 +129,7 @@ func RetrieveUser(r *http.Request, id string) (*model.PublicUser, bool, uint, in
var currentUserID uint
var isAuthor bool
if db.ORM.Table(config.TableName).First(&user, id).RecordNotFound() {
if db.ORM.Table(config.TorrentsTableName).First(&user, id).RecordNotFound() {
return nil, isAuthor, currentUserID, http.StatusNotFound, errors.New("user not found")
}
currentUser, err := CurrentUser(r)

Voir le fichier

@ -11,6 +11,9 @@
<a href="https://nyaa.pantsu.cat">Nyaa - nyaa.pantsu.cat</a><br />
<a href="https://sukebei.pantsu.cat">Sukebei - sukebei.pantsu.cat</a>
<h2>{{T "server_status_link"}}</h2>
<a href="https://status.pantsu.cat/">https://status.pantsu.cat/</a><br />
<h2>{{T "what_happened"}}</h2>
<ul>
<li>{{T "nyaa_se_went_offline"}}</li>

Voir le fichier

@ -4,6 +4,7 @@
<div class="blockBody">
<div class="row" style="margin-top:20px">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
{{ with .LoginForm }}
<form role="form" method="POST">
<fieldset>
<h2>{{T "sign_in_box_title"}}</h2>
@ -39,6 +40,7 @@
</div>
</fieldset>
</form>
{{end}}
</div>
</div>
<br />

Voir le fichier

@ -751,6 +751,10 @@
"id": "last_scraped",
"translation": "Last scraped: "
},
{
"id": "server_status_link",
"translation": "Server status can be found here"
},
{
"id": "no_database_dumps_available",
"translation": "No database dumps are available at this moment."