eigenes duplicity ebuild nicht mehr nötig => 0.4.2-r1 im tree
Bernd Wurst

Bernd Wurst commited on 2007-03-09 07:15:52
Zeige 9 geänderte Dateien mit 1 Einfügungen und 801 Löschungen.

... ...
@@ -1,64 +0,0 @@
1
-# ChangeLog for app-backup/duplicity
2
-# Copyright 2002-2006 Gentoo Foundation; Distributed under the GPL v2
3
-# $Header: /var/cvsroot/gentoo-x86/app-backup/duplicity/ChangeLog,v 1.8 2006/04/30 16:06:59 dertobi123 Exp $
4
-
5
-  30 Apr 2006; Tobias Scherbaum <dertobi123@gentoo.org>
6
-  duplicity-0.4.2.ebuild:
7
-  ppc stable
8
-
9
-  27 Apr 2006; Marien Zwart <marienz@gentoo.org>
10
-  files/digest-duplicity-0.4.1, files/digest-duplicity-0.4.2, Manifest:
11
-  Fixing SHA256 digest for real, pass three...
12
-
13
-  27 Apr 2006; Marien Zwart <marienz@gentoo.org>
14
-  files/digest-duplicity-0.4.1, files/digest-duplicity-0.4.2, Manifest:
15
-  Fixing SHA256 digest, pass two.
16
-
17
-  17 Apr 2006; <ticho@gentoo.org> duplicity-0.4.2.ebuild:
18
-  Stable on x86.
19
-
20
-*duplicity-0.4.2 (12 Mar 2006)
21
-
22
-  12 Mar 2006; <ticho@gentoo.org> +duplicity-0.4.2.ebuild:
23
-  Version bump. Closes bug #125928, reported by Jiri Tyr <jiri.tyr at
24
-  e-learning.vslib.cz>.
25
-
26
-  15 Oct 2005; Joseph Jezak <josejx@gentoo.org> duplicity-0.4.1.ebuild:
27
-  Marked ppc stable for bug #106067.
28
-
29
-  04 Jul 2005; Robin H. Johnson <robbat2@gentoo.org> +metadata.xml,
30
-  +duplicity-0.4.1.ebuild:
31
-  Moved from net-misc/duplicity to app-backup/duplicity.
32
-
33
-  10 May 2005; David Holm <dholm@gentoo.org> duplicity-0.4.1.ebuild:
34
-  Added to ~ppc.
35
-
36
-  16 Nov 2004; Andrej Kacian <ticho@gentoo.org> -duplicity-0.4.0.ebuild:
37
-  Removed 0.4.0 from portage.
38
-
39
-  10 Nov 2004; Andrej Kacian <ticho@gentoo.org> duplicity-0.4.1.ebuild:
40
-  Fixed librsync dependancy. Closes bug #70595, reported by Dave S
41
-  <jk@pusspaws.net>.
42
-
43
-  01 Nov 2004; Andrej Kacian <ticho@gentoo.org> duplicity-0.4.1.ebuild:
44
-  Stable on x86
45
-
46
-  24 Oct 2004; Andrej Kacian <ticho@gentoo.org> +metadata.xml,
47
-  duplicity-0.4.0.ebuild, duplicity-0.4.1.ebuild:
48
-  Revamped DEPEND and RDEPEND. Made 0.4.0 depend on librsync <=0.9.5.1. This
49
-  closes #67940, reported by Dave S <jk@pusspaws.net>. Set myself as
50
-  maintainer (and added missing metadata.xml).
51
-
52
-  01 Jul 2004; Jon Hood <squinky86@gentoo.org> duplicity-0.4.0.ebuild,
53
-  duplicity-0.4.1.ebuild:
54
-  change virtual/glibc to virtual/libc, add IUSE
55
-
56
-*duplicity-0.4.1 (19 Oct 2003)
57
-
58
-  19 Oct 2003; Martin Holzer <mholzer@gentoo.org> duplicity-0.4.1.ebuild:
59
-  Version bumped. Closes #30179.
60
-
61
-*duplicity-0.4.0 (14 May 2003)
62
-
63
-  14 May 2003; Martin Holzer <mholzer@gentoo.org> duplicity-0.4.0.ebuild :
64
-  Initial Version submitted by rob holland <robh@gentoo.org> in #20693
... ...
@@ -1,28 +0,0 @@
1
-AUX duplicity-0.4.2-timeout-fixed-backends.py 21964 RMD160 cb0ba56204b2e7786e40f74f44e4cc3b1d4d7f48 SHA1 10c726c8b030df15169035132abdcc612526a2f8 SHA256 ed9885708025607991c7a7e38194b1dbb7886cda15c1f150616b234e8d17a66f
2
-MD5 61d0b9a78dc5c56f6a91f92621b18bd1 files/duplicity-0.4.2-timeout-fixed-backends.py 21964
3
-RMD160 cb0ba56204b2e7786e40f74f44e4cc3b1d4d7f48 files/duplicity-0.4.2-timeout-fixed-backends.py 21964
4
-SHA256 ed9885708025607991c7a7e38194b1dbb7886cda15c1f150616b234e8d17a66f files/duplicity-0.4.2-timeout-fixed-backends.py 21964
5
-DIST duplicity-0.4.1.tar.gz 101626 RMD160 192ce5111fbe408d5927292ae8b5eb8bc21319bd SHA256 b46ff5fe7c89283c635e2a94294d28ec8a501a9d58c41f5672943fb0e5daa725
6
-DIST duplicity-0.4.2.tar.gz 103183 RMD160 c6c86f397e43b7d5f63965d69f3328daa601d00b SHA1 37e861218800910fab7590f45520e0f1d8b318d4 SHA256 5fdf8aeb32bb4c09e3c9d5c4150245a71d757d31d9bb341524de75e06421e176
7
-EBUILD duplicity-0.4.1.ebuild 703 RMD160 a52bcc6a407764788cb039999284fe7c6cb6370b SHA1 2991533ae94bb5f257ba733d8987af447bcbc3cd SHA256 4053ca1afcfe01cb93467a5682d1edbc855b27dc288f790be28ac65224b37058
8
-MD5 ed7b72a8780e38926badaa0bf866ac8d duplicity-0.4.1.ebuild 703
9
-RMD160 a52bcc6a407764788cb039999284fe7c6cb6370b duplicity-0.4.1.ebuild 703
10
-SHA256 4053ca1afcfe01cb93467a5682d1edbc855b27dc288f790be28ac65224b37058 duplicity-0.4.1.ebuild 703
11
-EBUILD duplicity-0.4.2.ebuild 971 RMD160 4c97979827820363b78c2f2fc42824574d1dca37 SHA1 2f7f6eb94ccf3e6d7174ef2996ee000bb3f0be08 SHA256 e682a7d29e628db56f46a6b1e624189d7146ad741dc6cd82b6db1f9bfbbe76b7
12
-MD5 5725f0dfb95d3a8487d03fa071c06053 duplicity-0.4.2.ebuild 971
13
-RMD160 4c97979827820363b78c2f2fc42824574d1dca37 duplicity-0.4.2.ebuild 971
14
-SHA256 e682a7d29e628db56f46a6b1e624189d7146ad741dc6cd82b6db1f9bfbbe76b7 duplicity-0.4.2.ebuild 971
15
-MISC ChangeLog 2376 RMD160 e07cb927b91de7a24214867724478ae7cd0c72bc SHA1 59d1f6d02f22eb398bd38acb7edd2901b605dff6 SHA256 6871437952da46a60888f349516b959be9da053b8c75b9142216c59166b13fdf
16
-MD5 48cff4f1ce16bc800cc7869e57fb0e53 ChangeLog 2376
17
-RMD160 e07cb927b91de7a24214867724478ae7cd0c72bc ChangeLog 2376
18
-SHA256 6871437952da46a60888f349516b959be9da053b8c75b9142216c59166b13fdf ChangeLog 2376
19
-MISC metadata.xml 250 RMD160 b80f36e207a57583a06b1ddb538793eac15397fe SHA1 7aa5562e71958d16a80076a7cdd0e4002eeb99a0 SHA256 5e1a7d2736303cec3dc620e1951c9a809be04bfe07760d89741f824b7760bfaf
20
-MD5 bd9e210457c22384582e7c1394314d3f metadata.xml 250
21
-RMD160 b80f36e207a57583a06b1ddb538793eac15397fe metadata.xml 250
22
-SHA256 5e1a7d2736303cec3dc620e1951c9a809be04bfe07760d89741f824b7760bfaf metadata.xml 250
23
-MD5 66ccbbbe31ea6d7d887f161ca910c6af files/digest-duplicity-0.4.1 247
24
-RMD160 d3757d5050f0cf4495ab1c6abc051a360c06cee4 files/digest-duplicity-0.4.1 247
25
-SHA256 c547e600067221be62b903f26b628cb244acf5f3ca4c71b3bc8591b585a0c484 files/digest-duplicity-0.4.1 247
26
-MD5 6d9ae5885e91f1ad9c46ecab2e4ae8c8 files/digest-duplicity-0.4.2 247
27
-RMD160 3ff2413e0aa240285377c4c987043995968edca2 files/digest-duplicity-0.4.2 247
28
-SHA256 3abc53cada3b4e46dba6de362adf476af57166107f8055b2aa29c0bebf8008fd files/digest-duplicity-0.4.2 247
... ...
@@ -1,26 +0,0 @@
1
-# Copyright 1999-2005 Gentoo Foundation
2
-# Distributed under the terms of the GNU General Public License v2
3
-# $Header: /var/cvsroot/gentoo-x86/app-backup/duplicity/duplicity-0.4.1.ebuild,v 1.2 2005/10/15 20:37:48 josejx Exp $
4
-
5
-IUSE=""
6
-DESCRIPTION="duplicity is a secure backup system using gnupg to encrypt data"
7
-HOMEPAGE="http://www.nongnu.org/duplicity/"
8
-SRC_URI="http://savannah.nongnu.org/download/${PN}/${P}.tar.gz"
9
-
10
-LICENSE="GPL-2"
11
-SLOT="0"
12
-KEYWORDS="ppc x86"
13
-
14
-DEPEND="virtual/libc
15
-	>=dev-lang/python-2.3
16
-	>=net-libs/librsync-0.9.6"
17
-RDEPEND="${DEPEND}
18
-	app-crypt/gnupg"
19
-
20
-src_compile() {
21
-	python setup.py build || die "compile failed"
22
-}
23
-
24
-src_install() {
25
-	python setup.py install --prefix=${D}/usr
26
-}
... ...
@@ -1,43 +0,0 @@
1
-# Copyright 1999-2006 Gentoo Foundation
2
-# Distributed under the terms of the GNU General Public License v2
3
-# $Header: /var/cvsroot/gentoo-x86/app-backup/duplicity/duplicity-0.4.2.ebuild,v 1.3 2006/04/30 16:06:59 dertobi123 Exp $
4
-
5
-inherit distutils
6
-
7
-IUSE=""
8
-DESCRIPTION="duplicity is a secure backup system using gnupg to encrypt data"
9
-HOMEPAGE="http://www.nongnu.org/duplicity/"
10
-SRC_URI="http://savannah.nongnu.org/download/${PN}/${P}.tar.gz"
11
-
12
-LICENSE="GPL-2"
13
-SLOT="0"
14
-KEYWORDS="ppc x86"
15
-
16
-DEPEND="virtual/libc
17
-	>=dev-lang/python-2.3
18
-	>=net-libs/librsync-0.9.6"
19
-RDEPEND="${DEPEND}
20
-	app-crypt/gnupg"
21
-
22
-src_unpack() {
23
-	unpack ${A}
24
-	cp ${FILESDIR}/duplicity-0.4.2-timeout-fixed-backends.py ${S}/src/backends.py
25
-}
26
-
27
-src_compile() {
28
-	distutils_src_compile
29
-}
30
-
31
-src_install() {
32
-	python setup.py install --prefix=${D}/usr
33
-}
34
-
35
-pkg_postinst() {
36
-	python_version
37
-	python_mod_optimize /usr/lib/python${PYVER}/site-packages/duplicity
38
-}
39
-
40
-pkg_postrm() {
41
-	python_version
42
-	python_mod_cleanup
43
-}
... ...
@@ -1,3 +0,0 @@
1
-MD5 c91933a10f97057b899ba97673ad8a63 duplicity-0.4.1.tar.gz 101626
2
-RMD160 192ce5111fbe408d5927292ae8b5eb8bc21319bd duplicity-0.4.1.tar.gz 101626
3
-SHA256 b46ff5fe7c89283c635e2a94294d28ec8a501a9d58c41f5672943fb0e5daa725 duplicity-0.4.1.tar.gz 101626
... ...
@@ -1,3 +0,0 @@
1
-MD5 a9fd4094f23bb36c82cc1dc2816a5b7d duplicity-0.4.2.tar.gz 103183
2
-RMD160 c6c86f397e43b7d5f63965d69f3328daa601d00b duplicity-0.4.2.tar.gz 103183
3
-SHA256 5fdf8aeb32bb4c09e3c9d5c4150245a71d757d31d9bb341524de75e06421e176 duplicity-0.4.2.tar.gz 103183
... ...
@@ -1,624 +0,0 @@
1
-# Copyright 2002 Ben Escoto
2
-#
3
-# This file is part of duplicity.
4
-#
5
-# Duplicity is free software; you can redistribute it and/or modify it
6
-# under the terms of the GNU General Public License as published by the
7
-# Free Software Foundation; either version 2 of the License, or (at your
8
-# option) any later version.
9
-#
10
-# Duplicity is distributed in the hope that it will be useful, but
11
-# WITHOUT ANY WARRANTY; without even the implied warranty of
12
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
-# General Public License for more details.
14
-#
15
-# You should have received a copy of the GNU General Public License
16
-# along with duplicity; if not, write to the Free Software Foundation,
17
-# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
-
19
-"""Provides functions and classes for getting/sending files to destination"""
20
-
21
-import os, types, ftplib, tempfile, time, sys
22
-import log, path, dup_temp, file_naming
23
-import socket
24
-
25
-# TODO: move into globals?
26
-socket.setdefaulttimeout(10)
27
-
28
-class BackendException(Exception): pass
29
-class ParsingException(Exception): pass
30
-
31
-def get_backend(url_string):
32
-	"""Return Backend object from url string, or None if not a url string
33
-
34
-	url strings are like
35
-	scp://foobar:password@hostname.net:124/usr/local.  If a protocol
36
-	is unsupported a fatal error will be raised.
37
-
38
-	"""
39
-	global protocol_class_dict
40
-	try: pu = ParsedUrl(url_string)
41
-	except ParsingException: return None
42
-
43
-	try: backend_class = protocol_class_dict[pu.protocol]
44
-	except KeyError: log.FatalError("Unknown protocol '%s'" % (pu.protocol,))
45
-	return backend_class(pu)
46
-
47
-class ParsedUrl:
48
-	"""Contains information gleaned from a generic url"""
49
-	protocol = None # set to string like "ftp" indicating protocol
50
-	suffix = None # Set to everything after protocol://
51
-
52
-	server = None # First part of suffix (part before '/')
53
-	path = None # Second part of suffix (part after '/')
54
-
55
-	host = None # Set to host, if can be extracted
56
-	user = None # Set to user, as in ftp://user@host/whatever
57
-	port = None # Set to port, like scp://host:port/foo
58
-
59
-	def __init__(self, url_string):
60
-		"""Create ParsedUrl object, process url_string"""
61
-		self.url_string = url_string
62
-		self.set_protocol_suffix()
63
-		self.set_server_path()
64
-		self.set_host_user_port()
65
-
66
-	def bad_url(self, message = None):
67
-		"""Report a bad url, using message if given"""
68
-		if message:
69
-			err_string = "Bad URL string '%s': %s" % (self.url_string, message)
70
-		else: err_string = "Bad URL string '%s'" % (self.url_string,)
71
-		raise ParsingException(err_string)
72
-
73
-	def set_protocol_suffix(self):
74
-		"""Parse self.url_string, setting self.protocol and self.suffix"""
75
-		colon_position = self.url_string.find(":")
76
-		if colon_position < 1: self.bad_url("No colon (:) found")
77
-		self.protocol = self.url_string[:colon_position]
78
-		if self.url_string[colon_position+1:colon_position+3] != '//':
79
-			self.bad_url("first colon not followed by '//'")
80
-		self.suffix = self.url_string[colon_position+3:]
81
-
82
-	def set_server_path(self):
83
-		"""Set self.server and self.path from self.suffix"""
84
-		comps = self.suffix.split('/')
85
-		assert len(comps) > 0
86
-		self.server = comps[0]
87
-		if len(comps) > 1:
88
-			self.path = '/'.join(comps[1:])
89
-
90
-	def set_host_user_port(self):
91
-		"""Set self.host, self.user, and self.port from self.server"""
92
-		if not self.server: return
93
-
94
-		# Extract port
95
-		port_comps = self.server.split(":")
96
-		if len(port_comps) >= 2:
97
-			try: self.port = int(port_comps[-1])
98
-			except ValueError: user_host = self.server
99
-			else: user_host = ":".join(port_comps[:-1])
100
-		else: user_host = self.server
101
-
102
-		# Set user and host
103
-		user_comps = user_host.split("@")
104
-		if len(user_comps) >= 2:
105
-			self.user = user_comps[0]
106
-			self.host = "@".join(user_comps[1:])
107
-		else: self.host = user_host
108
-
109
-
110
-class Backend:
111
-	"""Represent a connection to the destination device/computer
112
-
113
-	Classes that subclass this should implement the put, get, list,
114
-	and delete methods.
115
-
116
-	"""
117
-	def put(self, source_path, remote_filename = None):
118
-		"""Transfer source_path (Path object) to remote_filename (string)
119
-
120
-		If remote_filename is None, get the filename from the last
121
-		path component of pathname.
122
-
123
-		"""
124
-		if not remote_filename: remote_filename = source_path.get_filename()
125
-		pass
126
-
127
-	def get(self, remote_filename, local_path):
128
-		"""Retrieve remote_filename and place in local_path"""
129
-		local_path.setdata()
130
-		pass
131
-
132
-	def list(self):
133
-		"""Return list of filenames (strings) present in backend"""
134
-		pass
135
-
136
-	def delete(self, filename_list):
137
-		"""Delete each filename in filename_list, in order if possible"""
138
-		pass
139
-
140
-	def run_command(self, commandline):
141
-		"""Run given commandline with logging and error detection"""
142
-		log.Log("Running '%s'" % commandline, 5)
143
-		if os.system(commandline):
144
-			raise BackendException("Error running '%s'" % commandline)
145
-
146
-	def popen(self, commandline):
147
-		"""Run command and return stdout results"""
148
-		log.Log("Reading results of '%s'" % commandline, 5)
149
-		fout = os.popen(commandline)
150
-		results = fout.read()
151
-		if fout.close():
152
-			raise BackendException("Error running '%s'" % commandline)
153
-		return results
154
-
155
-	def get_fileobj_read(self, filename, parseresults = None):
156
-		"""Return fileobject opened for reading of filename on backend
157
-
158
-		The file will be downloaded first into a temp file.  When the
159
-		returned fileobj is closed, the temp file will be deleted.
160
-
161
-		"""
162
-		if not parseresults:
163
-			parseresults = file_naming.parse(filename)
164
-			assert parseresults, "Filename not correctly parsed"
165
-		tdp = dup_temp.new_tempduppath(parseresults)
166
-		self.get(filename, tdp)
167
-		tdp.setdata()
168
-		return tdp.filtered_open_with_delete("rb")
169
-
170
-	def get_fileobj_write(self, filename, parseresults = None,
171
-						  sizelist = None):
172
-		"""Return fileobj opened for writing, write to backend on close
173
-
174
-		The file will be encoded as specified in parseresults (or as
175
-		read from the filename), and stored in a temp file until it
176
-		can be copied over and deleted.
177
-
178
-		If sizelist is not None, it should be set to an empty list.
179
-		The number of bytes will be inserted into the list.
180
-
181
-		"""
182
-		if not parseresults:
183
-			parseresults = file_naming.parse(filename)
184
-			assert parseresults, "Filename %s not correctly parsed" % filename
185
-		tdp = dup_temp.new_tempduppath(parseresults)
186
-
187
-		def close_file_hook():
188
-			"""This is called when returned fileobj is closed"""
189
-			self.put(tdp, filename)
190
-			if sizelist is not None:
191
-				tdp.setdata()
192
-				sizelist.append(tdp.getsize())
193
-			tdp.delete()
194
-
195
-		fh = dup_temp.FileobjHooked(tdp.filtered_open("wb"))
196
-		fh.addhook(close_file_hook)
197
-		return fh
198
-
199
-	def get_data(self, filename, parseresults = None):
200
-		"""Retrieve a file from backend, process it, return contents"""
201
-		fin = self.get_fileobj_read(filename, parseresults)
202
-		buf = fin.read()
203
-		assert not fin.close()
204
-		return buf
205
-
206
-	def put_data(self, buffer, filename, parseresults = None):
207
-		"""Put buffer into filename on backend after processing"""
208
-		fout = self.get_fileobj_write(filename, parseresults)
209
-		fout.write(buffer)
210
-		assert not fout.close()
211
-
212
-	def close(self):
213
-		"""This is called when a connection is no longer needed"""
214
-		pass
215
-
216
-
217
-class LocalBackend(Backend):
218
-	"""Use this backend when saving to local disk
219
-
220
-	Urls look like file://testfiles/output.  Relative to root can be
221
-	gotten with extra slash (file:///usr/local).
222
-
223
-	"""
224
-	def __init__(self, parsed_url):
225
-		self.remote_pathdir = path.Path(parsed_url.suffix)
226
-
227
-	def put(self, source_path, remote_filename = None, rename = None):
228
-		"""If rename is set, try that first, copying if doesn't work"""
229
-		if not remote_filename: remote_filename = source_path.get_filename()
230
-		target_path = self.remote_pathdir.append(remote_filename)
231
-		log.Log("Writing %s" % target_path.name, 6)
232
-		if rename:
233
-			try: source_path.rename(target_path)
234
-			except OSError: pass
235
-			else: return
236
-		target_path.writefileobj(source_path.open("rb"))
237
-
238
-	def get(self, filename, local_path):
239
-		"""Get file and put in local_path (Path object)"""
240
-		source_path = self.remote_pathdir.append(filename)
241
-		local_path.writefileobj(source_path.open("rb"))
242
-
243
-	def list(self):
244
-		"""List files in that directory"""
245
-		return self.remote_pathdir.listdir()
246
-
247
-	def delete(self, filename_list):
248
-		"""Delete all files in filename list"""
249
-		assert type(filename_list) is not types.StringType
250
-		try:
251
-			for filename in filename_list:
252
-				self.remote_pathdir.append(filename).delete()
253
-		except OSError, e: raise BackendException(str(e))
254
-
255
-
256
-# The following can be redefined to use different shell commands from
257
-# ssh or scp or to add more arguments.  However, the replacements must
258
-# have the same syntax.  Also these strings will be executed by the
259
-# shell, so shouldn't have strange characters in them.
260
-ssh_command = "ssh"
261
-scp_command = "scp"
262
-sftp_command = "sftp"
263
-
264
-class scpBackend(Backend):
265
-	"""This backend copies files using scp.  List not supported"""
266
-	def __init__(self, parsed_url):
267
-		"""scpBackend initializer"""
268
-		self.host_string = parsed_url.server # of form user@hostname:port
269
-		self.remote_dir = parsed_url.path # can be empty string
270
-		if self.remote_dir: self.remote_prefix = self.remote_dir + "/"
271
-		else: self.remote_prefix = ""
272
-
273
-	def put(self, source_path, remote_filename = None):
274
-		"""Use scp to copy source_dir/filename to remote computer"""
275
-		if not remote_filename: remote_filename = source_path.get_filename()
276
-		commandline = "%s %s %s:%s%s" % \
277
-					  (scp_command, source_path.name, self.host_string,
278
-					   self.remote_prefix, remote_filename)
279
-		self.run_command(commandline)
280
-
281
-	def get(self, remote_filename, local_path):
282
-		"""Use scp to get a remote file"""
283
-		commandline = "%s %s:%s%s %s" % \
284
-					  (scp_command, self.host_string, self.remote_prefix,
285
-					   remote_filename, local_path.name)
286
-		self.run_command(commandline)
287
-		local_path.setdata()
288
-		if not local_path.exists():
289
-			raise BackendException("File %s not found" % local_path.name)
290
-
291
-	def list(self):
292
-		"""List files available for scp
293
-
294
-		Note that this command can get confused when dealing with
295
-		files with newlines in them, as the embedded newlines cannot
296
-		be distinguished from the file boundaries.
297
-
298
-		"""
299
-		commandline = ("echo -e 'cd %s\nls -1' | %s -b - %s" %
300
-					   (self.remote_dir, sftp_command, self.host_string))
301
-		l = self.popen(commandline).split('\n')[2:] # omit sftp prompts
302
-		return filter(lambda x: x, l)
303
-
304
-	def delete(self, filename_list):
305
-		"""Runs ssh rm to delete files.  Files must not require quoting"""
306
-		assert len(filename_list) > 0
307
-		pathlist = map(lambda fn: self.remote_prefix + fn, filename_list)
308
-		del_prefix = "echo 'rm "
309
-		del_postfix = ("' | %s -b - %s 1>/dev/null" %
310
-					   (sftp_command, self.host_string))
311
-		for fn in filename_list:
312
-			commandline = del_prefix + self.remote_prefix + fn + del_postfix
313
-			self.run_command(commandline)
314
-
315
-
316
-class sftpBackend(Backend):
317
-	"""This backend uses sftp to perform file operations"""
318
-	pass # Do this later
319
-
320
-
321
-class ftpBackend(Backend):
322
-	"""Connect to remote store using File Transfer Protocol"""
323
-	RETRY_SLEEP = 10 # time in seconds before reconnecting on errors (gets multiplied with the try counter)
324
-	RETRIES = 15 # number of retries
325
-
326
-	def __init__(self, parsed_url):
327
-		"""Create a new ftp backend object, log in to host"""
328
-		self.parsed_url = parsed_url
329
-		self.connect()
330
-
331
-	def connect(self):
332
-		"""Connect to self.parsed_url"""
333
-		self.ftp = ftplib.FTP()
334
-		self.is_connected = False
335
-		if self.parsed_url.port is None:
336
-			self.error_wrap('connect', self.parsed_url.host)
337
-		else: self.error_wrap('connect', self.parsed_url.host,
338
-							  self.parsed_url.port)
339
-		self.is_connected = True
340
-
341
-		if self.parsed_url.user is not None:
342
-			self.error_wrap('login', self.parsed_url.user, self.get_password())
343
-		else: self.error_wrap('login')
344
-		self.ftp.cwd(self.parsed_url.path)
345
-
346
-	def error_wrap(self, command, *args):
347
-		"""Run self.ftp.command(*args), but raise BackendException on error"""
348
-
349
-		# Log FTP command:
350
-		if command is 'login':
351
-			if log.verbosity > 8:
352
-				# Log full args at level 9:
353
-				log.Log("FTP: %s %s" % (command,args), 9)
354
-			else:
355
-				# replace password with stars:
356
-				log_args = list(args)
357
-				log_args[1] = '*' * len(log_args[1])
358
-				log.Log("FTP: %s %s" % (command,log_args), 5)
359
-		else:
360
-			log.Log("FTP: %s %s" % (command,args), 5)
361
-
362
-		# Execute:
363
-		tries = 0
364
-		while( True ):
365
-			tries = tries+1
366
-			try:
367
-				return ftplib.FTP.__dict__[command](self.ftp, *args)
368
-			except ftplib.all_errors, e:
369
-				if "450" in str(e) and command == 'nlst':
370
-					# 450 on list isn't an error, but indicates an empty dir
371
-					return []
372
-
373
-				if tries > self.RETRIES:
374
-					# Give up:
375
-					log.FatalError("Catched exception %s%s (%d exceptions in total), giving up.." % (sys.exc_info()[0],sys.exc_info()[1],tries,))
376
-					raise BackendException(e)
377
-
378
-				# Sleep and retry (after trying to reconnect, if possible):
379
-				sleep_time = self.RETRY_SLEEP * tries;
380
-				log.Warn("Catched exception %s%s (#%d), sleeping %ds before retry.." % (sys.exc_info()[0],sys.exc_info()[1],tries,sleep_time,))
381
-				time.sleep(sleep_time)
382
-				try:
383
-					if self.is_connected:
384
-						self.connect()
385
-					return ftplib.FTP.__dict__[command](self.ftp, *args)
386
-				except ftplib.all_errors, e:
387
-					continue
388
-			else: break
389
-
390
-	def get_password(self):
391
-		"""Get ftp password using environment if possible"""
392
-		try: return os.environ['FTP_PASSWORD']
393
-		except KeyError:
394
-			log.Log("FTP_PASSWORD not set, using empty ftp password", 3)
395
-			return ''
396
-
397
-	def put(self, source_path, remote_filename = None):
398
-		"""Transfer source_path to remote_filename"""
399
-		if not remote_filename: remote_filename = source_path.get_filename()
400
-		source_file = source_path.open("rb")
401
-		log.Log("Saving %s on FTP server" % (remote_filename,), 5)
402
-		self.error_wrap('storbinary', "STOR "+remote_filename, source_file)
403
-		assert not source_file.close()
404
-
405
-	def get(self, remote_filename, local_path):
406
-		"""Get remote filename, saving it to local_path"""
407
-		target_file = local_path.open("wb")
408
-		log.Log("Retrieving %s from FTP server" % (remote_filename,), 5)
409
-		self.error_wrap('retrbinary', "RETR "+remote_filename,
410
-						target_file.write)
411
-		assert not target_file.close()
412
-		local_path.setdata()
413
-
414
-	def list(self):
415
-		"""List files in directory"""
416
-		log.Log("Listing files on FTP server", 5)
417
-		# Some ftp servers raise error 450 if the directory is empty
418
-		try: return self.error_wrap('nlst')
419
-		except BackendException, e:
420
-			if "450" in str(e) or "500" in str(e) or "550" in str(e):
421
-				return []
422
-			raise
423
-
424
-	def delete(self, filename_list):
425
-		"""Delete files in filename_list"""
426
-		for filename in filename_list:
427
-			log.Log("Deleting %s from FTP server" % (filename,), 5)
428
-			self.error_wrap('delete', filename)
429
-
430
-	def close(self):
431
-		"""Shut down connection"""
432
-		try: self.error_wrap('quit')
433
-		except BackendException, e:
434
-			if "104" in str(e): return
435
-			raise
436
-
437
-
438
-class rsyncBackend(Backend):
439
-	"""Connect to remote store using rsync
440
-
441
-	rsync backend contributed by Sebastian Wilhelmi <seppi@seppi.de>
442
-
443
-	"""
444
-	def __init__(self, parsed_url):
445
-		"""rsyncBackend initializer"""
446
-		self.url_string = parsed_url.url_string
447
-		if self.url_string[-1] != '/':
448
-			self.url_string += '/'
449
-
450
-	def put(self, source_path, remote_filename = None):
451
-		"""Use rsync to copy source_dir/filename to remote computer"""
452
-		if not remote_filename: remote_filename = source_path.get_filename()
453
-		remote_path = os.path.join (self.url_string, remote_filename)
454
-		commandline = "rsync %s %s" % (source_path.name, remote_path)
455
-		self.run_command(commandline)
456
-
457
-	def get(self, remote_filename, local_path):
458
-		"""Use rsync to get a remote file"""
459
-		remote_path = os.path.join (self.url_string, remote_filename)
460
-		commandline = "rsync %s %s" % (remote_path, local_path.name)
461
-		self.run_command(commandline)
462
-		local_path.setdata()
463
-		if not local_path.exists():
464
-			raise BackendException("File %s not found" % local_path.name)
465
-
466
-	def list(self):
467
-		"""List files"""
468
-		def split (str):
469
-			line = str.split ()
470
-			if len (line) > 4 and line[4] != '.':
471
-				return line[4]
472
-			else:
473
-				return None
474
-		commandline = "rsync %s" % self.url_string
475
-		return filter (lambda x: x, map (split, self.popen(commandline).split('\n')))
476
-
477
-	def delete(self, filename_list):
478
-		"""Delete files."""
479
-		delete_list = filename_list
480
-		dont_delete_list = []
481
-		for file in self.list ():
482
-			if file in delete_list:
483
-				delete_list.remove (file)
484
-			else:
485
-				dont_delete_list.append (file)
486
-		if len (delete_list) > 0:
487
-			raise BackendException("Files %s not found" % str (delete_list))
488
-
489
-		dir = tempfile.mktemp ()
490
-		exclude_name = tempfile.mktemp ()
491
-		exclude = open (exclude_name, 'w')
492
-		to_delete = [exclude_name]
493
-		os.mkdir (dir)
494
-		for file in dont_delete_list:
495
-				path = os.path.join (dir, file)
496
-				to_delete.append (path)
497
-				f = open (path, 'w')
498
-				f.close ()
499
-				print >>exclude, file
500
-		exclude.close ()
501
-		commandline = ("rsync --recursive --delete --exclude-from=%s %s/ %s" %
502
-			       (exclude_name, dir, self.url_string))
503
-		self.run_command(commandline)
504
-		for file in to_delete:
505
-			os.unlink (file)
506
-		os.rmdir (dir)
507
-
508
-
509
-class BitBucketBackend(Backend):
510
-        """Backend for accessing Amazon S3 using the bitbucket.py module.
511
-
512
-        This backend supports access to Amazon S3 (http://aws.amazon.com/s3)
513
-        using a mix of environment variables and URL's. The access key and
514
-        secret key are taken from the environment variables S3KEY and S3SECRET
515
-        and the bucket name from the url. For example (in BASH):
516
-
517
-            $ export S3KEY='44CF9590006BF252F707'
518
-            $ export S3SECRET='OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV'
519
-            $ duplicity /home/me s3+http://bucket_name
520
-
521
-        Note: / is disallowed in bucket names in case prefix support is implemented
522
-        in future.
523
-
524
-        TODO:
525
-            - support bucket prefixes with url's like s3+http://bucket_name/prefix
526
-            - bitbucket and amazon s3 are currently not very robust. We provide a
527
-              simplistic way of trying to re-connect and re-try an operation when
528
-              it fails. This is just a band-aid and should be removed if bitbucket
529
-              becomes more robust.
530
-            - Logging of actions.
531
-            - Better error messages for failures.
532
-        """
533
-
534
-        def __init__(self, parsed_url):
535
-                import bitbucket
536
-                self.module = bitbucket
537
-                self.bucket_name = parsed_url.suffix
538
-                if '/' in self.bucket_name:
539
-                    raise NotImplementedError("/ disallowed in bucket names and "
540
-                                              "bucket prefixes not supported.")
541
-                self.access_key = os.environ["S3KEY"]
542
-                self.secret_key = os.environ["S3SECRET"]
543
-                self._connect()
544
-
545
-        def _connect(self):
546
-                self.connection = self.module.connect(access_key=self.access_key,
547
-                                                      secret_key=self.secret_key)
548
-                self.bucket = self.connection.get_bucket(self.bucket_name)
549
-                # populate the bitbucket cache we do it here to be sure that
550
-                # even on re-connect we have a list of all keys on the server
551
-                self.bucket.fetch_all_keys()
552
-
553
-        def _logException(self, message=None):
554
-                # Simply dump the exception onto stderr since formatting it
555
-                # ourselves looks dangerous.
556
-                if message is not None:
557
-                    sys.stderr.write(message)
558
-                sys.excepthook(*sys.exc_info())
559
-
560
-        def put(self, source_path, remote_filename = None):
561
-		"""Transfer source_path (Path object) to remote_filename (string)
562
-
563
-		If remote_filename is None, get the filename from the last
564
-		path component of pathname.
565
-
566
-		"""
567
-		if not remote_filename:
568
-                    remote_filename = source_path.get_filename()
569
-                bits = self.module.Bits(filename=source_path.name)
570
-                try:
571
-                    self.bucket[remote_filename] = bits
572
-                except:
573
-                    self._logException("Error sending file %s, attempting to "
574
-                                       "re-connect.\n Got this Traceback:\n"
575
-                                       % remote_filename)
576
-                    self._connect()
577
-                    self.bucket[remote_filename] = bits
578
-
579
-	def get(self, remote_filename, local_path):
580
-		"""Retrieve remote_filename and place in local_path"""
581
-		local_path.setdata()
582
-                try:
583
-                    bits = self.bucket[remote_filename]
584
-                    bits.to_file(local_path.name)
585
-                except:
586
-                    self._logException("Error getting file %s, attempting to "
587
-                                       "re-connect.\n Got this Traceback:\n"
588
-                                       % remote_filename)
589
-                    self._connect()
590
-                    bits = self.bucket[remote_filename]
591
-                    bits.to_file(local_path.name)
592
-		local_path.setdata()
593
-
594
-	def list(self):
595
-		"""Return list of filenames (strings) present in backend"""
596
-                try:
597
-                    keys = self.bucket.keys()
598
-                except:
599
-                    self._logException("Error getting bucket keys, attempting to "
600
-                                       "re-connect.\n Got this Traceback:\n")
601
-                    self._connect()
602
-                    keys = self.bucket.keys()
603
-                return keys
604
-
605
-	def delete(self, filename_list):
606
-		"""Delete each filename in filename_list, in order if possible"""
607
-                for file in filename_list:
608
-                    try:
609
-                        del self.bucket[file]
610
-                    except:
611
-                        self._logException("Error deleting file %s, attempting to "
612
-                                           "re-connect.\n Got this Traceback:\n"
613
-                                           % file)
614
-                        self._connect()
615
-                        del self.bucket[file]
616
-
617
-# Dictionary relating protocol strings to backend_object classes.
618
-protocol_class_dict = {"scp": scpBackend,
619
-					   "ssh": scpBackend,
620
-					   "file": LocalBackend,
621
-					   "ftp": ftpBackend,
622
-					   "rsync": rsyncBackend,
623
-					   "s3+http": BitBucketBackend}
624
-
... ...
@@ -1,9 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
3
-<pkgmetadata>
4
-<herd>no-herd</herd>
5
-<maintainer>
6
-  <email>ticho@gentoo.org</email>
7
-  <name>Andrej Kacian</name>
8
-</maintainer>
9
-</pkgmetadata>
... ...
@@ -56,6 +56,7 @@ RDEPEND=">=dev-python/twisted-1.3.0
56 56
 	>=dev-python/nevow-0.4.1
57 57
 	>=dev-python/imaging-1.1"
58 58
 
59
+PYTRANSPORT_CONFIG=config_example.xml
59 60
 
60 61
 
61 62
 
... ...
@@ -105,7 +106,6 @@ pytransport_install_libs() {
105 106
 	return 0
106 107
 }
107 108
 
108
-PYTRANSPORT_CONFIG=config_example.xml
109 109
 
110 110
 pytransport_install_config() {
111 111
 	insinto /etc/jabber
112 112