Snippets populaires
Une progress bar mise à jour à partir d'un thread
Dans le cadre d'une application graphique, un traitement long peut être déporté dans un thread à part. Si l'on veut afficher une progress bar, elle doit être mise-à-jour à partir de ce thread.
En PyQt, on utilise un mécanisme de SIGNAL/SLOT pour faire cela.
#!/usr/bin/python # use a progress dialog from a thread from PyQt4.QtCore import * from PyQt4.QtGui import * import time,sys STEPS=5 class MyThread(QThread): def __init__(self,parent): super(MyThread,self).__init__(parent) self.cancel = False def run (self): for i in range(STEPS): if self.cancel: break time.sleep(1) self.emit(SIGNAL("increment")) print "%d "%(i), @pyqtSignature("") def cancel(self): """SLOT to cancel treatment""" self.cancel = True class MyAppli(QWidget): def __init__(self,parent=None): QWidget.__init__(self, parent) # create button to start the thread self.btnStart = QPushButton("Start",self) self.connect(self.btnStart, SIGNAL("clicked()"), self, SLOT("on_btnStart_clicked()")) @pyqtSignature("") def on_btnStart_clicked(self): """Start the treatment in the thread""" self.p = QProgressDialog("Running...","Stop",0,STEPS-1,self) self.th = MyThread(self) self.th.connect(self.th,SIGNAL("increment"), self.incProgress) self.p.connect (self.p, SIGNAL("canceled()"), self.th,SLOT("cancel()")) self.p.show() self.th.start() def incProgress(self): """Increment the progress dialog""" self.p.setValue(self.p.value()+1) if __name__ == "__main__": app = QApplication(sys.argv) widget = MyAppli() widget.show() sys.exit(app.exec_())
On commence par créer un simple bouton pour lancer le thread. Lorsqu'il est cliqué, une boite de progression est créée et l'on connecte deux signaux :
- increment pour déclencher la maj de la progressdialog dans le thread principal
- canceled pour annuler le traitement
Puis on affiche la boite et on lance le thread.
[Symfony] Utiliser sqlite pour stocker le cache des templates
D'abord, s'assurer d'avoir le module sqlite de php5 chargé et activé :
$ sudo apt-get install php5-sqlite
$ sudo /etc/init.d/apache2 restart
Dans le fichier factories.yml de l'application concernée :
view_cache:
class: sfSQLiteCache
param:
automaticCleaningFactor: 0
database: %SF_ROOT_DIR%/cache/cache.db
Et voilà, maintenant les symfony cc se feront en un éclair.
[Symfony] Un validateur de date qu'il est bien
Quelques fonctionnalités en plus par rapport à sfDateValidator (qu'il étend), notamment l'interdiction de date futures ou passées et l'évitement du traitement de la langue courante utilisateur (utile pour les formats de date figés).
/** * Custom date validator * */ class myDateValidator extends sfDateValidator { /** * Execute this validator. * * @param mixed A file or parameter value/array * @param error An error message reference * * @return bool true, if this validator executes successfully, otherwise false */ public function execute(&$value, &$error) { $culture = $this->getContext()->getUser()->getCulture(); // Validate the given date if ($this->getParameter('with_culture')) { $value1 = $this->getValidDate($value, $culture); } else { $value1 = strtotime($value); } if (!$value1 || -1 == $value1) // Before php 5.1, strtotime() returns -1 on fail { $error = $this->getParameter('date_error'); return false; } // Is there a compare to do? $compareDateParam = $this->getParameter('compare'); $compareDate = $this->getContext()->getRequest()->getParameter($compareDateParam); // If the compare date is given if ($compareDate) { $operator = trim($this->getParameter('operator', '=='), '\'" '); $value2 = $this->getValidDate($compareDate, $culture); // If the check date is valid, compare it. Otherwise ignore the comparison if ($value2) { $valid = false; switch ($operator) { case '>': $valid = $value1 > $value2; break; case '>=': $valid = $value1 >= $value2; break; case '==': $valid = $value1 == $value2; break; case '<=': $valid = $value1 <= $value2; break; case '<': $valid = $value1 < $value2; break; default: throw new sfValidatorException(sprintf('Invalid date comparison operator "%s"', $operator)); } if (!$valid) { $error = $this->getParameter('compare_error'); return false; } } } if (!$this->getParameter('allow_future') && $value1 > time()) { $error = $this->getParameter('future_error'); return false; } if (!$this->getParameter('allow_past') && $value1 < time()) { $error = $this->getParameter('past_error'); return false; } return true; } /** * Initializes the validator. * * @param sfContext The current application context * @param array An associative array of initialization parameters * * @return bool true, if initialization completes successfully, otherwise false */ public function initialize($context, $parameters = null) { // Initialize parent parent::initialize($context, $parameters); // Set defaults $this->getParameterHolder()->set('with_culture', true); $this->getParameterHolder()->set('allow_future', true); $this->getParameterHolder()->set('future_error', 'Future dates not allowed'); $this->getParameterHolder()->set('allow_past', true); $this->getParameterHolder()->set('past_error', 'Past dates not allowed'); $this->getParameterHolder()->add($parameters); return true; } }
Compiler tous les fichiers PHP en un seul
Pour faire un gros fichier comportant l'intégralité d'un projet par exemple :
$ find . -name "*.php" |xargs php -w > mongrosprojet.php
Export/Import d'une base MySQL utf8
C'est pas facile, mais c'est possible.
I. Exportation de la base :
$ mysqldump -uuser -p --opt --default-character-set=utf8 mabase > mabase.sql
II. Reconversion :
$ iconv -f iso-8859-1 -t utf-8 mabase.sql > mabase_utf8.sql
III. Reimport :
$ mysql -uuser -p mabase < mabase_utf8.sql
[Symfony] [Validator] Valider une valeur en fonction d'une blacklist
Pour s'assurer qu'une valeur saisie par un utilisateur dans un formulaire Symfony ne fait pas partie d'une liste de valeurs interdites, on peut utiliser le validateur suivant :
Fichier sfBlacklistValidator.class.php :
<?php class sfBlacklistValidator extends sfValidator { public function initialize($context, $parameters = null) { // initialize parent parent::initialize($context); // set defaults $this->getParameterHolder()->set('blacklist_error', 'Value is not an allowed one'); $this->getParameterHolder()->set('case_sensitive', false); $this->getParameterHolder()->set('trim', true); $this->getParameterHolder()->add($parameters); return true; } public function execute(&$value, &$error) { // Forbidden names $blacklist = $this->getParameter('blacklist'); $casesensitive = $this->getParameter('case_sensitive'); $trim = $this->getParameter('trim'); if ($trim) { $value = trim($value); } if (is_array($blacklist) && count($blacklist) > 0) { if ($casesensitive) { $match = in_array($value, $blacklist); } else { $match = false; foreach ($blacklist as $item) { if (is_string($item) && strtolower($item) == strtolower($value)) { $match = true; break; } } } if ($match) { $error = $this->getParameterHolder()->get('blacklist_error'); return false; } } return true; } }
Dans un fichier de validation yml:
fields:
myfield:
sfBlacklistValidator:
blacklist: [admin, contact, info, infos, commercial, tech, support, sales, partnership, webmaster, business, owner]
case_sensitive: no
trim: yes
blacklist_error: The username you requested is not available
Les options sont assez explicites, mais en voici tout de même le détail :
- blacklist: tableau de valeurs prohibées au format YAML
- case_sensitive: effectuer les comparaisons en tenant compte de la casse
- trim: inclure les espaces en début et fin de chaînes
- blacklist_error: Message d'erreur à afficher en cas de valeur blacklistée
[Symfony] [Propel] Afficher la dernière requête effectuée
Pour afficher la dernière requête effectuée avec Propel :
echo Propel::getConnection()->getLastExecutedQuery();
C'est tout con, hein ?
Shortest XmlHttpRequest instanciation ever
if (!XMLHttpRequest) { window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP'); } }
Formatter un document XML avec DOM et PHP5
Ça peut bien aider.
$dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->load('/path/to/file.xml'); $dom->formatOutput = true; file_put_contents('formatted.xml', $dom->saveXML());
Raccourcis pour changer de bash rapidement
Beaucoup de monde connait le ctrl+alt+FX (X allant de 1 à 6 pour les sessions de terminal, et au dessus pour les sessions graphiques)
Je viens de découvrir par hasard le alt+super pour passer rapidement à la console suivante. (super étant assigné à la touche windows sur les claviers prévus pour fonctionner avec les systèmes de Microsoft)





