Large diffs are not rendered by default.

@@ -21,16 +21,102 @@
# along with Pups. If not, see <http://www.gnu.org/licenses/>.

from django.db import models
from django.db.models import F
from django.core.exceptions import ObjectDoesNotExist
from django.core import serializers


class Issue(models.Model):
issue_id = models.CharField(max_length=64)
text = models.TextField()
frequency = models.IntegerField()
frequency = models.IntegerField(default=1)
created_by = models.CharField(max_length=64)
is_locked = models.BooleanField()
created_at = models.DateTimeField(auto_now_add=True)
last_edited_at = models.DateTimeField(auto_now_add=True)
is_locked = models.BooleanField(default=False)
locked_by = models.CharField(max_length=64)
last_edited_by = models.CharField(max_length=64)

def __unicode__(self):
return u'ID: %s Owner: %s Text: %s' % (self.issue_id, self.owner, self.text)
return u'ID: %s Text: %s Freq: %s locked: %s' % \
(self.pk, self.text, self.frequency, self.is_locked)

@staticmethod
def get_issues_json():
return serializers.serialize(
"json",
Issue.objects.all().order_by('-frequency'))

@staticmethod
def create_issue(user, text):
q = Issue(
text=text,
created_by=user
)
q.save()

return q.id is not None

@staticmethod
def delete_issue(id):
issue = Issue.objects.filter(id=id)

if not issue:
return False

issue.delete()
return True

@staticmethod
def save_edit(id, edited_text, user):
issue = Issue.objects.filter(id=id)

if not issue:
return False

issue.update(text=edited_text)
issue.update(last_edited_by=user)
return True

@staticmethod
def plus_one(id):
issue = Issue.objects.filter(id=id)

if not issue:
return False

issue.update(frequency=F('frequency')+1)
return True

@staticmethod
def lock(id, user):
# Stats: Locked, not_found, lock

# Checking if the row exists
try:
issue_obj = Issue.objects.get(id=id)
except ObjectDoesNotExist:
# Someone deleted the row while user tried to edit it
return False

issue_db_row = Issue.objects.filter(id=id)

# Checking if issue is locked for editing by another user
if issue_obj.is_locked:
return {'locked_by': issue_obj.locked_by}

# If issue isn't used by anyone lock it
issue_db_row.update(is_locked=True)
issue_db_row.update(locked_by=user)
return True

@staticmethod
def unlock(id):

issue = Issue.objects.filter(id=id)

if not issue:
return False

issue.update(is_locked=False)
issue.update(locked_by="")
return True
@@ -15,31 +15,51 @@

{% block content %}
{% include "nav_bar.html" %}
<div id="newq">
<input id="new_issue_text" class="form-control" placeholder="Warning: This is not ready yet!" type="text" style="display: inline-block;">
<input id="save_issue" class="btn btn-default" type="button" value="Save">
</div>

<div id="issues"></div>
<form role="form" method="post" action="/create_issue">
{% csrf_token %}
<input id="new_issue_text" name="new_issue_text" class="form-control" placeholder="Warning: This is not ready yet!" type="text" style="display: inline-block;">
<button id="save_issue" class="btn btn-default" type="submit">Save</button>
<div id="newq">
</div>
</form>

<div id="issues">
</div>

<!-- Issue Edit Modal -->
<div class="modal fade" id="EditIssue" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Edit issue</h4>
</div>
<div class="modal-body">
<textarea id="edit_text" rows="8" cols="65"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="close_edit">Close</button>
<button type="button" class="btn btn-primary" id="save_edit">Save changes</button>
</div>
<!-- Issue Edit Modal -->
<div class="modal fade" id="EditIssue" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Edit issue</h4>
</div>
<div class="modal-body">
<textarea id="edit_text" rows="8" cols="65"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="close_edit">Close</button>
<button type="button" class="btn btn-primary" id="save_edit">Save changes</button>
</div>
</div>
</div>
</div>

<!-- Alert Modal -->
<div class="modal fade" id="Alert" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="AlertLable"></h4>
</div>
<div class="alert-body" style="word-wrap:break-word;">
</div>
<div class="modal-footer">
<button id="alert-ok" type="button" class="btn btn-default" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>

{% include "footer.html" %}
{% endblock content %}
@@ -25,5 +25,13 @@

urlpatterns = patterns(
'',
url(r'^stats$', 'stats.views.stats')
url(r'^stats$', 'stats.views.stats_page'),
url(r'^create_issue$', 'stats.views.create_issue'),
url(r'^delete_issue$', 'stats.views.delete_issue_ajax'),
url(r'^edit_issue$', 'stats.views.edit_issue_ajax'),
url(r'^save_issue_edit$', 'stats.views.save_issue_edit_ajax'),
url(r'^unlock_issue$', 'stats.views.unlock_issue_ajax'),
url(r'^plus_one$', 'stats.views.plus_one_ajax'),
url(r'^stats_data_ajax$', 'stats.views.stats_data_ajax'),

)
@@ -20,12 +20,105 @@
# You should have received a copy of the GNU General Public License
# along with Pups. If not, see <http://www.gnu.org/licenses/>.

import json
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from stats.models import Issue


@login_required
def stats(request):

@login_required
def stats_page(request):
return render(request, 'stats.html')

@login_required
def stats_data_ajax(request):
return HttpResponse(json.dumps(Issue.get_issues_json()),
content_type="application/json")

@login_required
def create_issue(request):

Issue.create_issue(request.user.username, request.POST['new_issue_text'])
return redirect("/stats")


@login_required
def plus_one_ajax(request):
'''
This method increases an issue by one in the db
'''
response_data = {}
response_data['status'] = 'failure'

if Issue.plus_one(request.POST['id']):
response_data['status'] = 'success'

return HttpResponse(json.dumps(response_data),
content_type="application/json")


@login_required
def edit_issue_ajax(request):
'''
Attempts to lock issue row in db and reports back if row
was locked by another user or does not exist.
'''
response_data = {}
lock_status = Issue.lock(request.POST['id'], request.user.username)

if lock_status is True:
response_data['lock_status'] = 'lock_success'
elif lock_status is False:
response_data['lock_status'] = 'does_not_exist'
elif type(lock_status) is dict:
response_data['locked_by'] = lock_status['locked_by']

return HttpResponse(json.dumps(response_data),
content_type="application/json")


@login_required
def save_issue_edit_ajax(request):

response_data = {}
response_data['status'] = 'failure'

if Issue.save_edit(request.POST['id'],
request.POST['edited_text'],
request.user.username):

response_data['status'] = 'success'

return HttpResponse(json.dumps(response_data),
content_type="application/json")


@login_required
def unlock_issue_ajax(request):

response_data = {}
response_data['status'] = 'failure'

if Issue.unlock(request.POST['id']):
response_data['status'] = 'success'

return HttpResponse(json.dumps(response_data),
content_type="application/json")


@login_required
def delete_issue_ajax(request):
'''
Deletes one issue (db row) and gives back feedback in json
'''

response_data = {}
response_data['status'] = 'failure'

if Issue.delete_issue(request.POST['id']):
response_data['status'] = 'success'

return HttpResponse(json.dumps(response_data),
content_type="application/json")