From 1c84a36c695e498da0b0dddc2e4ae0aed975e989 Mon Sep 17 00:00:00 2001 From: nojhan Date: Mon, 4 Feb 2008 14:24:17 +0000 Subject: [PATCH 002/127] RSS en ordre inverse (bug #1843853) + bugfix sous PHP5 (le fameux clone bug) --- configuration.php | 2 +- rss.php | 12 +++++++++--- strip_manager.php | 1 - 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/configuration.php b/configuration.php index 4d7c581..bff5d04 100644 --- a/configuration.php +++ b/configuration.php @@ -18,7 +18,7 @@ class configuration /** * URL of the website */ - var $url = 'http://www.nojhan.net/geekscottes'; + var $url = 'http://localhost/~nojhan/stripit/trunk'; /** * Title of the website diff --git a/rss.php b/rss.php index 50a2ae6..7437443 100644 --- a/rss.php +++ b/rss.php @@ -14,6 +14,12 @@ set_include_path(get_include_path() . PATH_SEPARATOR . getcwd()); require_once 'strip_manager.php'; require_once 'configuration.php'; +// hack for passing objects by values instead of reference under PHP5 (but not PHP4) +// damn clone keyword ! +if (version_compare(phpversion(), '5.0') < 0) { + eval('function clone($object) {return $object;}'); +} + /** * RSS manager */ @@ -47,13 +53,13 @@ class rss_manager $sm->strips_list_get(); - for( $i = 0; $i < $sm->strips_count; $i++ ) { + for( $i = $sm->strips_count-1; $i >= 0; $i-- ) { // reverser order $sm->strip_info_get( $i ); - + // conversion iso8601 -> RFC822 $sm->date = date('r', strtotime($sm->date)); - $this->items_list[] = $sm; + $this->items_list[] = clone($sm); // hack for php4/5 compat } } diff --git a/strip_manager.php b/strip_manager.php index 60ed67b..27b35a2 100644 --- a/strip_manager.php +++ b/strip_manager.php @@ -241,7 +241,6 @@ class strip_manager * @param integer index of the file to parse in the {@link $strips_list} */ function strip_info_get( $element_asked ) { - $this->current_id = $element_asked; $file = $this->strips_list[$element_asked]; From 7a1146a56a7d683a2028831b71e8e61c40895e06 Mon Sep 17 00:00:00 2001 From: nojhan Date: Mon, 4 Feb 2008 14:40:14 +0000 Subject: [PATCH 003/127] renommage fichier de conf, infos anonymes --- configuration-dist.php | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 configuration-dist.php diff --git a/configuration-dist.php b/configuration-dist.php new file mode 100644 index 0000000..3e9047f --- /dev/null +++ b/configuration-dist.php @@ -0,0 +1,73 @@ + +* @license http://www.gnu.org/licenses/gpl.html GPL +* @copyright 2007 Johann Dréo +* +* @package stripit +*/ + +/** +* Configuration +*/ +class configuration +{ + + /** + * URL of the website + */ + var $url = 'http://localhost/stripit'; + + /** + * Title of the website + */ + var $title = 'Stripit'; + + /** + * Short description + * + * Is displayed as a subtitle + */ + var $description = 'Ce serait mieux avec des strips libres !'; + + /** + * Default language of the interface + */ + var $language = 'fr-FR'; + + /** + * Webmaster's name + */ + var $webmaster = 'inconnu'; + + /** + * Webmaster's email + */ + var $email = 'inconnu'; + + /** + * Forum URL + */ + var $forum = 'http://perdu.com'; + + /** + * Additional URL + */ + var $see_also = array( + 'Geekscottes' => 'http://www.nojhan.net/geekscottes' + ); + + /** + * Shop URL + */ + var $shop = 'http://perdu.com'; + + /** + * HTML template to use + */ + var $template_html = 'template_default.html'; +} + +?> From fc04dd79ac881c8abc239bb131a92f7bf0a406ba Mon Sep 17 00:00:00 2001 From: nojhan Date: Mon, 4 Feb 2008 14:43:15 +0000 Subject: [PATCH 004/127] damn msg changelog --- README | 1 + RELEASE | 2 ++ configuration.php | 82 ----------------------------------------------- 3 files changed, 3 insertions(+), 82 deletions(-) delete mode 100644 configuration.php diff --git a/README b/README index 776b9a7..3c8b31f 100644 --- a/README +++ b/README @@ -3,6 +3,7 @@ 1. Installation * copiez les fichiers dans le répertoire de votre choix sur le serveur +* renommez le fichier 'configuration-dist.php' en 'configuration.php' * éditez le fichier 'configuration.php' avec les valeurs de votre choix Attention, StripIt n'est testé que sur des fichiers SVG produits par le logiciel Inkscape. Il est très probable que les diff --git a/RELEASE b/RELEASE index 07e29ae..9793b40 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,6 @@ SVN : +* entrées du flux RSS en ordre inverse, permet une lecture plus agréable sous les aggrégateurs ne triant pas sur la date (FireFox, par exemple) +* fichier de configuration anonymisé Version 0.3 : * texte du SVG dans l'élément ALT de la balise image diff --git a/configuration.php b/configuration.php deleted file mode 100644 index bff5d04..0000000 --- a/configuration.php +++ /dev/null @@ -1,82 +0,0 @@ - -* @license http://www.gnu.org/licenses/gpl.html GPL -* @copyright 2007 Johann Dréo -* -* @package stripit -*/ - -/** -* Configuration -*/ -class configuration -{ - - /** - * URL of the website - */ - var $url = 'http://localhost/~nojhan/stripit/trunk'; - - /** - * Title of the website - */ - var $title = 'Geekscottes'; - - /** - * Short description - * - * Is displayed as a subtitle - */ - var $description = 'Des miettes libres'; - - /** - * Default language of the interface - */ - var $language = 'fr-FR'; - - /** - * Webmaster's name - */ - var $webmaster = 'nojhan'; - - /** - * Webmaster's email - */ - var $email = 'nojhan@gmail.com'; - - /** - * Forum URL - */ - var $forum = 'http://www.nojhan.net/geekscottes/forum'; - - /** - * Additional URL - */ - var $see_also = array( - 'Bash' => 'http://bash.org', - 'BashFr' => 'http://bashfr.org', - 'LinuxFr' => 'http://linuxfr.org', - 'Gary Larson' => 'http://www.thefarside.com/', - 'Calvin et Hobbes' => 'http://www.gocomics.com/calvinandhobbes/', - 'Le Chat' => 'http://www.geluck.com', - 'XKCD' => 'http://www.xkcd.com', - 'Piled Higher and Deeper' => 'http://www.phdcomics.com', - 'Wulffmorgenthaler' => 'http://www.wulffmorgenthaler.com', - 'User friendly' => 'http://ars.userfriendly.org' - ); - - /** - * Shop URL - */ - var $shop = 'http://geekscottes.spreadshirt.net/fr/FR/Shop'; - - /** - * HTML template to use - */ - var $template_html = 'template_default.html'; -} - -?> From 1590d37de04b3bae89e3b39308f0f1c502e6bbaa Mon Sep 17 00:00:00 2001 From: nojhan Date: Mon, 25 Feb 2008 21:16:17 +0000 Subject: [PATCH 005/127] script export/upload automatique --- stripit.py | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100755 stripit.py diff --git a/stripit.py b/stripit.py new file mode 100755 index 0000000..c97a564 --- /dev/null +++ b/stripit.py @@ -0,0 +1,343 @@ +#!/bin/env python +# -*- coding: utf-8 -*- + +import sys,os +from PIL import Image +import ftplib +import getopt +from elementtree import ElementTree +import unicodedata + +class Options: + + def __init__(self, argv, usage = "" ): + + # Message à afficher en cas de mauvaise utilisation des options + self.usage = usage + + self.options = {} + self.argv = argv + + def parse(self): + + # construction de la chaine argument pour getopt + gos_short = '' + gos_long = '' + + for o in self.options: + opt = self.options[o] + + # getopt demande deux chaines pour les typographies longues et courtes + gos_short += opt['short'] + gos_long += opt['long'] + + # si l'option prend un paramètre + if not opt['flag']: + gos_short += ':' + gos_long += '=' + + # parse la ligne de commande + try: + opts, args = getopt.getopt( self.argv[1:], gos_short, gos_long ) + except getopt.GetoptError: + print 'Unkown option' + self.print_usage() + sys.exit(2) + + # création des dicionnaires pour les valeurs + self.param = {} + self.is_flag = {} + s2l = {} # associations court:long + for o in self.options: + s2l[ self.options[o]['short'] ] = self.options[o]['long'] + + + # prend les valeurs indiquées sur la ligne de commande + for o,a in opts: + # court => on enlève un tiret + os = o[1:] + # long => on enlève deux tirets + ol = o[2:] + + # si c'est une option courte + if os in s2l: + # si c'est un flag + if self.options[ s2l[os] ]['flag']: + # demandé => vrai + self.options[ s2l[os] ]['value'] = True + else: + # prend la valeur indiquée + self.options[ s2l[os] ]['value'] = a + # si c'est une option longue + elif ol in self.options: + if self.options[ol]['flag']: + self.options[ ol ]['value'] = True + else: + self.options[ol]['value'] = a + + # retourne tout ce qui n'a pas été parsé + return args + + + def add( self, short, long, description, default='' ): + flag = False + if default==True or default==False: + flag = True + self.options [ long ] = { 'short':short, 'long':long, 'description':description, 'default':default, 'flag':flag, 'value':default } + + + def print_usage(self): + print self.usage + + for o in self.options: + print "\t-%s, --%s\t%s." % ( self.options[o]['short'], self.options[o]['long'], self.options[o]['description'] ) + + def print_state(self): + print "Options settings:" + for o in self.options: + print "\t%s=%s (%s)" % ( self.options[o]['long'], self.options[o]['value'], self.options[o]['default'] ) + + def get( self, long ): + return self.options[long]['value'] + +# +# XPath-friendlier ElementTree namespace helper +# http://infix.se/2007/02/21/xpath-friendlier-elementtree-namespace-helper +# +class NS: + def __init__(self, uri): + self.uri = '{'+uri+'}' + def __getattr__(self, tag): + return self.uri + tag + def __call__(self, path): + return "/".join((tag not in ("", ".", "*")) + and getattr(self, tag) + or tag + for tag in path.split("/")) + + +class Stripit: + def __init__( self, verbose=False ): + self.verbose = verbose + + # + # wrapper around PIL 1.1.6 Image.save to preserve PNG metadata + # + # public domain, Nick Galbreath + # http://blog.modp.com/2007/08/python-pil-and-png-metadata-take-2.html + # + def pngsave(self, im, file): + # these can be automatically added to Image.info dict + # they are not user-added metadata + reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect') + + # undocumented class + from PIL import PngImagePlugin + meta = PngImagePlugin.PngInfo() + + # copy metadata into new object + for k,v in im.info.iteritems(): + if k in reserved: continue + meta.add_text(k, v, 0) + + # and save + im.save(file, "PNG", pnginfo=meta) + + + def export( self, file_we, max_size=None, options='' ): + """file name only, without extension""" + + if self.verbose: + print '\tCreating the PNG from the SVG...', + sys.stdout.flush() + + size_arg='' + if max_size: + w = os.popen( 'inkscape --query-width %s.svg' % (file_we) ) + h = os.popen( 'inkscape --query-height %s.svg' % (file_we) ) + + width = float(w.read()) + height = float(h.read()) + ratio = height/width + max_size = float( max_size ) + + w.close() + h.close() + + if height > width: + size_arg += ' --export-height=%f' % (max_size) + size_arg += ' --export-width=%f' % (max_size / ratio) + else: + size_arg += ' --export-height=%f' % (max_size * ratio) + size_arg += ' --export-width=%f' % (max_size) + + + cmd = 'inkscape -z %s --export-png %s.png %s.svg ' % (size_arg, file_we,file_we) + cmd += options + + #if self.verbose: + # print ' " %s " ' % (cmd) + # sys.stdout.flush() + + os.popen( cmd ) + + if self.verbose: + print '\tok' + + + def xfind( self, tree, ns ): + # on ne veut passer qu'un liste d'élements + q = '//' + '/'.join( ns ) + + # requête sur le xml + res = unicode( tree.findtext( q ) ) + + # la norme PNG demande de l'ASCII, on essaye de convertir au mieux + return unicodedata.normalize('NFKD', res ).encode('ASCII', 'ignore') + + + def get_svg_metadata( self, file_we ): + + if self.verbose: + print '\tGet SVG metadata...', + sys.stdout.flush() + + # raccourcis pour les namespaces + DC = NS('http://purl.org/dc/elements/1.1/') + CC = NS('http://web.resource.org/cc/') + RDF = NS('http://www.w3.org/1999/02/22-rdf-syntax-ns#') + SVG = NS('http://www.w3.org/2000/svg') + + tree = ElementTree.parse( file_we + '.svg') + + # PNG metadata textual informations : + # (from http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.Anc-text ) + # + # Title Short (one line) title or caption for image + # Author Name of image's creator + # Description Description of image (possibly long) + # Copyright Copyright notice + # Creation Time Time of original image creation + # Software Software used to create the image + # Disclaimer Legal disclaimer + # Warning Warning of nature of content + # Source Device used to create the image + # Comment Miscellaneous comment; conversion from + # GIF comment + + metadata = {} + metadata['Author'] = self.xfind( tree, [ CC('Agent'), DC('title') ] ) + metadata['Description'] = self.xfind( tree, [ CC('Work'), DC('description') ]) + metadata['Copyright'] = self.xfind( tree, [ CC('Work'), CC('license') ] ) # FIXME ne marche pas + metadata['Creation Time'] = self.xfind( tree, [ CC('Work'), DC('date') ] ) + metadata['Software'] = 'www.inkscape.org / stripit.sourceforge.net' # FIXME pas très élégant + metadata['Disclaimer'] ='' + metadata['Warning'] = '' + metadata['Source'] = self.xfind( tree, [ CC('Work'), DC('source') ]) + lang = self.xfind( tree, [ CC('Work'), DC('language') ]) + metadata['Comment'] = 'Language: %s' % lang + + if self.verbose: + print '\t\t\tok' + return metadata + + + def save_png_with_metadata( self, file_we, metadata ): + if self.verbose: + print '\tWrite metadata in the PNG...\t', + sys.stdout.flush() + + Image.init() + im = Image.open( file_we+'.png' ) + im.info = metadata + #print im.info + self.pngsave( im, file_we+'.png' ) + if self.verbose: + print '\tok' + + + def upload( self, file_we, host, user, dir, password ): + if self.verbose: + print '\tUpload of %s on %s.\t' % (file_we, host), + sys.stdout.flush() + ftp = ftplib.FTP( host, user, password ) + ftp.cwd( dir ) + + if self.verbose: + print '.', + sys.stdout.flush() + + f_png = open( '%s.png' % file_we ) + ftp.storbinary( 'STOR %s.png' % file_we, f_png ) + f_png.close() + + if self.verbose: + print '.', + sys.stdout.flush() + + f_svg = open( '%s.svg' % file_we ) + ftp.storbinary( 'STOR %s.svg' % file_we, f_svg ) + f_svg.close() + + ftp.quit() + + if self.verbose: + print '\ŧok' + + + +if __name__=="__main__": + + usage = """Script d'aide à l'export et au téléchargement pour StripIt. +\tCe script va exporter un fichier SVG au format PNG, puis télécharger le tout sur un serveur FTP. +Usage: stripit.py [OPTIONS] fichier""" + + oo = Options( sys.argv, usage ) + + oo.add( 'H', 'host', 'Serveur FTP', '' ) + oo.add( 'u', 'user', 'Login FTP', 'anonymous' ) + oo.add( 'd', 'dir', 'Dossier FTP', 'strips' ) + oo.add( 'p', 'port', 'Port FTP', '21' ) + oo.add( 'P', 'pass', 'Mot de passe FTP', '' ) + oo.add( 'x', 'no-export', "Pas d'export PNG", False ) + oo.add( 'n', 'no-upload', 'Pas de téléchargement FTP', False ) + oo.add( 'v', 'verbose', "Afficher plus d'informations", False ) + oo.add( 's', 'supp', 'Options supplémentaires pour inkscape', '' ) + oo.add( 'h', 'help', "Ce message d'aide", False ) + oo.add( 'm', 'max-size', 'Taille maximale en hauteur ou en largeur, en pixels', '800' ) + + args = oo.parse() + #oo.print_state() + + if oo.get('help'): + oo.print_usage() + sys.exit() + + while args: + + f = args.pop() + + # supprime l'extension + f = os.path.splitext( f ) [0] + + if oo.get('verbose'): + print "Processing %s:" % os.path.basename( f ) + + si = Stripit( oo.get('verbose') ) + + if not oo.get('no-export'): + si.export( f, oo.get('max-size'), oo.get('supp') ) + + md = si.get_svg_metadata( f ) + + si.save_png_with_metadata( f, md ) + + if not oo.get('no-upload'): + si.upload( + f, + oo.get('host'), + oo.get('user'), + oo.get('dir'), + oo.get('pass') + ) # FIXME options ou .conf ? + From ab8bf4aad78ae66c5c1b2a42032213f382958142 Mon Sep 17 00:00:00 2001 From: nojhan Date: Fri, 7 Mar 2008 13:08:07 +0000 Subject: [PATCH 006/127] =?UTF-8?q?meilleure=20gestion=20des=20options,=20?= =?UTF-8?q?bugfix=20m=C3=A9tadonn=C3=A9es=20licence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stripit.py | 145 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 122 insertions(+), 23 deletions(-) diff --git a/stripit.py b/stripit.py index c97a564..9f353dc 100755 --- a/stripit.py +++ b/stripit.py @@ -7,19 +7,57 @@ import ftplib import getopt from elementtree import ElementTree import unicodedata +import ConfigParser class Options: - def __init__(self, argv, usage = "" ): - - # Message à afficher en cas de mauvaise utilisation des options - self.usage = usage - + def __init__(self, argv, usage = "", app_name = None ): self.options = {} self.argv = argv - def parse(self): + if app_name: + self.app_name = app_name + else: + # si aucun nom n'est précisé, on l'extrait de l'argv, mais sans l'extension + self.app_name = os.path.splitext( os.path.basename( argv[0] ) )[0] + + # Message à afficher en cas de mauvaise utilisation des options + usage += "\nUsage: %s [OPTIONS] arguments" % self.app_name + self.usage = usage + + + def __configure_file( self, filename ): + # prend les valeurs indiquées dans le fichier de configuration + config = ConfigParser.ConfigParser() + + try: + config.readfp( open( filename ) ) + except: + return + + # Pour chaque option prévue + for o in self.options: + try: + # essaye de la lire dans le fichier de conf + a = config.get('default',o) + + # si c'est un flag + if self.options[o]['flag'] == True: + # il faut convertir en booléen + self.options[o]['value'] = bool( eval( a ) ) + else: + # sinon c'est un string + self.options[o]['value'] = a + + # on ajoute que ce fichier de conf à changer la valeur + self.options[o]['origin'] = filename + + except: + pass + + + def __configure_command( self ): # construction de la chaine argument pour getopt gos_short = '' gos_long = '' @@ -44,14 +82,14 @@ class Options: self.print_usage() sys.exit(2) - # création des dicionnaires pour les valeurs - self.param = {} - self.is_flag = {} s2l = {} # associations court:long for o in self.options: + short = self.options[o]['short'] + # lève une erreur si l'option courte a déjà été déclarée + if short in s2l: + raise "Short option '%s' already declared for the options '%s', please use another letter for the option '%s'." % (short, s2l[short], o ) s2l[ self.options[o]['short'] ] = self.options[o]['long'] - # prend les valeurs indiquées sur la ligne de commande for o,a in opts: # court => on enlève un tiret @@ -68,34 +106,64 @@ class Options: else: # prend la valeur indiquée self.options[ s2l[os] ]['value'] = a + self.options[ s2l[os] ]['origin'] = 'command line' # si c'est une option longue elif ol in self.options: if self.options[ol]['flag']: self.options[ ol ]['value'] = True else: self.options[ol]['value'] = a + self.options[ol]['origin'] = 'command line' # retourne tout ce qui n'a pas été parsé return args + def parse(self): + # on essaye d'abord le fichier de conf général + self.__configure_file( '%s.conf' % self.app_name ) + + # puis on essaye le fichier de conf utilisateur + self.__configure_file( os.path.join( os.path.expanduser('~'), '.%s.conf' % self.app_name ) ) + + # enfin, la ligne de commande + args = self.__configure_command() + + return args + + def add( self, short, long, description, default='' ): flag = False if default==True or default==False: flag = True - self.options [ long ] = { 'short':short, 'long':long, 'description':description, 'default':default, 'flag':flag, 'value':default } + + # si l'option est déjà présente + if long in self.options: + raise "Long option '%s' already declared, please use another one." % long + else: + self.options [ long ] = { + 'short':short, # identifiant court (une lettre) + 'long':long, # identifiant long + 'description':description, # texte de description + 'origin':'hard coded', # source de la valeur + 'flag':flag, # indicateur de flag + 'value':default } # valeur de l'option def print_usage(self): print self.usage for o in self.options: - print "\t-%s, --%s\t%s." % ( self.options[o]['short'], self.options[o]['long'], self.options[o]['description'] ) + fs = "\t-%s, --%s\t\t%s" + # si pas un flag, indique qu'il faut un paramètre + if not self.options[o]['flag']: + fs = "\t-%s, --%s\t=VAL\t%s" + print fs % ( self.options[o]['short'], self.options[o]['long'], self.options[o]['description'] ) def print_state(self): print "Options settings:" for o in self.options: - print "\t%s=%s (%s)" % ( self.options[o]['long'], self.options[o]['value'], self.options[o]['default'] ) + print "\t%s='%s' (%s)" % ( self.options[o]['long'], self.options[o]['value'], self.options[o]['origin'] ) def get( self, long ): return self.options[long]['value'] @@ -144,7 +212,7 @@ class Stripit: im.save(file, "PNG", pnginfo=meta) - def export( self, file_we, max_size=None, options='' ): + def export( self, file_we, options='', max_size=None ): """file name only, without extension""" if self.verbose: @@ -196,6 +264,29 @@ class Stripit: return unicodedata.normalize('NFKD', res ).encode('ASCII', 'ignore') + def xfind_attribute( self, tree, ns ): + # pour une raison qui m'échappe, ElementTree ne considère pas les attributs comme des sous-éléments de chaque noeud + # cette fonction est donc un hack pour pallier le problème + + # les premiers éléments sont considérés comme des noeuds de la requête xpath + q = '//' + '/'.join( ns[0:-1] ) + # le dernier est l'attribut + attribute = ns[-1] + + # on récupère l'objet élément + el = tree.find( q) + + # les attributs sont récupérables dans une liste de tuples (!) + # on convertit donc en dictionnaire, plus logique + # TODO vérifier (quand même) s'il ne peut pas y avoir plusieurs attributs identiques + attr = dict( el.items() ) + + # ce qui permet de récupérer le contenu directement avec l'identifiant + res = unicode( attr[attribute] ) + + return unicodedata.normalize('NFKD', res ).encode('ASCII', 'ignore') + + def get_svg_metadata( self, file_we ): if self.verbose: @@ -228,7 +319,9 @@ class Stripit: metadata = {} metadata['Author'] = self.xfind( tree, [ CC('Agent'), DC('title') ] ) metadata['Description'] = self.xfind( tree, [ CC('Work'), DC('description') ]) - metadata['Copyright'] = self.xfind( tree, [ CC('Work'), CC('license') ] ) # FIXME ne marche pas + + metadata['Copyright'] = self.xfind_attribute( tree, [ CC('Work'),CC('license'),RDF('resource') ] ) + metadata['Creation Time'] = self.xfind( tree, [ CC('Work'), DC('date') ] ) metadata['Software'] = 'www.inkscape.org / stripit.sourceforge.net' # FIXME pas très élégant metadata['Disclaimer'] ='' @@ -236,7 +329,7 @@ class Stripit: metadata['Source'] = self.xfind( tree, [ CC('Work'), DC('source') ]) lang = self.xfind( tree, [ CC('Work'), DC('language') ]) metadata['Comment'] = 'Language: %s' % lang - + if self.verbose: print '\t\t\tok' return metadata @@ -288,9 +381,9 @@ class Stripit: if __name__=="__main__": - usage = """Script d'aide à l'export et au téléchargement pour StripIt. -\tCe script va exporter un fichier SVG au format PNG, puis télécharger le tout sur un serveur FTP. -Usage: stripit.py [OPTIONS] fichier""" + usage = """Aide à l'export et au téléchargement pour StripIt. +\tCe script va exporter un ou plusieurs fichiers SVG au format PNG, en préservant les métadonnées ; +\tpuis télécharger le tout sur un serveur FTP.""" oo = Options( sys.argv, usage ) @@ -304,10 +397,13 @@ Usage: stripit.py [OPTIONS] fichier""" oo.add( 'v', 'verbose', "Afficher plus d'informations", False ) oo.add( 's', 'supp', 'Options supplémentaires pour inkscape', '' ) oo.add( 'h', 'help', "Ce message d'aide", False ) - oo.add( 'm', 'max-size', 'Taille maximale en hauteur ou en largeur, en pixels', '800' ) + oo.add( 'z', 'size', "Limiter la taille du PNG", False ) + oo.add( 'm', 'max-size', 'Taille maximale en hauteur ou en largeur, en pixels', '800') args = oo.parse() - #oo.print_state() + + if oo.get('verbose'): + oo.print_state() if oo.get('help'): oo.print_usage() @@ -326,7 +422,10 @@ Usage: stripit.py [OPTIONS] fichier""" si = Stripit( oo.get('verbose') ) if not oo.get('no-export'): - si.export( f, oo.get('max-size'), oo.get('supp') ) + if oo.get('size'): + si.export( f, oo.get('supp'), oo.get('max-size') ) + else: + si.export( f, options=oo.get('supp') ) md = si.get_svg_metadata( f ) @@ -339,5 +438,5 @@ Usage: stripit.py [OPTIONS] fichier""" oo.get('user'), oo.get('dir'), oo.get('pass') - ) # FIXME options ou .conf ? + ) From 3b57df8b495fda72aaccb0ac9164df2bb80a87a1 Mon Sep 17 00:00:00 2001 From: nojhan Date: Fri, 7 Mar 2008 13:09:46 +0000 Subject: [PATCH 007/127] =?UTF-8?q?m=C3=A0j=20explications?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README | 51 ++++++++++++++++++++++++++++++++++++++++----------- RELEASE | 3 +++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/README b/README index 3c8b31f..360f78d 100644 --- a/README +++ b/README @@ -1,24 +1,53 @@ -- Français ------------------------------------------------------------------------------------------------------------- +StripIt est une application web de gestion de webcomic au format SVG. + +Fonctionnalités : +* Le webcomic est accessible sous forme de page web et en flux RSS. +* Les strips sont présentés un par un, avec boutons de naviguation. +* StripIt utilise les méta-données contenues dans les fichiers SVG pour présenter des informations supplémentaires (auteur, licence, description, etc.) +* Pour publier un strip, il suffit de lancer un script qui va convertir le SVG en PNG et le télécharger via FTP sur un site web. +* Les PNG produits conservent la plupart des méta-données du SVG. + +Contact : nojhan@gmail.com + + 1. Installation * copiez les fichiers dans le répertoire de votre choix sur le serveur * renommez le fichier 'configuration-dist.php' en 'configuration.php' * éditez le fichier 'configuration.php' avec les valeurs de votre choix + +2. Utilisation + +2.1 Conversion et téléchargement automatique + +Vous devez appeler le script python "stripit.py" en lui passant en argument le fichier SVG créé. +Il est possible de paramétrer le script (serveur FTP, options d'export, etc.) en utilisant un fichier "~/.stripit.conf", "./stripit.conf", ou encore en utilisant les options de la ligne de commande. + +Lancez "python stripit.py -h" pour plus d'informations. + + +2.2 Conversion et téléchargement manuel + +Vous devez exporter vous-même le fichier SVG au format PNG. +En effet, Strip-It ne convertit pas de lui-même les fichiers SVG en PNG à la volée. Les fichiers doivent évidemment avoir le même nom, à l'extension près. +Attention, il est probable que les méta-données ne soient pas incluent dans le PNG. Pour que les méta-données soient présente, utilisez le script (cf. 2.1). + +Vous devez télécharger à la fois les fichiers SVG et leur pendant PNG dans le répertoire 'strips/'. + +Strip-It extrait les informations à afficher de chaque fichier SVG. Ceux-ci doivent donc contenir des +méta-données (au format RDF). Le logiciel Inkscape propose d'éditer ces données via le menu "Fichier > méta-données". + + +3. Précautions + +Strip-It créé une page pour chaque fichier SVG présent, et les trie alphabétiquement sur leur nom. Pensez-donc à nommer +les fichiers de manière adéquate. + Attention, StripIt n'est testé que sur des fichiers SVG produits par le logiciel Inkscape. Il est très probable que les SVG issues d'autres logiciels ou de convertisseurs ne produisent pas les effets escomptés. -2. Utilisation - -Vous devez télécharger à la fois les fichiers SVG et leur pendant PNG dans le répertoire 'strips/'. -En effet, Strip-It ne convertit pas les fichiers SVG en PNG à la volée. Les fichiers doivent évidemment avoir -le même nom, à l'extension près. - -Strip-It extrait les informations à afficher de chaque fichier SVG. Ceux-ci doivent donc contenir des -méta-données au format RDF. Le logiciel Inkscape propose d'éditer ces données via le menu "Fichier > méta-données". - -Strip-It créer une page pour chaque fichier SVG présent, et les trie alphabétiquement sur leur nom. Pensez-donc à nommer -les fichiers de manière adéquate. diff --git a/RELEASE b/RELEASE index 9793b40..3fc308c 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,7 @@ SVN : +* script d'aide à l'export PNG et au téléchargement : + * ajout des métadonnées SVG lors de l'export + * configurable via la ligne de commande ou un fichier ~/.stripit.conf * entrées du flux RSS en ordre inverse, permet une lecture plus agréable sous les aggrégateurs ne triant pas sur la date (FireFox, par exemple) * fichier de configuration anonymisé From 65419836e766e58c9165e69fd494d9d629b12d94 Mon Sep 17 00:00:00 2001 From: Leblanc Simon Date: Fri, 21 Mar 2008 16:51:00 +0000 Subject: [PATCH 008/127] =?UTF-8?q?bug=20#1902085=20:=20le=20premier=20str?= =?UTF-8?q?ip=20est=20d=C3=A9sormais=20accessible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strip_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strip_manager.php b/strip_manager.php index 27b35a2..4f97b4a 100644 --- a/strip_manager.php +++ b/strip_manager.php @@ -293,7 +293,7 @@ class strip_manager $element_asked = -1; // If one ask for a particular strip - if( !isset($_GET['strip']) || empty($_GET['strip'])) { + if( !isset($_GET['strip']) || $_GET['strip'] == '' || !is_numeric($_GET['strip']) ) { $element_asked = $this->strips_count-1; } else { From 6dcfdba0e0601d2a45f4098cd5f919018933ad54 Mon Sep 17 00:00:00 2001 From: Leblanc Simon Date: Fri, 21 Mar 2008 17:22:20 +0000 Subject: [PATCH 009/127] =?UTF-8?q?R=C3=A9ponse=20en=20partie=20=C3=A0=20l?= =?UTF-8?q?a=20requ=C3=AAte=20#1886192.=20Une=20limitation=20du=20nombre?= =?UTF-8?q?=20de=20strip=20affich=C3=A9=20dans=20le=20flux=20rss=20en=20ap?= =?UTF-8?q?pellant=20le=20RSS=20de=20cette=20mani=C3=A8re:=20http://site/r?= =?UTF-8?q?ss.php=3Flimit=3D10=20(on=20affiche=20alors=20les=2010=20dernie?= =?UTF-8?q?rs=20strips)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rss.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rss.php b/rss.php index 7437443..444a8e0 100644 --- a/rss.php +++ b/rss.php @@ -52,8 +52,17 @@ class rss_manager $this->lang = $sm->lang; $sm->strips_list_get(); + + // limit the number of strip in RSS + $limit = 0; + if (isset($_GET['limit']) && is_numeric($_GET['limit'])) { + // check for have no infinite for + if ($_GET['limit'] > 0 && $_GET['limit'] < $sm->strips_count) { + $limit = $sm->strips_count - $_GET['limit']; + } + } - for( $i = $sm->strips_count-1; $i >= 0; $i-- ) { // reverser order + for( $i = $sm->strips_count-1; $i >= $limit; $i-- ) { // reverser order $sm->strip_info_get( $i ); // conversion iso8601 -> RFC822 From df3c91c6a46253f7cea3d13416c52bea40f98477 Mon Sep 17 00:00:00 2001 From: nojhan Date: Tue, 8 Apr 2008 09:55:08 +0000 Subject: [PATCH 010/127] preparation de la version 0.4 --- AUTHORS | 2 +- RELEASE | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index d5a9ed6..286ee85 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,4 +8,4 @@ N:Simon Leblanc P:Simon E:contact@leblanc-simon.eu D:2007-12 -C:Patch internationalisation +C:internationalisation, limitation items RSS, bugfixes diff --git a/RELEASE b/RELEASE index 3fc308c..51dc5c4 100644 --- a/RELEASE +++ b/RELEASE @@ -1,9 +1,12 @@ -SVN : + +Version 0.4 : * script d'aide à l'export PNG et au téléchargement : * ajout des métadonnées SVG lors de l'export * configurable via la ligne de commande ou un fichier ~/.stripit.conf * entrées du flux RSS en ordre inverse, permet une lecture plus agréable sous les aggrégateurs ne triant pas sur la date (FireFox, par exemple) * fichier de configuration anonymisé +* bugfix #1902085, le premier strip est désormais accessible +* possibilité de limiter le nombre d'items dans le flux rss, en passant un paramètre en argument : rss.php?limit=10 Version 0.3 : * texte du SVG dans l'élément ALT de la balise image From 0442f52da07c19aaa678355c4106837c10c556cb Mon Sep 17 00:00:00 2001 From: nojhan Date: Tue, 22 Apr 2008 19:34:13 +0000 Subject: [PATCH 011/127] autorise le html dans la description et les commentaires --- template_default.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/template_default.html b/template_default.html index edef5c1..8616151 100644 --- a/template_default.html +++ b/template_default.html @@ -44,7 +44,7 @@
« {title} »
-

{description}

+

{description:h}

© {author} : {date} : {lang.source}

{lang.licence} : {license}

@@ -56,6 +56,7 @@

{lang.forum}

+

{comments:h}

{lang.boutique} {general.title} {lang.teeshirt}.

{lang.see_also}