Package imagizer :: Module config'
[hide private]
[frames] | no frames]

Source Code for Module imagizer.config'

  1  #!/usr/bin/env python  
  2  # -*- coding: UTF8 -*- 
  3  #******************************************************************************\ 
  4  #* $Source$ 
  5  #* $Id$ 
  6  #* 
  7  #* Copyright (C) 2006 - 2009,  Jérome Kieffer <kieffer@terre-adelie.org> 
  8  #* Conception : Jérôme KIEFFER, Mickael Profeta & Isabelle Letard 
  9  #* Licence GPL v2 
 10  #* 
 11  #* This program is free software; you can redistribute it and/or modify 
 12  #* it under the terms of the GNU General Public License as published by 
 13  #* the Free Software Foundation; either version 2 of the License, or 
 14  #* (at your option) any later version. 
 15  #* 
 16  #* This program is distributed in the hope that it will be useful, 
 17  #* but WITHOUT ANY WARRANTY; without even the implied warranty of 
 18  #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 19  #* GNU General Public License for more details. 
 20  #* 
 21  #* You should have received a copy of the GNU General Public License 
 22  #* along with this program; if not, write to the Free Software 
 23  #* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 24  #* 
 25  #*****************************************************************************/ 
 26   
 27  """ 
 28  Config is a class containing all the configuration of the imagizer suite. 
 29  Technically it is a Borg (design Pattern) so every instance of Config has exactly the same contents. 
 30  """ 
 31   
 32  import os, locale, logging, ConfigParser 
 33  installdir = os.path.dirname(os.path.abspath(__file__)) 
 34   
 35  #here we detect the OS runnng the program so that we can call exftran in the right way 
 36  if os.name == 'nt': #sys.platform == 'win32': 
 37      ConfFile = [os.path.join(os.getenv("ALLUSERSPROFILE"), "imagizer.conf"), os.path.join(os.getenv("USERPROFILE"), "imagizer.conf"), "imagizer.conf"] 
 38  elif os.name == 'posix': 
 39      ConfFile = ["/etc/imagizer.conf", os.path.join(os.getenv("HOME"), ".imagizer"), ".imagizer"] 
 40  else: 
 41      raise OSError("Your platform does not seem to be an Unix nor a M$ Windows.\nI am sorry but the exiftran binary is necessary to run selector, and exiftran is probably not available for you plateform. If you have exiftran installed, please contact the developper to correct that bug, kieffer at terre-adelie dot org") 
 42   
 43   
 44   
 45  ################################################################################################ 
 46  ###############  Class Config for storing the cofiguratio in a Borg ############################ 
 47  ################################################################################################ 
48 -class Config:
49 """this class is a Borg : always returns the same values regardless to the instance of the object""" 50 __shared_state = {}
51 - def __init__(self):
52 """ 53 This is a Borg, so the constructor is more or less empty 54 """ 55 self.__dict__ = self.__shared_state 56 if len(self.__dict__) < 5: 57 logging.debug("Config: initializition of the class") 58 self.ScreenSize = 500 59 self.NbrPerPage = 20 60 self.PagePrefix = "page" 61 self.TrashDirectory = "Trash" 62 self.SelectedDirectory = "Selected" 63 self.Selected_save = ".selected-photos" 64 self.Extensions = [".jpg", ".jpeg", ".jpe", ".jfif"] 65 self.RawExtensions = [".cr2", ".arw", ".mrw", ".dng", ".pef", ".nef"] 66 self.AutoRotate = False 67 self.DefaultMode = "664" 68 self.DefaultRepository = os.getcwd() 69 self.CommentFile = "index.desc" 70 self.Interpolation = 1 71 self.DefaultFileMode = int(self.DefaultMode, 8) 72 self.DefaultDirMode = self.DefaultFileMode + 3145 #73 = +111 en octal ... 3145 +s mode octal 73 self.Filigrane = False 74 self.FiligraneSource = os.path.join(installdir, "signature.png") 75 self.FiligranePosition = 5 76 self.FiligraneQuality = 75 77 self.FiligraneOptimize = False 78 self.FiligraneProgressive = False 79 self.WebDirIndexStyle = "list" 80 self.MediaSize = 680 81 self.Burn = "grave-rep $Selected" 82 self.WebServer = "cp -r $Selected/* $WebRepository && generator" 83 self.WebRepository = "/var/www/imagizer" 84 self.Locale, self.Coding = locale.getdefaultlocale() 85 self.ExportSingleDir = False 86 self.GraphicMode = "Normal" 87 self.WebPageAnchor = "end" 88 self.SlideShowDelay = 5.0 89 self.SlideShowType = "chronological" 90 self.SynchronizeRep = "user@host:/mnt/photo" 91 self.SynchronizeType = "Newer" 92 self.ImageCache = 100 93 self.ImageWidth = None 94 self.ImageHeight = None 95 self.DEBUG = None 96 self.Gimp = "gimp" 97 self.Dcraw = "dcraw -w -c" 98 self.Thumbnails = { 99 "Size":160, 100 "Suffix": "thumb", 101 "Interpolation":1, 102 "Progressive":False, 103 "Optimize":False, 104 "ExifExtraction":True, 105 "Quality": 75 106 } 107 self.ScaledImages = { 108 "Size":800, 109 "Suffix": "scaled", 110 "Interpolation":1, 111 "Progressive":False, 112 "Optimize":False, 113 "ExifExtraction":False, 114 "Quality": 75 115 }
116
117 - def load(self, filenames):
118 """retrieves the the default options, if the filenames does not exist, uses the default instead 119 @param filenames: list of filename 120 @type filenames: list of strings or unicode 121 """ 122 logging.debug("Config.load") 123 configparser = ConfigParser.ConfigParser() 124 files = [] 125 for i in filenames: 126 if os.path.isfile(i):files.append(i) 127 if len(files) == 0: 128 logging.warning("No configuration file found. Falling back on defaults") 129 return 130 131 configparser.read(files) 132 for i in configparser.items("Selector"): 133 j = i[0] 134 if j == "ScreenSize".lower(): self.ScreenSize = int(i[1]) 135 elif j == "Interpolation".lower(): self.Interpolation = int(i[1]) 136 elif j == "PagePrefix".lower(): self.PagePrefix = i[1] 137 elif j == "NbrPerPage".lower(): self.NbrPerPage = int(i[1]) 138 elif j == "TrashDirectory".lower(): self.TrashDirectory = i[1] 139 elif j == "SelectedDirectory".lower():self.SelectedDirectory = i[1] 140 elif j == "Selected_save".lower(): self.Selected_save = i[1] 141 elif j == "AutoRotate".lower(): self.AutoRotate = configparser.getboolean("Selector", "AutoRotate") 142 elif j == "Filigrane".lower(): self.Filigrane = configparser.getboolean("Selector", "Filigrane") 143 elif j == "FiligraneSource".lower(): self.FiligraneSource = i[1] 144 elif j == "FiligranePosition".lower():self.FiligranePosition = int(i[1]) 145 elif j == "FiligraneQuality".lower(): self.FiligraneQuality = int(i[1]) 146 elif j == "FiligraneOptimize".lower():self.FiligraneOptimize = configparser.getboolean("Selector", "FiligraneOptimize") 147 elif j == "FiligraneProgressive".lower():self.FiligraneProgressive = configparser.getboolean("Selector", "FiligraneProgressive") 148 elif j == "CommentFile".lower(): self.CommentFile = i[1] 149 elif j == "WebDirIndexStyle".lower(): self.WebDirIndexStyle = i[1] 150 elif j == "DefaultFileMode".lower(): 151 self.DefaultFileMode = int(i[1], 8) 152 self.DefaultDirMode = self.DefaultFileMode + 3145 #73 = +111 en octal ... 3145 +s mode octal 153 elif j == "RawExtensions".lower(): self.RawExtensions = i[1].split() 154 elif j == "Extensions".lower(): self.Extensions = i[1].split() 155 elif j == "DefaultRepository".lower():self.DefaultRepository = i[1] 156 elif j == "MediaSize".lower(): self.MediaSize = float(i[1]) 157 elif j == "Burn".lower(): self.Burn = i[1] 158 elif j == "WebServer".lower(): self.WebServer = i[1] 159 elif j == "WebRepository".lower(): self.WebRepository = i[1] 160 elif j == "Locale".lower(): self.Locale = i[1] 161 elif j == "Coding".lower(): self.Coding = i[1] 162 elif j == "ExportSingleDir".lower(): self.ExportSingleDir = configparser.getboolean("Selector", "ExportSingleDir") 163 elif j == "WebPageAnchor".lower(): self.WebPageAnchor = i[1] 164 elif j == "SlideShowDelay".lower(): self.SlideShowDelay = float(i[1]) 165 elif j == "SlideShowType".lower(): self.SlideShowType = i[1] 166 elif j == "SynchronizeRep".lower(): self.SynchronizeRep = i[1] 167 elif j == "SynchronizeType".lower(): self.SynchronizeType = i[1] 168 elif j == "ImageCache".lower(): self.ImageCache = int(i[1]) 169 elif j == "ImageWidth".lower(): self.ImageWidth = int(i[1]) 170 elif j == "ImageHeight".lower(): self.ImageHeight = int(i[1]) 171 elif j == "gimp".lower(): self.Gimp = i[1] 172 elif j == "dcraw".lower(): self.Dcraw = i[1] 173 else: logging.warning("Config.load: unknown key %s" % j) 174 175 176 for k in ["ScaledImages", "Thumbnails"]: 177 try: 178 dico = eval(k) 179 except: 180 dico = {} 181 for i in configparser.items(k): 182 j = i[0] 183 if j == "Size".lower():dico["Size"] = int(i[1]) 184 elif j == "Suffix".lower():dico["Suffix"] = i[1] 185 elif j == "Interpolation".lower():dico["Interpolation"] = int(i[1]) 186 elif j == "Progressive".lower():dico["Progressive"] = configparser.getboolean(k, "Progressive") 187 elif j == "Optimize".lower():dico["Optimize"] = configparser.getboolean(k, "Optimize") 188 elif j == "ExifExtraction".lower():dico["ExifExtraction"] = configparser.getboolean(k, "ExifExtraction") 189 elif j == "Quality".lower():dico["Quality"] = int(i[1]) 190 exec("self.%s=dico" % k)
191
192 - def __repr__(self):
193 logging.debug("Config.__repr__") 194 listtxt = ["", 195 "Size on the images on the Screen: %s pixels in the largest dimension" % self.ScreenSize, 196 "Page prefix:\t\t\t %s" % self.PagePrefix, 197 "Number of images per page:\t %s" % self.NbrPerPage, 198 "Use Exif for Auto-Rotate:\t %s" % self.AutoRotate, 199 "Default mode for files (octal):\t %o" % self.DefaultFileMode, 200 "JPEG extensions:\t\t %s" % self.Extensions, 201 "Default photo repository:\t %s" % self.DefaultRepository, 202 "Add signature for exported images:%s" % self.Filigrane, 203 "Backup media size (CD,DVD):\t %s MByte" % self.MediaSize, 204 "Scaled imagesSize:\t\t %s pixels in the largest dimension" % self.ScaledImages["Size"], 205 "Thumbnail Size:\t\t\t %s pixels in the largest dimension" % self.Thumbnails["Size"], 206 "Caching of %s images " % self.ImageCache 207 ] 208 return os.linesep.join(listtxt)
209 210
211 - def printConfig(self):
212 """ 213 Print out the 214 """ 215 logging.debug("Config.printConfig") 216 logging.info(self.__repr__())
217 218
219 - def saveConfig(self, filename):
220 """ 221 Saves the default options to file 222 223 @param filename: name of the file to save the configuration to 224 @type filename: string or unicode 225 """ 226 logging.debug("Config.saveConfig") 227 lsttxt = ["[Selector]", 228 "#Size of the image on the Screen, by default", "ScreenSize: %s" % self.ScreenSize, "", 229 "#Downsampling quality [0=nearest, 1=tiles, 2=bilinear, 3=hyperbolic]", "Interpolation: %s" % self.Interpolation, "", 230 "#Page prefix (used when there are too many images per day to fit on one web page)", "PagePrefix: %s" % self.PagePrefix, "", 231 "#Maximum number of images per web page", "NbrPerPage: %s" % self.NbrPerPage, "", 232 "#Trash sub-directory", "TrashDirectory: %s" % self.TrashDirectory, "", 233 "#Selected/processed images sub-directory", "SelectedDirectory: %s" % self.SelectedDirectory, "", 234 "#File containing the list of selected but unprocessed images", "Selected_save: %s" % self.Selected_save, "", 235 "#Use Exif data for auto-rotation of the images (canon cameras mainly)", "AutoRotate: %s" % self.AutoRotate, "", 236 "#Default mode for files (in octal)", "DefaultFileMode: %o" % self.DefaultFileMode, "", 237 "#Default JPEG extensions", "Extensions: " + " ".join(self.Extensions), "", 238 "#Default Raw images extensions", "RawExtensions: " + " ".join(self.RawExtensions), "", 239 "#Default photo repository", "DefaultRepository: %s" % self.DefaultRepository, "", 240 "#Size of the backup media (in MegaByte)", "MediaSize: %s" % self.MediaSize, "", 241 "#Add signature to web published images", "Filigrane: %s" % self.Filigrane, "", 242 "#File containing the image of the signature for the filigrane", "FiligraneSource: %s" % self.FiligraneSource, "", 243 "#Position of the filigrane : 0=center 12=top center 1=upper-right 3=center-right...", "FiligranePosition: %s" % self.FiligranePosition, "", 244 "#Quality of the saved image in filigrane mode (JPEG quality)", "FiligraneQuality: %s" % self.FiligraneQuality, "", 245 "#Optimize the filigraned image (2 pass JPEG encoding)", "FiligraneOptimize: %s" % self.FiligraneOptimize, "", 246 "#Progressive JPEG for saving filigraned images", "FiligraneProgressive: %s" % self.FiligraneProgressive, "", 247 "#File containing the description of the day in each directory", "CommentFile: %s" % self.CommentFile, "", 248 "#Style of the dirindex web pages, either <<list>> or <<table>>, the latest includes thumbnail photos", "WebDirIndexStyle: %s" % self.WebDirIndexStyle, "", 249 "#System command to use to burn a CD or a DVD", "# $Selected will be replaced by the directory where the files are", "Burn: %s" % self.Burn, "", 250 "#System command to copy the selection to the server", "# $Selected will be replaced by the directory where the files are", "# $WebRepository will be replaced by the directory of the root of generator", "WebServer: %s" % self.WebServer, "", 251 "#The location of the root of generator", "WebRepository: %s" % self.WebRepository, "", 252 "#The localization code, fr_FR is suggested for unix or FR for win32", "Locale: %s" % self.Locale, "", 253 "#Default encoding for text files, latin-1 is suggested,UTF-8 should be possible", "Coding: %s" % self.Coding, "", 254 "#All selected photos should be exported in a single directory", "ExportSingleDir: %s" % self.ExportSingleDir, "", 255 "#Where should the dirindex page start-up ? [begin/end] ", "WebPageAnchor: %s" % self.WebPageAnchor, "", 256 "#Delay between imges in the slideshow? ", "SlideShowDelay: %s" % self.SlideShowDelay, "", 257 "#Type of slideshow : chronological, anti-chronological or random ?", "SlideShowType: %s" % self.SlideShowType, "", 258 "#Remote repository to synchronize with (rsync like)", "SynchronizeRep: %s" % self.SynchronizeRep, "", 259 "#Synchronization type, acceptable values are Newer, Older, Selected and All", "SynchronizeType: %s" % self.SynchronizeType, "", 260 "#Allow the creation of a Cache of images with the given size in number of images", "ImageCache: %s" % self.ImageCache, "", 261 "#Gnu Image Manipulation Program (GIMP) path to executable", "Gimp: %s" % self.Gimp, "", 262 "#Digital Camera Raw (dcraw) extraction program and option (-w -c is suggested)", "Dcraw: %s" % self.Dcraw, ""] 263 if self.ImageWidth is not None: 264 lsttxt += ["#Width of the last image displayed ... should not be modified", "ImageWidth:%s" % self.ImageWidth, ""] 265 if self.ImageHeight is not None: 266 lsttxt += ["#Height of the last image displayed ... should not be modified", "ImageHeight:%s" % self.ImageHeight, ""] 267 268 269 for i in ["ScaledImages", "Thumbnails"]: 270 lsttxt += ["[%s]" % i, ""] 271 j = eval("self.%s" % i) 272 lsttxt += ["#%s size" % i, "Size: %s" % j["Size"], ""] 273 lsttxt += ["#%s suffix" % i, "Suffix: %s" % j["Suffix"], ""] 274 lsttxt += ["#%s downsampling quality [0=nearest, 1=antialias 2=bilinear, 3=bicubic]" % i, "Interpolation: %s" % j["Interpolation"], ""] 275 lsttxt += ["#%s progressive JPEG files" % i, "Progressive: %s" % j["Progressive"], ""] 276 lsttxt += ["#%s optimized JPEG (2 pass encoding)" % i, "Optimize: %s" % j["Optimize"], ""] 277 lsttxt += ["#%s quality (in percent)" % i, "Quality: %s" % j["Quality"], ""] 278 lsttxt += ["#%s image can be obtained by Exif extraction ?" % i, "ExifExtraction: %s" % j["ExifExtraction"], ""] 279 w = open(filename, "w") 280 w.write(os.linesep.join(lsttxt)) 281 w.close() 282 if self.DEBUG: 283 logging.info("Configuration saved to file %s" % filename)
284