mirror of https://gitlab.com/bashrc2/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 | 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 | ## Delete posts | ||||||
| 
 | 
 | ||||||
| To delete a post which you wrote you must first know its url. It is usually something like: | 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 shares import addShare | ||||||
| from theme import setTheme | from theme import setTheme | ||||||
| from announce import sendAnnounceViaServer | from announce import sendAnnounceViaServer | ||||||
|  | from socnet import instancesGraph | ||||||
| import argparse | import argparse | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -151,6 +152,10 @@ parser.add_argument('--postDomains', dest='postDomains', type=str, | ||||||
|                     default=None, |                     default=None, | ||||||
|                     help='Show domains referenced in public ' |                     help='Show domains referenced in public ' | ||||||
|                     'posts for the given handle') |                     '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, | parser.add_argument('--postsraw', dest='postsraw', type=str, | ||||||
|                     default=None, |                     default=None, | ||||||
|                     help='Show raw json of posts for the given handle') |                     help='Show raw json of posts for the given handle') | ||||||
|  | @ -449,13 +454,35 @@ if args.postDomains: | ||||||
|     elif args.gnunet: |     elif args.gnunet: | ||||||
|         proxyType = 'gnunet' |         proxyType = 'gnunet' | ||||||
|     domainList = [] |     domainList = [] | ||||||
|     domainList = getPublicPostDomains(baseDir, nickname, domain, False, True, |     domainList = getPublicPostDomains(baseDir, nickname, domain, | ||||||
|                                       proxyType, args.port, httpPrefix, debug, |                                       proxyType, args.port, | ||||||
|  |                                       httpPrefix, debug, | ||||||
|                                       __version__, domainList) |                                       __version__, domainList) | ||||||
|     for postDomain in domainList: |     for postDomain in domainList: | ||||||
|         print(postDomain) |         print(postDomain) | ||||||
|     sys.exit() |     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 args.postsraw: | ||||||
|     if '@' not in args.postsraw: |     if '@' not in args.postsraw: | ||||||
|         print('Syntax: --postsraw nickname@domain') |         print('Syntax: --postsraw nickname@domain') | ||||||
|  |  | ||||||
							
								
								
									
										25
									
								
								posts.py
								
								
								
								
							
							
						
						
									
										25
									
								
								posts.py
								
								
								
								
							|  | @ -146,11 +146,14 @@ def getUserUrl(wfRequest: {}) -> str: | ||||||
| 
 | 
 | ||||||
| def parseUserFeed(session, feedUrl: str, asHeader: {}, | def parseUserFeed(session, feedUrl: str, asHeader: {}, | ||||||
|                   projectVersion: str, httpPrefix: str, |                   projectVersion: str, httpPrefix: str, | ||||||
|                   domain: str) -> None: |                   domain: str,depth=0) -> {}: | ||||||
|  |     if depth > 10: | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|     feedJson = getJson(session, feedUrl, asHeader, None, |     feedJson = getJson(session, feedUrl, asHeader, None, | ||||||
|                        projectVersion, httpPrefix, domain) |                        projectVersion, httpPrefix, domain) | ||||||
|     if not feedJson: |     if not feedJson: | ||||||
|         return |         return None | ||||||
| 
 | 
 | ||||||
|     if 'orderedItems' in feedJson: |     if 'orderedItems' in feedJson: | ||||||
|         for item in feedJson['orderedItems']: |         for item in feedJson['orderedItems']: | ||||||
|  | @ -168,7 +171,8 @@ def parseUserFeed(session, feedUrl: str, asHeader: {}, | ||||||
|                 userFeed = \ |                 userFeed = \ | ||||||
|                     parseUserFeed(session, nextUrl, asHeader, |                     parseUserFeed(session, nextUrl, asHeader, | ||||||
|                                   projectVersion, httpPrefix, |                                   projectVersion, httpPrefix, | ||||||
|                                   domain) |                                   domain, depth+1) | ||||||
|  |                 if userFeed: | ||||||
|                     for item in userFeed: |                     for item in userFeed: | ||||||
|                         yield item |                         yield item | ||||||
|         elif isinstance(nextUrl, dict): |         elif isinstance(nextUrl, dict): | ||||||
|  | @ -444,8 +448,8 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, | ||||||
|                    maxMentions: int, |                    maxMentions: int, | ||||||
|                    maxEmoji: int, maxAttachments: int, |                    maxEmoji: int, maxAttachments: int, | ||||||
|                    federationList: [], |                    federationList: [], | ||||||
|                    personCache: {}, raw: bool, |                    personCache: {}, | ||||||
|                    simple: bool, debug: bool, |                    debug: bool, | ||||||
|                    projectVersion: str, httpPrefix: str, |                    projectVersion: str, httpPrefix: str, | ||||||
|                    domain: str, domainList=[]) -> []: |                    domain: str, domainList=[]) -> []: | ||||||
|     """Returns a list of domains referenced within public posts |     """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, |     userFeed = parseUserFeed(session, outboxUrl, asHeader, | ||||||
|                              projectVersion, httpPrefix, domain) |                              projectVersion, httpPrefix, domain) | ||||||
|     for item in userFeed: |     for item in userFeed: | ||||||
|  |         i += 1 | ||||||
|  |         if i > maxPosts: | ||||||
|  |             break | ||||||
|         if not item.get('object'): |         if not item.get('object'): | ||||||
|             continue |             continue | ||||||
|         if not isinstance(item['object'], dict): |         if not isinstance(item['object'], dict): | ||||||
|  | @ -486,9 +493,6 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, | ||||||
|                             getDomainFromActor(tagItem['href']) |                             getDomainFromActor(tagItem['href']) | ||||||
|                         if postDomain not in postDomains: |                         if postDomain not in postDomains: | ||||||
|                             postDomains.append(postDomain) |                             postDomains.append(postDomain) | ||||||
|         i += 1 |  | ||||||
|         if i == maxPosts: |  | ||||||
|             break |  | ||||||
|     return postDomains |     return postDomains | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -2986,8 +2990,7 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def getPublicPostDomains(baseDir: str, nickname: str, domain: str, | def getPublicPostDomains(baseDir: str, nickname: str, domain: str, | ||||||
|                          raw: bool, simple: bool, proxyType: str, |                          proxyType: str, port: int, httpPrefix: str, | ||||||
|                          port: int, httpPrefix: str, |  | ||||||
|                          debug: bool, projectVersion: str, |                          debug: bool, projectVersion: str, | ||||||
|                          domainList=[]) -> []: |                          domainList=[]) -> []: | ||||||
|     """ Returns a list of domains referenced within public posts |     """ Returns a list of domains referenced within public posts | ||||||
|  | @ -3028,7 +3031,7 @@ def getPublicPostDomains(baseDir: str, nickname: str, domain: str, | ||||||
|     postDomains = \ |     postDomains = \ | ||||||
|         getPostDomains(session, personUrl, 64, maxMentions, maxEmoji, |         getPostDomains(session, personUrl, 64, maxMentions, maxEmoji, | ||||||
|                        maxAttachments, federationList, |                        maxAttachments, federationList, | ||||||
|                        personCache, raw, simple, debug, |                        personCache, debug, | ||||||
|                        projectVersion, httpPrefix, domain, domainList) |                        projectVersion, httpPrefix, domain, domainList) | ||||||
|     postDomains.sort() |     postDomains.sort() | ||||||
|     return postDomains |     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