/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to olive/push.py

  • Committer: Jelmer Vernooij
  • Date: 2006-09-29 20:59:52 UTC
  • mfrom: (0.8.92 merge)
  • Revision ID: jelmer@samba.org-20060929205952-32ce1f02b7cf334b
MergeĀ OliveĀ code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    pygtk.require("2.0")
22
22
except:
23
23
    pass
24
 
try:
25
 
    import gtk
26
 
    import gtk.gdk
27
 
    import gtk.glade
28
 
except:
29
 
    sys.exit(1)
30
 
 
31
 
import olive.backend.commit as commit
32
 
import olive.backend.errors as errors
33
 
import olive.backend.info as info
 
24
    
 
25
import gtk
 
26
import gtk.gdk
 
27
import gtk.glade
 
28
 
 
29
import bzrlib.errors as errors
 
30
 
 
31
from olive import gladefile
34
32
 
35
33
class OlivePush:
36
34
    """ Display Push dialog and perform the needed actions. """
37
 
    def __init__(self, gladefile, comm, dialog):
 
35
    def __init__(self, branch):
38
36
        """ Initialize the Push dialog. """
39
 
        self.gladefile = gladefile
40
 
        self.glade = gtk.glade.XML(self.gladefile, 'window_push')
41
 
        
42
 
        # Communication object
43
 
        self.comm = comm
44
 
        # Dialog object
45
 
        self.dialog = dialog
 
37
        self.glade = gtk.glade.XML(gladefile, 'window_push')
46
38
        
47
39
        self.window = self.glade.get_widget('window_push')
 
40
 
 
41
        self.branch = branch
48
42
        
49
43
        # Dictionary for signal_autoconnect
50
44
        dic = { "on_button_push_push_clicked": self.push,
51
45
                "on_button_push_cancel_clicked": self.close,
 
46
                "on_button_push_test_clicked": self.test,
52
47
                "on_radiobutton_push_stored_toggled": self.stored_toggled,
53
48
                "on_radiobutton_push_specific_toggled": self.specific_toggled, }
54
49
        
56
51
        self.glade.signal_autoconnect(dic)
57
52
        
58
53
        # Get some useful widgets
 
54
        self.radio_stored = self.glade.get_widget('radiobutton_push_stored')
 
55
        self.radio_specific = self.glade.get_widget('radiobutton_push_specific')
59
56
        self.entry_stored = self.glade.get_widget('entry_push_stored')
60
57
        self.entry_location = self.glade.get_widget('entry_push_location')
61
58
        self.check_remember = self.glade.get_widget('checkbutton_push_remember')
62
59
        self.check_overwrite = self.glade.get_widget('checkbutton_push_overwrite')
63
60
        self.check_create = self.glade.get_widget('checkbutton_push_create')
64
 
        
65
 
        # Get stored location
66
 
        self.notbranch = False
67
 
        try:
68
 
            loc = info.get_push_location(self.comm.get_path())
69
 
        except errors.NotBranchError:
70
 
            self.notbranch = True
71
 
            return
72
 
 
73
 
        if loc is not None:
74
 
            self.entry_stored.set_text(loc)
 
61
        self.label_test = self.glade.get_widget('label_push_test')
 
62
        self.image_test = self.glade.get_widget('image_push_test')
 
63
        
 
64
        # Set initial state
 
65
        self.entry_location.set_sensitive(0)
 
66
        self.check_remember.set_sensitive(0)
 
67
        self.check_create.set_sensitive(0)
 
68
        
 
69
        self.entry_stored.set_text(branch.get_push_location())
75
70
    
76
71
    def display(self):
77
72
        """ Display the Push dialog. """
78
 
        if self.notbranch:
79
 
            self.dialog.error_dialog(_('Directory is not a branch'),
80
 
                                     _('You can perform this action only in a branch.'))
81
 
            self.close()
82
 
        else:
83
 
            self.window.show()
84
 
            self.width, self.height = self.window.get_size()
 
73
        self.window.show()
 
74
        self.width, self.height = self.window.get_size()
85
75
    
86
76
    def stored_toggled(self, widget):
87
77
        if widget.get_active():
88
 
            self.entry_stored.show()
89
 
            self.entry_location.hide()
90
 
            self.check_remember.hide()
91
 
            self.check_create.hide()
92
 
            self.window.resize(self.width, self.height)
 
78
            self.entry_stored.set_sensitive(1)
 
79
            self.entry_location.set_sensitive(0)
 
80
            self.check_remember.set_sensitive(0)
 
81
            self.check_create.set_sensitive(0)
93
82
        else:
94
 
            self.entry_stored.hide()
95
 
            self.entry_location.show()
96
 
            self.check_remember.show()
97
 
            self.check_create.show()
 
83
            self.entry_stored.set_sensitive(0)
 
84
            self.entry_location.set_sensitive(1)
 
85
            self.check_remember.set_sensitive(1)
 
86
            self.check_create.set_sensitive(1)
98
87
    
99
88
    def specific_toggled(self, widget):
100
89
        if widget.get_active():
101
 
            self.entry_stored.hide()
102
 
            self.entry_location.show()
103
 
            self.check_remember.show()
104
 
            self.check_create.show()
 
90
            self.entry_stored.set_sensitive(0)
 
91
            self.entry_location.set_sensitive(1)
 
92
            self.check_remember.set_sensitive(1)
 
93
            self.check_create.set_sensitive(1)
105
94
        else:
106
 
            self.entry_stored.show()
107
 
            self.entry_location.hide()
108
 
            self.check_remember.hide()
109
 
            self.check_create.hide()
 
95
            self.entry_stored.set_sensitive(1)
 
96
            self.entry_location.set_sensitive(0)
 
97
            self.check_remember.set_sensitive(0)
 
98
            self.check_create.set_sensitive(0)
110
99
    
111
100
    def push(self, widget):
112
 
        radio_stored = self.glade.get_widget('radiobutton_push_stored')
113
 
        radio_specific = self.glade.get_widget('radiobutton_push_specific')
114
 
        
115
101
        revs = 0
116
 
        self.comm.set_busy(self.window)
117
 
        if radio_stored.get_active():
 
102
        if self.radio_stored.get_active():
118
103
            try:
119
 
                revs = commit.push(self.comm.get_path(),
120
 
                                   overwrite=self.check_overwrite.get_active())
 
104
                revs = do_push(self.branch,
 
105
                               overwrite=self.check_overwrite.get_active())
121
106
            except errors.NotBranchError:
122
 
                self.dialog.error_dialog(_('Directory is not a branch'),
 
107
                error_dialog(_('Directory is not a branch'),
123
108
                                         _('You can perform this action only in a branch.'))
124
109
                return
125
 
            except errors.NoLocationKnown:
126
 
                self.dialog.error_dialog(_('Push location is unknown'),
127
 
                                         _('Please specify a location manually.'))
128
 
                return
129
 
            except errors.NonExistingParent, errmsg:
130
 
                self.dialog.error_dialog(_('Non existing parent directory'),
131
 
                                         _("The parent directory (%s)\ndoesn't exist.") % errmsg)
132
 
                return
133
 
            except errors.DivergedBranchesError:
134
 
                self.dialog.error_dialog(_('Branches have been diverged'),
 
110
            except errors.DivergedBranches:
 
111
                error_dialog(_('Branches have been diverged'),
135
112
                                         _('You cannot push if branches have diverged. Use the\noverwrite option if you want to push anyway.'))
136
113
                return
137
 
            except:
138
 
                raise
139
 
        elif radio_specific.get_active():
 
114
        elif self.radio_specific.get_active():
140
115
            location = self.entry_location.get_text()
141
116
            if location == '':
142
 
                self.dialog.error_dialog(_('No location specified'),
 
117
                error_dialog(_('No location specified'),
143
118
                                         _('Please specify a location or use the default.'))
144
119
                return
145
120
            
146
121
            try:
147
 
                revs = commit.push(self.comm.get_path(), location,
148
 
                                   self.check_remember.get_active(),
149
 
                                   self.check_overwrite.get_active(),
150
 
                                   self.check_create.get_active())
 
122
                revs = do_push(self.branch, location,
 
123
                               self.check_remember.get_active(),
 
124
                               self.check_overwrite.get_active(),
 
125
                               self.check_create.get_active())
151
126
            except errors.NotBranchError:
152
 
                self.dialog.error_dialog(_('Directory is not a branch'),
 
127
                error_dialog(_('Directory is not a branch'),
153
128
                                         _('You can perform this action only in a branch.'))
154
 
                self.comm.set_busy(self.window, False)
155
 
                return
156
 
            except errors.NonExistingParent, errmsg:
157
 
                self.dialog.error_dialog(_('Non existing parent directory'),
158
 
                                         _("The parent directory (%s)\ndoesn't exist.") % errmsg)
159
 
                self.comm.set_busy(self.window, False)
160
 
                return
161
 
            except errors.DivergedBranchesError:
162
 
                self.dialog.error_dialog(_('Branches have been diverged'),
 
129
                return
 
130
            except errors.DivergedBranches:
 
131
                error_dialog(_('Branches have been diverged'),
163
132
                                         _('You cannot push if branches have diverged. Use the\noverwrite option if you want to push anyway.'))
164
 
                self.comm.set_busy(self.window, False)
165
 
                return
166
 
            except errors.PathPrefixNotCreated:
167
 
                self.dialog.error_dialog(_('Path prefix not created'),
168
 
                                         _("The path leading up to the specified location couldn't\nbe created."))
169
 
                self.comm.set_busy(self.window, False)
170
 
                return
171
 
            except:
172
 
                raise
173
 
        else:
174
 
            # This should really never happen
175
 
            pass
 
133
                return
176
134
        
177
135
        self.close()
178
 
        self.dialog.info_dialog(_('Push successful'),
 
136
        info_dialog(_('Push successful'),
179
137
                                _('%d revision(s) pushed.') % revs)
180
138
    
 
139
    def test(self, widget):
 
140
        """ Test if write access possible. """
 
141
        import re
 
142
        _urlRE = re.compile(r'^(?P<proto>[^:/\\]+)://(?P<path>.*)$')
 
143
        
 
144
        if self.radio_stored.get_active():
 
145
            url = self.entry_stored.get_text()
 
146
        elif self.radio_specific.get_active():
 
147
            url = self.entry_location.get_text()
 
148
        
 
149
        m = _urlRE.match(url)
 
150
        if m:
 
151
            proto = m.groupdict()['proto']
 
152
            if (proto == 'sftp') or (proto == 'file') or (proto == 'ftp'):
 
153
                # have write acces (most probably)
 
154
                self.image_test.set_from_stock(gtk.STOCK_YES, 4)
 
155
                self.label_test.set_markup(_('<b>Write access is probably available</b>'))
 
156
            else:
 
157
                # no write access
 
158
                self.image_test.set_from_stock(gtk.STOCK_NO, 4)
 
159
                self.label_test.set_markup(_('<b>No write access</b>'))
 
160
        else:
 
161
            # couldn't determine
 
162
            self.image_test.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
 
163
            self.label_test.set_markup(_('<b>Could not determine</b>'))
 
164
    
181
165
    def close(self, widget=None):
182
166
        self.window.destroy()
 
167
 
 
168
def do_push(branch, location=None, remember=False, overwrite=False,
 
169
         create_prefix=False):
 
170
    """ Update a mirror of a branch.
 
171
    
 
172
    :param branch: the source branch
 
173
    
 
174
    :param location: the location of the branch that you'd like to update
 
175
    
 
176
    :param remember: if set, the location will be stored
 
177
    
 
178
    :param overwrite: overwrite target location if it diverged
 
179
    
 
180
    :param create_prefix: create the path leading up to the branch if it doesn't exist
 
181
    
 
182
    :return: number of revisions pushed
 
183
    """
 
184
    from bzrlib.branch import Branch
 
185
    from bzrlib.bzrdir import BzrDir
 
186
    from bzrlib.transport import get_transport
 
187
        
 
188
    br_from = Branch.open_containing(branch)[0]
 
189
    
 
190
    stored_loc = br_from.get_push_location()
 
191
    if location is None:
 
192
        if stored_loc is None:
 
193
            error_dialog(_('Push location is unknown'),
 
194
                                     _('Please specify a location manually.'))
 
195
            return
 
196
        else:
 
197
            location = stored_loc
 
198
 
 
199
    transport = get_transport(location)
 
200
    location_url = transport.base
 
201
 
 
202
    if br_from.get_push_location() is None or remember:
 
203
        br_from.set_push_location(location_url)
 
204
 
 
205
    old_rh = []
 
206
 
 
207
    try:
 
208
        dir_to = BzrDir.open(location_url)
 
209
        br_to = dir_to.open_branch()
 
210
    except errors.NotBranchError:
 
211
        # create a branch.
 
212
        transport = transport.clone('..')
 
213
        if not create_prefix:
 
214
            try:
 
215
                relurl = transport.relpath(location_url)
 
216
                transport.mkdir(relurl)
 
217
            except errors.NoSuchFile:
 
218
                error_dialog(_('Non existing parent directory'),
 
219
                                         _("The parent directory (%s)\ndoesn't exist.") % location)
 
220
                return
 
221
        else:
 
222
            current = transport.base
 
223
            needed = [(transport, transport.relpath(location_url))]
 
224
            while needed:
 
225
                try:
 
226
                    transport, relpath = needed[-1]
 
227
                    transport.mkdir(relpath)
 
228
                    needed.pop()
 
229
                except errors.NoSuchFile:
 
230
                    new_transport = transport.clone('..')
 
231
                    needed.append((new_transport,
 
232
                                   new_transport.relpath(transport.base)))
 
233
                    if new_transport.base == transport.base:
 
234
                        error_dialog(_('Path prefix not created'),
 
235
                                                 _("The path leading up to the specified location couldn't\nbe created."))
 
236
                        return
 
237
        dir_to = br_from.bzrdir.clone(location_url,
 
238
            revision_id=br_from.last_revision())
 
239
        br_to = dir_to.open_branch()
 
240
        count = len(br_to.revision_history())
 
241
    else:
 
242
        old_rh = br_to.revision_history()
 
243
        try:
 
244
            tree_to = dir_to.open_workingtree()
 
245
        except errors.NotLocalUrl:
 
246
            # FIXME - what to do here? how should we warn the user?
 
247
            #warning('This transport does not update the working '
 
248
            #        'tree of: %s' % (br_to.base,))
 
249
            count = br_to.pull(br_from, overwrite)
 
250
        except errors.NoWorkingTree:
 
251
            count = br_to.pull(br_from, overwrite)
 
252
        else:
 
253
            count = tree_to.pull(br_from, overwrite)
 
254
 
 
255
    return count