-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
250 lines (200 loc) · 6.14 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//************************************************************************************************
// Copyright © 2010 Steven M. Cohn. All Rights Reserved.
//************************************************************************************************
namespace CatalogTcx
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
class Program
{
/// <summary>
/// blah blah blah
/// </summary>
/// <param name="args">blah blah blah</param>
static void Main(string[] args)
{
var path = (args.Length == 0 ? "." : args[0]);
// scan for tcx files in the current or specified path
Console.WriteLine();
Console.WriteLine("... scanning files in current directory");
var count = ScanFiles(path, path, true);
Console.WriteLine("... found: " + count.ToString());
// determine if a Garmin USB is mounted
count += ScanGarmin(path);
// scan for Zwift files
Console.WriteLine();
Console.WriteLine("... scanning for Zwift files");
count += ScanZwift(path, true);
Console.WriteLine("... found: " + count);
Console.WriteLine();
Console.Write("... Press any key: ");
Console.ReadKey();
}
private static int ScanFiles(string sourcePath, string targetPath, bool clean)
{
var count = 0;
var dirnam = Path.GetDirectoryName(targetPath);
if (dirnam == null) return 0;
foreach (var filnam in GetFiles(sourcePath, new[] { ".fit", ".tcx" }))
{
var ext = Path.GetExtension(filnam);
if (ext.Equals(".fit"))
{
// TODO: convert fit to tcx
// TODO: set filnam to converted tcx file
}
// open each TCX file and look for its activity start time
XElement root = null;
try
{
// some activities (e.g. heart rate only) show up as HTML instead of XML
root = XElement.Load(filnam);
}
catch
{
Console.WriteLine($" skipping {filnam}");
continue;
}
var ns = root.GetDefaultNamespace();
var lap = (from e in root
.Element(ns + "Activities")?
.Element(ns + "Activity")?
.Elements(ns + "Lap")
where e.Attribute("StartTime") != null
select e).FirstOrDefault();
var startTime = lap?.Attribute("StartTime");
if (startTime == null) continue;
// parse the start time so we can reformat into a filename
var dttm = DateTime.Parse(startTime.Value);
// the year is also used as a directory name
var year = dttm.Year.ToString("0000");
// build the final file name
var stamp = $"{year}{dttm.Month:00}{dttm.Day:00}_{dttm.Hour:00}{dttm.Minute:00}.tcx";
// ensure the archive directory (year name) exists
var dirpath = Path.Combine(dirnam, year);
if (!Directory.Exists(dirpath))
{
Directory.CreateDirectory(dirpath);
}
var target = Path.Combine(dirpath, stamp);
if (File.Exists(target))
{
// delete target so there's no problem overwriting it
File.Delete(target);
}
// save as formatted XML
root.Save(target, SaveOptions.None);
Console.WriteLine(" " + Path.GetFileName(filnam) + " --> " + Path.GetFileName(target));
count++;
// set the timestamps of the file to the activity start time
File.SetCreationTime(target, dttm);
File.SetLastWriteTime(target, dttm);
if (clean)
{
// delete the source
File.Delete(filnam);
}
}
return count;
}
private static int ScanGarmin (string path)
{
int count = 0;
IEnumerable<UsbDisk> disks = null;
try
{
disks = new UsbFactory().GetAvailableDisks();
}
catch
{
// System.Management doesn't work in .NET Core
return count;
}
if ((disks != null) && (disks.Any()))
{
var disk = disks.FirstOrDefault(
e => e.Model.StartsWith("Garmin", StringComparison.InvariantCulture));
if (disk != null)
{
// scan for tcx files on the Garmin, disk.Name would be simply like "G:"
// Edge 820 stores fit files in Garmin\Activities
var sourcePath = disk.Name + @"\Garmin\Activities";
if (!Directory.Exists(sourcePath))
{
// Edge 705 stores tcx files in Garmin\History
sourcePath = disk.Name + @"\Garmin\History";
}
if (Directory.Exists(sourcePath))
{
Console.WriteLine();
Console.WriteLine("... scanning files in " + sourcePath);
count = ScanFiles(sourcePath, path, false);
Console.WriteLine("... found: " + count);
}
}
}
else
{
Console.WriteLine();
Console.WriteLine("... Garmin not found");
}
return count;
}
// gpsbabel -t -i garmin_fit
// -f C:/Users/steven/Documents/Zwift/Activities/2016-12-08-18-33-29.fit
// -o gtrnctr,course=0,sport=Biking
// -F C:/Users/steven/Desktop/qwe.tcx
private static int ScanZwift(string targetPath, bool clean)
{
var dirnam = Path.GetDirectoryName(targetPath);
if (dirnam == null) return 0;
var sourcePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
@"Zwift\Activities");
if (!Directory.Exists(sourcePath)) return 0;
// the year is also used as target directory name
var year = DateTime.Now.Year.ToString("0000");
// ensure the archive directory (year name) exists
var dirpath = Path.Combine(targetPath, year);
if (!Directory.Exists(dirpath))
{
Directory.CreateDirectory(dirpath);
}
var count = 0;
foreach (var filnam in GetFiles(sourcePath, new[] { ".fit" }))
{
var name = Path.GetFileName(filnam);
if (name != null)
{
var target = Path.Combine(dirpath, name);
if (File.Exists(target))
{
// delete target so there's no problem overwriting it
File.Delete(target);
}
if (clean)
{
File.Move(filnam, target);
}
else
{
File.Copy(filnam, target);
}
count++;
// set the timestamps of the file to the activity start time
//File.SetCreationTime(target, dttm);
//File.SetLastWriteTime(target, dttm);
}
}
return count;
}
private static IEnumerable<string> GetFiles(string path, string[] types)
{
return Directory.GetFiles(path)
.Where(file => types.Any(t => t.Equals(Path.GetExtension(file)))).ToList();
}
}
}