From 4d50f9a0f9351e21b87672711f462418f76fe881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Wed, 17 Jul 2024 13:47:40 +0200 Subject: [PATCH] Add pagination and tree structure for posts --- content/posts/ia.md | 22 +++++++ content/posts/manipuler-pdf.md | 69 ++++++++++++++++++++++ content/posts/{ => test}/19700101_hello.md | 0 content/posts/xs-compromise.md | 25 ++++++++ content/templates/jinja2/post-list.html | 35 +++++++++-- content/templates/jinja2/post.html | 4 +- jssg/models.py | 34 ++++++++--- jssg/settings.py | 1 + jssg/urls.py | 14 ++--- jssg/views.py | 2 +- 10 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 content/posts/ia.md create mode 100644 content/posts/manipuler-pdf.md rename content/posts/{ => test}/19700101_hello.md (100%) create mode 100644 content/posts/xs-compromise.md diff --git a/content/posts/ia.md b/content/posts/ia.md new file mode 100644 index 0000000..50b4668 --- /dev/null +++ b/content/posts/ia.md @@ -0,0 +1,22 @@ +--- +title L'IA 🧠 va-t-elle remplacer la recherche web classique ? +date 2024-05-20T15:12:42+00:00 +category Technologie +abstract L'intelligence artificielle est partout. Tout le monde en parle ... Cet article vous propose de découvrir un cas intéressant et très puissant. +author Damien ACCORSI +--- +{ + +} +--- + +{%markdown%} +La question se pose ... + +Quelques mots-clé : #veilletechno #googlesearch #ia #notopensource + +Cette publication n'a pas vocation a approfondir et à répondre à la question mais plutôt à partager l'existence d'une solution intéressante et qui a été présentée à l'un des suricates comme le futur remplaçant de google search. + +![Perplexity va-t-il remplacer Google Search ?](/actualites/images/800x600/image-14219ee739c6a17b76d59f1d55b73776ea8b5e0e.png) + +{%endmarkdown%} \ No newline at end of file diff --git a/content/posts/manipuler-pdf.md b/content/posts/manipuler-pdf.md new file mode 100644 index 0000000..be3f3af --- /dev/null +++ b/content/posts/manipuler-pdf.md @@ -0,0 +1,69 @@ +--- +title Quels logiciels libres pour manipuler des fichiers PDF ? +date 2024-05-03T08:43:47+00:00 +category univers du libre +abstract Manipuler des fichiers PDF est chose courante ; il existe une série de logiciels libres qui permet de procéder à la majorité des manipulations que l'on est en droit d'attendre de tels outils. +author Damien ACCORSI +--- +{ + +} +--- + +{%markdown%} +Nous sommes tous amenés, à un moment ou à un autre, dans notre vie personnelle ou professionnelle, à manipuler des PDF. + +Tout le monde connait Acrobat Reader et autres services en ligne tels que Ilovepdf. + +Mais existe-t-il des logiciels libres pour procéder aux même opérations ? Si oui quels sont ces outils ? + + +## Consulter des PDF + +**Evince** est un visionneur de documents pour GNOME. Il permet de visualiser des PDFs et de les imprimer + +## Modifier et produire des PDF + +**Libreoffice** permet d'exporter les documents que l'on rédige en PDF. + +Moins connu, **Libreoffice Draw** permet quant à lui d'ouvrir des PDF existant et d'en éditer le contenu. + +## Découper, extraire, fusionner des fichiers PDF en masse (en ligne de commande) + +PDFtk permet facilement de découper un fichier PDF via la commande `pdftk file.pdf burst` + +Il est également possible d'extraire un lot de pages `pdftk file.pdf cat 3-5 output pages-3-to-5.pdf` + +Enfin, il est possible de concaténer des fichiers PDF, exemple : `pdftk file1.pdf file2.pdf cat output file1-file2-merged.pdf` + +D'autres opérations sont possibles. + +Pour un équivalent graphique, je vous renvoie vers PDF Chain qui m'a permis, par exemple, de découvrir qu'on pouvait intégrer des pièces jointes quelconques dans un PDF. + + +![](/actualites/images/500x500/image-b0158969619b6e2215ff928a68a0cd882228d06a.png) + +## Découper, extraire, fusionner des PDFs naturellement + +Pour un usage plus grand public, je ne peux que vous conseiller de vous tourner vers PDF Arranger. + +Il permet de procéder aux même opérations que les outils précédemment cités, avec l'avantage de travailler sur des éléments visuels car l'interface intègre une prévisualisation des pages, une sélection à la souris et des menus contextuels - bref un ensemble plus intuitif pour les utilisations qui ne sont pas familiers avec la ligne de commande. + +![](/actualites/images/500x500/image-3a7f8c0e10a091e5b7d8d5ac1d454ff27f1edf6d.png) + +---- + +Voilà, vous savez désormais quoi utiliser pour : + + +- 🖨 Imprimer un document PDF +- ⤵ tourner les pages d'un document PDF +- ✂ découper un document PDF page par page +- 🖇 fusionner plusieurs documents PDF +- 🔎 extraire des sections de pages d'un document PDF + + +Vous n'avez plus aucune excuse pour diffuser des données confidentielles sur des services en ligne "gratuits" ;) + + +{%endmarkdown%} \ No newline at end of file diff --git a/content/posts/19700101_hello.md b/content/posts/test/19700101_hello.md similarity index 100% rename from content/posts/19700101_hello.md rename to content/posts/test/19700101_hello.md diff --git a/content/posts/xs-compromise.md b/content/posts/xs-compromise.md new file mode 100644 index 0000000..ce16595 --- /dev/null +++ b/content/posts/xs-compromise.md @@ -0,0 +1,25 @@ +--- +title La lib de compression Xz compromise ... +date 2024-04-03T13:13:26+00:00 +category Technologie +abstract Une porte dérobée introduite dans la lib de compression Xz a été fortuitement découverte par un développeur PostgreSQL ... +author Damien ACCORSI +--- +{ + +} +--- + +{%markdown%} +La bibliothèque partagée de compression Xz (liblzma) a été compromise par l'un de ses 2 principaux développeurs. Une porte dérobée a été introduite et fortuitement découverte par un développeur du projet PostgreSQL qui [évoque humblement sa découverte sur Mastodon](https://mastodon.social/@AndresFreundTec/112180083704606941) : « I accidentally found a security issue while benchmarking postgres changes » + +L'ingéniosité de l'attaque est de passer par un contributeur au long court et par une démarche très ingénieuse ; [Ytterbium décrit en détail l'attaque dans un long journal publié sur LinuxFR](https://linuxfr.org/users/ytterbium/journaux/xz-liblzma-compromis). + +Une fois n'est pas coutume : le problème des dépendances "invisibles" (et pour autant stratégiques) se pose ... + +![Dépendances](https://imgs.xkcd.com/comics/dependency.png) + +(source: https://xkcd.com/2347/ ) + + +{%endmarkdown%} \ No newline at end of file diff --git a/content/templates/jinja2/post-list.html b/content/templates/jinja2/post-list.html index 6d43bd5..f7256f1 100644 --- a/content/templates/jinja2/post-list.html +++ b/content/templates/jinja2/post-list.html @@ -4,9 +4,9 @@
@@ -17,8 +17,7 @@
- - +

{{ post.title }}

@@ -42,7 +41,7 @@

{{ post.title }}

Lire la suite ... @@ -57,5 +56,31 @@

{{ post.title }}

{% endfor %}
+
+{% if object.page > 1 %} + {% if object.category != "" %} + Page précédente + {% else %} + Page précédente + {% endif %} +{% endif %} +{% if object.page < object.nb_pages %} + {% if object.category != "" %} + Page suivante + {% else %} + Page suivante + {% endif %} +{% endif %} +
+
+Pages : +{% for page in range(1, object.nb_pages+1) %} + {% if object.category != "" %} + {{page}} + {% else %} + {{page}} + {% endif %} +{% endfor %} +
{% endblock %} \ No newline at end of file diff --git a/content/templates/jinja2/post.html b/content/templates/jinja2/post.html index 7ba96ce..25a1e33 100644 --- a/content/templates/jinja2/post.html +++ b/content/templates/jinja2/post.html @@ -5,5 +5,7 @@

{{ object.title }}

{{ object.content|safe }} -Tous les posts +
+Tous les posts +
{% endblock %} diff --git a/jssg/models.py b/jssg/models.py index 33f266e..f0a6450 100644 --- a/jssg/models.py +++ b/jssg/models.py @@ -27,6 +27,8 @@ from django.core.management.commands.runserver import Command as runserver +from math import ceil + class Document: """A document. @@ -302,12 +304,18 @@ class PostList : metadata = {"page_header_h1":"Posts"} category = "" - def __init__(self, category = "") -> None: + def __init__(self, category = "", page = 1) -> None: self.category = category + self.page = page + self.posts_by_page = settings.JFME_NUMBER_OF_POSTS_BY_PAGE + if self.category == "" : + self.nb_pages = ceil(len(list(Post.load_glob(all=True))) / self.posts_by_page) # number of posts / number of posts by page + else : + self.nb_pages = ceil(len(list(filter(lambda p: p.metadata["category"] == self.category, Post.load_glob(all=True)))) / self.posts_by_page) # number of posts of the category / number of posts by page @classmethod - def load_post_list_with_category(cls, category) : - return cls(category) + def load_post_list_with_category(cls, category, page) : + return cls(category, page) @property def categories(self) : @@ -315,17 +323,25 @@ def categories(self) : for post in Post.load_glob(all = True) : if post.metadata["category"] != "" : cat.add(post.metadata["category"]) - return cat + return sorted(cat) @classmethod - def get_categories(cls) : - return [{"category": category} for category in cls().categories] + def get_categories_and_pages(cls) : + t = [] + for category in cls().categories : + t += [{"category": category, "page":page} for page in range(1, cls(category).nb_pages + 1)] + return t + + + @classmethod + def get_pages(cls) : + return [{"page": page} for page in range(1, cls().nb_pages+1)] @property def posts(self) : - posts = sorted(Post.load_glob(), key=lambda p: p.timestamp, reverse=True) + posts = sorted(Post.load_glob(all=True), key=lambda p: p.timestamp, reverse=True) if self.category == "" : - return posts + return posts[self.posts_by_page*(self.page-1):self.posts_by_page*(self.page)] else : - return filter(lambda p: p.metadata["category"] == self.category, posts) + return list(filter(lambda p: p.metadata["category"] == self.category, posts))[self.posts_by_page*(self.page-1):self.posts_by_page*(self.page)] \ No newline at end of file diff --git a/jssg/settings.py b/jssg/settings.py index 71e6f44..81b75a0 100644 --- a/jssg/settings.py +++ b/jssg/settings.py @@ -52,6 +52,7 @@ JFME_POSTS_DIRS = [path / "posts" for path in JFME_CONTENT_DIRS] JFME_TEMPLATES_DIRS = [path / "templates" for path in JFME_CONTENT_DIRS] JFME_STATIC_DIRS = [path / "static" for path in JFME_CONTENT_DIRS] +JFME_NUMBER_OF_POSTS_BY_PAGE = 3 diff --git a/jssg/urls.py b/jssg/urls.py index a90da9f..736bb23 100644 --- a/jssg/urls.py +++ b/jssg/urls.py @@ -20,7 +20,7 @@ # print([p for p in Page.get_pages()]) -# print([p for p in PostList.get_categories()]) +# print([p for p in PostList.get_categories_and_pages()]) urlpatterns = [ distill_path( @@ -41,25 +41,25 @@ distill_path("atom.xml", views.PostFeedsView(), name="atom_feed"), distill_path( - "posts/", + "posts/page.html", views.PostListView.as_view(), name = "post-index", - distill_file = "posts/index.html" + distill_func = PostList.get_pages ), distill_path( - "posts/category/.html", + "posts/category//page.html", views.PostListView.as_view(), name = "post-category", - distill_func = PostList.get_categories + distill_func = PostList.get_categories_and_pages ), distill_path( - "posts/.html", + "posts/articles/.html", views.PostView.as_view(), name="post", distill_func=Post.get_posts, ), distill_path( - "posts//.html", + "posts/articles//.html", views.PostView.as_view(), name="post", distill_func=Post.get_posts, diff --git a/jssg/views.py b/jssg/views.py index 86e0766..3145513 100644 --- a/jssg/views.py +++ b/jssg/views.py @@ -87,4 +87,4 @@ def get_object(self, queryset=None) -> Model: if "category" not in self.kwargs.keys() : self.kwargs["category"] = "" print(self.kwargs["category"]) - return PostList.load_post_list_with_category(self.kwargs["category"]) \ No newline at end of file + return PostList.load_post_list_with_category(self.kwargs["category"], self.kwargs["page"]) \ No newline at end of file