from collections import defaultdict
from django.utils import translation
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import user_passes_test, login_required
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.cache import cache_page
from django.shortcuts import redirect, render
from django.conf import settings
from django.contrib.auth import logout
from django.utils.translation import gettext as _
from knox.views import LoginView as KnoxLoginView
from rest_framework.authentication import BasicAuthentication
from taggit.models import Tag
from .forms import JoinForm
from . import models
from .tools import get_user_from_token, send_template_mail
from .api import serializers
[docs]
class LoginView(KnoxLoginView):
authentication_classes = [BasicAuthentication]
[docs]
def set_language(request, language_code):
if request.user.is_authenticated:
user = request.user
user.language = language_code
user.save()
return redirect('/' + language_code.lower())
[docs]
def user_status(request):
if request.user.is_anonymous:
return HttpResponse(status=401)
return HttpResponse('OK')
[docs]
def logout_user(request):
logout(request)
return HttpResponse('OK')
[docs]
def logmein(request):
username = request.GET.get('username')
password = request.GET.get('pwd')
token = request.GET.get('token')
user = None
if password:
user = authenticate(username=username, password=password)
elif token:
user = get_user_from_token(token)
if user is not None:
if user.is_active:
login(request, user)
user_serializer = serializers.UserSerializer(models.User.objects.get(id=request.user.id))
return JsonResponse(user_serializer.data)
else:
return HttpResponse('inactive')
else:
return HttpResponse('bad')
[docs]
def app(request):
site_config = models.SiteConfiguration.get_solo()
return render(request, 'app/app.html', {
'godot_filesize_combined': settings.GODOT_FILESIZE_COMBINED,
'SENTRY_JS_URL': settings.SENTRY_JS_URL,
'TOS_URL': site_config.tos_url,
'PRIVACY_URL': site_config.privacy_url
})
[docs]
def webmanifest(request):
return render(request, 'memopolis/manifest.webmanifest', {})
[docs]
@xframe_options_exempt
@login_required
def content(request):
if request.method == "POST":
images = request.FILES.getlist('images')
for image in images:
models.Content.objects.create(image=image, user=request.user, team=request.user.active_team)
return redirect('/editor/content/')
mine = models.Content.objects.filter(user=request.user).exclude(special__icontains="buildin:")
if request.user.active_team:
team = models.Content.objects.filter(team=models.Team.objects.get(id=request.user.active_team.id))
team_content = team.difference(mine)
else:
team_content = None
buildin_qs = models.Content.objects.filter(special__icontains="buildin:")
buildin = {}
for tag in Tag.objects.all():
buildin[tag] = buildin_qs.filter(tags__name__in=[tag])
context = {
"groups": [
{
"id": "user",
'title': _("Your Content"),
'tags': {"-": mine},
'delete_button': True
},
{
"id": "team",
'title': _("Your Team's Content"),
'tags': {"-": team_content }
},
{
"id": "buildin",
'title': _("Stock Content"),
'tags': buildin
},
]
}
return render(request, 'memopolis/content.html', context)
[docs]
@login_required
def content_upload(request):
if request.method == "POST":
images = request.FILES.getlist('images')
for image in images:
models.Content.objects.create(image=image, user=request.user, team=models.Team.objects.get(id=1))
return redirect('/editor/content/')
return render(request, 'memopolis/content_upload.html', )
def _invite_logic(request, admin=False):
team = models.Team.objects.get(id=request.POST.get('team'))
data = request.POST.getlist('emails[]')
for email in data:
created = False
if email.isdigit():
user = models.User.objects.get(id=email)
email = user.email
else:
user, created = models.User.objects.get_or_create(organization=team.organization, email=email)
if admin:
team.admins.add(user)
else:
team.users.add(user)
if created:
url = "%s?join=%s" % (settings.URL, user.invite_token)
else:
url = settings.URL
user.username = email
user.language = team.organization.language
user.active_team = team
user.save()
with translation.override(team.organization.language):
send_template_mail("invite", email, {
"team_admin_name":request.user.username,
"team": "New Team",
"organization": team.organization.name,
"url": url,
})
return HttpResponse(data)
[docs]
@login_required
def invite(request):
return _invite_logic(request)
[docs]
@login_required
def invite_admins(request):
return _invite_logic(request, True)
[docs]
@login_required
def remove_user(request):
team = models.Team.objects.get(id=request.POST.get('team'))
user = models.User.objects.get(id=request.POST.get('user'))
team.users.remove(user)
team.admins.remove(user)
return HttpResponse({})
[docs]
def join(request, uuid):
try:
user = models.User.objects.get(invite_token=uuid)
except :
user = None
reload = False
if request.method == 'POST':
form = JoinForm(request.POST)
if form.is_valid():
# process the data in form.cleaned_data as required
user.first_name = form.cleaned_data.get("first_name")
user.last_name = form.cleaned_data.get("last_name")
user.set_password(form.cleaned_data.get("password"))
user.username = form.cleaned_data.get("username")
user.invite_token = None
user.save()
reload = True
else:
form = JoinForm()
return render(request, 'memopolis/join.html', {
'new_user': user,
'form': form,
'reload': reload
})
[docs]
def dialog(request):
return render(request, 'memopolis/dialog_editor.html', {})
[docs]
def user_is_team_admin(user):
return len(user.admin_teams.all()) or user.is_superuser
[docs]
@user_passes_test(user_is_team_admin, login_url="/missing_permissions")
def admin_team(request):
return HttpResponse("team admin todo")
[docs]
def user_is_orga_admin(user):
return len(user.admin_organizations.all()) or user.is_superuser
[docs]
@user_passes_test(user_is_orga_admin, login_url="/missing_permissions")
def admin_organization(request):
return render(request, 'memopolis/orga-admin.html', {})
[docs]
def missing_permissions(request):
return HttpResponse("you don't have permission to view this.<br>please contact your organization admin if this is a mistake.")
[docs]
def switch_team(request):
team_id = request.POST.get('team')
team = models.Team.objects.get(id=team_id)
print("switching user %s to team %s" % (request.user, team))
request.user.active_team = team
request.user.save()
return HttpResponse("OK")
[docs]
def content_remove(request):
content_id = request.POST.get('content')
content = models.Content.objects.get(id=content_id)
if content.user == request.user:
models.Content.objects.get(id=content_id).delete()
return HttpResponse("OK")
return HttpResponse(status=500)
[docs]
def delete_map(request):
map_id = request.POST.get('map')
map = models.Map.objects.get(id=map_id)
if map.mark_for_deletion and (
request.user.is_superuser or\
request.user in map.quest.team.admins.all() or\
request.user in map.quest.team.organization.admins.all()
):
map.delete()
else:
map.mark_for_deletion = True
map.save()
return HttpResponse("OK")
[docs]
def hint(request):
hint_id = request.POST.get('id')
print("ADD HINT ID %s" % hint_id)
if "hidden_hints" not in request.user.json:
request.user.json["hidden_hints"] = []
if hint_id not in request.user.json["hidden_hints"]:
request.user.json["hidden_hints"].append(hint_id)
request.user.save()
return HttpResponse("OK")
[docs]
def restore_map(request):
map_id = request.POST.get('map')
map = models.Map.objects.get(id=map_id)
map.mark_for_deletion = False
map.save()
return HttpResponse("OK")
#@cache_page(60 * 1)
[docs]
def select2_objects(request):
qs = models.WorldObject.objects.filter(map__isnull=False).select_related('map')
type = request.GET.get('type')
if type:
qs = qs.filter(json__type=type)
groups = defaultdict(list)
for obj in qs:
groups["Map %d: %s" % (obj.map.id, obj.map.name)].append({
"id": "%d/%s" % (obj.map.id, obj.uuid),
"text": "%s" % obj.json["object_name"]
})
data = []
for name, children in groups.items():
data.append({
"text": name,
"children": children
})
return JsonResponse(data, safe=False)
#@cache_page(60 * 1)
[docs]
def select2_variables(request):
map = request.GET.get('map')
data = []
quest = models.Map.objects.get(id=map).quest
for variable in quest.json["variables"]:
data.append({
"text": variable["name"],
"id": variable["name"],
})
return JsonResponse(data, safe=False)