diff --git a/templates/tutorial/member/online.html b/templates/tutorial/member/online.html
index 171035d892..9d31b3fd70 100644
--- a/templates/tutorial/member/online.html
+++ b/templates/tutorial/member/online.html
@@ -31,7 +31,7 @@
Tutoriels publiés par {{ usr.username }}
{% for tutorial in tutorials %}
- {% include 'tutorial/includes/tutorial_item.part.html' with beta=True %}
+ {% include 'tutorial/includes/tutorial_item.part.html' %}
{% endfor %}
{% else %}
diff --git a/zds/article/models.py b/zds/article/models.py
index 319afe9f34..29fe606c76 100644
--- a/zds/article/models.py
+++ b/zds/article/models.py
@@ -5,6 +5,7 @@
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import models
from math import ceil
+from git import Repo
import os
import string
import uuid
@@ -25,15 +26,11 @@
from zds.utils import get_current_user
from zds.utils import slugify
-from zds.utils.articles import export_article
+from zds.utils.articles import export_article, get_blob
from zds.utils.models import SubCategory, Comment, Licence
from django.core.urlresolvers import reverse
-IMAGE_MAX_WIDTH = 480
-IMAGE_MAX_HEIGHT = 100
-
-
def image_path(instance, filename):
"""Return path to an image."""
ext = filename.split('.')[-1]
@@ -141,6 +138,30 @@ def load_json(self, path=None, online=False):
else:
return None
+ def load_json_for_public(self):
+ repo = Repo(self.get_path())
+ manarticle = get_blob(repo.commit(self.sha_public).tree, 'manifest.json')
+ data = json_reader.loads(manarticle)
+
+ return data
+
+ def load_dic(self, article_version):
+ article_version['pk'] = self.pk
+ article_version['slug'] = slugify(article_version['title'])
+ article_version['image'] = self.image
+ article_version['pubdate'] = self.pubdate
+ article_version['is_locked'] = self.is_locked
+ article_version['sha_draft'] = self.sha_draft
+ article_version['sha_validation'] = self.sha_validation
+ article_version['sha_public'] = self.sha_public
+ article_version['get_reaction_count'] = self.get_reaction_count
+ article_version['get_absolute_url'] = reverse('zds.article.views.view',
+ args=[self.pk, self.slug])
+ article_version['get_absolute_url_online'] = reverse('zds.article.views.view_online',
+ args=[self.pk,slugify(article_version['title'])])
+
+ return article_version
+
def dump_json(self, path=None):
if path is None:
man_path = os.path.join(self.get_path(), 'manifest.json')
diff --git a/zds/article/urls.py b/zds/article/urls.py
index f1b2532f12..40c472c366 100644
--- a/zds/article/urls.py
+++ b/zds/article/urls.py
@@ -29,7 +29,7 @@
url(r'^nouveau/$', 'zds.article.views.new'),
url(r'^editer/$', 'zds.article.views.edit'),
url(r'^modifier/$', 'zds.article.views.modify'),
- url(r'^recherche/(?P\d+)/$',
+ url(r'^recherche/(?P\d+)/$',
'zds.article.views.find_article'),
diff --git a/zds/article/views.py b/zds/article/views.py
index b08d78a184..742934eefa 100644
--- a/zds/article/views.py
+++ b/zds/article/views.py
@@ -55,20 +55,26 @@ def index(request):
tag = None
if tag is None:
- article = Article.objects\
+ articles = Article.objects\
.filter(sha_public__isnull=False).exclude(sha_public="")\
.order_by('-pubdate')\
.all()
else:
# The tag isn't None and exist in the system. We can use it to retrieve
# all articles in the subcategory specified.
- article = Article.objects\
+ articles = Article.objects\
.filter(sha_public__isnull=False, subcategory__in=[tag])\
.exclude(sha_public="").order_by('-pubdate')\
.all()
+
+ article_versions = []
+ for article in articles:
+ article_version = article.load_json_for_public()
+ article_version = article.load_dic(article_version)
+ article_versions.append(article_version)
return render_template('article/index.html', {
- 'articles': article,
+ 'articles': article_versions,
'tag': tag,
})
@@ -83,10 +89,6 @@ def view(request, article_pk, article_slug):
if not request.user.has_perm('article.change_article'):
raise PermissionDenied
- # The slug of the article must to be right.
- if article_slug != slugify(article.title):
- return redirect(article.get_absolute_url())
-
# Retrieve sha given by the user. This sha must to be exist.
# If it doesn't exist, we take draft version of the article.
try:
@@ -105,17 +107,8 @@ def view(request, article_pk, article_slug):
manifest = get_blob(repo.commit(sha).tree, 'manifest.json')
article_version = json_reader.loads(manifest)
- article_version['txt'] = get_blob(
- repo.commit(sha).tree,
- article_version['text'])
- article_version['pk'] = article.pk
- article_version['slug'] = article.slug
- article_version['image'] = article.image
- article_version['pubdate'] = article.pubdate
- article_version['sha_draft'] = article.sha_draft
- article_version['sha_validation'] = article.sha_validation
- article_version['sha_public'] = article.sha_public
- article_version['get_absolute_url_online'] = article.get_absolute_url_online()
+ article_version['txt'] = get_blob(repo.commit(sha).tree, article_version['text'])
+ article_version = article.load_dic(article_version)
validation = Validation.objects.filter(article__pk=article.pk,
version=sha)\
@@ -135,28 +128,14 @@ def view_online(request, article_pk, article_slug):
"""Show the given article if exists and is visible."""
article = get_object_or_404(Article, pk=article_pk)
- # The slug of the article must to be right.
- if article_slug != slugify(article.title):
- return redirect(article.get_absolute_url_online())
-
# Load the article.
- article_version = article.load_json()
- txt = open(
- os.path.join(
- article.get_path(),
- article_version['text'] +
- '.html'),
- "r")
+ article_version = article.load_json_for_public()
+ txt = open(os.path.join(article.get_path(),
+ article_version['text'] + '.html'),
+ "r")
article_version['txt'] = txt.read()
txt.close()
- article_version['pk'] = article.pk
- article_version['slug'] = article.slug
- article_version['image'] = article.image
- article_version['pubdate'] = article.pubdate
- article_version['is_locked'] = article.is_locked
- article_version['get_reaction_count'] = article.get_reaction_count
- article_version['get_absolute_url'] = article.get_absolute_url()
- article_version['get_absolute_url_online'] = article.get_absolute_url_online()
+ article_version = article.load_dic(article_version)
# If the user is authenticated
if request.user.is_authenticated():
@@ -364,16 +343,23 @@ def edit(request):
})
-def find_article(request, name):
+def find_article(request, pk_user):
"""Find an article from his author."""
- user = get_object_or_404(User, pk=name)
+ user = get_object_or_404(User, pk=pk_user)
articles = Article.objects\
.filter(authors__in=[user], sha_public__isnull=False).exclude(sha_public="")\
.order_by('-pubdate')\
.all()
+
+ article_versions = []
+ for article in articles:
+ article_version = article.load_json_for_public()
+ article_version = article.load_dic(article_version)
+ article_versions.append(article_version)
+
# Paginator
return render_template('article/find.html', {
- 'articles': articles, 'usr': user,
+ 'articles': article_versions, 'usr': user,
})
diff --git a/zds/member/views.py b/zds/member/views.py
index e6f664dbfb..bfc4e5da18 100644
--- a/zds/member/views.py
+++ b/zds/member/views.py
@@ -117,18 +117,30 @@ def details(request, user_name):
fchart = os.path.join(img_path, "mod-{}.svg".format(str(usr.pk)))
dot_chart.render_to_file(fchart)
my_articles = Article.objects.filter(sha_public__isnull=False).order_by(
- "-pubdate").filter(authors__in=[usr]).all()
+ "-pubdate").filter(authors__in=[usr]).all()[:5]
my_tutorials = \
Tutorial.objects.filter(sha_public__isnull=False) \
.filter(authors__in=[usr]) \
.order_by("-pubdate"
- ).all()
+ ).all()[:5]
+
+ my_tuto_versions = []
+ for my_tutorial in my_tutorials:
+ mandata = my_tutorial.load_json_for_public()
+ mandata = my_tutorial.load_dic(mandata)
+ my_tuto_versions.append(mandata)
+ my_article_versions = []
+ for my_article in my_articles:
+ article_version = my_article.load_json_for_public()
+ article_version = my_article.load_dic(article_version)
+ my_article_versions.append(article_version)
+
my_topics = \
Topic.objects\
.filter(author=usr)\
.exclude(Q(forum__group__isnull=False) & ~Q(forum__group__in=request.user.groups.all()))\
.prefetch_related("author")\
- .order_by("-pubdate").all()
+ .order_by("-pubdate").all()[:5]
form = OldTutoForm(profile)
oldtutos = []
@@ -142,9 +154,9 @@ def details(request, user_name):
"usr": usr,
"profile": profile,
"bans": bans,
- "articles": my_articles[:5],
- "tutorials": my_tutorials[:5],
- "topics": my_topics[:5],
+ "articles": my_article_versions,
+ "tutorials": my_tuto_versions,
+ "topics": my_topics,
"form": form,
"old_tutos": oldtutos,
})
diff --git a/zds/pages/views.py b/zds/pages/views.py
index e372c970a7..14b0e961e8 100644
--- a/zds/pages/views.py
+++ b/zds/pages/views.py
@@ -29,20 +29,14 @@ def home(request):
tutos = []
for tuto in get_last_tutorials():
data = tuto.load_json_for_public()
- data['pk'] = tuto.pk
- data['image'] = tuto.image
- data['gallery'] = tuto.gallery
- data['pubdate'] = tuto.pubdate
- data['update'] = tuto.update
- data['subcategory'] = tuto.subcategory
- data['get_absolute_url_online'] = reverse(
- 'zds.tutorial.views.view_tutorial_online',
- args=[
- tuto.pk,
- slugify(
- data['title'])])
-
+ data = tuto.load_dic(data)
tutos.append(data)
+
+ articles = []
+ for article in get_last_articles():
+ data = article.load_json_for_public()
+ data = article.load_dic(data)
+ articles.append(data)
try:
with open(os.path.join(SITE_ROOT, 'quotes.txt'), 'r') as fh:
@@ -51,9 +45,8 @@ def home(request):
quote = u'Zeste de Savoir, la connaissance pour tous et sans pépins !'
return render_template('home.html', {
- 'last_topics': get_last_topics(request.user),
'last_tutorials': tutos,
- 'last_articles': get_last_articles(),
+ 'last_articles': articles,
'quote': quote,
})
diff --git a/zds/tutorial/models.py b/zds/tutorial/models.py
index a429fd318d..31171594b8 100644
--- a/zds/tutorial/models.py
+++ b/zds/tutorial/models.py
@@ -183,7 +183,9 @@ def get_prod_path(self):
str(self.pk) + '_' + slugify(data['title']))
def load_dic(self, mandata):
- mandata['get_absolute_url_online'] = self.get_absolute_url_online()
+ mandata['get_absolute_url_online'] = reverse('zds.tutorial.views.view_tutorial_online',
+ args=[self.pk, slugify(mandata["title"])])
+ mandata['get_absolute_url_beta'] = self.get_absolute_url_beta()
mandata['get_absolute_url'] = self.get_absolute_url()
mandata['get_introduction_online'] = self.get_introduction_online()
mandata['get_conclusion_online'] = self.get_conclusion_online()
@@ -203,7 +205,9 @@ def load_dic(self, mandata):
return mandata
- def load_json_for_public(self):
+ def load_json_for_public(self, sha=None):
+ if sha is None:
+ sha = self.sha_public
repo = Repo(self.get_path())
mantuto = get_blob(repo.commit(self.sha_public).tree, 'manifest.json')
data = json_reader.loads(mantuto)
@@ -241,13 +245,21 @@ def dump_json(self, path=None):
json_data.write(data.encode('utf-8'))
json_data.close()
- def get_introduction(self):
- path = os.path.join(self.get_path(), self.introduction)
- intro = open(path, "r")
- intro_contenu = intro.read()
- intro.close()
-
- return intro_contenu.decode('utf-8')
+ def get_introduction(self, sha=None):
+ # find hash code
+ if sha is None:
+ sha = self.sha_draft
+ repo = Repo(self.get_path())
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "introduction" in tutorial_version:
+ path_tuto = tutorial_version["introduction"]
+
+ if path_tuto:
+ return get_blob(repo.commit(sha).tree, path_tuto)
+ else:
+ return None
def get_introduction_online(self):
intro = open(
@@ -261,12 +273,21 @@ def get_introduction_online(self):
return intro_contenu.decode('utf-8')
- def get_conclusion(self):
- conclu = open(os.path.join(self.get_path(), self.conclusion), "r")
- conclu_contenu = conclu.read()
- conclu.close()
-
- return conclu_contenu.decode('utf-8')
+ def get_conclusion(self, sha=None):
+ # find hash code
+ if sha is None:
+ sha = self.sha_draft
+ repo = Repo(self.get_path())
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "introduction" in tutorial_version:
+ path_tuto = tutorial_version["conclusion"]
+
+ if path_tuto:
+ return get_blob(repo.commit(sha).tree, path_tuto)
+ else:
+ return None
def get_conclusion_online(self):
conclu = open(
@@ -522,16 +543,27 @@ def get_path(self, relative=False):
else:
return os.path.join(settings.REPO_PATH, self.tutorial.get_phy_slug(), self.get_phy_slug())
- def get_introduction(self):
- intro = open(
- os.path.join(
- self.tutorial.get_path(),
- self.introduction),
- "r")
- intro_contenu = intro.read()
- intro.close()
-
- return intro_contenu.decode('utf-8')
+ def get_introduction(self, sha=None):
+
+ tutorial = self.tutorial
+
+ # find hash code
+ if sha is None:
+ sha = tutorial.sha_draft
+ repo = Repo(tutorial.get_path())
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "parts" in tutorial_version:
+ for part in tutorial_version["parts"]:
+ if part["pk"] == self.pk:
+ path_part = part["introduction"]
+ break
+
+ if path_part:
+ return get_blob(repo.commit(sha).tree, path_part)
+ else:
+ return None
def get_introduction_online(self):
intro = open(
@@ -545,16 +577,27 @@ def get_introduction_online(self):
return intro_contenu.decode('utf-8')
- def get_conclusion(self):
- conclu = open(
- os.path.join(
- self.tutorial.get_path(),
- self.conclusion),
- "r")
- conclu_contenu = conclu.read()
- conclu.close()
-
- return conclu_contenu.decode('utf-8')
+ def get_conclusion(self, sha=None):
+
+ tutorial = self.tutorial
+
+ # find hash code
+ if sha is None:
+ sha = tutorial.sha_draft
+ repo = Repo(tutorial.get_path())
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "parts" in tutorial_version:
+ for part in tutorial_version["parts"]:
+ if part["pk"] == self.pk:
+ path_part = part["conclusion"]
+ break
+
+ if path_part:
+ return get_blob(repo.commit(sha).tree, path_part)
+ else:
+ return None
def get_conclusion_online(self):
conclu = open(
@@ -702,25 +745,34 @@ def get_path(self, relative=False):
return chapter_path
- def get_introduction(self):
- if self.introduction:
- if self.tutorial:
- path = os.path.join(
- self.tutorial.get_path(),
- self.introduction)
- else:
- path = os.path.join(
- self.part.tutorial.get_path(),
- self.introduction)
+ def get_introduction(self, sha=None):
- if os.path.isfile(path):
- intro = open(path, "r")
- intro_contenu = intro.read()
- intro.close()
-
- return intro_contenu.decode('utf-8')
- else:
- return None
+ if self.tutorial:
+ tutorial = self.tutorial
+ else:
+ tutorial = self.part.tutorial
+ repo = Repo(tutorial.get_path())
+
+ # find hash code
+ if sha is None:
+ sha = tutorial.sha_draft
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "parts" in tutorial_version:
+ for part in tutorial_version["parts"]:
+ if "chapters" in part:
+ for chapter in part["chapters"]:
+ if chapter["pk"] == self.pk:
+ path_chap = chapter["introduction"]
+ break
+ if "chapter" in tutorial_version:
+ chapter = tutorial_version["chapter"]
+ if chapter["pk"] == self.pk:
+ path_chap = chapter["introduction"]
+
+ if path_chap:
+ return get_blob(repo.commit(sha).tree, path_chap)
else:
return None
@@ -748,23 +800,34 @@ def get_introduction_online(self):
else:
return None
- def get_conclusion(self):
- if self.conclusion:
- if self.tutorial:
- path = os.path.join(self.tutorial.get_path(), self.conclusion)
- else:
- path = os.path.join(
- self.part.tutorial.get_path(),
- self.conclusion)
-
- if os.path.isfile(path):
- conclu = open(path, "r")
- conclu_contenu = conclu.read()
- conclu.close()
+ def get_conclusion(self, sha=None):
- return conclu_contenu.decode('utf-8')
- else:
- return None
+ if self.tutorial:
+ tutorial = self.tutorial
+ else:
+ tutorial = self.part.tutorial
+ repo = Repo(tutorial.get_path())
+
+ # find hash code
+ if sha is None:
+ sha = tutorial.sha_draft
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "parts" in tutorial_version:
+ for part in tutorial_version["parts"]:
+ if "chapters" in part:
+ for chapter in part["chapters"]:
+ if chapter["pk"] == self.pk:
+ path_chap = chapter["conclusion"]
+ break
+ if "chapter" in tutorial_version:
+ chapter = tutorial_version["chapter"]
+ if chapter["pk"] == self.pk:
+ path_chap = chapter["conclusion"]
+
+ if path_chap:
+ return get_blob(repo.commit(sha).tree, path_chap)
else:
return None
@@ -802,7 +865,9 @@ def update_children(self):
self.introduction = os.path.join("introduction.md")
self.conclusion = os.path.join("conclusion.md")
self.save()
+
for extract in self.get_extracts():
+ extract.text = extract.get_path(relative=True)
extract.save()
class Extract(models.Model):
@@ -884,20 +949,38 @@ def get_prod_path(self):
str(ext['pk']) + "_" + slugify(ext['title'])) \
+ '.md.html'
- def get_text(self):
+ def get_text(self, sha=None):
+
if self.chapter.tutorial:
- path = os.path.join(self.chapter.tutorial.get_path(), self.text)
+ tutorial = self.chapter.tutorial
else:
- path = os.path.join(
- self.chapter.part.tutorial.get_path(),
- self.text)
-
- if os.path.isfile(path):
- text = open(path, "r")
- text_contenu = text.read()
- text.close()
-
- return text_contenu.decode('utf-8')
+ tutorial = self.chapter.part.tutorial
+ repo = Repo(tutorial.get_path())
+
+ # find hash code
+ if sha is None:
+ sha = tutorial.sha_draft
+
+ manifest = get_blob(repo.commit(sha).tree, "manifest.json")
+ tutorial_version = json_reader.loads(manifest)
+ if "parts" in tutorial_version:
+ for part in tutorial_version["parts"]:
+ if "chapters" in part:
+ for chapter in part["chapters"]:
+ if "extracts" in chapter:
+ for extract in chapter["extracts"]:
+ if extract["pk"] == self.pk:
+ path_ext = extract["text"]
+ break
+ if "chapter" in tutorial_version:
+ chapter = tutorial_version["chapter"]
+ if "extracts" in chapter:
+ for extract in chapter["extracts"]:
+ path_ext = extract["text"]
+ break
+
+ if path_ext:
+ return get_blob(repo.commit(sha).tree, path_ext)
else:
return None
diff --git a/zds/tutorial/tests.py b/zds/tutorial/tests.py
index a909dbf77c..b54efefd4c 100644
--- a/zds/tutorial/tests.py
+++ b/zds/tutorial/tests.py
@@ -2,12 +2,13 @@
import os
import shutil
-
+import HTMLParser
from django.conf import settings
from django.core import mail
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.utils import override_settings
+from django.utils import html
from zds.member.factories import ProfileFactory, StaffProfileFactory
from zds.gallery.factories import GalleryFactory, UserGalleryFactory, ImageFactory
@@ -476,7 +477,7 @@ def test_url_for_guest(self):
def test_workflow_tuto(self):
"""Test workflow of tutorial."""
-
+
# logout before
self.client.logout()
# login with simple member
@@ -508,7 +509,7 @@ def test_workflow_tuto(self):
{
'title': u"Partie 1",
'introduction':u"Présentation",
- 'conclusion': u"Fin de la présenation",
+ 'conclusion': u"Fin de la présentation",
},
follow=False)
self.assertEqual(result.status_code, 302)
@@ -526,7 +527,7 @@ def test_workflow_tuto(self):
p1.slug]),
follow=True)
self.assertContains(response=result, text = u"Présentation")
- self.assertContains(response=result, text = u"Fin de la présenation")
+ self.assertContains(response=result, text = u"Fin de la présentation")
#add part 2
result = self.client.post(
@@ -699,6 +700,108 @@ def test_workflow_tuto(self):
follow=True)
self.assertContains(response=result, text = u"Mon premier chapitre d'une autre partie")
+ # add extract 1 of chapter 3
+ result = self.client.post(
+ reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(c3.pk),
+ {
+ 'title': u"Extrait 1",
+ 'text':"Prune",
+ },
+ follow=False)
+ self.assertEqual(result.status_code, 302)
+ self.assertEqual(Extract.objects.filter(chapter=c3).count(), 1)
+ e1 = Extract.objects.filter(chapter=c3).last()
+
+ # add extract 2 of chapter 3
+ result = self.client.post(
+ reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(c3.pk),
+ {
+ 'title': u"Extrait 2",
+ 'text':"Citron",
+ },
+ follow=False)
+ self.assertEqual(result.status_code, 302)
+ self.assertEqual(Extract.objects.filter(chapter=c3).count(), 2)
+ e2 = Extract.objects.filter(chapter=c3).last()
+
+ # add extract 3 of chapter 2
+ result = self.client.post(
+ reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(c2.pk),
+ {
+ 'title': u"Extrait 3",
+ 'text':"Kiwi",
+ },
+ follow=False)
+ self.assertEqual(result.status_code, 302)
+ self.assertEqual(Extract.objects.filter(chapter=c2).count(), 1)
+ e3 = Extract.objects.filter(chapter=c2).last()
+
+ #check content edit part
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Présentation")
+ self.assertContains(response=result, text = u"Fin de la présentation")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Analyse")
+ self.assertContains(response=result, text = "Fin de l'analyse")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Expérimentation")
+ self.assertContains(response=result, text = u"est terminé")
+
+ #check content edit chapter
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 1")
+ self.assertContains(response=result, text = u"Mon premier chapitre")
+ self.assertContains(response=result, text = u"Fin de mon premier chapitre")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 2")
+ self.assertContains(response=result, text = u"Mon deuxième chapitre")
+ self.assertContains(response=result, text = u"Fin de mon deuxième chapitre")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 2")
+ self.assertContains(response=result, text = u"Mon troisième chapitre homonyme")
+ self.assertContains(response=result, text = u"Fin de mon troisième chapitre")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c4.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 1")
+ self.assertContains(response=result, text = u"Mon premier chapitre d'une autre partie")
+
+ #check content edit extract
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 1")
+ self.assertContains(response=result, text = u"Prune")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 2")
+ self.assertContains(response=result, text = u"Citron")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 3")
+ self.assertContains(response=result, text = u"Kiwi")
+
#edit part 2
result = self.client.post(
reverse('zds.tutorial.views.edit_part') + '?partie={}'.format(p2.pk),
@@ -714,7 +817,7 @@ def test_workflow_tuto(self):
self.assertContains(response=result, text = u"Expérimentation : edition d'introduction")
self.assertContains(response=result, text = u"C'est terminé : edition de conlusion")
self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 3)
-
+
#edit chapter 3
result = self.client.post(
reverse('zds.tutorial.views.edit_chapter') + '?chapitre={}'.format(c3.pk),
@@ -731,6 +834,7 @@ def test_workflow_tuto(self):
self.assertContains(response=result, text = u"Edition de conlusion")
self.assertEqual(Chapter.objects.filter(part=p2.pk).count(), 3)
p2 = Part.objects.filter(pk=p2.pk).first()
+
#edit part 2
result = self.client.post(
reverse('zds.tutorial.views.edit_part') + '?partie={}'.format(p2.pk),
@@ -762,6 +866,85 @@ def test_workflow_tuto(self):
self.assertContains(response=result, text = u"Edition d'introduction")
self.assertContains(response=result, text = u"Edition de conlusion")
self.assertEqual(Chapter.objects.filter(part=p2.pk).count(), 3)
+
+ #edit extract 2
+ result = self.client.post(
+ reverse('zds.tutorial.views.edit_extract') + '?extrait={}'.format(e2.pk),
+ {
+ 'title': u"Extrait 2 : edition de titre",
+ 'text': u"Agrume",
+ "last_hash": compute_hash([os.path.join(e2.get_path())])
+ },
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 2 : edition de titre")
+ self.assertContains(response=result, text = u"Agrume")
+
+ #check content edit part
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Présentation")
+ self.assertContains(response=result, text = u"Fin de la présentation")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Partie 2 : seconde edition de titre")
+ self.assertContains(response=result, text = "Expérimentation : seconde edition d'introduction")
+ self.assertContains(response=result, text = "C'est terminé : seconde edition de conlusion")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_part')+"?partie={}".format(p3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Expérimentation")
+ self.assertContains(response=result, text = u"est terminé")
+
+ #check content edit chapter
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 1")
+ self.assertContains(response=result, text = u"Mon premier chapitre")
+ self.assertContains(response=result, text = u"Fin de mon premier chapitre")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 2 : edition de titre")
+ self.assertContains(response=result, text = u"Edition d'introduction")
+ self.assertContains(response=result, text = u"Edition de conlusion")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 3 : edition de titre")
+ self.assertContains(response=result, text = u"Edition d'introduction")
+ self.assertContains(response=result, text = u"Edition de conlusion")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_chapter')+"?chapitre={}".format(c4.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Chapitre 1")
+ self.assertContains(response=result, text = u"Mon premier chapitre d'une autre partie")
+
+ #check content edit extract
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e1.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 1")
+ self.assertContains(response=result, text = u"Prune")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e2.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 2 : edition de titre")
+ self.assertContains(response=result, text = u"Agrume")
+
+ result = self.client.get(
+ reverse('zds.tutorial.views.edit_extract')+"?extrait={}".format(e3.pk),
+ follow=True)
+ self.assertContains(response=result, text = u"Extrait 3")
+ self.assertContains(response=result, text = u"Kiwi")
#move chapter 1 against 2
result = self.client.post(
diff --git a/zds/tutorial/views.py b/zds/tutorial/views.py
index bb0a52d5cf..8070d47e6b 100644
--- a/zds/tutorial/views.py
+++ b/zds/tutorial/views.py
@@ -89,7 +89,13 @@ def index(request):
tutorials = Tutorial.objects.filter(
sha_public__isnull=False,
subcategory__in=[tag]).exclude(sha_public="").order_by("-pubdate").all()
- return render_template("tutorial/index.html", {"tutorials": tutorials, "tag": tag})
+
+ tuto_versions = []
+ for tutorial in tutorials:
+ mandata = tutorial.load_json_for_public()
+ mandata = tutorial.load_dic(mandata)
+ tuto_versions.append(mandata)
+ return render_template("tutorial/index.html", {"tutorials": tuto_versions, "tag": tag})
# Staff actions.
@@ -219,10 +225,6 @@ def history(request, tutorial_pk, tutorial_slug):
if not request.user.has_perm("tutorial.change_tutorial"):
raise PermissionDenied
- # Make sure the URL is well-formed
-
- if not tutorial_slug == slugify(tutorial.title):
- return redirect(tutorial.get_absolute_url())
repo = Repo(tutorial.get_path())
logs = repo.head.reference.log()
logs = sorted(logs, key=attrgetter("time"), reverse=True)
@@ -1924,6 +1926,7 @@ def edit_extract(request):
if not request.user.has_perm("tutorial.change_tutorial"):
raise PermissionDenied
+
if request.method == "POST":
data = request.POST
if content_has_changed([extract.get_path()], data["last_hash"]):
@@ -2082,20 +2085,33 @@ def find_tuto(request, pk_user):
type = request.GET["type"]
except KeyError:
type = None
- u = get_object_or_404(User, pk=pk_user)
+ display_user = get_object_or_404(User, pk=pk_user)
if type == "beta":
tutorials = Tutorial.objects.all().filter(
- authors__in=[u],
+ authors__in=[display_user],
sha_beta__isnull=False).exclude(sha_beta="").order_by("-pubdate")
+
+ tuto_versions = []
+ for tutorial in tutorials:
+ mandata = tutorial.load_json_for_public(sha=tutorial.sha_beta)
+ mandata = tutorial.load_dic(mandata)
+ tuto_versions.append(mandata)
+
return render_template("tutorial/member/beta.html",
- {"tutorials": tutorials, "usr": u})
+ {"tutorials": tuto_versions, "usr": display_user})
else:
tutorials = Tutorial.objects.all().filter(
- authors__in=[u],
+ authors__in=[display_user],
sha_public__isnull=False).exclude(sha_public="").order_by("-pubdate")
+
+ tuto_versions = []
+ for tutorial in tutorials:
+ mandata = tutorial.load_json_for_public()
+ mandata = tutorial.load_dic(mandata)
+ tuto_versions.append(mandata)
- return render_template("tutorial/member/online.html", {"tutorials": tutorials,
- "usr": u})
+ return render_template("tutorial/member/online.html", {"tutorials": tuto_versions,
+ "usr": display_user})
def upload_images(images, tutorial):
@@ -2880,7 +2896,6 @@ def MEP(tutorial, sha):
get_url_images(md_file_contenu, tutorial.get_prod_path())
# convert to out format
-
out_file = open(os.path.join(tutorial.get_prod_path(), fichier), "w")
if md_file_contenu is not None:
out_file.write(markdown_to_out(md_file_contenu.encode("utf-8")))