瀏覽代碼

migrate to python3

- updated .gitignore
- updated README to markdown format
- deprecated distribution
- updated optparse to argparse
- deprecated all coding functions
- fix some syntax errors

Now this package should be python3-only.
tags/0.1.4.dev1^0
Jingbei Li 2 年之前
父節點
當前提交
774f371070
共有 5 個文件被更改,包括 82 次插入569 次删除
  1. 3
    1
      .gitignore
  2. 27
    25
      README
  3. 0
    485
      distribute_setup.py
  4. 50
    53
      gcp
  5. 2
    5
      setup.py

+ 3
- 1
.gitignore 查看文件

@@ -1,3 +1,5 @@
1 1
 *.pyc
2 2
 *.pyv
3
-*.sw?
3
+*.sw*
4
+*.tar*
5
+*.egg

+ 27
- 25
README 查看文件

@@ -1,10 +1,11 @@
1 1
 gcp v0.1.3
2
+====
2 3
 (c) Jérôme Poisson aka Goffi 2010, 2011
3 4
 
4 5
 gcp (Goffi's cp) is a files copier.
5 6
 
6 7
 
7
-** LICENSE **
8
+### LICENSE
8 9
 
9 10
 gcp is free software: you can redistribute it and/or modify
10 11
 it under the terms of the GNU General Public License as published by
@@ -21,25 +22,26 @@ along with gcp.  If not, see <http://www.gnu.org/licenses/>.
21 22
 
22 23
 
23 24
 
24
-** WTF ? **
25
+### WTF ?
25 26
 gcp is a file copier, loosely inspired from cp, but with high level functionalities like:
26
-	- progression indicator
27
-	- gcp continue copying even when there is an issue: he just skip the file with problem, and go on
28
-	- journalization: gcp write what he is doing, this allow to know which files were effectively copied
29
-	- fixing names to be compatible with the target filesystem (e.g. removing incompatible chars like "?" or "*" on vfat)
30
-	- if you launch a copy when an other is already running, the files are added to the first queue, this avoid your hard drive to move its read/write head all the time
31
-	- files saving: you can keep track of files you have copied, and re-copy them later (useful when, for example, you always copy some free music to all your friends).
32
-	- gcp will be approximately option-compatible with cp (approximately because the behaviour is not exactly the same, see below)
33
-
34
-/!\ WARNING /!\
27
+
28
+- progression indicator
29
+- gcp continue copying even when there is an issue: he just skip the file with problem, and go on
30
+- journalization: gcp write what he is doing, this allow to know which files were effectively copied
31
+- fixing names to be compatible with the target filesystem (e.g. removing incompatible chars like "?" or "*" on vfat)
32
+- if you launch a copy when an other is already running, the files are added to the first queue, this avoid your hard drive to move its read/write head all the time
33
+- files saving: you can keep track of files you have copied, and re-copy them later (useful when, for example, you always copy some free music to all your friends).
34
+- gcp will be approximately option-compatible with cp (approximately because the behaviour is not exactly the same, see below)
35
+
36
+**WARNING**
35 37
 gcp is at an early stage of development, and really experimental: use at your own risks !
36 38
 
37
-** How to use it ? **
39
+### How to use it ?
38 40
 Pretty much like cp (see gcp --help).
39 41
 Please note that the behaviour is not exactly the same as cp, even if gcp want to be option-compatible. Mainly, the destination filenames can be changed (by default, can be deactivated).
40 42
 gcp doesn't implement yet all the options from cp, but it's planed.
41 43
 
42
-** journalizaion **
44
+### Journalizaion
43 45
 The journal is planed to be used by gcp itself, buts remains human-readable. It is located in ~/.gcp/journal
44 46
 
45 47
 3 states are used:
@@ -49,7 +51,7 @@ The journal is planed to be used by gcp itself, buts remains human-readable. It
49 51
 
50 52
 after the state, a list of things which went wront are show, separated by ", "
51 53
 
52
-** What's next ? **
54
+### What's next ?
53 55
 
54 56
 Several improvment are already planed
55 57
 - copy queue management (moving copy order)
@@ -65,32 +67,32 @@ Several improvment are already planed
65 67
 - distant copy (ftp)
66 68
 - basic server mode, for copying files on network without the need of nfs or other heavy stuff
67 69
 
68
-** Credits **
70
+### Credits
69 71
 
70 72
 A big big thank to the authors/contributors of...
71 73
 
72
-	progressbar:
73
-	gcp use ProgressBar (http://pypi.python.org/pypi/progressbar/2.2), a class coded by Nilton Volpato which allow the textual representation of progression.
74
+* progressbar:
75
+gcp use ProgressBar (http://pypi.python.org/pypi/progressbar/2.2), a class coded by Nilton Volpato which allow the textual representation of progression.
74 76
 
75
-	GLib:
76
-	This heavily used library is used here for the main loop, event catching, and for DBus. Get it at http://library.gnome.org/devel/glib/
77
+* GLib:
78
+This heavily used library is used here for the main loop, event catching, and for DBus. Get it at http://library.gnome.org/devel/glib/
77 79
 
78
-	DBus:
79
-	This excellent IPC is in the heart of gcp. Get more information at www.freedesktop.org/wiki/Software/dbus
80
+* DBus:
81
+This excellent IPC is in the heart of gcp. Get more information at www.freedesktop.org/wiki/Software/dbus
80 82
 
81
-	python and its amazing standard library:
82
-	gcp was coded quickly for my own need thanks to this excellent and efficient language and its really huge standard library. Python can be download at www.python.org
83
+* python and its amazing standard library:
84
+gcp was coded quickly for my own need thanks to this excellent and efficient language and its really huge standard library. Python can be download at www.python.org
83 85
 
84 86
 If I forgot any credit, please contact me (mail below) to fix it.
85 87
 
86 88
 Big thanks to contributors and package mainteners
87 89
 
88
-** Contributions **
90
+### Contributions
89 91
 2011: Thomas Preud'homme <robotux@celest.fr>: manpage, stat resolution fix
90 92
 
91 93
 
92 94
 
93
-** Contact **
95
+### Contact
94 96
 
95 97
 You can contact me at goffi@goffi.org .
96 98
 You'll find the latest version on my ftp: ftp://ftp.goffi.org/gcp, or check the wiki ( http://wiki.goffi.org/wiki/Gcp )

+ 0
- 485
distribute_setup.py 查看文件

@@ -1,485 +0,0 @@
1
-#!python
2
-"""Bootstrap distribute installation
3
-
4
-If you want to use setuptools in your package's setup.py, just include this
5
-file in the same directory with it, and add this to the top of your setup.py::
6
-
7
-    from distribute_setup import use_setuptools
8
-    use_setuptools()
9
-
10
-If you want to require a specific version of setuptools, set a download
11
-mirror, or use an alternate download directory, you can do so by supplying
12
-the appropriate options to ``use_setuptools()``.
13
-
14
-This file can also be run as a script to install or upgrade setuptools.
15
-"""
16
-import os
17
-import sys
18
-import time
19
-import fnmatch
20
-import tempfile
21
-import tarfile
22
-from distutils import log
23
-
24
-try:
25
-    from site import USER_SITE
26
-except ImportError:
27
-    USER_SITE = None
28
-
29
-try:
30
-    import subprocess
31
-
32
-    def _python_cmd(*args):
33
-        args = (sys.executable,) + args
34
-        return subprocess.call(args) == 0
35
-
36
-except ImportError:
37
-    # will be used for python 2.3
38
-    def _python_cmd(*args):
39
-        args = (sys.executable,) + args
40
-        # quoting arguments if windows
41
-        if sys.platform == 'win32':
42
-            def quote(arg):
43
-                if ' ' in arg:
44
-                    return '"%s"' % arg
45
-                return arg
46
-            args = [quote(arg) for arg in args]
47
-        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
48
-
49
-DEFAULT_VERSION = "0.6.14"
50
-DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
51
-SETUPTOOLS_FAKED_VERSION = "0.6c11"
52
-
53
-SETUPTOOLS_PKG_INFO = """\
54
-Metadata-Version: 1.0
55
-Name: setuptools
56
-Version: %s
57
-Summary: xxxx
58
-Home-page: xxx
59
-Author: xxx
60
-Author-email: xxx
61
-License: xxx
62
-Description: xxx
63
-""" % SETUPTOOLS_FAKED_VERSION
64
-
65
-
66
-def _install(tarball):
67
-    # extracting the tarball
68
-    tmpdir = tempfile.mkdtemp()
69
-    log.warn('Extracting in %s', tmpdir)
70
-    old_wd = os.getcwd()
71
-    try:
72
-        os.chdir(tmpdir)
73
-        tar = tarfile.open(tarball)
74
-        _extractall(tar)
75
-        tar.close()
76
-
77
-        # going in the directory
78
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
79
-        os.chdir(subdir)
80
-        log.warn('Now working in %s', subdir)
81
-
82
-        # installing
83
-        log.warn('Installing Distribute')
84
-        if not _python_cmd('setup.py', 'install'):
85
-            log.warn('Something went wrong during the installation.')
86
-            log.warn('See the error message above.')
87
-    finally:
88
-        os.chdir(old_wd)
89
-
90
-
91
-def _build_egg(egg, tarball, to_dir):
92
-    # extracting the tarball
93
-    tmpdir = tempfile.mkdtemp()
94
-    log.warn('Extracting in %s', tmpdir)
95
-    old_wd = os.getcwd()
96
-    try:
97
-        os.chdir(tmpdir)
98
-        tar = tarfile.open(tarball)
99
-        _extractall(tar)
100
-        tar.close()
101
-
102
-        # going in the directory
103
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
104
-        os.chdir(subdir)
105
-        log.warn('Now working in %s', subdir)
106
-
107
-        # building an egg
108
-        log.warn('Building a Distribute egg in %s', to_dir)
109
-        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
110
-
111
-    finally:
112
-        os.chdir(old_wd)
113
-    # returning the result
114
-    log.warn(egg)
115
-    if not os.path.exists(egg):
116
-        raise IOError('Could not build the egg.')
117
-
118
-
119
-def _do_download(version, download_base, to_dir, download_delay):
120
-    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
121
-                       % (version, sys.version_info[0], sys.version_info[1]))
122
-    if not os.path.exists(egg):
123
-        tarball = download_setuptools(version, download_base,
124
-                                      to_dir, download_delay)
125
-        _build_egg(egg, tarball, to_dir)
126
-    sys.path.insert(0, egg)
127
-    import setuptools
128
-    setuptools.bootstrap_install_from = egg
129
-
130
-
131
-def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
132
-                   to_dir=os.curdir, download_delay=15, no_fake=True):
133
-    # making sure we use the absolute path
134
-    to_dir = os.path.abspath(to_dir)
135
-    was_imported = 'pkg_resources' in sys.modules or \
136
-        'setuptools' in sys.modules
137
-    try:
138
-        try:
139
-            import pkg_resources
140
-            if not hasattr(pkg_resources, '_distribute'):
141
-                if not no_fake:
142
-                    _fake_setuptools()
143
-                raise ImportError
144
-        except ImportError:
145
-            return _do_download(version, download_base, to_dir, download_delay)
146
-        try:
147
-            pkg_resources.require("distribute>="+version)
148
-            return
149
-        except pkg_resources.VersionConflict:
150
-            e = sys.exc_info()[1]
151
-            if was_imported:
152
-                sys.stderr.write(
153
-                "The required version of distribute (>=%s) is not available,\n"
154
-                "and can't be installed while this script is running. Please\n"
155
-                "install a more recent version first, using\n"
156
-                "'easy_install -U distribute'."
157
-                "\n\n(Currently using %r)\n" % (version, e.args[0]))
158
-                sys.exit(2)
159
-            else:
160
-                del pkg_resources, sys.modules['pkg_resources']    # reload ok
161
-                return _do_download(version, download_base, to_dir,
162
-                                    download_delay)
163
-        except pkg_resources.DistributionNotFound:
164
-            return _do_download(version, download_base, to_dir,
165
-                                download_delay)
166
-    finally:
167
-        if not no_fake:
168
-            _create_fake_setuptools_pkg_info(to_dir)
169
-
170
-def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
171
-                        to_dir=os.curdir, delay=15):
172
-    """Download distribute from a specified location and return its filename
173
-
174
-    `version` should be a valid distribute version number that is available
175
-    as an egg for download under the `download_base` URL (which should end
176
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
177
-    `delay` is the number of seconds to pause before an actual download
178
-    attempt.
179
-    """
180
-    # making sure we use the absolute path
181
-    to_dir = os.path.abspath(to_dir)
182
-    try:
183
-        from urllib.request import urlopen
184
-    except ImportError:
185
-        from urllib2 import urlopen
186
-    tgz_name = "distribute-%s.tar.gz" % version
187
-    url = download_base + tgz_name
188
-    saveto = os.path.join(to_dir, tgz_name)
189
-    src = dst = None
190
-    if not os.path.exists(saveto):  # Avoid repeated downloads
191
-        try:
192
-            log.warn("Downloading %s", url)
193
-            src = urlopen(url)
194
-            # Read/write all in one block, so we don't create a corrupt file
195
-            # if the download is interrupted.
196
-            data = src.read()
197
-            dst = open(saveto, "wb")
198
-            dst.write(data)
199
-        finally:
200
-            if src:
201
-                src.close()
202
-            if dst:
203
-                dst.close()
204
-    return os.path.realpath(saveto)
205
-
206
-def _no_sandbox(function):
207
-    def __no_sandbox(*args, **kw):
208
-        try:
209
-            from setuptools.sandbox import DirectorySandbox
210
-            if not hasattr(DirectorySandbox, '_old'):
211
-                def violation(*args):
212
-                    pass
213
-                DirectorySandbox._old = DirectorySandbox._violation
214
-                DirectorySandbox._violation = violation
215
-                patched = True
216
-            else:
217
-                patched = False
218
-        except ImportError:
219
-            patched = False
220
-
221
-        try:
222
-            return function(*args, **kw)
223
-        finally:
224
-            if patched:
225
-                DirectorySandbox._violation = DirectorySandbox._old
226
-                del DirectorySandbox._old
227
-
228
-    return __no_sandbox
229
-
230
-def _patch_file(path, content):
231
-    """Will backup the file then patch it"""
232
-    existing_content = open(path).read()
233
-    if existing_content == content:
234
-        # already patched
235
-        log.warn('Already patched.')
236
-        return False
237
-    log.warn('Patching...')
238
-    _rename_path(path)
239
-    f = open(path, 'w')
240
-    try:
241
-        f.write(content)
242
-    finally:
243
-        f.close()
244
-    return True
245
-
246
-_patch_file = _no_sandbox(_patch_file)
247
-
248
-def _same_content(path, content):
249
-    return open(path).read() == content
250
-
251
-def _rename_path(path):
252
-    new_name = path + '.OLD.%s' % time.time()
253
-    log.warn('Renaming %s into %s', path, new_name)
254
-    os.rename(path, new_name)
255
-    return new_name
256
-
257
-def _remove_flat_installation(placeholder):
258
-    if not os.path.isdir(placeholder):
259
-        log.warn('Unkown installation at %s', placeholder)
260
-        return False
261
-    found = False
262
-    for file in os.listdir(placeholder):
263
-        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
264
-            found = True
265
-            break
266
-    if not found:
267
-        log.warn('Could not locate setuptools*.egg-info')
268
-        return
269
-
270
-    log.warn('Removing elements out of the way...')
271
-    pkg_info = os.path.join(placeholder, file)
272
-    if os.path.isdir(pkg_info):
273
-        patched = _patch_egg_dir(pkg_info)
274
-    else:
275
-        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
276
-
277
-    if not patched:
278
-        log.warn('%s already patched.', pkg_info)
279
-        return False
280
-    # now let's move the files out of the way
281
-    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
282
-        element = os.path.join(placeholder, element)
283
-        if os.path.exists(element):
284
-            _rename_path(element)
285
-        else:
286
-            log.warn('Could not find the %s element of the '
287
-                     'Setuptools distribution', element)
288
-    return True
289
-
290
-_remove_flat_installation = _no_sandbox(_remove_flat_installation)
291
-
292
-def _after_install(dist):
293
-    log.warn('After install bootstrap.')
294
-    placeholder = dist.get_command_obj('install').install_purelib
295
-    _create_fake_setuptools_pkg_info(placeholder)
296
-
297
-def _create_fake_setuptools_pkg_info(placeholder):
298
-    if not placeholder or not os.path.exists(placeholder):
299
-        log.warn('Could not find the install location')
300
-        return
301
-    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
302
-    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
303
-            (SETUPTOOLS_FAKED_VERSION, pyver)
304
-    pkg_info = os.path.join(placeholder, setuptools_file)
305
-    if os.path.exists(pkg_info):
306
-        log.warn('%s already exists', pkg_info)
307
-        return
308
-
309
-    log.warn('Creating %s', pkg_info)
310
-    f = open(pkg_info, 'w')
311
-    try:
312
-        f.write(SETUPTOOLS_PKG_INFO)
313
-    finally:
314
-        f.close()
315
-
316
-    pth_file = os.path.join(placeholder, 'setuptools.pth')
317
-    log.warn('Creating %s', pth_file)
318
-    f = open(pth_file, 'w')
319
-    try:
320
-        f.write(os.path.join(os.curdir, setuptools_file))
321
-    finally:
322
-        f.close()
323
-
324
-_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
325
-
326
-def _patch_egg_dir(path):
327
-    # let's check if it's already patched
328
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
329
-    if os.path.exists(pkg_info):
330
-        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
331
-            log.warn('%s already patched.', pkg_info)
332
-            return False
333
-    _rename_path(path)
334
-    os.mkdir(path)
335
-    os.mkdir(os.path.join(path, 'EGG-INFO'))
336
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
337
-    f = open(pkg_info, 'w')
338
-    try:
339
-        f.write(SETUPTOOLS_PKG_INFO)
340
-    finally:
341
-        f.close()
342
-    return True
343
-
344
-_patch_egg_dir = _no_sandbox(_patch_egg_dir)
345
-
346
-def _before_install():
347
-    log.warn('Before install bootstrap.')
348
-    _fake_setuptools()
349
-
350
-
351
-def _under_prefix(location):
352
-    if 'install' not in sys.argv:
353
-        return True
354
-    args = sys.argv[sys.argv.index('install')+1:]
355
-    for index, arg in enumerate(args):
356
-        for option in ('--root', '--prefix'):
357
-            if arg.startswith('%s=' % option):
358
-                top_dir = arg.split('root=')[-1]
359
-                return location.startswith(top_dir)
360
-            elif arg == option:
361
-                if len(args) > index:
362
-                    top_dir = args[index+1]
363
-                    return location.startswith(top_dir)
364
-        if arg == '--user' and USER_SITE is not None:
365
-            return location.startswith(USER_SITE)
366
-    return True
367
-
368
-
369
-def _fake_setuptools():
370
-    log.warn('Scanning installed packages')
371
-    try:
372
-        import pkg_resources
373
-    except ImportError:
374
-        # we're cool
375
-        log.warn('Setuptools or Distribute does not seem to be installed.')
376
-        return
377
-    ws = pkg_resources.working_set
378
-    try:
379
-        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
380
-                                  replacement=False))
381
-    except TypeError:
382
-        # old distribute API
383
-        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
384
-
385
-    if setuptools_dist is None:
386
-        log.warn('No setuptools distribution found')
387
-        return
388
-    # detecting if it was already faked
389
-    setuptools_location = setuptools_dist.location
390
-    log.warn('Setuptools installation detected at %s', setuptools_location)
391
-
392
-    # if --root or --preix was provided, and if
393
-    # setuptools is not located in them, we don't patch it
394
-    if not _under_prefix(setuptools_location):
395
-        log.warn('Not patching, --root or --prefix is installing Distribute'
396
-                 ' in another location')
397
-        return
398
-
399
-    # let's see if its an egg
400
-    if not setuptools_location.endswith('.egg'):
401
-        log.warn('Non-egg installation')
402
-        res = _remove_flat_installation(setuptools_location)
403
-        if not res:
404
-            return
405
-    else:
406
-        log.warn('Egg installation')
407
-        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
408
-        if (os.path.exists(pkg_info) and
409
-            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
410
-            log.warn('Already patched.')
411
-            return
412
-        log.warn('Patching...')
413
-        # let's create a fake egg replacing setuptools one
414
-        res = _patch_egg_dir(setuptools_location)
415
-        if not res:
416
-            return
417
-    log.warn('Patched done.')
418
-    _relaunch()
419
-
420
-
421
-def _relaunch():
422
-    log.warn('Relaunching...')
423
-    # we have to relaunch the process
424
-    # pip marker to avoid a relaunch bug
425
-    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
426
-        sys.argv[0] = 'setup.py'
427
-    args = [sys.executable] + sys.argv
428
-    sys.exit(subprocess.call(args))
429
-
430
-
431
-def _extractall(self, path=".", members=None):
432
-    """Extract all members from the archive to the current working
433
-       directory and set owner, modification time and permissions on
434
-       directories afterwards. `path' specifies a different directory
435
-       to extract to. `members' is optional and must be a subset of the
436
-       list returned by getmembers().
437
-    """
438
-    import copy
439
-    import operator
440
-    from tarfile import ExtractError
441
-    directories = []
442
-
443
-    if members is None:
444
-        members = self
445
-
446
-    for tarinfo in members:
447
-        if tarinfo.isdir():
448
-            # Extract directories with a safe mode.
449
-            directories.append(tarinfo)
450
-            tarinfo = copy.copy(tarinfo)
451
-            tarinfo.mode = 448 # decimal for oct 0700
452
-        self.extract(tarinfo, path)
453
-
454
-    # Reverse sort directories.
455
-    if sys.version_info < (2, 4):
456
-        def sorter(dir1, dir2):
457
-            return cmp(dir1.name, dir2.name)
458
-        directories.sort(sorter)
459
-        directories.reverse()
460
-    else:
461
-        directories.sort(key=operator.attrgetter('name'), reverse=True)
462
-
463
-    # Set correct owner, mtime and filemode on directories.
464
-    for tarinfo in directories:
465
-        dirpath = os.path.join(path, tarinfo.name)
466
-        try:
467
-            self.chown(tarinfo, dirpath)
468
-            self.utime(tarinfo, dirpath)
469
-            self.chmod(tarinfo, dirpath)
470
-        except ExtractError:
471
-            e = sys.exc_info()[1]
472
-            if self.errorlevel > 1:
473
-                raise
474
-            else:
475
-                self._dbg(1, "tarfile: %s" % e)
476
-
477
-
478
-def main(argv, version=DEFAULT_VERSION):
479
-    """Install or upgrade setuptools and EasyInstall"""
480
-    tarball = download_setuptools()
481
-    _install(tarball)
482
-
483
-
484
-if __name__ == '__main__':
485
-    main(sys.argv[1:])

+ 50
- 53
gcp 查看文件

@@ -28,26 +28,26 @@ logging.basicConfig(level=logging.INFO,
28 28
 ###
29 29
 
30 30
 import gettext
31
-gettext.install('gcp', "i18n", unicode=True)
31
+gettext.install('gcp', "i18n")
32 32
 
33 33
 import sys
34 34
 import os,os.path
35
-from optparse import OptionParser, OptionGroup #To be replaced by argparse ASAP
36
-import cPickle as pickle
35
+from argparse import ArgumentParser
36
+import pickle
37 37
 try:
38 38
     import gobject
39 39
     #DBus
40 40
     import dbus, dbus.glib
41 41
     import dbus.service
42 42
     import dbus.mainloop.glib
43
-except ImportError,e:
43
+except ImportError as e:
44 44
     error(_("Error during import"))
45 45
     error(_("Please check dependecies:"),e)
46 46
     exit(1)
47 47
 try:
48 48
     from progressbar import ProgressBar, Percentage, Bar, ETA, FileTransferSpeed
49 49
     pbar_available=True
50
-except ImportError, e:
50
+except ImportError as e:
51 51
     info (_('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar'))
52 52
     info (_('Progress bar deactivated\n--\n'))
53 53
     pbar_available=False
@@ -103,11 +103,13 @@ class DbusObject(dbus.service.Object):
103 103
         @return: success (boolean) and error message if any (string)"""
104 104
         try:
105 105
             args = pickle.loads(str(args))
106
-        except TypeError, pickle.UnpicklingError:
106
+        except TypeError as e:
107
+            pickle.UnpicklingError = e
107 108
             return (False, _("INTERNAL ERROR: invalid arguments"))
108 109
         try:
109 110
             source_dir = pickle.loads(str(source_dir))
110
-        except TypeError, pickle.UnpicklingError:
111
+        except TypeError as e:
112
+            pickle.UnpicklingError = e
111 113
             return (False, _("INTERNAL ERROR: invalid source_dir"))
112 114
         return self._gcp.parseArguments(args, source_dir)
113 115
 
@@ -194,7 +196,7 @@ class GCP():
194 196
                                 dbus_interface=const_DBUS_INTERFACE)
195 197
             self._main_instance = False
196 198
 
197
-        except dbus.exceptions.DBusException,e:
199
+        except dbus.exceptions.DBusException as e:
198 200
             if e._dbus_error_name=='org.freedesktop.DBus.Error.ServiceUnknown':
199 201
                 self.launchDbusMainInstance()
200 202
                 debug (_("gcp launched"))
@@ -230,7 +232,7 @@ class GCP():
230 232
         #(check freedesktop mounting signals)
231 233
         ret =  {}
232 234
         try:
233
-            with open("/proc/mounts",'rb') as mounts:
235
+            with open("/proc/mounts",'r') as mounts:
234 236
                 for line in mounts.readlines():
235 237
                    fs_spec, fs_file, fs_vfstype, fs_mntops, fs_freq, fs_passno = line.split(' ')
236 238
                    ret[fs_file] = fs_vfstype
@@ -242,14 +244,12 @@ class GCP():
242 244
         """Add a file to the copy list
243 245
         @param path: absolute path of file
244 246
         @param options: options as return by optparse"""
245
-        debug (_("Adding to copy list: %(path)s ==> %(dest_path)s (%(fs_type)s)") % {"path":path.decode('utf-8','replace'),
246
-                                                                                  "dest_path":dest_path.decode('utf-8','replace'),
247
-                                                                                   "fs_type":self.getFsType(dest_path)}              )
247
+        debug (_("Adding to copy list: %(path)s ==> %(dest_path)s (%(fs_type)s)") % {"path":path, "dest_path":dest_path, "fs_type":self.getFsType(dest_path)}              )
248 248
         try:
249 249
             self.bytes_total+=os.path.getsize(path)
250 250
             self.copy_list.insert(0,(path, dest_path, options))
251
-        except OSError,e:
252
-            error(_("Can't copy %(path)s: %(exception)s") % {'path':path.decode('utf-8','replace'), 'exception':e.strerror})
251
+        except OSError as e:
252
+            error(_("Can't copy %(path)s: %(exception)s") % {'path':path, 'exception':e.strerror})
253 253
 
254 254
 
255 255
     def __appendDirToList(self, dirpath, dest_path, options):
@@ -267,21 +267,19 @@ class GCP():
267 267
             for filename in os.listdir(dirpath):
268 268
                 filepath = os.path.join(dirpath,filename)
269 269
                 if os.path.islink(filepath) and not options.dereference:
270
-                    debug ("Skippink symbolic dir: %s" % filepath.decode('utf-8','replace'))
270
+                    debug ("Skippink symbolic dir: %s" % filepath)
271 271
                     continue
272 272
                 if os.path.isdir(filepath):
273 273
                     full_dest_path = os.path.join(dest_path,filename)
274 274
                     self.__appendDirToList(filepath, full_dest_path, options)
275 275
                 else:
276 276
                     self.__appendToList(filepath, dest_path, options)
277
-        except OSError,e:
277
+        except OSError as e:
278 278
             try:
279
-                error(_("Can't append %(path)s to copy list: %(exception)s") % {'path':filepath.decode('utf-8','replace'),
280
-                                                             'exception':e.strerror})
279
+                error(_("Can't append %(path)s to copy list: %(exception)s") % {'path':filepath, 'exception':e.strerror})
281 280
             except NameError:
282 281
                 #We can't list the dir
283
-                error(_("Can't access %(dirpath)s: %(exception)s") % {'dirpath':dirpath.decode('utf-8','replace'),
284
-                                                             'exception':e.strerror})
282
+                error(_("Can't access %(dirpath)s: %(exception)s") % {'dirpath':dirpath, 'exception':e.strerror})
285 283
 
286 284
     def __checkArgs(self, options, source_dir, args):
287 285
         """Check thats args are files, and add them to copy list
@@ -292,17 +290,17 @@ class GCP():
292 290
         len_args = len(args)
293 291
         try:
294 292
             dest_path = os.path.normpath(os.path.join(source_dir, args.pop()))
295
-        except OSError,e:
293
+        except OSError as e:
296 294
             error (_("Invalid dest_path: %s"),e)
297 295
 
298 296
         for path in args:
299 297
             abspath = os.path.normpath(os.path.join(os.path.expanduser(source_dir), path))
300 298
             if not os.path.exists(abspath):
301
-                warning(_("The path given in arg doesn't exist or is not accessible: %s") % abspath.decode('utf-8','replace'))
299
+                warning(_("The path given in arg doesn't exist or is not accessible: %s") % abspath)
302 300
             else:
303 301
                 if os.path.isdir(abspath):
304 302
                     if not options.recursive:
305
-                        warning (_('omitting directory "%s"') % abspath.decode('utf-8','replace'))
303
+                        warning (_('omitting directory "%s"') % abspath)
306 304
                     else:
307 305
                         _basename=os.path.basename(os.path.normpath(path))
308 306
                         full_dest_path = dest_path if options.directdir else os.path.normpath(os.path.join(dest_path, _basename))
@@ -327,7 +325,7 @@ class GCP():
327 325
             assert(filename)
328 326
             dest_file = self.__filename_fix(options.dest_file,options) if options.dest_file else self.__filename_fix(os.path.join(dest_path,filename),options)
329 327
             if os.path.exists(dest_file) and not options.force:
330
-                warning (_("File [%s] already exists, skipping it !") % dest_file.decode('utf-8','replace'))
328
+                warning (_("File [%s] already exists, skipping it !") % dest_file)
331 329
                 self.journal.copyFailed()
332 330
                 self.journal.error("already exists")
333 331
                 self.journal.closeFile()
@@ -345,8 +343,7 @@ class GCP():
345 343
             gobject.io_add_watch(source_fd,gobject.IO_IN,self._copyFile,
346 344
                                  (dest_fd, options), priority=gobject.PRIORITY_DEFAULT)
347 345
             if not self.progress:
348
-                info(_("COPYING %(source)s ==> %(dest)s") % {"source":source_file.decode('utf-8','replace'),
349
-                                                             "dest":dest_file.decode('utf-8','replace')})
346
+                info(_("COPYING %(source)s ==> %(dest)s") % {"source":source_file, "dest":dest_file})
350 347
             return True
351 348
         else:
352 349
             #Nothing left to copy, we quit
@@ -439,7 +436,7 @@ class GCP():
439 436
                     os.chown(dest_file, st_file.st_uid, st_file.st_gid)
440 437
                 elif preserve == 'timestamps':
441 438
                     os.utime(dest_file, (st_file.st_atime, st_file.st_mtime))
442
-            except OSError,e:
439
+            except OSError as e:
443 440
                 self.journal.error("preserve-"+preserve)
444 441
 
445 442
     def __get_string_size(self, size):
@@ -543,69 +540,69 @@ class GCP():
543 540
         @return: a tuple (boolean, message) where the boolean is the success of the arguments
544 541
                  validation, and message is the error message to print when necessary"""
545 542
         _usage="""
546
-        %prog [options] FILE DEST
547
-        %prog [options] FILE1 [FILE2 ...] DEST-DIR
543
+        %(prog)s [options] FILE DEST
544
+        %(prog)s [options] FILE1 [FILE2 ...] DEST-DIR
548 545
 
549
-        %prog --help for options list
546
+        %(prog)s --help for options list
550 547
         """
551 548
         for idx in range(len(full_args)):
552
-            if isinstance(full_args[idx], unicode):
553
-                #We don't want unicode as some filenames can be invalid unicode
554
-                full_args[idx] = full_args[idx].encode('utf-8')
549
+            full_args[idx] = full_args[idx].encode('utf-8')
555 550
 
556
-        parser = OptionParser(usage=_usage,version=ABOUT)
551
+        parser = ArgumentParser(usage=_usage)
557 552
 
558
-        parser.add_option("-r", "--recursive", action="store_true", default=False,
553
+        parser.add_argument("-r", "--recursive", action="store_true", default=False,
559 554
                     help=_("copy directories recursively"))
560 555
 
561
-        parser.add_option("-f", "--force", action="store_true", default=False,
556
+        parser.add_argument("-f", "--force", action="store_true", default=False,
562 557
                     help=_("force overwriting of existing files"))
563 558
 
564
-        parser.add_option("--preserve", action="store", default='mode,ownership,timestamps',
559
+        parser.add_argument("--preserve", action="store", default='mode,ownership,timestamps',
565 560
                     help=_("preserve  the  specified  attributes"))
566 561
 
567
-        parser.add_option("-L", "--dereference", action="store_true", default=False,
562
+        parser.add_argument("-L", "--dereference", action="store_true", default=False,
568 563
                     help=_("always follow symbolic links in sources"))
569 564
 
570
-        parser.add_option("-P", "--no-dereference", action="store_false", dest='dereference',
565
+        parser.add_argument("-P", "--no-dereference", action="store_false", dest='dereference',
571 566
                     help=_("never follow symbolic links in sources"))
572 567
 
573
-        #parser.add_option("--no-unicode-fix", action="store_false", dest='unicode_fix', default=True,
568
+        #parser.add_argument("--no-unicode-fix", action="store_false", dest='unicode_fix', default=True,
574 569
         #            help=_("don't fix name encoding errors")) #TODO
575 570
 
576
-        parser.add_option("--no-fs-fix", action="store_false", dest='fs_fix', default=True,
571
+        parser.add_argument("--no-fs-fix", action="store_false", dest='fs_fix', default=True,
577 572
                     help=_("don't fix filesystem name incompatibily"))
578 573
 
579
-        parser.add_option("--no-progress", action="store_false", dest="progress", default=True,
574
+        parser.add_argument("--no-progress", action="store_false", dest="progress", default=True,
580 575
                     help=_("deactivate progress bar"))
581 576
 
582
-        parser.add_option("-v", "--verbose", action="store_true", default=False,
577
+        parser.add_argument("-v", "--verbose", action="store_true", default=False,
583 578
                     help=_("Show what is currently done"))
584 579
 
585
-        group_saving = OptionGroup(parser, "sources saving")
580
+        parser.add_argument("-V", "--version", action="version", version=ABOUT)
586 581
 
587
-        group_saving.add_option("--sources-save", action="store",
582
+        group_saving = parser.add_argument_group("sources saving")
583
+
584
+        group_saving.add_argument("--sources-save", action="store",
588 585
                     help=_("Save source arguments"))
589 586
 
590
-        group_saving.add_option("--sources-replace", action="store",
587
+        group_saving.add_argument("--sources-replace", action="store",
591 588
                     help=_("Save source arguments and replace memory if it already exists"))
592 589
 
593
-        group_saving.add_option("--sources-load", action="store",
590
+        group_saving.add_argument("--sources-load", action="store",
594 591
                     help=_("Load source arguments"))
595 592
 
596
-        group_saving.add_option("--sources-del", action="store",
593
+        group_saving.add_argument("--sources-del", action="store",
597 594
                     help=_("delete saved sources"))
598 595
 
599
-        group_saving.add_option("--sources-list", action="store_true", default=False,
596
+        group_saving.add_argument("--sources-list", action="store_true", default=False,
600 597
                     help=_("List names of saved sources"))
601 598
 
602
-        group_saving.add_option("--sources-full-list", action="store_true", default=False,
599
+        group_saving.add_argument("--sources-full-list", action="store_true", default=False,
603 600
                     help=_("List names of saved sources and files in it"))
604 601
 
605
-        parser.add_option_group(group_saving)
602
+        parser.add_argument_group(group_saving)
606 603
 
607 604
 
608
-        (options, args) = parser.parse_args(full_args)
605
+        (options, args) = parser.parse_known_args()
609 606
         options.directdir = False #True only in the special case: we are copying a dir and it doesn't exists
610 607
         #options check
611 608
         if options.progress and not pbar_available:
@@ -653,7 +650,7 @@ class GCP():
653 650
             if len(args) < 2:
654 651
                 _error_msg = _("Wrong number of arguments")
655 652
                 return (False, _error_msg)
656
-            debug(_("adding args to gcp: %s") % str(args).decode('utf-8','replace'))
653
+            debug(_("adding args to gcp: %s") % args)
657 654
             self.__checkArgs(options, source_dir, args)
658 655
             if not self.__launched:
659 656
                 self.journal = Journal()

+ 2
- 5
setup.py 查看文件

@@ -1,9 +1,6 @@
1 1
 #!/usr/bin/env python
2 2
 # -*- coding: utf-8 -*-
3 3
 
4
-from distribute_setup import use_setuptools
5
-use_setuptools()
6
-
7 4
 from setuptools import setup
8 5
 import sys
9 6
 from os import path
@@ -24,8 +21,8 @@ setup(name=name,
24 21
                    'Programming Language :: Python',
25 22
                    'Topic :: Utilities'
26 23
                    ],
27
-      data_files=[(path.join(sys.prefix,'share/locale/fr/LC_MESSAGES'), ['i18n/fr/LC_MESSAGES/gcp.mo']),
24
+      data_files=[('share/locale/fr/LC_MESSAGES', ['i18n/fr/LC_MESSAGES/gcp.mo']),
28 25
                   ('share/man/man1', ["gcp.1"]),
29
-                  ('share/doc/%s' % name, ['COPYING','README'])],
26
+                  ('share/doc/%s' % name, ['COPYING','README.rst'])],
30 27
       scripts=['gcp'],
31 28
      )

Loading…
取消
儲存