home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / serpentine / common.py < prev    next >
Encoding:
Python Source  |  2006-08-23  |  5.7 KB  |  166 lines

  1. # Copyright (C) 2005 Tiago Cogumbreiro <cogumbreiro@users.sf.net>
  2. #
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #
  17. # Authors: Tiago Cogumbreiro <cogumbreiro@users.sf.net>
  18.  
  19. import os
  20. import statvfs
  21. import sys
  22. import tempfile
  23.  
  24. from gettext import gettext as _
  25. from os import path
  26.  
  27.  
  28. class ApplicationLocations:
  29.     def __init__(self, root, appname):
  30.         self.root = path.abspath(root)
  31.         pyver = "python%d.%d" % sys.version_info[0:2]
  32.         self.lib = path.join(root, "lib", pyver, "site-packages")
  33.         self.data = path.join(root, "share", appname)
  34.         self.bin = path.join(root, "bin")
  35.         self.locale = path.join(root, "share", "locale")
  36.  
  37.     def get_data_file(self, filename):
  38.         return path.join(self.data, filename)
  39.     
  40.     def get_lib_file(self, filename):
  41.         return path.join(self.lib, filename)
  42.  
  43.     def get_bin_file(self, filename):
  44.         return path.join(self.bin, filename)
  45.  
  46.     def get_locale_file(self, filename):
  47.         return path.join(self.locale, filename)
  48.  
  49.     def get_root_file(self, filename):
  50.         return path.join(self.root, filename)
  51.  
  52.  
  53.  
  54. class SerpentineError (StandardError): pass
  55.  
  56. class SerpentineCacheError (SerpentineError):
  57.     INVALID = 1
  58.     NO_SPACE = 2
  59.     def __init__ (self, error_id, error_message):
  60.         self.__error_id = error_id
  61.         self.__error_message = error_message
  62.     
  63.     error_id = property (lambda self: self.__error_id)
  64.     error_message = property (lambda self: self.__error_message)
  65.     
  66.     def __str__ (self):
  67.         return "[Error %d] %s" % (self.error_id, self.error_message)
  68.  
  69. class SerpentineNotSupportedError (SerpentineError): pass
  70.  
  71. def __hig_bytes (bytes):
  72.     hig_desc = [(_("GByte"), _("GBytes")),
  73.                 (_("MByte"), _("MBytes")),
  74.                 (_("KByte"), _("KByte") ),
  75.                 (_("byte") , _("bytes") )]
  76.     value, strings = __decompose_bytes (bytes, 30, hig_desc)
  77.     return "%.1f %s" % (value, __plural (value, strings))
  78.  
  79. def __decompose_bytes (bytes, offset, hig_desc):
  80.     if bytes == 0:
  81.         return (0.0, hig_desc[-1:])
  82.     if offset == 0:
  83.         return (float (bytes), hig_desc[-1:])
  84.         
  85.     part = bytes >> offset
  86.     if part > 0:
  87.         sub_part = part ^ ((part >> offset) << offset)
  88.         return ((part * 1024 + sub_part) / 1024.0, hig_desc[0])
  89.     else:
  90.         del hig_desc[0]
  91.         return __decompose_bytes (bytes, offset - 10, hig_desc)
  92.  
  93. def __plural (value, strings):
  94.     if value == 1:
  95.         return strings[0]
  96.     else:
  97.         return strings[1]
  98.  
  99.  
  100. class SafeFileWrite:
  101.     """This class enables the user to safely write the contents to a file and
  102.     if something wrong happens the original file will not be damaged. It writes
  103.     the contents in a temporary file and when the file descriptor is closed the
  104.     contents are transfered to the real filename."""
  105.     
  106.     def __init__ (self, filename):
  107.         self.filename = filename
  108.         basedir = path.dirname (filename)
  109.         # must be in the same directory so that renaming works
  110.         fd, self.tmp_filename = tempfile.mkstemp (dir = basedir)
  111.         os.close (fd)
  112.         self.fd = open (self.tmp_filename, "w")
  113.         
  114.     def __getattr__ (self, attr):
  115.         return getattr (self.fd, attr)
  116.     
  117.     def close (self):
  118.         self.fd.close ()
  119.         
  120.         try:
  121.             os.unlink (self.filename)
  122.         except:
  123.             pass
  124.         os.rename (self.tmp_filename, self.filename)
  125.     
  126.     def abort (self):
  127.         """Abort is used to cancel the changes made and remove the temporary
  128.         file. The original filename will not be altered."""
  129.         self.fd.close ()
  130.         try:
  131.             os.unlink (self.tmp_filename)
  132.         except:
  133.             pass
  134.  
  135. def validate_music_list (music_list, preferences):
  136.     # Check if we have space available in our cache dir
  137.     secs = 0
  138.     for music in music_list:
  139.         # When music is not available it will have to be converted
  140.         if not preferences.pool.is_available (music["location"]):
  141.             secs += music["duration"]
  142.     # 44100hz * 16bit * 2channels / 8bits = 176400 bytes per sec
  143.     size_needed = secs * 176400L
  144.     
  145.     # Now check if cache location is ok
  146.     try:
  147.         s = os.statvfs (preferences.temporaryDir)
  148.         # Raise exception if temporary dir is not ok
  149.         assert preferences.temporaryDirIsOk
  150.     except OSError, AssertionError:
  151.         raise SerpentineCacheError (SerpentineCacheError.INVALID, _("Please "
  152.                                     "check if the cache location exists and "
  153.                                     "has writable permissions."))
  154.     
  155.     size_avail = s[statvfs.F_BAVAIL] * long(s[statvfs.F_BSIZE])
  156.     if (size_avail - size_needed) < 0:
  157.         preferences.pool.clear ()
  158.     
  159.     size_avail = s[statvfs.F_BAVAIL] * long(s[statvfs.F_BSIZE])
  160.     if (size_avail - size_needed) < 0:
  161.         raise SerpentineCacheError (SerpentineCacheError.NO_SPACE, _("Remove " 
  162.                                     "some music tracks or make sure your "     
  163.                                     "cache location location has enough free " 
  164.                                     "space (about %s).")
  165.                                     % __hig_bytes(size_needed - size_avail))
  166.