~ubuntu-branches/ubuntu/feisty/aptoncd/feisty

« back to all changes in this revision

Viewing changes to utils.py

  • Committer: Bazaar Package Importer
  • Author(s): Rafael Proença
  • Date: 2007-02-02 14:00:59 UTC
  • Revision ID: james.westby@ubuntu.com-20070202140059-7p801vwa0h1yymq9
Tags: upstream-0.0.99+svn20070202
Import upstream version 0.0.99+svn20070202

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
# utils.py
 
4
#  
 
5
#  Author: Laudeci Oliveira <laudeci@gmail.com>
 
6
#          Rafael Proença   <cypherbios@ubuntu.com>
 
7
 
8
#  This program is free software; you can redistribute it and/or 
 
9
#  modify it under the terms of the GNU General Public License as 
 
10
#  published by the Free Software Foundation; either version 2 of the
 
11
#  License, or (at your option) any later version.
 
12
 
13
#  This program is distributed in the hope that it will be useful,
 
14
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#  GNU General Public License for more details.
 
17
 
18
#  You should have received a copy of the GNU General Public License
 
19
#  along with this program; if not, write to the Free Software
 
20
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
21
#  USA
 
22
 
 
23
import apt_inst
 
24
import apt_pkg
 
25
import gtk
 
26
import math
 
27
import fnmatch
 
28
import os
 
29
import pygtk
 
30
import shutil
 
31
import urllib
 
32
import gnomevfs
 
33
import re
 
34
import tarfile
 
35
import bz2
 
36
 
 
37
import config
 
38
 
 
39
def isValidFileName(filename):
 
40
    try:
 
41
        p=re.compile('[^0-9A-Za-z_\+\.,-]+')
 
42
        if p.search(filename):
 
43
            return False
 
44
        else:
 
45
            return True
 
46
    except:
 
47
        return False
 
48
    
 
49
def updateUI():
 
50
    while gtk.events_pending(): gtk.main_iteration() 
 
51
 
 
52
#  Do case insensitive wildcard search on column 1.
 
53
def TreeViewSearch( model, column, key, it, data):
 
54
    key, title = key.lower(), model.get_value(it, column).lower()
 
55
    return title.find(key) == -1
 
56
        
 
57
def getCDROM():
 
58
    vol_monitor =  gnomevfs.VolumeMonitor()
 
59
    volume = gnomevfs.Volume()
 
60
    drives = []
 
61
    for volume in vol_monitor.get_mounted_volumes():
 
62
        if volume.get_hal_udi() != None:
 
63
            vol_type = volume.get_device_type()
 
64
            if vol_type == gnomevfs.DEVICE_TYPE_CDROM or vol_type == gnomevfs.DEVICE_TYPE_VIDEO_DVD:
 
65
                drives.append(volume.get_drive())
 
66
    
 
67
    return drives
 
68
            
 
69
def packageTooltip(widget, e, tooltips, cell, emptyText="no information"):
 
70
     """ If emptyText is None, the cursor has to enter widget from a side that contains an item, otherwise no tooltip will be displayed. """
 
71
     try:
 
72
         (path, col, x, y) = widget.get_path_at_pos(int(e.x), int(e.y))
 
73
         it = widget.get_model().get_iter(path)
 
74
         value = widget.get_model().get_value(it, config.C_PKG)
 
75
         tooltips.set_tip(widget, value.get_pkg_ShortDescription())
 
76
         tooltips.enable()
 
77
     except:
 
78
         tooltips.set_tip(widget, emptyText)
 
79
            
 
80
def checkAccess(path):
 
81
    """Checks file/folder permissions and returns True if the file/folder could be accessed"""
 
82
    mRet = False
 
83
    if pathExists(path):
 
84
        if os.access(path, os.R_OK | os.W_OK | os.X_OK):
 
85
            mRet = True
 
86
        return mRet
 
87
 
 
88
def copyFile(source , destination):
 
89
    try:
 
90
        dest = os.path.dirname(destination)
 
91
        if not pathExists(dest):
 
92
            mkdir(dest)
 
93
        
 
94
        shutil.copyfile(source , destination)
 
95
    except Exception , e :
 
96
        print str(e)
 
97
 
 
98
def delFile( path):
 
99
    """ Deletes a file if it exists"""
 
100
    if fileExist(path):
 
101
        os.remove(path)
 
102
    
 
103
def removePath( path):
 
104
    """ Removes a directory path """
 
105
    try:
 
106
        shutil.rmtree(path, ignore_errors=True)
 
107
    except:
 
108
        pass
 
109
        
 
110
def pathExists( path):
 
111
    """Returns True if a path exists."""
 
112
    return os.path.isdir(path)
 
113
    
 
114
def fileExist( path):
 
115
    """Returns True if a file exist."""
 
116
    return os.path.isfile(path)
 
117
    
 
118
def mkdir( path, removeExisting = False):
 
119
    """ Create a full path, directory by directory"""
 
120
    #remove directiory if already exists
 
121
    if removeExisting:
 
122
        if pathExists(path):
 
123
            removePath(path)
 
124
                
 
125
    dirs = path.split("/")
 
126
    dir = ""
 
127
        
 
128
    for dirname in dirs:
 
129
        dir += dirname + "/"
 
130
        if not os.path.isdir(dir) and len(dir)>0:
 
131
            os.mkdir(dir)
 
132
            
 
133
def TimeFormat(value):
 
134
    #get days
 
135
    
 
136
    fDays = (value / 86400)
 
137
    tModDay = math.modf(fDays)
 
138
    Days = int(tModDay[1])
 
139
    decimalDays =tModDay[0]
 
140
    
 
141
    fTimeHour = decimalDays  * 24
 
142
 
 
143
     # Extract decimal from integer part
 
144
    tModHour = math.modf(fTimeHour)
 
145
    nHour = int(tModHour[1])
 
146
    fDecimalHour = tModHour[0]
 
147
    
 
148
    # Transform decimal in minutes
 
149
    fMinute = fDecimalHour*60
 
150
    # Again, extract the decimal and the integer part
 
151
    tModMinute = math.modf(fMinute)
 
152
    nMinute = int(tModMinute[1])
 
153
    fDecimalMinute = tModMinute[0]
 
154
    # Transform decimal in seconds
 
155
    fSecond = fDecimalMinute*60    
 
156
    # Again, extract the decimal and the integer part
 
157
    tModSecond = math.modf(fSecond)
 
158
    nSecond = int(tModSecond[1])
 
159
    
 
160
    
 
161
    output=''
 
162
    if Days >0:
 
163
        output = '%id' % Days
 
164
 
 
165
    if nHour >0:
 
166
        output+='%ih' % nHour
 
167
    
 
168
    if nMinute >0:
 
169
        output+='%im' % nMinute
 
170
    
 
171
    output+='%is' % nSecond
 
172
    
 
173
    return output
 
174
 
 
175
 
 
176
def fileSizeFormat( i):
 
177
    """
 
178
        Taken from jinja
 
179
        Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
 
180
        102 bytes, etc).
 
181
    """
 
182
    bytes = float(i)
 
183
    if bytes < 1024:
 
184
        return u"%d Byte%s" % (bytes, bytes != 1 and u's' or u'')
 
185
    elif bytes < 1024 * 1024:
 
186
        return u"%.1f KB" % (bytes / 1024)
 
187
    elif bytes < 1024 * 1024 * 1024:
 
188
        return u"%.1f MB" % (bytes / (1024 * 1024))
 
189
    else:
 
190
        return u"%.1f GB" % (bytes / (1024 * 1024 * 1024)) 
 
191
 
 
192
def openSelectDialog(title, filterName, pattern, selectMultiple = False):
 
193
        
 
194
    file_open = gtk.FileChooserDialog(title=title, 
 
195
                          action=gtk.FILE_CHOOSER_ACTION_OPEN, 
 
196
                          buttons=(gtk.STOCK_CANCEL, 
 
197
                          gtk.RESPONSE_CANCEL, 
 
198
                          gtk.STOCK_OPEN, gtk.RESPONSE_OK))
 
199
    filter = gtk.FileFilter()
 
200
    filter.set_name(filterName)
 
201
    filter.add_pattern(pattern)
 
202
    file_open.add_filter(filter)
 
203
    file_open.set_select_multiple(selectMultiple)
 
204
        
 
205
    result = ""
 
206
    path = ""
 
207
    filename = ""
 
208
    if file_open.run() == gtk.RESPONSE_OK:
 
209
        file_open.hide()
 
210
        results = file_open.get_filenames()
 
211
        file_open.destroy()
 
212
        return gtk.RESPONSE_OK, results
 
213
    else:
 
214
        file_open.destroy()
 
215
        return gtk.RESPONSE_CANCEL, []
 
216
        
 
217
def getFilePathFromUrl( uri):
 
218
     """ helper to get a useful path from a drop uri"""
 
219
     path = urllib.url2pathname(uri) # escape special chars
 
220
     path = path.strip('\r\n\x00') # remove \r\n and NULL
 
221
     # get the path to file
 
222
     if path.startswith('file:\\\\\\'): # windows
 
223
         path = path[8:] # 8 is len('file:///')
 
224
     elif path.startswith('file://'): # nautilus, rox
 
225
         path = path[7:] # 7 is len('file://')
 
226
     elif path.startswith('file:'): # xffm
 
227
         path = path[5:] # 5 is len('file:')
 
228
     return path          
 
229
 
 
230
class cursorManager:
 
231
 
 
232
        def __init__(self):
 
233
                self.window = None
 
234
 
 
235
        #procedure to change window cursor to ready cursor
 
236
        def setBusy(self, window_main = None, flag = True):
 
237
                """ Show a watch cursor if the app is busy for more than 0.3 sec.
 
238
                Furthermore provide a loop to handle user interface events """
 
239
                if window_main is None:
 
240
                        return
 
241
                self.window = window_main.window
 
242
                if flag == True:
 
243
                        try:
 
244
                                self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
 
245
                        except:
 
246
                                print "An error occured changing cursor"
 
247
                else:
 
248
                        self.window.set_cursor(None)
 
249
                        while gtk.events_pending():
 
250
                                gtk.main_iteration()
 
251
 
 
252
                return
 
253
    
 
254
class ContextMenu(gtk.Menu):
 
255
    def __init__(self, *args):
 
256
        gtk.Menu.__init__(self)
 
257
        self.menuItem = None
 
258
         
 
259
    def addMenuItem(self,menuName,actionFunction= None):
 
260
        
 
261
        if menuName == "-":
 
262
            self.menuItem = gtk.SeparatorMenuItem()
 
263
        else: 
 
264
            self.menuItem = gtk.MenuItem(menuName)
 
265
            if actionFunction is not None :
 
266
                self.menuItem.connect("activate", actionFunction)
 
267
        self.menuItem.show()
 
268
        self.append(self.menuItem)
 
269
        return
 
270
    
 
271
class SystemInfo:
 
272
 
 
273
    def __init__(self):
 
274
        self.distro = ''
 
275
        self.architecture = ''
 
276
        self.codename = ''
 
277
        self.release = ''
 
278
        self.read_release_info()
 
279
        
 
280
    def read_release_info(self):
 
281
 
 
282
        self.get_infos()
 
283
        self.architecture = self.__architecture()
 
284
   
 
285
    def get_infos(self):
 
286
  
 
287
        try:
 
288
            p = open('/etc/lsb-release','r')
 
289
            for line in p:
 
290
                if 'DISTRIB_ID' in line:
 
291
                    self.distro = line.split('=')[-1].replace('\n','').lower()
 
292
                elif 'DISTRIB_CODENAME' in line:
 
293
                    self.codename = line.split('=')[-1].replace('\n','').lower()
 
294
                elif 'DISTRIB_RELEASE' in line:
 
295
                    self.release = line.split('=')[-1].replace('\n','').lower()
 
296
            p.close()
 
297
        except:
 
298
            pass
 
299
 
 
300
    def __architecture(self):
 
301
        """
 
302
        Detect whether the architecture is x86/ppc/amd64
 
303
        """
 
304
        arch = os.uname()[-1]
 
305
        if arch in ('ppc', 'ppc64'):
 
306
            arch = 'powerpc'
 
307
        elif arch in ('sparc32','sparc64','sparc'):
 
308
            arch = 'sparc'
 
309
        elif arch =='x86_64':
 
310
            if self.distro in ('debian'):
 
311
                arch = 'ia64'
 
312
            else:
 
313
                arch = 'amd64'
 
314
        elif arch in ('i386','i686','i586','k7'):
 
315
            arch = 'i386'
 
316
 
 
317
        return arch
 
318
        
 
319
class RecursiveSearch:
 
320
    def __init__(self, directory, pattern="*"):
 
321
        self.stack = [directory]
 
322
        self.pattern = pattern
 
323
        self.files = []
 
324
        self.index = 0
 
325
 
 
326
    def __getitem__(self, index):
 
327
        while 1:
 
328
            try:
 
329
                file = self.files[self.index]
 
330
                self.index = self.index + 1
 
331
            except IndexError:
 
332
                # pop next directory from stack
 
333
                self.directory = self.stack.pop()
 
334
                self.files = os.listdir(self.directory)
 
335
                self.index = 0
 
336
            else:
 
337
                # got a filename
 
338
                fullname = os.path.join(self.directory, file)
 
339
                if os.path.isdir(fullname) and not os.path.islink(fullname):
 
340
                    self.stack.append(fullname)
 
341
                if fnmatch.fnmatch(file, self.pattern):
 
342
                    return fullname
 
343
                    
 
344
def compress(source, dest):
 
345
    dest_ext = '.bz2'
 
346
    arcname = os.path.basename (source)
 
347
    dest_name = '%s%s' % (dest, dest_ext)
 
348
    dest_path = os.path.join(dest, dest_name)
 
349
 
 
350
    input = bz2.compress(file(source, 'r').read())
 
351
    out = file(dest_path,'w')
 
352
    out.write(input)
 
353
    out.close()
 
354
    return dest_path