Skip to content

Commit 94e074c

Browse files
committed
More production ready version
1 parent 8c25c9c commit 94e074c

9 files changed

Lines changed: 107 additions & 42 deletions

File tree

README.md

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,65 @@
1-
# Yi Camera FTP Scanner and Video Clips/Images Downloader
1+
# Yi Camera FTP Scanner and Video Clips/Images Downloader with embedded FTP Server for other Cameras
2+
3+
- **Automatic** network scanning for YI Cameras
4+
- **Embedded** FTP server for other cameras
25

36
The application supports two modes - arguments explicitly specified in command prompt and configuration based.
47
It can also run as Windows service.
58

69
[![GitHub release](https://img.shields.io/github/release/AndMu/YiScanner.svg)](https://github.com/AndMu/YiScanner/releases)
710

811
## Configuration via service.json
9-
In this mode, application will monitor designated cameras
1012

1113
```
12-
"Scan": 30,
13-
"Cameras": "1080i,720p",
14-
"Hosts": "192.168.0.103,192.168.0.129",
15-
"Compress": false,
16-
"Archive": 2,
17-
"Images": false,
18-
"All": false,
19-
"Out": "D:/Cloud/Camera/Monitor",
20-
"Action": null,
14+
{
15+
"Scan": 30,
16+
"Archive": 2,
17+
"Output": {
18+
"Compress": false,
19+
"Images": true,
20+
"Out": "D:/Cloud/GoogleUni/Camera/Monitor"
21+
},
22+
"Action": null,
23+
"AutoDiscovery": {
24+
"On": true,
25+
"NetworkMask": "192.168.0.0/255.255.255.0"
26+
},
27+
28+
"YiFtp": {
29+
"Path": "/tmp/sd/record/",
30+
"Password": "",
31+
"Login": "root",
32+
"FileMask": "*.mp4"
33+
},
34+
35+
"Server": {
36+
"Path": "CCTV",
37+
"Port": 21
38+
}
39+
}
2140
```
2241

23-
## Settings:
24-
- **Cameras** - list of cameras
25-
- **Hosts** - list of camera ips.
26-
- **Compress** - do you want to compress retrieved video/images
27-
- **Out** - location of downloaded files
2842
- **Scan** - frequency of FTP scan (in seconds)
29-
- **Archive** - delete previously downloaded old files. Number specifies how many days you want to keep history
30-
- **Images** - Do you want to retrieve video as images
31-
- **Action** - Execute action on each retrieved image
43+
- **Archive** - delete previously downloaded old files. Number specifies how many days you want to keep history.
44+
45+
## Output
46+
47+
- **Compress** - do you want to compress files
48+
- **Out** - location of downloaded files
49+
- **Archive** - delete previously downloaded old files. Number specifies how many days you want to keep history.
50+
51+
## Yi FTP Details
52+
53+
- **Path** - Where images are stored
54+
- **Login** - Login
55+
- **FileMask** - Files to download
56+
- **Password** - Password
57+
58+
## Embedded FTP
59+
60+
- **Path** - Local sub-folder where images will be stored
61+
- **Port** - Server port
62+
3263

3364
## Actions on image
3465

@@ -71,6 +102,3 @@ Options:
71102
- **Scan** - frequency of FTP scan (in seconds)
72103
- **Archive** - delete previously downloaded old files. Number specifies how many days you want to keep history.
73104

74-
75-
# FTP configuration
76-
FTP configuration can be modified in file **appsettings.json**

src/Wikiled.YiScanner.Tests/Monitoring/MonitoringInstanceTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public void SetUp()
3333
scheduler = new TestScheduler();
3434
monitoringConfig = new MonitoringConfig();
3535
monitoringConfig.Scan = 1;
36+
monitoringConfig.Known = new PredefinedCameraConfig();
37+
monitoringConfig.Output = new OutputConfig();
3638
archiving = new Mock<IDeleteArchiving>();
3739
mockDestinationFactory = new Mock<ISourceFactory>();
3840
ftpDownloader = new Mock<IDownloader>();

src/YiScanner/Downloader/FileDownloader.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,18 @@ public async Task<DateTime> Download()
4646

4747
foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
4848
{
49-
if (predicate.CanDownload(lastScanned, file, File.GetLastWriteTime(file)))
49+
try
5050
{
51-
await ProcessFile(file).ConfigureAwait(false);
51+
if (predicate.CanDownload(lastScanned, file, File.GetLastWriteTime(file)))
52+
{
53+
await ProcessFile(file).ConfigureAwait(false);
54+
}
55+
56+
File.Delete(file);
57+
}
58+
catch (Exception ex)
59+
{
60+
log.Error(ex);
5261
}
5362
}
5463

src/YiScanner/Monitoring/Config/MonitoringConfig.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
using Wikiled.YiScanner.Destinations;
1+
using NLog;
2+
using Wikiled.YiScanner.Destinations;
23

34
namespace Wikiled.YiScanner.Monitoring.Config
45
{
56
public class MonitoringConfig
67
{
8+
private static readonly Logger log = LogManager.GetCurrentClassLogger();
9+
710
public int Scan { get; set; }
811

912
public PredefinedCameraConfig Known { get; set; }
@@ -19,5 +22,22 @@ public class MonitoringConfig
1922
public FtpConfig YiFtp { get; set; }
2023

2124
public ServerConfig Server { get; set; }
25+
26+
public bool Validate()
27+
{
28+
if (Output == null)
29+
{
30+
log.Error("Output is not defined");
31+
return false;
32+
}
33+
34+
if (YiFtp == null)
35+
{
36+
log.Error("Yi Ftp is not defined");
37+
return false;
38+
}
39+
40+
return true;
41+
}
2242
}
2343
}

src/YiScanner/Monitoring/Config/ServerConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
public class ServerConfig
44
{
55
public string Path { get; set; }
6+
7+
public int Port { get; set; }
68
}
79
}

src/YiScanner/Network/INetworkScanner.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Net;
34
using System.Threading.Tasks;
45
using Wikiled.YiScanner.Monitoring.Source;
@@ -10,5 +11,7 @@ public interface INetworkScanner
1011
IObservable<Host> FindAddresses(string network, int port);
1112

1213
Task<bool> ScanPort(IPAddress address, int port);
14+
15+
IEnumerable<IPAddress> GetLocalIPAddress();
1316
}
1417
}

src/YiScanner/Network/NetworkScanner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public NetworkScanner(IScheduler scheduler)
2121
{
2222
Guard.NotNull(() => scheduler, scheduler);
2323
this.scheduler = scheduler;
24-
localAddresses = GetIPAddress().ToLookup(item => item);
24+
localAddresses = GetLocalIPAddress().ToLookup(item => item);
2525
}
2626

2727
public IObservable<Host> FindAddresses(string network, int port)
@@ -53,7 +53,7 @@ public async Task<bool> ScanPort(IPAddress address, int port)
5353
}
5454
}
5555

56-
private static IEnumerable<IPAddress> GetIPAddress()
56+
public IEnumerable<IPAddress> GetLocalIPAddress()
5757
{
5858
var host = Dns.GetHostEntry(Dns.GetHostName());
5959
foreach (IPAddress ip in host.AddressList)

src/YiScanner/Program.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Reactive.Concurrency;
56
using System.Reflection;
67
using Newtonsoft.Json;
78
using Newtonsoft.Json.Linq;
@@ -10,6 +11,7 @@
1011
using Wikiled.YiScanner.Commands;
1112
using Wikiled.YiScanner.Monitoring;
1213
using Wikiled.YiScanner.Monitoring.Config;
14+
using Wikiled.YiScanner.Network;
1315

1416
namespace Wikiled.YiScanner
1517
{
@@ -29,19 +31,19 @@ public static void Main(string[] args)
2931
}
3032

3133
MonitoringConfig config = JsonConvert.DeserializeObject<MonitoringConfig>(File.ReadAllText(Path.Combine(directory, "service.json")));
32-
if (config.Output == null)
34+
if (!config.Validate())
3335
{
34-
log.Error("Output not configured");
36+
log.Error("Invalid configuration");
3537
return;
3638
}
3739

38-
if (config.YiFtp == null)
40+
NetworkScanner scanner = new NetworkScanner(TaskPoolScheduler.Default);
41+
log.Info("Starting {0} version utility...", Assembly.GetExecutingAssembly().GetName().Version);
42+
foreach (var address in scanner.GetLocalIPAddress())
3943
{
40-
log.Error("Yi Ftp not configured");
41-
return;
44+
log.Info("Starting on [{0}]", address);
4245
}
43-
44-
log.Info("Starting {0} version utility...", Assembly.GetExecutingAssembly().GetName().Version);
46+
4547
List<Command> commandsList = new List<Command>();
4648
commandsList.Add(new MonitorCommand(config));
4749
commandsList.Add(new DownloadCommand(config));
@@ -64,7 +66,5 @@ public static void Main(string[] args)
6466
log.Error(ex);
6567
}
6668
}
67-
68-
6969
}
7070
}

src/YiScanner/Server/ServerManager.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.IO;
3+
using System.Reflection;
34
using FubarDev.FtpServer;
45
using FubarDev.FtpServer.AccountManagement;
56
using FubarDev.FtpServer.AccountManagement.Anonymous;
@@ -25,6 +26,11 @@ public ServerManager(ServerConfig config)
2526
this.config = config;
2627
}
2728

29+
public void Dispose()
30+
{
31+
ftpServer?.Dispose();
32+
}
33+
2834
public void Start()
2935
{
3036
log.Debug("Start");
@@ -34,15 +40,10 @@ public void Start()
3440
var provider = new DotNetFileSystemProvider(outPath, false);
3541

3642
// Initialize the FTP server
37-
ftpServer = new FtpServer(provider, membershipProvider, "127.0.0.1");
43+
ftpServer = new FtpServer(provider, membershipProvider, "127.0.0.1", config.Port, new AssemblyFtpCommandHandlerFactory(typeof(FtpServer).GetTypeInfo().Assembly));
3844

3945
// Start the FTP server
4046
ftpServer.Start();
4147
}
42-
43-
public void Dispose()
44-
{
45-
ftpServer?.Dispose();
46-
}
4748
}
4849
}

0 commit comments

Comments
 (0)