Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print('loading insync nemo plugin..')
- from gi.repository import GObject
- from gi.repository import Nemo
- DEV_MODE = False
- import json
- import os
- import socket
- import sys
- import urllib
- FS_ENCODING = sys.getfilesystemencoding() # C is 'ANSI_X3.4-1968'
- def ipc_insync(**kw):
- #print('<ipc-insync>',kw)
- data = json.dumps( kw )
- socket_file = u'/tmp/insync%r.sock' % os.getuid()
- if not os.path.exists(socket_file):
- if DEV_MODE:
- print('WARN: insync socket not found')
- return None
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- sock.connect(socket_file)
- except:
- return None
- sock.send(data)
- res = sock.recv(4096)
- sock.close()
- if res.strip():
- return json.loads(res.strip())
- else:
- return None
- GDRIVE = ('Open in Google Drive', 'cm:open', 'web-browser-symbolic')
- SEPARATOR = (unicode(u'\u2015' * 10), None, None)
- SHARE = ('Share', 'cm:share', 'send-to-symbolic')
- LINK = ('Copy public Link', 'cm:public_link', 'document-save-symbolic')
- _EMBLEM_KEYS = {
- 'SYNCED': 'emblem-insync-synced',
- 'SYNCING': 'emblem-insync-syncing',
- 'ERROR': 'emblem-insync-error',
- 'DES_ERROR': 'emblem-insync-des-error',
- 'DES_SYNCING': 'emblem-insync-syncing',
- }
- class InsyncMenuProvider(GObject.GObject, Nemo.MenuProvider, Nemo.InfoProvider):
- DEFAULT_INSYNC_CONFIG_PATH = os.path.expanduser('~/.config/Insync')
- def __init__(self):
- self._insync_active = False
- self._insync_roots = None
- self._symlinks = {} # link : target
- def load_insync_settings(self):
- msg = ipc_insync(command='GET-INFO')
- if msg:
- if DEV_MODE:
- print('INSYNC ACTIVE')
- print(msg)
- self._insync_active = True
- self._insync_roots = msg
- else:
- self._insync_active = False
- symcache = os.path.join(self.DEFAULT_INSYNC_CONFIG_PATH, 'symlink-cache.json')
- if os.path.isfile(symcache):
- f = open(symcache, 'rb')
- self._symlinks = json.load(f)
- f.close()
- def get_background_items(self, window, file):
- print( 'calling get background items' )
- return None
- def get_file_items(self, window, files):
- if DEV_MODE:
- print('get file items', files)
- if len(files) != 1:
- # TODO what can we do with mutiple files here
- return None
- self.load_insync_settings()
- if not self._insync_roots:
- return None
- file = files[0]
- path = urllib.unquote(file.get_uri()[len('file://'):])
- path = unicode(path, FS_ENCODING)
- if DEV_MODE:
- print path
- is_dir = os.path.isdir(path)
- roots = tuple([root + '/' for root in self._insync_roots])
- if self._insync_active and path.startswith(roots): ## this block requires insync daemon is running
- tip = 'Insync folder actions' if is_dir else 'Insync file actions'
- item = Nemo.MenuItem(
- name="Insync",
- label="Insync",
- tip=tip,
- icon='insync'
- )
- sub_menu = Nemo.Menu()
- item.set_submenu(sub_menu)
- for text, cmd, icon in [GDRIVE, SEPARATOR, SHARE, LINK]:
- menu_item = Nemo.MenuItem(name=text, label=text, tip=text, icon=icon)
- if cmd:
- menu_item.connect('activate', self.do_action, file, cmd)
- else:
- menu_item.sensitive = False
- sub_menu.append_item(menu_item)
- return [item]
- elif not path.startswith(tuple(self._insync_roots)): ## do not allow paths starting with ~/Insync to be symlinked inside itself
- targets = self._symlinks.values()
- if DEV_MODE:
- print 'self._symlinks', self._symlinks
- symlink_target = unicode(
- urllib.unquote(file.get_uri()[len('file://'):]),
- FS_ENCODING
- )
- toplevel = self.make_symlinks_menu(symlink_target)
- return [toplevel]
- def make_symlinks_menu(self, symlink_target):
- uid = 0 # this is lame
- toplevel = Nemo.MenuItem(
- name="Insync::%s" % uid,
- label="Add to Insync",
- tip="Add to Insync - creates a symlink to this folder, in the user folder you select",
- icon='insync'
- )
- uid += 1
- submenu = Nemo.Menu()
- toplevel.set_submenu(submenu)
- reverse_symlinks = dict((value, key) for key, value in self._symlinks.iteritems())
- if symlink_target in reverse_symlinks:
- full_path, symlink_name = os.path.split(reverse_symlinks[symlink_target])
- _, folder_name = os.path.split(full_path)
- label = u'%s/%s (linked)' % (folder_name, symlink_name)
- item = Nemo.MenuItem(
- name='Insync::%s' % uid,
- label=label,
- tip=label
- )
- submenu.append_item(item)
- uid += 1
- else:
- _, target_name = os.path.split(symlink_target)
- for insync_root in self._insync_roots:
- _, folder_name = os.path.split(insync_root)
- if target_name in os.listdir(insync_root):
- label = u'%s/%s (name in use)' % (folder_name, target_name)
- item = Nemo.MenuItem(
- name='Insync::%s' % uid,
- label=label,
- tip=label
- )
- else:
- item = Nemo.MenuItem(
- name='Insync::%s' % uid,
- label=folder_name,
- tip='create symlink in user root folder'
- )
- item.connect('activate', self.do_symlink, symlink_target, target_name, insync_root)
- submenu.append_item(item)
- uid += 1
- return toplevel
- def do_symlink(self, menu, path, target, insync_root):
- dest = os.path.join(insync_root, target)
- if DEV_MODE:
- print('<doing symlink>', path, dest)
- self._symlinks[path] = dest
- os.symlink(path, dest)
- if not ipc_insync(command='IS-ALIVE') and os.path.isdir(self.DEFAULT_INSYNC_CONFIG_PATH):
- symcache = os.path.join(self.DEFAULT_INSYNC_CONFIG_PATH, 'symlink-cache.json')
- with open(symcache, 'wb') as f:
- json.dump(self._symlinks, f)
- def do_action(self, menu, file, method):
- path = urllib.unquote(
- file.get_uri()[len('file://'):]
- )
- ipc_insync( method=method, full_path=path)
- def update_file_info_full(self, provider, handle, closure, file):
- if file.get_uri_scheme() != 'file':
- return
- filename = urllib.unquote(file.get_uri()[len('file://'):])
- status = ipc_insync(command='GET-FILE-STATUS', full_path=filename)
- if DEV_MODE:
- print filename, status
- if not status or status == 'UNKNOWN':
- return Nemo.OperationResult.COMPLETE
- GObject.timeout_add(1, self.add_emblem, provider, handle, closure, file,
- filename, status)
- return Nemo.OperationResult.IN_PROGRESS
- def add_emblem(self, provider, handle, closure, file, filename, status):
- emblem = _EMBLEM_KEYS[status]
- if os.path.isdir(filename):
- is_shared = ipc_insync(command='IS-FILE-SHARED', full_path=filename)
- if is_shared:
- emblem += '-shared'
- file.add_emblem(emblem)
- Nemo.info_provider_update_complete_invoke(closure, provider, handle,
- Nemo.OperationResult.COMPLETE)
- return False
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement