2 # -*- coding: utf-8 -*-
3 #################################################################################
4 # LAYMAN OVERLAY BASE CLASS
5 #################################################################################
8 # Base class for the different overlay types.
11 # (c) 2005 - 2008 Gunnar Wrobel
12 # Distributed under the terms of the GNU General Public License v2
15 # Gunnar Wrobel <wrobel@gentoo.org>
17 ''' Basic overlay class.'''
19 __version__
= "$Id: overlay.py 273 2006-12-30 15:54:50Z wrobel $"
21 #===============================================================================
25 #-------------------------------------------------------------------------------
27 import sys
, types
, re
, os
, os
.path
, shutil
, subprocess
29 from layman
.utils
import node_to_dict
, dict_to_node
, path
31 from layman
.debug
import OUT
33 #===============================================================================
37 #-------------------------------------------------------------------------------
40 ''' Derive the real implementations from this.'''
44 def __init__(self
, xml
, ignore
= 0, quiet
= False):
46 >>> here = os.path.dirname(os.path.realpath(__file__))
47 >>> document = open(here + '/../tests/testfiles/global-overlays.xml').read()
48 >>> import xml.dom.minidom
49 >>> document = xml.dom.minidom.parseString(document)
50 >>> overlays = document.getElementsByTagName('overlay')
51 >>> a = Overlay(overlays[0])
57 u'https://overlays.gentoo.org/svn/dev/wrobel'
64 >>> b = Overlay(overlays[1])
70 self
.data
= node_to_dict(xml
)
72 if '&name' in self
.data
.keys():
73 self
.name
= self
.data
['&name']
75 raise Exception('Overlay is missing a "name" attribute!')
77 if '&src' in self
.data
.keys():
78 self
.src
= self
.data
['&src']
80 raise Exception('Overlay "' + self
.name
+ '" is missing a "src" '
83 if '&contact' in self
.data
.keys():
84 self
.contact
= self
.data
['&contact']
88 raise Exception('Overlay "' + self
.name
+ '" is missing a '
89 '"contact" attribute!')
91 OUT
.warn('Overlay "' + self
.name
+ '" is missing a '
92 '"contact" attribute!', 4)
94 if '<description>1' in self
.data
.keys():
95 self
.description
= self
.data
['<description>1']['@'].strip()
99 raise Exception('Overlay "' + self
.name
+ '" is missing a '
100 '"description" entry!')
102 OUT
.warn('Overlay "' + self
.name
+ '" is missing a '
103 '"description" entry!', 4)
105 if '&status' in self
.data
.keys():
106 self
.status
= self
.data
['&status']
110 if '&priority' in self
.data
.keys():
111 self
.priority
= int(self
.data
['&priority'])
115 def set_priority(self
, priority
):
116 '''Set the priority of this overlay.'''
118 self
.data
['&priority'] = str(priority
)
119 self
.priority
= int(priority
)
121 def to_minidom(self
, document
):
122 '''Convert to xml.'''
124 return dict_to_node(self
.data
, document
, 'overlay')
126 def add(self
, base
, quiet
= False):
127 '''Add the overlay.'''
129 mdir
= path([base
, self
.name
])
131 if os
.path
.exists(mdir
):
132 raise Exception('Directory ' + mdir
+ ' already exists. Will not ov'
133 'erwrite its contents!')
137 def sync(self
, base
, quiet
= False):
138 '''Sync the overlay.'''
141 def delete(self
, base
):
142 '''Delete the overlay.'''
143 mdir
= path([base
, self
.name
])
145 if not os
.path
.exists(mdir
):
146 raise Exception('Directory ' + mdir
+ ' does not exist. Cannot remo'
151 def cmd(self
, command
):
154 OUT
.info('Running command "' + command
+ '"...', 2)
156 if hasattr(sys
.stdout
,'encoding'):
157 enc
= sys
.stdout
.encoding
or sys
.getfilesystemencoding()
159 command
= command
.encode(enc
)
162 return os
.system(command
)
164 cmd
= subprocess
.Popen([command
], shell
= True,
165 stdout
= subprocess
.PIPE
,
166 stderr
= subprocess
.PIPE
,
173 >>> here = os.path.dirname(os.path.realpath(__file__))
174 >>> document = open(here + '/../tests/testfiles/global-overlays.xml').read()
175 >>> import xml.dom.minidom
176 >>> document = xml.dom.minidom.parseString(document)
177 >>> overlays = document.getElementsByTagName('overlay')
178 >>> a = Overlay(overlays[0])
182 Source : https://overlays.gentoo.org/svn/dev/wrobel
183 Contact : nobody@gentoo.org
184 Type : None; Priority: 10
193 result
+= self
.name
+ u
'\n' + (len(self
.name
) * u
'~')
195 result
+= u
'\nSource : ' + self
.src
196 result
+= u
'\nContact : ' + self
.contact
197 result
+= u
'\nType : ' + self
.type
198 result
+= u
'; Priority: ' + str(self
.priority
) + u
'\n'
200 description
= self
.description
201 description
= re
.compile(u
' +').sub(u
' ', description
)
202 description
= re
.compile(u
'\n ').sub(u
'\n', description
)
203 result
+= u
'\nDescription:'
204 result
+= u
'\n '.join((u
'\n' + description
).split(u
'\n'))
207 if '<link>1' in self
.data
.keys():
208 link
= self
.data
['<link>1']['@'].strip()
209 link
= re
.compile(u
' +').sub(u
' ', link
)
210 link
= re
.compile(u
'\n ').sub(u
'\n', link
)
211 result
+= u
'\nLink:\n'
212 result
+= u
'\n '.join((u
'\n' + link
).split(u
'\n'))
217 def short_list(self
, width
= 0):
219 >>> here = os.path.dirname(os.path.realpath(__file__))
220 >>> document = open(here + '/../tests/testfiles/global-overlays.xml').read()
221 >>> import xml.dom.minidom
222 >>> document = xml.dom.minidom.parseString(document)
223 >>> overlays = document.getElementsByTagName('overlay')
224 >>> a = Overlay(overlays[0])
225 >>> print a.short_list(80)
226 wrobel [None ] (https://o.g.o/svn/dev/wrobel )
229 def pad(string
, length
):
230 '''Pad a string with spaces.'''
231 if len(string
) <= length
:
232 return string
+ ' ' * (length
- len(string
))
234 return string
[:length
- 3] + '...'
236 def terminal_width():
237 '''Determine width of terminal window.'''
239 width
= int(os
.environ
['COLUMNS'])
245 import struct
, fcntl
, termios
246 query
= struct
.pack('HHHH', 0, 0, 0, 0)
247 response
= fcntl
.ioctl(1, termios
.TIOCGWINSZ
, query
)
248 width
= struct
.unpack('HHHH', response
)[1]
255 name
= pad(self
.name
, 25)
256 mtype
= ' [' + pad(self
.type, 10) + ']'
258 width
= terminal_width()
261 if len(source
) > srclen
:
262 source
= source
.replace("overlays.gentoo.org", "o.g.o")
263 source
= ' (' + pad(source
, srclen
) + ')'
265 return name
+ mtype
+ source
267 def supported(self
, binaries
= []):
268 '''Is the overlay type supported?'''
271 for mpath
, mtype
, package
in binaries
:
272 if not os
.path
.exists(mpath
):
273 raise Exception('Binary ' + mpath
+ ' seems to be missing!'
274 ' Overlay type "' + mtype
+ '" not support'
275 'ed. Did you emerge ' + package
+ '?')
279 def is_supported(self
):
280 '''Is the overlay type supported?'''
285 except Exception, error
:
288 def is_official(self
):
289 '''Is the overlay official?'''
291 return self
.status
== 'official'
293 #================================================================================
297 #--------------------------------------------------------------------------------
299 if __name__
== '__main__':
301 doctest
.testmod(sys
.modules
[__name__
])