diff --git a/helpers/app-store/genres.js b/helpers/app-store/genres.js new file mode 100644 index 0000000..ab11d51 --- /dev/null +++ b/helpers/app-store/genres.js @@ -0,0 +1,76 @@ +export default { + '0': ['Mobile Software Application'], + '6018': ['Book'], + '6000': ['Business'], + '6022': ['Catalogs'], + '6017': ['Education'], + '6016': ['Entertainment'], + '6015': ['Finance'], + '6023': ['Food & Drink'], + '6014': ['Games'], + '7001': ['Games', 'Action'], + '7002': ['Games', 'Adventure'], + '7003': ['Games', 'Arcade'], + '7004': ['Games', 'Board'], + '7005': ['Games', 'Card'], + '7006': ['Games', 'Casino'], + '7007': ['Games', 'Dice'], + '7008': ['Games', 'Educational'], + '7009': ['Games', 'Family'], + '7011': ['Games', 'Music'], + '7012': ['Games', 'Puzzle'], + '7013': ['Games', 'Racing'], + '7014': ['Games', 'Role Playing'], + '7015': ['Games', 'Simulation'], + '7016': ['Games', 'Sports'], + '7017': ['Games', 'Strategy'], + '7018': ['Games', 'Trivia'], + '7019': ['Games', 'Word'], + '6013': ['Health & Fitness'], + '6012': ['Lifestyle'], + '6020': ['Medical'], + '6011': ['Music'], + '6010': ['Navigation'], + '6009': ['News'], + '6021': ['Newsstand'], + '6008': ['Photo & Video'], + '6007': ['Productivity'], + '6006': ['Reference'], + '6024': ['Shopping'], + '6005': ['Social Networking'], + '6004': ['Sports'], + '6025': ['Stickers'], + '6003': ['Travel'], + '6002': ['Utilities'], + '6001': ['Weather'], + '6026': ['Developer Tools'], + '6027': ['Graphics & Design'], + '13001': ['Newsstand', 'News & Politics'], + '13002': ['Newsstand', 'Fashion & Style'], + '13003': ['Newsstand', 'Home & Garden'], + '13004': ['Newsstand', 'Outdoors & Nature'], + '13005': ['Newsstand', 'Sports & Leisure'], + '13006': ['Newsstand', 'Automotive'], + '13007': ['Newsstand', 'Arts & Photography'], + '13008': ['Newsstand', 'Brides & Weddings'], + '13009': ['Newsstand', 'Business & Investing'], + '13010': ['Newsstand', 'Children\'s Magazines'], + '13011': ['Newsstand', 'Computers & Internet'], + '13012': ['Newsstand', 'Cooking, Food & Drink'], + '13013': ['Newsstand', 'Crafts & Hobbies'], + '13014': ['Newsstand', 'Electronics & Audio'], + '13015': ['Newsstand', 'Entertainment'], + '13017': ['Newsstand', 'Health, Mind & Body'], + '13018': ['Newsstand', 'History'], + '13019': ['Newsstand', 'Literary Magazines & Journals'], + '13020': ['Newsstand', 'Men\'s Interest'], + '13021': ['Newsstand', 'Movies & Music'], + '13023': ['Newsstand', 'Parenting & Family'], + '13024': ['Newsstand', 'Pets'], + '13025': ['Newsstand', 'Professional & Trade'], + '13026': ['Newsstand', 'Regional News'], + '13027': ['Newsstand', 'Science'], + '13028': ['Newsstand', 'Teens'], + '13029': ['Newsstand', 'Travel & Regional'], + '13030': ['Newsstand', 'Women\'s Interest'], +} diff --git a/helpers/build-app-list.js b/helpers/build-app-list.js index 42eafa1..2a4906b 100644 --- a/helpers/build-app-list.js +++ b/helpers/build-app-list.js @@ -5,6 +5,7 @@ import slugify from 'slugify' import axios from 'axios' import statuses, { getStatusName } from './statuses' +import appStoreGenres from './app-store/genres.js' import parseDate from './parse-date' import { eitherMatches } from './matching.js' import { getAppEndpoint } from './app-derived' @@ -98,6 +99,41 @@ const lookForLastUpdated = function (app, commits) { return null } +// Fetch list of genres for each bundle +async function fetchBundleGenres () { + const genresJsonUrl = `${process.env.VFUNCTIONS_URL}/app-store/listings-sheet?fields=bundleId,genreIds` + + return await axios.get( genresJsonUrl ) + .then( response => { + return new Map( response.data.apps ) + }) + .catch(function (error) { + // handle error + console.warn('Error fetching bundle genres', error) + }) +} + + +function generateTagsFromGenres( bundleId, bundleGenres ) { + // If we don't have this bundleID + // then return empty + if ( !bundleGenres.has( bundleId ) ) return [] + + const genres = new Set() + + bundleGenres.get( bundleId ).split(',').forEach( genreId => { + if ( !appStoreGenres.hasOwnProperty(genreId) ) { + console.warn('Not known genre ID', genreId) + } + + appStoreGenres[genreId].forEach( genreName => { + genres.add(genreName) + }) + }) + + return genres +} + export default async function () { @@ -113,6 +149,7 @@ export default async function () { // Save commits to file just in case // await fs.writeFile('./commits-data.json', JSON.stringify(commits)) + const bundleGenres = await fetchBundleGenres() const scanListMap = new Map() @@ -154,10 +191,15 @@ export default async function () { href: 'https://doesitarm.com/apple-silicon-app-test/', }) + // console.log('appScan', appScan) + + const tags = generateTagsFromGenres( appScan.bundleIdentifier, bundleGenres ) + // Add to scanned app list scanListMap.set( appSlug, { name: appName, aliases: appScan['aliases'], + bundleId: appScan.bundleIdentifier, status: statusName, lastUpdated: parseDate( appScan['Date'] ), // url, @@ -172,6 +214,7 @@ export default async function () { category: { slug: 'uncategorized' }, + tags, relatedLinks }) }) @@ -236,14 +279,27 @@ export default async function () { const [ name, url ] = link.substring(1, link.length-1).split('](') + let bundleId = null + let tags = [] + // Search for this app in the scanList and remove duplicates scanListMap.forEach( ( scannedApp, key ) => { - for ( const alias of scannedApp.aliases) { + for ( const alias of scannedApp.aliases ) { // console.log( key, alias, name, eitherMatches(alias, name) ) if ( eitherMatches(alias, name) ) { - console.log(`Removing ${alias} from scanned apps`) + // If we don't have a bundleId yet + // Set this app's bundleId + if ( bundleId === null ) { bundleId = scannedApp.bundleId } + + // Merge this scanned app's tags into the matching app + tags = Array.from(new Set([ + ...tags, + ...scannedApp.tags + ])) + + console.log(`Merged ${alias} (${scannedApp.bundleId}) from scanned apps into ${name} from README`) scanListMap.delete( key ) } } @@ -285,15 +341,22 @@ export default async function () { appList.push({ name, status, + bundleId, lastUpdated, // url, text, slug: appSlug, endpoint, category, + tags, // content: token.content, - relatedLinks + relatedLinks, }) + + + // if ( tags.length > 1 ) { + // console.log('tags', name, bundleId, tags) + // } } // appList[categorySlug]