in eden/scm/edenscm/hgext/commitcloud/interactivehistory.py [0:0]
def showhistory(ui, repo, reponame, workspacename, template, **opts):
class cloudsl(object):
def __init__(self, ui, repo, reponame, workspacename, **opts):
self.ui = ui
self.repo = repo
self.reponame = reponame
self.workspacename = workspacename
self.opts = opts
self.serv = service.get(ui, tokenmod.TokenLocator(ui).token)
self.servlock = threading.Lock()
self.renderevent = threading.Event()
self.running = True
self.cache = {}
with progress.spinner(ui, _("fetching cloud smartlog history")):
self.versions = sorted(
self.serv.gethistoricalversions(reponame, workspacename),
key=lambda version: version["version_number"],
)
initversion = opts.get("workspace_version")
date = opts.get("date")
inittime = int(util.parsedate(date)[0]) if date else None
if initversion and inittime:
raise error.Abort(
"'--workspace-version' and '--date' options can't be both provided"
)
if inittime:
timestamps = sorted(
self.versions,
key=lambda version: version["timestamp"],
)
for index, version in enumerate(timestamps):
if version["timestamp"] >= inittime:
initversion = version["version_number"]
break
if index == len(timestamps) - 1:
raise error.Abort(
"You have no recorded history at or after this date"
)
smartlogstyle = ui.config("templatealias", template)
if smartlogstyle:
self.opts["template"] = "{%s}" % smartlogstyle
if initversion:
initversion = int(initversion)
for index, version in enumerate(self.versions):
if version["version_number"] == initversion:
self.cur_index = index
break
else:
versionrange = [
version["version_number"] for version in self.versions
]
raise error.Abort(
"workspace version %s is not available (%s to %s are available)"
% (initversion, min(versionrange), max(versionrange))
)
else:
self.cur_index = len(self.versions)
if opts.get("all"):
self.limit = 0
else:
self.limit = 12 * 7 * 24 * 60 * 60 # 12 weeks
self.flags = []
if ui.configbool("commitcloud", "sl_showremotebookmarks"):
self.flags.append("ADD_REMOTE_BOOKMARKS")
if ui.configbool("commitcloud", "sl_showallbookmarks"):
self.flags.append("ADD_ALL_BOOKMARKS")
if opts.get("force_original_backend"):
self.flags.append("USE_ORIGINAL_BACKEND")
def prevversion(self):
if self.cur_index > 0:
self.cur_index -= 1
self.schedulerender()
def nextversion(self):
if self.cur_index < len(self.versions):
self.cur_index += 1
self.schedulerender()
def schedulerender(self):
self.renderevent.set()
def renderloop(self):
while self.running:
self.renderevent.clear()
self.render()
self.renderevent.wait()
def run(self):
# Bind [ and ] to switch versions. Unbind switching file (tab + shift-tab).
self.tui = sptui.sptui(
"Cloud Smartlog History",
[
(
("Navigation", "Go to previous version", self.prevversion),
[(sptui.NONE, "[")],
),
(
("Navigation", "Go to next version", self.nextversion),
[(sptui.NONE, "]")],
),
(
None,
[(sptui.NONE, "Tab"), (sptui.SHIFT, "Tab")],
),
],
)
# Start a background thread that will render the smartlog
# versions into streampager.
r = threading.Thread(target=self.renderloop, name="render")
r.daemon = True
r.start()
# Pre-cache some recent versions in another background thread.
t = threading.Thread(target=self.precache, name="precache")
t.daemon = True
t.start()
# On the main thread, wait for the pager to terminate, and
# then clean up.
self.tui.wait()
self.running = False
self.renderevent.set()
def precache(self):
for i in range(3):
v = len(self.versions) - 1 - i
if v not in self.cache:
try:
self.cache[v] = self.rendercontents(v)
except Exception:
pass
time.sleep(0)
def loadoldversion(self, versionindex):
versionnumber = self.versions[versionindex]["version_number"]
with self.servlock, progress.spinner(
self.ui, _("fetching version %s") % versionnumber
):
limit = self.limit
if limit > 0:
# Increase the limit by how long ago the smartlog was
# backed-up. This gives a rolling window, so viewing
# versions more than the limit in age will still show
# commits.
timestamp = self.versions[versionindex]["timestamp"]
limit += max(0, int(time.time() - timestamp))
slinfo = self.serv.getsmartlogbyversion(
self.reponame,
self.workspacename,
self.repo,
None,
versionnumber,
limit,
self.flags,
)
formatteddate = time.strftime(
"%Y-%m-%d %H:%M:%S", time.localtime(slinfo.timestamp)
)
title = "Smartlog version %d synced at %s:" % (
slinfo.version,
formatteddate,
)
return (title, slinfo)
def loadcurrentversion(self):
with self.servlock:
with progress.spinner(self.ui, _("fetching latest version")):
slinfo = self.serv.getsmartlog(
self.reponame,
self.workspacename,
self.repo,
self.limit,
self.flags,
)
title = "Current cloud smartlog"
return (title, slinfo)
def render(self):
versionindex = self.cur_index
try:
contents = self.rendercontents(versionindex)
self.tui.replace_contents(contents)
except Exception:
if versionindex == len(self.versions):
error = "Failed to load latest smartlog"
else:
versionnumber = self.versions[versionindex]["version_number"]
error = "Failed to load version %s" % versionnumber
contents = [
error.encode(),
b"",
b"The error was:",
b"",
] + traceback.format_exc().encode().split(b"\n")
self.tui.replace_contents(contents)
def rendercontents(self, versionindex):
if versionindex in self.cache:
contents = self.cache[versionindex]
else:
if versionindex == len(self.versions):
(title, slinfo) = self.loadcurrentversion()
else:
(title, slinfo) = self.loadoldversion(versionindex)
contents = [
ui.label(
"Commit Cloud Smartlog History", "bold cyan underline"
).encode(),
ui.label(
"Use [ and ] to navigate to earlier or later versions", "cyan"
).encode(),
ui.label(
"Note: version dates may be off by one due to a server bug",
"cyan",
).encode(),
b"",
title.encode(),
b"",
]
firstpublic, revdag = self.serv.makedagwalker(slinfo, self.repo)
displayer = cmdutil.show_changeset(
self.ui, self.repo, self.opts, buffered=True
)
def out(row):
contents.extend(row.rstrip().encode().split(b"\n"))
with progress.spinner(ui, _("loading commit information")):
cmdutil.displaygraph(
self.ui,
self.repo,
revdag,
displayer,
reserved=firstpublic,
out=out,
)
self.cache[versionindex] = contents
return contents
cloudsl(ui, repo, reponame, workspacename, **opts).run()