Beispiel #1
0
 def test_makes_right_calls__buggy_nodeinfo_wellknown_2(
         self, mock_parse, mock_fetch):
     fetch_nodeinfo_document('example.com')
     args, kwargs = mock_fetch.call_args_list[0]
     assert kwargs['host'] == 'example.com'
     assert kwargs['path'] == '/.well-known/nodeinfo'
     args, kwargs = mock_fetch.call_args_list[1]
     assert kwargs['url'] == 'https://example.com/nodeinfo/1.0'
Beispiel #2
0
 def test_makes_right_calls(self, mock_parse, mock_fetch):
     fetch_nodeinfo_document('example.com')
     args, kwargs = mock_fetch.call_args_list[0]
     assert kwargs['host'] == 'example.com'
     assert kwargs['path'] == '/.well-known/nodeinfo'
     args, kwargs = mock_fetch.call_args_list[1]
     assert kwargs['url'] == 'https://example.com/2.0'
     mock_parse.assert_called_once_with(json.loads(self.dummy_doc),
                                        'example.com')
Beispiel #3
0
def parse_mastodon_document(doc, host):
    # Check first this is not actually Pleroma or Misskey
    if doc.get('version', '').find('Pleroma') > -1 or doc.get('version', '').find('Pixelfed') > -1 or \
            doc.get('version', '').find('Kibou') > -1 or doc.get('version', '').find('Kroeg') > -1:
        # Use NodeInfo instead, otherwise this is logged as Mastodon
        from federation.hostmeta.fetchers import fetch_nodeinfo_document
        return fetch_nodeinfo_document(host)
    elif doc.get('version', '').find('misskey') > -1:
        # Use Misskey instead, otherwise this is logged as Mastodon
        from federation.hostmeta.fetchers import fetch_misskey_document
        return fetch_misskey_document(host, mastodon_document=doc)

    result = deepcopy(defaults)
    result['host'] = host
    result['name'] = doc.get('title', host)
    result['platform'] = 'mastodon'
    result['version'] = doc.get('version', '')

    # Awkward parsing of signups from about page
    # TODO remove if fixed, issue logged: https://github.com/tootsuite/mastodon/issues/9350
    about_doc, _status_code, _error = fetch_document(host=host, path='/about')
    if about_doc:
        result['open_signups'] = about_doc.find(
            "<div class='closed-registrations-message'>") == -1

    version = re.sub(r'[^0-9.]', '', doc.get('version', ''))
    version = [int(part) for part in version.split('.')]
    if version >= [3, 0, 0]:
        result['protocols'] = ['activitypub']
    elif version >= [1, 6, 0]:
        result['protocols'] = ['ostatus', 'activitypub']
    else:
        result['protocols'] = ['ostatus']
    result['relay'] = False

    result['activity']['users']['total'] = int_or_none(
        doc.get('stats', {}).get('user_count'))
    result['activity']['local_posts'] = int_or_none(
        doc.get('stats', {}).get('status_count'))

    if "contact_account" in doc and doc.get('contact_account') is not None:
        contact_account = doc.get('contact_account', {})
    else:
        contact_account = {}
    result['organization']['account'] = contact_account.get('url', '')
    result['organization']['contact'] = doc.get('email', '')
    result['organization']['name'] = contact_account.get('display_name', '')

    activity_doc, _status_code, _error = fetch_document(
        host=host, path='/api/v1/instance/activity')
    if activity_doc:
        try:
            activity_doc = json.loads(activity_doc)
        except json.JSONDecodeError:
            return result
        else:
            try:
                logins = activity_doc[1].get('logins')
            except KeyError:
                logins = activity_doc[0].get('logins')
            weekly_count = int_or_none(logins)
            if weekly_count and result['activity']['users']['total']:
                result['activity']['users']['weekly'] = weekly_count
                # Ensure multiplied counts from weekly count don't go over total user count
                result['activity']['users']['half_year'] = min(
                    int(weekly_count * WEEKLY_USERS_HALFYEAR_MULTIPLIER),
                    result['activity']['users']['total'],
                )
                result['activity']['users']['monthly'] = min(
                    int(weekly_count * WEEKLY_USERS_MONTHLY_MULTIPLIER),
                    result['activity']['users']['total'],
                )

    return result