forked from cory/tildefriends
		
	
		
			
				
	
	
		
			77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import argparse
 | |
| import feedparser
 | |
| import json
 | |
| import re
 | |
| import subprocess
 | |
| import time
 | |
| 
 | |
| parser = argparse.ArgumentParser()
 | |
| parser.add_argument('--state_file', help = 'Path to a file in which to store state.')
 | |
| args = parser.parse_args()
 | |
| 
 | |
| k_feeds = {
 | |
|     'tildefriends': 'https://dev.tildefriends.net/cory/tildefriends.rss',
 | |
|     'erlbutt': 'https://github.com/cmoid/erlbutt/commits/main.atom',
 | |
|     'habitat': 'https://tildegit.org/jeremylist/habitat.rss',
 | |
|     'manyverse': 'https://gitlab.com/staltz/manyverse/-/commits/master?format=atom',
 | |
|     'ahau': 'https://gitlab.com/ahau/ahau/-/commits/master.atom',
 | |
|     'patchfox': 'https://github.com/soapdog/patchfox/commits.atom',
 | |
| }
 | |
| 
 | |
| def fix_title(entry):
 | |
|     if entry.summary.startswith('<a href=') and '\n' in entry.summary and entry.summary and '\n' in entry.summary:
 | |
|         return entry.summary.split('\n')[1]
 | |
|     return entry.title.split('\n')[0]
 | |
| 
 | |
| def get_entries():
 | |
|     seen = set()
 | |
|     results = []
 | |
|     for name, url in k_feeds.items():
 | |
|         feed = feedparser.parse(url)
 | |
|         for entry in feed.entries:
 | |
|             if '/issues/' in entry.link:
 | |
|                 m = re.match(r'^(\d+)#(.*)#$', entry.description)
 | |
|                 if m:
 | |
|                     results.append((time.mktime(entry.get('updated_parsed')), name, entry.link, f'new issue #{m.group(1)}: {m.group(2)}'))
 | |
|                     continue
 | |
|             elif '/releases/' in entry.link:
 | |
|                 m = re.match(r'(.*) released <a href=".*?">(.*?)</a>', entry.title)
 | |
|                 if m:
 | |
|                     results.append((time.mktime(entry.get('updated_parsed')), name, entry.link, f'{m.group(1)} released {m.group(2)}'))
 | |
|                     continue
 | |
|             if entry.summary.startswith('<a href='):
 | |
|                 for m in re.findall(r'<a href="(.*?)">.*?</a>$\s*^([^\n]+)$', entry.summary, re.S | re.M):
 | |
|                     if not m[0] in seen:
 | |
|                         seen.add(m[0])
 | |
|                         results.append((time.mktime(entry.get('updated_parsed')), name, m[0], m[1]))
 | |
|             else:
 | |
|                 if not entry.link in seen:
 | |
|                     seen.add(entry.link)
 | |
|                     results.append((time.mktime(entry.get('updated_parsed')), name, entry.link, entry.title.split('\n')[0]))
 | |
|     results.sort()
 | |
|     results.reverse()
 | |
|     return results
 | |
| 
 | |
| state = {}
 | |
| if args.state_file:
 | |
|     try:
 | |
|         with open(args.state_file, 'r') as f:
 | |
|             state = json.load(f)
 | |
|     except:
 | |
|         pass
 | |
| cutoff = state.get('last_update') or (time.time() - 2 * 7 * 24 * 60 * 60)
 | |
| 
 | |
| entries = [entry for entry in get_entries() if entry[0] > cutoff]
 | |
| if entries:
 | |
|     text = '\n'.join([f' * **{entry[1]}** [{entry[3]}]({entry[2]})' for entry in entries])
 | |
|     state['last_update'] = entries[0][0]
 | |
|     if args.state_file:
 | |
|         content = json.dumps({'type': 'post', 'text': text, 'mentions': []})
 | |
|         subprocess.check_call(['out/debug/tildefriends', 'publish', '--user', 'cory', '--id', '@DnYDqFfmxdNkYQlpflF9Wkltk2HIhJ5u1MW5njKPLzM=.ed25519', '--content', content])
 | |
|         with open(args.state_file, 'w') as f:
 | |
|             json.dump(state, f)
 | |
|     else:
 | |
|         print(text)
 |