~cmn/sparkleshare/trunk

« back to all changes in this revision

Viewing changes to SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py.in

  • Committer: Carlos Martín Nieto
  • Date: 2011-11-29 22:13:39 UTC
  • Revision ID: git-v1:319e847e7e9ef34e936d6fd44931e86032cf8a8f
pseudo-initial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
18
import os
 
19
import shutil
 
20
import time
 
21
import urllib
 
22
 
 
23
# http://projects.gnome.org/nautilus-python/documentation/html/
 
24
from gi.repository import Nautilus, GObject, Gtk, Gdk
 
25
 
 
26
SPARKLESHARE_PATH = os.path.join (os.path.expanduser ('~'), "SparkleShare")
 
27
 
 
28
import gettext
 
29
gettext.bindtextdomain('sparkleshare', '@prefix@/share/locale')
 
30
gettext.textdomain('sparkleshare')
 
31
_ = gettext.gettext
 
32
 
 
33
class 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]