|
@@ -1,17 +1,24 @@
|
|
|
from datetime import datetime, timedelta
|
|
from datetime import datetime, timedelta
|
|
|
|
|
+import json
|
|
|
|
|
+import uuid
|
|
|
|
|
|
|
|
from django.contrib.auth import logout, login, update_session_auth_hash
|
|
from django.contrib.auth import logout, login, update_session_auth_hash
|
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib.auth.decorators import login_required
|
|
|
from django.contrib.auth.forms import PasswordChangeForm
|
|
from django.contrib.auth.forms import PasswordChangeForm
|
|
|
from django.contrib.auth.models import User
|
|
from django.contrib.auth.models import User
|
|
|
|
|
+from django.core.files.base import ContentFile
|
|
|
|
|
+from django.core.files.storage import default_storage
|
|
|
from django.core.paginator import Paginator
|
|
from django.core.paginator import Paginator
|
|
|
from django.db.models.aggregates import Sum
|
|
from django.db.models.aggregates import Sum
|
|
|
from django.http.response import HttpResponse
|
|
from django.http.response import HttpResponse
|
|
|
from django.shortcuts import render, get_object_or_404, redirect
|
|
from django.shortcuts import render, get_object_or_404, redirect
|
|
|
from django.urls.base import reverse
|
|
from django.urls.base import reverse
|
|
|
|
|
+from martor.utils import LazyEncoder
|
|
|
from notifications.models import Notification
|
|
from notifications.models import Notification
|
|
|
from notifications.signals import notify
|
|
from notifications.signals import notify
|
|
|
|
|
+from path import Path
|
|
|
|
|
|
|
|
|
|
+from backlog import settings
|
|
|
from main.forms import StoryForm, EpicForm, RegisterForm, ProfileForm, \
|
|
from main.forms import StoryForm, EpicForm, RegisterForm, ProfileForm, \
|
|
|
CommentForm, SprintForm, NewSprintForm
|
|
CommentForm, SprintForm, NewSprintForm
|
|
|
from main.models import Story, Epic, Sprint, Comment, Project
|
|
from main.models import Story, Epic, Sprint, Comment, Project
|
|
@@ -475,3 +482,30 @@ def notify_sprint_end(sprint, next_sprint, ended_by):
|
|
|
target_url = reverse(f"report_sprints")
|
|
target_url = reverse(f"report_sprints")
|
|
|
notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Fin du <a href='{target_url}'>{sprint}</a>")
|
|
notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Fin du <a href='{target_url}'>{sprint}</a>")
|
|
|
notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Démarrage du <a href='{target_url}'>{next_sprint}</a>")
|
|
notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Démarrage du <a href='{target_url}'>{next_sprint}</a>")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@login_required
|
|
|
|
|
+def md_upload_file(request):
|
|
|
|
|
+ if request.method == 'POST' and request.is_ajax():
|
|
|
|
|
+ if 'markdown-image-upload' in request.FILES:
|
|
|
|
|
+
|
|
|
|
|
+ image = request.FILES['markdown-image-upload']
|
|
|
|
|
+
|
|
|
|
|
+ if image.size > settings.MAX_IMAGE_UPLOAD_SIZE:
|
|
|
|
|
+ data = json.dumps({'status': 405,
|
|
|
|
|
+ 'error': _('Maximum image file is %(size) MB.') % {'size': (settings.MAX_IMAGE_UPLOAD_SIZE / (1024 * 1024))} },
|
|
|
|
|
+ cls=LazyEncoder)
|
|
|
|
|
+ return HttpResponse(data, content_type='application/json', status=405)
|
|
|
|
|
+
|
|
|
|
|
+ img_uuid = "{0}-{1}".format(uuid.uuid4().hex[:10], image.name.replace(' ', '-'))
|
|
|
|
|
+ tmp_file = Path(settings.MARTOR_UPLOAD_PATH) / img_uuid
|
|
|
|
|
+ def_path = default_storage.save(tmp_file, ContentFile(image.read()))
|
|
|
|
|
+ img_url = Path(settings.MEDIA_URL) / def_path
|
|
|
|
|
+
|
|
|
|
|
+ data = json.dumps({'status': 200, 'link': img_url, 'name': image.name})
|
|
|
|
|
+ return HttpResponse(data, content_type='application/json')
|
|
|
|
|
+ return HttpResponse(_('Invalid request!'))
|
|
|
|
|
+ return HttpResponse(_('Invalid request!'))
|
|
|
|
|
+
|
|
|
|
|
+
|