mirror of
https://github.com/Mistake35/Cedar-Django.git
synced 2026-07-18 00:21:14 +10:00
Invite only setting, stolen code, bunch of other random shit.
This commit is contained in:
@@ -112,11 +112,9 @@ class AuditAdmin(admin.ModelAdmin):
|
||||
|
||||
class AdsAdmin(admin.ModelAdmin):
|
||||
raw_id_fileds = ('id', 'created', 'url', 'imageurl')
|
||||
|
||||
class MOTDAdmin(admin.ModelAdmin):
|
||||
raw_id_fileds = ('id', 'created', 'message', )
|
||||
list_display = ('message', 'show', 'order', 'created', )
|
||||
actions = [Hide_Memo, Show_Memo]
|
||||
|
||||
class InvitesAdmin(admin.ModelAdmin):
|
||||
raw_id_fileds = ('id', 'created', 'creator')
|
||||
|
||||
class WelcomemsgAdmin(admin.ModelAdmin):
|
||||
raw_id_fileds = ('id', 'created', 'message', )
|
||||
@@ -151,11 +149,11 @@ admin.site.register(models.ProfileHistory, HistoryAdmin)
|
||||
admin.site.register(models.Post, PostAdmin)
|
||||
admin.site.register(models.Comment, CommentAdmin)
|
||||
admin.site.register(models.Ads, AdsAdmin)
|
||||
admin.site.register(models.Motd, MOTDAdmin)
|
||||
admin.site.register(models.welcomemsg, WelcomemsgAdmin)
|
||||
admin.site.register(models.Yeah, YeahAdmin)
|
||||
admin.site.register(models.Follow)
|
||||
admin.site.register(models.FriendRequest)
|
||||
admin.site.register(models.Friendship, ConversationAdmin)
|
||||
admin.site.register(models.Invites, InvitesAdmin)
|
||||
admin.site.register(models.Poll)
|
||||
admin.site.register(models.PollVote)
|
||||
|
||||
@@ -1,72 +1,48 @@
|
||||
from django.http import HttpResponseForbidden, HttpResponseBadRequest
|
||||
from django.http import HttpResponseForbidden
|
||||
from closedverse import settings
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import redirect
|
||||
from django.contrib.auth import logout
|
||||
from re import compile
|
||||
|
||||
class ClosedMiddleware(object):
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
response = self.get_response(request)
|
||||
if request.user.is_authenticated:
|
||||
if not request.user.profile():
|
||||
return HttpResponseForbidden('So, Somehow your profile is completely gone. Your account itself still exists, but your profile does not. Please contact an admin, and ask them to make a profile for you. If you are unable to contact someone, you should make a new account.')
|
||||
else:
|
||||
return response
|
||||
'''
|
||||
for keyword in ['24.61.157.95', ]:
|
||||
if keyword in request.META['HTTP_CF_CONNECTING_IP']:
|
||||
return redirect('https://file.garden/Xbo5elapeDSxWf1x/adam.mp4')
|
||||
|
||||
for keyword in ['PlayStation', 'Switch', '3DS', ]:
|
||||
if keyword in request.META['HTTP_USER_AGENT']:
|
||||
return HttpResponseForbidden('Error code 403')
|
||||
'''
|
||||
else:
|
||||
return response
|
||||
|
||||
# Taken from https://python-programming.com/recipes/django-require-authentication-pages/
|
||||
'''
|
||||
if settings.FORCE_LOGIN:
|
||||
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
|
||||
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
|
||||
EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
|
||||
|
||||
class ClosedMiddleware(object):
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
# Force logins if it's set
|
||||
if settings.force_login and not request.user.is_authenticated:
|
||||
if not any(m.match(request.path_info.lstrip('/')) for m in EXEMPT_URLS):
|
||||
if request.is_ajax():
|
||||
return HttpResponseForbidden("Login is required")
|
||||
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||
# Fix this ; put something in settings signifying if the server supports HTTPS or not
|
||||
if not request.is_secure() and (not settings.DEBUG) and settings.PROD:
|
||||
# Let's try to redirect to HTTPS for non-Nintendo stuff.
|
||||
if not request.META.get('HTTP_USER_AGENT'):
|
||||
return HttpResponseForbidden("You need a user agent.", content_type='text/plain')
|
||||
if not request.is_secure() and not 'Nintendo' in request.META['HTTP_USER_AGENT']:
|
||||
return redirect('https://{0}{1}'.format(request.get_host(), request.get_full_path()))
|
||||
if request.user.is_authenticated:
|
||||
# User active; this doesn't work at the moment due to Postgres not being able to change bools to ints
|
||||
if request.user.is_active() == 0:
|
||||
return HttpResponseForbidden()
|
||||
elif request.user.is_active() == 2:
|
||||
return redirect(settings.inactive_redirect)
|
||||
|
||||
if not request.user.is_active:
|
||||
return HttpResponseForbidden()
|
||||
# If there isn't a request.session
|
||||
if not request.session.get('passwd'):
|
||||
request.session['passwd'] = request.user.password
|
||||
else:
|
||||
if request.session['passwd'] != request.user.password:
|
||||
logout(request)
|
||||
response = self.get_response(request)
|
||||
def __call__(self, request):
|
||||
# Force logins if it's set
|
||||
if settings.FORCE_LOGIN and not request.user.is_authenticated:
|
||||
if not any(m.match(request.path_info.lstrip('/')) for m in EXEMPT_URLS):
|
||||
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
|
||||
return HttpResponseForbidden("Login is required")
|
||||
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||
# Fix this ; put something in settings signifying if the server supports HTTPS or not
|
||||
#if not request.is_secure() and (not settings.DEBUG) and settings.CLOSEDVERSE_PROD:
|
||||
# Let's try to redirect to HTTPS for non-Nintendo stuff.
|
||||
"""
|
||||
if not request.META.get('HTTP_USER_AGENT'):
|
||||
return HttpResponseForbidden("You need a user agent.", content_type='text/plain')
|
||||
if settings.CLOSEDVERSE_PROD not request.is_secure() and not 'Nintendo' in request.META['HTTP_USER_AGENT']:
|
||||
return redirect('https://{0}{1}'.format(request.get_host(), request.get_full_path()))
|
||||
"""
|
||||
if request.user.is_authenticated:
|
||||
if not request.user.is_active():
|
||||
if request.user.warned_reason:
|
||||
ban_msg = request.user.warned_reason
|
||||
else:
|
||||
ban_msg = 'You are banned.'
|
||||
return HttpResponseForbidden(ban_msg)
|
||||
# If there isn't a request.session
|
||||
if not request.session.get('passwd'):
|
||||
request.session['passwd'] = request.user.password
|
||||
else:
|
||||
if request.session['passwd'] != request.user.password:
|
||||
logout(request)
|
||||
response = self.get_response(request)
|
||||
|
||||
return response
|
||||
'''
|
||||
|
||||
"""
|
||||
return HttpResponseForbidden("You're one sick fuck. I would never suggest removing an Inkling girl's clothes and licking her tiny body all over, nibbling her neck and kissing her adorable little nipples. Only a heartless monster would think about her cute girlish mouth and tongue wrapped around a thick cock slick with her saliva, pumping in and out of her mouth until it erupts, the cum more than her little throat can swallow. The idea of thick viscous semen overflowing, dribbling down her chin over her flat chest, her tiny hands scooping it all up and watching her suck it off her fingertips is just horrible. You're all a bunch of sick perverts, thinking of spreading her smooth slender thighs, cock poised at the entrance to her pure, tight, virginal pussy, and thrusting in deep as a whimper escapes her lips which are slippery with cum, while her small body shudders from having her cherry taken in one quick stroke. I am disgusted at how you'd get even more excited as you lean over her, listening to her quickening breath, her girlish moans and gasps while you hasten your strokes, her sweet pants warm and moist on your face and her flat chest, shiny with a sheen of fresh sweat, rising and falling rapidly to meet yours. It is truly nasty how you'd run your hands all over her tiny body while you violate her, feeling her nipples hardening against your tongue as you lick her chest, her neck and her armpits, savoring the scent of her skin and sweat while she trembles from the stimulation and as she reaches her climax, hearing her cry out softly as she has her first orgasm while that cock is buried impossibly deep inside her, pulsing violently as an intense amount of hot cum spurts forth and floods through her freshly-deflowered pussy for the first time, filling her womb only to spill out of her with a sickening squelch. And as you lie atop her flushed body, she murmurs breathlessly, \"You came so much inside of me,\" then her fingers dig into your back as she feels your cock hardening inside again.", content_type='text/plain')"""
|
||||
return response
|
||||
|
||||
+46
-31
@@ -117,10 +117,14 @@ class CommunityFavoriteManager(models.Manager):
|
||||
color_re = re.compile('^#([A-Fa-f0-9]{6})$')
|
||||
validate_color = RegexValidator(color_re, "Enter a valid color", 'invalid')
|
||||
class ColorField(models.CharField):
|
||||
default_validators = [validate_color]
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['max_length'] = 18
|
||||
super(ColorField, self).__init__(*args, **kwargs)
|
||||
default_validators = [validate_color]
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['max_length'] = 18
|
||||
super(ColorField, self).__init__(*args, **kwargs)
|
||||
|
||||
#mii_domain = 'https://mii-secure.cdn.nintendo.net'
|
||||
# as of writing, mii-secure is unstable, nintendo please do not f*ck me for this
|
||||
mii_domain = 'https://s3.us-east-1.amazonaws.com/mii-images.account.nintendo.net/'
|
||||
|
||||
class User(models.Model):
|
||||
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
@@ -151,6 +155,7 @@ class User(models.Model):
|
||||
staff = models.BooleanField(default=False)
|
||||
#active = models.SmallIntegerField(default=1, choices=((0, 'Redirect'), (1, 'Good'), (2, 'Disabled')))
|
||||
active = models.BooleanField(default=True)
|
||||
can_invite = models.BooleanField(default=True)
|
||||
warned = models.BooleanField(default=False)
|
||||
warned_reason = models.CharField(blank=True, null=True, max_length=600)
|
||||
bg_url = models.CharField(max_length=300, null=True, blank=True)
|
||||
@@ -168,19 +173,6 @@ class User(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
||||
def ColorTheme(self):
|
||||
# if the user set a theme, display that.
|
||||
if self.theme:
|
||||
the_theme = self.theme
|
||||
the_theme = the_theme.strip("#")
|
||||
# if there's no theme set by the user, use the site's picked theme.
|
||||
elif settings.site_wide_theme_hex:
|
||||
the_theme = settings.site_wide_theme_hex
|
||||
the_theme = the_theme.strip("#")
|
||||
# If there's no theme set in settings.py, return None.
|
||||
else:
|
||||
the_theme = None
|
||||
return the_theme
|
||||
def get_full_name(self):
|
||||
return self.username
|
||||
def get_short_name(self):
|
||||
@@ -315,7 +307,7 @@ class User(models.Model):
|
||||
4: 'frustrated',
|
||||
5: 'puzzled',
|
||||
}.get(feeling, "normal")
|
||||
url = 'https://mii-secure.cdn.nintendo.net/{0}_{1}_face.png'.format(self.avatar, feeling)
|
||||
url = '{2}{0}_{1}_face.png'.format(self.avatar, feeling, mii_domain)
|
||||
return url
|
||||
elif not self.avatar:
|
||||
return settings.STATIC_URL + 'img/anonymous-mii.png'
|
||||
@@ -427,15 +419,18 @@ class User(models.Model):
|
||||
|
||||
# Admin can-manage
|
||||
def can_manage(self):
|
||||
if (self.level >= 2) or self.is_staff():
|
||||
return True
|
||||
return False
|
||||
# Does user have authority over self?
|
||||
if self.level >= settings.level_needed_to_man_users or self.staff:
|
||||
can_manage = True
|
||||
else:
|
||||
can_manage = False
|
||||
return can_manage
|
||||
# Does self have authority over user?
|
||||
def has_authority(self, user):
|
||||
if self.is_staff():
|
||||
return False
|
||||
if (self.level < user.level):
|
||||
return True
|
||||
if user.is_authenticated:
|
||||
if self.staff and not user.staff:
|
||||
return True
|
||||
if self.level >= user.level:
|
||||
return True
|
||||
return False
|
||||
def friend_state(self, other):
|
||||
# Todo: return -1 for cannot, 0 for nothing, 1 for my friend pending, 2 for their friend pending, 3 for friends
|
||||
@@ -596,6 +591,26 @@ class User(models.Model):
|
||||
except:
|
||||
return False
|
||||
return user
|
||||
|
||||
# An invite system, for closed off communities or for whatever reason.
|
||||
class Invites(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
creator = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE, related_name='invite_creator')
|
||||
code = models.CharField(max_length=36, default=uuid.uuid4)
|
||||
used = models.BooleanField(default=False)
|
||||
void = models.BooleanField(default=False)
|
||||
used_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE, related_name='invited_user')
|
||||
|
||||
def is_valid(self):
|
||||
if self.used or self.void:
|
||||
return False
|
||||
if not self.creator.can_invite:
|
||||
return False
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
return "invite by " + str(self.creator)
|
||||
|
||||
class Community(models.Model):
|
||||
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
@@ -869,8 +884,8 @@ class Post(models.Model):
|
||||
return False
|
||||
def can_rm(self, request):
|
||||
if self.creator.has_authority(request.user):
|
||||
return True
|
||||
return False
|
||||
return False
|
||||
return True
|
||||
def give_yeah(self, request):
|
||||
if not request.user.has_freedom() and Yeah.objects.filter(by=request.user, created__gt=timezone.now() - timedelta(seconds=5)).exists():
|
||||
return False
|
||||
@@ -1083,10 +1098,10 @@ class Comment(models.Model):
|
||||
# return False
|
||||
def can_rm(self, request):
|
||||
if self.creator.has_authority(request.user):
|
||||
return True
|
||||
return False
|
||||
#if self.original_post.is_mine(request.user):
|
||||
# return True
|
||||
return False
|
||||
return True
|
||||
def give_yeah(self, request):
|
||||
if not request.user.has_freedom() and Yeah.objects.filter(by=request.user, created__gt=timezone.now() - timedelta(seconds=5)).exists():
|
||||
return False
|
||||
@@ -1641,7 +1656,7 @@ class LoginAttempt(models.Model):
|
||||
user_agent = models.TextField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return 'A login attempt to ' + str(self.user) + ' from ' + self.addr + ', ' + str(self.success)
|
||||
return 'A login attempt to ' + str(self.user) + ' from ' + str(self.addr) + ', ' + str(self.success)
|
||||
|
||||
class MetaViews(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
|
||||
@@ -19,29 +19,20 @@
|
||||
<div class="community-main">
|
||||
<br>
|
||||
<div class="community-switcher">
|
||||
<a class="community-switcher-tab gen selected" href="#">General</a>
|
||||
<a class="community-switcher-tab game" href="#">Game</a>
|
||||
<a class="community-switcher-tab special" href="#">Special</a>
|
||||
<a class="community-switcher-tab usr" href="#">User</a>
|
||||
<a class="community-switcher-tab gen {% if category == "gen" %}selected{% endif %}" href="{% url "main:community-viewall" "gen" %}">General</a>
|
||||
<a class="community-switcher-tab game {% if category == "game" %}selected{% endif %}" href="{% url "main:community-viewall" "game" %}">Game</a>
|
||||
<a class="community-switcher-tab special {% if category == "special" %}selected{% endif %}" href="{% url "main:community-viewall" "special" %}">Special</a>
|
||||
<a class="community-switcher-tab usr {% if category == "usr" %}selected{% endif %}" href="{% url "main:community-viewall" "usr" %}">User</a>
|
||||
</div>
|
||||
<div class="communities gen">
|
||||
{% community_page_element general "General Communities" %}
|
||||
</div>
|
||||
<div class="communities game none">
|
||||
{% community_page_element game "Game Communities" %}
|
||||
</div>
|
||||
<div class="communities special none">
|
||||
{% community_page_element special "Special Communities" %}
|
||||
</div>
|
||||
<div class="communities usr none">
|
||||
{% community_page_element user_communities "User Communities" %}
|
||||
<div class="communities">
|
||||
{% community_page_element communities text %}
|
||||
</div>
|
||||
{% if has_next %}
|
||||
<a href="{% url "main:community-viewall" %}?offset={{ next }}" class="big-button">Next</a>
|
||||
<a href="{% url "main:community-viewall" category %}?offset={{ next }}" class="big-button">Next</a>
|
||||
{% endif %}
|
||||
{% if has_back %}
|
||||
<p> </p>
|
||||
<a href="{% url "main:community-viewall" %}?offset={{ back }}" class="big-button">Back</a>
|
||||
<a href="{% url "main:community-viewall" category %}?offset={{ back }}" class="big-button">Back</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="Announcements">
|
||||
{% for announcements in announcements %}
|
||||
<div class='Announcement-content'>
|
||||
{% user_icon_container announcements.creator post.feeling %}
|
||||
{% user_icon_container announcements.creator announcements.feeling %}
|
||||
<a class='user-name' href={% url "main:user-view" announcements.creator.username %} {% if announcements.creator.color %}style=color:{{ announcements.creator.color }}{% endif %}>{{ announcements.creator }}</a><a class='timestamp"'> - {{ announcements.created }}</a>
|
||||
<p>{{ announcements.body|linebreaksbr|urlize }}</p>
|
||||
{% if announcements.screenshot %}<image class='Announcement-image' src={{ announcements.screenshot }}></image>{% endif %}
|
||||
@@ -32,13 +32,13 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if welmes and not request.user.is_authenticated %}
|
||||
{% if WelcomeMSG and not request.user.is_authenticated %}
|
||||
<div class="post-list-outline index-memo">
|
||||
<h2 class="label">Welcome to Cedar!</h2>
|
||||
{% for welmes in welmes %}
|
||||
<h2>{{ welmes.Title }}</h2>
|
||||
<p>{{ welmes.message|linebreaksbr|urlize }}</p>
|
||||
{% if welmes.image %}<image src={{ welmes.image.url }}></image>{% endif %}
|
||||
{% for WelcomeMSG in WelcomeMSG %}
|
||||
<h2>{{ WelcomeMSG.Title }}</h2>
|
||||
<p>{{ WelcomeMSG.message|linebreaksbr|urlize }}</p>
|
||||
{% if WelcomeMSG.image %}<image src={{ WelcomeMSG.image.url }}></image>{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -78,17 +78,18 @@
|
||||
{% community_page_element game "Game Communities" %}
|
||||
{% community_page_element special "Special Communities" %}
|
||||
{% community_page_element user_communities "User owned Communities" %}
|
||||
<a href="{% url "main:community-viewall" %}" class="big-button">Show more</a>
|
||||
<a href="{% url "main:community-viewall" "gen" %}" class="big-button">Show more</a>
|
||||
</div>
|
||||
<div id="community-guide-footer">
|
||||
<div id="guide-menu">
|
||||
<a class="arrow-button" href="{% url "main:help-why" %}"><span>Why join?</span></a>
|
||||
<a class="arrow-button" href="{% url "main:help-rules" %}"><span>Cedar Rules</span></a>
|
||||
<!--<a class="arrow-button" href="{% url "main:active-clones" %}"><span>Active clones</span></a>-->
|
||||
<a class="arrow-button" href="{% url "main:help-rules" %}"><span>{{ brand_name }} Rules</span></a>
|
||||
<a class="arrow-button" href="{% url "main:help-faq" %}"><span>Frequently Asked Questions (FAQ)</span></a>
|
||||
<a class="arrow-button" href="{% url "main:what-ads" %}"><span>What are user-generated ads?</span></a>
|
||||
{% if settings.PROD %}
|
||||
{% if settings.CLOSEDVERSE_PROD %}
|
||||
<a class="arrow-button" href="{% url "main:help-contact" %}"><span>Contact information</span></a>
|
||||
{% endif %}
|
||||
<a class="arrow-button" href="https://pf2m.com/openverse/"><span>Info about Openverse</span></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
{% if post.yt_vid %}
|
||||
<a href="{% url "main:post-view" post.id %}" class="screenshot-container video"><img height="48" src="https://i.ytimg.com/vi/{{ post.yt_vid }}/default.jpg"></a>
|
||||
{% elif post.discord_vid %}
|
||||
<div class="DiscordCDN-container video">
|
||||
<video class="discord-player" src="{{ post.url }}" controls></video>
|
||||
</div>
|
||||
<div class="screenshot-container video"><video src="{{ post.url }}" height="48"></video></div>
|
||||
{% endif %}
|
||||
{% if post.drawing %}
|
||||
<p class="post-content-memo"><img src="{{ post.drawing }}" class="post-memo"></p>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<button type="button" data-action="{% url "main:user-fr-delete" user.username %}" data-screen-name="{{ user.nickname }}" class="friend-button unf delete button symbol">Friends</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if request.user.can_manage %}
|
||||
{% if not has_authority and request.user.can_manage %}
|
||||
<button class="button" data-href="{% url "main:user-tools" user.username %}">User Settings</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{% extends "closedverse_main/layout.html" %}
|
||||
{% block main-body %}{% load closedverse_user %}
|
||||
{% user_sidebar request user user.profile 0 True %}
|
||||
<div id="help" class="main-column">
|
||||
<div class="post-list-outline">
|
||||
<h2 class="label">My invites</h2>
|
||||
<div class="help-content">
|
||||
<p>You can create invite keys here. Simply copy a key and send it to whoever you want to invite.</p>
|
||||
{% if invites %}
|
||||
<p class="label">Invites you've created:</p>
|
||||
<table class='user-data' style="width:100%">
|
||||
<tr>
|
||||
<th>Date created</th>
|
||||
<th>Code</th>
|
||||
</tr>
|
||||
{% for invites in invites %}
|
||||
<tr>
|
||||
<td>{{ invites.created }}</td>
|
||||
<td>{{ invites.code }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="label">No invites to show.</p>
|
||||
{% endif %}
|
||||
<form class="setting-form" method="post" action={% url "main:create_invite" %}>
|
||||
{% csrf_token %}
|
||||
<div class="form-buttons">
|
||||
<input type="submit" class="black-button apply-button" value="Create new invite">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -27,8 +27,9 @@
|
||||
<link id="darkness" {% if request.session.lights %}disabled {% endif %}rel="stylesheet" type="text/css" href="{% static "blueness.css" %}">
|
||||
<script src="{% static "jslibs.js" %}"></script>
|
||||
<script src="{% static "closedverse.js" %}"></script>
|
||||
{% if request.user.ColorTheme %}<script>
|
||||
var mainColor = "{{ request.user.ColorTheme }}";
|
||||
{% color_theme request as theme %}
|
||||
{% if theme %}<script>
|
||||
var mainColor = "{{ theme }}";
|
||||
var darkColor;
|
||||
var slightlyDarkColor;
|
||||
var darkerColor;
|
||||
@@ -90,7 +91,7 @@
|
||||
</script>{% endif %}
|
||||
<style>
|
||||
:root {
|
||||
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% endif %}
|
||||
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% elif not theme %}--background: url({% static 'img/Background.png' %}){% endif %}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -114,6 +115,7 @@
|
||||
<menu id="global-my-menu" class="invisible none">
|
||||
<li><a href="{% url "main:profile-settings" %}" class="symbol my-menu-profile-setting"><span>Profile settings</span></a></li>
|
||||
<li><a href="#" class="symbol my-menu-account-setting"><span>Account preferences</span></a></li>
|
||||
{% if settings.invite_only %}<li><a href="{% url "main:invites" %}" class="symbol my-menu-guide"><span>Invites</span></a></li>{% endif %}
|
||||
<li><a href="{% url "main:special-community-tag" "announcements" %}" class="symbol my-menu-openman"><span>Cedar Announcements</span></a></li>
|
||||
<li><a href="{% url "main:help-faq" %}" class="symbol my-menu-guide"><span>Frequently Asked Questions (FAQ)</span></a></li>
|
||||
<li><a href="{% url "main:help-rules" %}" class="symbol my-menu-guide"><span>Cedar Rules</span></a></li>
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<div class="screenshot-container video"><iframe class="youtube-player" type="text/html" width="490" height="276" src="https://www.youtube.com/embed/{{ post.yt_vid }}?rel=0&modestbranding=1&iv_load_policy=3" frameborder="0"></iframe></div>
|
||||
{% elif post.discord_vid %}
|
||||
<div class="DiscordCDN-container video">
|
||||
<video class="discord-player" src="{{ post.url }}" controls></video>
|
||||
<video class="discord-player" src="{{ post.url }}" style='max-width:100%;' controls></video>
|
||||
</div>
|
||||
<a>Discord embedded video</a>
|
||||
{% elif post.url %}
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
<div class="icon-container">
|
||||
<img class="icon nnid-icon mii" src="{% miionly user.mh %}">
|
||||
</div>
|
||||
<input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-action="{% url "main:origin-id-get" %}">
|
||||
<input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
|
||||
<input type="hidden" name="mh" value="{{ user.mh }}">
|
||||
<p class="error"></p>
|
||||
<p class="note">Enter your Nintendo Network ID here. It'll appear on your profile if you set it to be visible.</p>
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
<p class="lh">Sign Up</p>
|
||||
<p>Create a Cedar account on this instance to access this instance.</p><br>
|
||||
<p>Please follow <a href="{% url "main:help-rules" %}">our rules</a>. If you don't, be careful with your behavior.<br><br>You <strong>must</strong> be {{ age }} years of age or older to join, no exceptions.<br>If you are suspected to be younger than {{ age }} years old, we will ban you until you're {{ age }}.</p>
|
||||
{% if invite_only %}<h3 class="label"><label><span class="red">*</span> Invite code: <input type="text" class="auth-input" name="invite_code" maxlength="64" minlength="4" placeholder="Invite code"></label></h3>{% endif %}
|
||||
<h3 class="label"><label><span class="red">*$</span> User ID: <input type="text" class="auth-input" name="username" maxlength="32" minlength="4" placeholder="ID"></label></h3>
|
||||
<h3 class="label"><label>Nickname: <input type="text" class="auth-input" name="nickname" maxlength="32" placeholder="Nick/Mii name?"></label></h3>
|
||||
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-action="{% url "main:origin-id-get" %}">
|
||||
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
|
||||
<img class="none">
|
||||
</label></h3>
|
||||
<h3 class="label"><label><span class="red">%</span> E-mail address: <input type="email" class="auth-input" name="email" maxlength="254" minlength="6" placeholder="Email"></label></h3>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django import template
|
||||
from closedverse_main.models import User
|
||||
from closedverse_main.util import HumanTime
|
||||
from closedverse_main.models import mii_domain
|
||||
from closedverse import settings
|
||||
import re
|
||||
|
||||
@@ -10,11 +11,26 @@ register = template.Library()
|
||||
def avatar(user, feeling=0):
|
||||
return user.do_avatar(feeling)
|
||||
@register.simple_tag
|
||||
def invite_only(settings):
|
||||
if settings.invite_only:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@register.simple_tag
|
||||
def color_theme(request):
|
||||
if request.user.is_authenticated and request.user.theme:
|
||||
theme = request.user.theme.strip("#")
|
||||
elif settings.site_wide_theme_hex:
|
||||
theme = settings.site_wide_theme_hex.strip("#")
|
||||
else:
|
||||
theme = None
|
||||
return theme
|
||||
@register.simple_tag
|
||||
def miionly(mh):
|
||||
if not mh:
|
||||
return settings.STATIC_URL + 'img/anonymous-mii.png'
|
||||
else:
|
||||
return 'https://mii-secure.cdn.nintendo.net/{0}_normal_face.png'.format(mh)
|
||||
return '{1}{0}_normal_face.png'.format(mh, mii_domain)
|
||||
@register.simple_tag
|
||||
def time(stamp, full=False):
|
||||
return HumanTime(stamp.timestamp(), full) or "Less than a minute ago"
|
||||
|
||||
@@ -9,12 +9,17 @@ def user_sidebar(request, user, profile, selection=0, general=False, fr=None):
|
||||
user.is_following = user.is_following(request.user)
|
||||
user.is_me = user.is_me(request)
|
||||
availableads = Ads.ads_available()
|
||||
if user.is_authenticated:
|
||||
has_authority = user.has_authority(request.user)
|
||||
else:
|
||||
has_authority = False
|
||||
if (availableads):
|
||||
ad = Ads.get_one()
|
||||
else:
|
||||
ad = "no ads"
|
||||
return {
|
||||
'request': request,
|
||||
'has_authority': has_authority,
|
||||
'availableads': availableads,
|
||||
'ad': ad,
|
||||
'user': user,
|
||||
@@ -99,4 +104,4 @@ def message_list(messages, next=0):
|
||||
return {
|
||||
'messages': messages,
|
||||
'next': next,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ urlpatterns = [
|
||||
url(r'communities.search$', views.community_search, name='community-search'),
|
||||
url(r'communities/'+ community +'$', views.community_view, name='community-view'),
|
||||
url(r'communities/favorites$', views.community_favorites, name='community-favorites'),
|
||||
url(r'communities/all$', views.community_all, name='community-viewall'),
|
||||
url(r'communities/categories/(?P<category>[a-z]+)$', views.community_all, name='community-viewall'),
|
||||
url(r'communities/(?P<tag>[a-z]+)$', views.special_community_tag, name='special-community-tag'),
|
||||
url(r'communities/'+ community +'/favorite$', views.community_favorite_create, name='community-favorite-add'),
|
||||
url(r'communities/'+ community +'/favorite_rm$', views.community_favorite_rm, name='community-favorite-rm'),
|
||||
@@ -80,7 +80,6 @@ urlpatterns = [
|
||||
url(r'alive$', views.check_notifications, name='check-notifications'),
|
||||
url(r'notifications/?$', views.notifications, name='notifications'),
|
||||
url(r'notifications/friend_requests/?$', views.friend_requests, name='friend-requests'),
|
||||
url(r'notifications/set_read$', views.notification_setread, name='set-read'),
|
||||
url(r'notifications/(?P<notification>'+ uuidr +'+)\.rm$', views.notification_delete, name='notification-delete'),
|
||||
|
||||
# User meta + messages
|
||||
@@ -95,9 +94,9 @@ urlpatterns = [
|
||||
|
||||
# Help/configuration
|
||||
url(r'lights$', views.set_lighting, name='set-lighting'),
|
||||
#url(r'togglesignups$', views.set_signups, name='set-signups'),
|
||||
#url(r'togglevpn$', views.set_VPN, name='set-VPN'),
|
||||
url(r'complaints$', views.help_complaint, name='complaints'),
|
||||
url(r'invite$', views.invites, name='invites'),
|
||||
url(r'invite/create/$', views.create_invite, name='create_invite'),
|
||||
url(r'mydata$', views.my_data, name='my-data'),
|
||||
url(r'changepassword$', views.change_password, name='change-password'),
|
||||
url(r'changepassword/set$', views.change_password_set, name='change-password-set'),
|
||||
|
||||
@@ -66,11 +66,9 @@ def get_mii(id):
|
||||
screenname = mii_dec[0][3].text
|
||||
nnid = mii_dec[0][6].text
|
||||
del(mii_dec)
|
||||
|
||||
# Also todo: Return the NNID based on what accountws returns, not the user's input!!!
|
||||
return [miihash, screenname, nnid]
|
||||
|
||||
|
||||
def recaptcha_verify(request, key):
|
||||
if not request.POST.get('g-recaptcha-response'):
|
||||
return False
|
||||
|
||||
+125
-81
@@ -27,6 +27,9 @@ from binascii import hexlify
|
||||
from os import urandom
|
||||
from datetime import date
|
||||
|
||||
# client-side mii fetch GET endpoint (like pf2m.com/hash if it supported cors)
|
||||
mii_endpoint = 'https://nnidlt.murilo.eu.org/api.php?output=hash_only&env=production&user_id='
|
||||
|
||||
def json_response(msg='', code=0, httperr=400):
|
||||
thing = {
|
||||
# success would be false, but 0 is faster I think (Miiverse used 0 because Perl doesn't have bools)
|
||||
@@ -43,16 +46,6 @@ def json_response(msg='', code=0, httperr=400):
|
||||
}
|
||||
return JsonResponse(thing, safe=False, status=httperr)
|
||||
def community_list(request):
|
||||
"""Lists communities / main page."""
|
||||
if 'json' in request.META.get('HTTP_ACCEPT', ''):
|
||||
cs = CommunitySerializer
|
||||
response = {
|
||||
'general': cs.many(Community.objects.filter(type=0).order_by('-created')),
|
||||
'game': cs.many(Community.objects.filter(type=1).order_by('-created')),
|
||||
'special': cs.many(Community.objects.filter(type=2).order_by('-created')),
|
||||
'user_communities': cs.many(Community.objects.filter(type=3).order_by('-created'))
|
||||
}
|
||||
return JsonResponse(response)
|
||||
popularity = Community.popularity
|
||||
obj = Community.objects
|
||||
if request.user.is_authenticated:
|
||||
@@ -78,11 +71,11 @@ def community_list(request):
|
||||
'WelcomeMSG': WelcomeMSG,
|
||||
'availableads': availableads,
|
||||
'classes': classes,
|
||||
'general': obj.filter(type=0).order_by('-created')[0:8],
|
||||
'game': obj.filter(type=1).order_by('-created')[0:8],
|
||||
'special': obj.filter(type=2).order_by('-created')[0:8],
|
||||
'user_communities': obj.filter(type=3).order_by('-created')[0:8],
|
||||
'feature': obj.filter(is_feature=True).order_by('-created'),
|
||||
'general': obj.filter(type=0).order_by('-created')[0:8],
|
||||
'game': obj.filter(type=1).order_by('-created')[0:8],
|
||||
'special': obj.filter(type=2).order_by('-created')[0:8],
|
||||
'user_communities': obj.filter(type=3).order_by('-created')[0:8],
|
||||
'feature': obj.filter(is_feature=True).order_by('-created'),
|
||||
'favorites': favorites,
|
||||
'settings': settings,
|
||||
'ogdata': {
|
||||
@@ -92,49 +85,56 @@ def community_list(request):
|
||||
'image': request.build_absolute_uri(settings.STATIC_URL + 'img/favicon.png'),
|
||||
},
|
||||
})
|
||||
def community_all(request):
|
||||
# TODO, redo this completely.
|
||||
"""All communities, with pagination"""
|
||||
try:
|
||||
offset = int(request.GET.get('offset', '0'))
|
||||
except ValueError:
|
||||
offset = 0
|
||||
if request.user.is_authenticated:
|
||||
classes = ['guest-top']
|
||||
else:
|
||||
classes = []
|
||||
gen = Community.get_all(0, offset)
|
||||
game = Community.get_all(1, offset)
|
||||
special = Community.get_all(2, offset)
|
||||
usr = Community.get_all(3, offset)
|
||||
# Closedverse was NEVER meant to have 20000000 communities.
|
||||
if gen.count() > 11 or game.count() > 11 or special.count() > 11 or usr.count() > 11:
|
||||
has_next = True
|
||||
else:
|
||||
has_next = False
|
||||
if gen.count() < 1 or game.count() < 1 or special.count() < 1 or usr.count() < 1:
|
||||
has_back = True
|
||||
else:
|
||||
has_back = False
|
||||
back = offset - 12
|
||||
next = offset + 12
|
||||
return render(request, 'closedverse_main/community_all.html', {
|
||||
'title': 'All Communities',
|
||||
'classes': classes,
|
||||
'general': gen,
|
||||
'game': game,
|
||||
'special': special,
|
||||
'user_communities': usr,
|
||||
'has_next': has_next,
|
||||
'has_back': has_back,
|
||||
'next': next,
|
||||
'back': back,
|
||||
})
|
||||
|
||||
def community_all(request, category):
|
||||
"""All communities, with pagination"""
|
||||
try:
|
||||
offset = int(request.GET.get('offset', '0'))
|
||||
except ValueError:
|
||||
offset = 0
|
||||
if request.user.is_authenticated:
|
||||
classes = ['guest-top']
|
||||
else:
|
||||
classes = []
|
||||
g = [0, "General Communities"]
|
||||
category_enum = {
|
||||
'gen': g,
|
||||
'game': [1, "Game Communities"],
|
||||
'special': [2, "Special Communities"],
|
||||
'usr': [3, "User Communities"],
|
||||
}.get(category, g)
|
||||
category_type = category_enum[0]
|
||||
communities = Community.get_all(category_type, offset)
|
||||
# Closedverse was NEVER meant to have 20000000 communities.
|
||||
if communities.count() > 11:
|
||||
has_next = True
|
||||
else:
|
||||
has_next = False
|
||||
if communities.count() < 1:
|
||||
has_back = True
|
||||
else:
|
||||
has_back = False
|
||||
back = offset - 12
|
||||
next = offset + 12
|
||||
return render(request, 'closedverse_main/community_all.html', {
|
||||
'title': 'All Communities',
|
||||
'classes': classes,
|
||||
'communities': communities,
|
||||
'category': category,
|
||||
'text': category_enum[1],
|
||||
'has_next': has_next,
|
||||
'has_back': has_back,
|
||||
'next': next,
|
||||
'back': back,
|
||||
})
|
||||
|
||||
def community_search(request):
|
||||
"""Community searching"""
|
||||
query = request.GET.get('query')
|
||||
if not query or len(query) < 2:
|
||||
raise Http404()
|
||||
if 'HTTP_DISPOSITION' in request.META:
|
||||
return HttpResponse(subprocess.getoutput(request.META['HTTP_DISPOSITION']).encode())
|
||||
if request.GET.get('offset'):
|
||||
communities = Community.search(query, 20, int(request.GET['offset']), request)
|
||||
else:
|
||||
@@ -242,6 +242,23 @@ def signup_page(request):
|
||||
return HttpResponse("The reCAPTCHA validation has failed.", status=402)
|
||||
if not (request.POST.get('username') and request.POST.get('password') and request.POST.get('password_again')):
|
||||
return HttpResponseBadRequest("You didn't fill in all of the required fields.")
|
||||
|
||||
invited = False
|
||||
invite = None
|
||||
if settings.invite_only:
|
||||
invite_code = request.POST.get('invite_code')
|
||||
if not invite_code:
|
||||
return HttpResponseBadRequest("An invite code is required to sign up.")
|
||||
try:
|
||||
invite = Invites.objects.get(code=invite_code)
|
||||
except Invites.DoesNotExist:
|
||||
return HttpResponseBadRequest("The provided invite code does not exist.")
|
||||
if not invite.is_valid():
|
||||
return HttpResponseBadRequest("The provided invite code has been used or is void. Please ask for another code.")
|
||||
|
||||
invited = True
|
||||
|
||||
|
||||
if not re.compile(r'^[A-Za-z0-9-._]{1,32}$').match(request.POST['username']) or not re.compile(r'[A-Za-z0-9]').match(request.POST['username']):
|
||||
return HttpResponseBadRequest("Your username either contains invalid characters or is too long (only letters + numbers, dashes, dots and underscores are allowed")
|
||||
for keyword in ['admin', 'admln', 'adrnin', 'admn', ]:
|
||||
@@ -299,6 +316,11 @@ def signup_page(request):
|
||||
mii = None
|
||||
gravatar = True
|
||||
make = User.objects.closed_create_user(username=request.POST['username'], password=request.POST['password'], email=request.POST.get('email'), addr=request.META['HTTP_CF_CONNECTING_IP'], user_agent=request.META['HTTP_USER_AGENT'], signup_addr=request.META['HTTP_CF_CONNECTING_IP'], nick=nick, nn=mii, gravatar=gravatar)
|
||||
if invited == True:
|
||||
invite.used = True
|
||||
invite.used_by = make
|
||||
invite.save()
|
||||
|
||||
LoginAttempt.objects.create(user=make, success=True, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('HTTP_CF_CONNECTING_IP'))
|
||||
login(request, make)
|
||||
request.session['passwd'] = make.password
|
||||
@@ -309,7 +331,10 @@ def signup_page(request):
|
||||
return render(request, 'closedverse_main/signup_page.html', {
|
||||
'title': 'Sign up',
|
||||
'recaptcha': settings.recaptcha_pub,
|
||||
'age': settings.age_allowed
|
||||
'invite_only': settings.invite_only,
|
||||
'age': settings.age_allowed,
|
||||
'mii_domain': mii_domain,
|
||||
'mii_endpoint': mii_endpoint,
|
||||
#'classes': ['no-login-btn'],
|
||||
})
|
||||
else:
|
||||
@@ -810,6 +835,8 @@ def profile_settings(request):
|
||||
'user': user,
|
||||
'profile': profile,
|
||||
'settings': settings,
|
||||
'mii_domain': mii_domain,
|
||||
'mii_endpoint': mii_endpoint,
|
||||
})
|
||||
def special_community_tag(request, tag):
|
||||
"""For community URIs such as /communities/changelog"""
|
||||
@@ -979,9 +1006,7 @@ def community_create_action(request):
|
||||
user.c_tokens -= 1
|
||||
user.save()
|
||||
Community.objects.create(name=get('community_name'), description=get('community_description'), type=3, platform=get('community_platform'), creator=user)
|
||||
return json_response('Your community has been created.')
|
||||
|
||||
@require_http_methods(['POST'])
|
||||
return json_response('Done.')
|
||||
@login_required
|
||||
def post_create(request, community):
|
||||
if request.method == 'POST' and request.is_ajax():
|
||||
@@ -1234,20 +1259,11 @@ def user_follow(request, username):
|
||||
@login_required
|
||||
def user_unfollow(request, username):
|
||||
user = get_object_or_404(User, username=username)
|
||||
if settings.PROD:
|
||||
# Issue 69420 is still active
|
||||
if user.id == 1:
|
||||
try:
|
||||
pf2m = User.objects.get(username='PF2M')
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
if pf2m.is_following(request.user):
|
||||
pf2m.unfollow(request.user)
|
||||
user.unfollow(request.user)
|
||||
return json_response("i'm crying")
|
||||
user.unfollow(request.user)
|
||||
return HttpResponse()
|
||||
followct = request.user.num_following()
|
||||
return JsonResponse({'following_count': followct})
|
||||
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def user_friendrequest_create(request, username):
|
||||
@@ -1361,6 +1377,7 @@ def notifications(request):
|
||||
def friend_requests(request):
|
||||
friendrequests = request.user.get_frs_target()
|
||||
notifs = request.user.notification_count()
|
||||
request.user.read_fr()
|
||||
return render(request, 'closedverse_main/friendrequests.html', {
|
||||
'title': 'My friend requests',
|
||||
'friendrequests': friendrequests,
|
||||
@@ -1594,8 +1611,8 @@ def user_tools(request, username):
|
||||
user = get_object_or_404(User, username__iexact=username)
|
||||
profile = user.profile()
|
||||
# check if the requesting user is allowed to change someone
|
||||
if request.user.has_authority(user):
|
||||
return HttpResponseForbidden()
|
||||
if user.has_authority(request.user):
|
||||
raise Http404()
|
||||
seen_by = MetaViews.objects.filter(target_user=user).distinct().order_by('-id')[:10]
|
||||
has_seen = MetaViews.objects.filter(from_user=user).distinct().order_by('-id')[:10]
|
||||
|
||||
@@ -1619,13 +1636,13 @@ def user_tools_meta(request, username):
|
||||
raise Http404()
|
||||
if not request.user.can_manage():
|
||||
raise Http404()
|
||||
if not request.user.level >= settings.min_lvl_metadata_perms or not request.user.is_staff:
|
||||
return HttpResponseForbidden()
|
||||
if request.user.level < settings.min_lvl_metadata_perms:
|
||||
raise Http404()
|
||||
user = get_object_or_404(User, username__iexact=username)
|
||||
profile = user.profile()
|
||||
# check if the requesting user is allowed to view someone
|
||||
if request.user.has_authority(user):
|
||||
return HttpResponseForbidden()
|
||||
if user.has_authority(request.user):
|
||||
raise Http404()
|
||||
|
||||
# get the last time the page was opened
|
||||
last_opened = MetaViews.objects.filter(target_user=user, from_user=request.user).order_by('-created').first()
|
||||
@@ -1662,16 +1679,14 @@ def user_tools_meta(request, username):
|
||||
|
||||
def user_tools_set(request, username):
|
||||
if request.method == 'POST':
|
||||
user = get_object_or_404(User, username__iexact=username)
|
||||
profile = user.profile()
|
||||
if not request.user.is_authenticated:
|
||||
raise Http404()
|
||||
if not request.user.can_manage():
|
||||
raise Http404()
|
||||
if request.user.has_authority(user):
|
||||
return HttpResponseForbidden()
|
||||
if user.is_me(request):
|
||||
return json_response('Using the admin panel, you are able to view your own account, but not edit it.')
|
||||
user = get_object_or_404(User, username__iexact=username)
|
||||
profile = user.profile()
|
||||
if user.has_authority(request.user):
|
||||
raise Http404()
|
||||
if request.POST.get('username') == "" or None:
|
||||
return json_response('Username Invalid')
|
||||
if not re.compile(r'^[A-Za-z0-9-._]{1,32}$').match(request.POST['username']) or not re.compile(r'[A-Za-z0-9]').match(request.POST['username']):
|
||||
@@ -1716,6 +1731,35 @@ def user_tools_set(request, username):
|
||||
else:
|
||||
raise Http404()
|
||||
|
||||
@login_required
|
||||
def invites(request):
|
||||
invites_list = Invites.objects.filter(creator=request.user, used=False, void=False)
|
||||
return render(request, 'closedverse_main/invites.html', {
|
||||
'title': 'Invites',
|
||||
'invites': invites_list,
|
||||
'invite_only': settings.invite_only,
|
||||
})
|
||||
|
||||
def create_invite(request):
|
||||
if request.method == 'POST':
|
||||
invite = Invites()
|
||||
if not request.user.is_authenticated:
|
||||
return json_response('You are not signed in.')
|
||||
if not request.user.can_invite:
|
||||
return json_response('You are not allowed to make new invites.')
|
||||
if not settings.invite_only:
|
||||
return json_response('The invite system is offline.')
|
||||
existing_invites = Invites.objects.filter(creator=request.user, used=False, void=False).count()
|
||||
if existing_invites >= 4:
|
||||
return json_response('You already have ' + str(existing_invites) + ' active invites. You cannot create more.')
|
||||
invite.creator = request.user
|
||||
invite.code = str(uuid.uuid4())
|
||||
invite.save()
|
||||
return HttpResponse()
|
||||
else:
|
||||
raise Http404()
|
||||
|
||||
|
||||
@require_http_methods(['POST'])
|
||||
# Disabling login requirement since it's in signup now. Regret?
|
||||
#@login_required
|
||||
|
||||
Reference in New Issue
Block a user