more model prep

This commit is contained in:
john liddell
2020-09-04 23:22:36 -05:00
parent ee06f99e25
commit 16c865875c
7 changed files with 202 additions and 152 deletions

View File

@@ -1,7 +1,7 @@
import { WowClientType } from "app/models/warcraft/wow-client-type";
import { WowClientType } from "../../models/warcraft/wow-client-type";
import { Addon } from "../entities/addon";
import { PotentialAddon } from "app/models/wowup/potential-addon";
import { AddonSearchResult } from "app/models/wowup/addon-search-result";
import { PotentialAddon } from "../../models/wowup/potential-addon";
import { AddonSearchResult } from "../../models/wowup/addon-search-result";
export interface AddonProvider {

View File

@@ -11,153 +11,181 @@ import { Observable } from "rxjs";
import { AddonSearchResultFile } from "app/models/wowup/addon-search-result-file";
import { CurseReleaseType } from "app/models/curse/curse-release-type";
import { AddonChannelType } from "app/models/wowup/addon-channel-type";
import { PotentialAddon } from "../../models/wowup/potential-addon";
const API_URL = "https://addons-ecs.forgesvc.net/api/v2";
export class CurseAddonProvider implements AddonProvider {
private readonly _httpClient: HttpClient;
private readonly _httpClient: HttpClient;
public readonly name = "Curse";
public readonly name = "Curse";
constructor(httpClient: HttpClient) {
this._httpClient = httpClient;
}
constructor(httpClient: HttpClient) {
this._httpClient = httpClient;
}
getAll(clientType: WowClientType, addonIds: string[]): Promise<import("../../models/wowup/addon-search-result").AddonSearchResult[]> {
throw new Error("Method not implemented.");
}
getAll(clientType: WowClientType, addonIds: string[]): Promise<import("../../models/wowup/addon-search-result").AddonSearchResult[]> {
throw new Error("Method not implemented.");
}
getFeaturedAddons(clientType: WowClientType): Promise<import("../../models/wowup/potential-addon").PotentialAddon[]> {
throw new Error("Method not implemented.");
}
getFeaturedAddons(clientType: WowClientType): Promise<PotentialAddon[]> {
searchByQuery(query: string, clientType: WowClientType): Promise<import("../../models/wowup/potential-addon").PotentialAddon[]> {
throw new Error("Method not implemented.");
}
}
searchByUrl(addonUri: URL, clientType: WowClientType): Promise<import("../../models/wowup/potential-addon").PotentialAddon> {
throw new Error("Method not implemented.");
}
searchByQuery(query: string, clientType: WowClientType): Promise<import("../../models/wowup/potential-addon").PotentialAddon[]> {
throw new Error("Method not implemented.");
}
searchByName(addonName: string, folderName: string, clientType: WowClientType, nameOverride?: string): Promise<import("../../models/wowup/addon-search-result").AddonSearchResult[]> {
throw new Error("Method not implemented.");
}
searchByUrl(addonUri: URL, clientType: WowClientType): Promise<import("../../models/wowup/potential-addon").PotentialAddon> {
throw new Error("Method not implemented.");
}
getById(addonId: string, clientType: WowClientType): Promise<AddonSearchResult> {
const url = `${API_URL}/addon/${addonId}`;
searchByName(addonName: string, folderName: string, clientType: WowClientType, nameOverride?: string): Promise<import("../../models/wowup/addon-search-result").AddonSearchResult[]> {
throw new Error("Method not implemented.");
}
return this._httpClient.get<CurseSearchResult>(url)
.pipe(
map(result => {
if (!result) {
return null;
}
getById(addonId: string, clientType: WowClientType): Promise<AddonSearchResult> {
const url = `${API_URL}/addon/${addonId}`;
const latestFiles = this.getLatestFiles(result, clientType);
if (!latestFiles?.length) {
return null;
}
return this.getAddonSearchResult(result, latestFiles);
})
)
.toPromise();
}
isValidAddonUri(addonUri: URL): boolean {
throw new Error("Method not implemented.");
}
onPostInstall(addon: Addon): void {
throw new Error("Method not implemented.");
}
private getAddonSearchResult(result: CurseSearchResult, latestFiles: CurseFile[]): AddonSearchResult {
try {
var thumbnailUrl = this.getThumbnailUrl(result);
var id = result.id;
var name = result.name;
var author = this.getAuthor(result);
var searchResultFiles: AddonSearchResultFile[] = latestFiles.map(lf => {
return {
channelType: this.getChannelType(lf.releaseType),
version: lf.fileName,
downloadUrl: lf.downloadUrl,
folders: this.getFolderNames(lf),
gameVersion: this.getGameVersion(lf)
};
});
var searchResult: AddonSearchResult = {
author,
externalId: id.toString(),
name,
thumbnailUrl,
externalUrl: result.websiteUrl,
providerName: this.name,
files: searchResultFiles
};
return searchResult;
} catch (e) {
console.error(e);
return this._httpClient.get<CurseSearchResult>(url)
.pipe(
map(result => {
if (!result) {
return null;
}
}
}
private getChannelType(releaseType: CurseReleaseType): AddonChannelType {
switch (releaseType) {
case CurseReleaseType.Alpha:
return AddonChannelType.Alpha;
case CurseReleaseType.Beta:
return AddonChannelType.Beta;
case CurseReleaseType.Release:
default:
return AddonChannelType.Stable;
}
}
const latestFiles = this.getLatestFiles(result, clientType);
if (!latestFiles?.length) {
return null;
}
private getFolderNames(file: CurseFile): string[] {
return file.modules.map(m => m.foldername);
}
return this.getAddonSearchResult(result, latestFiles);
})
)
.toPromise();
}
private getGameVersion(file: CurseFile): string {
return _.first(file.gameVersion);
}
isValidAddonUri(addonUri: URL): boolean {
throw new Error("Method not implemented.");
}
private getAuthor(result: CurseSearchResult): string {
var authorNames = result.authors.map(a => a.name);
return authorNames.join(', ');
}
onPostInstall(addon: Addon): void {
throw new Error("Method not implemented.");
}
private getThumbnailUrl(result: CurseSearchResult): string {
const attachment = _.find(result.attachments, f => f.isDefault && !!f.thumbnailUrl);
return attachment?.thumbnailUrl;
}
private getAddonSearchResult(result: CurseSearchResult, latestFiles: CurseFile[]): AddonSearchResult {
try {
var thumbnailUrl = this.getThumbnailUrl(result);
var id = result.id;
var name = result.name;
var author = this.getAuthor(result);
private getLatestFiles(result: CurseSearchResult, clientType: WowClientType): CurseFile[] {
const clientTypeStr = this.getClientTypeString(clientType);
var searchResultFiles: AddonSearchResultFile[] = latestFiles.map(lf => {
return {
channelType: this.getChannelType(lf.releaseType),
version: lf.fileName,
downloadUrl: lf.downloadUrl,
folders: this.getFolderNames(lf),
gameVersion: this.getGameVersion(lf)
};
});
return _.flow(
_.filter((f: CurseFile) => f.isAlternate == false && f.gameVersionFlavor == clientTypeStr),
_.orderBy((f: CurseFile) => f.id),
_.reverse
)(result.latestFiles) as CurseFile[];
}
var searchResult: AddonSearchResult = {
author,
externalId: id.toString(),
name,
thumbnailUrl,
externalUrl: result.websiteUrl,
providerName: this.name,
files: searchResultFiles
};
private getClientTypeString(clientType: WowClientType): string {
switch (clientType) {
case WowClientType.Classic:
case WowClientType.ClassicPtr:
return "wow_classic";
case WowClientType.Retail:
case WowClientType.RetailPtr:
case WowClientType.Beta:
default:
return "wow_retail";
}
return searchResult;
} catch (e) {
console.error(e);
return null;
}
}
private getFeaturedAddonList(): Promise<CurseSearchResult[]> {
const url = `${API_URL}/addon/featured`;
const body = {
gameId: 1,
featuredCount: 6,
popularCount: 50,
updatedCount: 0
};
return this._httpClient.post<CurseGetFeaturedResponse>(url, body)
.pipe(
map(result => {
if (!result) {
return null;
}
const latestFiles = this.getLatestFiles(result, clientType);
if (!latestFiles?.length) {
return null;
}
return this.getAddonSearchResult(result, latestFiles);
})
)
.toPromise();
}
private getChannelType(releaseType: CurseReleaseType): AddonChannelType {
switch (releaseType) {
case CurseReleaseType.Alpha:
return AddonChannelType.Alpha;
case CurseReleaseType.Beta:
return AddonChannelType.Beta;
case CurseReleaseType.Release:
default:
return AddonChannelType.Stable;
}
}
private getFolderNames(file: CurseFile): string[] {
return file.modules.map(m => m.foldername);
}
private getGameVersion(file: CurseFile): string {
return _.first(file.gameVersion);
}
private getAuthor(result: CurseSearchResult): string {
var authorNames = result.authors.map(a => a.name);
return authorNames.join(', ');
}
private getThumbnailUrl(result: CurseSearchResult): string {
const attachment = _.find(result.attachments, f => f.isDefault && !!f.thumbnailUrl);
return attachment?.thumbnailUrl;
}
private getLatestFiles(result: CurseSearchResult, clientType: WowClientType): CurseFile[] {
const clientTypeStr = this.getClientTypeString(clientType);
return _.flow(
_.filter((f: CurseFile) => f.isAlternate == false && f.gameVersionFlavor == clientTypeStr),
_.orderBy((f: CurseFile) => f.id),
_.reverse
)(result.latestFiles) as CurseFile[];
}
private getClientTypeString(clientType: WowClientType): string {
switch (clientType) {
case WowClientType.Classic:
case WowClientType.ClassicPtr:
return "wow_classic";
case WowClientType.Retail:
case WowClientType.RetailPtr:
case WowClientType.Beta:
default:
return "wow_retail";
}
}
}

View File

@@ -1,18 +1,19 @@
import { Injectable } from "@angular/core";
import { WowClientType } from "app/models/warcraft/wow-client-type";
import { WowClientType } from "../../../models/warcraft/wow-client-type";
import { AddonStorageService } from "../storage/addon.storage.service";
import { Addon } from "app/core/entities/addon";
import { Addon } from "../../entities/addon";
import { WarcraftService } from "../warcraft/warcraft.service";
import { AddonProvider } from "app/core/addon-providers/addon-provider";
import { CurseAddonProvider } from "app/core/addon-providers/curse-addon-provider";
import { AddonProvider } from "../../addon-providers/addon-provider";
import { CurseAddonProvider } from "../../addon-providers/curse-addon-provider";
import { HttpClient } from "@angular/common/http";
import { AddonSearchResult } from "app/models/wowup/addon-search-result";
import { AddonSearchResultFile } from "app/models/wowup/addon-search-result-file";
import { AddonChannelType } from "app/models/wowup/addon-channel-type";
import { AddonSearchResult } from "../../../models/wowup/addon-search-result";
import { AddonSearchResultFile } from "../../../models/wowup/addon-search-result-file";
import { AddonChannelType } from "../../../models/wowup/addon-channel-type";
import * as _ from 'lodash';
import * as uuid from 'uuid';
import { AddonFolder } from "app/models/wowup/addon-folder";
import { AddonFolder } from "../../../models/wowup/addon-folder";
import { WowUpApiService } from "../wowup-api/wowup-api.service";
import { PotentialAddon } from "../../../models/wowup/potential-addon";
@Injectable({
providedIn: 'root'
@@ -51,6 +52,11 @@ export class AddonService {
return addons;
}
public async getFeaturedAddons(clientType: WowClientType) : Promise<PotentialAddon[]>{
const results = await Promise.all(this._addonProviders.map(p => p.getFeaturedAddons(clientType)));
return results.flat(1);
}
private getAllStoredAddons(clientType: WowClientType) {
const addons: Addon[] = [];

View File

@@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { WowClientType } from '../models/warcraft/wow-client-type';
import { AddonService } from '../core/services/addons/addon.service';
@Component({
selector: 'app-get-addons',
@@ -22,12 +24,21 @@ export class GetAddonsComponent implements OnInit {
{ position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' },
];
public selectedClient = 'retail';
public query = '';
public selectedClient = WowClientType.Classic;
constructor() { }
constructor(
private _addonService: AddonService
) { }
ngOnInit(): void {
}
private loadPopularAddons(){
if(this.selectedClient === WowClientType.None){
return;
}
}
}

View File

@@ -0,0 +1,7 @@
import { CurseSearchResult } from './curse-search-result';
export interface CurseGetFeaturedResponse {
featured: CurseSearchResult[];
popular: CurseSearchResult[];
recentlyUpdated: CurseSearchResult[];
}

View File

@@ -3,5 +3,6 @@ export enum WowClientType {
Classic,
RetailPtr,
ClassicPtr,
Beta
Beta,
None
}

View File

@@ -1,12 +1,12 @@
import { Component, OnInit } from '@angular/core';
import { WarcraftService } from 'app/core/services/warcraft/warcraft.service';
import { WowClientType } from 'app/models/warcraft/wow-client-type';
import { AddonService } from 'app/core/services/addons/addon.service';
import { WarcraftService } from '../core/services/warcraft/warcraft.service';
import { WowClientType } from '../models/warcraft/wow-client-type';
import { AddonService } from '../core/services/addons/addon.service';
import { first, tap } from 'rxjs/operators';
import { from, BehaviorSubject } from 'rxjs';
import { Addon } from 'app/core/entities/addon';
import { AddonTableColumnComponent } from 'app/components/addon-table-column/addon-table-column.component';
import { AddonStatusColumnComponent } from 'app/components/addon-status-column/addon-status-column.component';
import { Addon } from '../core/entities/addon';
import { AddonTableColumnComponent } from '../components/addon-table-column/addon-table-column.component';
import { AddonStatusColumnComponent } from '../components/addon-status-column/addon-status-column.component';
@Component({
selector: 'app-my-addons',
@@ -77,7 +77,7 @@ export class MyAddonsComponent implements OnInit {
this.warcraftService.clientTypes$
.pipe(
first(types => Array.isArray(types) && types.length > 0),
tap(() => this.loadAddons())
tap(() => this.loadAddons(this.selectedClient))
)
.subscribe(types => this.selectedClient = types[0]);
@@ -87,27 +87,24 @@ export class MyAddonsComponent implements OnInit {
}
onReScan() {
this.loadAddons(true)
this.loadAddons(this.selectedClient, true)
}
onClientChange() {
this.busy = true;
console.log(this.selectedClient);
this.busy = false;
this.loadAddons(this.selectedClient, false);
}
onGridReady(params) {
this.gridApi = params.api;
this.gridApi.sizeColumnsToFit();
}
private loadAddons(rescan: boolean = false) {
private loadAddons(clientType: WowClientType, rescan: boolean = false) {
this.busy = true;
console.log('Load-addons')
console.log('Load-addons', clientType);
from(this.addonService.getAddons(this.selectedClient, rescan))
from(this.addonService.getAddons(clientType, rescan))
.subscribe((addons) => {
this.busy = false;
this.formatAddons(addons);