/SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py.in
Autoconf | 200 lines | 115 code | 51 blank | 34 comment | 14 complexity | c35dd383ba3d681d86154efb98a77857 MD5 | raw file
1#!/usr/bin/python 2# SparkleShare, an instant update workflow to Git. 3# Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com> 4# 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18import os 19import shutil 20import time 21import urllib 22 23# http://projects.gnome.org/nautilus-python/documentation/html/ 24from gi.repository import Nautilus, GObject, Gtk, Gdk 25 26SPARKLESHARE_PATH = os.path.join (os.path.expanduser ('~'), "SparkleShare") 27 28import gettext 29gettext.bindtextdomain('sparkleshare', '@prefix@/share/locale') 30gettext.textdomain('sparkleshare') 31_ = gettext.gettext 32 33class SparkleShareExtension (GObject.GObject, Nautilus.MenuProvider): 34 35 36 def __init__ (self): 37 pass 38 39 def checkout_version (self, menu, file_path, commit_hash, username, timestamp): 40 41 file_name = os.path.basename (file_path) 42 tmp_file_path = os.path.join (SPARKLESHARE_PATH, ".tmp", file_name) 43 44 # Move the current version to a temporary path 45 shutil.move (file_path, tmp_file_path) 46 47 # Check out the earlier version 48 os.chdir (os.path.dirname (file_path)) 49 os.popen ("git checkout " + commit_hash + " '" + file_name + "'") 50 51 new_tmp_file_name = file_name + " (" + username + ", " 52 new_tmp_file_name += time.strftime ("%H:%M %d %b %Y", timestamp).replace (" 0", " ") + ") " 53 54 # Rename the checked out file 55 shutil.move (file_name, new_tmp_file_name) 56 57 # Move the original file back 58 shutil.move (tmp_file_path, file_path) 59 60 return True 61 62 def format_web_link (self, path): 63 # Get the remote url used for the repo 64 self.chdir_to_repo_base(path) 65 url_command = os.popen ("git config --get remote.origin.url") 66 origin_url = url_command.readline ().strip () 67 if not origin_url: 68 return 69 70 # Get components 71 # TODO use regex here or something not so ugly 72 protocol, remaining = origin_url.split ("://", 1) 73 host, origin_path = remaining.split("@")[1].split("/", 1); 74 # Format the right web url depending on the service 75 repo_base = self.get_repo_base_path(path) 76 relative_path = path.split(repo_base, 1)[1].lstrip("/") 77 78 #url = url.rstrip (".git") 79 if "gitorious.org" in host: 80 # ssh://git@gitorious.org/gnome-design/gnome-design.git 81 # http://gitorious.org/gnome-design/gnome-design/blobs/raw/master/COPYING 82 url = "http://" + host + "/" + urllib.quote(origin_path.rstrip(".git")) + "/blobs/master/" + urllib.quote(relative_path) 83 elif "github.com" in host: 84 # ssh://git@github.com/hbons/SparkleShare.git 85 # https://raw.github.com/hbons/SparkleShare/master/README 86 url = "http://raw.github.com/" + urllib.quote(origin_path.rstrip(".git")) + "/raw/master/" + urllib.quote(relative_path) 87 else: 88 # https://git.one-gear.com/?p=thansen/Public.git;a=blob;f=SparkleShare.txt;hb=HEAD 89 url = "http://" + host + "/?p=" + urllib.quote(origin_path) +";a=blob;f=" + urllib.quote(relative_path) + ";hb=HEAD" 90 91 return url 92 93 def copy_web_link (self, menu, path): 94 url = self.format_web_link(path) 95 clipboard = Gtk.Clipboard.get (Gdk.Atom.intern ("CLIPBOARD", False)) 96 clipboard.set_text (url, -1) 97 clipboard.store () 98 99 return 100 101 def chdir_to_repo_base(self, file_path): 102 base_path = self.get_repo_base_path(file_path) 103 os.chdir(base_path) 104 105 def get_repo_base_path(self, path): 106 path = os.path.abspath(path) 107 parts = path.split(SPARKLESHARE_PATH, 1)[1].split("/") 108 if len(parts) > 1: 109 sub_folder = parts[1] 110 else: 111 sub_folder = parts[0] 112 return SPARKLESHARE_PATH + "/" + sub_folder 113 114 def get_file_items (self, window, files): 115 116 # Only work if one file is selected 117 if len (files) != 1: 118 return 119 120 file_reference = files [0] 121 122 # Only work if we're in a SparkleShare repository folder 123 if file_reference.is_directory (): 124 return 125 if not (file_reference.get_parent_uri ().startswith ('file://' + SPARKLESHARE_PATH)): 126 return 127 if file_reference.get_parent_uri () == 'file://' + SPARKLESHARE_PATH: 128 return 129 130 file_path = urllib.unquote ('/' + file_reference.get_uri ().lstrip('file:/')) 131 url = self.format_web_link (file_path) 132 parent_path = os.path.dirname (os.path.abspath (file_path)) 133 134 top_menuitem = Nautilus.MenuItem (name="Nautilus::SparkleShare", 135 label="SparkleShare") 136 137 top_submenu = Nautilus.Menu () 138 top_menuitem.set_submenu (top_submenu) 139 140 web_link_menu_item_copy = Nautilus.MenuItem (name="Nautilus::CopyWebLink", 141 label=_("Copy Web Link"), 142 tip=_("Copy the web address of this file to the clipboard")) 143 144 web_link_menu_item_copy.connect ("activate", self.copy_web_link, file_path) 145 146 147 epochs = ["", "", "", "", "", "", "", "", "", ""] 148 commit_hashes = ["", "", "", "", "", "", "", "", "", ""] 149 150 151 time_command = os.popen ("git log -10 --format='%at' '" + file_path + "'") 152 153 author_command = os.popen ("git log -10 --format='%an' '" + file_path + "'") 154 155 hash_command = os.popen ("git log -10 --format='%H' '" + file_path + "'") 156 157 i = 0 158 for line in time_command.readlines (): 159 epochs [i] = line.strip ("\n") 160 i += 1 161 162 163 # Only work if there is history 164 if i < 2: 165 top_submenu.append_item (web_link_menu_item_copy) 166 return [top_menuitem] 167 168 i = 0 169 for line in hash_command.readlines (): 170 commit_hashes [i] = line.strip ("\n") 171 i += 1 172 173 earlier_version_menu_item = Nautilus.MenuItem (name="Nautilus::OpenOlderVersion", 174 label=_("Get Earlier Version"), 175 tip=_("Make a copy of an earlier version in this folder")) 176 version_submenu = Nautilus.Menu () 177 178 i = 0 179 for line in author_command.readlines (): 180 181 if i > 0: 182 183 timestamp = time.strftime ("%d %b\t%H:%M", time.localtime (float (epochs [i]))) 184 username = line.strip ("\n") 185 186 menu_item = Nautilus.MenuItem (name="Nautilus::Version" + epochs [i], 187 label=timestamp + "\t" + username, 188 tip=_("Select to get a copy of this version")) 189 190 menu_item.connect ("activate", self.checkout_version, file_path, commit_hashes [i], 191 username, time.localtime (float (epochs [i]))) 192 version_submenu.append_item (menu_item) 193 194 i += 1 195 196 earlier_version_menu_item.set_submenu (version_submenu) 197 top_submenu.append_item (earlier_version_menu_item) 198 top_submenu.append_item (web_link_menu_item_copy) 199 200 return [top_menuitem]