/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 push.py

  • Committer: Jelmer Vernooij
  • Date: 2007-02-03 14:18:57 UTC
  • Revision ID: jelmer@samba.org-20070203141857-9xxd3uvju5oo1p8z
Move dialog to top-level directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
 
# Copyright (C) 2007 by Jelmer Vernooij <jelmer@samba.org>
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
23
22
    
24
23
import gtk
25
24
 
 
25
from olive import delimiter
26
26
from errors import show_bzr_error
27
27
 
28
 
# FIXME: This needs to be public JRV 20070714
29
 
from bzrlib.builtins import _create_prefix
30
28
from bzrlib.config import LocationConfig
31
29
import bzrlib.errors as errors
32
30
 
33
 
from bzrlib.plugins.gtk import _i18n
34
 
from dialog import error_dialog, info_dialog, question_dialog
 
31
from olive.dialog import error_dialog, info_dialog, question_dialog
35
32
 
36
 
from history import UrlHistory
37
33
 
38
34
class PushDialog(gtk.Dialog):
39
35
    """ New implementation of the Push dialog. """
40
 
    def __init__(self, repository, revid, branch=None, parent=None):
 
36
    def __init__(self, branch, parent=None):
41
37
        """ Initialize the Push dialog. """
42
38
        gtk.Dialog.__init__(self, title="Push - Olive",
43
39
                                  parent=parent,
45
41
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
46
42
        
47
43
        # Get arguments
48
 
        self.repository = repository
49
 
        self.revid = revid
50
44
        self.branch = branch
51
45
        
52
46
        # Create the widgets
53
 
        self._label_location = gtk.Label(_i18n("Location:"))
 
47
        self._label_location = gtk.Label(_("Location:"))
 
48
        self._label_test = gtk.Label(_("(click the Test button to check write access)"))
 
49
        self._check_remember = gtk.CheckButton(_("_Remember as default location"),
 
50
                                               use_underline=True)
 
51
        self._check_prefix = gtk.CheckButton(_("Create the path _leading up to the location"),
 
52
                                             use_underline=True)
 
53
        self._check_overwrite = gtk.CheckButton(_("_Overwrite target if diverged"),
 
54
                                                use_underline=True)
54
55
        self._combo = gtk.ComboBoxEntry()
55
 
        self._button_push = gtk.Button(_i18n("_Push"), use_underline=True)
 
56
        self._button_test = gtk.Button(_("_Test"), use_underline=True)
 
57
        self._button_push = gtk.Button(_("_Push"), use_underline=True)
56
58
        self._hbox_location = gtk.HBox()
 
59
        self._hbox_test = gtk.HBox()
 
60
        self._image_test = gtk.Image()
57
61
        
58
62
        # Set callbacks
 
63
        self._button_test.connect('clicked', self._on_test_clicked)
59
64
        self._button_push.connect('clicked', self._on_push_clicked)
60
65
        
61
66
        # Set properties
 
67
        self._image_test.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
62
68
        self._label_location.set_alignment(0, 0.5)
 
69
        self._label_test.set_alignment(0, 0.5)
63
70
        self._hbox_location.set_spacing(3)
 
71
        self._hbox_test.set_spacing(3)
64
72
        self.vbox.set_spacing(3)
65
73
        
66
74
        # Pack widgets
67
75
        self._hbox_location.pack_start(self._label_location, False, False)
68
76
        self._hbox_location.pack_start(self._combo, True, True)
 
77
        self._hbox_test.pack_start(self._image_test, False, False)
 
78
        self._hbox_test.pack_start(self._label_test, True, True)
69
79
        self.vbox.pack_start(self._hbox_location)
 
80
        self.vbox.pack_start(self._check_remember)
 
81
        self.vbox.pack_start(self._check_prefix)
 
82
        self.vbox.pack_start(self._check_overwrite)
 
83
        self.vbox.pack_start(self._hbox_test)
 
84
        self.action_area.pack_start(self._button_test)
70
85
        self.action_area.pack_end(self._button_push)
71
86
        
72
87
        # Show the dialog
73
88
        self.vbox.show_all()
74
89
        
75
90
        # Build location history
76
 
        self._history = UrlHistory(self.branch.get_config(), 'push_history')
77
91
        self._build_history()
78
92
        
79
93
    def _build_history(self):
80
94
        """ Build up the location history. """
81
 
        self._combo_model = gtk.ListStore(str)
82
 
        for item in self._history.get_entries():
83
 
            self._combo_model.append([ item ])
84
 
        self._combo.set_model(self._combo_model)
85
 
        self._combo.set_text_column(0)
86
 
        
87
 
        if self.branch is not None:
88
 
            location = self.branch.get_push_location()
89
 
            if location is not None:
90
 
                self._combo.get_child().set_text(location)
 
95
        config = LocationConfig(self.branch.base)
 
96
        history = config.get_user_option('gpush_history')
 
97
        if history is not None:
 
98
            self._combo_model = gtk.ListStore(str)
 
99
            for item in history.split(delimiter):
 
100
                self._combo_model.append([ item ])
 
101
            self._combo.set_model(self._combo_model)
 
102
            self._combo.set_text_column(0)
 
103
        
 
104
        location = self.branch.get_push_location()
 
105
        if location:
 
106
            self._combo.get_child().set_text(location)
 
107
    
 
108
    def _add_to_history(self, location):
 
109
        """ Add specified location to the history (if not yet added). """
 
110
        config = LocationConfig(self.branch.base)
 
111
        history = config.get_user_option('gpush_history')
 
112
        if history is None:
 
113
            config.set_user_option('gpush_history', location)
 
114
        else:
 
115
            h = history.split(delimiter)
 
116
            if location not in h:
 
117
                h.append(location)
 
118
            config.set_user_option('gpush_history', delimiter.join(h))
 
119
    
 
120
    def _on_test_clicked(self, widget):
 
121
        """ Test button clicked handler. """
 
122
        import re
 
123
        _urlRE = re.compile(r'^(?P<proto>[^:/\\]+)://(?P<path>.*)$')
 
124
        
 
125
        url = self._combo.get_child().get_text()
 
126
        
 
127
        m = _urlRE.match(url)
 
128
        if m:
 
129
            proto = m.groupdict()['proto']
 
130
            if (proto == 'sftp') or (proto == 'file') or (proto == 'ftp'):
 
131
                # have write acces (most probably)
 
132
                self._image_test.set_from_stock(gtk.STOCK_YES, 4)
 
133
                self._label_test.set_markup(_('<b>Write access is probably available</b>'))
 
134
            else:
 
135
                # no write access
 
136
                self._image_test.set_from_stock(gtk.STOCK_NO, 4)
 
137
                self._label_test.set_markup(_('<b>No write access</b>'))
 
138
        else:
 
139
            # couldn't determine
 
140
            self._image_test.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
 
141
            self._label_test.set_markup(_('<b>Could not determine</b>'))
91
142
    
92
143
    @show_bzr_error
93
144
    def _on_push_clicked(self, widget):
94
145
        """ Push button clicked handler. """
95
146
        location = self._combo.get_child().get_text()
96
147
        revs = 0
97
 
        if self.branch is not None and self.branch.get_push_location() is None:
98
 
            response = question_dialog(_i18n('Set default push location'),
99
 
                                       _i18n('There is no default push location set.\nSet %r as default now?') % location)
100
 
            if response == gtk.RESPONSE_OK:
101
 
                self.branch.set_push_location(location)
102
 
 
103
148
        try:
104
 
            revs = do_push(self.branch, location=location, overwrite=False)
 
149
            revs = do_push(self.branch,
 
150
                           location=location,
 
151
                           overwrite=self._check_overwrite.get_active(),
 
152
                           remember=self._check_remember.get_active(),
 
153
                           create_prefix=self._check_prefix.get_active())
105
154
        except errors.DivergedBranches:
106
 
            response = question_dialog(_i18n('Branches have been diverged'),
107
 
                                       _i18n('You cannot push if branches have diverged.\nOverwrite?'))
108
 
            if response == gtk.RESPONSE_YES:
109
 
                revs = do_push(self.branch, location=location, overwrite=True)
 
155
            response = question_dialog(_('Branches have been diverged'),
 
156
                                       _('You cannot push if branches have diverged.\nOverwrite?'))
 
157
            if response == gtk.RESPONSE_OK:
 
158
                revs = do_push(self.branch, overwrite=True)
 
159
            return
110
160
        
111
 
        self._history.add_entry(location)
112
 
        info_dialog(_i18n('Push successful'),
113
 
                    _i18n("%d revision(s) pushed.") % revs)
 
161
        self._add_to_history(location)
 
162
        info_dialog(_('Push successful'),
 
163
                    _("%d revision(s) pushed.") % revs)
114
164
        
115
165
        self.response(gtk.RESPONSE_OK)
116
166
 
117
 
def do_push(br_from, location, overwrite):
 
167
def do_push(branch, location=None, remember=False, overwrite=False,
 
168
         create_prefix=False):
118
169
    """ Update a mirror of a branch.
119
170
    
120
 
    :param br_from: the source branch
 
171
    :param branch: the source branch
121
172
    
122
173
    :param location: the location of the branch that you'd like to update
123
174
    
 
175
    :param remember: if set, the location will be stored
 
176
    
124
177
    :param overwrite: overwrite target location if it diverged
125
178
    
 
179
    :param create_prefix: create the path leading up to the branch if it doesn't exist
 
180
    
126
181
    :return: number of revisions pushed
127
182
    """
128
183
    from bzrlib.bzrdir import BzrDir
129
184
    from bzrlib.transport import get_transport
130
185
        
 
186
    br_from = branch
 
187
    
 
188
    stored_loc = br_from.get_push_location()
 
189
    if location is None:
 
190
        if stored_loc is None:
 
191
            error_dialog(_('Push location is unknown'),
 
192
                         _('Please specify a location manually.'))
 
193
            return
 
194
        else:
 
195
            location = stored_loc
 
196
 
131
197
    transport = get_transport(location)
132
198
    location_url = transport.base
133
199
 
 
200
    if br_from.get_push_location() is None or remember:
 
201
        br_from.set_push_location(location_url)
 
202
 
134
203
    old_rh = []
135
204
 
136
205
    try:
139
208
    except errors.NotBranchError:
140
209
        # create a branch.
141
210
        transport = transport.clone('..')
142
 
        try:
143
 
            relurl = transport.relpath(location_url)
144
 
            transport.mkdir(relurl)
145
 
        except errors.NoSuchFile:
146
 
            response = question_dialog(_i18n('Non existing parent directory'),
147
 
                         _i18n("The parent directory (%s)\ndoesn't exist. Create?") % location)
148
 
            if response == gtk.RESPONSE_OK:
149
 
                _create_prefix(transport)
150
 
            else:
 
211
        if not create_prefix:
 
212
            try:
 
213
                relurl = transport.relpath(location_url)
 
214
                transport.mkdir(relurl)
 
215
            except errors.NoSuchFile:
 
216
                error_dialog(_('Non existing parent directory'),
 
217
                             _("The parent directory (%s)\ndoesn't exist.") % location)
151
218
                return
 
219
        else:
 
220
            current = transport.base
 
221
            needed = [(transport, transport.relpath(location_url))]
 
222
            while needed:
 
223
                try:
 
224
                    transport, relpath = needed[-1]
 
225
                    transport.mkdir(relpath)
 
226
                    needed.pop()
 
227
                except errors.NoSuchFile:
 
228
                    new_transport = transport.clone('..')
 
229
                    needed.append((new_transport,
 
230
                                   new_transport.relpath(transport.base)))
 
231
                    if new_transport.base == transport.base:
 
232
                        error_dialog(_('Path prefix not created'),
 
233
                                     _("The path leading up to the specified location couldn't\nbe created."))
 
234
                        return
152
235
        dir_to = br_from.bzrdir.clone(location_url,
153
236
            revision_id=br_from.last_revision())
154
237
        br_to = dir_to.open_branch()
159
242
            tree_to = dir_to.open_workingtree()
160
243
        except errors.NotLocalUrl:
161
244
            # FIXME - what to do here? how should we warn the user?
 
245
            #warning('This transport does not update the working '
 
246
            #        'tree of: %s' % (br_to.base,))
162
247
            count = br_to.pull(br_from, overwrite)
163
248
        except errors.NoWorkingTree:
164
249
            count = br_to.pull(br_from, overwrite)