|
# 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()
|
Loading...