forked from indymedia/epicyon
Plotting federated instances
parent
b1516507f8
commit
7b06a3b262
|
@ -144,6 +144,15 @@ To list the domains referenced in public posts:
|
|||
python3 epicyon.py --postDomains nickname@domain
|
||||
```
|
||||
|
||||
## Plotting federated instances
|
||||
|
||||
To plot a set of federated instances, based upon a sample of handles on those instances:
|
||||
|
||||
``` bash
|
||||
python3 epicyon.py --socnet nickname1@domain1,nickname2@domain2,nickname3@domain3
|
||||
xdot socnet.dot
|
||||
```
|
||||
|
||||
## Delete posts
|
||||
|
||||
To delete a post which you wrote you must first know its url. It is usually something like:
|
||||
|
|
31
epicyon.py
31
epicyon.py
|
@ -67,6 +67,7 @@ from shares import sendUndoShareViaServer
|
|||
from shares import addShare
|
||||
from theme import setTheme
|
||||
from announce import sendAnnounceViaServer
|
||||
from socnet import instancesGraph
|
||||
import argparse
|
||||
|
||||
|
||||
|
@ -151,6 +152,10 @@ parser.add_argument('--postDomains', dest='postDomains', type=str,
|
|||
default=None,
|
||||
help='Show domains referenced in public '
|
||||
'posts for the given handle')
|
||||
parser.add_argument('--socnet', dest='socnet', type=str,
|
||||
default=None,
|
||||
help='Show dot diagram for social network '
|
||||
'of federated instances')
|
||||
parser.add_argument('--postsraw', dest='postsraw', type=str,
|
||||
default=None,
|
||||
help='Show raw json of posts for the given handle')
|
||||
|
@ -449,13 +454,35 @@ if args.postDomains:
|
|||
elif args.gnunet:
|
||||
proxyType = 'gnunet'
|
||||
domainList = []
|
||||
domainList = getPublicPostDomains(baseDir, nickname, domain, False, True,
|
||||
proxyType, args.port, httpPrefix, debug,
|
||||
domainList = getPublicPostDomains(baseDir, nickname, domain,
|
||||
proxyType, args.port,
|
||||
httpPrefix, debug,
|
||||
__version__, domainList)
|
||||
for postDomain in domainList:
|
||||
print(postDomain)
|
||||
sys.exit()
|
||||
|
||||
if args.socnet:
|
||||
if ',' not in args.socnet:
|
||||
print('Syntax: '
|
||||
'--socnet nick1@domain1,nick2@domain2,nick3@domain3')
|
||||
sys.exit()
|
||||
|
||||
if not args.http:
|
||||
args.port = 443
|
||||
proxyType = 'tor'
|
||||
dotGraph = instancesGraph(baseDir, args.socnet,
|
||||
proxyType, args.port,
|
||||
httpPrefix, debug,
|
||||
__version__)
|
||||
try:
|
||||
with open('socnet.dot', 'w') as fp:
|
||||
fp.write(dotGraph)
|
||||
print('Saved to socnet.dot')
|
||||
except BaseException:
|
||||
pass
|
||||
sys.exit()
|
||||
|
||||
if args.postsraw:
|
||||
if '@' not in args.postsraw:
|
||||
print('Syntax: --postsraw nickname@domain')
|
||||
|
|
29
posts.py
29
posts.py
|
@ -146,11 +146,14 @@ def getUserUrl(wfRequest: {}) -> str:
|
|||
|
||||
def parseUserFeed(session, feedUrl: str, asHeader: {},
|
||||
projectVersion: str, httpPrefix: str,
|
||||
domain: str) -> None:
|
||||
domain: str,depth=0) -> {}:
|
||||
if depth > 10:
|
||||
return None
|
||||
|
||||
feedJson = getJson(session, feedUrl, asHeader, None,
|
||||
projectVersion, httpPrefix, domain)
|
||||
if not feedJson:
|
||||
return
|
||||
return None
|
||||
|
||||
if 'orderedItems' in feedJson:
|
||||
for item in feedJson['orderedItems']:
|
||||
|
@ -168,9 +171,10 @@ def parseUserFeed(session, feedUrl: str, asHeader: {},
|
|||
userFeed = \
|
||||
parseUserFeed(session, nextUrl, asHeader,
|
||||
projectVersion, httpPrefix,
|
||||
domain)
|
||||
for item in userFeed:
|
||||
yield item
|
||||
domain, depth+1)
|
||||
if userFeed:
|
||||
for item in userFeed:
|
||||
yield item
|
||||
elif isinstance(nextUrl, dict):
|
||||
userFeed = nextUrl
|
||||
if userFeed.get('orderedItems'):
|
||||
|
@ -444,8 +448,8 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int,
|
|||
maxMentions: int,
|
||||
maxEmoji: int, maxAttachments: int,
|
||||
federationList: [],
|
||||
personCache: {}, raw: bool,
|
||||
simple: bool, debug: bool,
|
||||
personCache: {},
|
||||
debug: bool,
|
||||
projectVersion: str, httpPrefix: str,
|
||||
domain: str, domainList=[]) -> []:
|
||||
"""Returns a list of domains referenced within public posts
|
||||
|
@ -467,6 +471,9 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int,
|
|||
userFeed = parseUserFeed(session, outboxUrl, asHeader,
|
||||
projectVersion, httpPrefix, domain)
|
||||
for item in userFeed:
|
||||
i += 1
|
||||
if i > maxPosts:
|
||||
break
|
||||
if not item.get('object'):
|
||||
continue
|
||||
if not isinstance(item['object'], dict):
|
||||
|
@ -486,9 +493,6 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int,
|
|||
getDomainFromActor(tagItem['href'])
|
||||
if postDomain not in postDomains:
|
||||
postDomains.append(postDomain)
|
||||
i += 1
|
||||
if i == maxPosts:
|
||||
break
|
||||
return postDomains
|
||||
|
||||
|
||||
|
@ -2986,8 +2990,7 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str,
|
|||
|
||||
|
||||
def getPublicPostDomains(baseDir: str, nickname: str, domain: str,
|
||||
raw: bool, simple: bool, proxyType: str,
|
||||
port: int, httpPrefix: str,
|
||||
proxyType: str, port: int, httpPrefix: str,
|
||||
debug: bool, projectVersion: str,
|
||||
domainList=[]) -> []:
|
||||
""" Returns a list of domains referenced within public posts
|
||||
|
@ -3028,7 +3031,7 @@ def getPublicPostDomains(baseDir: str, nickname: str, domain: str,
|
|||
postDomains = \
|
||||
getPostDomains(session, personUrl, 64, maxMentions, maxEmoji,
|
||||
maxAttachments, federationList,
|
||||
personCache, raw, simple, debug,
|
||||
personCache, debug,
|
||||
projectVersion, httpPrefix, domain, domainList)
|
||||
postDomains.sort()
|
||||
return postDomains
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
__filename__ = "socnet.py"
|
||||
__author__ = "Bob Mottram"
|
||||
__license__ = "AGPL3+"
|
||||
__version__ = "1.1.0"
|
||||
__maintainer__ = "Bob Mottram"
|
||||
__email__ = "bob@freedombone.net"
|
||||
__status__ = "Production"
|
||||
|
||||
from session import createSession
|
||||
from webfinger import webfingerHandle
|
||||
from posts import getPersonBox
|
||||
from posts import getPostDomains
|
||||
|
||||
|
||||
def instancesGraph(baseDir: str, handles: str,
|
||||
proxyType: str,
|
||||
port: int, httpPrefix: str,
|
||||
debug: bool, projectVersion: str) -> str:
|
||||
""" Returns a dot graph of federating instances
|
||||
based upon a few sample handles.
|
||||
The handles argument should contain a comma separated list
|
||||
of handles on different instances
|
||||
"""
|
||||
dotGraphStr = 'digraph instances {\n'
|
||||
if ',' not in handles:
|
||||
return dotGraphStr + '}\n'
|
||||
session = createSession(proxyType)
|
||||
if not session:
|
||||
return dotGraphStr + '}\n'
|
||||
|
||||
personCache = {}
|
||||
cachedWebfingers = {}
|
||||
federationList = []
|
||||
maxMentions = 99
|
||||
maxEmoji = 99
|
||||
maxAttachments = 5
|
||||
|
||||
personHandles = handles.split(',')
|
||||
for handle in personHandles:
|
||||
handle = handle.strip()
|
||||
if handle.startswith('@'):
|
||||
handle = handle[1:]
|
||||
if '@' not in handle:
|
||||
continue
|
||||
|
||||
nickname = handle.split('@')[0]
|
||||
domain = handle.split('@')[1]
|
||||
|
||||
domainFull = domain
|
||||
if port:
|
||||
if port != 80 and port != 443:
|
||||
if ':' not in domain:
|
||||
domainFull = domain + ':' + str(port)
|
||||
handle = httpPrefix + "://" + domainFull + "/@" + nickname
|
||||
wfRequest = \
|
||||
webfingerHandle(session, handle, httpPrefix,
|
||||
cachedWebfingers,
|
||||
domain, projectVersion)
|
||||
if not wfRequest:
|
||||
return dotGraphStr + '}\n'
|
||||
if not isinstance(wfRequest, dict):
|
||||
print('Webfinger for ' + handle + ' did not return a dict. ' +
|
||||
str(wfRequest))
|
||||
return dotGraphStr + '}\n'
|
||||
|
||||
(personUrl, pubKeyId, pubKey,
|
||||
personId, shaedInbox,
|
||||
capabilityAcquisition,
|
||||
avatarUrl, displayName) = getPersonBox(baseDir, session, wfRequest,
|
||||
personCache,
|
||||
projectVersion, httpPrefix,
|
||||
nickname, domain, 'outbox')
|
||||
postDomains = \
|
||||
getPostDomains(session, personUrl, 64, maxMentions, maxEmoji,
|
||||
maxAttachments, federationList,
|
||||
personCache, debug,
|
||||
projectVersion, httpPrefix, domain, [])
|
||||
postDomains.sort()
|
||||
for fedDomain in postDomains:
|
||||
dotLineStr = ' "' + domain + '" -> "' + fedDomain + '";\n'
|
||||
if dotLineStr not in dotGraphStr:
|
||||
dotGraphStr += dotLineStr
|
||||
return dotGraphStr + '}\n'
|
Loading…
Reference in New Issue