def get_apps(self, appid_filter=None, fetch_images=True):
        ''' Parse the badge pages, add app info (like name and icon) if needed
            fetch and store the icons and cache app info in shelve.

            Return a dict of all apps on badges page (with and without remaining drops):
            {<appid>: <App istance>, <appid>: <App instance>, ...}
        '''
        appid_filter = appid_filter or []
        apps = self.parse_badges_pages(appid_filter)
        #apps = mockSome()

        # check for appids not in shelve
        appshelve = shelve.open(self.shelve_path)
        appids_not_in_shelve = []
        for appid in apps.keys():
            if str(appid) in appshelve:
                # Load aditional app info from shelve
                a = appshelve[str(appid)]
                apps[appid].name = a['name']
            else:
                appids_not_in_shelve.append(str(appid))

        if appids_not_in_shelve:
            # GetAppInfo only returns info for 100 apps at once
            # TODO: Call https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/ with access_token instead?
            # params = {'access_token': self.swb.oauth_access_token, 'appids_filter': ','.join(appids_not_in_shelve), 'steamid': swb.steamid, 'format': 'json', 'include_appinfo': 1}

            appinfos = []
            self.logger.debug('Requesting %d appids from GetAppInfo:', len(appids_not_in_shelve))
            for appid_chunk in chunks(appids_not_in_shelve, 100):
                params = {
                    'access_token': self.swb.oauth_access_token,
                    'appids': ','.join(appid_chunk)
                }
                self.logger.debug('Requesting a chunk of %d appids from GetAppInfo:', len(appid_chunk))
                r = self.swb.get('https://api.steampowered.com/ISteamGameOAuth/GetAppInfo/v1/', params=params)
                ainfo = r.json().get('apps', [])
                appinfos.extend(ainfo)
                self.logger.debug('GetAppInfo returned data for %d appids:', len(ainfo))

            if fetch_images is True:
                # Retrieve and store icon and logosmall
                tasks = multiprocessing.JoinableQueue()
                num_consumers = multiprocessing.cpu_count() * 2

                consumers = []
                for _i in range(num_consumers):
                    c = FetchImages(tasks, self.image_path)
                    c.start()
                    consumers.append(c)

                for appinfo in appinfos:
                    tasks.put(appinfo)

                # Add a poison pill for each consumer
                for _i in range(num_consumers):
                    tasks.put(None)

                # Wait for all of the tasks to finish
                tasks.join()

            # Merge new data with data from shelve and store new values
            for appinfo in appinfos:
                appid = appinfo.get('appid')
                name = appinfo.get('name')
                apps[appid].name = name
                # Store in shelve
                data = {
                    'name': name,
                }
                appshelve[str(appid)] = data

        appshelve.close()
        return apps
Parse the badge pages, add app info (like name and icon) if needed
            fetch and store the icons and cache app info in shelve.

            Return a dict of all apps on badges page (with and without remaining drops):
            {<appid>: <App istance>, <appid>: <App instance>, ...}