~ubuntu-branches/ubuntu/lucid/ubuntuone-client/lucid

« back to all changes in this revision

Viewing changes to ubuntuone/syncdaemon/volume_manager.py

  • Committer: Bazaar Package Importer
  • Author(s): Rodney Dawes
  • Date: 2009-08-26 17:15:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090826171500-axw44px0xy7tf1vi
Tags: 0.93.1-0ubuntu1
* New upstream release.
  - Fix AttributeError in __hide_icon (LP: #419488)
  - Fix OSError crash in syncdaemon (LP: #419533)
  - Fix OSError in _upgrade_metadata_2 (LP: #405688)

Show diffs side-by-side

added added

removed removed

Lines of Context:
91
91
class VolumeManager(object):
92
92
    """Manages shares and mount points."""
93
93
 
94
 
    METADATA_VERSION = '4'
 
94
    METADATA_VERSION = '5'
95
95
 
96
96
    def __init__(self, main):
97
97
        """Create the instance and populate the shares/d attributes
129
129
            os.makedirs(self._shared_dir)
130
130
 
131
131
        # build the dir layout
132
 
        # TODO: migrate from old dir layout
133
132
        if not os.path.exists(self.m.root_dir):
 
133
            self.log.debug('creating root dir: %r', self.m.root_dir)
134
134
            os.makedirs(self.m.root_dir)
135
135
        if not os.path.exists(self.m.shares_dir):
 
136
            self.log.debug('creating shares directory: %r', self.m.shares_dir)
136
137
            os.makedirs(self.m.shares_dir)
137
138
        # create the shares symlink
138
139
        if not os.path.exists(self.m.shares_dir_link):
 
140
            self.log.debug('creating Shares symlink: %r -> %r',
 
141
                           self.m.shares_dir_link, self.m.shares_dir)
139
142
            os.symlink(self.m.shares_dir, self.m.shares_dir_link)
140
143
        # make the shares_dir read only
141
144
        os.chmod(self.m.shares_dir, 0555)
508
511
            for dirpath, dirnames, filenames in os.walk(top):
509
512
                with allow_writes(dirpath):
510
513
                    for names in filenames, dirnames:
511
 
                        for pos, name in enumerate(names):
512
 
                            if name == '.partial':
513
 
                                new_name = '.u1partial'
514
 
                            else:
515
 
                                new_name = re.sub(r'^(.+)\.partial$',
516
 
                                                  r'.u1partial.\1', name)
517
 
                                conflict_re = r'^(.+)\.conflict((?:\.\d+)?)$'
518
 
                                new_name = re.sub(conflict_re,
519
 
                                                  r'\1.u1conflict\2', new_name)
520
 
                            if new_name != name:
521
 
                                self.log.debug('renaming %r to %r',
522
 
                                               name, new_name)
523
 
                                os.rename(os.path.join(dirpath, name),
524
 
                                          os.path.join(dirpath, new_name))
525
 
                                names[pos] = new_name
 
514
                        self._upgrade_names(dirpath, names)
526
515
        self._upgrade_metadata_3(md_version)
527
516
        self._update_metadata_version()
528
517
 
 
518
    def _upgrade_names(self, dirpath, names):
 
519
        """
 
520
        Do the actual renaming for _upgrade_metadata_2
 
521
        """
 
522
        for pos, name in enumerate(names):
 
523
            new_name = name
 
524
            if re.match(r'.*\.partial$|\.u1partial(?:\..+)?', name):
 
525
                if name == '.partial':
 
526
                    new_name = '.u1partial'
 
527
                else:
 
528
                    new_name = re.sub(r'^(.+)\.partial$',
 
529
                                      r'.u1partial.\1', name)
 
530
                if new_name != name:
 
531
                    while os.path.lexists(os.path.join(dirpath, new_name)):
 
532
                        # very, very strange
 
533
                        self.log.warning('Found a .partial and .u1partial'
 
534
                                         ' for the same file: %s!' % new_name)
 
535
                        new_name += '.1'
 
536
            elif re.search(r'\.(?:u1)?conflict(?:\.\d+)?$', name):
 
537
                new_name = re.sub(r'^(.+)\.conflict((?:\.\d+)?)$',
 
538
                                  r'\1.u1conflict\2', name)
 
539
                if new_name != name:
 
540
                    while os.path.lexists(os.path.join(dirpath, new_name)):
 
541
                        m = re.match(r'(.*\.u1conflict)((?:\.\d+)?)$', new_name)
 
542
                        base, num = m.groups()
 
543
                        if not num:
 
544
                            num = '.1'
 
545
                        else:
 
546
                            num = '.' + str(int(num[1:])+1)
 
547
                        new_name = base + num
 
548
            if new_name != name:
 
549
                old_path = os.path.join(dirpath, name)
 
550
                new_path = os.path.join(dirpath, new_name)
 
551
                self.log.debug('renaming %r to %r' % (old_path, new_path))
 
552
                os.rename(old_path, new_path)
 
553
                names[pos] = new_name
 
554
 
 
555
 
529
556
    def _upgrade_metadata_3(self, md_version):
530
557
        """
531
558
        Upgrade to version 4 (new layout!)
542
569
            os.chmod(old_share_dir, 0775)
543
570
            if not os.path.exists(os.path.dirname(self.m.shares_dir)):
544
571
                os.makedirs(os.path.dirname(self.m.shares_dir))
 
572
            self.log.debug('moving shares dir from: %r to %r',
 
573
                           old_share_dir, self.m.shares_dir)
545
574
            shutil.move(old_share_dir, self.m.shares_dir)
546
575
        # update the shares metadata
547
576
        shares = ShareFileShelf(self._shares_dir)
555
584
        shared = ShareFileShelf(self._shared_dir)
556
585
        for key in shared.keys():
557
586
            share = shared[key]
558
 
            share.path = share.path.replace(old_root_dir, self.m.root_dir)
 
587
            if share.path is not None:
 
588
                share.path = share.path.replace(old_root_dir, self.m.root_dir)
559
589
            shared[key] = share
560
590
        # move the My Files contents, taking care of dir/files with the same
561
591
        # in the new root
562
592
        if os.path.exists(old_root_dir):
 
593
            self.log.debug('moving My Files contents to the root')
563
594
            # make My Files rw
564
595
            os.chmod(old_root_dir, 0775)
565
596
            path_join = os.path.join
566
597
            for relpath in os.listdir(old_root_dir):
567
598
                old_path = path_join(old_root_dir, relpath)
568
599
                new_path = path_join(self.m.root_dir, relpath)
 
600
 
569
601
                if os.path.exists(new_path):
570
602
                    shutil.move(new_path, new_path+'.u1conflict')
571
 
                shutil.move(old_path, new_path)
 
603
                if relpath == 'Shared With Me':
 
604
                    # remove the Shared with Me symlink inside My Files!
 
605
                    self.log.debug('removing shares symlink from old root')
 
606
                    os.remove(old_path)
 
607
                else:
 
608
                    self.log.debug('moving %r to %r', old_path, new_path)
 
609
                    shutil.move(old_path, new_path)
 
610
            self.log.debug('removing old root: %r', old_root_dir)
572
611
            os.rmdir(old_root_dir)
 
612
 
 
613
        self._upgrade_metadata_4(md_version)
573
614
        # update the .version file
574
615
        self._update_metadata_version()
575
616
 
 
617
    def _upgrade_metadata_4(self, md_version):
 
618
        """
 
619
        Upgrade to version 5 (fix the broken symlink!)
 
620
        """
 
621
        self.log.debug('upgrading from metadata 4 (broken symlink!)')
 
622
        if os.path.islink(self.m.shares_dir_link):
 
623
            target = os.readlink(self.m.shares_dir_link)
 
624
            if os.path.normpath(target) == self.m.shares_dir_link:
 
625
                # the symnlink points to itself
 
626
                self.log.debug('removing broken shares symlink: %r -> %r',
 
627
                               self.m.shares_dir_link, target)
 
628
                os.remove(self.m.shares_dir_link)
 
629
 
 
630
        self._update_metadata_version()
 
631
 
576
632
    def _update_metadata_version(self):
577
633
        """write the version of the metadata"""
578
634
        if not os.path.exists(os.path.dirname(self._version_file)):