Skip to content

Commit

Permalink
Merge branch 'release/1.1.23'
Browse files Browse the repository at this point in the history
* release/1.1.23:
  Update version_check.php
  Update changelog
  Show 'modified by' device in conflict resolver
  If there are no folders, enable notifications
  Fix possible cause of null bytes in config file
  Remove note about filesystem watching from README
  • Loading branch information
canton7 committed Apr 7, 2019
2 parents b287efc + 4773f76 commit 8f51c95
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 20 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

v1.1.23
-------

- Include the latest version of Syncthing (#493)
- Show 'modified by' device in conflict resolver (#492)
- Fix possible cause of null bytes in config file (#471)
- If creating the first folder, enable notifications by default (#495)

v1.1.22
-------

Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ Features include:
- One of your folders is out of sync
- Folders finish syncing
- Devices connect / disconnect
- Can watch your folders for changes, so you don't have to poll them frequently:
- 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.
- 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
7 changes: 4 additions & 3 deletions server/version_check.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function get_with_wildcard($src, $value, $default = null)
}

$versions = [
'1.1.22' => [
'1.1.23' => [
'base_url' => 'https://github.com/canton7/SyncTrayzor/releases/download',
'installed' => [
'direct_download_url' => [
Expand Down Expand Up @@ -106,10 +106,11 @@ function get_with_wildcard($src, $value, $default = null)
];

$upgrades = [
// Github start supporting tls3 only, and versions prior to 1.1.20 didn't support this. 1.1.20 and 1.1.21 are hosted on my server. 1.1.20 can download
// directly from github, but versions prior have to use my server.
'1.1.22' => ['to' => 'latest', 'formatter' => '5'],
'1.1.21' => ['to' => 'latest', 'formatter' => '5'],
'1.1.20' => ['to' => 'latest', 'formatter' => '5'],
// Github start supporting tls3 only, and versions prior to 1.1.20 didn't support this. 1.1.20 and 1.1.21 are hosted on my server. 1.1.20 can download
// directly from github, but versions prior have to use my server.
'1.1.19' => ['to' => '1.1.21', 'formatter' => '5'],
'1.1.18' => ['to' => '1.1.21', 'formatter' => '5'],
'1.1.17' => ['to' => '1.1.21', 'formatter' => '5'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class ConflictOptionViewModel : PropertyChangedBase
public DateTime DateCreated => this.ConflictOption.Created;
public DateTime LastModified => this.ConflictOption.LastModified;
public string Size => FormatUtils.BytesToHuman(this.ConflictOption.SizeBytes, 1);
public string ModifiedBy => this.ConflictOption.Device?.Name;

public ConflictOptionViewModel(ConflictOption conflictOption)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<ColumnDefinition Width="{Binding View.Columns[1].ActualWidth, ElementName=SelectConflictOptions}"/>
<ColumnDefinition Width="{Binding View.Columns[2].ActualWidth, ElementName=SelectConflictOptions}"/>
<ColumnDefinition Width="{Binding View.Columns[3].ActualWidth, ElementName=SelectConflictOptions}"/>
<ColumnDefinition Width="{Binding View.Columns[4].ActualWidth, ElementName=SelectConflictOptions}"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
Expand All @@ -40,7 +41,8 @@
<TextBlock Grid.Row="1" Grid.Column="0" Style="{StaticResource Value}" Text="{Binding Conflict.FileName}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Style="{StaticResource Value}" Text="{Binding Conflict.LastModified}"/>
<TextBlock Grid.Row="1" Grid.Column="2" Style="{StaticResource Value}" Text="{Binding Conflict.Size}"/>
<Button Grid.Row="1" Grid.Column="3"

<Button Grid.Row="1" Grid.Column="4"
HorizontalAlignment="Left"
Style="{StaticResource Value}"
Padding="5,0"
Expand Down Expand Up @@ -76,6 +78,13 @@
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{l:Loc ConflictResolutionView_Header_ModifiedBy}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="0,0,10,0" Text="{Binding ModifiedBy}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
Expand Down
11 changes: 10 additions & 1 deletion src/SyncTrayzor/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/SyncTrayzor/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,10 @@ Do you want to restart SyncTrayzor now?</value>
<value>Original File</value>
<comment>Header shown above the 'Original File' entry, which contains the name of the original file in the conflict, and is shown when the user selects a conflict</comment>
</data>
<data name="ConflictResolutionView_Header_ModifiedBy" xml:space="preserve">
<value>Modified By</value>
<comment>Header shown above the 'Modified by' entry, which contains the name of the device which last modified the file, and is shown when the user selects a conflict</comment>
</data>
<data name="ConflictResolutionView_Scanning_CancelButton" xml:space="preserve">
<value>Cancel</value>
<comment>Text on the 'Cancel' button, shown next to the 'Scanning' progress bar at the top of the page when scanning is in progress</comment>
Expand Down
5 changes: 3 additions & 2 deletions src/SyncTrayzor/Services/ConfigurationApplicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ private void LoadFolders(Configuration configuration)
var folderIds = this.syncthingManager.Folders.FetchAll().Select(x => x.FolderId).ToList();

// If all folders are not watched, new folders are not watched too. Likewise notifications.
bool areAnyWatched = configuration.Folders.Any(x => x.IsWatched);
bool areAnyNotifications = configuration.Folders.Any(x => x.NotificationsEnabled);
// If there are no folders, then enable
bool areAnyWatched = configuration.Folders.Count == 0 || configuration.Folders.Any(x => x.IsWatched);
bool areAnyNotifications = configuration.Folders.Count == 0 || configuration.Folders.Any(x => x.NotificationsEnabled);

foreach (var newKey in folderIds.Except(configuration.Folders.Select(x => x.ID)))
{
Expand Down
30 changes: 23 additions & 7 deletions src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Pri.LongPath;
using NLog;
using System.Reactive.Linq;
using SyncTrayzor.Syncthing.Devices;
using SyncTrayzor.Syncthing;

namespace SyncTrayzor.Services.Conflicts
{
Expand Down Expand Up @@ -36,13 +38,15 @@ public class ConflictOption

public DateTime Created { get; }
public long SizeBytes { get; }
public Device Device { get; }

public ConflictOption(string filePath, DateTime lastModified, DateTime created, long sizeBytes)
public ConflictOption(string filePath, DateTime lastModified, DateTime created, long sizeBytes, Device device)
{
this.FilePath = filePath;
this.LastModified = lastModified;
this.Created = created;
this.SizeBytes = sizeBytes;
this.Device = device;
}

public override string ToString()
Expand All @@ -68,12 +72,14 @@ public struct ParsedConflictFileInfo
public string FilePath { get; }
public string OriginalPath { get; }
public DateTime Created { get; }
public string ShortDeviceId { get; }

public ParsedConflictFileInfo(string filePath, string originalPath, DateTime created)
public ParsedConflictFileInfo(string filePath, string originalPath, DateTime created, string shortDeviceId)
{
this.FilePath = filePath;
this.OriginalPath = originalPath;
this.Created = created;
this.ShortDeviceId = shortDeviceId;
}
}

Expand All @@ -96,17 +102,19 @@ public class ConflictFileManager : IConflictFileManager
private const string syncthingSpecialFileMarker = "~syncthing~";

private static readonly Regex conflictRegex =
new Regex(@"^(?<prefix>.*).sync-conflict-(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})-(?<hours>\d{2})(?<mins>\d{2})(?<secs>\d{2})(?<suffix>.*)(?<extension>\..*)$");
new Regex(@"^(?<prefix>.*).sync-conflict-(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})-(?<hours>\d{2})(?<mins>\d{2})(?<secs>\d{2})(-(?<device>[a-zA-Z0-9]+))?(?<suffix>.*)(?<extension>\..*)$");
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private const int maxSearchDepth = 255; // Loosely based on the max path length (a bit over)

private readonly IFilesystemProvider filesystemProvider;
private readonly ISyncthingManager syncthingManager;

public string ConflictPattern => conflictPattern;

public ConflictFileManager(IFilesystemProvider filesystemProvider)
public ConflictFileManager(IFilesystemProvider filesystemProvider, ISyncthingManager syncthingManager)
{
this.filesystemProvider = filesystemProvider;
this.syncthingManager = syncthingManager;
}

public IObservable<ConflictSet> FindConflicts(string basePath)
Expand Down Expand Up @@ -187,7 +195,12 @@ private void FindConflictsImpl(string basePath, IObserver<ConflictSet> observer,
try
{
var file = new ConflictFile(kvp.Key, this.filesystemProvider.GetLastWriteTime(kvp.Key), this.filesystemProvider.GetFileSize(kvp.Key));
var conflicts = kvp.Value.Select(x => new ConflictOption(x.FilePath, this.filesystemProvider.GetLastWriteTime(x.FilePath), x.Created, this.filesystemProvider.GetFileSize(x.FilePath))).ToList();
var devices = this.syncthingManager.Devices.FetchDevices();
var conflicts = kvp.Value.Select(x =>
{
var device = x.ShortDeviceId == null ? null : devices.FirstOrDefault(d => d.ShortDeviceId == x.ShortDeviceId);
return new ConflictOption(x.FilePath, this.filesystemProvider.GetLastWriteTime(x.FilePath), x.Created, this.filesystemProvider.GetFileSize(x.FilePath), device);
}).ToList();
observer.OnNext(new ConflictSet(file, conflicts));
cancellationToken.ThrowIfCancellationRequested();
}
Expand Down Expand Up @@ -255,6 +268,9 @@ public bool TryFindBaseFileForConflictFile(string filePath, out ParsedConflictFi
var hours = Int32.Parse(parsed.Groups["hours"].Value);
var mins = Int32.Parse(parsed.Groups["mins"].Value);
var secs = Int32.Parse(parsed.Groups["secs"].Value);
var device = parsed.Groups["device"].Value;
if (string.IsNullOrWhiteSpace(device))
device = null;
var suffix = parsed.Groups["suffix"].Value;
var extension = parsed.Groups["extension"].Value;

Expand All @@ -279,14 +295,14 @@ public bool TryFindBaseFileForConflictFile(string filePath, out ParsedConflictFi
var withSuffix = Path.Combine(directory, prefix + suffix + extension);
if (this.filesystemProvider.FileExists(withSuffix))
{
parsedConflictFileInfo = new ParsedConflictFileInfo(filePath, withSuffix, dateCreated);
parsedConflictFileInfo = new ParsedConflictFileInfo(filePath, withSuffix, dateCreated, device);
return true;
}

var withoutSuffix = Path.Combine(directory, prefix + extension);
if (this.filesystemProvider.FileExists(withoutSuffix))
{
parsedConflictFileInfo = new ParsedConflictFileInfo(filePath, withoutSuffix, dateCreated);
parsedConflictFileInfo = new ParsedConflictFileInfo(filePath, withoutSuffix, dateCreated, device);
return true;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/SyncTrayzor/Syncthing/Devices/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public class Device : IEquatable<Device>
private readonly object syncRoot = new object();

public string DeviceId { get; }

private string _shortDeviceId;
public string ShortDeviceId => _shortDeviceId ?? (_shortDeviceId = this.DeviceId.Substring(0, this.DeviceId.IndexOf('-')));

public string Name { get; }

public bool IsConnected
Expand Down
4 changes: 2 additions & 2 deletions src/SyncTrayzor/Utils/AtomicFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ private static string TempFilePath(string path)
return path + DefaultTempFileSuffix;
}

public override void Close()
protected override void Dispose(bool disposing)
{
base.Close();
base.Dispose(disposing);

bool success = NativeMethods.MoveFileEx(this.tempPath, this.path, MoveFileFlags.ReplaceExisting | MoveFileFlags.WriteThrough);
if (!success)
Expand Down

0 comments on commit 8f51c95

Please sign in to comment.