<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>30 minutes par jour</title>
	<atom:link href="http://30minparjour.la-bnbox.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://30minparjour.la-bnbox.fr</link>
	<description>ou presque...</description>
	<lastBuildDate>Mon, 23 Feb 2026 12:31:50 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Four or three columns: or a technique to help with too many projects</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2026/02/23/four-or-three-columns-or-a-technique-to-help-with-too-many-projects/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2026/02/23/four-or-three-columns-or-a-technique-to-help-with-too-many-projects/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Mon, 23 Feb 2026 12:31:49 +0000</pubDate>
				<category><![CDATA[Organisation]]></category>
		<guid isPermaLink="false">https://30minparjour.la-bnbox.fr/?p=2846</guid>

					<description><![CDATA[Recently, I read this blog post from Nick Charlton: Two sides and four columns of A5: or a technique to help with too many projects (actually, I do not know him at all, I just added its blog in my RSS feed last week). I am using a similar technique to keep track of my numerous tasks and projects and &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2026/02/23/four-or-three-columns-or-a-technique-to-help-with-too-many-projects/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Recently, I read this blog post from Nick Charlton: <a href="https://nickcharlton.net/posts/two-sides-and-four-columns-of-5-a-technique-to-help-with-too-many-projects">Two sides and four columns of A5: or a technique to help with too many projects</a> (actually, I do not know him at all, I just added its blog in my RSS feed last week).</p>



<p>I am using a similar technique to keep track of my numerous tasks and projects and trying to control them. As a CTO in a SME (small and medium-sized enterprise), I am involved in <em>way too many</em> projects and discussions, and I need to keep control.</p>



<ul class="wp-block-list">
<li>I a have a A5 notebook always accessible near my keyboard</li>



<li><strong>At the beginning of each month</strong>, at the end of my notebook, I start a new page with 4 columns listing all the tasks and projects in progress
<ul class="wp-block-list">
<li><strong>Sales</strong>: listing ongoing sales opportunities and also companies or contacts I shall recontact</li>



<li><strong>Management</strong>: listing all the tasks I shall do to help others, or the company, for their specific tasks (sign this stuff, send this invoice, add X to this account, etc)</li>



<li><strong>Prod</strong>: listing all my projects, and for all the tasks at projects level</li>



<li><strong>Corporate</strong>: for all the topics I shall take care at the company level</li>
</ul>
</li>



<li>In the opposite page of the « Month page », I have a 3 columns page. This page will be used for the whole month. <strong>At the beginning of each week</strong>, I start a new section to select topics I have to finish this week. <em>The less is the better, I am very very selective with this list, I need to focus, some tasks cannot wait another week, I need to select the ones that have to be finished this week.</em>
<ul class="wp-block-list">
<li><strong>Sales</strong></li>



<li><strong>Management</strong></li>



<li><strong>Prod and Corporate</strong></li>
</ul>
</li>



<li>At the beginning of each week, at the start of my notebook, I start a new page with 4 columns. This page will be used for the whole week. <strong>At the beginning of each day</strong>, I start a new section listing all the tasks for the day. I can check when a task is done and indicates how much time I spent on it. <em>This part is important to report how much time I spent on each project or category of sales/management/corporate tasks. </em>
<ul class="wp-block-list">
<li><strong>Sales</strong></li>



<li><strong>Management</strong></li>



<li><strong>Prod and Corporate</strong></li>



<li><strong>Meeting</strong>s: listing all the appointments I have today (<em>too much, as often</em>)</li>
</ul>
</li>
</ul>



<p>I am using the « Day pages » since quite a long time. It is great. The month and week pages are new and really useful. I like them.</p>



<p>I am trying to have everything noted somewhere in these pages instead of tasks as « not read emails ». Unfortunately, I am still using a « Category » mechanism for my mailbox with Thunderbird (Important, To be done, To be followed, New contract or invoice, Meeting to schedule), but I would prefer to get rid of it as soon as I can. </p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2026/02/23/four-or-three-columns-or-a-technique-to-help-with-too-many-projects/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Le temps</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2026/01/27/le-temps/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2026/01/27/le-temps/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Tue, 27 Jan 2026 11:29:58 +0000</pubDate>
				<category><![CDATA[Pensées]]></category>
		<guid isPermaLink="false">https://30minparjour.la-bnbox.fr/?p=2840</guid>

					<description><![CDATA[De tout temps l&#8217;être humain a cherché à gagner du temps. Bien souvent grâce à la technologie sous toutes ses formes. C&#8217;est encore plus vrai aujourd&#8217;hui avec l&#8217;avènement de l&#8217;IA générative et l&#8217;usage qu&#8217;en promeut la plupart des acteurs du numérique et les marchés financiers. C&#8217;est bien connu : le temps, c&#8217;est de l&#8217;argent ! Et pourtant : l&#8217;argent ne &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2026/01/27/le-temps/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>De tout temps l&rsquo;être humain a cherché à gagner du temps. Bien souvent grâce à la technologie sous toutes ses formes. C&rsquo;est encore plus vrai aujourd&rsquo;hui avec l&rsquo;avènement de l&rsquo;IA générative et l&rsquo;usage qu&rsquo;en promeut la plupart des acteurs du numérique et les marchés financiers.</p>



<p>C&rsquo;est bien connu : <em>le temps, c&rsquo;est de l&rsquo;argent</em> !</p>



<p>Et pourtant : <em>l&rsquo;argent ne fait pas le bonheur</em>.</p>



<p>Et par ailleurs, on peut perdre de l&rsquo;argent et le retrouver ensuite. Alors que le temps&#8230; <em>lorsque du temps est perdu, on ne peut pas le retrouver, et même l&rsquo;argent ne peut le racheter</em>.</p>



<p></p>



<p>Inspiré de la lecture de <a href="https://www.24joursdeweb.fr/2025/l-illusion-de-l-immediatete-et-si-le-vrai-luxe-c-etait-la-pause">L’illusion de l’immédiateté – et si le vrai luxe, c’était la pause ?</a></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2026/01/27/le-temps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mais comment grouper des lignes d&#8217;une table MySQL selon une période de date ?</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2025/09/18/mais-comment-grouper-des-lignes-dune-table-mysql-selon-une-periode-de-date/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2025/09/18/mais-comment-grouper-des-lignes-dune-table-mysql-selon-une-periode-de-date/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Thu, 18 Sep 2025 12:32:59 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[base de données]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2826</guid>

					<description><![CDATA[Mettons que j&#8217;ai une table MySQL avec une liste de commandes datées : id, date, amount id date amount 1 2024-03-20 100 2 2024-09-03 50 3 2025-02-28 25 4 2025-05-02 25 Pour obtenir le montant total des commandes réalisé par année, je peux effectuer la requête suivante : Le YEAR(date) permet de récupérer uniquement la partie « année » de la date &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2025/09/18/mais-comment-grouper-des-lignes-dune-table-mysql-selon-une-periode-de-date/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Mettons que j&rsquo;ai une table MySQL avec une liste de commandes datées : <code>id, date, amount</code></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>id</strong></td><td><strong>date</strong></td><td><strong>amount</strong></td></tr><tr><td>1</td><td>2024-03-20</td><td>100</td></tr><tr><td>2</td><td>2024-09-03</td><td>50</td></tr><tr><td>3</td><td>2025-02-28</td><td>25</td></tr><tr><td>4</td><td>2025-05-02</td><td>25</td></tr></tbody></table></figure>



<p>Pour obtenir le montant total des commandes réalisé par année, je peux effectuer la requête suivante :</p>



<pre class="wp-block-code"><code>SELECT YEAR(date) as date_year, SUM(amount) as total
FROM mytable
GROUP BY YEAR(date)</code></pre>



<p><em>Le <code>YEAR(date)</code> permet de récupérer uniquement la partie « année » de la date en question. J&rsquo;aurai aussi pu utiliser <code>EXTRACT(YEAR FROM date)</code>.</em></p>



<p>Cela va me donner :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>date_year</strong></td><td><strong>total</strong></td></tr><tr><td>2024</td><td>150</td></tr><tr><td>2025</td><td>50</td></tr></tbody></table></figure>



<p><strong>Mais comment faire pour obtenir le total des commandes réalisé entre le 1 juillet et le 30 juin de l&rsquo;année suivante ? Bref, comment grouper selon une période de date ?</strong></p>



<span id="more-2826"></span>



<p>J&rsquo;ai l&rsquo;impression que c&rsquo;est aussi la question posée <a href="https://dba.stackexchange.com/questions/205177/group-data-by-custom-period-ranges-using-a-reference-date" data-type="link" data-id="https://dba.stackexchange.com/questions/205177/group-data-by-custom-period-ranges-using-a-reference-date">ici</a>. La méthode <code>GROUP BY</code> ne permettant que de filtrer sur un nom de colonne, et non sur une condition, ce n&rsquo;est pas simple. <code>HAVING</code> ne me sauvera pas, <code>HAVING</code> c&rsquo;est « comme » un <code>WHERE</code> mais qui s&rsquo;applique après le <code>SELECT</code> (i.e. il « connaît » les alias <code>AS</code> que l&rsquo;on a créé) et après la résolution des functions d’agrégats (i.e. il sait faire une condition sur une somme, comme illustré <a href="https://stackoverflow.com/questions/6924896/having-without-group-by" data-type="link" data-id="https://stackoverflow.com/questions/6924896/having-without-group-by">ici</a>).</p>



<p>Mais quand bien même <code>GROUP BY</code> fonctionnerait avec une condition, en y réfléchissant, je ne saurai pas tellement comment exprimer ce que je recherche comme une condition.</p>



<p><s>A vrai dire, je ne sais pas (encore) répondre à cette question. Mais en attendant, j&rsquo;ai appris quelques petites choses sur SQL (i.e. MySQL) au passage et les voici.</s></p>



<p>Bon, j&rsquo;ai envoyé cet article à ChatGPT et il a trouvé. Fichtre. Je n&rsquo;aurai pas compris sa réponse si je n&rsquo;avais pas cherché un peu au préalable. Mais quand même, c&rsquo;est me fiche un coup à chaque fois. D&rsquo;autant plus qu&rsquo;il a compris que je voulais faire un groupement par année fiscale, ce dont je n&rsquo;avais même pas parlé dans cet article ! (histoire de rire, je lui ai demandé de relire cette nouvelle version de l&rsquo;article, il me félicite le petit malin, et il a même trouvé une coquille)</p>



<p>L&rsquo;astuce ici, c&rsquo;est que dans une condition <code>CASE WHEN</code> on peut générer une nouvelle valeur. On fait donc une condition :</p>



<ul class="wp-block-list">
<li>Si le mois est supérieur au mois de janvier, alors on créé un item « année en cours »-« année en cours + 1 »</li>



<li>Sinon on créé « année en cours &#8211; 1 « -« année en cours »</li>
</ul>



<p>Et il n&rsquo;y a plus qu&rsquo;à grouper sur ce résultat. Ce qui donne, avec un petit rollup pour avoir le somme total de toutes les années :</p>



<pre class="wp-block-code"><code>SELECT 
    CASE
      WHEN MONTH(date) >= 7 THEN CONCAT(YEAR(date), '-', YEAR(date) + 1)
      ELSE CONCAT(YEAR(date) - 1, '-', YEAR(date))
    END AS date_year_fiscal,
    SUM(amount) as total
FROM mytable
GROUP BY date_year_fiscal WITH ROLLUP</code></pre>



<p>Ce qui donne bien :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>date_year_fiscal</strong></td><td><strong>total</strong></td></tr><tr><td>2023-2024</td><td>100</td></tr><tr><td>2024-2025</td><td>100</td></tr><tr><td>NULL</td><td>200</td></tr></tbody></table></figure>



<p>Et voici maintenant les astuces que j&rsquo;avais trouvé entre temps. Je n&rsquo;étais pas si loin.</p>



<h2 class="wp-block-heading">CASE WHEN</h2>



<p>Avec la fonction <code>QUARTER(date</code>) je peux récupérer le numéro du trimestre d&rsquo;une date. J&rsquo;ai découvert <code>CASE WHEN</code> qui permet d&rsquo;exprimer une condition de type switch, et donc de faire un total par semestre :</p>



<pre class="wp-block-code"><code>SELECT
   YEAR(date) as date_year
   (CASE WHEN QUARTER(date) IN (1,2) THEN 1 ELSE 2 END) as date_semester,
   SUM(amount) as total
FROM mytable
GROUP BY YEAR(date), (CASE WHEN QUARTER(date) IN (1,2) THEN 1 ELSE 2 END)</code></pre>



<p>J&rsquo;obtiens alors le résultat suivant, que je peux re-traiter en dehors de SQL pour sommer les 2 morceaux de semestre qui m&rsquo;intéresse. Ce n&rsquo;est pas l&rsquo;idéal, mais c&rsquo;est déjà pas mal.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>date_year</strong></td><td><strong>date_semester</strong></td><td><strong>total</strong></td></tr><tr><td>2024</td><td>1</td><td>100</td></tr><tr><td>2024</td><td>2</td><td>50</td></tr><tr><td>2025</td><td>1</td><td>50</td></tr></tbody></table></figure>



<p>Avec <code>CONCAT</code> on peut aussi facilement rajouter une colonne qui indique le semestre de chaque année : <code><br>   CONCAT(YEAR(date), '_', (CASE WHEN QUARTER(date) IN (1,2) THEN 1 ELSE 2 END)) as date_year_semester</code></p>



<p>Documentation et exemple d&rsquo;utilisation :</p>



<ul class="wp-block-list">
<li><a href="https://www.w3schools.com/SQL/func_mysql_case.asp">https://www.w3schools.com/SQL/func_mysql_case.asp</a></li>
</ul>



<h2 class="wp-block-heading">WITH ROLLUP</h2>



<p>En rajoutant <code>WITH ROLLUP</code> à la clause <code>GROUP BY</code>, MySQL va s&rsquo;occuper de calculer aussi la somme en groupant uniquement par la colonne <code>YEAR(date)</code>, puis la somme totale de tout le data set.</p>



<pre class="wp-block-code"><code>SELECT
   YEAR(date) as date_year
   (CASE WHEN QUARTER(date) IN (1,2) THEN 1 ELSE 2 END) as date_semester,
   SUM(amount) as total
FROM mytable
GROUP BY YEAR(date), (CASE WHEN QUARTER(date) IN (1,2) THEN 1 ELSE 2 END) WITH ROLLUP</code></pre>



<p>Ce qui donne le résultat suivant. Sympa. Ce n&rsquo;est pas ce que je voulais, mais auparavant pour avoir ce genre de résultat, je faisais un retraitement en dehors de SQL :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>date_year</strong></td><td><strong>date_semester</strong></td><td><strong>total</strong></td></tr><tr><td>2024</td><td>1</td><td>100</td></tr><tr><td>2024</td><td>2</td><td>50</td></tr><tr><td>2024</td><td>NULL</td><td>150</td></tr><tr><td>2025</td><td>1</td><td>50</td></tr><tr><td>2025</td><td>NULL</td><td>50</td></tr><tr><td>NULL</td><td>NULL</td><td>200</td></tr></tbody></table></figure>



<p>Plus d&rsquo;informations sur rollup <a href="https://www.mysqltutorial.org/mysql-basics/mysql-rollup/" data-type="link" data-id="https://www.mysqltutorial.org/mysql-basics/mysql-rollup/">ici</a> et surtout <a href="https://dev.mysql.com/doc/refman/8.4/en/group-by-modifiers.html" data-type="link" data-id="https://dev.mysql.com/doc/refman/8.4/en/group-by-modifiers.html">cette documentation de MySQL</a> qui explique comment renommer ces <code>NULL</code> disgracieux (et éviter de les confondre de vrais lignes contenant un NULL)</p>



<h2 class="wp-block-heading">Autres pistes</h2>



<ul class="wp-block-list">
<li>Une recherche sur une plage de dates avec <code>BETWEEN</code>.
<ul class="wp-block-list">
<li><a href="https://www.w3schools.com/mysql/mysql_between.asp">https://www.w3schools.com/mysql/mysql_between.asp</a></li>



<li><a href="https://stackoverflow.com/questions/6924896/having-without-group-by">https://stackoverflow.com/questions/6924896/having-without-group-by</a></li>
</ul>
</li>



<li>GROUP_CONCAT : <a href="https://dba.stackexchange.com/questions/196007/mysql-grouping-with-condition">https://dba.stackexchange.com/questions/196007/mysql-grouping-with-condition</a></li>



<li>Le <code>OVER</code> qui est non-dispo en MySQL mais pourrait servir en d&rsquo;autres circonstances
<ul class="wp-block-list">
<li><a href="https://alaburda.github.io/posts/grouping-overlapping-date-ranges.html">https://alaburda.github.io/posts/grouping-overlapping-date-ranges.html</a></li>



<li><a href="https://thelinuxcode.com/sql-group-date/">https://thelinuxcode.com/sql-group-date/</a></li>
</ul>
</li>



<li><code>GROUPING</code> : <a href="https://dev.mysql.com/blog-archive/mysql-8-0-grouping-function/">https://dev.mysql.com/blog-archive/mysql-8-0-grouping-function/</a></li>



<li>Une astuce intéressante <a href="https://stackoverflow.com/questions/18194950/mysql-query-to-group-by-date-range" data-type="link" data-id="https://stackoverflow.com/questions/18194950/mysql-query-to-group-by-date-range">ici</a> avec <code>INTERVAL</code> pour grouper par mois, mais sans commencer le 1er du mois. Mais c&rsquo;est légèrement différent de ce que je cherche à faire.</li>



<li>Une discussion intéressante <a href="https://www.developpez.net/forums/d1844244/bases-donnees/mysql/requetes/group-by-periode/" data-type="link" data-id="https://www.developpez.net/forums/d1844244/bases-donnees/mysql/requetes/group-by-periode/">ici</a>, on ne doit pas être très loin</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2025/09/18/mais-comment-grouper-des-lignes-dune-table-mysql-selon-une-periode-de-date/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Créer et exécuter des tests cases avec QTestLib</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2025/03/17/creer-executer-tests-cases-qtestlib/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2025/03/17/creer-executer-tests-cases-qtestlib/#comments</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Mon, 17 Mar 2025 16:46:24 +0000</pubDate>
				<category><![CDATA[C / C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Test]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2476</guid>

					<description><![CDATA[Après avoir soliloqué sur l&#8217;architecture de tests Qt / C++ que j&#8217;aimerai obtenir, commençons par le commencement : créer un test avec QTestLib et l&#8217;exécuter. A vrai dire, cet article traine dans mes brouillons depuis au moins 2014, mais je me suis décidé à le publier. Les liens datent un peu, mais tout reste très fonctionnel. Un mini rappel sur &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2025/03/17/creer-executer-tests-cases-qtestlib/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Après avoir soliloqué sur l&rsquo;<a title="Architecture de tests en C++ avec Qt" href="http://30minparjour.la-bnbox.fr/2014/architecture-tests-en-cpp-avec-qt">architecture de tests Qt / C++</a> que j&rsquo;aimerai obtenir, commençons par le commencement : créer un test avec <a href="https://doc.qt.io/qt-5/qtest-overview.html">QTestLib</a> et l&rsquo;exécuter. A vrai dire, cet article traine dans mes brouillons depuis au moins 2014, mais je me suis décidé à le publier. Les liens datent un peu, mais tout reste très fonctionnel.</p>



<p>Un mini rappel sur les tests unitaires :</p>



<ul class="wp-block-list">
<li><strong>Un <em>test case</em> par classe</strong> : ce <em>test case</em> testera les différentes fonctions de cette classe
<ul class="wp-block-list">
<li>dans des cas nominaux,</li>



<li>des cas d&rsquo;erreurs,</li>



<li>voire des cas limites.</li>
</ul>
</li>



<li><strong>Tester le plus petit bloc possible</strong> : si la classe à tester utilise d&rsquo;autres composants, on dit qu&rsquo;elle a des « dépendances », il faut alors « mocker » ces dépendances (si possible) ou en tout cas les maîtriser au maximum. Ce sont les <em>integration tests</em> qui testeront plusieurs blocs ensemble.</li>
</ul>



<span id="more-2476"></span>



<h3 class="wp-block-heading">Créer un test case</h3>



<p>Avec <a href="https://doc.qt.io/qt-5/qtest-overview.html">QTestLib</a>, un test case est un QObject classique. La classe de test contient plusieurs <strong>slots privés</strong> (i.e. « private slots », un slot public ne sera pas exécuté lors du passage des tests) qui seront exécutés les uns à la suite des autres. La documentation de Qt fournit aussi <a href="https://doc.qt.io/qt-5/qtest-tutorial.html">un exemple de test case</a>, mais nous en verrons d&rsquo;autres plus loin.</p>



<p>Dans chaque test, on va utiliser des <a href="https://fr.wikipedia.org/wiki/Assertion" data-type="link" data-id="https://fr.wikipedia.org/wiki/Assertion">assertions</a>, permettant de déterminer si un test est en&nbsp;<strong>Success</strong> ou <strong>Failure</strong>. On place dans l&rsquo;assertion ce que l&rsquo;on considère comme le bon comportement pour un bout de code selon le contexte donné. En enchaînant plusieurs assertions, on est censé tester un morceau code dans tous les contextes possibles.</p>



<ul class="wp-block-list">
<li><code>QVERIFY(bool assessmentExpectedTrue)</code> : « assessmentExpectedTrue » doit être vrai pour que le test soit en Success</li>



<li><code>QVERIFY2(bool assessmentExpectedTrue, char *descriptionIfItFailed)</code> : Idem mais on peut afficher un message de debug si l&rsquo;assertion est faux</li>



<li><code>QCOMPARE(actual, expected)</code> : Idem, sauf que cette fois-ci la valeur obtenue (<em>actual</em>) et attendue (<em>expected</em>) doivent être égales. L&rsquo;avantage, c&rsquo;est que ces valeurs apparaissent dans les logs si le test échoue (ce qui n&rsquo;est pas le cas avec QVERIFY) et c&rsquo;est bien pratique pour le debug ! A noter : il faut que l&rsquo;opérateur « == » et l&rsquo;opérateur <code>QDebug operator&lt;&lt;(QDebug dbg, T val)</code> soit définie pour les types complexes.</li>
</ul>



<p>En plus des slots privés qui représentent chacun un test, on peut définir au besoin 4 méthodes particulières dans le test case :</p>



<ul class="wp-block-list">
<li><strong>initTestCase (static)</strong> : exécuté au tout début du test case.</li>



<li><strong>cleanupTestCase</strong> (static) : exécuté à la toute fin du test case.</li>



<li><strong>init</strong> : exécuté avant chaque méthode de test. On parle parfois de « set up » ou « préambule ».</li>



<li><strong>cleanup</strong> : exécuté après chaque méthode de test. On parle parfois de « tear down » ou « postambule »</li>
</ul>



<p>Au niveau des bonnes pratiques, pour ma part je reprends les notations d&rsquo;autres moteurs de tests (PHPUnit et JUnit), et donc j&rsquo;aime bien :</p>



<ul class="wp-block-list">
<li>préfixer le nom des test cases par « Test ». Pour une classe <code>MyClass</code>&nbsp;→ <code>MyClassTest</code>.</li>



<li>préfixer le nom des tests (les <em>private slots</em>) par « test ». Ex : « testAdd » et « testAddWithErrors » pour tester la méthode <code>MyClass::add</code>.</li>
</ul>



<p>Voici un exemple de test case, le header et sa source :</p>



<pre class="wp-block-code"><code>&#91;cpp title="MyClassTest.h"]
#ifndef MYCLASSTEST_H
#define MYCLASSTEST_H

#include &lt;QObject&gt;<qobject>

class MyClassTest : public QObject
{
  Q_OBJECT
private slots:
  void initTestCase();
  void cleanupTestCase();
  void init();
  void cleanup();

  void testHelloThere();
};

#endif // MYCLASSTEST_H
&#91;/cpp]</qobject></code></pre>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<pre class="wp-block-code"><code>&#91;cpp title="MyClassTest.cpp"]
#include "MyClassTest.h"

#include &lt;QDebug&gt;
#include &lt;QTest&gt;

#include "MyClass.h"

void MyClassTest::initTestCase()
{
  qDebug()&lt;&lt;"Test is starting";
}

void MyClassTest::cleanupTestCase()
{
  qDebug()&lt;&lt;"Test is finished";
}

void MyClassTest::init()
{
  qDebug()&lt;&lt;"init";
}

void MyClassTest::cleanup()
{
  qDebug()&lt;&lt;"cleanup";
}

void MyClassTest::testHelloThere()
{
  MyClass myClass;
  QVERIFY("Hello!" == myClass.helloThere());
  QVERIFY2("Hello Martin!" == myClass.helloThere("Martin"), "Martin should have been saluted...");
  QCOMPARE(myClass.helloThere("Riggs"), QStringLiteral("Hello Riggs!"));
}
&#91;/cpp]</code></pre>
</div></div>



<p>Voilà qui est bien beau, mais voyons voir comment exécuter ce bout de test.</p>



<h3 class="wp-block-heading">Exécuter un test case</h3>



<p>Lancer un test case se fait relativement simple via la méthode qExec. Un petit exemple qui se contente d&rsquo;exécuter le test case « MyClassTest » et d&rsquo;afficher le résultat :</p>



<pre class="wp-block-code"><code>&#91;cpp]
#include &lt;QDebug&gt;
#include &lt;QTest&gt;

#include "MyClassTest.h"

int main(int argc, char **argv)
{
  MyClassTest testCase;
  int testCaseResult = QTest::qExec(&amp;testCase, argc, argv);
  qDebug()&lt;&lt;"MyClassTest: "&lt;&lt;(0 == testCaseResult ? "Success" : "Failure");
  return testCaseResult;
}
&#91;/cpp]</code></pre>



<p>Voici qui devrait afficher :</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>********* Start testing of MyClassTest *********</p>



<p>Config: Using QtTest library 5.3.2, Qt 5.3.2</p>



<p>QDEBUG : MyClassTest::initTestCase() Test is starting</p>



<p>PASS : MyClassTest::initTestCase()</p>



<p>QDEBUG : MyClassTest::testHelloThere() init</p>



<p>QDEBUG : MyClassTest::testHelloThere() cleanup</p>



<p>PASS : MyClassTest::testHelloThere()</p>



<p>QDEBUG : MyClassTest::cleanupTestCase() Test is finished</p>



<p>PASS : MyClassTest::cleanupTestCase()</p>



<p>Totals: 3 passed, 0 failed, 0 skipped</p>



<p>********* Finished testing of MyClassTest *********</p>



<p>MyClassTest: Success</p>
</blockquote>



<h3 class="wp-block-heading">Lancer une série de test cases</h3>



<p>Allons plus loin en se fabriquant un petit outil, un <em>test suite runner</em>, qui va lancer plusieurs <em>test cases</em> d&rsquo;un coup. Pour se faire nous allons créer une classe <code>TestRunner</code>. Chaque test case aura un log séparé, et le TesterRunner doit décrire globalement le statut de chaque test case (passed / failure), ainsi que le statut du test suite (passed / failure) c&rsquo;est-à-dire un « ET » logique sur le résultat de tous les test cases.</p>



<pre class="wp-block-code"><code>&#91;code file="TestRunner.h" language="cpp"]
#ifndef TESTRUNNER_H
#define TESTRUNNER_H

#include &lt;QHash&gt;
#include &lt;QTimer&gt;
#include &lt;QDateTime&gt;
#include &lt;QCoreApplication&gt;
#include &lt;QtTest&gt;
#include "Logger.h"

class TestRunner: public QObject
{
    Q_OBJECT

public:
    Logger logTestsResult;
    TestRunner()  : overallResult(0)
    {
        logTestsResult = Logger("TestRunner", "testsresult_", Logger::DontAddToGeneralLog);
        logTestsResult.setFolder("result");
        logTestsResult.cleanAll();
    }

    void addTest(QString testCaseName, QObject * testCase) {
        testCase-&amp;amp;gt;setParent(this);
        testCaseList.insert(testCaseName, testCase);
    }

    bool runTests() {
        int argc =0;
        char * argv&#91;] = {0};
        QCoreApplication app(argc, argv);
        QTimer::singleShot(0, this, SLOT(run()));
        app.exec();
        return overallResult == 0;
    }

private slots:
    void run() {
        // Launch
        doRunTests();
        // Log overall result
        logTestsResult.i(0 == overallResult ? "Passed" : "Failure");
        // Quit
        QApplication::instance()-&amp;amp;gt;quit();
    }

private:
    void doRunTests() {
        foreach (QString testCaseName, testCaseList.keys()) {
            QStringList outputLogfileCmd;
            outputLogfileCmd&lt;&lt;" "&lt;&lt;"-o"&lt;&lt;logTestsResult.getFolder()+testCaseName+".log";
            int testCaseResult = QTest::qExec(testCaseList.value(testCaseName), outputLogfileCmd);
            logTestsResult.i(testCaseName+": "+(0 == testCaseResult ? "Passed" : "Faillure"));
            overallResult |= testCaseResult;
        }
    }

    QHash&lt;QString, QObject *&gt; testCaseList;
    int overallResult;
};

#endif // TESTRUNNER_H

&#91;/code]</code></pre>



<pre class="wp-block-code"><code>&#91;code file="TestRunner.cpp" language="cpp"]
#include "TestRunner.h"
#include "tst_ExampleTest.h"

#include &lt;QString&gt;

int main() {
 TestRunner testRunner;
 testRunner.addTest("ExampleTest", new ExampleTest());
 testRunner.runTests();
 return 0;
}
&#91;/code]</code></pre>



<pre class="wp-block-code"><code>&#91;code file="tst_ExampleTest.h" language="cpp"]
#ifndef TST_EXAMPLETEST_H
#define TST_EXAMPLETEST_H

#include &lt;QtCore/QString&gt;
#include &lt;QtTest/QtTest&gt;

class ExampleTest: public QObject
{
    Q_OBJECT

public:
    ExampleTest(bool debugMode=false);

private Q_SLOTS:
    void initTestCase();
    void cleanupTestCase();

    void testEx1();

};

#endif // TST_EXAMPLETEST_H
&#91;/code]</code></pre>



<pre class="wp-block-code"><code>&#91;code file="tst_ExampleTest.cpp" language="cpp"]
#include "tst_ExampleTest.h"

ExampleTest::ExampleTest()
{
}

void ExampleTest::initTestCase()
{
}

void ExampleTest::cleanupTestCase()
{
}

void ExampleTest::testEx1()
{
    QVERIFY2(true, "Should be true");
}
&#91;/code]</code></pre>



<h3 class="wp-block-heading">L’environnement de tests de mes rêves</h3>



<p>Voici ma liste personnelle du <em>test suite runner</em> de mes rêves en C++/Qt :</p>



<ul class="wp-block-list">
<li>Pas de TestRunner à créer, juste des classes de tests (héritant d&rsquo;un type spécifique, ou au pire s&rsquo;inscrivant quelque part)</li>



<li>Lancement des tests unitaires au choix lors de la compilation (grâce à une config ou un define)</li>



<li>Résultat des tests (par test case et résultat global) dans des fichiers de logs, et/ou au choix dans stdout (coloré dans ce cas). En utilisant exclusivement qDebug bien sûr, ou stdout, pour ne pas inclure de bibliothèque supplémentaire.</li>



<li>Fonction de setup/teardown par test case, et avant chaque test</li>



<li>Supporter les fixtures (les quoi ? cf l&rsquo;excellent article <a href="http://marcoarena.wordpress.com/2012/06/23/increase-your-qtest-productivity/" data-type="link" data-id="http://marcoarena.wordpress.com/2012/06/23/increase-your-qtest-productivity/">Increase your QTest productivity</a>)</li>



<li>Tester les signaux / slots Qt avec <a href="https://doc.qt.io/qt-5/qsignalspy.html">QSignalSpy</a> (outil indispensable pour les tests unitaires Qt !)</li>



<li>Ajouter une librairie pour gérer facilement les stub / mock</li>
</ul>



<p>La bonne nouvelle c&rsquo;est que j&rsquo;ai partiellement atteint ce rêve (ohoh) avec un jeu de classes <code>TestRunner</code> et <code>IUnitTest</code>, empaqueté dans un package <a href="https://github.com/Fylhan/qompoter" data-type="link" data-id="https://github.com/Fylhan/qompoter">Qompoter</a> appelé <code>autotest</code> pour l&rsquo;utiliser facilement. C&rsquo;est ce que l&rsquo;on va voir au prochain épisode <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Plus d&rsquo;informations</h3>



<ul class="wp-block-list">
<li><a href="http://marcoarena.wordpress.com/2012/06/23/increase-your-qtest-productivity/">Increase your QTest productivity</a> &#8211; soulève le problème du TestRunner QtTestLib classique, et propose une solution !</li>



<li><a href="http://qtcreator.blogspot.fr/2009/10/running-multiple-unit-tests.html">Running multiple unit test</a> &#8211; Idem, le TestRunner utilisé généralement pour QTestLib doit être modifié à chaque ajout d&rsquo;un test case. Encore une autre solution est proposée.</li>



<li><a href="http://stackoverflow.com/questions/1524390/what-unit-testing-framework-should-i-use-for-qt">Stack Over flow : What unit testing framework should I use for Qt?</a> &#8211; aborde le sujet du test runner avec QTestLib</li>



<li><a href="http://stackoverflow.com/questions/8355979/how-to-redirect-valgrinds-output-to-a-file">How to redirect Valgrinds output to a file?</a> &#8211; Rediriger output dans un fichier</li>



<li><a href="http://pysnippet.blogspot.fr/2010/04/unit-testing-with-qt.html">QTestLib &#8211; Unit testing with Qt</a></li>



<li><a href="https://doc.qt.io/qt-5/qtest-tutorial.html">QTestlib Tutorial</a></li>



<li><a href="https://doc.qt.io/qt-5/qtest-overview.html">QTestlib User Manual</a></li>



<li><a href="http://harmattan-dev.nokia.com/docs/library/html/qt4/qtest.html">L&rsquo;intéressante doc de QTest</a> et <a href="http://harmattan-dev.nokia.com/docs/library/html/qt4/qtestlib-manual.html#qtestlib">QTestLib Manual</a> version Qt 4.7, mais étrangement, cela a l&rsquo;air plus complet par rapport à la précédente&#8230; est-ce une illusion ?</li>



<li><a href="http://qt-project.org/wiki/Writing_Unit_Tests">Some principles to write Unit tests</a></li>



<li><a href="http://techbase.kde.org/Development/Tutorials/Unittests#About_Unit_Testing">About Unit Testing</a>. Tout un tas d&rsquo;exemple avec QtTestLib.</li>



<li>Comment faire apparaître <a href="http://dragly.org/2013/04/19/setting-up-unittest-with-qt-creator/">les résultats de vos tests (UnitTest++) directement dans l&rsquo;interface de QtCreator.</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2025/03/17/creer-executer-tests-cases-qtestlib/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Tips to dig into git log</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2023/12/08/tips-to-dig-into-git-log/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2023/12/08/tips-to-dig-into-git-log/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Fri, 08 Dec 2023 09:37:44 +0000</pubDate>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Ligne de commande]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2808</guid>

					<description><![CDATA[Recently, I had to check the changes made on a specific line of a source file. I started digging into 7 years of commits... and obviously it was time to search for a better option :-)

Fortunately, git log is really powerful. <a href="http://30minparjour.la-bnbox.fr/blog/2023/12/08/tips-to-dig-into-git-log/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>I am a regular user of <code>git dag</code> &lt;sourcefilepath> to check all commits applying on a single source file. You can also do it with <code>gitk &lt;sourcefile></code> but I always find <code>git dag</code> more convenient.</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="664" height="638" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2023/12/image-1.png" alt="" class="wp-image-2810" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2023/12/image-1.png 664w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2023/12/image-1-300x288.png 300w" sizes="(max-width: 664px) 100vw, 664px" /><figcaption class="wp-element-caption">git dag interface</figcaption></figure>



<p>Recently, I had to check the <strong>changes made on a specific line</strong> of a source file. I started digging into 7 years of commits&#8230; and obviously it was time to search for a better option <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Fortunately, <code>git log</code> is really powerful.</p>



<p>First you can list commits with an impact on a specific function using the -L option. The diff are display immediately which is pretty handy. For example: <code>git log -L:sendTcpRequest:src/evcc/Evcc.cpp</code>. The <code>-L</code> option be used for numerous other stuff, please check <code>git log --help</code>.</p>



<p>This was still listing dozen of diff. The <code>-G</code> option allows to directly search on all the diffs and list related commit. For example <code>git log -G "flush" Evcc.cpp</code> was listing me 3 commits with a diff containing the word « flush ». </p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2023/12/08/tips-to-dig-into-git-log/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Plus de folie avec les QThread</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2022/12/07/plus-de-folie-avec-les-qthread/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2022/12/07/plus-de-folie-avec-les-qthread/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Wed, 07 Dec 2022 09:14:28 +0000</pubDate>
				<category><![CDATA[C / C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Thread]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=1715</guid>

					<description><![CDATA[La programmation avec des threads est complexe et ne doit jamais être prise à la légère. Tête froide, mutex et variables atomiques sont de rigueur si on veut s&#8217;éviter les affres de l&#8217;horreur. Qt peut nous simplifier la vie. Il peut nous y aider en tout cas. Mais. Oui il y a un mais. En regardant la documentation disponible sur &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2022/12/07/plus-de-folie-avec-les-qthread/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>La programmation avec des threads est complexe et ne doit jamais être prise à la légère. Tête froide, mutex et variables atomiques sont de rigueur si on veut s&rsquo;éviter les affres de l&rsquo;horreur.</p>
<p>Qt peut nous simplifier la vie. Il peut nous y aider en tout cas. Mais. Oui il y a un mais. En regardant la documentation disponible sur Internet, c&rsquo;est le bazar car : il y a bien longtemps, entre Qt 4.4 et Qt 4.7, on utilisait les mêmes noms de méthodes (<code>run</code>) pour quelque chose de différent ! Du coup, même aujourd&rsquo;hui on trouve de tout sur le Web.</p>
<p>Voici quelques conseils en vrac avant de pointer vers de la documentation intéressante.</p>
<h1>Conseils en vrac</h1>
<ul>
<li>Si cela ne vous parle pas, allez regarder les définitions de thread-safe et re-entrant. En fait, renseignez-vous sur les threads avant d&rsquo;utiliser les QThreads, vous gagnerez du temps.</li>
<li>Un QObject appartient au thread dans lequel il est créé, ou dans lequel il est déplacé (mais dans ce cas, il ne peut avoir de parents)
<ul>
<li>Corolaire : les enfants d&rsquo;un QObject vivent dans le même thread que leur parent. Mais attention, les variables membres ne deviennent pas automatiquement enfant de leur QObject ! (bigre)</li>
</ul>
</li>
<li>Si la notion de QEventLoop Qt ne vous parle pas, renseignez-vous !</li>
<li>De manière assez logique, on peut appeler tranquillement un QObject via plusieurs thread, donc la même fonction d&rsquo;une même classe peut être appelée par différents threads. En général on évite. Pour faire de la communication inter-thread, le plus safe est d&rsquo;utiliser les signaux / slots en mode QueueConnection (mode par défaut dans ce cas). Si le thread A émet un signal <em>variableChanged(int)</em>, ce signal peut être catché par une classe dans le thread principal via un slot <em>handleVariableChanged(int). </em>Voir <a href="http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum">QueuedConnection</a></li>
<li>En fait, si on ne fait pas gaffe, notamment si on n&rsquo;utilise pas les signaux / slots, ou si on utilise le mode DirectConnection, on peut sans se rendre compte avoir plusieurs threads qui modifient en même temps la même donnée. Le mécanisme de protection de base, c&rsquo;est les mutex (QMutexLocker et QMutex sont vos amis). Mais on peut aussi jouer avec les variables atomiques. Plus difficile, pas toujours possible, mais indispensable si on veut éviter de manière fiable les interlocks.</li>
<li>Pour utiliser les signaux / slots entre thread, il faut au préalable s&rsquo;assurer que les paramètres des signaux soient bien enregistrés avec <em>Q_DECLARE_METATYPE(Type)</em> et <em>qRegisterMetaType&lt;Type&gt;()</em>. Sans cela, en QueuedConnection le slot ne serait juste pas appelé (dommage, try again).</li>
<li>D&rsquo;une manière générale, je préconise d&rsquo;utiliser <a href="http://qt-project.org/doc/qt-5/qtconcurrentmap.html">QConcurrent</a> et <a href="http://qt-project.org/doc/qt-4.8/qfuturewatcher.html">QFutureWatcher</a> qui encapsule le comportement des QThreads. C&rsquo;est mieux, plus simple et presque toujours possible. Je ne suis pas le seul à le préconiser, c&rsquo;est la doc Qt qui le dit.</li>
<li>Si on doit utiliser directement QThread, alors la lecture de la doc Qt et des articles de Maya et FabienPN est fortement encourager.</li>
</ul>
<p><span id="more-1715"></span></p>
<h1>La documentation Qt</h1>
<ul>
<li><a href="https://doc.qt.io/qt-5/qthread.html">Classe QThread</a></li>
<li><a href="https://doc.qt.io/qt-5/thread-basics.html">Les principes de base des threads</a></li>
<li><a href="https://doc.qt.io/qt-5/threads-technologies.html">Qt et le multithreading</a></li>
<li><a href="https://doc.qt.io/qt-5/threads-qobject.html">Les principes des threads avec QObject</a></li>
</ul>
<h1>Des articles intéressants sur le Web</h1>
<ul>
<li>Le mieux et le plus éclairant : http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
<ul>
<li>L&rsquo;auteure a posté son article sur le Wiki Qt, la discussion (assez intéressante, notamment un paragraphe primordial sur les enfants des QObjects qui sont moveToThread avec leur parent, ou presque) est ici : http://qt-project.org/forums/viewthread/14806/P15</li>
</ul>
</li>
<li>Deux bons articles récapitulatifs des différentes solutions : http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/, http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-2/ (avec exemples à la clé !)
<ul>
<li>Il parle de l&rsquo;article instigateur de la solution et du problème : http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/</li>
</ul>
</li>
<li>Explications et exemples : http://fabienpn.wordpress.com/2013/05/01/qt-thread-simple-and-stable-with-sources/, http://fabienpn.wordpress.com/2013/08/16/qt-thread-multiple-methods-with-sources/</li>
<li>Autres
<ul>
<li>http://www.christeck.de/wp/2010/10/23/the-great-qthread-mess/</li>
<li>http://blog.mathieu-leplatre.info/le-piege-des-qthread-fr.html</li>
<li>http://ilearnstuff.blogspot.fr/2012/09/qthread-best-practices-when-qthread.html</li>
<li>http://codethis.wordpress.com/2011/04/04/using-qthread-without-subclassing/</li>
</ul>
</li>
<li>Quelques exemples de code : https://gitorious.org/qthreadhowto/qthreadhowto/source/e7a681970a260cb733c142350d5311698303e879</li>
</ul>
<p>Have fun!</p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2022/12/07/plus-de-folie-avec-les-qthread/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>X11, SDDM, Kwin et Plasma desktop</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2021/10/21/x11-sddm-kwin-et-plasma-desktop/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2021/10/21/x11-sddm-kwin-et-plasma-desktop/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Thu, 21 Oct 2021 12:14:03 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2796</guid>

					<description><![CDATA[Cinq mois après mes mésaventures suites à une mise à jour Debian/KDE testing, rebelote, j&#8217;ai à nouveau un problème suite à une mise à jour classique. Ce qui n&#8217;est pas si étonnant quand on utilise testing, surtout que testing a switché assez récemment sur bookworm. Les symptômes très classiques : la page de login s&#8217;affiche, je m&#8217;authentifie, la page de &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2021/10/21/x11-sddm-kwin-et-plasma-desktop/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Cinq mois après mes mésaventures suites à une mise à jour Debian/KDE testing, rebelote, j&rsquo;ai à nouveau un problème suite à une mise à jour classique. Ce qui n&rsquo;est pas si étonnant quand on utilise testing, surtout que testing a switché assez récemment sur bookworm.</p>



<p>Les symptômes très classiques : la page de login s&rsquo;affiche, je m&rsquo;authentifie, la page de chargement de Plasma KDE s&rsquo;affiche, le loader tourne puis s&rsquo;arrête au bout de quelques secondes et&#8230; voilà ! J&rsquo;ai la souris, mais pour le reste c&rsquo;est figé sur l&rsquo;écran de chargement.</p>



<p>J&rsquo;ai fini par trouver quel était le problème (incompatibilité temporaire entre kwin et kdecorator), mais voici les étapes par lesquels j&rsquo;ai dû passer, pour finalement trouver la réponse sur un rapport de bug dans une mailing list Debian. J&rsquo;en sais désormais d&rsquo;avantage sur SDDM, X11, Kwin et le montage du bureau.</p>



<p>Au delà de l&rsquo;analyse de sa machine, le bon réflexe à avoir c&rsquo;est de regarder la liste des bugs en cours sur Debian : le <a href="https://www.debian.org/Bugs/" data-type="URL" data-id="https://www.debian.org/Bugs/">portail des bugs</a> et son <a href="https://udd.debian.org/bugs/" data-type="URL" data-id="https://udd.debian.org/bugs/">moteur de recherche</a>.</p>



<span id="more-2796"></span>



<h2 class="wp-block-heading">SDDM</h2>



<p>Sur la plupart des distributions récentes, tout démarre avec SDDM (Simple Destkop Display Manager).</p>



<p>SDDM permet d&rsquo;afficher le formulaire de login. J&rsquo;ai l&rsquo;impression que SDDM démarre son propre petit serveur X11pour cela (Xsetup ?). Ensuite SDDM effectue l&rsquo;authentification avec PAM puis lance le desktop sélectionné, dans mon cas Plasma avec <code>/usr/bin/startplasma-x11.</code> Tout cela est confiruable dans le fichier <code>/etc/sddm.conf</code>. Moi je chiffre aussi mon dossier user avec encryptfs et je vois que ce dernier récupère mon mot de passe utilisateur à ce moment là pour pouvoir déchiffrer mon dossier dès le démarrage de &#8230; Kwin? Plasma? &#8230; bref, dès le démarrage.</p>



<p>Quelques erreurs possibles à ce niveau :</p>



<ul class="wp-block-list"><li>La <a href="https://wiki.archlinux.org/title/SDDM_(Fran%C3%A7ais)" data-type="URL" data-id="https://wiki.archlinux.org/title/SDDM_(Fran%C3%A7ais)">doc de SDDM</a> explique : « En cas de blocage après la connexion, supprimer ~/.Xauthory et redémarrer ». Pas mieux chez moi.</li><li>Si le disque est plein, on est aussi souvent bloqué à cette étape du login. Il suffit d&rsquo;aller en console avec <kbd>Ctrl+Alt+F2</kbd> (par ex) et de supprimer 2-3 babioles.</li><li>J&rsquo;ai un collègue qui avait une partition /root trop petite. A chaque mise à jour du noyau, il avait une mise à jour qui échouait et se retrouver avec un Linux en vrac. Par exemple son SDDM ne parvenait plus à détecter aucun bureau. Il a fallu réinstaller <code>task-kde-deskto</code> avec <code>sudo apt install task-kde-desktop</code>.</li></ul>



<h2 class="wp-block-heading">Kwin et Plasma</h2>



<p>Grosso modo, la procédure que j&rsquo;ai détaillé dans <a href="http://30minparjour.la-bnbox.fr/blog/2021/05/03/astuces-en-cas-de-pepin-avec-kde-plasma/" data-type="post" data-id="2760">cet article de Mai</a> explique bien les problèmes de config pouvant arriver suite à une mauvaise configuration du bureau (ou un bug lors d&rsquo;une mise à jour) et comment les corriger.</p>



<p>Si cela ne suffit pas, on peut être plus bourrin, et faire la manip suivante (après avoir fait des backup) :</p>



<ul class="wp-block-list"><li>Supprimer .config/kwinrc, .config/plasmarc, .config/plasmashellrc et .config/plasma-org.kde.plasma.desktop-appletsrc</li><li>Supprimer les paquets kwin-x11 et plasma-desktop avec <code>apt purge kwin-x11 plasma-desktop</code></li><li>Réinstaller ces paquets avec <code>apt install kwin-x11 plasma-desktop</code></li></ul>



<p>Chez moi, cela ne pas suffit. L&rsquo;erreur ne viendrait donc pas de la configuration de Kwin ou de Plasma. Je soupçonne une erreur quelque part entre kwin et Plasma, car le fichier kwinrc est bien recréé mais pas le fichier plasmarc.</p>



<p>Alors il faut regarder l&rsquo;état de ces paquets dans les repository Debian :</p>



<ul class="wp-block-list"><li>Côté kwin,<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=974135" data-type="URL" data-id="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=974135"> il y a eu une erreur corrigée à partir de la version 5.19</a>. Mais je suis à la version 5.21.5-2.</li><li>Ah et côté kwin toujours, quand on est sûr Debian/KDE testing (i.e. bookworm)(so 2021 :D) et qu&rsquo;on a fait une mise à jour autour de 17 octobre (je l&rsquo;ai faites hier le 20), <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996761" data-type="URL" data-id="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996761">il y a une incompatibilité entre kwin et kdecoration</a> ! C&rsquo;est en regarde le fichier de log <code>~/.xsessions-errors</code> que j&rsquo;aurai pu voir tout seul ce problème. En attendant que kwin soit corrigé, on peut temporairement downgrade kdecoration en le téléchargeant <a href="https://snapshot.debian.org/archive/debian/20210817T204926Z/pool/main/k/kdecoration/libkdecorations2-5v5_5.21.5-2_amd64.deb" data-type="URL" data-id="https://snapshot.debian.org/archive/debian/20210817T204926Z/pool/main/k/kdecoration/libkdecorations2-5v5_5.21.5-2_amd64.deb">ici</a> et en faisant :<code> dpkg -i libkdecorations2-5v5_5.21.5-2_amd64.deb</code>. Debian nous indiquera sans cesse des mises à jour, mais il vaut mieux attendre que le fix soit disponible. apt nous indiquera de faire un <code>apt install --fix-broken</code> pour supprimer le downgrade et revienne sur la version de la distribution.</li></ul>



<h2 class="wp-block-heading">Logs d&rsquo;erreur</h2>



<p>D&rsquo;abord il faut commencer par regarder la commande <code>dmesg</code> (plutôt pour des problèmes lors du boot) et les syslogs avec <code>less /var/log/syslog</code> (pour des problèmes system). Si on soupçonne quelque chose autour de X11 ou Kwin, alors <code>~/.xsessions-errors</code> semble être le bon point d&rsquo;entrée.</p>



<p>On peut aussi afficher toutes les erreurs des services systemd qui tournent avec <code>journalctl -r -p err</code>. Bien pratique.</p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2021/10/21/x11-sddm-kwin-et-plasma-desktop/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Copier / coller un tableau HTML</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2021/08/19/copier-coller-un-tableau-html/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2021/08/19/copier-coller-un-tableau-html/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Thu, 19 Aug 2021 12:15:56 +0000</pubDate>
				<category><![CDATA[HTML et CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2768</guid>

					<description><![CDATA[Il existe une astuce pour copier / coller un tableau HTML d&#8217;un navigateur vers un fichier Excel (par exemple). De base, si je sélectionne un tableau avec ma souris, la sélection s&#8217;effectue ligne par ligne. Pratique pour copier un tableau entier. Mais embêtant lorsque l&#8217;on ne souhaite copier que quelques colonnes comme c&#8217;est mon cas ici. Dans ce cas, pendant &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2021/08/19/copier-coller-un-tableau-html/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Il existe une astuce pour copier / coller un tableau HTML d&rsquo;un navigateur vers un fichier Excel (par exemple).</p>



<p>De base, si je sélectionne un tableau avec ma souris, la sélection s&rsquo;effectue ligne par ligne.</p>



<div class="wp-block-image"><figure class="alignleft size-full is-resized"><img decoding="async" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image.png" alt="" class="wp-image-2769" width="372" height="196" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image.png 743w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image-300x158.png 300w" sizes="(max-width: 372px) 100vw, 372px" /></figure></div>



<p>Pratique pour copier un tableau entier. Mais embêtant lorsque l&rsquo;on ne souhaite copier que quelques colonnes comme c&rsquo;est mon cas ici.</p>



<p>Dans ce cas, pendant la sélection, il faut appuyer sur la touche <kbd>Ctrl</kbd>. On obtient alors une sélection par colonne.</p>



<span id="more-2768"></span>



<div class="wp-block-image"><figure class="alignleft size-full is-resized"><img decoding="async" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image-1.png" alt="" class="wp-image-2770" width="372" height="196" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image-1.png 743w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2021/08/image-1-300x158.png 300w" sizes="(max-width: 372px) 100vw, 372px" /></figure></div>



<p>Voilà qui peut être utile !</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2021/08/19/copier-coller-un-tableau-html/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Akonadi pour 15 go</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2021/06/03/akonadi-pour-15-go/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2021/06/03/akonadi-pour-15-go/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Thu, 03 Jun 2021 14:46:10 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2764</guid>

					<description><![CDATA[Sur ma Debian KDE bulleyes, j&#8217;ai récemment remarqué qu&#8217;Akonadi utilisait plus de 15 go d&#8217;espace disque ! Akonadi, c&#8217;est ce mécanisme de base de données partagées que peuvent utiliser les applications Linux pour faciliter l&#8217;accès aux données de l’utilisateur : email, agenda, rappels, etc. C&#8217;est principalement utilisé par de plus en plus d&#8217;applications KDE comme KMail, KOrganizer, etc. Pourtant, il &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2021/06/03/akonadi-pour-15-go/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Sur ma Debian KDE bulleyes, j&rsquo;ai récemment remarqué qu&rsquo;<a href="https://userbase.kde.org/Akonadi/fr" data-type="URL" data-id="https://userbase.kde.org/Akonadi/fr">Akonadi</a> utilisait plus de 15 go d&rsquo;espace disque ! Akonadi, c&rsquo;est ce mécanisme de base de données partagées que peuvent utiliser les applications Linux pour faciliter l&rsquo;accès aux données de l’utilisateur : email, agenda, rappels, etc. C&rsquo;est principalement utilisé par de plus en plus d&rsquo;applications KDE comme KMail, KOrganizer, etc. </p>



<p>Pourtant, il ne me semble pas utiliser particulièrement ces applications&#8230; J&rsquo;utilise Thunderbird et je m&rsquo;en porte très bien ! Akonadi est normalement coupé par défaut, et activé dès qu&rsquo;une application le nécessite. Il semblerait que l&rsquo;horloge KDE puisse l&rsquo;activer (eh oui, elle peut afficher un agenda), mais à part ça, mystère.</p>



<p>Mon hypothèse c&rsquo;est que j&rsquo;ai dû tester un jour KMail, puis le désinstaller, et Akonadi s&rsquo;est ainsi retrouvée avec 15 go d&#8217;emails dans sa base de données.</p>



<p>J&rsquo;ai cherché, et je n&rsquo;ai pas trouvé comment savoir si ces données étaient vraiment utiliser, ni comment purger. Alors j&rsquo;ai suivi les conseils de ce <a href="https://forum.kde.org/viewtopic.php?t=122797" data-type="URL" data-id="https://forum.kde.org/viewtopic.php?t=122797">thread KDE</a> : couper Akonadi, tout supprimer, relancer Akonadi. Oui.</p>



<span id="more-2764"></span>



<p>On coupe Akonadi avec <code>akonadictl stop</code>.</p>



<p>Puis on supprime <code>~/.local/share/akonadi</code>, <code>~/.config/akonadi</code> et <code>~/.kde/share/config/akonadi*</code>.</p>



<p>Ensuite on redémarre Akonadi et on lance un refresh de la base.</p>



<pre class="wp-block-preformatted">akonadictl stop
akonadictl <code>fsck</code> # it takes time...</pre>



<p>Dans mon cas, cela a généré plein d&rsquo;erreurs. Akonadi voyait dans sa base de données les fichiers que j&rsquo;avais supprimé, mais ne les retrouvais plus. Il a tout mis dans <code>~/.local/share/akonadi/file_lost+found</code>.</p>



<p>Et depuis, ça roule !</p>



<p>A vos risques et périls !</p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2021/06/03/akonadi-pour-15-go/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Astuces en cas de pépin avec KDE Plasma</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2021/05/03/astuces-en-cas-de-pepin-avec-kde-plasma/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2021/05/03/astuces-en-cas-de-pepin-avec-kde-plasma/#comments</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Mon, 03 May 2021 10:06:47 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2760</guid>

					<description><![CDATA[Plasma crashe au boot à cause d&#8217;EventCalendar Pour ceux qui sont sous Debian Testing Bulleyes (so 2020), si jamais vous avez le même problème que moi (j&#8217;ai juste ouvert mon ordi pour rien d&#8217;important, et pof écran noir, juste la souris, même après le reboot, bref galère) : Je ne sais pas qui est la cause de quoi, mais il &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2021/05/03/astuces-en-cas-de-pepin-avec-kde-plasma/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Plasma crashe au boot à cause d&rsquo;EventCalendar</h2>



<p>Pour ceux qui sont sous Debian Testing Bulleyes (so 2020), si jamais vous avez le même problème que moi (j&rsquo;ai juste ouvert mon ordi pour rien d&rsquo;important, et pof écran noir, juste la souris, même après le reboot, bref galère) :</p>



<p>Je ne sais pas qui est la cause de quoi, mais il s&rsquo;avère que le plugin qui affiche l&rsquo;heure EventCalendar s&rsquo;est aussi mis à crasher et le résultat c&rsquo;est que Plasma crash au démarrage et affiche un écran noir. Le plus simple c&rsquo;est de sauvegarder puis supprimer `<code>.config/plasma-org.kde.plasma.desktop-appletsrc</code>` puis de reboot (Donc `<code>Alt+F2</code>` pour afficher un terminal, ou bien `<code>Ctrl+Alt+F2</code>`). ça recréera une config par défaut. J&rsquo;ai pu comparer les 2, faire des tests, détecter le pb d&rsquo;affichage de l&rsquo;heure par hasard, et du coup remettre ma config d&rsquo;origine corrigée.<br>Plasma s&rsquo;affichait bien, mais pas le décorateur de fenêtre (pas possible de déplacer, fermer des fenêtres, alt+tab marchait pas).</p>



<p>EventCalendar est toujours planté aujourd&rsquo;hui, donc je ne l&rsquo;utilise plus. Lorsque j&rsquo;ai eu ce problème, j&rsquo;avais probablement un double bug EventCalendar + kwin. C&rsquo;est peut-être dû à la dernière mise à jour que j&rsquo;ai faite, soit ça a cassé mon kwin (le « window decorator »), soit ça a introduit un bug dans kwin. Bref, dans la soirée une nouvelle version de kwin est apparu et cela a réglé le souci. J&rsquo;ai cherché à savoir si c&rsquo;était ma config ou un bug, mais je n&rsquo;ai pas trouvé.</p>



<p>Au moins, je sais maintenant où trouver la config de Plasma, et je sais ce qu&rsquo;est un window decorator <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Redémarrage live de Plasma</h2>



<p>La commande pour redémarrer plasma c&rsquo;est : `<code>killall plasmasheel</code>` (pour tuer l&rsquo;ancien) puis tout simplement `<code>plasmashell &amp;</code>`.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2021/05/03/astuces-en-cas-de-pepin-avec-kde-plasma/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>libpicoipp installation error</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2021/03/30/libpicoipp-installation-error/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2021/03/30/libpicoipp-installation-error/#comments</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Tue, 30 Mar 2021 12:32:03 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Ligne de commande]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2756</guid>

					<description><![CDATA[Sur mon Debian bulleyes (encore « testing » pour l&#8217;instant, mais plus pour longtemps), je me suis récemment retrouvé avec une erreur étrange lors de la mise à jour de mon système : Et en faisant un apt --fix-broken install je n&#8217;obtenais pas beaucoup mieux, mais au moins j&#8217;ai trouvé de l&#8217;info : Où se situe le problème ? Très visiblement, le &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2021/03/30/libpicoipp-installation-error/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Sur mon Debian bulleyes (encore « testing » pour l&rsquo;instant, mais plus pour longtemps), je me suis récemment retrouvé avec une erreur étrange lors de la mise à jour de mon système :</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ sudo apt upgrade                                                                                                                  
Lecture des listes de paquets... Fait                                                                                               
Construction de l&#039;arbre des dépendances                                                                                             
Lecture des informations d&#039;état... Fait                                                                                             
Vous pouvez lancer « apt --fix-broken install » pour corriger ces problèmes.                                                        
Les paquets suivants contiennent des dépendances non satisfaites :                                                                  
 libps2000a : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                       
 libps3000a : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                       
 libps4000 : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                        
 libps4000a : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                       
 libps5000a : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                       
 libps6000 : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                        
 libps6000a : Dépend: libpicoipp (&gt;= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                       
 picoscope : Dépend: libpicoipp (= 1.3.0-4r78) mais 1.3.0-4r29 est installé                                                         
E: Dépendances non satisfaites. Essayez « apt --fix-broken install » sans paquet                                                    
   (ou indiquez une solution).
</pre></div>


<span id="more-2756"></span>



<p>Et en faisant un <code>apt --fix-broken install</code> je n&rsquo;obtenais pas beaucoup mieux, mais au moins j&rsquo;ai trouvé de l&rsquo;info :</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ sudo apt --fix-broken install                                                                                                     
Lecture des listes de paquets... Fait                                                                                               
Construction de l&#039;arbre des dépendances                                                                                             
Lecture des informations d&#039;état... Fait                                                                                             
Correction des dépendances... Fait                                                                                                                                                                      
Les paquets supplémentaires suivants seront installés :                                                                             
  libpicoipp                                                                                                                        
Les paquets suivants seront mis à jour :                                                                                            
  libpicoipp                                                                                                                        
1 mis à jour, 0 nouvellement installés, 0 à enlever et 998 non mis à jour.                                                          
1150 partiellement installés ou enlevés.                                                                                            
Il est nécessaire de prendre 0 o/4 260 ko dans les archives.                                                                        
Après cette opération, 43,0 ko d&#039;espace disque seront libérés.                                                                      
Souhaitez-vous continuer ? &#x5B;O/n] O                                                                                                  
Lecture des fichiers de modifications (« changelog »)... Terminé                                                                    
(Lecture de la base de données... 490198 fichiers et répertoires déjà installés.)                                                   
Préparation du dépaquetage de .../libpicoipp_1.3.0-4r78_amd64.deb ...                                                               
dpkg: erreur de traitement de l&#039;archive /var/cache/apt/archives/libpicoipp_1.3.0-4r78_amd64.deb (--unpack) :                        
 conffile name &#039;etc/ld.so.conf.d/picoscope.conf&#039; is not an absolute pathname                                                        
Des erreurs ont été rencontrées pendant l&#039;exécution :                                                                               
 /var/cache/apt/archives/libpicoipp_1.3.0-4r78_amd64.deb                                                                            
E: Sub-process /usr/bin/dpkg returned an error code (1)
</pre></div>


<h2 class="wp-block-heading">Où se situe le problème ?</h2>



<p>Très visiblement, le problème vient du paquet libpicoipp. Un paquet permettant de faire fonctionner les <a href="https://www.picotech.com/">picoscopes de chez Picotech</a>. Ma machine va chercher ce paquet car j&rsquo;ai ajouté <code>deb https://labs.picotech.com/debian/ picoscope main</code> <a href="https://www.picotech.com/downloads/linux">aux dépôts</a>.</p>



<p>Il <a href="https://www.picotech.com/support/viewtopic.php?f=22&amp;p=145387">semblerait</a> qu&rsquo;au moins depuis la version 1.1, et encore dans la version 1.3, ce paquet soit mal formé. Le fichier <code>DEBIAN/conffiles</code> du paquet pointe vers <em><code>etc/ld.so.conf.d/picoscope.conf</code></em> au lieu de <em><code>/etc/ld.so.conf.d/picoscope.conf</code></em>. Too bad.</p>



<h2 class="wp-block-heading">Comment <s>corriger</s> cacher le problème ?</h2>



<p>J&rsquo;ai d&rsquo;abord cherché à supprimer le paquet. Une chose que j&rsquo;ai appris, et qui semble pourtant logique, c&rsquo;est que pour supprimer le paquet, il faut supprimer aussi tous les paquets qui en dépendent.</p>



<p>En regardant le résultat de <code>sudo apt upgrade</code>, j&rsquo;ai donc pu lancer <code>sudo apt remove libps2000a libps3000a libps4000 libps4000a libps5000a libps6000 libps6000a picoscope</code>. Suppression réussie. Une manière comme une autre de résoudre un problème non ?</p>



<p>Ce qui a permis de mettre à jour mon système avec <code>sudo apt upgrade</code> !</p>



<h2 class="wp-block-heading">Comment vraiment corriger ?</h2>



<p>Pour pouvoir continuer à utiliser les picoscopes, ce <a href="https://www.picotech.com/support/viewtopic.php?f=22&amp;p=145387">topic du forum Picotech</a> explique le problème et la solution possible : corriger manuellement le paquet Debian.</p>



<p>Voilà un bon exercice !</p>



<p>Plutôt que de bêtement faire un <code>tar xf</code> du paquet (un paquet Debian est en réalité une archive au contenu bien précis et ayant l&rsquo;extension .deb), on va utiliser <code>dpkg-deb -R</code> pour l&rsquo;ouvrir et <code>dpkg-deb -b</code> pour le recréer. Entre temps, on modifiera le fichier incorrect.</p>



<p>Je n&rsquo;ai pas encore testé cette dernière étape, mais cela doit donner quelque chose comme ça :</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# Unpack
mkdir ~/tmp &amp;amp;&amp;amp; dpkg-deb -R /var/cache/apt/archives/libpicoipp_1.3.0-4r78_amd64.deb ~/tmp
# Fix package
vim ~/tmp/DEBIAN/conffiles
# Remove first line containing &quot;etc/ld.so.conf.d/picoscope.conf&quot;
# Recreate the package
dpkg-deb -b ~/temp ~/libpicoipp_1.3.0-4r78_amd64.deb
# Install it
sudo apt install ~/libpicoipp_1.3.0-4r78_amd64.deb
# Let&#039;s reinstall the required Pico drivers
sudo apt install libps2000a libps3000a libps4000 libps4000a libps5000a libps6000 libps6000a picoscope
</pre></div>


<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2021/03/30/libpicoipp-installation-error/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Monter le Storex AivX avec Samba</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2020/04/13/monter-le-storex-aivx-avec-samba/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2020/04/13/monter-le-storex-aivx-avec-samba/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Mon, 13 Apr 2020 07:18:00 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Samba]]></category>
		<category><![CDATA[Storex]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2739</guid>

					<description><![CDATA[J&#8217;ai depuis plusieurs année un disque dur Wifi / media center Storex AivX &#8211; 372 HD. A part que c&#8217;est un peu vieux, c&#8217;est assez cool : 1to et il permet de lire facilement des films sur un écran (très pratique, je n&#8217;ai que faire d&#8217;un télé). Voilà longtemps que je voulais pouvoir y accéder à distance via mes autres &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2020/04/13/monter-le-storex-aivx-avec-samba/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>J&rsquo;ai depuis plusieurs année un disque dur Wifi / media center <strong>Storex AivX &#8211; 372 HD</strong>. A part que c&rsquo;est un peu vieux, c&rsquo;est assez cool : 1to et il permet de lire facilement des films sur un écran (très pratique, je n&rsquo;ai que faire d&rsquo;un télé).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="653" height="419" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_155200.png" alt="" class="wp-image-2743" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_155200.png 653w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_155200-300x192.png 300w" sizes="auto, (max-width: 653px) 100vw, 653px" /></figure>



<p>Voilà longtemps que je voulais pouvoir y accéder à distance via mes autres ordinateurs. C&rsquo;est censé être possible puisqu&rsquo;il est connecté en Wifi à ma box Internet. Via Windows c&rsquo;est un peu la croix et la bannière, mais ça marche. Sous Linux&#8230; je n&rsquo;avais jamais réussi ! L&rsquo;autre jour, je me suis un peu acharné, j&rsquo;ai trouvé et relu la doc, et j&rsquo;ai fini par trouver la solution (et les raisons) juste avant de lâcher prise. Ouf !</p>



<span id="more-2739"></span>



<h2 class="wp-block-heading">Avec un montage cifs</h2>



<div class="wp-block-image"><figure class="alignleft size-large"><img loading="lazy" decoding="async" width="232" height="287" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/solum.jpeg" alt="" class="wp-image-2741"/><figcaption>Mémoire&#8230;</figcaption></figure></div>



<p>Via la configuration de mon Storex, j&rsquo;ai pu checker son adresse IP, sélectionner un workgroup et un nom du partage. J&rsquo;ai choisi <code>Solum</code> : <a href="https://fr.wiktionary.org/wiki/solum">du latin signifiant « succession verticale des couches du sol »</a>. C&rsquo;est aussi une planète dans l&rsquo;univers de Valérian et Laureline : la ville unique de cette planète s&rsquo;enfonce d&rsquo;année en année dans le sous-sol, obligeant ses habitants à construire régulièrement un nouvel étage à la cité. Une créature immortelle s&rsquo;installe alors à chaque nouvel étage englouti afin d&rsquo;être la mémoire de ce qui s&rsquo;est passé à son époque.</p>



<p>Bref, chouette nom pour un disque dur de backup non ? </p>



<p>Après avoir créé un dossier à l&rsquo;endroit où je désire monter mon Storex (<code>mkdir /home/smb4k/Solum</code>), voici le montage <code>cifs</code> (vive <code>cifs</code> !!!) qui fonctionne :</p>



<pre><pre class="brush: bash; title: ; notranslate">
$ sudo mount -t cifs //ip-address/STOREX /home/smb4k/Solum -o username=Solum,workgroup=WORKGROUP,vers=1.0
Password for Solum@//ip-address/STOREX: ********
</pre></pre>



<p>Il y a plusieurs erreurs possibles :</p>



<ul class="wp-block-list"><li>Même si on a changé le nom de partage en Solum, le dossier continue de s&rsquo;appeler « STOREX ». C&rsquo;est bête mais c&rsquo;est indiqué nul part. J&rsquo;ai fini par m&rsquo;en rendre compte grâce au message d&rsquo;erreur <code>mount error(2): No such file or directory</code> </li><li>Lorsqu&rsquo;on enlève <code>vers=1.0</code>, cela ne fonctionne pas et le message d&rsquo;erreur suivant <code>Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)</code> nous invite à faire un <code>sudo dmesg</code> qui nous dit : <code>No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3 (or SMB2.1) specify vers=1.0 on mount.</code> Ahh, ok ! En bref mon Storex est trop vieux et utilise Samba v1.0 qui est désactivé mais heureusement encore supporté ! </li></ul>



<p>Un petit <code>ls -l /home/smb4k/Solum</code> me liste tous mes fichiers, yes !</p>



<h2 class="wp-block-heading">Avec SMB4K</h2>



<p>Sur mon Debian KDE (testing !), comme sur mon Kubuntu, j&rsquo;aime bien l&rsquo;utilitaire SMB4K pour monter facilement mes disques réseaux. L&rsquo;IHM est vraiment abscons, mais ça fait le job.</p>



<p>ça fonctionne bien sur mon vieux Kubuntu avec la configuration suivante :</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="976" height="1024" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/smb4k_storex-976x1024.png" alt="" class="wp-image-2742" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/smb4k_storex-976x1024.png 976w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/smb4k_storex-286x300.png 286w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/smb4k_storex-768x806.png 768w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/smb4k_storex.png 996w" sizes="auto, (max-width: 976px) 100vw, 976px" /></figure>



<p>Sur mon Debian, je dois avoir un SMB4K un peu trop récent et le montage ne se fait pas. C&rsquo;est probablement le problème de Samba 1.0, mais je ne vois pas comment configurer cela sur SMB4K. Arf, allez encore quelques recherches (one day) et le setup sera complet !</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2020/04/13/monter-le-storex-aivx-avec-samba/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Installer syncthing sur recalbox</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2020/04/09/installer-syncthing-sur-recalbox/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2020/04/09/installer-syncthing-sur-recalbox/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Thu, 09 Apr 2020 13:50:32 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[RaspberryPi]]></category>
		<category><![CDATA[Recalbox]]></category>
		<category><![CDATA[Syncthing]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2716</guid>

					<description><![CDATA[J&#8217;ai récemment installé l&#8217;OS Recalbox, l&#8217;émulateur de consoles de jeux, sur mon RaspberryPi3. Une petite manette USB, et&#8230; ah oui il me faudra une manette USB ou Bluetooth supplémentaire, et prendre le temps de retrouver des jeux sympas&#8230; et cela devrait animer les soirées d&#8217;hiver ! Mon objectif est d&#8217;avoir un RaspberryPi près du bureau pour : Faire console de &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2020/04/09/installer-syncthing-sur-recalbox/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image is-style-circle-mask"><figure class="alignright size-large is-resized"><img loading="lazy" decoding="async" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-1024x717.jpg" alt="" class="wp-image-2724" width="169" height="118" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-1024x717.jpg 1024w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-300x210.jpg 300w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-768x538.jpg 768w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-1536x1075.jpg 1536w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/recalbox-2048x1434.jpg 2048w" sizes="auto, (max-width: 169px) 100vw, 169px" /></figure></div>



<p>J&rsquo;ai récemment installé l&rsquo;<a href="https://www.recalbox.com/fr/">OS Recalbox</a>, l&rsquo;émulateur de consoles de jeux, sur mon <strong>RaspberryPi3</strong>. Une petite manette USB, et&#8230; ah oui il me faudra une manette USB ou Bluetooth supplémentaire, et prendre le temps de retrouver des jeux sympas&#8230; et cela devrait animer les soirées d&rsquo;hiver !</p>



<p>Mon objectif est d&rsquo;avoir un RaspberryPi près du bureau pour :</p>



<ul class="wp-block-list"><li>Faire console de jeux (checked)</li><li>Ah tiens Recalbox est fourni avec le media center Kodi (à creuser)</li><li>Rendre mon imprimante utilisable via le réseau (peut-être compliqué avec Recalbox, c&rsquo;est mon prochain défi)</li><li>Rajouter un noeud Syncthing à la maison (checked)</li></ul>



<p>Mais <strong>comment installer synchting sur Recalbox ?</strong> Puisque comme le disent certains sur les forums : il n&rsquo;y a pas de gestionnaire de paquet sur Recalbox.</p>



<span id="more-2716"></span>



<div class="wp-block-image is-style-circle-mask"><figure class="alignleft size-large"><img loading="lazy" decoding="async" width="128" height="128" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/syncthing.png" alt="" class="wp-image-2725" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/syncthing.png 128w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/syncthing-120x120.png 120w" sizes="auto, (max-width: 128px) 100vw, 128px" /></figure></div>



<p><a href="https://syncthing.net/">Syncthing</a> est fait pour synchroniser des trucs. J&rsquo;ai connecté les ordinateurs de la maison à deux noeuds Synchting sur 2 RasberryPi. Cela permet d&rsquo;échanger facilement les fichiers, de rajouter des photos facilement à mon RaspberryPi faisant office de cadre numérique, et ça sert de backup en cas de casse de disque dur. C&rsquo;est aussi une petite protection contre le vol (4 copies, avec un peu de chance le voleur ne les trouvera pas toutes), mais c&rsquo;est inutile contre une suppression malencontreuse de données, pour ça j&rsquo;ai un disque dur externe.</p>



<h2 class="wp-block-heading">Accès SSH à Recalbox</h2>



<p>Recalbox est fourni avec un <a href="https://github.com/recalbox/recalbox-os/wiki/Root-access-on-terminal-(EN)">serveur SSH</a>, yes!</p>



<pre class="wp-block-preformatted">$ ssh root@ip-address
recalboxroot
# </pre>



<p>Le tour est joué !</p>



<h2 class="wp-block-heading">Installé Syncthing sur Recalbox</h2>



<p>Syncthing ayant relativement peu de dépendance, il suffit de déposer l&rsquo;exécutable <code>syncthing</code> sur Recalbox et de l&rsquo;exécuter pour que le tour soit jouer.</p>



<p>Pour trouver l&rsquo;exécutable, on peut le recompiler (certes), mais sur RaspberryPi, la <a href="https://syncthing.net/downloads/">version pré-compilé pour ARM</a> fera très bien l&rsquo;affaire. On peut par exemple le télécharger et l&rsquo;envoyer sur le RaspberryPi avec <code>scp</code>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ wget https://github.com/syncthing/syncthing/releases/download/v1.4.2/syncthing-linux-arm-v1.4.2.tar.gz
$ tar xf syncthing-linux-arm-v1.4.2.tar.gz
$ scp syncthing-linux-arm-v1.4.2/synchting root@ip-address:.
</pre></div>


<p>Dans les dernières versions de Recalbox, il faut placer les scripts dans le dossier /usr/bin puis le rendre exécutable:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ mount -o remount,rw / # Disk is mounted read only by default
$ mv syncthing /usr/bin
$ chmod 755 /usr/bin/syncthing
</pre></div>


<p>Personnellement, j&rsquo;active toujours l&rsquo;<a href="https://docs.syncthing.net/users/guilisten.html">accès distant à l&rsquo;IHM Web de Syncthing</a>. Après avoir exécuter une fois syncthing grâce à <code>./syncthing</code>, je quitte (ctrl+c) et j&rsquo;édite le fichier de config <code>~/.config/syncthing /config.xml</code> en changeant <code>address</code> avec <code>0.0.0.0:8384</code>. J&rsquo;ajoute un mot de passe plus tard via l&rsquo;IHM.</p>



<h2 class="wp-block-heading">Démarré Syncthing au démarrage</h2>



<p>Recalbox utiliser <a href="https://github.com/recalbox/recalbox-os/wiki/Add-your-own-startup-script-(EN)https://github.com/recalbox/recalbox-os/wiki/Add-your-own-startup-script-(EN)">init.d</a> comme utilitaire de démarrage. Il faut donc rajouter le fichier suivant, nommé <code>S95Syncthing</code> (par exemple) dans <code>/etc/init.d/</code>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
#!/bin/bash
RECALHOME=/recalbox/share/system
EXE=/usr/bin/syncthing
case &quot;$1&quot; in 
    start)  
          nohup ${EXE} -home ${RECALHOME}/.config/syncthing -no-browser &gt;${RECALHOME}/logs/syncthing_initd.log 2&gt;&amp;amp;1 &amp;amp;
          ;;  
    stop)  
          pkill -f &quot;syncthing&quot;
          ;;  
    status)
          ps aux | grep syncthing
          ;;
    restart|reload)  
          pkill -f &quot;syncthing&quot; 
          nohup ${EXE} -home ${RECALHOME}/.config/syncthing -no-browser &gt;${RECALHOME}/logs/syncthing_initd.log 2&gt;&amp;amp;1 &amp;amp;
          ;;  
    *)  
esac  
exit $?
</pre></div>


<p>Sans oublier de rendre ce script exécutable :</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ mount -o remount,rw / # Disk is mounted read only by default
$ chmod 755 /etc/init.d/S95Syncthing
</pre></div>


<p>Et voilà, syncthing démarrera tout seul au prochain redémarrage !</p>



<figure class="wp-block-image size-large is-resized is-style-default"><img loading="lazy" decoding="async" src="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_154209-1024x657.png" alt="" class="wp-image-2726" width="533" height="342" srcset="http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_154209-1024x657.png 1024w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_154209-300x192.png 300w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_154209-768x492.png 768w, http://30minparjour.la-bnbox.fr/wp-content/uploads/2020/04/Screenshot_20200409_154209.png 1129w" sizes="auto, (max-width: 533px) 100vw, 533px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2020/04/09/installer-syncthing-sur-recalbox/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Grub rescue après mise à jour Windows</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2020/02/25/grub-rescue-apres-mise-a-jour-windows/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2020/02/25/grub-rescue-apres-mise-a-jour-windows/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Tue, 25 Feb 2020 09:42:24 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Grub]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2705</guid>

					<description><![CDATA[Contexte Sur un Dell Inspiron 155000, j&#8217;ai un dual boot Windows 10 / Kubuntu. Lors d&#8217;une mise à jour Windows, ce dernier semble avoir purement et simplement supprimé grub. J&#8217;avais déjà eu le cas où Windows modifie le disque d&#8217;amorçage, et il faut donc reconfigurer grub à la main, mais cette fois-ci, je n&#8217;avais carrément plus de grub, juste un &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2020/02/25/grub-rescue-apres-mise-a-jour-windows/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p><strong>Contexte</strong> <br> Sur un Dell Inspiron 155000, j&rsquo;ai un dual boot Windows 10 / Kubuntu. Lors d&rsquo;une mise à jour Windows, ce dernier semble avoir purement et<br> simplement supprimé grub. J&rsquo;avais déjà eu le cas où Windows modifie le disque d&rsquo;amorçage, et il faut donc reconfigurer grub à la main, mais cette<br> fois-ci, je n&rsquo;avais carrément plus de grub, juste un prompt “grub rescue”. Génial !</p>



<p><br><strong>Solution</strong> <br> Dans le prompt grub rescue : <br><code>grub rescue&gt; ls # affiche la liste des disques, pour moi cela allait de gpt9 à gtp1<br>grub rescue&gt; set # affiche la configuration courante, pour moi gtp8 était sélectionné<br>grub rescue&gt; set prefix=(hd0,gtp5)/boot/grub<br>grub rescue&gt; set roothd0,gpt5<br>grub rescue&gt; insmod linux # Maybe useless<br>grub rescue&gt; insmod normal<br>grub rescue&gt; normal # Linux will start</code></p>



<p>J&rsquo;ai fait plusieurs tentatives pour trouver la bonne partition car je ne me rappelais plus laquelle c&rsquo;était ! (petite piqûre de rappel de qwerty en<br> prime) Il n&rsquo;y a pas de risque à faire des essais, quand ce n&rsquo;est pas correct, la commande <code>insmod linux</code> déclare <code>unknown filesystem</code>. <br> Pour rendre cette modification permanente, il faut utiliser les commandes suivantes une fois qu&rsquo;on a un prompt digne de ce nom : <br><code> sudo os-prober<br> sudo update-grub<br> sudo grub-install /dev/sda</code></p>



<p><strong>Ressources</strong> </p>



<ul class="wp-block-list"><li>https://doc.ubuntu-fr.org/tutoriel/comment_restaurer_grub</li><li>http://forum.ubuntu-fr.org/viewtopic.php?id=358656</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2020/02/25/grub-rescue-apres-mise-a-jour-windows/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Office 2010 sous Linux Debian</title>
		<link>http://30minparjour.la-bnbox.fr/blog/2019/09/09/a-traduire-en-fr_fr-office-2010-sous-linux-debian/</link>
					<comments>http://30minparjour.la-bnbox.fr/blog/2019/09/09/a-traduire-en-fr_fr-office-2010-sous-linux-debian/#respond</comments>
		
		<dc:creator><![CDATA[Fylhan]]></dc:creator>
		<pubDate>Mon, 09 Sep 2019 11:03:10 +0000</pubDate>
				<category><![CDATA[Geekeries]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Office]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Wine]]></category>
		<guid isPermaLink="false">http://30minparjour.la-bnbox.fr/?p=2693</guid>

					<description><![CDATA[Aujourd&#8217;hui j&#8217;ai réussi à installer une version official de Microsoft Office 2010 (32bits version Academic) sur mon Linux : une Debian Bulleyes avec wine 4.0.1. J&#8217;ai utilisé les commandes suivantes : sudo apt install winetricks winbind WINEARCH=win32 WINEPREFIX=~/.wineoffice2010 winetricks dotnet20 msxml6 corefonts WINEPREFIX=~/.wineoffice2010 wine ../hubiC/Olivier/WorkTrialog/Software/Office_2010_ProPlusAc_SP1_French_x32.exe Après cela, Word et Excel ont fonctionné correctement (une fois activé en ligne). Mais PowerPoint &#8230; <a href="http://30minparjour.la-bnbox.fr/blog/2019/09/09/a-traduire-en-fr_fr-office-2010-sous-linux-debian/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p>Aujourd&rsquo;hui j&rsquo;ai réussi à installer une version official de Microsoft <strong>Office 2010</strong> (32bits version Academic) sur mon <strong>Linux</strong> : une <strong>Debian Bulleyes</strong> avec <strong>wine</strong> 4.0.1. J&rsquo;ai utilisé les commandes suivantes :</p>



<p><code>sudo apt install winetricks winbind
WINEARCH=win32 WINEPREFIX=~/.wineoffice2010 winetricks dotnet20 msxml6 corefonts
WINEPREFIX=~/.wineoffice2010 wine ../hubiC/Olivier/WorkTrialog/Software/Office_2010_ProPlusAc_SP1_French_x32.exe</code></p>



<p>Après cela, <strong>Word</strong> et <strong>Excel</strong> ont fonctionné correctement (une fois activé en ligne). Mais <strong>PowerPoint</strong> ne démarrait pas&#8230; Il semble que <a href="https://appdb.winehq.org/objectManager.php?sClass=version&amp;iId=22220">PowerPoint on wine « does not automatically use the riched20 installed by Office »</a>.&nbsp; Donc, nous devons sélectioner <a href="https://ubuntuforums.org/showthread.php?t=1139929">riched20 to native in winecfg</a>. C&rsquo;est ce que j&rsquo;ai fait avec succès en lançant :</p>



<p><code> WINEPREFIX=~/.wineoffice2010 winecfg</code></p>



<p>Et voilà ! Bon courage avec votre installation d &lsquo;Office sous Linux !

Pour info, j&rsquo;ai aussi une version d&rsquo;Office 2016, mais c&rsquo;est juste mort pour l&rsquo;installer sous Linux ! Une histoire de version d&rsquo;ActiveX pas (encore) supporté par Wine.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://30minparjour.la-bnbox.fr/blog/2019/09/09/a-traduire-en-fr_fr-office-2010-sous-linux-debian/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
