Skip to content

Commit

Permalink
Match multiple developer ids, sometimes will work for both ios and an…
Browse files Browse the repository at this point in the history
…droid
  • Loading branch information
ddxv committed Jan 22, 2025
1 parent c3187a1 commit 2e3a84b
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 32 deletions.
43 changes: 38 additions & 5 deletions backend/api_app/controllers/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
Category,
Collection,
DeveloperApps,
PlatformDeveloper,
SDKsDetails,
)
from config import get_logger
Expand Down Expand Up @@ -467,18 +468,50 @@ async def get_developer_apps(self: Self, developer_id: str) -> DeveloperApps:
apps_df = get_single_developer(developer_id)

if apps_df.empty:
msg = f"Store ID not found: {developer_id!r}"
msg = f"Developer ID not found: {developer_id!r}"
raise NotFoundException(
msg,
status_code=404,
)
developer_name = apps_df.to_dict(orient="records")[0]["developer_name"]
apps_dict = apps_df.to_dict(orient="records")

developer_url = apps_df[apps_df["developer_url"].notna()].to_dict(
orient="records"
)[0]["developer_url"]

ios_df = apps_df[apps_df["store"] == "Apple App Store"]
google_df = apps_df[apps_df["store"] == "Google Play"]
if not google_df.empty:
google_developer_name = google_df.to_dict(orient="records")[0][
"developer_name"
]
google_developer_id = google_df.to_dict(orient="records")[0]["developer_id"]
else:
google_developer_name = "Google developer not found"
google_developer_id = None
if not ios_df.empty:
apple_developer_name = ios_df.to_dict(orient="records")[0]["developer_name"]
apple_developer_id = ios_df.to_dict(orient="records")[0]["developer_id"]
else:
apple_developer_name = "Apple developer not found"
apple_developer_id = None
developer_name = google_developer_name or apple_developer_name
google_apps_dict = google_df.to_dict(orient="records")
apple_apps_dict = ios_df.to_dict(orient="records")

developer_apps = DeveloperApps(
developer_id=developer_id,
google=PlatformDeveloper(
developer_id=google_developer_id,
developer_name=google_developer_name,
developer_url=developer_url,
apps=AppGroup(title="Google", apps=google_apps_dict),
),
apple=PlatformDeveloper(
developer_id=apple_developer_id,
developer_name=apple_developer_name,
developer_url=developer_url,
apps=AppGroup(title="Apple", apps=apple_apps_dict),
),
title=developer_name,
apps=apps_dict,
)
duration = round((time.perf_counter() * 1000 - start), 2)
logger.info(f"{self.path}/developers/{developer_id} took {duration}ms")
Expand Down
14 changes: 12 additions & 2 deletions backend/api_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,26 @@ class Category:
google: AppGroup


@dataclass
class PlatformDeveloper:
"""Developer details for a specific platform."""

developer_id: str
developer_name: str
developer_url: str
apps: AppGroup


@dataclass
class DeveloperApps:
"""A developer's list of apps.
Note: This is platform specific.
"""

developer_id: str
google: PlatformDeveloper
apple: PlatformDeveloper
title: str
apps: list[AppDetail]


@dataclass
Expand Down
13 changes: 12 additions & 1 deletion backend/dbcon/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,18 @@ def get_tag_source_totals() -> pd.DataFrame:


def clean_app_df(df: pd.DataFrame) -> pd.DataFrame:
"""Apply generic cleaning for a DF with app data from store_apps table."""
"""Apply generic cleaning for a DF with app data from store_apps table.
Required columns:
- store
- store_id
- developer_id
- installs
- review_count
- rating_count
- rating
"""
df["store"] = df["store"].replace({1: "Google Play", 2: "Apple App Store"})
string_nums = ["installs", "review_count", "rating_count"]
for col in string_nums:
Expand Down
26 changes: 10 additions & 16 deletions backend/dbcon/sql/query_single_developer.sql
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
SELECT
sa.*,
d.name AS developer_name,
pd.url AS developer_url,
d.store AS developer_store
SELECT *
FROM
app_urls_map AS aum
LEFT JOIN pub_domains AS pd
ON
aum.pub_domain = pd.id
LEFT JOIN store_apps AS sa
ON
aum.store_app = sa.id
LEFT JOIN developers AS d
ON
sa.developer = d.id
developer_store_apps
WHERE
d.developer_id = :developer_id;
developer_id = :developer_id
OR domain_id IN (
SELECT DISTINCT dd.domain_id
FROM
developer_store_apps AS dd
WHERE
dd.developer_id = :developer_id
);
4 changes: 2 additions & 2 deletions frontend/src/routes/developers/[developer]/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const load: PageServerLoad = async ({ params, locals }) => {
console.log(`load started developer=${developerValue}`);
try {
return {
results: res
devs: res
.then((resp) => {
if (resp.status === 200) {
return resp.json();
Expand All @@ -32,7 +32,7 @@ export const load: PageServerLoad = async ({ params, locals }) => {
} catch (error) {
console.error('Failed to load data:', error);
return {
results: {},
devs: {},
status: 500,
error: 'Failed to load trending apps'
};
Expand Down
33 changes: 28 additions & 5 deletions frontend/src/routes/developers/[developer]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<svelte:head>
<link rel="canonical" href="https://appgoblin.info/developers/{page.params.developer}" />
{#await data.results then dev}
{#await data.devs then dev}
<title>{dev.title} Android Trends | {page.params.developer} | AppGoblin Developer Data</title>
<meta
name="description"
Expand Down Expand Up @@ -52,17 +52,40 @@
</svelte:head>

<div>
{#await data.results}
{#await data.devs}
<div>
<span>Loading...</span>
</div>
{:then devs}
{#if typeof devs == 'string'}
Failed to load developer
{:else}
<h1 class="h1 p-2">Apps: {devs.title}</h1>
<AppsCard apps={devs} />
<p class="p-2"></p>
<h1 class="h1 p-2">{devs.title}</h1>
<h2 class="h2 p-2">Google Apps: {devs.google.developer_name}</h2>
<p class="p-2">
Matched Developer ID: <a href={`/developers/${devs.google.developer_id}`}
>{devs.google.developer_id}</a
>
<br />
Matched Developer URL:
<a href={devs.google.developer_url} target="_blank" rel="noopener noreferrer">
{devs.google.developer_url}
</a>
</p>
<AppsCard apps={devs.google.apps} />
<hr />
<h2 class="h2 p-2">Apple Apps: {devs.apple.developer_name}</h2>
<p class="p-2">
Matched Developer ID: <a href={`/developers/${devs.apple.developer_id}`}
>{devs.apple.developer_id}</a
>
<br />
Matched Developer URL:
<a href={devs.apple.developer_url} target="_blank" rel="noopener noreferrer">
{devs.apple.developer_url}
</a>
</p>
<AppsCard apps={devs.apple.apps} />
{/if}
{:catch error}
<p style="color: red">{error.message}</p>
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,20 @@ export interface CategoryResponse {
error?: string;
}

export interface PlatformDeveloper {
title: string;
developer_id: string;
developer_name: string;
developer_url: string;
apps: AppGroup;
}

export interface DeveloperResponse {
results: AppGroup;
devs: {
title: string;
google: PlatformDeveloper;
apple: PlatformDeveloper;
};
status?: number;
error?: string;
}
Expand Down

0 comments on commit 2e3a84b

Please sign in to comment.