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
|
"""Display models and utility functions"""
import collections
try:
import notify2
except ImportError:
notify2 = None
try:
import notifypy
except ImportError:
notifypy = None
from . import resources
from .models import prefs
NOTIFICATIONS_AVAILABLE = bool(notify2 or notifypy)
def shorten_paths(source_paths):
"""Shorten a sequence of paths into unique strings for display"""
result = {}
# Start by assuming that all paths are in conflict.
# On each iteration we will collect all the path suffixes, move the newly
# unique entries to the result, and repeat until no conflicts remain.
count = 0
conflicts = list(source_paths)
in_conflict = True
while in_conflict:
count += 1
# Gather the suffixes for the current paths in conflict
suffixes = collections.defaultdict(list)
for path in conflicts:
suffix = path_suffix(path, count)
suffixes[suffix].append(path)
# Loop over the suffixes to gather new conflicts and unique entries.
conflicts = []
in_conflict = False
for suffix, paths in suffixes.items():
# If only a single path exists for the suffix then no conflict
# exists, and the suffix is valid.
if len(paths) == 1:
result[paths[0]] = suffix
# If this loop runs too long then bail out by using the full path.
elif count >= 128:
for path in paths:
result[path] = path
# If multiple paths map to the same suffix then the paths are
# considered in conflict, and will be reprocessed.
else:
conflicts.extend(paths)
in_conflict = True
return result
def path_suffix(path, count):
"""Return `count` number of trailing path components"""
path = normalize_path(path)
components = path.split('/')[-count:]
return '/'.join(components)
def normalize_path(path):
"""Normalize a path so that only "/" is used as a separator"""
return path.replace('\\', '/')
def notify(context, title, message, icon):
"""Send a notification using notify2 xor notifypy"""
app_name = context.app_name
if notify2:
notify2.init(app_name)
notification = notify2.Notification(title, message, icon)
notification.show()
elif notifypy:
notification = notifypy.Notify()
notification.application_name = app_name
notification.title = title
notification.message = message
notification.icon = icon
notification.send()
else:
context.notifier.log.emit(f'{title}: {message}')
def push_notification(context, title, message, error=False, allow_popups=True):
"""Emit a push notification"""
if prefs.enable_popups(context) and allow_popups:
if error:
context.notifier.critical.emit(title, dict(message=message))
else:
context.notifier.information.emit(title, dict(message=message))
else:
if error:
icon = resources.icon_path('git-cola-error.svg')
else:
icon = resources.icon_path('git-cola-ok.svg')
notify(context, title, message, icon)
def git_commit_date(datetime):
"""Return the datetime as a string for use by Git"""
return datetime.strftime('%a %b %d %H:%M:%S %Y %z')
|