Как вы уже указали сами, вам в основном нужно что-то, что слушает ходы, поэтому я подумал, что что-то подделал, чтобы дать вам указание, как это будет работать.
Я пробовал использовать gio.FileMonitor, но в конце концов вернулся к использованию простой старой pyinotify, потому что у последнего есть встроенная поддержка для обнаружения переименования/перемещения файлов.
import pyinotify
import bzrlib
from bzrlib.workingtree import WorkingTree
from bzrlib.errors import NotBranchError, BzrRenameFailedError
directories_to_watch = [
# Add the paths to your working copies/branches to watch here
]
wm = pyinotify.WatchManager()
# When you listen to both MOVED_FROM and MOVED_TO the event for MOVED_TO will include both
# pathname (new path) and src_pathname (previous path).
mask = pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO
class EventHandler(pyinotify.ProcessEvent):
def process_IN_MOVED_TO(self, event):
try:
tree, path = WorkingTree.open_containing(event.src_pathname)
root = event.src_pathname[:-len(path)] # Ugh, hackish
if not path.startswith(".bzr"): # Also hackish (to exclude events for anything in the .bzr subdirectory)
try:
tree.lock_tree_write()
source = event.src_pathname[len(root):] # Again hackish
target = event.pathname[len(root):] # Same
tree.rename_one(source, target)
print "Renamed %s to %s" % (source, target)
except BzrRenameFailedError: # Same
pass
finally:
tree.unlock()
except NotBranchError:
return
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
for path in directories_to_watch:
wdd = wm.add_watch(path, mask, rec=True, auto_add=True)
print "Recursively watching %s" % path
notifier.loop()
Вот как это работает:
$ mv afile bfile
$ bzr status
renamed:
afile => bfile
$ mv bfile foobar/
$ bzr status
renamed:
afile => foobar/bfile
$ mv foobar/ zoobar
$ bzr status
renamed:
afile => zoobar/bfile
foobar/ => zoobar/
$ mv zoobar/ foobar
$ bzr status
renamed:
afile => foobar/bfile
$ mv foobar/bfile afile
И мы туда, где мы начали ;-)
[править]
Если вы не хотите вручную перечислить различные каталоги, чтобы посмотреть, что может быть хорошей идеей написать расширение Nautilus, которое отслеживает различные рабочие копии, с которыми он сталкивается, поскольку вы навигации. Вот кое-что, чтобы вы начали (это входит в ~/.nautilus/python-extensions
):
import os
import pickle
import nautilus
import gio
from xdg import BaseDirectory as basedir
import bzrlib
from bzrlib.workingtree import WorkingTree
from bzrlib.errors import NotBranchError
class BzrMonitor(nautilus.InfoProvider, nautilus.MenuProvider):
data_directory = basedir.save_data_path("bzrmonitor")
data_filename = os.path.join(data_directory, "workingcopies.db")
def __init__(self):
print "Initializing BzrMonitor extension..."
try:
data_file = open(self.data_filename, "r")
self.data = pickle.load(data_file)
except IOError:
self.data = []
data_file = open(self.data_filename, "w")
pickle.dump(self.data, data_file)
data_file.close()
def detect_and_save_branch(self, path):
try:
tree, rel_path = WorkingTree.open_containing(path)
# TODO: Still can't figure out how to get the path from the tree itself
if len(rel_path) > 0:
root = path[:-len(rel_path)]
else:
root = path
root = root.rstrip(os.path.sep)
if root not in self.data:
print "Added not seen before branch %s to cache..." % root
self.data.append(root)
data_file = open(self.data_filename, "w")
pickle.dump(self.data, data_file)
data_file.close()
except NotBranchError:
return
def update_file_info(self, item):
"""
This function is called when:
- When you enter a directory (once for each item but only when the
item was modified since the last time it was listed)
- When you refresh (once for each item visible)
- When an item viewable from the current window is created or modified
"""
self.detect_and_save_branch(gio.File(item.get_uri()).get_path())
def get_file_items(self, window, items):
"""
Menu activated with items selected. Nautilus also calls this function
when rendering submenus, even though this is not needed since the entire
menu has already been returned.
"""
pass
def get_background_items(self, window, item):
"""
Menu activated on entering a directory. Builds context menu for File
menu and for window background.
"""
self.detect_and_save_branch(gio.File(item.get_uri()).get_path())
заимствовали различные строки документации из кода ;-)
расширения RabbitVCS в В вашем мониторе вы, вероятно, хотите, чтобы посмотреть файл workingcopies.db
для добавляет и регистрирует часы на любых новых рабочих копиях, которые он нашел.
Ресурсы
Ты потрясающий! Конечно, есть некоторые ограничения. Чтобы вручную просмотреть каталоги, которые вы хотите посмотреть, это боль, и это не удается, если вы переместите файл в каталог, который еще не добавлен в bzr. Но для ответа на вопрос от незнакомца в Интернете это здорово! Я посмотрю и посмотрю, смогу ли я уточнить скрипт, когда буду его использовать. –
*/blush * Спасибо за добрые слова :-) Чтобы не было необходимости вручную перечислять каталоги, которые вы хотите просмотреть, может быть хорошей идеей создать расширение Nautilus, которое отслеживает, где ваши рабочие копии, когда вы перемещаетесь вдоль , Я добавил пример. Мне было бы очень интересно узнать, что вы придумали. –