<?xml
version="1.0" encoding="utf-8"?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>

<channel xml:lang="fr">
	<title>Geekographie Ma&#239;eulesque</title>
	<link>https://geekographie.maieul.net/</link>
	<description>Ce site est consacr&#233; &#224; quelques unes des mes geekeries. J'y donne des conseils, des r&#233;flexions, sur les logiciels et les langages que je connais ou que j'apprends.
J'y parle notamment de l'usage de LaTeX en sciences humaines et sociales, en particulier pour la gestion de la bibliographie.
Le contenu peut &#234;tre sous la forme d'articles d&#233;taill&#233;s ou de simples notes.
L'ensemble du contenu est, sauf pr&#233;cision contraire, sous licence Cr&#233;ative Commons Paternit&#233;-Partage des Conditions Initiales &#224; l'identique France.</description>
	<language>fr</language>
	<generator>SPIP - www.spip.net</generator>
	<atom:link href="https://geekographie.maieul.net/spip.php?id_rubrique=42&amp;page=backend" rel="self" type="application/rss+xml" />




<item xml:lang="fr">
		<title>R&#233;cup&#233;rer un r&#233;pertoire par FTP</title>
		<link>https://geekographie.maieul.net/19</link>
		<guid isPermaLink="true">https://geekographie.maieul.net/19</guid>
		<dc:date>2011-01-03T20:06:54Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Ma&#239;eul</dc:creator>



		<description>
&lt;p&gt;Pour sauvegarder r&#233;guli&#232;rement mes sites web, j'utilise un script Python personnel. Une des &#233;tapes consiste &#224; r&#233;cup&#233;rer des fichier sur un serveur &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt;. Comme j'ai eu un peu de mal &#224; comprendre comment fonctionne le module &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt; de Python, je vous livre ici ma solution. J'ai d&#233;cid&#233; de cr&#233;er une nouvelle classe ftp_perso qui contiendra un ensemble de m&#233;thode. D&#233;riv&#233;e de la classe &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt; elle devrait permettre&#160;: de lister r&#233;cursivement le contenu d'un r&#233;pertoire. de r&#233;cup&#233;rer r&#233;cursivement le&#160;(&#8230;)&lt;/p&gt;


-
&lt;a href="" rel="directory"&gt;FTP&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;Pour sauvegarder r&#233;guli&#232;rement mes sites web, j'utilise un script Python personnel. Une des &#233;tapes consiste &#224; r&#233;cup&#233;rer des fichier sur un serveur &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt;. Comme j'ai eu un peu de mal &#224; comprendre comment fonctionne le module &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt; de Python, je vous livre ici ma solution.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;p&gt;J'ai d&#233;cid&#233; de cr&#233;er une nouvelle classe &lt;code&gt;ftp_perso&lt;/code&gt; qui contiendra un ensemble de m&#233;thode.&lt;span class=&#034;spip_note_ref&#034;&gt; [&lt;a href=&#034;#nb1&#034; class=&#034;spip_note&#034; rel=&#034;appendix&#034; title=&#034;Si vous trouvez un nom mieux je suis preneur.&#034; id=&#034;nh1&#034;&gt;1&lt;/a&gt;]&lt;/span&gt; D&#233;riv&#233;e de la classe &lt;code&gt;FTP&lt;/code&gt; elle devrait permettre&#160;:&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; de lister r&#233;cursivement le contenu d'un r&#233;pertoire.&lt;/li&gt;&lt;li&gt; de r&#233;cup&#233;rer r&#233;cursivement le contenu d'un r&#233;pertoire.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Un probl&#232;me qui s'est pos&#233; est que tous les serveurs &lt;span class=&#034;caps&#034;&gt;FTP&lt;/span&gt; ne renvoient pas le m&#234;me type de chemin&#160;: certains renvoient un chemin depuis la racine, d'autres se contentent d'indiquer le nom du r&#233;pertoire courant.&lt;/p&gt;
&lt;p&gt;Pour r&#233;soudre cela, &#224; l'initialisation d'une instance de classe, un attribut d'objet est calcul&#233;. &lt;code&gt;self.hierarchie&lt;/code&gt;&#160;: selon sa valeur, le parcours r&#233;cursif ne sera pas effectu&#233; de la m&#234;me mani&#232;re, car il ne faudra pas envoyer les m&#234;mes requ&#234;tes au serveur.&lt;/p&gt;
&lt;p&gt;Par ailleurs certains listent les dossiers &lt;code&gt;.&lt;/code&gt; et &lt;code&gt;..&lt;/code&gt; lorsqu'on envoie une commande ls. Comme il s'agit du r&#233;pertoire courant et du r&#233;pertoire parent, il ne faut pas les utiliser lorsqu'on parcourt r&#233;cursivement, sinon on tourne. J'ai donc d&#233;fini un attribut de d'objet, avec une valeur standard mais pouvant prendre de nouvelles valeurs &#224; l'initialisation d'une instance&#160;: &lt;code&gt;self.faux_reps&lt;/code&gt;, qui contient la liste des dossiers &#224; ne pas parcourir.&lt;/p&gt;
&lt;p&gt;Enfin, il n'est pas toujours &#233;vident de savoir si un fichier est un r&#233;pertoire (dossier) ou nom&#160;: j'ai donc d&#233;fini une m&#233;thode &lt;code&gt;is_dir(self, file)&lt;/code&gt; que j'appelle sur chaque fichier avant de tenter d'y entrer comme un r&#233;pertoire.&lt;/p&gt;
&lt;p&gt;Au final j'ai donc&#160;:&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; une m&#233;thode &lt;code&gt;is_dir()&lt;/code&gt; &#224; usage interne.&lt;/li&gt;&lt;li&gt; une m&#233;thode &lt;code&gt;lister_repertoire(self,rep='',niveau=0)&lt;/code&gt; qui permet de lister r&#233;cursivement un r&#233;pertoire. Cette m&#233;thode s'appelle elle m&#234;me, d'o&#249; l'argument &lt;code&gt;niveau&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; une m&#233;thode &lt;code&gt;rapatrier_repertoire(self,chemin_local='.',rep='',niveau=0)&lt;/code&gt; qui permet de r&#233;cup&#233;rer un r&#233;pertoire distant en local.&lt;/li&gt;&lt;/ul&gt;&lt;div class='precode'&gt;&lt;pre dir='ltr' style='text-align: left;' class='python'&gt;&lt;code&gt;class ftp_perso(FTP): ''' Reprend la class FTP de ftplib en rajoutant le listage r&#233;cursive d'un r&#233;pertoire et la r&#233;cup&#233;ration de l'ensemble du contenur d'un r&#233;pertoire''' def __init__(self,host,user,mdp,faux_dossiers=()): FTP.__init__(self,host,user,mdp) self.mkd('pyftptest') self.mkd('pyftptest/pyftptest') self.hierarchie=self.nlst('pyftptest') self.rmd('pyftptest/pyftptest') self.rmd('pyftptest') self.faux_reps = ('..','.','.ok','article_PDF') + faux_dossiers if len(self.hierarchie) &gt; 1: from string import find if find(self.hierarchie[2],'/') &gt; -1: self.hierarchie = '/' else: self.hierarchie = '' else: self.hierarchie = '/' def lister_repertoire(self,rep='',niveau=0): from string import rfind contenu = self.nlst(rep) if self.hierarchie != '/': for i in contenu: if not i in self.faux_reps: print rep+'/'+i if not self.is_dir(rep+'/'+i): print &#034;%sFichier &#171;%s&#187;&#034; % (niveau * &#034;\t&#034;, i ) else: print &#034;%s Dossier &#171;%s&#187;&#034; % (niveau * &#034;\t&#034;, i ) self.lister_repertoire(rep+'/'+i,niveau=niveau+1) else: for i in contenu: if not i[rfind(i,'/')+1:] in self.faux_reps: if not self.is_dir(i): print &#034;%sFichier &#171;%s&#187;&#034; % (niveau * &#034;\t&#034;, i[rfind(i,'/')+1:] ) else: print &#034;%s Dossier &#171;%s&#187;&#034; % (niveau * &#034;\t&#034;, i[rfind(i,'/')+1:] ) self.lister_repertoire(i,niveau=niveau+1) def is_dir(self,file): try: courant = self.pwd() self.cwd(file) self.cwd(courant) return True except: return False def rapatrier_repertoire(self,chemin_local='.',rep='',niveau=0): from string import rfind contenu = self.nlst(rep) if self.hierarchie != '/': for i in contenu: if not i in self.faux_reps: print rep + '/' + i if not self.is_dir(rep+'/'+i): if rep!='' and rep[0]!='/': self.retrbinary('RETR '+rep+'/'+i,open(chemin_local+'/'+rep+'/'+i,'wb').write) else: self.retrbinary('RETR '+rep+'/'+i,open(chemin_local+rep+'/'+i,'wb').write) else: if rep!='' and rep[0]!='/': makedirs(chemin_local+'/'+rep+'/'+i) else: makedirs(chemin_local+rep+'/'+i) self.rapatrier_repertoire(chemin_local,rep+'/'+i,niveau=niveau+1) else: for i in contenu: if not i[rfind(i,'/')+1:] in self.faux_reps: print i if not self.is_dir(i): self.retrbinary('RETR '+i,open(chemin_local+'/'+i,'wb').write) else: makedirs(chemin_local+'/'+i) self.rapatrier_repertoire(chemin_local,i,niveau=niveau+1)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
		&lt;hr /&gt;
		&lt;div &lt;div class='rss_ps'&gt;&lt;p&gt;Si vous voulez r&#233;cuperer le code, attention &#224; bien prendre celui dans le lien de t&#233;l&#233;chargement, sinon vous perdez les indentations.&lt;/p&gt;&lt;/div&gt;
		&lt;hr /&gt;
		&lt;div class='rss_notes'&gt;&lt;div id=&#034;nb1&#034;&gt;
&lt;p&gt;&lt;span class=&#034;spip_note_ref&#034;&gt;[&lt;a href=&#034;#nh1&#034; class=&#034;spip_note&#034; title=&#034;Notes 1&#034; rev=&#034;appendix&#034;&gt;1&lt;/a&gt;] &lt;/span&gt;Si vous trouvez un nom mieux je suis preneur.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
		</content:encoded>


		

	</item>



</channel>

</rss>
