Skip to content

Commit

Permalink
Merge branch 'release/1.1.17'
Browse files Browse the repository at this point in the history
  • Loading branch information
canton7 committed Sep 4, 2017
2 parents d9fc454 + 2a286d1 commit b679a4a
Show file tree
Hide file tree
Showing 38 changed files with 552 additions and 144 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
Changelog
=========

v1.1.17
-------

- Don't store Syncthing's API key in config, and don't log it
- Fix filesystem notifications when the file contained non-ASCII characters (#400)
- Don't show device connected/disconnected notifications if a device is reconnecting a lot
- Don't watch / raise notifications about new folders if no existing folders are watched / have notifications (#393)
- Don't write to the disk as much by default (#370)
- Fix crash on the settings screen
- Be more reslient to weird registry permissions, fixing crash (#378)
- Fix crash when calculating data transfer stats (#380)
- Be more reslient when trying to find a free port for Syncthing to use (#381)
- Add installer command-line flags (for system administrators) (#371, #402)
- Add an exit poll to the uninstaller

v1.1.16
-------

Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Features include:
- Syncthing on its own has to poll your folders, in order to see if any files have changed.
- SyncTrayzor will watch your folders for changes, and alert Syncthing the second anything changes.
- This means you can increase the polling interval in Syncthing, avoiding the resource usage of high-frequency polling, but still have any changes propagated straight away.
- Folder watching respects the ignores configured in Syncthing.
- Has a tool to help you resolve file conflicts
- Can pause devices on metered networks, to stop Syncthing transferring data on e.g. a mobile connection or wifi hotspot.
- Contains translations for many languages
Expand Down Expand Up @@ -203,5 +202,19 @@ Building from Source
--------------------

You'll need [Visual Studio 2017](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx).
Make sure you install "Blend for Visual Studio SDK for .NET".
Clone/download the repository, open `src\SyncTrayzor.sln`, and compile.
You'll also need to [download syncthing.exe](https://github.com/syncthing/syncthing/releases) and place it in the `bin\x86\Debug`, `bin\x64\Debug`, `bin\x86\Release`, or `bin\x64\Release` folder as appropriate.


Notes for System Administrators
-------------------------------

The installer is built using Inno Setup, and has various command-line options, [documented here](http://www.jrsoftware.org/ishelp/index.php?topic=setupcmdline).
If you pass the `/silent` command-line flag when SyncTrayzor won't be launched when the installer completes: add `/StartSyncTrayzor` to override this (which also causes SyncTrayzor to be launched minimized).

There are various parameters inside the file `SyncTrayzor.exe.config` which can be customised by system administrators, including the default SyncTrayzor configuration (used to create the user's SyncTrayzor config file when SyncTrayzor is first launched).
To override these, pass the flag `/SyncTrayzorExeConfig="Path\To\Customized\SyncTrayzor.exe.config"` to the installer -- the specified `SyncTrayzor.exe.config` will overwrite the default.

Note that the contents / structure of `SyncTrayzor.exe.config` may change between releases.
Using the wrong version may cause a crash, or incorrect behaviour.
222 changes: 215 additions & 7 deletions installer/common.iss
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
#define AppDataFolder "SyncTrayzor"
#define RunRegKey "Software\Microsoft\Windows\CurrentVersion\Run"
#define DotNetInstallerExe "dotNet451Setup.exe"
#define DonateUrl = "https://synctrayzor.antonymale.co.uk/donate"
#define DonateUrl "https://synctrayzor.antonymale.co.uk/donate"
#define SurveyUrl "https://synctrayzor.antonymale.co.uk/survey.php"

[Setup]
AppId={{#AppId}
AppName={#AppName} ({#Arch})
AppVersion={#AppVersion}
VersionInfoVersion={#AppVersion}
;AppVerName={#AppName} {#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
Expand All @@ -29,8 +31,8 @@ OutputDir="."
OutputBaseFilename={#AppName}Setup-{#Arch}
SetupIconFile={#AppSrc}\Icons\default.ico
WizardSmallImageFile=..\icon.bmp
;Compression=lzma2/max
Compression=None
Compression=lzma2/max
;Compression=None
SolidCompression=yes
PrivilegesRequired=admin
CloseApplications=yes
Expand Down Expand Up @@ -79,11 +81,13 @@ Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(AppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(AppName, '&', '&&')}}"; Flags: nowait postinstall; Parameters: {code:SyncTrayzorStartFlags}; Check: ShouldStartSyncTrayzor

[Code]
var
GlobalRestartRequired: boolean;
UninstallPollPage: TNewNotebookPage;
UninstallNextButton: TNewButton;
function DotNetIsMissing(): Boolean;
var
Expand Down Expand Up @@ -187,6 +191,7 @@ var
FindRec: TFindRec;
FolderPath: String;
FilePath: String;
ExeConfig: String;
begin
if CurStep = ssInstall then
begin
Expand Down Expand Up @@ -219,6 +224,26 @@ begin
end;
end;
end
else if CurStep = ssPostInstall then
begin
ExeConfig := ExpandConstant('{param:SyncTrayzorExeConfig}');
if ExeConfig <> '' then
begin
if FileExists(ExeConfig) then
begin
FileCopy(ExeConfig, ExpandConstant('{app}\SyncTrayzor.exe.config'), false);
end
else
begin
MsgBox('Could not find SyncTrayzorExeConfig file: ' + ExeConfig + '. Using default.', mbError, MB_OK);
end
end
end
end;
procedure CurPageChanged(CurPageID: Integer);
begin
end;
function PrepareToInstall(var NeedsRestart: Boolean): String;
Expand All @@ -238,10 +263,193 @@ begin
Result := GlobalRestartRequired;
end;
function ShouldStartSyncTrayzor(): Boolean;
var
flagPassed: Boolean;
i: Integer;
begin
// Can't use {param}, as it doesn't match flags with no value
flagPassed := False;
for i := 0 to ParamCount do begin
if ParamStr(i) = '/StartSyncTrayzor' then begin
flagPassed := True;
break;
end;
end;
Result := (not WizardSilent()) or flagPassed;
end;
function SyncTrayzorStartFlags(param: String): String;
begin
if WizardSilent() then begin
Result := '-minimized'
end else begin
Result := ''
end;
end;
function SerializeBool(value: Boolean): String;
begin
if value then begin
Result := 'true';
end else begin
Result := 'false';
end
end;
function EscapeJsonString(value: String): String;
var
c: Char;
i: Integer;
begin
// http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_charlength
i := 1;
while i <= Length(value) do
begin
c := value[i];
if c = #10 then begin
Result := Result + '\n';
end else if c = #13 then begin
Result := Result + '\r';
end else if c = #9 then begin
Result := Result + '\t';
end else if Ord(c) < 32 then begin
Result := Result + Format('\x%.4x', [Ord(c)]);
end else if c = '"' then begin
Result := Result + '\"';
end else if c = '\' then begin
Result := Result + '\\'
end else begin
Result := Result + c;
end;
i := i + CharLength(value, i);
end;
end;
// See https://stackoverflow.com/a/42550055/1086121
procedure UpdateUninstallWizard;
begin
if UninstallProgressForm.InnerNotebook.ActivePage = UninstallPollPage then
begin
UninstallProgressForm.PageNameLabel.Caption := 'Please Tell Us Why You''re Leaving';
UninstallProgressForm.PageDescriptionLabel.Caption := '';
end;
UninstallNextButton.Caption := 'Uninstall';
// Make the "Uninstall" button break the ShowModal loop
UninstallNextButton.ModalResult := mrOK;
end;
procedure InitializeUninstallProgressForm();
var
PageText: TNewStaticText;
PageNameLabel: string;
PageDescriptionLabel: string;
CancelButtonEnabled: Boolean;
CancelButtonModalResult: Integer;
Checklist: TNewCheckListBox;
CommentsText: TNewStaticText;
CommentsBox: TNewMemo;
WinHttpReq: Variant;
begin
if not UninstallSilent then
begin
// Create the poll page and make it active
UninstallPollPage := TNewNotebookPage.Create(UninstallProgressForm);
UninstallPollPage.Notebook := UninstallProgressForm.InnerNotebook;
UninstallPollPage.Parent := UninstallProgressForm.InnerNotebook;
UninstallPollPage.Align := alClient;
PageText := TNewStaticText.Create(UninstallProgressForm);
PageText.Parent := UninstallPollPage;
PageText.AutoSize := True;
PageText.WordWrap := True;
PageText.SetBounds(UninstallProgressForm.StatusLabel.Left, UninstallProgressForm.StatusLabel.Top, UninstallProgressForm.StatusLabel.Width, UninstallProgressForm.StatusLabel.Height);
PageText.ShowAccelChar := False;
PageText.Caption := 'Sorry you''re leaving! Please tell us what you didn''t like so we can improve it.' + #13#10 +
'No personal data will be sent. You can skip this step if you want.';
Checklist := TNewCheckListBox.Create(UninstallProgressForm);
Checklist.Parent := UninstallPollPage;
Checklist.SetBounds(PageText.Left, PageText.Top + PageText.Height + ScaleY(10), PageText.Width, ScaleY(20) * 5);
Checklist.BorderStyle := bsNone;
Checklist.Color := clBtnFace;
Checklist.WantTabs := True;
Checklist.MinItemHeight := ScaleY(20);
Checklist.AddCheckBox('I couldn''t get Syncthing to work', '', 0, False, True, False, False, nil);
Checklist.AddCheckBox('Syncthing doesn''t do what I need', '', 0, False, True, False, False, nil);
Checklist.AddCheckBox('I prefer another sync tool (please say which below)', '', 0, False, True, False, False, nil);
Checklist.AddCheckBox('I don''t like SyncTrayzor - I''m going to use another wrapper', '', 0, False, True, False, False, nil);
Checklist.AddCheckBox('Other (please expand below)', '', 0, False, True, False, False, nil);
CommentsText := TNewStaticText.Create(UninstallProgressForm);
CommentsText.Parent := UninstallPollPage;
CommentsText.AutoSize := True;
CommentsText.WordWrap := True;
CommentsText.SetBounds(PageText.Left, Checklist.Top + Checklist.Height + ScaleY(10), PageText.Width, ScaleY(15));
CommentsText.AutoSize := False;
CommentsText.ShowAccelChar := False;
CommentsText.Caption := 'More Details / Complaints:';
CommentsBox := TNewMemo.Create(UninstallProgressForm);
CommentsBox.Parent := UninstallPollPage;
CommentsBox.SetBounds(PageText.Left, CommentsText.Top + CommentsText.Height + ScaleY(5), PageText.Width, ScaleY(60));
CommentsBox.ScrollBars := ssVertical;
UninstallProgressForm.InnerNotebook.ActivePage := UninstallPollPage;
PageNameLabel := UninstallProgressForm.PageNameLabel.Caption;
PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption;
UninstallNextButton := TNewButton.Create(UninstallProgressForm);
UninstallNextButton.Parent := UninstallProgressForm;
UninstallNextButton.Left := UninstallProgressForm.CancelButton.Left - UninstallProgressForm.CancelButton.Width - ScaleX(10);
UninstallNextButton.Top := UninstallProgressForm.CancelButton.Top;
UninstallNextButton.Width := UninstallProgressForm.CancelButton.Width;
UninstallNextButton.Height := UninstallProgressForm.CancelButton.Height;
UninstallProgressForm.CancelButton.TabOrder := UninstallNextButton.TabOrder + 1;
// Run our wizard pages
UpdateUninstallWizard;
CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled
UninstallProgressForm.CancelButton.Enabled := True;
CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult;
UninstallProgressForm.CancelButton.ModalResult := mrCancel;
if UninstallProgressForm.ShowModal = mrCancel then Abort;
if Checklist.Checked[0] or Checklist.Checked[1] or Checklist.Checked[2] or Checklist.Checked[3] or Checklist.Checked[4] or (CommentsBox.Text <> '') then begin
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('POST', '{#SurveyUrl}', false);
WinHttpReq.Send('{' +
' "version": "{#AppVersion}"' +
', "comment": "' + EscapeJsonString(CommentsBox.Text) + '"' +
', "checklist": {' +
' "wontWork": '+ SerializeBool(Checklist.Checked[0]) +
', "notWhatINeed": '+ SerializeBool(Checklist.Checked[1]) +
', "preferAnotherSyncTool": '+ SerializeBool(Checklist.Checked[2]) +
', "dontLikeSyncTrayzor": '+ SerializeBool(Checklist.Checked[3]) +
', "other": '+ SerializeBool(Checklist.Checked[4]) +
' }' +
' }');
end;
// Restore the standard page payout
UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled;
UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult;
UninstallProgressForm.PageNameLabel.Caption := PageNameLabel;
UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel;
UninstallProgressForm.InnerNotebook.ActivePage := UninstallProgressForm.InstallingPage;
end;
end;
[UninstallDelete]
Type: files; Name: "{app}\ProcessRunner.exe.old"
Type: files; Name: "{app}\InstallCount.txt"
Type: filesandordirs; Name: "{userappdata}\{#AppDataFolder}"
Type: filesandordirs; Name: "{localappdata}\{#AppDataFolder}"


Type: filesandordirs; Name: "{localappdata}\{#AppDataFolder}"
63 changes: 63 additions & 0 deletions server/survey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/**
* Survey endpoint for SyncTrayzor
*/

set_error_handler('error_handler');
date_default_timezone_set('UCT');

function error_handler($severity, $message, $filename, $lineno)
{
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}

define('DATABASE', 'survey.sqlite');

try
{
$exists = file_exists(DATABASE);

$db = new PDO('sqlite:'.DATABASE);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec('PRAGMA foreign_keys = ON;');

if (!$exists)
{
$db->exec("CREATE TABLE IF NOT EXISTS responses (
id INTEGER PRIMARY KEY,
date TEXT NOT NULL,
version TEXT NOT NULL,
ip TEXT NOT NULL,
comment TEXT
);");
$db->exec("CREATE TABLE IF NOT EXISTS checklist (
id INTEGER PRIMARY KEY,
response_id INTEGER NOT NULL REFERENCES responses(id),
key TEXT NOT NULL
);");
}

$data = json_decode(file_get_contents('php://input'), true);
$stmt = $db->prepare("INSERT INTO responses(date, ip, version, comment) VALUES (CURRENT_TIMESTAMP, :ip, :version, :comment);");
$stmt->execute(array(
'ip' => $_SERVER['REMOTE_ADDR'],
'version' => $data['version'],
'comment' => $data['comment']));
$responseId = $db->lastInsertId();

$stmt = $db->prepare("INSERT INTO CHECKLIST (response_id, key) VALUES (:response_id, :key);");

foreach ($data['checklist'] as $key => $value)
{
if ($value)
{
$stmt->execute(array('response_id' => $responseId, 'key' => $key));
}
}
}
catch (Exception $e)
{
$loggable_error = $e->getMessage() . "\n" . $e->getTraceAsString();
file_put_contents("survey_errors.txt", $loggable_error, FILE_APPEND);
}
Loading

0 comments on commit b679a4a

Please sign in to comment.