Skip to content

Commit

Permalink
Merge branch 'release/1.0.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
canton7 committed Mar 10, 2015
2 parents df3a6fb + 27b1816 commit 4f49b59
Show file tree
Hide file tree
Showing 29 changed files with 687 additions and 147 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Changelog
=========

v1.0.7
------

- Support GUI Authentication
- Ignore 'synced' events after device connection/disconnection, reducing noise
- Add option to obfuscate device IDs (thanks Adrian Rudnik)
- Allow Syncthing to localize by sending correct language headers (thanks Adrian Rudnik)
- Add validation to the Settings page
- Better handle exceptions encountered during shutdown
- Catch case where syncthing.exe can't be started because of group policy settings

v1.0.6
------

Expand Down
1 change: 1 addition & 0 deletions Contributers.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ The following individuals have contributed in same way towards making SyncTrayzo

- [Joel Kåberg](https://github.com/jkaberg): SyncTrayzor's first user! Caught bugs I would never have spotted.
- [d4k0](https://github.com/d4k0): Fixed some icon problems.
- [Adrian Rudnik](https://github.com/kreischweide): SyncTrayzor's first PR! Added device ID obfuscation
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ Grab the latest standalone .zip from the [releases](https://github.com/canton7/S
Unzip, and run `SyncTrayzor.exe`. If you're updating, you'll need to copy the `data` folder across from your previous standalone installation.


Contributing
------------

Got a bug? [Raise an issue](https://github.com/canton7/SyncTrayzor/issues), providing as much detail as you can.

Want to make a contribution? Fantastic, and thank you! Please read [Contributing](https://github.com/canton7/SyncTrayzor/wiki/Contributing) first.


What will SyncTrayzor do to Syncthing?
--------------------------------------

Expand Down
214 changes: 112 additions & 102 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,132 +6,142 @@ rescue LoadError
exit 1
end

ISCC = '"C:\Program Files (x86)\Inno Setup 5\ISCC.exe"'
ISCC = 'C:\Program Files (x86)\Inno Setup 5\ISCC.exe'
unless File.exist?(ISCC)
warn "Please install Inno Setup"
exit 1
end

BIN_DIR_64 = 'bin/x64/Release'
BIN_DIR_86 = 'bin/x86/Release'
CONFIG = ENV['CONFIG'] || 'Release'

SRC_DIR = 'src/SyncTrayzor'
INSTALLER_DIR = 'installer'

INSTALLER_64 = File.join(INSTALLER_DIR, 'x64')
INSTALLER_86 = File.join(INSTALLER_DIR, 'x86')

INSTALLER_64_OUTPUT = File.join(INSTALLER_64, 'SyncTrayzorSetup-x64.exe')
INSTALLER_86_OUTPUT = File.join(INSTALLER_86, 'SyncTrayzorSetup-x86.exe')

PORTABLE_OUTPUT_DIR_64 = File.absolute_path('SyncTrayzorPortable-x64')
PORTABLE_OUTPUT_DIR_86 = File.absolute_path('SyncTrayzorPortable-x86')

CONFIG = ENV['CONFIG'] || 'Release'

def cp_to_portable(ouput_dir, src)
dest = File.join(ouput_dir, src)
mkdir_p File.dirname(dest) unless File.exist?(File.dirname(dest))
cp src, dest
class ArchDirConfig
attr_reader :arch
attr_reader :bin_dir
attr_reader :installer_dir
attr_reader :installer_output
attr_reader :installer_iss
attr_reader :portable_output_dir

def initialize(arch)
@arch = arch
@bin_dir = "bin/#{@arch}/#{CONFIG}"
@installer_dir = File.join(INSTALLER_DIR, @arch)
@installer_output = File.join(@installer_dir, "SyncTrayzorSetup-#{@arch}.exe")
@installer_iss = File.join(@installer_dir, "installer-#{@arch}.iss")
@portable_output_dir = File.absolute_path("SyncTrayzorPortable-#{@arch}")
end
end

desc 'Build the project (64-bit)'
build :buildx64 do |b|
b.sln = 'src/SyncTrayzor.sln'
b.target = [:Clean, :Build]
b.prop 'Configuration', CONFIG
b.prop 'Platform', 'x64'
end
ARCH_CONFIG = [ArchDirConfig.new('x64'), ArchDirConfig.new('x86')]

desc 'Build the project (32-bit)'
build :buildx86 do |b|
b.sln = 'src/SyncTrayzor.sln'
b.target = [:Clean, :Build]
b.prop 'Configuration', CONFIG
b.prop 'Platform', 'x86'
namespace :build do
ARCH_CONFIG.each do |arch_config|
desc "Build the project (#{arch_config.arch})"
build arch_config.arch do |b|
b.sln = 'src/SyncTrayzor.sln'
b.target = [:Clean, :Build]
b.prop 'Configuration', CONFIG
b.prop 'Platform', arch_config.arch
end
end
end

desc 'Build both 64-bit and 32-bit binaries'
task :build => [:buildx64, :buildx86]

def create_installer(output_file, installer_dir, iss_name)
rm output_file if File.exist?(output_file)
sh ISCC, File.join(installer_dir, iss_name)
task :build => ARCH_CONFIG.map{ |x| :"build:#{x.arch}" }

namespace :installer do
ARCH_CONFIG.each do |arch_config|
desc "Create the installer (#{arch_config.arch})"
task arch_config.arch do
rm arch_config.installer_output if File.exist?(arch_config.installer_output)
sh %Q{"#{ISCC}"}, arch_config.installer_iss
end
end
end

desc 'Create 64-bit installer'
task :installerx64 do
create_installer(INSTALLER_64_OUTPUT, INSTALLER_64, 'installer-x64.iss')
end
desc 'Build both 64-bit and 32-bit installers'
task :installer => ARCH_CONFIG.map{ |x| :"installer:#{x.arch}" }

desc 'Create 32-bit installer'
task :installerx86 do
create_installer(INSTALLER_86_OUTPUT, INSTALLER_86, 'installer-x86.iss')
def cp_to_portable(ouput_dir, src)
dest = File.join(ouput_dir, src)
mkdir_p File.dirname(dest) unless File.exist?(File.dirname(dest))
cp src, dest
end

desc 'Create 32-bit and 64-bit installers'
task :installer => [:installerx64, :installerx86]

def create_portable(bin_dir, output_dir, installer_platform_dir)
rm_rf output_dir
mkdir_p output_dir

Dir.chdir(bin_dir) do
files = FileList[
'*.exe',
'*.exe.config',
'*.dll',
'*.pdb',
'*.pak',
'*.dat',
File.join('locales', '*'),
].exclude('*.vshost.*')

files.each do |file|
cp_to_portable(output_dir, file)
namespace :portable do
ARCH_CONFIG.each do |arch_config|
desc "Create the portable package (#{arch_config.arch})"
task arch_config.arch do
rm_rf arch_config.portable_output_dir
mkdir_p arch_config.portable_output_dir

Dir.chdir(arch_config.bin_dir) do
files = FileList[
'*.exe',
'*.exe.config',
'*.dll',
'*.pdb',
'*.pak',
'*.dat',
File.join('locales', '*'),
].exclude('*.vshost.*')

files.each do |file|
cp_to_portable(arch_config.portable_output_dir, file)
end
end

cp File.join(SRC_DIR, 'Icons', 'default.ico'), arch_config.portable_output_dir

FileList['*.md', '*.txt'].each do |file|
cp_to_portable(arch_config.portable_output_dir, file)
end

Dir.chdir(arch_config.installer_dir) do
FileList['syncthing.exe', '*.dll'].each do |file|
cp_to_portable(arch_config.portable_output_dir, file)
end
end

puts 'Rewriting app.config'
config_path = File.join(arch_config.portable_output_dir, 'SyncTrayzor.exe.config')
doc = File.open(config_path, 'r') do |f|
doc = REXML::Document.new(f)
REXML::XPath.first(doc, '/configuration/applicationSettings//setting[@name="PortableMode"]/value').text = 'True'
doc
end
File.open(config_path, 'w') do |f|
doc.write(f)
end
end
end
end

cp File.join(SRC_DIR, 'Icons', 'default.ico'), output_dir
desc 'Create both 64-bit and 32-bit portable packages'
task :portable => ARCH_CONFIG.map{ |x| :"portable:#{x.arch}" }

FileList['*.md', '*.txt'].each do |file|
cp_to_portable(output_dir, file)
end

Dir.chdir(installer_platform_dir) do
FileList['syncthing.exe', '*.dll'].each do |file|
cp_to_portable(output_dir, file)
namespace :clean do
ARCH_CONFIG.each do |arch_config|
desc "Clean everything (#{arch_config.arch})"
task arch_config.arch do
rm_rf arch_config.portable_output_dir if File.exist?(arch_config.portable_output_dir)
rm arch_config.installer_output if File.exist?(arch_config.installer_output)
end
end

puts 'Rewriting app.config'
config_path = File.join(output_dir, 'SyncTrayzor.exe.config')
doc = File.open(config_path, 'r') do |f|
doc = REXML::Document.new(f)
REXML::XPath.first(doc, '/configuration/applicationSettings//setting[@name="PortableMode"]/value').text = 'True'
doc
end
File.open(config_path, 'w') do |f|
doc.write(f)
end
end

desc 'Create the portable (x64) release directory'
task :portablex64 do
create_portable(BIN_DIR_64, PORTABLE_OUTPUT_DIR_64, INSTALLER_64)
end
desc 'Clean portable and installer, all architectures'
task :clean => ARCH_CONFIG.map{ |x| :"clean:#{x.arch}" }

desc 'Create the portable (x86) release directory'
task :portablex86 do
create_portable(BIN_DIR_86, PORTABLE_OUTPUT_DIR_86, INSTALLER_86)
namespace :package do
ARCH_CONFIG.each do |arch_config|
desc "Build installer and portable (#{arch_config.arch})"
task arch_config.arch => [:"clean:#{arch_config.arch}", :"build:#{arch_config.arch}", :"installer:#{arch_config.arch}", :"portable:#{arch_config.arch}"]
end
end

desc 'Create portable release directories for x64 and x86'
task :portable => [:portablex64, :portablex86]

desc 'Build and package everything'
task :package => [:build, :installer, :portable]

desc 'Remove portable and installer'
task :clean do
rm_rf PORTABLE_OUTPUT_DIR_64 if File.exist?(PORTABLE_OUTPUT_DIR_64)
rm_rf PORTABLE_OUTPUT_DIR_86 if File.exist?(PORTABLE_OUTPUT_DIR_86)
rm INSTALLER_64 if File.exist?(INSTALLER_64)
rm INSTALLER_86 if File.exist?(INSTALLER_86)
end
desc 'Build installer and portable for all architectures'
task :package => ARCH_CONFIG.map{ |x| :"package:#{x.arch}" }
1 change: 1 addition & 0 deletions src/SyncTrayzor/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
archiveEvery="Day"
archiveNumbering="Date"
maxArchiveFiles="7"
AutoFlush="True"
layout="${longdate} [${level}] ${logger}: ${message} ${exception:format=type,message,method,stacktrace,tostring:maxInnerExceptionLevel=10:innerFormat=shortType,message,method}"/>
<target name="debugger" type="Debugger"
layout="${time} [${level}] ${logger:shortName=true} ${message}"/>
Expand Down
42 changes: 33 additions & 9 deletions src/SyncTrayzor/Bootstrapper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CefSharp;
using FluentValidation;
using NLog;
using Stylet;
using StyletIoC;
Expand All @@ -8,6 +9,7 @@
using SyncTrayzor.Services;
using SyncTrayzor.Services.UpdateChecker;
using SyncTrayzor.SyncThing;
using SyncTrayzor.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -22,6 +24,8 @@ namespace SyncTrayzor
{
public class Bootstrapper : Bootstrapper<ShellViewModel>
{
private bool exiting;

protected override void ConfigureIoC(IStyletIoCBuilder builder)
{
builder.Bind<IApplicationState>().ToInstance(new ApplicationState(this.Application));
Expand All @@ -37,6 +41,9 @@ protected override void ConfigureIoC(IStyletIoCBuilder builder)
builder.Bind<IWatchedFolderMonitor>().To<WatchedFolderMonitor>().InSingletonScope();
builder.Bind<IGithubApiClient>().To<GithubApiClient>().InSingletonScope();
builder.Bind<IUpdateChecker>().To<UpdateChecker>().InSingletonScope();

builder.Bind(typeof(IModelValidator<>)).To(typeof(FluentModelValidator<>));
builder.Bind(typeof(IValidator<>)).ToAllImplementations(this.Assemblies);
}

protected override void Configure()
Expand Down Expand Up @@ -97,26 +104,43 @@ protected override void OnLaunch()

protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e)
{
var windowManager = this.Container.Get<IWindowManager>();
var logger = LogManager.GetCurrentClassLogger();
logger.Error("An unhandled exception occurred", e.Exception);

var configurationException = e.Exception as ConfigurationException;
if (configurationException != null)
// If we're shutting down, we're not going to be able to display an error dialog....
// We've logged it. Nothing else we can do.
if (this.exiting)
return;

try
{
windowManager.ShowMessageBox(String.Format("Configuration Error: {0}", configurationException.Message), "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
var windowManager = this.Container.Get<IWindowManager>();

var configurationException = e.Exception as ConfigurationException;
if (configurationException != null)
{
windowManager.ShowMessageBox(String.Format("Configuration Error: {0}", configurationException.Message), "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}
else
{
var vm = this.Container.Get<UnhandledExceptionViewModel>();
vm.Exception = e.Exception;
windowManager.ShowDialog(vm);
}
}
else
catch (Exception exception)
{
var vm = this.Container.Get<UnhandledExceptionViewModel>();
vm.Exception = e.Exception;
windowManager.ShowDialog(vm);
// Don't re-throw. Nasty stuff happens if we throw an exception while trying to handle an unhandled exception
// For starters, the event log shows the wrong exception - this one, instead of the root cause
logger.Error("Unhandled exception while trying to display unhandled exception window", exception);
}
}

protected override void OnExit(ExitEventArgs e)
{
this.exiting = true;

// Try and be nice and close SyncTrayzor gracefully, before the Dispose call on SyncThingProcessRunning kills it dead
this.Container.Get<ISyncThingManager>().StopAsync().Wait(500);
}
Expand Down
7 changes: 5 additions & 2 deletions src/SyncTrayzor/NotifyIcon/NotifyIconManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public interface INotifyIconManager

public class NotifyIconManager : INotifyIconManager
{
// Amount of time to squish 'synced' messages for after a connectivity event
private static readonly TimeSpan syncedDeadTime = TimeSpan.FromSeconds(10);

private readonly IViewManager viewManager;
private readonly NotifyIconViewModel viewModel;
private readonly IApplicationState application;
Expand Down Expand Up @@ -75,8 +78,8 @@ public NotifyIconManager(

this.syncThingManager.FolderSyncStateChanged += (o, e) =>
{
if (this.ShowSynchronizedBalloon && this.syncThingManager.StartedAt.HasValue &&
DateTime.UtcNow - this.syncThingManager.StartedAt.Value > TimeSpan.FromSeconds(60) &&
if (this.ShowSynchronizedBalloon &&
DateTime.UtcNow - this.syncThingManager.LastConnectivityEventTime > syncedDeadTime &&
e.SyncState == FolderSyncState.Idle && e.PrevSyncState == FolderSyncState.Syncing)
{
Application.Current.Dispatcher.CheckAccess(); // Double-check
Expand Down
Loading

0 comments on commit 4f49b59

Please sign in to comment.