Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def adminStatisticsView(request, dieName):
"""
"""
dieObject = Die.objects.filter(name=dieName)[0]
# Get how many fields and how many have been typed
allFields = TypedDie.objects.filter(Q(dieImage__die=dieObject))
typedFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & ~Q(typedField=""))
# Get a list of who's on first
scoreboard = list()
for user in User.objects.all():
userTyped = TypedDie.objects.filter(~Q(typedField="") & Q(submitter=user) & Q(dieImage__die=dieObject))
scoreboard.append( (user, len(userTyped)) )
sortedScores = sorted(scoreboard, key=lambda tup: tup[1], reverse=True)
context = {
'die' : dieObject,
'allFieldCount' : len(allFields),
'allTypedCount' : len(typedFields),
'scoreboard' : sortedScores
}
return render(request, 'typer/adminStatistics.html', context)
# If the given username isn't the logged-in user, see if it's staff. If not, go no further.
if userName != request.user.username and not request.user.is_staff:
return HttpResponse("Only administrators can access user statistics directly")
# Get the User object from the username
dieObject = Die.objects.filter(name=dieName)[0]
specifiedUser = None
for user in User.objects.all():
if userName == user.username:
specifiedUser = user
if specifiedUser is None:
return HttpResponse("The user %s does not exist." % userName)
# Carry on
userTypedTheseFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & Q(submitter=specifiedUser))
# How does this user's entry count compare to the others?
userEntryTupleList = list()
for user in User.objects.all():
if user == specifiedUser:
continue
otherUserTypedFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & Q(submitter=user))
userEntryTupleList.append((user, len(otherUserTypedFields)))
sortedByEntry = [x for (y,x) in sorted(userEntryTupleList, key=lambda pair: pair[1], reverse=True)]
quantityRank = len(sortedByEntry)
for i in range(len(sortedByEntry)):
if len(userTypedTheseFields) > sortedByEntry[i]:
quantityRank = i
break
quantityRank += 1
if not usableFields:
return HttpResponse("All fields have been typed for this die. Check back later to see if there are other dies to type.")
# Choose a random field to display
randomField = random.randint(0, len(usableFields)-1)
randomId = usableFields[randomField].id
# Display the random page
return imageInput(request, randomId)
else:
# Data has been POSTed
# Pull the previous die field out of the form's hidden data
dieId = int(request.POST['dieField'])
dieField = TypedDie.objects.filter(id=dieId)[0]
someoneCompletedTheFieldBeforeYou = dieField.completed()
# Create a form object from the post data and knowledge of which dieField we're dealing with
form = MonkeyTyperForm(request.POST, instance=dieField)
# Insure input is valid (if it is, data is stored in dieField, but not saved to the database)
# TODO: There is a very good chance exceptions aren't being used correctly here
if not form.is_valid():
# Redisplay the same page but with an error message
error = form.errors.as_data()['typedField'][0].message
return imageInput(request, dieField.id, error, form.data['typedField'])
# If the strange situation occurred where someone snuck in and completed the field before you
if someoneCompletedTheFieldBeforeYou:
# TODO: Convert to django/Python logging
dieObject = dieField.dieImage.die
specifiedUser = None
for user in User.objects.all():
if userName == user.username:
specifiedUser = user
if specifiedUser is None:
return HttpResponse("The user %s does not exist." % userName)
# Carry on
userTypedTheseFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & Q(submitter=specifiedUser))
# How does this user's entry count compare to the others?
userEntryTupleList = list()
for user in User.objects.all():
if user == specifiedUser:
continue
otherUserTypedFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & Q(submitter=user))
userEntryTupleList.append((user, len(otherUserTypedFields)))
sortedByEntry = [x for (y,x) in sorted(userEntryTupleList, key=lambda pair: pair[1], reverse=True)]
quantityRank = len(sortedByEntry)
for i in range(len(sortedByEntry)):
if len(userTypedTheseFields) > sortedByEntry[i]:
quantityRank = i
break
quantityRank += 1
# For each field the user typed, compare against other users' results
comparisonMessages = list()
for userTypedField in userTypedTheseFields:
typedFieldCount = 0
perfectMatchCount = 0
allFieldsRelatedToUserTypedField = TypedDie.objects.filter(Q(dieImage=userTypedField.dieImage) & ~Q(submitter=specifiedUser))
for field in allFieldsRelatedToUserTypedField:
def adminSummaryHomeView(request, dieName):
"""
An administrative view that displays a list of images and info about
the typed information for each for the given Die. The administrator
can see how much data has been entered for each image and click on
the image to open a new view showing more details.
"""
dieObject = Die.objects.filter(name=dieName)[0]
allAvailableDieImages = DieImage.objects.filter(Q(die=dieObject))
allApplicableTypedDies = TypedDie.objects.filter(Q(dieImage__die=dieObject))
# Count all the entered fields for this die image (TODO: There must be a more Pythonic way to do this)
totalFields = 0
totalCompletedFields = 0
dieIsCompleted = list()
dieImageEntryCounts = list()
# TODO: This is very slow right now - seems to be 2/3 python and 1/3 html - could be sped up with a Paginator
for di in allAvailableDieImages:
typedFields = allApplicableTypedDies.filter(Q(dieImage=di))
completedFieldCount = 0
for tf in typedFields:
if tf.completed():
completedFieldCount += 1
totalFields += len(typedFields)
totalCompletedFields += completedFieldCount
dieImageEntryCounts.append(completedFieldCount)
def adminStatisticsView(request, dieName):
"""
"""
dieObject = Die.objects.filter(name=dieName)[0]
# Get how many fields and how many have been typed
allFields = TypedDie.objects.filter(Q(dieImage__die=dieObject))
typedFields = TypedDie.objects.filter(Q(dieImage__die=dieObject) & ~Q(typedField=""))
# Get a list of who's on first
scoreboard = list()
for user in User.objects.all():
userTyped = TypedDie.objects.filter(~Q(typedField="") & Q(submitter=user) & Q(dieImage__die=dieObject))
scoreboard.append( (user, len(userTyped)) )
sortedScores = sorted(scoreboard, key=lambda tup: tup[1], reverse=True)
context = {
'die' : dieObject,
'allFieldCount' : len(allFields),
'allTypedCount' : len(typedFields),
'scoreboard' : sortedScores
}
return render(request, 'typer/adminStatistics.html', context)
data about which die has been randomly chosen passes through to the POST
method since this view decides it dynamically.
Note:
allAvailableFields = allAvailableFields.exclude(Q(dieImage=tuht.dieImage))
Resulted in large AND NOT query after adding many entries
Instead two separate queries and subtract out manually
"""
userIsStaff = request.user.is_staff
if request.method == 'GET':
# Standard page display
dieObject = Die.objects.filter(name=dieName)[0]
allAvailableFields = TypedDie.objects.filter(Q(typedField="") & Q(dieImage__die=dieObject))
thingsUserHasTyped = TypedDie.objects.filter(~Q(typedField="") & Q(submitter=request.user) & Q(dieImage__die=dieObject))
setTyped = [td.dieImage_id for td in thingsUserHasTyped]
usableFields = list(filter(lambda x: x.dieImage_id not in setTyped, allAvailableFields))
#print 'avail', len(allAvailableFields)
#print 'typed', len(setTyped)
#print 'usable', len(usableFields)
if not usableFields:
return HttpResponse("All fields have been typed for this die. Check back later to see if there are other dies to type.")
# Choose a random field to display
randomField = random.randint(0, len(usableFields)-1)
randomId = usableFields[randomField].id
# Display the random page
return imageInput(request, randomId)