PageRenderTime 28ms CodeModel.GetById 17ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py.in

http://github.com/hbons/SparkleShare
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]