minecraft_manager/views.py

484 lines
21 KiB
Python
Raw Normal View History

2018-09-20 02:56:17 +00:00
from __future__ import absolute_import
import json, datetime, pytz, os
2018-09-20 02:56:17 +00:00
from django.utils import timezone
from itertools import chain
from django.http import JsonResponse, HttpResponse
2018-09-20 02:56:17 +00:00
from django.shortcuts import render, reverse, redirect
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from django.conf import settings
from django.views.generic import View
from django.contrib.auth.models import User
from minecraft_manager.models import Application as AppModel, Player as PlayerModel, Ticket as TicketModel, TicketNote as TicketNoteModel, Note as NoteModel, IP as IPModel, Alert as AlertModel, UserSettings as UserSettingsModel, Attachment as AttachmentModel, RefModels
from minecraft_manager.forms import TicketNoteForm, NoteForm
from minecraft_manager.overview import overview_data
from minecraft_manager.utils import resolve_player
2018-09-20 02:56:17 +00:00
import minecraft_manager.api.api as API
class Overview(View):
def get(self, request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
user_ip = x_forwarded_for.split(',')[0]
else:
user_ip = request.META.get('REMOTE_ADDR')
try:
request.user.usersettings.last_ip = user_ip
except:
request.user.usersettings = UserSettingsModel(auth_user=request.user)
request.user.usersettings.last_ip = user_ip
request.user.usersettings.save()
return render(request, 'minecraft_manager/overview.html', {'current_app': 'overview', 'data': overview_data()})
2018-09-20 02:56:17 +00:00
2018-09-20 02:56:17 +00:00
class CoreProtect(View):
def get(self, request):
#http://www.24carrotcraft.com/assets/cp/index.php?username=etzelia
return render(request, 'minecraft_manager/coreprotect.html', {'current_app': 'coreprotect'})
2018-09-20 02:56:17 +00:00
class Activity(View):
def get(self, request):
#http://www.24carrotcraft.com/assets/cp/activity.php?username=etzelia
return render(request, 'minecraft_manager/activity.html', {'current_app': 'activity'})
2018-09-20 02:56:17 +00:00
class Ban(View):
def get(self, request):
ban_file = os.path.join(settings.MINECRAFT_BASE_DIR, 'banned-players.json')
with open(ban_file, encoding='utf-8') as f:
bans = json.load(f)
for idx, ban in enumerate(bans):
ban['source'] = API.strip_format(ban['source'])
if PlayerModel.objects.filter(uuid=ban['uuid']).exists():
ban['id'] = PlayerModel.objects.get(uuid=ban['uuid']).id
else:
ban['id'] = 0
ban['source'] = API.strip_format(ban['source'])
if ban['expires'] == "forever":
ban['expires'] = "Permanent"
else:
dt = datetime.datetime.strptime(ban['expires'], "%Y-%m-%d %H:%M:%S %z")
dt = dt.astimezone(pytz.timezone(request.user.usersettings.default_timezone))
ban['expires'] = dt.strftime("%m/%d/%y %I:%M %p")
dt = datetime.datetime.strptime(ban['created'], "%Y-%m-%d %H:%M:%S %z")
dt = dt.astimezone(pytz.timezone(request.user.usersettings.default_timezone))
ban['created'] = dt.strftime("%m/%d/%y %I:%M %p")
bans[idx] = ban
bans = sorted(bans, key=lambda ban: ban['created'], reverse=True)
return render(request, 'minecraft_manager/ban.html', {'current_app': 'ban', 'bans': bans})
class Alert(View):
def get(self, request):
alerts = AlertModel.objects.filter(user=request.user).order_by('seen', '-id')
unseen_alerts = AlertModel.objects.filter(user=request.user, seen=False)
return render(request, 'minecraft_manager/alert.html',
{'current_app': 'alert', 'alerts': alerts, 'unseen': len(unseen_alerts)})
def post(self, request):
post = request.POST
if 'action' in post:
if post['action'] == 'mar':
AlertModel.objects.filter(user=request.user).update(seen=True)
alerts = AlertModel.objects.filter(user=request.user).order_by('seen', '-id')
return render(request, 'minecraft_manager/alert.html',
{'current_app': 'alert', 'alerts': alerts, 'unseen': 0})
class AlertInfo(View):
def get(self, request, alert_id):
alert = AlertModel.objects.get(id=alert_id)
alert.seen = True
alert.save()
return render(request, 'minecraft_manager/alert_info.html',
{'current_app': 'alert', 'alert': alert})
def post(self, request, alert_id):
post = request.POST
alert = AlertModel.objects.get(id=alert_id)
if 'action' in post:
if post['action'] == 'mu':
alert.seen = False
alert.save()
return render(request, 'minecraft_manager/alert_info.html',
{'current_app': 'alert', 'alert': alert})
class Application(View):
def get(self, request):
get = request.GET
if 'accepted' in get:
if get['accepted'].lower() == 'true':
applications = AppModel.objects.filter(accepted=True)
elif get['accepted'].lower() == 'false':
applications = AppModel.objects.filter(accepted=False)
else:
applications = AppModel.objects.filter(accepted__isnull=True)
else:
applications1 = AppModel.objects.filter(accepted__isnull=True)
applications2 = AppModel.objects.filter(accepted__isnull=False)
applications = list(chain(applications1, applications2))
return render(request, 'minecraft_manager/application.html', {'current_app': 'application', 'applications': applications})
class Reference(View):
def get(self, request):
get = request.GET
applications = AppModel.objects.all()
return render(request, 'minecraft_manager/reference.html', {'current_app': 'application', 'applications': applications})
class ApplicationInfo(View):
@method_decorator(csrf_protect)
def get(self, request, application_id):
application = AppModel.objects.get(id=application_id)
return render(request, 'minecraft_manager/application_info.html', {'current_app': 'application', 'application': application})
def post(self, request, application_id):
post = request.POST
application = AppModel.objects.get(id=application_id)
if post['accept']:
if post['accept'] == 'accept':
application.accepted = True
if post['accept'] == 'deny':
application.accepted = False
application.save()
API.plugin(post['accept'], application.username)
API.discord_mcm("Application #**{0}** was **{1}** by **{2}**".format(application.id, "Accepted" if application.accepted else "Denied", request.user.player.username))
return render(request, 'minecraft_manager/application_info.html',
{'current_app': 'application', 'application': application})
class Player(View):
def get(self, request):
get = request.GET
if 'search' in get:
search = get['search']
player = resolve_player(search)
if player:
return redirect('{}{}/'.format(reverse('player'), player.id))
else:
players = PlayerModel.objects.filter(username__icontains=search)
else:
players = PlayerModel.objects.all()
2018-09-20 02:56:17 +00:00
ban_file = os.path.join(settings.MINECRAFT_BASE_DIR, 'banned-players.json')
with open(ban_file, encoding='utf-8') as f:
ban_list = json.load(f)
bans = []
for ban in ban_list:
bans.append(ban['uuid'])
return render(request, 'minecraft_manager/player.html', {'current_app': 'player', 'players': players, 'bans': bans})
class PlayerInfo(View):
def get(self, request, player_id):
player = PlayerModel.objects.get(id=player_id)
ips = IPModel.api.filter(player=player)
2018-09-20 02:56:17 +00:00
tickets = TicketModel.objects.filter(player=player)
notes = NoteModel.objects.filter(player=player)
form = {'ips': ips, 'tickets': tickets, 'notes': notes}
return render(request, 'minecraft_manager/player_info.html',
{'current_app': 'player', 'player': player, 'form': form})
2018-09-20 02:56:17 +00:00
def post(self, request, player_id):
player = PlayerModel.objects.get(id=player_id)
ips = IPModel.api.filter(player=player)
tickets = TicketModel.objects.filter(player=player)
notes = NoteModel.objects.filter(player=player)
form = {'ips': ips, 'tickets': tickets, 'notes': notes}
return render(request, 'minecraft_manager/player_info.html',
{'current_app': 'player', 'player': player, 'form': form})
2018-09-20 02:56:17 +00:00
class Ticket(View):
def get(self, request):
get = request.GET
tickets1 = TicketModel.objects.filter(resolved=False).order_by('-id')
tickets2 = TicketModel.objects.filter(resolved=True).order_by('-id')
tickets = list(chain(tickets1, tickets2))
2018-09-20 02:56:17 +00:00
return render(request, 'minecraft_manager/ticket.html', {'current_app': 'ticket', 'tickets': tickets})
class TicketInfo(View):
@method_decorator(csrf_protect)
def get(self, request, ticket_id):
ticket = TicketModel.objects.get(id=ticket_id)
active_staff = User.objects.filter(is_active=True)
inactive_staff = User.objects.filter(is_active=False)
ticket_notes = TicketNoteModel.objects.filter(ticket=ticket)
ticket_note_form = TicketNoteForm(instance=request.user)
has_ticket_note = False
for ticket_note in ticket_notes:
if ticket_note.author == request.user:
ticket_note_form = TicketNoteForm(instance=ticket_note)
has_ticket_note = True
if not has_ticket_note:
ticket_note_form.fields['ticket'].initial = ticket_id
2018-09-20 02:56:17 +00:00
form = {'active_staff': active_staff, 'inactive_staff': inactive_staff, 'priority': TicketModel.PRIORITY,
'resolved': ticket.resolved, 'ticket_note_form': ticket_note_form.as_p(), 'ticket_notes': ticket_notes, 'has_ticket_note': has_ticket_note,
'show_ticket_note': False}
2018-09-20 02:56:17 +00:00
return render(request, 'minecraft_manager/ticket_info.html', {'current_app': 'ticket', 'ticket': ticket, 'form': form})
def post(self, request, ticket_id):
post = request.POST
ticket = TicketModel.objects.get(id=ticket_id)
if 'priority' in post:
if post['priority'] != ticket.priority:
API.discord_mcm(
"Ticket #**{0}**'s priority was changed from **{1}** to **{2}** by **{3}**".format(ticket.id,
ticket.priority_display,
TicketModel.priority_code_to_display(
post['priority']),
request.user.username))
ticket.priority = post['priority']
if 'staff' in post and 'resolved' not in post:
2018-10-11 02:42:55 +00:00
if not ticket.staff or request.user.is_staff:
2018-09-20 02:56:17 +00:00
staff = User.objects.get(id=post['staff'])
if post['staff'] != str(getattr(ticket.staff, 'id', '-1')):
if post['staff'] == str(request.user.id):
API.discord_mcm(
"Ticket #**{0}** was claimed by **{1}**".format(ticket.id, request.user.username))
else:
API.discord_mcm(
"Ticket #**{0}** was given to **{1}** by **{2}**".format(ticket.id, staff.username, request.user.username))
2018-10-11 02:42:55 +00:00
ticket.staff = staff
2018-09-20 02:56:17 +00:00
if 'resolved' in post:
API.discord_mcm("Ticket #**{0}** was resolved by **{1}**".format(ticket.id, request.user.username))
ticket.resolved = True
ticket.save()
show_ticket_note = False
if 'ticket_note' in post:
ticket_note_form = TicketNoteForm(post)
if ticket_note_form.is_valid():
n = ticket_note_form.save(commit=False)
if post['ticket_note'] == 'create':
2018-09-20 02:56:17 +00:00
n.author = request.user
n.save()
elif post['ticket_note'] == 'edit':
db = TicketNoteModel.objects.get(ticket=ticket, author=request.user)
2018-09-20 02:56:17 +00:00
db.message = n.message
db.last_update = timezone.now()
db.save()
# Refresh to get the ID for attachments
note = TicketNoteModel.objects.get(ticket=ticket, author=request.user)
for file in request.FILES.getlist('attachments', []):
attachment = AttachmentModel(ref_model=RefModels.TICKET_NOTE[0], ref_id=note.id, file=file)
attachment.save()
2018-09-20 02:56:17 +00:00
else:
show_ticket_note = True
2018-09-20 02:56:17 +00:00
else:
ticket_note_form = TicketNoteForm(instance=request.user)
ticket_notes = TicketNoteModel.objects.filter(ticket=ticket)
has_ticket_note = False
for ticket_note in ticket_notes:
if ticket_note.author == request.user:
ticket_note_form = TicketNoteForm(instance=ticket_note)
has_ticket_note = True
if not has_ticket_note:
ticket_note_form.fields['ticket'].initial = ticket_id
2018-09-20 02:56:17 +00:00
active_staff = User.objects.filter(is_active=True)
inactive_staff = User.objects.filter(is_active=False)
form = {'active_staff': active_staff, 'inactive_staff': inactive_staff, 'priority': TicketModel.PRIORITY,
'resolved': ticket.resolved, 'ticket_note_form': ticket_note_form.as_p(), 'ticket_notes': ticket_notes, 'has_ticket_note': has_ticket_note,
'show_ticket_note': show_ticket_note}
2018-09-20 02:56:17 +00:00
return render(request, 'minecraft_manager/ticket_info.html',
{'current_app': 'ticket', 'ticket': ticket, 'form': form})
class Note(View):
2018-09-20 02:56:17 +00:00
def get(self, request):
notes = NoteModel.objects.order_by('-id')
return render(request, 'minecraft_manager/note.html', {'current_app': 'note', 'notes': notes})
2018-09-20 02:56:17 +00:00
class NoteInfo(View):
2018-09-20 02:56:17 +00:00
@method_decorator(csrf_protect)
def get(self, request, note_id):
note = NoteModel.objects.get(id=note_id)
form = {'importance': NoteModel.IMPORTANCE}
return render(request, 'minecraft_manager/note_info.html', {
'current_app': 'note',
'form': form,
'note': note
})
2018-09-20 02:56:17 +00:00
def post(self, request, note_id):
2018-09-20 02:56:17 +00:00
post = request.POST
note = NoteModel.objects.get(id=note_id)
if 'importance' in post:
API.discord_mcm("Note #**{0}**'s importance was changed from {1} to {2} by {3}".format(
note.id,
note.importance_display,
NoteModel.importance_code_to_display(post['importance']),
request.user.player.username)
)
note.importance = post['importance']
note.save()
form = {'importance': NoteModel.IMPORTANCE}
return render(request, 'minecraft_manager/note_info.html', context={
'current_app': 'note',
'form': form,
'note': note
})
2018-09-20 02:56:17 +00:00
class NoteAdd(View):
2018-09-20 02:56:17 +00:00
@method_decorator(csrf_protect)
def get(self, request):
get = request.GET
form = NoteForm()
if 'player' in get:
form.initial = {'player': get['player']}
return render(request, 'minecraft_manager/note_add.html', context={'current_app': 'note', 'form': form.as_p()})
2018-09-20 02:56:17 +00:00
def post(self, request):
post = request.POST
form = NoteForm(post)
2018-09-20 02:56:17 +00:00
if form.is_valid():
note = form.save()
note.staff = request.user
note.save()
2018-09-20 02:56:17 +00:00
API.discord_mcm(
"**{0}** made a **{1}** importance note for **{2}**\nPreview: {3}".format(
note.staff.player.username,
note.importance_display,
note.player.username,
note.snippet)
)
for file in request.FILES.getlist('attachments', []):
attachment = AttachmentModel(ref_model=RefModels.NOTE[0], ref_id=note.id, file=file)
attachment.save()
return redirect("{0}{1}".format(reverse('note'), note.id))
2018-09-20 02:56:17 +00:00
else:
return render(request, 'minecraft_manager/note_add.html', context={'current_app': 'note', 'form': form})
class Attachment(View):
def get(self, request, attachment_id):
attachment = AttachmentModel.objects.get(id=attachment_id)
resp = HttpResponse(attachment.file)
resp['Content-Disposition'] = f"attachment; filename={attachment.file_name}"
return resp
def delete(self, request, attachment_id):
attachment = AttachmentModel.objects.get(id=attachment_id)
attachment.delete()
return HttpResponse(status=204)
class AddAttachment(View):
def post(self, request, ref_model, ref_id):
for file in request.FILES.getlist('attachments', []):
attachment = AttachmentModel(ref_model=ref_model, ref_id=ref_id, file=file)
attachment.save()
return redirect(request.POST.get('next', reverse('overview')))
2018-09-20 02:56:17 +00:00
class IP(View):
def get(self, request, ip_id):
ip = IPModel.api.get(id=ip_id)
ips = IPModel.api.filter(ip=ip.ip)
return render(request, 'minecraft_manager/ip.html', {'ip': ip, 'ips': ips})
def post(self, request, ip_id):
pass
2018-09-20 02:56:17 +00:00
class Report(View):
def get(self, request):
get = request.GET
results = []
timestamp = None
report = get.get('report')
world = get.get('world')
if report and world:
# Get some results
report_dir = os.path.join(settings.MINECRAFT_BASE_DIR, 'plugins', 'MinecraftManager', 'report.json')
if os.path.exists(report_dir):
with open(report_dir) as rpt:
raw = json.load(rpt)
time = raw.get('time')
timestamp = datetime.datetime.utcfromtimestamp(float(time))
timestamp = pytz.timezone('UTC').localize(timestamp)
timestamp = timestamp.astimezone(pytz.timezone(request.user.usersettings.default_timezone))
for w in raw:
if w.endswith('_nether') and world == 'nether':
world_raw = raw[w]
elif w.endswith('_the_end') and world == 'end':
world_raw = raw[w]
elif w != 'time' and not (w.endswith('_nether') or w.endswith('_the_end')) and world == 'overworld': # Need to think of a way to clean this up...
world_raw = raw[w]
break
results_raw = world_raw.get(report)
for result in results_raw:
if report == 'players':
results.append({'name': result.get('name'), 'x': result.get('x'), 'y': result.get('y'),
'z': result.get('z')})
else:
type_formatted = ' '.join([part.title() for part in result.split('_')])
if report == 'entities':
for location in results_raw[result]:
results.append({'name': type_formatted, 'x': location.get('x'), 'y': location.get('y'),
'z': location.get('z')})
else:
results.append({'name': type_formatted, 'count': results_raw.get(result)})
else:
results = 'NONE'
elif report or world:
results = 'BOTH'
if len(results) == 0:
results = 'EMPTY'
return render(request, 'minecraft_manager/report.html', {'current_app': 'report', 'report': report, 'world': world, 'timestamp': timestamp, 'results': results})
def post(self, request):
pass
class Chat(View):
@staticmethod
def replace_ascii(message):
return message.replace(" ", "\\040").replace("\"", "\\042").replace("#", "\\043").replace("$", "\\044")\
.replace("%", "\\045").replace("&", "\\046").replace("(", "\\050").replace(")", "\\051").replace("*", "\\052")\
.replace("+", "\\053").replace("-", "\\055")
def get(self, request):
staff = hasattr(settings, 'STAFF_LOG')
return render(request, 'minecraft_manager/chat.html', {'current_app': 'chat', 'staff': staff})
def post(self, request):
post = request.POST
if 'chat' in post and 'message' in post:
API.plugin(post['chat'], "{0} {1}".format(request.user.player.username, post['message']))
data = {'success': True, 'message': 'Message sent successfully.'}
else:
data = {'success': False, 'message': 'No chat type or message set.'}
return JsonResponse(data)