2018-09-20 02:56:17 +00:00
#create your views here.
# https://api.mojang.com/users/profiles/minecraft/<username>
from __future__ import absolute_import
import json , datetime , pytz , os , sys
from django . utils import timezone
from itertools import chain
from django . http import JsonResponse
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 , Warning as WarningModel , IP as IPModel , Alert as AlertModel , Note as NoteModel , UserSettings as UserSettingsModel
from minecraft_manager . forms import WarningForm , NoteForm
import minecraft_manager . api . api as API
import subprocess
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 ( )
unanswered_apps = AppModel . unanswered . count ( )
accepted_apps = AppModel . objects . filter ( accepted = True ) . count ( )
denied_apps = AppModel . objects . filter ( accepted = False ) . count ( )
unclaimed_tickets = TicketModel . unclaimed . count ( )
claimed_tickets = TicketModel . claimed . count ( )
resolved_tickets = TicketModel . objects . filter ( resolved = True ) . count ( )
counts = { ' applications ' : AppModel . objects . count ( ) , ' players ' : PlayerModel . objects . count ( ) ,
" ips " : IPModel . objects . count ( ) , " tickets " : TicketModel . objects . count ( ) ,
" warnings " : WarningModel . objects . count ( ) }
form = { ' apps ' : { ' unanswered ' : unanswered_apps , ' accepted ' : accepted_apps , ' denied ' : denied_apps } ,
' tickets ' : { ' unclaimed ' : unclaimed_tickets , ' claimed ' : claimed_tickets , ' resolved ' : resolved_tickets } ,
' counts ' : counts }
return render ( request , ' minecraft_manager/overview.html ' , { ' current_app ' : ' overview ' , ' form ' : form } )
2018-09-21 05:05:11 +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-21 05:05:11 +00:00
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-21 05:05:11 +00:00
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 ) :
2018-09-21 05:05:11 +00:00
get = request . GET
if ' search ' in get :
search = get [ ' search ' ]
results = PlayerModel . objects . filter ( username__icontains = search )
if len ( results ) == 1 :
return redirect ( ' {} {} / ' . format ( reverse ( ' player ' ) , results [ 0 ] . id ) )
else :
for result in results :
if search . lower ( ) == result . username . lower ( ) :
return redirect ( ' {} {} / ' . format ( reverse ( ' player ' ) , result . id ) )
players = results
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 . objects . filter ( player = player )
tickets = TicketModel . objects . filter ( player = player )
warnings = WarningModel . objects . filter ( player = player )
form = { ' ips ' : ips , ' tickets ' : tickets , ' warnings ' : warnings }
return render ( request , ' minecraft_manager/player_info.html ' , { ' current_app ' : ' player ' , ' player ' : player , ' form ' : form } )
def post ( self , request , player_id ) :
player = PlayerModel . objects . get ( id = player_id )
return render ( request , ' minecraft_manager/player_info.html ' , { ' current_app ' : ' player ' , ' player ' : player } )
class Ticket ( View ) :
def get ( self , request ) :
get = request . GET
if ' claimed ' in get :
if get [ ' claimed ' ] . lower ( ) == ' true ' :
tickets = TicketModel . claimed . all ( )
elif get [ ' claimed ' ] . lower ( ) == ' false ' :
tickets = TicketModel . unclaimed . all ( )
else :
tickets = TicketModel . objects . filter ( resolved = True )
else :
tickets1 = TicketModel . objects . filter ( resolved = False ) . order_by ( ' -id ' )
tickets2 = TicketModel . objects . filter ( resolved = True ) . order_by ( ' -id ' )
tickets = list ( chain ( tickets1 , tickets2 ) )
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 )
notes = NoteModel . objects . filter ( ref_id = ticket_id , ref_table = ' TI ' )
note_form = NoteForm ( instance = request . user )
has_note = False
for note in notes :
if note . author == request . user :
note_form = NoteForm ( instance = note )
has_note = True
if not has_note :
note_form . fields [ ' ref_table ' ] . initial = ' TI '
note_form . fields [ ' ref_id ' ] . initial = ticket_id
form = { ' active_staff ' : active_staff , ' inactive_staff ' : inactive_staff , ' priority ' : TicketModel . PRIORITY ,
' resolved ' : ticket . resolved , ' note_form ' : note_form . as_p ( ) , ' notes ' : notes , ' has_note ' : has_note ,
' show_note ' : False }
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 :
if post [ ' staff ' ] :
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 ) )
else :
staff = None
API . discord_mcm (
" Ticket #** {0} ** was unclaimed by ** {1} ** " . format ( ticket . id , request . user . username ) )
ticket . staff = staff
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_note = False
if ' note ' in post :
note_form = NoteForm ( post )
if note_form . is_valid ( ) :
n = note_form . save ( commit = False )
if post [ ' note ' ] == ' create ' :
n . author = request . user
n . save ( )
elif post [ ' note ' ] == ' edit ' :
db = NoteModel . objects . get ( ref_id = ticket_id , ref_table = ' TI ' , author = request . user )
db . message = n . message
db . last_update = timezone . now ( )
db . save ( )
else :
show_note = True
else :
note_form = NoteForm ( instance = request . user )
notes = NoteModel . objects . filter ( ref_id = ticket_id , ref_table = ' TI ' )
has_note = False
for note in notes :
if note . author == request . user :
note_form = NoteForm ( instance = note )
has_note = True
if not has_note :
note_form . fields [ ' ref_table ' ] . initial = ' TI '
note_form . fields [ ' ref_id ' ] . initial = ticket_id
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 , ' note_form ' : note_form . as_p ( ) , ' notes ' : notes , ' has_note ' : has_note ,
' show_note ' : show_note }
return render ( request , ' minecraft_manager/ticket_info.html ' ,
{ ' current_app ' : ' ticket ' , ' ticket ' : ticket , ' form ' : form } )
class Warning ( View ) :
def get ( self , request ) :
warnings = WarningModel . objects . order_by ( ' -id ' )
return render ( request , ' minecraft_manager/warning.html ' , { ' current_app ' : ' warning ' , ' warnings ' : warnings } )
class WarningInfo ( View ) :
@method_decorator ( csrf_protect )
def get ( self , request , warning_id ) :
warning = WarningModel . objects . get ( id = warning_id )
form = { ' severity ' : WarningModel . SEVERITY }
return render ( request , ' minecraft_manager/warning_info.html ' , { ' current_app ' : ' warning ' , ' form ' : form , ' warning ' : warning } )
def post ( self , request , warning_id ) :
post = request . POST
warning = WarningModel . objects . get ( id = warning_id )
if ' severity ' in post :
API . discord_mcm ( " Warning #** {0} ** ' s severity was changed from {1} to {2} by {3} " . format ( warning . id ,
warning . severity_display ,
WarningModel . severity_code_to_display (
post [
' severity ' ] ) ,
request . user . player . username ) )
warning . severity = post [ ' severity ' ]
warning . save ( )
form = { ' severity ' : WarningModel . SEVERITY }
return render ( request , ' minecraft_manager/warning_info.html ' ,
{ ' current_app ' : ' warning ' , ' form ' : form , ' warning ' : warning } )
class WarningAdd ( View ) :
@method_decorator ( csrf_protect )
def get ( self , request ) :
form = WarningForm ( ) . as_p ( )
return render ( request , ' minecraft_manager/warning_add.html ' ,
{ ' current_app ' : ' warning ' , ' form ' : form } )
def post ( self , request ) :
post = request . POST
form = WarningForm ( post )
if form . is_valid ( ) :
warning = form . save ( )
warning . staff = request . user
warning . save ( )
API . discord_mcm (
" ** {0} ** issued a ** {1} ** severity warning to ** {2} ** \n Preview: {3} " . format ( warning . staff . player . username ,
warning . severity_display ,
warning . player . username ,
warning . snippet ) )
return redirect ( " {0} {1} " . format ( reverse ( ' warning ' ) , warning . id ) )
else :
return render ( request , ' minecraft_manager/warning_add.html ' ,
{ ' current_app ' : ' warning ' , ' form ' : form } )
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 )
class Bots ( View ) :
def assets ( self ) :
path = os . path . abspath ( os . path . dirname ( __file__ ) )
bot_dir = os . path . join ( path , ' assets/bots ' )
return bot_dir
def get_bots ( self ) :
bot_dir = getattr ( settings , ' BOT_DIR ' , None )
bots = [ ]
if bot_dir :
for file in os . listdir ( bot_dir ) :
if file . endswith ( ' .bot.py ' ) :
ve = file . replace ( ' .bot.py ' , ' ' )
py = os . path . join ( bot_dir , ve , ' bin/python ' )
if os . path . isfile ( py ) :
bots . append ( { ' name ' : file . replace ( ' .bot.py ' , ' ' ) , ' asset ' : False , ' executable ' : py } )
else :
bots . append ( { ' name ' : file . replace ( ' .bot.py ' , ' ' ) , ' asset ' : False , ' executable ' : sys . executable } )
# Also get packaged MCM bots
for file in os . listdir ( self . assets ( ) ) :
if file . endswith ( ' .bot.py ' ) :
bots . append ( { ' name ' : file . replace ( ' .bot.py ' , ' ' ) , ' asset ' : True , ' executable ' : sys . executable } )
return bots
def get_form ( self ) :
bots = self . get_bots ( )
plugin_port = getattr ( settings , ' PLUGIN_PORT ' , None )
screens = subprocess . getoutput ( " screen -ls " )
form = { ' screens ' : screens , ' bots ' : bots }
for bot in bots :
form [ bot [ ' name ' ] ] = True if " {0} _ {1} " . format ( plugin_port , bot [ ' name ' ] ) in screens else False
return form
def get ( self , request ) :
return render ( request , ' minecraft_manager/bots.html ' , { ' current_app ' : ' bots ' , ' form ' : self . get_form ( ) } )
def post ( self , request ) :
post = request . POST
plugin_port = getattr ( settings , ' PLUGIN_PORT ' , None )
for bot in self . get_bots ( ) :
if bot [ ' name ' ] in post :
if post [ bot [ ' name ' ] ] == " stop " :
subprocess . run ( ' screen -X -S " {0} _ {1} " quit ' . format ( plugin_port , bot [ ' name ' ] ) , shell = True )
elif post [ bot [ ' name ' ] ] in ( ' start ' , ' restart ' ) :
subprocess . run ( ' screen -X -S " {0} _ {1} " quit ' . format ( plugin_port , bot [ ' name ' ] ) , shell = True )
path = self . assets ( ) if bot [ ' asset ' ] else getattr ( settings , ' BOT_DIR ' , " " )
if not path . endswith ( " / " ) :
path + = " / "
print ( ' screen -S {0} _ {1} -d -m {2} {3} {1} .bot.py ' . format ( plugin_port , bot [ ' name ' ] , bot [ ' executable ' ] , path ) )
subprocess . run (
' screen -S {0} _ {1} -d -m {2} {3} {1} .bot.py ' . format ( plugin_port , bot [ ' name ' ] , bot [ ' executable ' ] , path ) ,
shell = True , stdout = subprocess . PIPE , stderr = subprocess . PIPE )
return render ( request , ' minecraft_manager/bots.html ' , { ' current_app ' : ' bots ' , ' form ' : self . get_form ( ) } )