2
# SparkleShare, an instant update workflow to Git.
3
# Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
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.
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.
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/>.
23
# http://projects.gnome.org/nautilus-python/documentation/html/
24
from gi.repository import Nautilus, GObject, Gtk, Gdk
26
SPARKLESHARE_PATH = os.path.join (os.path.expanduser ('~'), "SparkleShare")
29
gettext.bindtextdomain('sparkleshare', '@prefix@/share/locale')
30
gettext.textdomain('sparkleshare')
33
class SparkleShareExtension (GObject.GObject, Nautilus.MenuProvider):
39
def checkout_version (self, menu, file_path, commit_hash, username, timestamp):
41
file_name = os.path.basename (file_path)
42
tmp_file_path = os.path.join (SPARKLESHARE_PATH, ".tmp", file_name)
44
# Move the current version to a temporary path
45
shutil.move (file_path, tmp_file_path)
47
# Check out the earlier version
48
os.chdir (os.path.dirname (file_path))
49
os.popen ("git checkout " + commit_hash + " '" + file_name + "'")
51
new_tmp_file_name = file_name + " (" + username + ", "
52
new_tmp_file_name += time.strftime ("%H:%M %d %b %Y", timestamp).replace (" 0", " ") + ") "
54
# Rename the checked out file
55
shutil.move (file_name, new_tmp_file_name)
57
# Move the original file back
58
shutil.move (tmp_file_path, file_path)
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 ()
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("/")
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)
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"
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)
101
def chdir_to_repo_base(self, file_path):
102
base_path = self.get_repo_base_path(file_path)
105
def get_repo_base_path(self, path):
106
path = os.path.abspath(path)
107
parts = path.split(SPARKLESHARE_PATH, 1)[1].split("/")
109
sub_folder = parts[1]
111
sub_folder = parts[0]
112
return SPARKLESHARE_PATH + "/" + sub_folder
114
def get_file_items (self, window, files):
116
# Only work if one file is selected
120
file_reference = files [0]
122
# Only work if we're in a SparkleShare repository folder
123
if file_reference.is_directory ():
125
if not (file_reference.get_parent_uri ().startswith ('file://' + SPARKLESHARE_PATH)):
127
if file_reference.get_parent_uri () == 'file://' + SPARKLESHARE_PATH:
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))
134
top_menuitem = Nautilus.MenuItem (name="Nautilus::SparkleShare",
135
label="SparkleShare")
137
top_submenu = Nautilus.Menu ()
138
top_menuitem.set_submenu (top_submenu)
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"))
144
web_link_menu_item_copy.connect ("activate", self.copy_web_link, file_path)
147
epochs = ["", "", "", "", "", "", "", "", "", ""]
148
commit_hashes = ["", "", "", "", "", "", "", "", "", ""]
151
time_command = os.popen ("git log -10 --format='%at' '" + file_path + "'")
153
author_command = os.popen ("git log -10 --format='%an' '" + file_path + "'")
155
hash_command = os.popen ("git log -10 --format='%H' '" + file_path + "'")
158
for line in time_command.readlines ():
159
epochs [i] = line.strip ("\n")
163
# Only work if there is history
165
top_submenu.append_item (web_link_menu_item_copy)
166
return [top_menuitem]
169
for line in hash_command.readlines ():
170
commit_hashes [i] = line.strip ("\n")
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 ()
179
for line in author_command.readlines ():
183
timestamp = time.strftime ("%d %b\t%H:%M", time.localtime (float (epochs [i])))
184
username = line.strip ("\n")
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"))
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)
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)
200
return [top_menuitem]