/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/backend/info.py

  • Committer: Szilveszter Farkas (Phanatic)
  • Date: 2006-08-02 20:35:25 UTC
  • mto: (0.14.1 main) (93.1.1 win32.bialix)
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: Szilveszter.Farkas@gmail.com-20060802203525-9cb57147463c2672
Implemented context menu for the file list.

2006-08-02  Szilveszter Farkas <Szilveszter.Farkas@gmail.com>

    * cmenu.ui: context menu UIManager description added
    * setup.py: install cmenu.ui to the appropriate place
    * olive/frontend/gtk/menu.py: implement the context menus
    * olive/frontend/gtk/__init__.py: added button_press_event for file list
    * olive/frontend/gtk/handler.py: handling that even (show popup menu)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
 
2
# Some parts of the code are:
 
3
# Copyright (C) 2005, 2006 by Canonical Ltd
 
4
 
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
 
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
 
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
import bzrlib
 
20
import bzrlib.errors as errors
 
21
 
 
22
from bzrlib.branch import Branch
 
23
from bzrlib.workingtree import WorkingTree
 
24
 
 
25
from errors import (DifferentBranchesError, NotBranchError, PrefixFormatError,
 
26
                    RevisionValueError)
 
27
 
 
28
def diff(revision=None, file_list=None, diff_options=None, prefix=None):
 
29
    """ Save the diff into a temporary file.
 
30
    
 
31
    :param revision: a list of revision numbers (one or two elements)
 
32
    
 
33
    :param file_list: list of files you want to diff
 
34
    
 
35
    :param diff_options: external diff options
 
36
    
 
37
    :param prefix: 0 - p0, 1 - p1, or specify prefixes in the form of old/:new/
 
38
    
 
39
    :return: path to the temporary file which contains the diff output (the frontend has to remove it!)
 
40
    """
 
41
    from tempfile import mkstemp
 
42
    
 
43
    from bzrlib.builtins import internal_tree_files
 
44
    from bzrlib.diff import show_diff_trees
 
45
    from bzrlib.revisionspec import RevisionSpec_int
 
46
    from bzrlib.workingtree import WorkingTree
 
47
    
 
48
    from info_helper import diff_helper
 
49
 
 
50
    if (prefix is None) or (prefix == '0'):
 
51
        # diff -p0 format
 
52
        old_label = ''
 
53
        new_label = ''
 
54
    elif prefix == '1':
 
55
        old_label = 'old/'
 
56
        new_label = 'new/'
 
57
    else:
 
58
        if not ':' in prefix:
 
59
            raise PrefixFormatError
 
60
        old_label, new_label = prefix.split(":")
 
61
    
 
62
    try:
 
63
        tree1, file_list = internal_tree_files(file_list)
 
64
        tree2 = None
 
65
        b = None
 
66
        b2 = None
 
67
    except errors.FileInWrongBranch:
 
68
        if len(file_list) != 2:
 
69
            raise DifferentBranchesError
 
70
 
 
71
        tree1, file1 = WorkingTree.open_containing(file_list[0])
 
72
        tree2, file2 = WorkingTree.open_containing(file_list[1])
 
73
    
 
74
        if file1 != "" or file2 != "":
 
75
            raise DifferentBranchesError
 
76
    
 
77
        file_list = None
 
78
    
 
79
    tmpfile = mkstemp(prefix='olive_')
 
80
    tmpfp = open(tmpfile[1], 'w')
 
81
    
 
82
    if revision is not None:
 
83
        if tree2 is not None:
 
84
            raise RevisionValueError
 
85
    
 
86
        if len(revision) >= 1:
 
87
            revision[0] = RevisionSpec_int(revision[0])
 
88
        if len(revision) == 2:
 
89
            revision[1] = RevisionSpec_int(revision[1])
 
90
        
 
91
        if (len(revision) == 1) or (revision[1].spec is None):
 
92
            ret = diff_helper(tree1, file_list, diff_options,
 
93
                              revision[0], 
 
94
                              old_label=old_label, new_label=new_label,
 
95
                              output=tmpfp)
 
96
        elif len(revision) == 2:
 
97
            ret = diff_helper(tree1, file_list, diff_options,
 
98
                              revision[0], revision[1],
 
99
                              old_label=old_label, new_label=new_label,
 
100
                              output=tmpfp)
 
101
        else:
 
102
            raise RevisionValueError
 
103
    else:
 
104
        if tree2 is not None:
 
105
            ret = show_diff_trees(tree1, tree2, tmpfp, 
 
106
                                  specific_files=file_list,
 
107
                                  external_diff_options=diff_options,
 
108
                                  old_label=old_label, new_label=new_label)
 
109
        else:
 
110
            ret = diff_helper(tree1, file_list, diff_options,
 
111
                              old_label=old_label, new_label=new_label,
 
112
                              output=tmpfp)
 
113
    
 
114
    tmpfp.close()
 
115
    
 
116
    if ret == 0:
 
117
        return False
 
118
    else:
 
119
        return tmpfile[1]
 
120
 
 
121
def info(location):
 
122
    """ Get info about branch, working tree, and repository
 
123
    
 
124
    :param location: the location of the branch/working tree/repository
 
125
    
 
126
    :return: the information in dictionary format
 
127
    
 
128
    The following informations are delivered (if available):
 
129
    ret['location']['lightcoroot']: Light checkout root
 
130
    ret['location']['sharedrepo']: Shared repository
 
131
    ret['location']['repobranch']: Repository branch
 
132
    ret['location']['cobranch']: Checkout of branch
 
133
    ret['location']['repoco']: Repository checkout
 
134
    ret['location']['coroot']: Checkout root
 
135
    ret['location']['branchroot']: Branch root
 
136
    ret['related']['parentbranch']: Parent branch
 
137
    ret['related']['publishbranch']: Publish to branch
 
138
    ret['format']['control']: Control format
 
139
    ret['format']['workingtree']: Working tree format
 
140
    ret['format']['branch']: Branch format
 
141
    ret['format']['repository']: Repository format
 
142
    ret['locking']['workingtree']: Working tree lock status
 
143
    ret['locking']['branch']: Branch lock status
 
144
    ret['locking']['repository']: Repository lock status
 
145
    ret['mrevbranch']['missing']: Missing revisions in branch
 
146
    ret['mrevworking']['missing']: Missing revisions in working tree
 
147
    ret['wtstats']['unchanged']: Unchanged files
 
148
    ret['wtstats']['modified']: Modified files
 
149
    ret['wtstats']['added']: Added files
 
150
    ret['wtstats']['removed']: Removed files
 
151
    ret['wtstats']['renamed']: Renamed files
 
152
    ret['wtstats']['unknown']: Unknown files
 
153
    ret['wtstats']['ignored']: Ingnored files
 
154
    ret['wtstats']['subdirs']: Versioned subdirectories
 
155
    ret['brstats']['revno']: Revisions in branch
 
156
    ret['brstats']['commiters']: Number of commiters
 
157
    ret['brstats']['age']: Age of branch in days
 
158
    ret['brstats']['firstrev']: Time of first revision
 
159
    ret['brstats']['lastrev']: Time of last revision
 
160
    ret['repstats']['revisions']: Revisions in repository
 
161
    ret['repstats']['size']: Size of repository in bytes
 
162
    """
 
163
    import bzrlib.bzrdir as bzrdir
 
164
    
 
165
    import info_helper
 
166
    
 
167
    ret = {}
 
168
    a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
 
169
    try:
 
170
        working = a_bzrdir.open_workingtree()
 
171
        working.lock_read()
 
172
        try:
 
173
            branch = working.branch
 
174
            repository = branch.repository
 
175
            control = working.bzrdir
 
176
 
 
177
            ret['location'] = info_helper.get_location_info(repository, branch, working)
 
178
            ret['related'] = info_helper.get_related_info(branch)
 
179
            ret['format'] = info_helper.get_format_info(control, repository, branch, working)
 
180
            ret['locking'] = info_helper.get_locking_info(repository, branch, working)
 
181
            ret['mrevbranch'] = info_helper.get_missing_revisions_branch(branch)
 
182
            ret['mrevworking'] = info_helper.get_missing_revisions_working(working)
 
183
            ret['wtstats'] = info_helper.get_working_stats(working)
 
184
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
185
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
186
        finally:
 
187
            working.unlock()
 
188
            return ret
 
189
        return
 
190
    except (errors.NoWorkingTree, errors.NotLocalUrl):
 
191
        pass
 
192
 
 
193
    try:
 
194
        branch = a_bzrdir.open_branch()
 
195
        branch.lock_read()
 
196
        try:
 
197
            ret['location'] = info_helper.get_location_info(repository, branch)
 
198
            ret['related'] = info_helper.get_related_info(branch)
 
199
            ret['format'] = info_helper.get_format_info(control, repository, branch)
 
200
            ret['locking'] = info_helper.get_locking_info(repository, branch)
 
201
            ret['mrevbranch'] = info_helper.get_missing_revisions_branch(branch)
 
202
            ret['brstats'] = info_helper.get_branch_stats(branch)
 
203
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
204
        finally:
 
205
            branch.unlock()
 
206
            return ret
 
207
        return
 
208
    except errors.NotBranchError:
 
209
        pass
 
210
 
 
211
    try:
 
212
        repository = a_bzrdir.open_repository()
 
213
        repository.lock_read()
 
214
        try:
 
215
            ret['location'] = info_helper.get_location_info(repository)
 
216
            ret['format'] = info_helper.get_format_info(control, repository)
 
217
            ret['locking'] = info_helper.get_locking_info(repository)
 
218
            ret['repstats'] = info_helper.get_repository_stats(repository)
 
219
        finally:
 
220
            repository.unlock()
 
221
            return ret
 
222
        return
 
223
    except errors.NoRepositoryPresent:
 
224
        pass
 
225
 
 
226
def is_checkout(location):
 
227
    """ Check if the location is a checkout.
 
228
    
 
229
    :param location: the location you want to check
 
230
    
 
231
    :return: True or False respectively
 
232
    """
 
233
    try:
 
234
        branch = Branch.open_containing(location)[0]
 
235
    except errors.NotBranchError:
 
236
        raise NotBranchError
 
237
    
 
238
    try:
 
239
        working = WorkingTree.open_containing(location)[0]
 
240
    except:
 
241
        raise
 
242
    
 
243
    working_path = working.bzrdir.root_transport.base
 
244
    branch_path = branch.bzrdir.root_transport.base
 
245
    
 
246
    if working_path != branch_path:
 
247
        # lightweight checkout
 
248
        return True
 
249
    elif branch.get_bound_location():
 
250
        # checkout
 
251
        return True
 
252
    else:
 
253
        return False
 
254
 
 
255
 
 
256
def log(location, timezone='original', verbose=False, show_ids=False,
 
257
        forward=False, revision=None, log_format=None, message=None,
 
258
        long=False, short=False, line=False):
 
259
    """ Print log into a temporary file.
 
260
    
 
261
    :param location: location of local/remote branch or file
 
262
    
 
263
    :param timzone: requested timezone
 
264
    
 
265
    :param verbose: verbose output
 
266
    
 
267
    :param show_ids:
 
268
    
 
269
    :param forward: if True, start from the earliest entry
 
270
    
 
271
    :param revision: revision range as a list ([from, to])
 
272
    
 
273
    :param log_format: line, short, long
 
274
    
 
275
    :param message: show revisions whose message matches this regexp
 
276
    
 
277
    :param long: long log format
 
278
    
 
279
    :param short: short log format
 
280
    
 
281
    :param line: line log format
 
282
    
 
283
    :return: full path to the temporary file containing the log (the frontend has to remove it!)
 
284
    """
 
285
    from tempfile import mkstemp
 
286
    
 
287
    from bzrlib import bzrdir    
 
288
    from bzrlib.builtins import get_log_format
 
289
    from bzrlib.log import log_formatter, show_log
 
290
    from bzrlib.revisionspec import RevisionSpec_int
 
291
    
 
292
    assert message is None or isinstance(message, basestring), \
 
293
        "invalid message argument %r" % message
 
294
    direction = (forward and 'forward') or 'reverse'
 
295
        
 
296
    # log everything
 
297
    file_id = None
 
298
    
 
299
    # find the file id to log:
 
300
    dir, fp = bzrdir.BzrDir.open_containing(location)
 
301
    b = dir.open_branch()
 
302
    if fp != '':
 
303
        try:
 
304
            # might be a tree:
 
305
            inv = dir.open_workingtree().inventory
 
306
        except (errors.NotBranchError, errors.NotLocalUrl):
 
307
            # either no tree, or is remote.
 
308
            inv = b.basis_tree().inventory
 
309
        file_id = inv.path2id(fp)
 
310
 
 
311
    if revision is not None:
 
312
        if len(revision) >= 1:
 
313
            revision[0] = RevisionSpec_int(revision[0])
 
314
        if len(revision) == 2:
 
315
            revision[1] = RevisionSpec_int(revision[1])
 
316
    
 
317
    if revision is None:
 
318
        rev1 = None
 
319
        rev2 = None
 
320
    elif len(revision) == 1:
 
321
        rev1 = rev2 = revision[0].in_history(b).revno
 
322
    elif len(revision) == 2:
 
323
        if revision[0].spec is None:
 
324
            # missing begin-range means first revision
 
325
            rev1 = 1
 
326
        else:
 
327
            rev1 = revision[0].in_history(b).revno
 
328
 
 
329
        if revision[1].spec is None:
 
330
            # missing end-range means last known revision
 
331
            rev2 = b.revno()
 
332
        else:
 
333
            rev2 = revision[1].in_history(b).revno
 
334
    else:
 
335
        raise RevisionValueError
 
336
 
 
337
    # By this point, the revision numbers are converted to the +ve
 
338
    # form if they were supplied in the -ve form, so we can do
 
339
    # this comparison in relative safety
 
340
    if rev1 > rev2:
 
341
        (rev2, rev1) = (rev1, rev2)
 
342
 
 
343
    if (log_format == None):
 
344
        default = b.get_config().log_format()
 
345
        log_format = get_log_format(long=long, short=short, line=line, 
 
346
                                    default=default)
 
347
    
 
348
    tmpfile = mkstemp(prefix='olive_')
 
349
    tmpfp = open(tmpfile[1], 'w')
 
350
    
 
351
    lf = log_formatter(log_format,
 
352
                       show_ids=show_ids,
 
353
                       to_file=tmpfp,
 
354
                       show_timezone=timezone)
 
355
 
 
356
    show_log(b,
 
357
             lf,
 
358
             file_id,
 
359
             verbose=verbose,
 
360
             direction=direction,
 
361
             start_revision=rev1,
 
362
             end_revision=rev2,
 
363
             search=message)
 
364
    
 
365
    tmpfp.close()
 
366
    return tmpfile[1]
 
367
 
 
368
def nick(branch, nickname=None):
 
369
    """ Get or set nickname.
 
370
    
 
371
    :param branch: path to the branch
 
372
    
 
373
    :param nickname: if specified, the nickname will be set
 
374
    
 
375
    :return: nickname
 
376
    """
 
377
    try:
 
378
        branch = Branch.open_containing(branch)[0]
 
379
    except errors.NotBranchError:
 
380
        raise NotBranchError
 
381
    
 
382
    if nickname is not None:
 
383
        branch.nick = nickname
 
384
 
 
385
    return branch.nick    
 
386
 
 
387
def revno(branch):
 
388
    """ Get current revision number for specified branch
 
389
    
 
390
    :param branch: path to the branch
 
391
    
 
392
    :return: revision number
 
393
    """
 
394
    try:
 
395
        revno = Branch.open_containing(branch)[0].revno()
 
396
    except errors.NotBranchError:
 
397
        raise NotBranchError
 
398
    else:
 
399
        return revno
 
400
 
 
401
def version():
 
402
    """ Get version information from bzr
 
403
    
 
404
    :return: bzrlib version
 
405
    """
 
406
    return bzrlib.__version__
 
407
 
 
408
def whoami(branch=None, email=False):
 
409
    """ Get user's data (name and email address)
 
410
    
 
411
    :param branch: if specified, the user's data will be looked up in the branch's config
 
412
    
 
413
    :param email: if True, only the email address will be returned
 
414
    
 
415
    :return: user info (only email address if email is True)
 
416
    """
 
417
    from bzrlib.workingtree import WorkingTree
 
418
    
 
419
    if branch is not None:
 
420
        try:
 
421
            b = WorkingTree.open_containing(u'.')[0].branch
 
422
            config = bzrlib.config.BranchConfig(b)
 
423
        except NotBranchError:
 
424
            config = bzrlib.config.GlobalConfig()
 
425
    else:
 
426
        config = bzrlib.config.GlobalConfig()
 
427
        
 
428
    if email:
 
429
        return config.user_email()
 
430
    else:
 
431
        return config.username()