Skip to content

Commit

Permalink
First working version, seems to missing some results
Browse files Browse the repository at this point in the history
  • Loading branch information
rajbos committed Jul 28, 2019
1 parent 9074ae9 commit 16fc389
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 0 deletions.
25 changes: 25 additions & 0 deletions AzDoExtensionNews/AzDoExtensionNews.sln
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29025.244
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzDoExtensionNews", "AzDoExtensionNews\AzDoExtensionNews.csproj", "{A0A70CF0-421F-41FD-9FE4-BBE51D3A7B4F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A0A70CF0-421F-41FD-9FE4-BBE51D3A7B4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0A70CF0-421F-41FD-9FE4-BBE51D3A7B4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0A70CF0-421F-41FD-9FE4-BBE51D3A7B4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0A70CF0-421F-41FD-9FE4-BBE51D3A7B4F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {20B6B791-FFEA-45FF-B76D-BAF773066E66}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions AzDoExtensionNews/AzDoExtensionNews/AzDoExtensionNews.csproj
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

</Project>
93 changes: 93 additions & 0 deletions AzDoExtensionNews/AzDoExtensionNews/ExtensionDataResult.cs
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace AzDoExtensionNews
{
public class ExtensionDataResult
{
public Result[] results { get; set; }
}

public class Result
{
public Extension[] extensions { get; set; }
public object pagingToken { get; set; }
public Resultmetadata[] resultMetadata { get; set; }
}

public class Extension
{
public Publisher publisher { get; set; }
public string extensionId { get; set; }
public string extensionName { get; set; }
public string displayName { get; set; }
public string flags { get; set; }
public DateTime lastUpdated { get; set; }
public DateTime publishedDate { get; set; }
public DateTime releaseDate { get; set; }
public string shortDescription { get; set; }
public Version[] versions { get; set; }
public string[] categories { get; set; }
public string[] tags { get; set; }
public Statistic[] statistics { get; set; }
public Installationtarget[] installationTargets { get; set; }
public int deploymentType { get; set; }
}

public class Publisher
{
public string publisherId { get; set; }
public string publisherName { get; set; }
public string displayName { get; set; }
public string flags { get; set; }
}

public class Version
{
public string version { get; set; }
public string flags { get; set; }
public DateTime lastUpdated { get; set; }
public File[] files { get; set; }
public Property1[] properties { get; set; }
public string assetUri { get; set; }
public string fallbackAssetUri { get; set; }
}

public class File
{
public string assetType { get; set; }
public string source { get; set; }
}

public class Property1
{
public string key { get; set; }
public string value { get; set; }
}

public class Statistic
{
public string statisticName { get; set; }
public float value { get; set; }
}

public class Installationtarget
{
public string target { get; set; }
public string targetVersion { get; set; }
}

public class Resultmetadata
{
public string metadataType { get; set; }
public Metadataitem[] metadataItems { get; set; }
}

public class Metadataitem
{
public string name { get; set; }
public int count { get; set; }
}

}
98 changes: 98 additions & 0 deletions AzDoExtensionNews/AzDoExtensionNews/Program.cs
@@ -0,0 +1,98 @@
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace AzDoExtensionNews
{
class Program
{
static void Main(string[] args)
{
CheckForUpdates().GetAwaiter().GetResult();

if (Debugger.IsAttached)
{
Log("Hit the return key to close the application");
}
}

private static async Task CheckForUpdates()
{
var maxPages = 22;
// get data
for (int i = 0; i < maxPages; i++)
{
var data = await LoadExtensionDataAsync(pageNumber: i, pageSize: 50);

if (data == null || data.results[0].extensions.Length == 0) return;
LogDataResult(data, pageNumber: i);
}
}

private static void LogDataResult(ExtensionDataResult data, int pageNumber)
{
var extensions = data.results[0].extensions;
Log($"Found {extensions.Length} extensions");
Log("");

for (var i = 0; i < extensions.Length; i++)
{
var extension = extensions[i];
Log($"{(pageNumber * 50 + i):D3} {extension.lastUpdated} {extension.displayName}");
}
// check with stored data
// store new data
// tweet updates

Log($"pagingToken: {data.results[0].pagingToken}");
foreach (var resultMetadata in data.results[0].resultMetadata)
{
var itemText = new StringBuilder();
foreach (var items in resultMetadata.metadataItems)
{
itemText.AppendLine($"name: {items.name}= count:{items.count};");
}
Log($"metadataType: {resultMetadata.metadataType} itemText = {itemText.ToString()}");
}
Log("");
}

private static async Task<ExtensionDataResult> LoadExtensionDataAsync(int pageNumber, int pageSize)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://marketplace.visualstudio.com");

httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Add("accept", "application/json; api-version=5.2-preview.1; excludeUrls=true");

var body = JsonConvert.SerializeObject(RequestBody.GetDefault(pageNumber, pageSize));
var stringContent = new StringContent(body, Encoding.ASCII, "application/json");

Log("Loading data from Azure DevOps");
try
{
var response = await httpClient.PostAsync("_apis/public/gallery/extensionquery", stringContent);

response.EnsureSuccessStatusCode();

var stringResponse = await response.Content.ReadAsStringAsync();
var dataResult = JsonConvert.DeserializeObject<ExtensionDataResult>(stringResponse);

return dataResult;
}
catch (Exception e)
{
Log($"Error loading data: {e.Message}{e.InnerException?.Message}");
return null;
}
}

private static void Log(string message)
{
Console.WriteLine(message);
}
}
}
72 changes: 72 additions & 0 deletions AzDoExtensionNews/AzDoExtensionNews/RequestBody.cs
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace AzDoExtensionNews
{
public class RequestBody
{
public string[] assetTypes { get; set; }
public Filter[] filters { get; set; }
public int flags { get; set; }

public static readonly string RawBody = "{\"assetTypes\":[\"Microsoft.VisualStudio.Services.Icons.Default\",\"Microsoft.VisualStudio.Services.Icons.Branding\",\"Microsoft.VisualStudio.Services.Icons.Small\"],\"filters\":[{\"criteria\":[{\"filterType\":8,\"value\":\"Microsoft.VisualStudio.Services\"},{\"filterType\":8,\"value\":\"Microsoft.VisualStudio.Services.Integration\"},{\"filterType\":8,\"value\":\"Microsoft.VisualStudio.Services.Cloud\"},{\"filterType\":8,\"value\":\"Microsoft.TeamFoundation.Server\"},{\"filterType\":8,\"value\":\"Microsoft.TeamFoundation.Server.Integration\"},{\"filterType\":8,\"value\":\"Microsoft.VisualStudio.Services.Cloud.Integration\"},{\"filterType\":8,\"value\":\"Microsoft.VisualStudio.Services.Resource.Cloud\"},{\"filterType\":10,\"value\":\"target:\\\"Microsoft.VisualStudio.Services\\\" target:\\\"Microsoft.VisualStudio.Services.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Cloud\\\" target:\\\"Microsoft.TeamFoundation.Server\\\" target:\\\"Microsoft.TeamFoundation.Server.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Cloud.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Resource.Cloud\\\" \"},{\"filterType\":12,\"value\":\"37888\"}],\"direction\":2,\"pageSize\":54,\"pageNumber\":2,\"sortBy\":10,\"sortOrder\":0,\"pagingToken\":null}],\"flags\":870}";

public static readonly string RawBody2 = "{\"assetTypes\":],\",{\"filterType\":12,\"value\":\"37888\"}],\"direction\":2,\"pageSize\":5000,\"pageNumber\":0,\"sortBy\":10,\"sortOrder\":0,\"pagingToken\":null}],\"flags\":870}";

public static RequestBody GetDefault(int pageNumber, int pageSize)
{
var body = new RequestBody
{
assetTypes = new string[3]
{
"\"Microsoft.VisualStudio.Services.Icons.Default\"",
"\"Microsoft.VisualStudio.Services.Icons.Branding\"",
"\"Microsoft.VisualStudio.Services.Icons.Small\""
},
filters = new Filter[1]
{
new Filter {
criteria = new Criterion[9]
{
new Criterion { filterType = 8, value = "Microsoft.VisualStudio.Services" } ,
new Criterion { filterType = 8, value = "Microsoft.VisualStudio.Services.Integration" } ,
new Criterion { filterType = 8, value = "Microsoft.VisualStudio.Services.Cloud" } ,
new Criterion { filterType = 8, value = "Microsoft.TeamFoundation.Server" } ,
new Criterion { filterType = 8, value = "Microsoft.TeamFoundation.Server.Integration" } ,
new Criterion { filterType = 8, value = "Microsoft.VisualStudio.Services.Cloud.Integration" } ,
new Criterion { filterType = 8, value = "Microsoft.VisualStudio.Services.Resource.Cloud" } ,
new Criterion { filterType = 10, value = "\"target:\\\"Microsoft.VisualStudio.Services\\\" target:\\\"Microsoft.VisualStudio.Services.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Cloud\\\" target:\\\"Microsoft.TeamFoundation.Server\\\" target:\\\"Microsoft.TeamFoundation.Server.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Cloud.Integration\\\" target:\\\"Microsoft.VisualStudio.Services.Resource.Cloud\\\"" } ,
new Criterion { filterType = 12, value= "37888"}
},
direction = 2,
pageNumber = pageNumber,
pageSize = pageSize,
sortBy = 10,
sortOrder = 0
}
},
flags = 870
};

return body;
}
}

public class Filter
{
public Criterion[] criteria { get; set; }
public int direction { get; set; }
public int pageSize { get; set; }
public int pageNumber { get; set; }
public int sortBy { get; set; }
public int sortOrder { get; set; }
public object pagingToken { get; set; }
}

public class Criterion
{
public int filterType { get; set; }
public string value { get; set; }
}
}

0 comments on commit 16fc389

Please sign in to comment.