Kiln » TortoiseHg » TortoiseHg
Clone URL:  
shlib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# shlib.py - TortoiseHg shell utilities # # Copyright 2007 TK Soh <teekaysoh@gmail.com> # Copyright 2008 Steve Borho <steve@borho.org> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. import os import sys import time import threading from mercurial.i18n import _ from mercurial import hg def get_system_times(): t = os.times() if t[4] == 0.0: # Windows leaves this as zero, so use time.clock() t = (t[0], t[1], t[2], t[3], time.clock()) return t if os.name == 'nt': def browse_url(url): try: import win32api except ImportError: return def start_browser(): try: win32api.ShellExecute(0, 'open', url, None, None, 0) except Exception: pass threading.Thread(target=start_browser).start() def shell_notify(paths): try: from win32com.shell import shell, shellcon import pywintypes except ImportError: return dirs = set() for path in paths: if path is None: continue abspath = os.path.abspath(path) if not os.path.isdir(abspath): abspath = os.path.dirname(abspath) dirs.add(abspath) # send notifications to deepest directories first for dir in sorted(dirs, key=len, reverse=True): try: pidl, ignore = shell.SHILCreateFromPath(dir, 0) except pywintypes.com_error: return if pidl is None: continue shell.SHChangeNotify(shellcon.SHCNE_UPDATEITEM, shellcon.SHCNF_IDLIST | shellcon.SHCNF_FLUSH, pidl, None) def update_thgstatus(ui, root, wait=False): '''Rewrite the file .hg/thgstatus Caches the information provided by repo.status() in the file .hg/thgstatus, which can then be read by the overlay shell extension to display overlay icons for directories. The file .hg/thgstatus contains one line for each directory that has removed, modified or added files (in that order of preference). Each line consists of one char for the status of the directory (r, m or a), followed by the relative path of the directory in the repo. If the file .hg/thgstatus is empty, then the repo's working directory is clean. Specify wait=True to wait until the system clock ticks to the next second before accessing Mercurial's dirstate. This is useful when Mercurial's .hg/dirstate contains unset entries (in output of "hg debugstate"). unset entries happen if .hg/dirstate was updated within the same second as Mercurial updated the respective file in the working tree. This happens with a high probability for example when cloning a repo. The overlay shell extension will display unset dirstate entries as (potentially false) modified. Specifying wait=True ensures that there are no unset entries left in .hg/dirstate when this function exits. ''' if wait: tref = time.time() tdelta = float(int(tref)) + 1.0 - tref if (tdelta > 0.0): time.sleep(tdelta) repo = hg.repository(ui, root) # a fresh repo object is needed repo.bfstatus = True repo.lfstatus = True repostate = repo.status() # will update .hg/dirstate as a side effect repo.bfstatus = False repo.lfstatus = False modified, added, removed, deleted = repostate[:4] dirstatus = {} def dirname(f): return '/'.join(f.split('/')[:-1]) for fn in added: dirstatus[dirname(fn)] = 'a' for fn in modified: dirstatus[dirname(fn)] = 'm' for fn in removed + deleted: dirstatus[dirname(fn)] = 'r' update = False f = None try: try: f = repo.opener('thgstatus', 'rb') for dn in sorted(dirstatus): s = dirstatus[dn] e = f.readline() if e.startswith('@@noicons'): break if e == '' or e[0] != s or e[1:-1] != dn: update = True break if f.readline() != '': # extra line in f, needs update update = True except IOError: update = True finally: if f != None: f.close() if update: f = repo.opener('thgstatus', 'wb', atomictemp=True) for dn in sorted(dirstatus): s = dirstatus[dn] f.write(s + dn + '\n') ui.note("%s %s\n" % (s, dn)) f.rename() else: def shell_notify(paths): if not paths: return notify = os.environ.get('THG_NOTIFY', '.tortoisehg/notify') if not os.path.isabs(notify): notify = os.path.join(os.path.expanduser('~'), notify) os.environ['THG_NOTIFY'] = notify if not os.path.isfile(notify): return try: f_notify = open(notify, 'w') except IOError: return try: abspaths = [os.path.abspath(path) for path in paths if path] f_notify.write('\n'.join(abspaths)) finally: f_notify.close() def update_thgstatus(*args, **kws): pass def browse_url(url): def start_browser(): if sys.platform == 'darwin': # use Mac OS X internet config module (removed in Python 3.0) import ic ic.launchurl(url) else: try: import gconf client = gconf.client_get_default() browser = client.get_string( '/desktop/gnome/url-handlers/http/command') + '&' os.system(browser % url) except ImportError: # If gconf is not found, fall back to old standard os.system('firefox ' + url) threading.Thread(target=start_browser).start()