Advertisement
lpugoy

test nautilus extension

Jul 29th, 2013
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.46 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # Insync Nautilus Plugin
  4. #
  5. # Authors
  6. # Brett Hartshorn <brett@insynchq.com>
  7. # Luis Manuel R. Pugoy <lpugoy@insynchq.com>
  8. #
  9. # Copyright Insynchq Pte. Ltd., ("Insync") | http://www.insynchq.com
  10. # License: GNU GPL v2
  11.  
  12. DEV_MODE = False
  13.  
  14. import json
  15. import os
  16. import socket
  17. import sys
  18. import urllib
  19. from gi.repository import GObject
  20.  
  21. GTK3 = False
  22. try:
  23.   from gi.repository import Nautilus
  24.   GTK3 = True   # this might not be true
  25. except:
  26.   print('WARN - using Nautilus2 wrapper')
  27.   import nautilus as Nautilus   # Nautilus2
  28.  
  29. if GTK3:
  30.   # http://python-gtk-3-tutorial.readthedocs.org/en/latest/drag_and_drop.html
  31.   from gi.repository import Gtk
  32.   from gi.repository import Gdk
  33.   (TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF) = range(2)
  34.   (COLUMN_TEXT, COLUMN_PIXBUF) = range(2)
  35.   DRAG_ACTION = Gdk.DragAction.COPY
  36.  
  37. print(Nautilus)
  38.  
  39. if __name__ == '__main__':  ## this is only for testing ##
  40.   if '--install-local' in sys.argv:
  41.     ## Nautilus2 is no longer supported ##
  42.     #if os.path.isdir( os.path.expanduser('~/.nautilus') ):
  43.     #  path = os.path.expanduser('~/.nautilus/python-extensions')
  44.     #  if not os.path.isdir(path): os.makedirs( path )
  45.     #  os.system('cp -v %s ~/.nautilus/python-extensions/.' %__file__)
  46.  
  47.     ## Nautilus3 ##
  48.     path = os.path.expanduser('~/.local/share/nautilus-python/extensions')
  49.     if not os.path.isdir(path):
  50.       os.makedirs(path)
  51.     os.system('cp -v %s ~/.local/share/nautilus-python/extensions/.' %__file__)
  52.   else:
  53.     os.system('cp -v %s /usr/share/nautilus-python/extensions/.' %__file__)
  54.  
  55.   os.system('nautilus -q')
  56.   sys.exit()
  57.  
  58.  
  59. print('Insync Nautilus Plugin')
  60.  
  61. FS_ENCODING = sys.getfilesystemencoding()   # C is 'ANSI_X3.4-1968'
  62.  
  63.  
  64. def ipc_insync(**kw):
  65.   data = json.dumps(kw)
  66.   socket_file = u'/tmp/insync%r.sock' % os.getuid()
  67.   if not os.path.exists(socket_file):
  68.     if DEV_MODE:
  69.       print('WARN: insync socket not found')
  70.     return None
  71.   sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  72.   sock.settimeout(0.1)
  73.   try:
  74.     sock.connect(socket_file)
  75.     sock.send(data)
  76.     res = sock.recv(4096)
  77.     sock.close()
  78.   except:
  79.     return None
  80.   if res.strip():
  81.     return json.loads(res.strip())
  82.   else:
  83.     return None
  84.  
  85.  
  86. _EMBLEM_KEYS = {
  87.   'SYNCED': 'emblem-insync-synced',
  88.   'SYNCING': 'emblem-insync-syncing',
  89.   'ERROR': 'emblem-insync-error',
  90.   'DES_ERROR': 'emblem-insync-des-error',
  91.   'DES_SYNCING': 'emblem-insync-syncing',
  92. }
  93.  
  94.  
  95. class InsyncExtension(GObject.GObject, Nautilus.MenuProvider, Nautilus.InfoProvider):
  96.   '''
  97.  see: /usr/share/doc/python-nautilus/examples/
  98.  
  99.  1. nautilus.ColumnProvider - It exposes a single function get_columns . This function has to return a sequence of nautilus.Column objects.
  100.  2. nautilus.InfoProvider - Exposes a single function update_file_info with a file as an argument.
  101.  3. nautilus.LocationWidgetProvider - Exposes a single function get_widget, return some gtk widget near the location bar.
  102.  4. nautilus.MenuProvider - Probably the most used interface. It exposes three functions :
  103.     get_file_items, get_background_items and get_toolbar_items . The first two functions determine the entries that appear in the context menu. The difference is that get_background_items is usually called for a folder.
  104.     The last function is used for toolbar items hence you must name the icon parameter of the menuItem.
  105.  5. nautilus.PropertyPageProvider - Exposes get_property_pages function where you reture one or more "pages" or tabs.
  106.  
  107.  '''
  108.  
  109.   def __init__(self):
  110.     print('[__init__ insync plugin]', self)
  111.  
  112.  
  113.   def get_background_items(self, window, folder):
  114.     '''
  115.    This method needs to be defined to avoid this warning:
  116.    ** (nautilus:2913): CRITICAL **: nautilus_menu_provider_get_background_items: assertion
  117.    `NAUTILUS_IS_MENU_PROVIDER (provider)' failed
  118.    '''
  119.     #print('background items', window, folder)
  120.     return None
  121.  
  122.  
  123.   def get_file_items(self, window, files):
  124.     if DEV_MODE:
  125.       print('get file items', files)
  126.  
  127.     if len(files) != 1:
  128.       # TODO what can we do with mutiple files here
  129.       return None
  130.  
  131.     file = files[0]
  132.     if file.get_uri_scheme() != 'file':
  133.       return None
  134.  
  135.     path = urllib.unquote(file.get_uri()[len('file://'):])
  136.     path = unicode(path, FS_ENCODING)
  137.     if DEV_MODE:
  138.       print path
  139.     is_dir = os.path.isdir(path)
  140.  
  141.     cm_info = ipc_insync(command='CONTEXT-MENU-ITEMS', full_path=path)
  142.  
  143.     if cm_info:
  144.       title, cm_items = cm_info
  145.       tip = 'Insync folder actions' if is_dir else 'Insync file actions'
  146.       item = Nautilus.MenuItem(
  147.         name=title,
  148.         label=title,
  149.         tip=tip,
  150.         icon='insync'
  151.       )
  152.       sub_menu = Nautilus.Menu()
  153.       item.set_submenu(sub_menu)
  154.  
  155.       sep_id = 0
  156.       for text, cmd in cm_items:
  157.         if text == 'separator':
  158.           text = u'\u2015' * 10
  159.           name = 'separator:' + str(sep_id)
  160.           sep_id += 1
  161.         else:
  162.           name = text
  163.         menu_item = Nautilus.MenuItem(name=name, label=text, tip=text)
  164.         if cmd:
  165.           menu_item.connect('activate', self.do_action, file, cmd)
  166.         else:
  167.           menu_item.sensitive = False
  168.         sub_menu.append_item(menu_item)
  169.  
  170.       return [item]
  171.     return None
  172.  
  173.  
  174.   def do_action(self, menu, file, method):
  175.     path = urllib.unquote(
  176.       file.get_uri()[len('file://'):]
  177.     )
  178.     ipc_insync(method=method, full_path=path)
  179.  
  180.  
  181.   def update_file_info_full(self, provider, handle, closure, file):
  182.     if file.get_uri_scheme() != 'file':
  183.       return
  184.  
  185.     file.invalidate_extension_info()
  186.     GObject.timeout_add(1, self.add_emblem, provider, handle, closure, file)
  187.     return Nautilus.OperationResult.IN_PROGRESS
  188.  
  189.  
  190.   def cancel_update(self, provider, handle):
  191.     pass
  192.  
  193.  
  194.   def add_emblem(self, provider, handle, closure, file):
  195.     filename = urllib.unquote(file.get_uri()[len('file://'):])
  196.     filename = os.path.realpath(filename)
  197.     status = ipc_insync(command='GET-FILE-STATUS', full_path=filename)
  198.     if status and status != 'UNKNOWN':
  199.       emblem = _EMBLEM_KEYS[status]
  200.       if os.path.isdir(filename):
  201.         is_shared = ipc_insync(command='IS-FILE-SHARED', full_path=filename)
  202.         if is_shared:
  203.           emblem += '-shared'
  204.       file.add_emblem(emblem)
  205.     Nautilus.info_provider_update_complete_invoke(closure, provider, handle,
  206.                                                   Nautilus.OperationResult.COMPLETE)
  207.     return False
  208.  
  209.  
  210. print(InsyncExtension)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement