diff --git a/SparkleShare/Linux/Makefile.am b/SparkleShare/Linux/Makefile.am new file mode 100644 index 00000000..fe91c418 --- /dev/null +++ b/SparkleShare/Linux/Makefile.am @@ -0,0 +1,30 @@ +SUBDIRS = Nautilus + +ASSEMBLY = SparkleShare +TARGET = exe + +LINK = $(REF_SPARKLESHARE) $(NOTIFY_SHARP_LIBS) $(WEBKIT_SHARP_LIBS) + +if HAVE_APP_INDICATOR +BUILD_DEFINES="-define:HAVE_APP_INDICATOR" +endif + +SOURCES = \ + SparkleAbout.cs \ + SparkleBubbles.cs \ + SparkleController.cs \ + SparkleEventLog.cs \ + SparkleSetup.cs \ + SparkleSetupWindow.cs \ + SparkleSpinner.cs \ + SparkleStatusIcon.cs \ + SparkleUI.cs \ + SparkleUIHelpers.cs + +include $(top_srcdir)/build/build.mk + +bin_SCRIPTS = sparkleshare + +Applicationsdir = $(datadir)/applications +dist_Applications_DATA = sparkleshare.desktop \ + sparkleshare-invite-opener.desktop diff --git a/SparkleShare/Nautilus/Makefile.am b/SparkleShare/Linux/Nautilus/Makefile.am similarity index 100% rename from SparkleShare/Nautilus/Makefile.am rename to SparkleShare/Linux/Nautilus/Makefile.am diff --git a/SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py new file mode 100644 index 00000000..ec474f49 --- /dev/null +++ b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# SparkleShare, an instant update workflow to Git. +# Copyright (C) 2010 Hylke Bons +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import shutil +import time + +import gio +import nautilus + +import pygtk +pygtk.require('2.0') +import gtk + +SPARKLESHARE_PATH = os.path.join (os.path.expanduser ('~'), "SparkleShare") + +import gettext +gettext.bindtextdomain('sparkleshare', '/usr/share/locale') +gettext.textdomain('sparkleshare') +_ = gettext.gettext + +class SparkleShareExtension (nautilus.MenuProvider): + + + def __init__ (self): + + debug = "Loaded Nautilus SparkleShare Extension." + + + def checkout_version (self, menu, file_reference, commit_hash, username, timestamp): + + file_name = file_reference.get_basename ().replace (" ", "\ ").replace ("(", "\(").replace (")", "\)") + file_path = file_reference.get_path ().replace (" ", "\ ").replace ("(", "\(").replace (")", "\)") + tmp_file_path = os.path.join (SPARKLESHARE_PATH, ".tmp", file_reference.get_basename ()) + + # Move the current version to a temporary path + shutil.move (file_reference.get_path (), tmp_file_path) + + # Check out the earlier version + os.chdir (file_reference.get_parent ().get_path ()) + os.popen ("git checkout " + commit_hash + " " + file_name + .replace (" ", "\ ").replace ("(", "\(").replace (")", "\)")) + + new_tmp_file_name = file_name + " (" + username + ", " + new_tmp_file_name += time.strftime ("%H:%M %d %b %Y", timestamp).replace (" 0", " ") + ") " + + # Rename the checked out file + shutil.move (file_name, new_tmp_file_name) + + # Move the original file back + shutil.move (tmp_file_path, file_path) + + return True + + + def copy_web_link (self, menu, file_reference): + + path = file_reference.get_path () + + # Get the remote url used for the repo + url_command = os.popen ("git config --get remote.origin.url") + url = url_command.readline ().strip () + + # Strip the unneeded parts + url = url.lstrip ("ssh://git") + url = url.lstrip ("@") + url = url.rstrip (".git") + + # Format the right web url depending on the service + relative_path = path.lstrip (SPARKLESHARE_PATH) + repo_name = relative_path [:relative_path.find ("/")] + relative_path = relative_path.lstrip (repo_name) + + if "gitorious.org" in url: + url = "http://" + url + "/blobs/master" + relative_path + if "github.com" in url: + url = "http://" + url + "/raw/master" + relative_path + + url = url.replace (" ", "%20"); + + clipboard = gtk.clipboard_get () + clipboard.set_text (url) + clipboard.store () + + return + + + def get_file_items (self, window, files): + + # Only work if one file is selected + if len (files) != 1: + return + + file_reference = gio.File (files [0].get_uri ()) + + # Only work if we're in a SparkleShare repository folder + if not (file_reference.get_path ().startswith (SPARKLESHARE_PATH)): + return + + web_link_menu_item = nautilus.MenuItem ("Nautilus::CopyWebLink", _("Copy Web Link"), + _("Copy the web address of this file to the clipboard")) + + web_link_menu_item.connect ("activate", self.copy_web_link, file_reference) + + + epochs = ["", "", "", "", "", "", "", "", "", ""] + commit_hashes = ["", "", "", "", "", "", "", "", "", ""] + + os.chdir (file_reference.get_parent ().get_path ()) + + time_command = os.popen ("git log -10 --format='%at' " + file_reference.get_basename () + .replace (" ", "\ ").replace ("(", "\(").replace (")", "\)")) + + author_command = os.popen ("git log -10 --format='%an' " + file_reference.get_basename () + .replace (" ", "\ ").replace ("(", "\(").replace (")", "\)")) + + hash_command = os.popen ("git log -10 --format='%H' " + file_reference.get_basename () + .replace (" ", "\ ").replace ("(", "\(").replace (")", "\)")) + + i = 0 + for line in time_command.readlines (): + epochs [i] = line.strip ("\n") + i += 1 + + # Only work if there is history + if i < 2: + return web_link_menu_item, + + i = 0 + for line in hash_command.readlines (): + commit_hashes [i] = line.strip ("\n") + i += 1 + + earlier_version_menu_item = nautilus.MenuItem ("Nautilus::OpenOlderVersion", _("Get Earlier Version"), + _("Make a copy of an earlier version in this folder")) + submenu = nautilus.Menu () + + i = 0 + for line in author_command.readlines (): + + if i > 0: + + timestamp = time.strftime ("%d %b\t%H:%M", time.localtime (float (epochs [i]))) + username = line.strip ("\n") + + menu_item = nautilus.MenuItem ("Nautilus::Version" + epochs [i], + timestamp + "\t" + username, + _("Select to get a copy of this version")) + + menu_item.connect ("activate", self.checkout_version, file_reference, commit_hashes [i], + username, time.localtime (float (epochs [i]))) + submenu.append_item (menu_item) + + i += 1 + + earlier_version_menu_item.set_submenu (submenu) + + + return earlier_version_menu_item, web_link_menu_item diff --git a/SparkleShare/Nautilus/sparkleshare-nautilus-extension.py.in b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py.in similarity index 100% rename from SparkleShare/Nautilus/sparkleshare-nautilus-extension.py.in rename to SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py.in diff --git a/SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py new file mode 100644 index 00000000..9f21c8eb --- /dev/null +++ b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py @@ -0,0 +1,200 @@ +#!/usr/bin/python +# SparkleShare, an instant update workflow to Git. +# Copyright (C) 2010 Hylke Bons +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import shutil +import time +import urllib + +# http://projects.gnome.org/nautilus-python/documentation/html/ +from gi.repository import Nautilus, GObject, Gtk, Gdk + +SPARKLESHARE_PATH = os.path.join (os.path.expanduser ('~'), "SparkleShare") + +import gettext +gettext.bindtextdomain('sparkleshare', '/usr/share/locale') +gettext.textdomain('sparkleshare') +_ = gettext.gettext + +class SparkleShareExtension (GObject.GObject, Nautilus.MenuProvider): + + + def __init__ (self): + pass + + def checkout_version (self, menu, file_path, commit_hash, username, timestamp): + + file_name = os.path.basename (file_path) + tmp_file_path = os.path.join (SPARKLESHARE_PATH, ".tmp", file_name) + + # Move the current version to a temporary path + shutil.move (file_path, tmp_file_path) + + # Check out the earlier version + os.chdir (os.path.dirname (file_path)) + os.popen ("git checkout " + commit_hash + " '" + file_name + "'") + + new_tmp_file_name = file_name + " (" + username + ", " + new_tmp_file_name += time.strftime ("%H:%M %d %b %Y", timestamp).replace (" 0", " ") + ") " + + # Rename the checked out file + shutil.move (file_name, new_tmp_file_name) + + # Move the original file back + shutil.move (tmp_file_path, file_path) + + return True + + def format_web_link (self, path): + # Get the remote url used for the repo + self.chdir_to_repo_base(path) + url_command = os.popen ("git config --get remote.origin.url") + origin_url = url_command.readline ().strip () + if not origin_url: + return + + # Get components + # TODO use regex here or something not so ugly + protocol, remaining = origin_url.split ("://", 1) + host, origin_path = remaining.split("@")[1].split("/", 1); + # Format the right web url depending on the service + repo_base = self.get_repo_base_path(path) + relative_path = path.split(repo_base, 1)[1].lstrip("/") + + #url = url.rstrip (".git") + if "gitorious.org" in host: + # ssh://git@gitorious.org/gnome-design/gnome-design.git + # http://gitorious.org/gnome-design/gnome-design/blobs/raw/master/COPYING + url = "http://" + host + "/" + urllib.quote(origin_path.rstrip(".git")) + "/blobs/master/" + urllib.quote(relative_path) + elif "github.com" in host: + # ssh://git@github.com/hbons/SparkleShare.git + # https://raw.github.com/hbons/SparkleShare/master/README + url = "http://raw.github.com/" + urllib.quote(origin_path.rstrip(".git")) + "/raw/master/" + urllib.quote(relative_path) + else: + # https://git.one-gear.com/?p=thansen/Public.git;a=blob;f=SparkleShare.txt;hb=HEAD + url = "http://" + host + "/?p=" + urllib.quote(origin_path) +";a=blob;f=" + urllib.quote(relative_path) + ";hb=HEAD" + + return url + + def copy_web_link (self, menu, path): + url = self.format_web_link(path) + clipboard = Gtk.Clipboard.get (Gdk.Atom.intern ("CLIPBOARD", False)) + clipboard.set_text (url, -1) + clipboard.store () + + return + + def chdir_to_repo_base(self, file_path): + base_path = self.get_repo_base_path(file_path) + os.chdir(base_path) + + def get_repo_base_path(self, path): + path = os.path.abspath(path) + parts = path.split(SPARKLESHARE_PATH, 1)[1].split("/") + if len(parts) > 1: + sub_folder = parts[1] + else: + sub_folder = parts[0] + return SPARKLESHARE_PATH + "/" + sub_folder + + def get_file_items (self, window, files): + + # Only work if one file is selected + if len (files) != 1: + return + + file_reference = files [0] + + # Only work if we're in a SparkleShare repository folder + if file_reference.is_directory (): + return + if not (file_reference.get_parent_uri ().startswith ('file://' + SPARKLESHARE_PATH)): + return + if file_reference.get_parent_uri () == 'file://' + SPARKLESHARE_PATH: + return + + file_path = urllib.unquote ('/' + file_reference.get_uri ().lstrip('file:/')) + url = self.format_web_link (file_path) + parent_path = os.path.dirname (os.path.abspath (file_path)) + + top_menuitem = Nautilus.MenuItem (name="Nautilus::SparkleShare", + label="SparkleShare") + + top_submenu = Nautilus.Menu () + top_menuitem.set_submenu (top_submenu) + + web_link_menu_item_copy = Nautilus.MenuItem (name="Nautilus::CopyWebLink", + label=_("Copy Web Link"), + tip=_("Copy the web address of this file to the clipboard")) + + web_link_menu_item_copy.connect ("activate", self.copy_web_link, file_path) + + + epochs = ["", "", "", "", "", "", "", "", "", ""] + commit_hashes = ["", "", "", "", "", "", "", "", "", ""] + + + time_command = os.popen ("git log -10 --format='%at' '" + file_path + "'") + + author_command = os.popen ("git log -10 --format='%an' '" + file_path + "'") + + hash_command = os.popen ("git log -10 --format='%H' '" + file_path + "'") + + i = 0 + for line in time_command.readlines (): + epochs [i] = line.strip ("\n") + i += 1 + + + # Only work if there is history + if i < 2: + top_submenu.append_item (web_link_menu_item_copy) + return [top_menuitem] + + i = 0 + for line in hash_command.readlines (): + commit_hashes [i] = line.strip ("\n") + i += 1 + + earlier_version_menu_item = Nautilus.MenuItem (name="Nautilus::OpenOlderVersion", + label=_("Get Earlier Version"), + tip=_("Make a copy of an earlier version in this folder")) + version_submenu = Nautilus.Menu () + + i = 0 + for line in author_command.readlines (): + + if i > 0: + + timestamp = time.strftime ("%d %b\t%H:%M", time.localtime (float (epochs [i]))) + username = line.strip ("\n") + + menu_item = Nautilus.MenuItem (name="Nautilus::Version" + epochs [i], + label=timestamp + "\t" + username, + tip=_("Select to get a copy of this version")) + + menu_item.connect ("activate", self.checkout_version, file_path, commit_hashes [i], + username, time.localtime (float (epochs [i]))) + version_submenu.append_item (menu_item) + + i += 1 + + earlier_version_menu_item.set_submenu (version_submenu) + top_submenu.append_item (earlier_version_menu_item) + top_submenu.append_item (web_link_menu_item_copy) + + return [top_menuitem] diff --git a/SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py.in b/SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py.in similarity index 100% rename from SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py.in rename to SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py.in diff --git a/SparkleShare/SparkleAbout.cs b/SparkleShare/Linux/SparkleAbout.cs similarity index 100% rename from SparkleShare/SparkleAbout.cs rename to SparkleShare/Linux/SparkleAbout.cs diff --git a/SparkleShare/SparkleBubbles.cs b/SparkleShare/Linux/SparkleBubbles.cs similarity index 100% rename from SparkleShare/SparkleBubbles.cs rename to SparkleShare/Linux/SparkleBubbles.cs diff --git a/SparkleShare/SparkleController.cs b/SparkleShare/Linux/SparkleController.cs similarity index 100% rename from SparkleShare/SparkleController.cs rename to SparkleShare/Linux/SparkleController.cs diff --git a/SparkleShare/SparkleEventLog.cs b/SparkleShare/Linux/SparkleEventLog.cs similarity index 100% rename from SparkleShare/SparkleEventLog.cs rename to SparkleShare/Linux/SparkleEventLog.cs diff --git a/SparkleShare/SparkleSetup.cs b/SparkleShare/Linux/SparkleSetup.cs similarity index 100% rename from SparkleShare/SparkleSetup.cs rename to SparkleShare/Linux/SparkleSetup.cs diff --git a/SparkleShare/SparkleSetupWindow.cs b/SparkleShare/Linux/SparkleSetupWindow.cs similarity index 100% rename from SparkleShare/SparkleSetupWindow.cs rename to SparkleShare/Linux/SparkleSetupWindow.cs diff --git a/SparkleShare/SparkleShare.csproj b/SparkleShare/Linux/SparkleShare.csproj similarity index 100% rename from SparkleShare/SparkleShare.csproj rename to SparkleShare/Linux/SparkleShare.csproj diff --git a/SparkleShare/SparkleShare.sln b/SparkleShare/Linux/SparkleShare.sln similarity index 100% rename from SparkleShare/SparkleShare.sln rename to SparkleShare/Linux/SparkleShare.sln diff --git a/SparkleShare/SparkleSpinner.cs b/SparkleShare/Linux/SparkleSpinner.cs similarity index 100% rename from SparkleShare/SparkleSpinner.cs rename to SparkleShare/Linux/SparkleSpinner.cs diff --git a/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Linux/SparkleStatusIcon.cs similarity index 100% rename from SparkleShare/SparkleStatusIcon.cs rename to SparkleShare/Linux/SparkleStatusIcon.cs diff --git a/SparkleShare/SparkleUI.cs b/SparkleShare/Linux/SparkleUI.cs similarity index 100% rename from SparkleShare/SparkleUI.cs rename to SparkleShare/Linux/SparkleUI.cs diff --git a/SparkleShare/SparkleUIHelpers.cs b/SparkleShare/Linux/SparkleUIHelpers.cs similarity index 100% rename from SparkleShare/SparkleUIHelpers.cs rename to SparkleShare/Linux/SparkleUIHelpers.cs diff --git a/SparkleShare/Linux/sparkleshare b/SparkleShare/Linux/sparkleshare new file mode 100644 index 00000000..c1d78082 --- /dev/null +++ b/SparkleShare/Linux/sparkleshare @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +if [[ $UID -eq 0 ]]; then + echo "Cannot run as root. Things would go utterly wrong." + exit 1 +fi + +if [ "$XDG_RUNTIME_DIR" ]; then + pidfile=${XDG_RUNTIME_DIR}/sparkleshare.pid +else + pidfile=/tmp/sparkleshare-${USER}.pid +fi + +start() { + if [ -e "${pidfile}" ]; then + sparklepid=`cat ${pidfile}` + if [ -n "`ps -p ${sparklepid} | grep ${sparklepid}`" ]; then + echo "SparkleShare is already running." + exit 0 + else + echo "SparkleShare stale pid file found, starting a new instance." + rm -f $pidfile + fi + fi + + echo -n "Starting SparkleShare... " + if [ -n "${SSH_AGENT_PID}" -o -n "${SSH_AUTH_SOCK}" ] ; then + mono "/usr/lib/sparkleshare/SparkleShare.exe" $2 & + else + ssh-agent mono "/usr/lib/sparkleshare/SparkleShare.exe" $2 & + fi + ( umask 066; echo $! > ${pidfile} ) + echo "Done." +} + +stop() { + if [ -e "${pidfile}" ]; then + sparklepid=`cat ${pidfile}` + if [ -n "`ps -p ${sparklepid} | grep ${sparklepid}`" ]; then + echo -n "Stopping SparkleShare... " + kill ${sparklepid} + rm -f ${pidfile} + echo "Done." + else + echo "SparkleShare is not running, removing stale pid file..." + rm -f ${pidfile} + fi + else + echo "SparkleShare is not running." + fi +} + +case $1 in + start|--start) + start + ;; + stop|--stop) + stop + ;; + restart|--restart) + stop + start + ;; + open|--open) + invite=`date -u +%N` + curl -o ~/SparkleShare/$invite.xml `echo $2 | sed s/sparkleshare:/https:/` + ;; + help|--help|-h) + mono "/usr/lib/sparkleshare/SparkleShare.exe" --help + ;; + version|--version|-v) + mono "/usr/lib/sparkleshare/SparkleShare.exe" --version + ;; + *) + echo "Usage: sparkleshare {start|stop|restart|help|version}" + ;; +esac diff --git a/SparkleShare/sparkleshare-invite-opener.desktop b/SparkleShare/Linux/sparkleshare-invite-opener.desktop similarity index 100% rename from SparkleShare/sparkleshare-invite-opener.desktop rename to SparkleShare/Linux/sparkleshare-invite-opener.desktop diff --git a/SparkleShare/sparkleshare.desktop b/SparkleShare/Linux/sparkleshare.desktop similarity index 100% rename from SparkleShare/sparkleshare.desktop rename to SparkleShare/Linux/sparkleshare.desktop diff --git a/SparkleShare/sparkleshare.in b/SparkleShare/Linux/sparkleshare.in similarity index 100% rename from SparkleShare/sparkleshare.in rename to SparkleShare/Linux/sparkleshare.in diff --git a/SparkleShare/Mac/Makefile.am b/SparkleShare/Mac/Makefile.am deleted file mode 100755 index 5091b192..00000000 --- a/SparkleShare/Mac/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -EXTRA_DIST = \ - config \ - AppDelegate.cs \ - Growl.framework \ - Growl.plist \ - Info.plist \ - MainMenu.xib \ - MainMenu.xib.designer.cs \ - SparkleAbout.cs \ - SparkleBadger.cs \ - SparkleBubbles.cs \ - SparkleController.cs \ - SparkleEventLog.cs \ - SparkleMacWatcher.cs \ - SparkleSetup.cs \ - SparkleSetupWindow.cs \ - SparkleShare.csproj \ - SparkleShare.sln \ - SparkleStatusIcon.cs \ - SparkleUI.cs diff --git a/SparkleShare/Makefile.am b/SparkleShare/Makefile.am index fdfd339c..2eb7e269 100755 --- a/SparkleShare/Makefile.am +++ b/SparkleShare/Makefile.am @@ -1,6 +1,4 @@ -SUBDIRS = \ - Nautilus \ - Mac +SUBDIRS = Linux ASSEMBLY = SparkleShare TARGET = exe @@ -13,34 +11,18 @@ endif SOURCES = \ Program.cs \ - SparkleAbout.cs \ SparkleAboutController.cs \ - SparkleBubbles.cs \ SparkleBubblesController.cs \ - SparkleController.cs \ SparkleControllerBase.cs \ - SparkleEventLog.cs \ SparkleEventLogController.cs \ SparkleExtensions.cs \ SparkleInvite.cs \ SparkleOptions.cs \ SparklePlugin.cs \ - SparkleSetup.cs \ SparkleSetupController.cs \ - SparkleSetupWindow.cs \ - SparkleSpinner.cs \ - SparkleStatusIcon.cs \ - SparkleStatusIconController.cs \ - SparkleUI.cs \ - SparkleUIHelpers.cs + SparkleStatusIconController.cs include $(top_srcdir)/build/build.mk - -bin_SCRIPTS = sparkleshare - -Applicationsdir = $(datadir)/applications -dist_Applications_DATA = sparkleshare.desktop \ - sparkleshare-invite-opener.desktop install-data-hook: update-desktop-database diff --git a/configure.ac b/configure.ac index 538babad..7e7d0dab 100755 --- a/configure.ac +++ b/configure.ac @@ -158,12 +158,12 @@ SparkleLib/AssemblyInfo.cs SparkleLib/Defines.cs SparkleLib/Makefile SparkleLib/Git/Makefile -SparkleShare/sparkleshare +SparkleShare/Linux/Makefile +SparkleShare/Linux/sparkleshare +SparkleShare/Linux/Nautilus/Makefile +SparkleShare/Linux/Nautilus/sparkleshare-nautilus-extension.py +SparkleShare/Linux/Nautilus/sparkleshare-nautilus3-extension.py SparkleShare/Makefile -SparkleShare/Mac/Makefile -SparkleShare/Nautilus/Makefile -SparkleShare/Nautilus/sparkleshare-nautilus-extension.py -SparkleShare/Nautilus/sparkleshare-nautilus3-extension.py po/Makefile.in Makefile ])