-
Notifications
You must be signed in to change notification settings - Fork 3
feat: collect raw application download statistics #321
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
schemas/app-downloads-increment/1.0/app-downloads-increment.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema", | ||
| "$ref": "#/definitions/app-downloads-increment", | ||
|
|
||
| "definitions": { | ||
| "app-downloads-increment": { | ||
| "type": "object", | ||
| "required": [ | ||
| "product", | ||
| "version", | ||
| "tier", | ||
| "count" | ||
| ], | ||
| "additionalProperties": true, | ||
| "properties": { | ||
| "product": { "type": "string" }, | ||
| "version": { "type": "string" }, | ||
| "tier": { "type": "string" }, | ||
| "count": { "type": "integer" } | ||
| } | ||
| } | ||
| } | ||
| } |
28 changes: 28 additions & 0 deletions
28
script/app-downloads-increment/app-downloads-increment.inc.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <?php | ||
| namespace Keyman\Site\com\keyman\api; | ||
|
|
||
| require_once(__DIR__ . '/../../tools/util.php'); | ||
|
|
||
| class AppDownloads { | ||
| static function increment($mssql, $product, $version, $tier) { | ||
|
|
||
| $stmt = $mssql->prepare('EXEC sp_app_downloads_increment :product, :version, :tier'); | ||
| $stmt->bindParam(":product", $product); | ||
| $stmt->bindParam(":version", $version); | ||
| $stmt->bindParam(":tier", $tier); | ||
| $stmt->execute(); | ||
| $data = $stmt->fetchAll(); | ||
| if(count($data) == 0) { | ||
| return NULL; | ||
| } | ||
|
|
||
| $obj = [ | ||
| 'product' => $data[0]['product'], | ||
| 'version' => $data[0]['version'], | ||
| 'tier' => $data[0]['tier'], | ||
| 'count' => intval($data[0]['count']) | ||
| ]; | ||
|
|
||
| return $obj; | ||
| } | ||
| } |
72 changes: 72 additions & 0 deletions
72
script/app-downloads-increment/app-downloads-increment.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| <?php | ||
| require_once(__DIR__ . '/../../tools/util.php'); | ||
|
|
||
| allow_cors(); | ||
| json_response(); | ||
|
|
||
| require_once(__DIR__ . '/app-downloads-increment.inc.php'); | ||
| require_once(__DIR__ . '/../../tools/db/db.php'); | ||
| require_once __DIR__ . '/../../tools/autoload.php'; | ||
|
|
||
| use Keyman\Site\Common\KeymanHosts; | ||
|
|
||
| $mssql = Keyman\Site\com\keyman\api\Tools\DB\DBConnect::Connect(); | ||
| $env = getenv(); | ||
|
|
||
| header('Link: <' . KeymanHosts::Instance()->api_keyman_com .'/schemas/app-downloads-increment/1.0/app-downloads-increment.json#>; rel="describedby"'); | ||
|
|
||
| $AllowGet = isset($_REQUEST['debug']); | ||
|
|
||
| if(!$AllowGet && $_SERVER['REQUEST_METHOD'] != 'POST') { | ||
| fail('POST required'); | ||
| } | ||
|
|
||
| if(!isset($_REQUEST['key'])) { | ||
| fail('key parameter must be set'); | ||
| } | ||
|
|
||
| // Note: we don't currently unit-test this one | ||
| if(KeymanHosts::Instance()->Tier() === KeymanHosts::TIER_DEVELOPMENT) | ||
| $key = 'local'; | ||
| else | ||
| $key = $env['API_KEYMAN_COM_INCREMENT_DOWNLOAD_KEY']; | ||
|
|
||
| if($_REQUEST['key'] !== $key) { | ||
| fail('Invalid key'); | ||
| } | ||
|
|
||
| if(!isset($_REQUEST['product']) || | ||
| !isset($_REQUEST['version']) || | ||
| !isset($_REQUEST['tier']) | ||
| ) { | ||
| // We don't constrain what the product / version / tier may be here, because | ||
| // we may add other products in the future | ||
| fail('product, version, tier parameters must be set'); | ||
| } | ||
|
|
||
| $product = $_REQUEST['product']; | ||
| $version = $_REQUEST['version']; | ||
| $tier = $_REQUEST['tier']; | ||
|
|
||
| /** | ||
| * POST https://api.keyman.com/app-downloads-increment/product/version/tier | ||
| * | ||
| * Increments the download counter for a single product identified by | ||
| * `product`, `version`, and `tier`. Returns the new total count for the | ||
| * product/version/tier for the day | ||
| * | ||
| * https://api.keyman.com/schemas/app-downloads-increment.json is JSON schema | ||
| * | ||
| * @param product the name of the product to increment ( "android", "ios", | ||
| * "linux", "macos", "web", "windows", "developer"...) | ||
| * @param version the version number ("1.2.3") | ||
| * @param tier the tier of the product ("alpha", "beta", "stable") | ||
| * @param key internal key to allow endpoint to run | ||
| */ | ||
|
|
||
| $json = \Keyman\Site\com\keyman\api\AppDownloads::increment($mssql, $product, $version, $tier); | ||
| if($json === NULL) { | ||
| fail("Failed to increment stat, invalid parameters [$product, $version, $tier]?", 401); | ||
| } | ||
|
|
||
| echo json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /* | ||
| sp_app_downloads_increment | ||
| */ | ||
|
|
||
| DROP PROCEDURE IF EXISTS sp_app_downloads_increment; | ||
| GO | ||
|
|
||
| CREATE PROCEDURE sp_app_downloads_increment ( | ||
| @prmProduct NVARCHAR(64), | ||
| @prmVersion NVARCHAR(64), | ||
| @prmTier NVARCHAR(16) | ||
| ) AS | ||
| BEGIN | ||
| SET NOCOUNT ON; | ||
|
|
||
| BEGIN TRANSACTION; | ||
|
|
||
| DECLARE @date DATE, @count INT; | ||
|
|
||
| SET @date = CONVERT(date, GETDATE()); | ||
|
|
||
| UPDATE kstats.t_app_downloads | ||
| WITH (UPDLOCK, SERIALIZABLE) -- ensure that this statement is atomic with following INSERT | ||
| SET count = count + 1, @count = count + 1 | ||
| WHERE product = @prmProduct AND version = @prmVersion AND tier = @prmTier AND statdate = @date; | ||
|
|
||
| IF @@ROWCOUNT = 0 | ||
| BEGIN | ||
| INSERT kstats.t_app_downloads (product, version, tier, statdate, count) | ||
| SELECT @prmProduct, @prmVersion, @prmTier, @date, 1 | ||
| SET @count = 1 | ||
| END | ||
|
|
||
| SET NOCOUNT OFF | ||
|
|
||
| SELECT @prmProduct product, @prmVersion version, @prmTier tier, @count count | ||
|
|
||
| COMMIT TRANSACTION; | ||
| END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| /* | ||
| sp_increment_download | ||
| TODO: rename to sp_keyboard_downloads_increment | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lowpri but more 'namespaced' in the future |
||
| */ | ||
|
|
||
| DROP PROCEDURE IF EXISTS sp_increment_download; | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the internal key get passed here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a POST endpoint and so the key is passed as POST formdata to the .php, not as part of the URL.