':param categories: The categories of coming episodes. See ``ComingEpisodes.categories``
:param sort: The sort to apply to the coming episodes. See ``ComingEpisodes.sorts``
:param group: ``True`` to group the coming episodes by category, ``False`` otherwise
:param paused: ``True`` to include paused shows, ``False`` otherwise
:return: The list of coming episodes'

@staticmethod
def get_coming_episodes(categories, sort, group, paused=False):

    paused = (sickrage.srCore.srConfig.COMING_EPS_DISPLAY_PAUSED or paused)
    if (not isinstance(categories, list)):
        categories = categories.split(u'|')
    if (sort not in ComingEpisodes.sorts.keys()):
        sort = u'date'
    today = datetime.date.today().toordinal()
    next_week = (datetime.date.today() + datetime.timedelta(days=7)).toordinal()
    recently = (datetime.date.today() - datetime.timedelta(days=sickrage.srCore.srConfig.COMING_EPS_MISSED_RANGE)).toordinal()
    qualities_list = (((((Quality.DOWNLOADED + Quality.SNATCHED) + Quality.SNATCHED_BEST) + Quality.SNATCHED_PROPER) + Quality.ARCHIVED) + Quality.IGNORED)
    results = []
    for s in [s[u'doc'] for s in sickrage.srCore.mainDB.db.all(u'tv_shows', with_doc=True)]:
        for e in [e[u'doc'] for e in sickrage.srCore.mainDB.db.get_many(u'tv_episodes', s[u'indexer_id'], with_doc=True) if ((e[u'doc'][u'season'] != 0) and (today <= e[u'doc'][u'airdate'] < next_week) and (e[u'doc'][u'status'] not in qualities_list))]:
            results += [{u'airdate': e[u'airdate'], u'airs': s[u'airs'], u'description': e[u'description'], u'episode': e[u'episode'], u'imdb_id': s[u'imdb_id'], u'indexer': e[u'indexer'], u'indexer_id': s[u'indexer_id'], u'name': e[u'name'], u'network': s[u'network'], u'paused': s[u'paused'], u'quality': s[u'quality'], u'runtime': s[u'runtime'], u'season': e[u'season'], u'show_name': s[u'show_name'], u'showid': e[u'showid'], u'status': s[u'status']}]
    done_shows_list = [int(result[u'showid']) for result in results]
    for s in [s[u'doc'] for s in sickrage.srCore.mainDB.db.all(u'tv_shows', with_doc=True)]:
        for e in [e[u'doc'] for e in sickrage.srCore.mainDB.db.get_many(u'tv_episodes', s[u'indexer_id'], with_doc=True) if ((e[u'doc'][u'season'] != 0) and (e[u'doc'][u'showid'] not in done_shows_list) and (e[u'doc'][u'airdate'] >= next_week) and (e[u'doc'][u'status'] not in (((Quality.DOWNLOADED + Quality.SNATCHED) + Quality.SNATCHED_BEST) + Quality.SNATCHED_PROPER)))]:
            results += [{u'airdate': e[u'airdate'], u'airs': s[u'airs'], u'description': e[u'description'], u'episode': e[u'episode'], u'imdb_id': s[u'imdb_id'], u'indexer': e[u'indexer'], u'indexer_id': s[u'indexer_id'], u'name': e[u'name'], u'network': s[u'network'], u'paused': s[u'paused'], u'quality': s[u'quality'], u'runtime': s[u'runtime'], u'season': e[u'season'], u'show_name': s[u'show_name'], u'showid': e[u'showid'], u'status': s[u'status']}]
    for s in [s[u'doc'] for s in sickrage.srCore.mainDB.db.all(u'tv_shows', with_doc=True)]:
        for e in [e[u'doc'] for e in sickrage.srCore.mainDB.db.get_many(u'tv_episodes', s[u'indexer_id'], with_doc=True) if ((e[u'doc'][u'season'] != 0) and (today > e[u'doc'][u'airdate'] >= recently) and (e[u'doc'][u'status'] in [WANTED, UNAIRED]) and (e[u'doc'][u'status'] not in qualities_list))]:
            results += [{u'airdate': e[u'airdate'], u'airs': s[u'airs'], u'description': e[u'description'], u'episode': e[u'episode'], u'imdb_id': s[u'imdb_id'], u'indexer': e[u'indexer'], u'indexer_id': s[u'indexer_id'], u'name': e[u'name'], u'network': s[u'network'], u'paused': s[u'paused'], u'quality': s[u'quality'], u'runtime': s[u'runtime'], u'season': e[u'season'], u'show_name': s[u'show_name'], u'showid': e[u'showid'], u'status': s[u'status']}]
    for (index, item) in enumerate(results):
        results[index][u'localtime'] = srDateTime.convert_to_setting(parse_date_time(item[u'airdate'], item[u'airs'], item[u'network']))
    results.sort(ComingEpisodes.sorts[sort])
    if (not group):
        return results
    grouped_results = {category: [] for category in categories}
    for result in results:
        if (result[u'paused'] and (not paused)):
            continue
        result[u'airs'] = str(result[u'airs']).replace(u'am', u'    AM').replace(u'pm', u'    PM').replace(u'        ', u'    ')
        result[u'airdate'] = result[u'localtime'].toordinal()
        if (result[u'airdate'] < today):
            category = u'missed'
        elif (result[u'airdate'] >= next_week):
            category = u'later'
        elif (result[u'airdate'] == today):
            category = u'today'
        else:
            category = u'soon'
        if ((len(categories) > 0) and (category not in categories)):
            continue
        if (not result[u'network']):
            result[u'network'] = u''
        result[u'quality'] = get_quality_string(result[u'quality'])
        result[u'airs'] = srDateTime.srftime(result[u'localtime'], t_preset=timeFormat).lstrip(u'0').replace(u'    0', u'    ')
        result[u'weekday'] = (1 + datetime.date.fromordinal(result[u'airdate']).weekday())
        result[u'tvdbid'] = result[u'indexer_id']
        result[u'airdate'] = srDateTime.srfdate(result[u'localtime'], d_preset=dateFormat)
        result[u'localtime'] = result[u'localtime'].toordinal()
        grouped_results[category].append(result)
    return grouped_results
