Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Konrad Żaba committed Dec 13, 2020
1 parent a8e815d commit d7770bd
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 0 deletions.
25 changes: 25 additions & 0 deletions Strava.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1231
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strava", "Strava\Strava.csproj", "{1D30A9D5-4481-49EC-ABEC-C458AE41013B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1D30A9D5-4481-49EC-ABEC-C458AE41013B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D30A9D5-4481-49EC-ABEC-C458AE41013B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D30A9D5-4481-49EC-ABEC-C458AE41013B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D30A9D5-4481-49EC-ABEC-C458AE41013B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4A629EB7-EA5A-4E1E-BE83-C244640BB2C4}
EndGlobalSection
EndGlobal
19 changes: 19 additions & 0 deletions Strava/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="ClientId" value="" />
<add key="ClientSecret" value="" />
<add key="FolderWithTcx" value="" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
167 changes: 167 additions & 0 deletions Strava/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using Newtonsoft.Json;
using Strava.Api;
using Strava.Authentication;
using Strava.Clients;
using Strava.Upload;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace Strava
{
class Program
{
static string ClientId { get; set; }
static string ClientSecret { get; set; }
static string FolderWithTcx { get; set; }

//You can also provide it here, if you don't want to mess around with UI
static string AuthCode = string.Empty;

static void Main(string[] args)
{
#region settings

if (!ReadClientSettings())
{
//prompt and save to file
ClientId = ShowInputBox("Provide your Strava Client ID", "Configuration");
ClientSecret = ShowInputBox("Provide your Strava Client Secret", "Configuration");
FolderWithTcx = ShowInputBox("Provide path to folder with TCX files", "Configuration");

if (string.IsNullOrEmpty(ClientId) || string.IsNullOrEmpty(ClientSecret))
{
Environment.Exit(0);
}
SetSetting(GetPropertyName(() => ClientId), ClientId);
SetSetting(GetPropertyName(() => ClientSecret), ClientSecret);
SetSetting(GetPropertyName(() => FolderWithTcx), FolderWithTcx);
}
Console.WriteLine("Configuration values - OK");
#endregion

#region authentication

System.Diagnostics.Process.Start(
$"https://www.strava.com/oauth/mobile/authorize?client_id={ClientId}&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&approval_prompt=auto&scope=activity%3Awrite%2Cread&state=test");

if (string.IsNullOrEmpty(AuthCode))
{
AuthCode = ShowInputBox("Provide your Strava Auth Code","Configuration");
}

#endregion

string[] files = Directory.GetFiles(FolderWithTcx, "*.tcx");
Console.WriteLine($"Found {files.Count()} TCX files to process.");

HttpClient httpClient = new HttpClient();

var values = new Dictionary<string, string>
{
{ "client_id", ClientId },
{ "client_secret", ClientSecret },
{ "code", AuthCode },
{ "grant_type", "authorization_code" }
};

try
{
var content = new FormUrlEncodedContent(values);
var response = httpClient.PostAsync("https://www.strava.com/api/v3/oauth/token", content).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
dynamic objects = JsonConvert.DeserializeObject(responseString);
string token = objects["access_token"];
if (!string.IsNullOrEmpty(token))
Console.WriteLine("Authentication - OK");
else Console.WriteLine("Authentication - FAILURE");

StaticAuthentication auth = new StaticAuthentication(token);
StravaClient client = new StravaClient(auth);

Console.WriteLine("If you see nothing below for a longer period - try again after 15 minutes.");

foreach (var item in files)
{
var task =
Task.Run(async () =>
{
UploadStatus status = await client.Uploads.UploadActivityAsync(item, DataFormat.Tcx);
Thread.Sleep(2000);
UploadStatusCheck check = new UploadStatusCheck(token, status.Id.ToString());

check.UploadChecked += delegate (object o, UploadStatusCheckedEventArgs args2)
{
Console.WriteLine($"{args2.Status} {item} || Limit {Limits.Limit.ShortTerm} {Limits.Usage.ShortTerm}");
if (args2.Status == CurrentUploadStatus.Ready)
{
File.Delete(item);
}
};

check.Start();
});

task.Wait();
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
Console.Read();
}
}

private static bool ReadClientSettings()
{
ClientId = GetSetting(GetPropertyName(() => ClientId));
ClientSecret = GetSetting(GetPropertyName(() => ClientSecret));
FolderWithTcx = GetSetting(GetPropertyName(() => FolderWithTcx));

if (string.IsNullOrEmpty(ClientId) || string.IsNullOrEmpty(ClientSecret) || string.IsNullOrEmpty(FolderWithTcx))
return false;

return true;
}

private static string GetSetting(string key)
{
return ConfigurationManager.AppSettings[key];
}

private static void SetSetting(string key, string value)
{
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configuration.AppSettings.Settings[key].Value = value;
configuration.Save(ConfigurationSaveMode.Full, true);
ConfigurationManager.RefreshSection("appSettings");
}

private static string GetPropertyName(Expression<Func<string>> expr)
{
var member = expr.Body as MemberExpression;
if (member == null)
throw new InvalidOperationException("Expression is not a member access expression.");
var property = member.Member as PropertyInfo;
if (property == null)
throw new InvalidOperationException("Member in expression is not a property.");
return property.Name;
}

private static string ShowInputBox(string prompt, string title)
{
return Microsoft.VisualBasic.Interaction.InputBox(prompt,
title,
string.Empty,
0,
0);
}
}
}
36 changes: 36 additions & 0 deletions Strava/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Strava")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Strava")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1d30a9d5-4481-49ec-abec-c458ae41013b")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
62 changes: 62 additions & 0 deletions Strava/Strava.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1D30A9D5-4481-49EC-ABEC-C458AE41013B}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Strava</RootNamespace>
<AssemblyName>Strava</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="StravaDotNet, Version=3.4.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Strava.NET.3.4.4\lib\net46\StravaDotNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
5 changes: 5 additions & 0 deletions Strava/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
<package id="Strava.NET" version="3.4.4" targetFramework="net461" />
</packages>

0 comments on commit d7770bd

Please sign in to comment.