Commit 5d37117ca42d496ac8aa671795c1de8b1e8b2219

Authored by Zambom
1 parent 3096a6c4

Subject restore initials

subjects/templates/subjects/backup.html
... ... @@ -56,6 +56,7 @@
56 56 <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
57 57 <li><a href="{% url 'groups:index' subject.slug %}"><i class="fa fa-group fa-fw" aria-hidden="true"></i>{% trans 'Groups' %}</a></li>
58 58 <li><a href="{% url 'subjects:backup' subject.slug %}"><i class="fa fa-database fa-fw" aria-hidden="true"></i>{% trans 'Backup' %}</a></li>
  59 + <li><a href="{% url 'subjects:restore' subject.slug %}"><i class="fa fa-recycle fa-fw" aria-hidden="true"></i>{% trans 'Restore' %}</a></li>
59 60 <li><a href="javascript:delete_subject.get('{% url 'subjects:delete' subject.slug %}?view=index','#subject','#modal_subject')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp;{% trans 'Remove' %}</a></li>
60 61 </ul>
61 62 {% endif %}
... ... @@ -161,12 +162,5 @@
161 162 }
162 163 });
163 164 });
164   -
165   - // $("#bkp_form").submit(function () {
166   - // setTimeout(function() {
167   - // // Should be triggered after download started
168   - // document.location.href="{% url 'subjects:view' subject.slug %}";
169   - // }, 3000);
170   - // });
171 165 </script>
172 166 {% endblock content %}
... ...
subjects/templates/subjects/restore.html 0 → 100644
... ... @@ -0,0 +1,138 @@
  1 +{% extends 'categories/home.html' %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter chat_tags %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="{% static 'subjects/js/modal_subject.js' %}"></script>
  9 +{% endblock%}
  10 +
  11 +{% block breadcrumbs %}
  12 + {{ block.super }}
  13 + {% breadcrumb subject.category 'subjects:cat_view' subject.category.slug %}
  14 + {% breadcrumb subject 'subjects:view' subject.slug %}
  15 +
  16 + {% trans "Restore" as bread %}
  17 + {% breadcrumb bread 'subjects:restore' subject.slug %}
  18 +{% endblock %}
  19 +
  20 +{% block content %}
  21 + {% if messages %}
  22 + {% for message in messages %}
  23 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  24 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  25 + <span aria-hidden="true">&times;</span>
  26 + </button>
  27 + <p>{{ message }}</p>
  28 + </div>
  29 + {% endfor %}
  30 + {% endif %}
  31 +
  32 + {% subject_permissions request.user subject as has_subject_permissions %}
  33 +
  34 + {% if subject.visible %}
  35 + <div class="panel panel-info subject-panel" id="subject_{{subject.slug}}">
  36 + <div class="panel-heading">
  37 + {% elif has_subject_permissions %}
  38 + <div class="panel panel-info subject-panel-invisible" id="subject_{{subject.slug}}">
  39 + <div class="panel-heading panel-invisible">
  40 + {% endif %}
  41 + <div class="row">
  42 + <div class="col-md-12 category-header">
  43 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  44 + <span>{{ subject.name }} / {% trans "Restore" %}</span>
  45 + </h4>
  46 +
  47 + <div class="col-md-5 pull-right category-card-items">
  48 + {% if request.user in subject.professor.all or request.user in subject.category.coordinators.all or request.user.is_staff %}
  49 + <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  50 + <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
  51 + </a>
  52 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  53 + {% if request.user not in subject.professor.all %}
  54 + <li><a href="{% url 'subjects:replicate' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li>
  55 + {% endif %}
  56 + <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
  57 + <li><a href="{% url 'groups:index' subject.slug %}"><i class="fa fa-group fa-fw" aria-hidden="true"></i>{% trans 'Groups' %}</a></li>
  58 + <li><a href="{% url 'subjects:backup' subject.slug %}"><i class="fa fa-database fa-fw" aria-hidden="true"></i>{% trans 'Backup' %}</a></li>
  59 + <li><a href="{% url 'subjects:restore' subject.slug %}"><i class="fa fa-recycle fa-fw" aria-hidden="true"></i>{% trans 'Restore' %}</a></li>
  60 + <li><a href="javascript:delete_subject.get('{% url 'subjects:delete' subject.slug %}?view=index','#subject','#modal_subject')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp;{% trans 'Remove' %}</a></li>
  61 + </ul>
  62 + {% endif %}
  63 + </div>
  64 + </div>
  65 + </div>
  66 + </div>
  67 + <div id="{{subject.slug}}" class="panel-collapse in collapse category-panel-content" style="position: relative">
  68 + <h5>{% trans "Please select below the file you want to use for restore:" %}</h5>
  69 +
  70 + <div class="backup_container">
  71 + <form id="restore_form" method="post" action="{% url 'subjects:do_restore' subject.slug %}" enctype="multipart/form-data">
  72 + {% csrf_token %}
  73 +
  74 + <div class="form-group is-fileinput">
  75 + <input type="file" id="zip_file" name="zip_file" class="form-control" accept=".zip" />
  76 +
  77 + <div class="input-group common-file-input">
  78 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">
  79 + <span class="input-group-btn input-group-sm">
  80 + <button type="button" class="btn btn-fab btn-fab-mini">
  81 + <i class="material-icons">attach_file</i>
  82 + </button>
  83 + </span>
  84 + </div>
  85 +
  86 + <div class="filedrag">
  87 + {% trans 'Click or drop the file here' %}<br />
  88 + </div>
  89 + </div>
  90 +
  91 + <div class="row text-center">
  92 + <input type="submit" value="{% trans 'Restore' %}" class="btn btn-success btn-raised" />
  93 + </div>
  94 + </form>
  95 + </div>
  96 + </div>
  97 + </div>
  98 +
  99 + <script type="text/javascript">
  100 + $(function () {
  101 + $.material.init();
  102 +
  103 + if (window.File && window.FileList && window.FileReader) {
  104 + Init();
  105 + }
  106 + });
  107 +
  108 + // initialize
  109 + function Init() {
  110 + var small = $("#zip_file"),
  111 + filedrag = $(".filedrag"),
  112 + common = $(".common-file-input");
  113 +
  114 + // file select
  115 + small.on("change", FileSelectHandler);
  116 +
  117 + // is XHR2 available?
  118 + var xhr = new XMLHttpRequest();
  119 + if (xhr.upload) {
  120 + // file drop
  121 + filedrag.on("drop", FileSelectHandler);
  122 + filedrag.attr('style', 'display:block');
  123 + common.attr('style', 'display:none');
  124 + }
  125 + }
  126 +
  127 + // file selection
  128 + function FileSelectHandler(e) {
  129 + var files = e.target.files || e.dataTransfer.files,
  130 + parent = $(e.target.offsetParent);
  131 +
  132 + // process all File objects
  133 + for (var i = 0, f; f = files[i]; i++) {
  134 + parent.find('.filedrag').html(f.name);
  135 + }
  136 + }
  137 + </script>
  138 +{% endblock %}
0 139 \ No newline at end of file
... ...
subjects/templates/subjects/subject_card.html
... ... @@ -31,6 +31,7 @@
31 31 <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
32 32 <li><a href="{% url 'groups:index' subject.slug %}"><i class="fa fa-group fa-fw" aria-hidden="true"></i>{% trans 'Groups' %}</a></li>
33 33 <li><a href="{% url 'subjects:backup' subject.slug %}"><i class="fa fa-database fa-fw" aria-hidden="true"></i>{% trans 'Backup' %}</a></li>
  34 + <li><a href="{% url 'subjects:restore' subject.slug %}"><i class="fa fa-recycle fa-fw" aria-hidden="true"></i>{% trans 'Restore' %}</a></li>
34 35 <li><a href="javascript:delete_subject.get('{% url 'subjects:delete' subject.slug %}?view=index','#subject','#modal_subject')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp;{% trans 'Remove' %}</a></li>
35 36 </ul>
36 37 {% endif %}
... ...
subjects/urls.py
... ... @@ -10,7 +10,9 @@ urlpatterns = [
10 10 url(r'^update/(?P<slug>[\w_-]+)/$', views.SubjectUpdateView.as_view(), name='update'),
11 11 url(r'^delete/(?P<slug>[\w_-]+)/$', views.SubjectDeleteView.as_view(), name='delete'),
12 12 url(r'^backup/(?P<slug>[\w_-]+)/$', views.Backup.as_view(), name='backup'),
  13 + url(r'^restore/(?P<slug>[\w_-]+)/$', views.Restore.as_view(), name='restore'),
13 14 url(r'^do_backup/(?P<subject>[\w_-]+)/$', views.realize_backup, name='do_backup'),
  15 + url(r'^do_restore/(?P<subject>[\w_-]+)/$', views.realize_restore, name='do_restore'),
14 16 url(r'^view/(?P<slug>[\w_-]+)/$', views.SubjectDetailView.as_view(), name='view'),
15 17 url(r'^view/(?P<slug>[\w_-]+)/(?P<topic_slug>[\w_-]+)/$', views.SubjectDetailView.as_view(), name='topic_view'),
16 18 url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.SubjectSubscribeView.as_view(), name='subscribe'),
... ...
subjects/views.py
... ... @@ -837,4 +837,40 @@ def realize_backup(request, subject):
837 837 resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
838 838 resp['Content-Length'] = s.tell()
839 839  
840   - return resp
841 840 \ No newline at end of file
  841 + return resp
  842 +
  843 +class Restore(LoginRequiredMixin, TemplateView):
  844 + login_url = reverse_lazy("users:login")
  845 + redirect_field_name = 'next'
  846 +
  847 + template_name = 'subjects/restore.html'
  848 + model = Subject
  849 +
  850 + def dispatch(self, request, *args, **kwargs):
  851 + subject = get_object_or_404(Subject, slug = kwargs.get('slug', ''))
  852 +
  853 + if not has_subject_permissions(request.user, subject):
  854 + return redirect(reverse_lazy('subjects:home'))
  855 +
  856 + return super(Restore, self).dispatch(request, *args, **kwargs)
  857 +
  858 + def get_context_data(self, **kwargs):
  859 + context = super(Restore, self).get_context_data(**kwargs)
  860 +
  861 + subject = get_object_or_404(Subject, slug = self.kwargs.get('slug', ''))
  862 +
  863 + context['title'] = _('%s - Restore')%(str(subject))
  864 + context['subject'] = subject
  865 +
  866 + return context
  867 +
  868 +@login_required
  869 +def realize_restore(request, subject):
  870 + zip_file = request.FILES.get('zip_file', None)
  871 +
  872 + if zip_file:
  873 + if zipfile.is_zipfile(zip_file):
  874 + file = zipfile.ZipFile(zip_file)
  875 + print(file.namelist())
  876 +
  877 + return JsonResponse({'message': 'ok'})
842 878 \ No newline at end of file
... ...