Skip to content

Commit a865ed6

Browse files
author
amvanbaren
committed
Finish publisher stats
1 parent 6fb4a33 commit a865ed6

File tree

10 files changed

+91
-209
lines changed

10 files changed

+91
-209
lines changed

server/src/main/java/org/eclipse/openvsx/UserAPI.java

Lines changed: 4 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -347,105 +347,12 @@ public ResponseEntity<UserJson> signPublisherAgreement() {
347347
)
348348
public List<PublisherStatisticsJson> getPublisherStatistics() {
349349
var user = users.findLoggedInUser();
350-
if (users.findLoggedInUser() == null) {
350+
if (user == null) {
351351
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
352352
}
353353

354-
// TODO mock response to develop dashboard
355-
var octYaml = new PublisherStatisticsJson.ExtensionDownloads();
356-
octYaml.setExtensionIdentifier("amvanbaren.yaml");
357-
octYaml.setDownloads(123);
358-
359-
var octYamlTotal = new PublisherStatisticsJson.ExtensionDownloads();
360-
octYamlTotal.setExtensionIdentifier("amvanbaren.yaml");
361-
octYamlTotal.setDownloads(8943);
362-
363-
var octJava = new PublisherStatisticsJson.ExtensionDownloads();
364-
octJava.setExtensionIdentifier("amvanbaren.java");
365-
octJava.setDownloads(837);
366-
367-
var octJavaTotal = new PublisherStatisticsJson.ExtensionDownloads();
368-
octJavaTotal.setExtensionIdentifier("amvanbaren.java");
369-
octJavaTotal.setDownloads(2453);
370-
371-
var octTheme = new PublisherStatisticsJson.ExtensionDownloads();
372-
octTheme.setExtensionIdentifier("amvanbaren.theme");
373-
octTheme.setDownloads(345);
374-
375-
var octThemeTotal = new PublisherStatisticsJson.ExtensionDownloads();
376-
octThemeTotal.setExtensionIdentifier("amvanbaren.theme");
377-
octThemeTotal.setDownloads(9485);
378-
379-
var oct = new PublisherStatisticsJson();
380-
oct.setMonth(10);
381-
oct.setYear(2024);
382-
oct.setExtensionDownloads(List.of(octYaml, octJava, octTheme));
383-
oct.setExtensionTotalDownloads(List.of(octYamlTotal, octJavaTotal, octThemeTotal));
384-
385-
var novYaml = new PublisherStatisticsJson.ExtensionDownloads();
386-
novYaml.setExtensionIdentifier("amvanbaren.yaml");
387-
novYaml.setDownloads(3375);
388-
389-
var novYamlTotal = new PublisherStatisticsJson.ExtensionDownloads();
390-
novYamlTotal.setExtensionIdentifier("amvanbaren.yaml");
391-
novYamlTotal.setDownloads(12318);
392-
393-
var novJava = new PublisherStatisticsJson.ExtensionDownloads();
394-
novJava.setExtensionIdentifier("amvanbaren.java");
395-
novJava.setDownloads(1022);
396-
397-
var novJavaTotal = new PublisherStatisticsJson.ExtensionDownloads();
398-
novJavaTotal.setExtensionIdentifier("amvanbaren.java");
399-
novJavaTotal.setDownloads(3475);
400-
401-
var novTheme = new PublisherStatisticsJson.ExtensionDownloads();
402-
novTheme.setExtensionIdentifier("amvanbaren.theme");
403-
novTheme.setDownloads(10329);
404-
405-
var novThemeTotal = new PublisherStatisticsJson.ExtensionDownloads();
406-
novThemeTotal.setExtensionIdentifier("amvanbaren.theme");
407-
novThemeTotal.setDownloads(19814);
408-
409-
var nov = new PublisherStatisticsJson();
410-
nov.setMonth(11);
411-
nov.setYear(2024);
412-
nov.setExtensionDownloads(List.of(novYaml, novJava, novTheme));
413-
nov.setExtensionTotalDownloads(List.of(novYamlTotal, novJavaTotal, novThemeTotal));
414-
415-
var decYaml = new PublisherStatisticsJson.ExtensionDownloads();
416-
decYaml.setExtensionIdentifier("amvanbaren.yaml");
417-
decYaml.setDownloads(1971);
418-
419-
var decYamlTotal = new PublisherStatisticsJson.ExtensionDownloads();
420-
decYamlTotal.setExtensionIdentifier("amvanbaren.yaml");
421-
decYamlTotal.setDownloads(14289);
422-
423-
var decJava = new PublisherStatisticsJson.ExtensionDownloads();
424-
decJava.setExtensionIdentifier("amvanbaren.java");
425-
decJava.setDownloads(1788);
426-
427-
var decJavaTotal = new PublisherStatisticsJson.ExtensionDownloads();
428-
decJavaTotal.setExtensionIdentifier("amvanbaren.java");
429-
decJavaTotal.setDownloads(5263);
430-
431-
var decTheme = new PublisherStatisticsJson.ExtensionDownloads();
432-
decTheme.setExtensionIdentifier("amvanbaren.theme");
433-
decTheme.setDownloads(3384);
434-
435-
var decThemeTotal = new PublisherStatisticsJson.ExtensionDownloads();
436-
decThemeTotal.setExtensionIdentifier("amvanbaren.theme");
437-
decThemeTotal.setDownloads(23198);
438-
439-
var dec = new PublisherStatisticsJson();
440-
dec.setMonth(12);
441-
dec.setYear(2024);
442-
dec.setExtensionDownloads(List.of(decYaml, decJava, decTheme));
443-
dec.setExtensionTotalDownloads(List.of(decYamlTotal, decJavaTotal, decThemeTotal));
444-
445-
return List.of(oct, nov, dec);
446-
447-
// return repositories.findPublisherStatisticsByUser(user).stream()
448-
// .map(PublisherStatistics::toJson)
449-
// .toList();
354+
return repositories.findPublisherStatisticsByUser(user).stream()
355+
.map(PublisherStatistics::toJson)
356+
.toList();
450357
}
451358
}

server/src/main/java/org/eclipse/openvsx/entities/PublisherStatistics.java

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import org.eclipse.openvsx.json.PublisherStatisticsJson;
1414

1515
import java.util.*;
16-
import java.util.stream.Collectors;
1716

1817
@Entity
1918
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "year", "month"})})
@@ -35,35 +34,22 @@ public class PublisherStatistics {
3534
@ElementCollection(fetch = FetchType.EAGER)
3635
@MapKeyColumn(name = "extension_identifier")
3736
@Column(name = "downloads")
38-
private Map<String, Long> extensionDownlaods;
37+
private Map<String, Long> extensionDownloads;
3938

4039
@ElementCollection(fetch = FetchType.EAGER)
4140
@MapKeyColumn(name = "extension_identifier")
4241
@Column(name = "downloads")
43-
private Map<String, Long> extensionTotalDownlaods;
42+
private Map<String, Long> extensionTotalDownloads;
4443

4544
public PublisherStatisticsJson toJson() {
4645
var json = new PublisherStatisticsJson();
4746
json.setYear(year);
4847
json.setMonth(month);
49-
json.setExtensionDownloads(toExtensionDownloads(extensionDownlaods));
50-
json.setExtensionTotalDownloads(toExtensionDownloads(extensionTotalDownlaods));
51-
48+
json.setExtensionDownloads(extensionDownloads);
49+
json.setExtensionTotalDownloads(extensionTotalDownloads);
5250
return json;
5351
}
5452

55-
private List<PublisherStatisticsJson.ExtensionDownloads> toExtensionDownloads(Map<String, Long> downloads) {
56-
return downloads.entrySet().stream()
57-
.map(entry -> {
58-
var mapping = new PublisherStatisticsJson.ExtensionDownloads();
59-
mapping.setExtensionIdentifier(entry.getKey());
60-
mapping.setDownloads(entry.getValue());
61-
return mapping;
62-
})
63-
.sorted(Comparator.comparingLong(PublisherStatisticsJson.ExtensionDownloads::getDownloads).reversed())
64-
.collect(Collectors.toList());
65-
}
66-
6753
public long getId() {
6854
return id;
6955
}
@@ -96,19 +82,19 @@ public void setMonth(int month) {
9682
this.month = month;
9783
}
9884

99-
public Map<String, Long> getExtensionDownlaods() {
100-
return extensionDownlaods;
85+
public Map<String, Long> getExtensionDownloads() {
86+
return extensionDownloads;
10187
}
10288

103-
public void setExtensionDownlaods(Map<String, Long> extensionDownlaods) {
104-
this.extensionDownlaods = extensionDownlaods;
89+
public void setExtensionDownloads(Map<String, Long> extensionDownloads) {
90+
this.extensionDownloads = extensionDownloads;
10591
}
10692

107-
public Map<String, Long> getExtensionTotalDownlaods() {
108-
return extensionTotalDownlaods;
93+
public Map<String, Long> getExtensionTotalDownloads() {
94+
return extensionTotalDownloads;
10995
}
11096

111-
public void setExtensionTotalDownlaods(Map<String, Long> extensionTotalDownlaods) {
112-
this.extensionTotalDownlaods = extensionTotalDownlaods;
97+
public void setExtensionTotalDownloads(Map<String, Long> extensionTotalDownloads) {
98+
this.extensionTotalDownloads = extensionTotalDownloads;
11399
}
114100
}

server/src/main/java/org/eclipse/openvsx/json/PublisherStatisticsJson.java

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import com.fasterxml.jackson.annotation.JsonInclude;
1313

14-
import java.util.List;
14+
import java.util.Map;
1515

1616
@JsonInclude(JsonInclude.Include.NON_NULL)
1717
public class PublisherStatisticsJson extends ResultJson {
@@ -26,9 +26,9 @@ public static PublisherStatisticsJson error(String message) {
2626

2727
private int month;
2828

29-
private List<ExtensionDownloads> extensionDownloads;
29+
private Map<String, Long> extensionDownloads;
3030

31-
private List<ExtensionDownloads> extensionTotalDownloads;
31+
private Map<String, Long> extensionTotalDownloads;
3232

3333
public int getYear() {
3434
return year;
@@ -46,41 +46,19 @@ public void setMonth(int month) {
4646
this.month = month;
4747
}
4848

49-
public List<ExtensionDownloads> getExtensionDownloads() {
49+
public Map<String, Long> getExtensionDownloads() {
5050
return extensionDownloads;
5151
}
5252

53-
public void setExtensionDownloads(List<ExtensionDownloads> extensionDownloads) {
54-
this.extensionDownloads = extensionDownloads;
53+
public void setExtensionDownloads(Map<String, Long> extensionDownlaods) {
54+
this.extensionDownloads = extensionDownlaods;
5555
}
5656

57-
public List<ExtensionDownloads> getExtensionTotalDownloads() {
57+
public Map<String, Long> getExtensionTotalDownloads() {
5858
return extensionTotalDownloads;
5959
}
6060

61-
public void setExtensionTotalDownloads(List<ExtensionDownloads> extensionTotalDownloads) {
62-
this.extensionTotalDownloads = extensionTotalDownloads;
63-
}
64-
65-
public static class ExtensionDownloads {
66-
private String extensionIdentifier;
67-
68-
private long downloads;
69-
70-
public String getExtensionIdentifier() {
71-
return extensionIdentifier;
72-
}
73-
74-
public void setExtensionIdentifier(String extensionIdentifier) {
75-
this.extensionIdentifier = extensionIdentifier;
76-
}
77-
78-
public long getDownloads() {
79-
return downloads;
80-
}
81-
82-
public void setDownloads(long downloads) {
83-
this.downloads = downloads;
84-
}
61+
public void setExtensionTotalDownloads(Map<String, Long> extensionTotalDownlaods) {
62+
this.extensionTotalDownloads = extensionTotalDownlaods;
8563
}
8664
}

server/src/main/java/org/eclipse/openvsx/statistics/PublisherStatisticsJobRequestHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void run(StatisticsJobRequest jobRequest) throws Exception {
4545
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
4646

4747
var prevStatistics = repositories.findPublisherStatisticsByYearAndMonthAndUser(prevDate.getYear(), prevDate.getMonthValue(), user);
48-
var prevTotalDownloads = prevStatistics != null ? prevStatistics.getExtensionTotalDownlaods() : Collections.<String, Long>emptyMap();
48+
var prevTotalDownloads = prevStatistics != null ? prevStatistics.getExtensionTotalDownloads() : Collections.<String, Long>emptyMap();
4949
var downloads = totalDownloads.entrySet().stream()
5050
.map(e -> {
5151
var prevDownloads = prevTotalDownloads.getOrDefault(e.getKey(), 0L);
@@ -56,8 +56,8 @@ public void run(StatisticsJobRequest jobRequest) throws Exception {
5656
var statistics = new PublisherStatistics();
5757
statistics.setYear(year);
5858
statistics.setMonth(month);
59-
statistics.setExtensionDownlaods(downloads);
60-
statistics.setExtensionTotalDownlaods(totalDownloads);
59+
statistics.setExtensionDownloads(downloads);
60+
statistics.setExtensionTotalDownloads(totalDownloads);
6161
service.savePublisherStatistics(statistics);
6262
}
6363
}

server/src/main/resources/db/migration/V1_50__Publisher_Statistics.sql

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,27 @@ CREATE TABLE public.publisher_statistics(
33
id bigint NOT NULL,
44
user_data bigint NOT NULL,
55
year INT NOT NULL,
6-
month INT NOT NULL,
7-
downloads BIGINT NOT NULL,
8-
downloads_total BIGINT NOT NULL
6+
month INT NOT NULL
97
);
108

119
ALTER TABLE ONLY public.publisher_statistics ADD CONSTRAINT publisher_statistics_pkey PRIMARY KEY (id);
1210
ALTER TABLE ONLY public.publisher_statistics ADD CONSTRAINT fk_publisher_statistics_user_data FOREIGN KEY (user_data) REFERENCES public.user_data(id);
13-
CREATE SEQUENCE publisher_statistics_seq INCREMENT 50 OWNED BY public.publisher_statistics.id;
11+
CREATE SEQUENCE publisher_statistics_seq INCREMENT 50 OWNED BY public.publisher_statistics.id;
12+
13+
CREATE TABLE public.publisher_statistics_extension_downloads(
14+
publisher_statistics_id BIGINT NOT NULL,
15+
extension_identifier CHARACTER VARYING(255) NOT NULL,
16+
downloads BIGINT NOT NULL
17+
);
18+
19+
ALTER TABLE ONLY public.publisher_statistics_extension_downloads
20+
ADD CONSTRAINT publisher_statistics_extension_downloads_fkey FOREIGN KEY (publisher_statistics_id) REFERENCES publisher_statistics(id);
21+
22+
CREATE TABLE public.publisher_statistics_extension_total_downloads(
23+
publisher_statistics_id BIGINT NOT NULL,
24+
extension_identifier CHARACTER VARYING(255) NOT NULL,
25+
downloads BIGINT NOT NULL
26+
);
27+
28+
ALTER TABLE ONLY public.publisher_statistics_extension_total_downloads
29+
ADD CONSTRAINT publisher_statistics_extension_total_downloads_fkey FOREIGN KEY (publisher_statistics_id) REFERENCES publisher_statistics(id);

server/src/test/java/org/eclipse/openvsx/admin/StatisticsJobRequestHandlerTest.java renamed to server/src/test/java/org/eclipse/openvsx/statistics/StatisticsJobRequestHandlerTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* SPDX-License-Identifier: EPL-2.0
99
* ****************************************************************************** */
10-
package org.eclipse.openvsx.admin;
10+
package org.eclipse.openvsx.statistics;
1111

1212
import org.eclipse.openvsx.entities.AdminStatistics;
1313
import org.eclipse.openvsx.repositories.RepositoryService;
@@ -41,7 +41,7 @@ class StatisticsJobRequestHandlerTest {
4141
void testAdminStatisticsJobRequestHandler() throws Exception {
4242
var expectedStatistics = mockAdminStatistics();
4343

44-
var request = new StatisticsJobRequest(2023, 11);
44+
var request = new StatisticsJobRequest(AdminStatisticsJobRequestHandler.class, 2023, 11);
4545
handler.run(request);
4646
Mockito.verify(service).saveAdminStatistics(expectedStatistics);
4747
}
@@ -55,7 +55,7 @@ void testAdminStatisticsJobRequestHandlerWithPreviousStatistics() throws Excepti
5555
prevStatistics.setDownloadsTotal(5000);
5656
Mockito.when(repositories.findAdminStatisticsByYearAndMonth(2023, 10)).thenReturn(prevStatistics);
5757

58-
var request = new StatisticsJobRequest(2023, 11);
58+
var request = new StatisticsJobRequest(AdminStatisticsJobRequestHandler.class, 2023, 11);
5959
handler.run(request);
6060
Mockito.verify(service).saveAdminStatistics(expectedStatistics);
6161
}

webui/src/extension-registry-service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Extension, UserData, ExtensionCategory, ExtensionReviewList, PersonalAccessToken, SearchResult, NewReview,
1313
SuccessResult, ErrorResult, CsrfTokenJson, isError, Namespace, NamespaceDetails, MembershipRole, SortBy,
1414
SortOrder, UrlString, NamespaceMembershipList, PublisherInfo, SearchEntry, RegistryVersion,
15-
PublisherStatistic
15+
PublisherStatistics
1616
} from './extension-registry-types';
1717
import { createAbsoluteURL, addQuery } from './utils';
1818
import { sendRequest, ErrorResponse } from './server-request';
@@ -423,15 +423,15 @@ export class ExtensionRegistryService {
423423
return sendRequest({ abortController, endpoint });
424424
}
425425

426-
async getStatistics(abortController: AbortController): Promise<Readonly<PublisherStatistic[] | ErrorResult>> {
426+
async getStatistics(abortController: AbortController): Promise<Readonly<PublisherStatistics[] | ErrorResult>> {
427427
const csrfResponse = await this.getCsrfToken(abortController);
428428
const headers: Record<string, string> = {};
429429
if (!isError(csrfResponse)) {
430430
const csrfToken = csrfResponse as CsrfTokenJson;
431431
headers[csrfToken.header] = csrfToken.value;
432432
}
433433

434-
return sendRequest<PublisherStatistic[] | ErrorResult>({
434+
return sendRequest<PublisherStatistics[] | ErrorResult>({
435435
abortController,
436436
method: 'GET',
437437
credentials: true,

webui/src/extension-registry-types.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,9 @@ export type MembershipRole = 'contributor' | 'owner';
254254
export type SortBy = 'relevance' | 'timestamp' | 'rating' | 'downloadCount';
255255
export type SortOrder = 'asc' | 'desc';
256256

257-
export interface PublisherStatistic {
258-
year: number;
259-
month: number;
260-
extensionDownloads: ExtensionDownloads[];
261-
extensionTotalDownloads: ExtensionDownloads[];
262-
}
263-
264-
export interface ExtensionDownloads {
265-
extensionIdentifier: string;
266-
downloads: number;
257+
export interface PublisherStatistics {
258+
year: number
259+
month: number
260+
extensionDownloads: Record<string, number>;
261+
extensionTotalDownloads: Record<string, number>;
267262
}

0 commit comments

Comments
 (0)