Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include download stats #14

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions PluginBuilder/APIModels/PublishedVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class PublishedVersion
public string ProjectSlug { get; set; }
public string Version { get; set; }
public long BuildId { get; set; }
public long DownloadStat { get; set; }
public JObject BuildInfo { get; set; }
public JObject ManifestInfo { get; set; }
public string Documentation { get; set; }
Expand Down
46 changes: 44 additions & 2 deletions PluginBuilder/Controllers/ApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ public IActionResult GetVersion()
});
}

[AllowAnonymous]
[HttpGet("testfunctions")]
public async Task<IActionResult> TestFunctions([ModelBinder(typeof(PluginVersionModelBinder))] PluginVersion? btcpayVersion = null)
TChukwuleta marked this conversation as resolved.
Show resolved Hide resolved
{
bool includePreRelease = false;
bool includeAllVersions = false;
var getVersions = includeAllVersions switch
{
true => "get_all_versions",
false => "get_latest_versions"
};
await using var conn = await ConnectionFactory.Open();
// This query probably doesn't have right indexes
var rows = await conn.QueryAsync(
$"SELECT lv.download_stat FROM {getVersions}(@btcpayVersion, @includePreRelease) lv ",
new
{
includePreRelease = includePreRelease,
btcpayVersion = btcpayVersion?.VersionParts,
});
return Ok(rows);
}

[AllowAnonymous]
[HttpGet("plugins")]
public async Task<IActionResult> Plugins(
Expand All @@ -70,10 +93,11 @@ public async Task<IActionResult> Plugins(
};
await using var conn = await ConnectionFactory.Open();
// This query probably doesn't have right indexes
var rows = await conn.QueryAsync<(string plugin_slug, int[] ver, string settings, long id, string manifest_info, string build_info)>(
$"SELECT lv.plugin_slug, lv.ver, p.settings, b.id, b.manifest_info, b.build_info FROM {getVersions}(@btcpayVersion, @includePreRelease) lv " +
var rows = await conn.QueryAsync<(string plugin_slug, int[] ver, string settings, long id, string manifest_info, string build_info, long download_stat)>(
$"SELECT lv.plugin_slug, lv.ver, p.settings, b.id, b.manifest_info, b.build_info, v.download_stat FROM {getVersions}(@btcpayVersion, @includePreRelease) lv " +
"JOIN builds b ON b.plugin_slug = lv.plugin_slug AND b.id = lv.build_id " +
"JOIN plugins p ON b.plugin_slug = p.slug " +
"JOIN versions v ON v.plugin_slug = lv.plugin_slug " +
"WHERE b.manifest_info IS NOT NULL AND b.build_info IS NOT NULL " +
"ORDER BY manifest_info->>'Name'",
new
Expand All @@ -88,6 +112,7 @@ public async Task<IActionResult> Plugins(
var v = new PublishedVersion
{
ProjectSlug = r.plugin_slug,
DownloadStat = r.download_stat,
Version = string.Join('.', r.ver),
BuildId = r.id,
BuildInfo = JObject.Parse(r.build_info),
Expand Down Expand Up @@ -126,6 +151,23 @@ public async Task<IActionResult> Download(
return Redirect(url);
}

[AllowAnonymous]
[HttpPost("plugins/{pluginSlug}/record-download")]
public async Task<IActionResult> RecordDownload(string pluginSlug, string? action = null, string? version = null)
{
await using var conn = await ConnectionFactory.Open();
var count = await conn.ExecuteScalarAsync<int>(
"SELECT COUNT(*) FROM versions v WHERE v.plugin_slug = @plugin_slug AND v.pre_release IS FALSE",
new { plugin_slug = pluginSlug }
);

if (count == 0)
return NotFound();

await conn.RecordPluginDownloadStatistics(pluginSlug, action, version);
return Ok("Download statistics recorded successfully");
}

[HttpPost("plugins/{pluginSlug}/builds")]
public async Task<IActionResult> CreateBuild(
[ModelBinder(typeof(PluginSlugModelBinder))] PluginSlug pluginSlug,
Expand Down
1 change: 1 addition & 0 deletions PluginBuilder/Data/Scripts/10.VersionDownloadStat.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE versions ADD COLUMN download_stat BIGINT NOT NULL DEFAULT 0;
33 changes: 33 additions & 0 deletions PluginBuilder/NpgsqlConnectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
using System;
using Dapper;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
Expand Down Expand Up @@ -195,5 +196,37 @@ public static Task<long> NewBuild(this NpgsqlConnection connection, PluginSlug p
buildInfo = bi.ToString()
});
}

public static async Task RecordPluginDownloadStatistics(this NpgsqlConnection connection, PluginSlug pluginSlug, string action, string? version = null)
{
int[] versionArray = version?.Split('.').Select(int.Parse).ToArray();
string sql;
if (versionArray != null)
{
sql = action.ToLower() switch
{
"install" => "UPDATE versions AS v SET download_stat = v.download_stat + 1 WHERE v.pre_release IS FALSE AND plugin_slug = @plugin_slug AND ver = @version;",
"delete" => "UPDATE versions AS v SET download_stat = GREATEST(v.download_stat - 1, 0) WHERE v.pre_release IS FALSE AND plugin_slug = @plugin_slug AND ver = @version;",
_ => null
};
}
else
{
sql = action.ToLower() switch
{
"install" => "UPDATE versions AS v SET download_stat = v.download_stat + 1 WHERE v.pre_release IS FALSE AND plugin_slug = @plugin_slug AND ver = (SELECT MAX(ver) FROM versions WHERE plugin_slug = @plugin_slug AND pre_release IS FALSE);",
"delete" => "UPDATE versions AS v SET download_stat = GREATEST(v.download_stat - 1, 0) WHERE v.pre_release IS FALSE AND plugin_slug = @plugin_slug AND ver = (SELECT MAX(ver) FROM versions WHERE plugin_slug = @plugin_slug AND pre_release IS FALSE);",
_ => null
};
}
if (sql != null)
{
await connection.ExecuteAsync(sql, new
{
plugin_slug = pluginSlug.ToString(),
version = versionArray
});
}
}
}
}