add another platform switch

This commit is contained in:
Hylke Bons 2010-05-21 09:49:41 +01:00
parent b01513e9e4
commit 7210d3c602
4 changed files with 466 additions and 38 deletions

View file

@ -102,15 +102,7 @@ namespace SparkleShare {
public void CloneRepo (object o, EventArgs args) {
Remove (Child);
VBox Box = new VBox (false, 24);
SparkleSpinner Spinner = new SparkleSpinner ();
Label Label = new Label (_("Downloading files,\n") +
_("this may take a while..."));
Box.PackStart (Spinner, false, false, 0);
Box.PackStart (Label, false, false, 0);
BorderWidth = 30;
Add (Box);
Destroy ();
string RepoRemoteUrl = RemoteUrlCombo.Entry.Text;
string RepoName =
@ -121,8 +113,7 @@ namespace SparkleShare {
Process.StartInfo.RedirectStandardOutput = true;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.FileName = "git";
Process.StartInfo.WorkingDirectory =
SparklePaths.SparkleTmpPath;
Process.StartInfo.WorkingDirectory = SparklePaths.SparkleTmpPath;
Process.StartInfo.Arguments = "clone ";
Process.StartInfo.Arguments +=
@ -130,6 +121,10 @@ namespace SparkleShare {
Process.Start ();
SparkleBubble SparkleBubble =
new SparkleBubble ("Downloading " + RepoName + "",
"You will be notified when this is done");
// Move the folder to the SparkleShare folder when done cloning
Process.Exited += delegate {
Directory.Move (
@ -138,8 +133,21 @@ namespace SparkleShare {
SparkleHelpers.CombineMore (SparklePaths.SparklePath,
RepoName)
);
SparkleBubble =
new SparkleBubble ("Successfully added the folder" +
" " + RepoName + "",
"Now make great stuff happen!");
SparkleBubble.AddAction ("", "Open Folder",
delegate {
Process.StartInfo.FileName = "xdg-open";
Process.StartInfo.Arguments =
SparkleHelpers.CombineMore (
SparklePaths.SparklePath, RepoName);
Process.Start();
} );
Destroy ();
};
}

411
SparkleShare/SparkleRepo.cs Normal file
View file

@ -0,0 +1,411 @@
// SparkleShare, an instant update workflow to Git.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// 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 <http://www.gnu.org/licenses/>.
using Gtk;
using SparkleShare;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Timers;
namespace SparkleShare {
// SparkleRepo class holds repository information and timers
public class SparkleRepo {
private Process Process;
private Timer FetchTimer;
private Timer BufferTimer;
private FileSystemWatcher Watcher;
public string Name;
public string Domain;
public string LocalPath;
public string RemoteOriginUrl;
public string CurrentHash;
public string UserEmail;
public string UserName;
public SparkleRepo (string RepoPath) {
Process = new Process();
Process.EnableRaisingEvents = false;
Process.StartInfo.RedirectStandardOutput = true;
Process.StartInfo.UseShellExecute = false;
// Get the repository's path, example: "/home/user/SparkleShare/repo"
LocalPath = RepoPath;
Process.StartInfo.WorkingDirectory = LocalPath;
// Get user.name, example: "User Name"
UserName = "Anonymous";
Process.StartInfo.FileName = "git";
Process.StartInfo.Arguments = "config --get user.name";
Process.Start();
UserName = Process.StandardOutput.ReadToEnd().Trim ();
// Get user.email, example: "user@github.com"
UserEmail = "not.set@git-scm.com";
Process.StartInfo.FileName = "git";
Process.StartInfo.Arguments = "config --get user.email";
Process.Start();
UserEmail = Process.StandardOutput.ReadToEnd().Trim ();
// Get remote.origin.url, example: "ssh://git@github.com/user/repo"
Process.StartInfo.FileName = "git";
Process.StartInfo.Arguments = "config --get remote.origin.url";
Process.Start();
RemoteOriginUrl = Process.StandardOutput.ReadToEnd().Trim ();
// Get the repository name, example: "Project"
Name = Path.GetFileName (LocalPath);
// Get the domain, example: "github.com"
Domain = RemoteOriginUrl;
Domain = Domain.Substring (Domain.IndexOf ("@") + 1);
if (Domain.IndexOf (":") > -1)
Domain = Domain.Substring (0, Domain.IndexOf (":"));
else
Domain = Domain.Substring (0, Domain.IndexOf ("/"));
// Get hash of the current commit
Process.StartInfo.FileName = "git";
Process.StartInfo.Arguments = "rev-list --max-count=1 HEAD";
Process.Start();
CurrentHash = Process.StandardOutput.ReadToEnd().Trim ();
// Watch the repository's folder
Watcher = new FileSystemWatcher (LocalPath);
Watcher.IncludeSubdirectories = true;
Watcher.EnableRaisingEvents = true;
Watcher.Filter = "*";
Watcher.Changed += new FileSystemEventHandler(OnFileActivity);
Watcher.Created += new FileSystemEventHandler(OnFileActivity);
Watcher.Deleted += new FileSystemEventHandler(OnFileActivity);
// Fetch remote changes every 20 seconds
FetchTimer = new Timer ();
FetchTimer.Interval = 17500;
FetchTimer.Elapsed += delegate {
Fetch ();
};
FetchTimer.Start();
BufferTimer = new Timer ();
// Add everything that changed
// since SparkleShare was stopped
Add ();
Console.WriteLine ("[Git][" + Name + "] Nothing going on...");
}
// Starts a time buffer when something changes
public void OnFileActivity (object o, FileSystemEventArgs args) {
WatcherChangeTypes wct = args.ChangeType;
if (!ShouldIgnore (args.Name)) {
Console.WriteLine ("[Event][" + Name + "] " + wct.ToString() +
" '" + args.Name + "'");
StartBufferTimer ();
}
}
// A buffer that will fetch changes after
// file activity has settles down
public void StartBufferTimer () {
FetchTimer.Stop ();
int Interval = 4000;
if (!BufferTimer.Enabled) {
// Delay for a few seconds to see if more files change
BufferTimer.Interval = Interval;
BufferTimer.Elapsed += delegate (object o, ElapsedEventArgs args) {
Console.WriteLine ("[Buffer][" + Name + "] Done waiting.");
Add ();
};
Console.WriteLine ("[Buffer][" + Name + "] " +
"Waiting for more changes...");
BufferTimer.Start();
} else {
// Extend the delay when something changes
BufferTimer.Close ();
BufferTimer = new Timer ();
BufferTimer.Interval = Interval;
BufferTimer.Elapsed += delegate (object o, ElapsedEventArgs args) {
Console.WriteLine ("[Buffer][" + Name + "] Done waiting.");
Add ();
};
FetchTimer.Start ();
BufferTimer.Start();
Console.WriteLine ("[Buffer][" + Name + "] " +
"Waiting for more changes...");
}
}
// Clones a remote repo
public void Clone () {
Process.StartInfo.Arguments = "clone " + RemoteOriginUrl;
Process.Start();
// Add a gitignore file
TextWriter Writer = new StreamWriter(LocalPath + ".gitignore");
Writer.WriteLine("*~"); // Ignore gedit swap files
Writer.WriteLine(".*.sw?"); // Ignore vi swap files
Writer.Close();
}
// Stages the made changes
public void Add () {
BufferTimer.Stop ();
Console.WriteLine ("[Git][" + Name + "] Staging changes...");
Process.StartInfo.Arguments = "add --all";
Process.Start();
Process.WaitForExit ();
Console.WriteLine ("[Git][" + Name + "] Changes staged.");
// SparkleUI.NotificationIcon.SetSyncingState ();
string Message = FormatCommitMessage ();
if (!Message.Equals ("")) {
Commit (Message);
Push ();
Fetch ();
// Push again in case of a conflict
Push ();
}
}
// Commits the made changes
public void Commit (string Message) {
Console.WriteLine ("[Commit][" + Name + "] " + Message);
Console.WriteLine ("[Git][" + Name + "] Commiting changes...");
Process.StartInfo.Arguments = "commit -m \"" + Message + "\"";
Process.Start();
Process.WaitForExit ();
Console.WriteLine ("[Git][" + Name + "] Changes commited.");
}
// Fetches changes from the remote repo
public void Fetch () {
FetchTimer.Stop ();
// SparkleUI.NotificationIcon.SetSyncingState ();
Console.WriteLine ("[Git][" + Name + "] Fetching changes... ");
Process.StartInfo.Arguments = "fetch -v";
Process.Start();
string Output = Process.StandardOutput.ReadToEnd().Trim (); // TODO: This doesn't work :(
Process.WaitForExit ();
Console.WriteLine ("[Git][" + Name + "] Changes fetched.");
if (!Output.Contains ("up to date"))
Merge ();
// SparkleUI.NotificationIcon.SetIdleState ();
FetchTimer.Start ();
}
// Merges the fetched changes
public void Merge () {
// Watcher.EnableRaisingEvents = false;
Console.WriteLine ("[Git][" + Name + "] Merging fetched changes... ");
Process.StartInfo.Arguments = "merge origin/master";
Process.Start();
Process.WaitForExit ();
Console.WriteLine ("[Git][" + Name + "] Changes merged.");
string Output = Process.StandardOutput.ReadToEnd().Trim ();
// Show notification if there are updates
if (!Output.Equals ("Already up-to-date.")) {
// Get the last committer e-mail
Process.StartInfo.Arguments = "log --format=\"%ae\" -1";
Process.Start();
string LastCommitEmail = Process.StandardOutput.ReadToEnd().Trim ();
// Get the last commit message
Process.StartInfo.Arguments = "log --format=\"%s\" -1";
Process.Start();
string LastCommitMessage = Process.StandardOutput.ReadToEnd().Trim ();
// Get the last commiter
Process.StartInfo.Arguments = "log --format=\"%an\" -1";
Process.Start();
string LastCommitUserName = Process.StandardOutput.ReadToEnd().Trim ();
string NotifySettingFile =
SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath,
"sparkleshare.notify");
if (File.Exists (NotifySettingFile))
ShowEventBubble (LastCommitUserName + " " + LastCommitMessage,
SparkleHelpers.GetAvatar (LastCommitEmail, 48),
true);
}
// Watcher.EnableRaisingEvents = true;
Console.WriteLine ("[Git][" + Name + "] Nothing going on... ");
}
// Pushes the changes to the remote repo
public void Push () {
Console.WriteLine ("[Git][" + Name + "] Pushing changes...");
Process.StartInfo.Arguments = "push";
Process.Start();
Process.WaitForExit ();
Console.WriteLine ("[Git][" + Name + "] Changes pushed.");
// SparkleUI.NotificationIcon.SetIdleState ();
}
// Ignores Repos, dotfiles, swap files and the like.
public bool ShouldIgnore (string FileName) {
if (FileName.Substring (0, 1).Equals (".") ||
FileName.Contains (".lock") ||
FileName.Contains (".git") ||
FileName.Contains ("/.") ||
Directory.Exists (LocalPath + FileName))
return true; // Yes, ignore it.
else if (FileName.Length > 3 &&
FileName.Substring (FileName.Length - 4).Equals (".swp"))
return true;
else return false;
}
// Creates a pretty commit message based on what has changed
public string FormatCommitMessage () {
bool DoneAddCommit = false;
bool DoneEditCommit = false;
bool DoneRenameCommit = false;
bool DoneDeleteCommit = false;
int FilesAdded = 0;
int FilesEdited = 0;
int FilesRenamed = 0;
int FilesDeleted = 0;
Process.StartInfo.Arguments = "status";
Process.Start();
string Output = Process.StandardOutput.ReadToEnd();
foreach (string Line in Regex.Split (Output, "\n")) {
if (Line.IndexOf ("new file:") > -1)
FilesAdded++;
if (Line.IndexOf ("modified:") > -1)
FilesEdited++;
if (Line.IndexOf ("renamed:") > -1)
FilesRenamed++;
if (Line.IndexOf ("deleted:") > -1)
FilesDeleted++;
}
foreach (string Line in Regex.Split (Output, "\n")) {
// Format message for when files are added,
// example: "added 'file' and 3 more."
if (Line.IndexOf ("new file:") > -1 && !DoneAddCommit) {
DoneAddCommit = true;
if (FilesAdded > 1)
return "added " +
Line.Replace ("#\tnew file:", "").Trim () +
" and " + (FilesAdded - 1) + " more.";
else
return "added " +
Line.Replace ("#\tnew file:", "").Trim () + ".";
}
// Format message for when files are edited,
// example: "edited 'file'."
if (Line.IndexOf ("modified:") > -1 && !DoneEditCommit) {
DoneEditCommit = true;
if (FilesEdited > 1)
return "edited " +
Line.Replace ("#\tmodified:", "").Trim () +
" and " + (FilesEdited - 1) + " more.";
else
return "edited " +
Line.Replace ("#\tmodified:", "").Trim () + ".";
}
// Format message for when files are edited,
// example: "deleted 'file'."
if (Line.IndexOf ("deleted:") > -1 && !DoneDeleteCommit) {
DoneDeleteCommit = true;
if (FilesDeleted > 1)
return "deleted " +
Line.Replace ("#\tdeleted:", "").Trim () +
" and " + (FilesDeleted - 1) + " more.";
else
return "deleted " +
Line.Replace ("#\tdeleted:", "").Trim () + ".";
}
// Format message for when files are renamed,
// example: "renamed 'file' to 'new name'."
if (Line.IndexOf ("renamed:") > -1 && !DoneRenameCommit) {
DoneDeleteCommit = true;
if (FilesRenamed > 1)
return "renamed " +
Line.Replace ("#\trenamed:", "").Trim ().Replace
(" -> ", " to ") + " and " + (FilesDeleted - 1) +
" more.";
else
return "renamed " +
Line.Replace ("#\trenamed:", "").Trim ().Replace
(" -> ", " to ") + ".";
}
}
// Nothing happened:
return "";
}
// Shows a notification with text and image
public void ShowEventBubble (string Title,
Gdk.Pixbuf Avatar,
bool ShowButtons) {
SparkleBubble StuffChangedBubble = new SparkleBubble (Title, "");
StuffChangedBubble.Icon = Avatar;
// Add a button to open the folder where the changed file is
if (ShowButtons)
StuffChangedBubble.AddAction
("", "Open Folder",
delegate {
switch (SparklePlatform.Name) {
case "GNOME":
Process.StartInfo.FileName = "xdg-open";
break;
case "OSX":
Process.StartInfo.FileName = "open";
break;
}
Process.StartInfo.Arguments = LocalPath;
Process.Start();
Process.StartInfo.FileName = "git";
} );
}
}
}

View file

@ -38,29 +38,36 @@ namespace SparkleShare {
// Create 'SparkleShare' folder in the user's home folder
// if it's not there already
if (!Directory.Exists (SparklePath)) {
Directory.CreateDirectory (SparklePath);
Console.WriteLine ("[Config] Created '" + SparklePath + "'");
if (SparklePlatform.Name.Equals ("GNOME")) {
// Add a special icon to the SparkleShare folder
Process.StartInfo.FileName = "gvfs-set-attribute";
Process.StartInfo.Arguments = SparklePath +
" metadata::custom-icon " +
"file:///usr/share/icons/hicolor/" +
"48x48/places/" +
"folder-sparkleshare.png";
Process.Start();
// Add a special icon to the SparkleShare folder
switch (SparklePlatform.Name) {
case "GNOME":
Process.StartInfo.FileName = "gvfs-set-attribute";
Process.StartInfo.Arguments = SparklePath +
" metadata::custom-icon " +
"file:///usr/share/icons/hicolor/" +
"48x48/places/" +
"folder-sparkleshare.png";
break;
}
Process.Start();
// Add the SparkleShare folder to the bookmarks
string BookmarksFileName =
Path.Combine (SparklePaths.HomePath, ".gtk-bookmarks");
if (File.Exists (BookmarksFileName)) {
TextWriter TextWriter = File.AppendText (BookmarksFileName);
TextWriter.WriteLine ("file://" + SparklePath + " SparkleShare");
TextWriter.Close();
}
// Add the SparkleShare folder to the bookmarks
switch (SparklePlatform.Name) {
case "GNOME":
string BookmarksFileName =
Path.Combine (SparklePaths.HomePath, ".gtk-bookmarks");
if (File.Exists (BookmarksFileName)) {
TextWriter TextWriter = File.AppendText (BookmarksFileName);
TextWriter.WriteLine ("file://" + SparklePath + " SparkleShare");
TextWriter.Close();
}
break;
}
}
@ -79,14 +86,16 @@ namespace SparkleShare {
i++;
// Attach emblems
if (SparklePlatform.Name.Equals ("GNOME")) {
Process.StartInfo.FileName = "gvfs-set-attribute";
Process.StartInfo.Arguments = " file://" + Folder +
" metadata::emblems " +
"[synced]";
Process.Start();
switch (SparklePlatform.Name) {
case "GNOME":
Process.StartInfo.FileName = "gvfs-set-attribute";
Process.StartInfo.Arguments = " file://" + Folder +
" metadata::emblems " +
"[synced]";
break;
}
Process.Start();
}
}

View file

@ -2,7 +2,7 @@
mkdir -p locale
if [ $# -ne 1 ]; then
echo "Usage: ./create-po-file [LOCALE].po"
echo "Usage: ./create-po-file [LOCALE].pot"
else
xgettext -a --from-code=UTF-8 SparkleShare/*.cs -o locale/$1
echo "Created locale/$1."