mihobu.paste.lol / nowbot2.py · 1 year ago·

import boto3
import json
import urllib3
import yaml

from datetime import datetime

def normalize(item):
    obj = {}
    for k in item.keys():
        t = list(item[k].keys())[0]
        obj[k] = item[k][t]
    return obj

def denormalize(item):
    obj = {}
    for k in item.keys():
        obj[k] = {'S': item[k]}
    return obj

def lambda_handler(event, context):

    # OMG.LOL API CONFIG
    omg_now_url = 'https://api.omg.lol/address/mihobu/now'
    omg_paste_url = 'https://api.omg.lol/address/mihobu/pastebin'
    omg_api_key = 'lollollollollollollollollollollol'
    omg_headers = {
        'Authorization': f'Bearer {omg_api_key}'
    }
    
    # GET A CONNECTION POOL
    http = urllib3.PoolManager()
    
    # GET BOTO3 CLIENTS
    ddb_client = boto3.client('dynamodb')

    # GET THE NEW MEDIA YAML FILE
    resp = http.request('GET', 'https://mihobu.paste.lol/media4.yaml/raw')
    input_media = yaml.safe_load(resp.data)
    if input_media is None:
        # There's nothing new to add, so quit
        print('Nothing retrieved. Exiting.')
        return None

    # ADD PRIMARY KEY (VERSION & TIMESTAMP) TO 
    # NON-EMPTY ENTRIES IN NEW MEDIA LIST
    # THIS WAY WE CAN IGNORE ENTRY (TEMPLATE) ENTRIES
    sn = 0
    ts = datetime.now().strftime('%Y-%m-%d-%H-%M')
    new_media = []
    for item in input_media:
        if item['title'] is None:
            continue
        else:
            print('*')
        sn = sn + 1
        item['timestamp'] = f'{ts}-{sn:04n}'
        item['version'] = '3'
        new_media.append(item)

    # BAIL OUT IF NEW MEDIA LIST IS EMPTY
    if len(new_media) == 0:
        print('No new media found. Exiting.')
        return
    
    # GET UP TO 100 PREVIOUSLY STORED MEDIA FROM DYNAMODB
    resp = ddb_client.scan(TableName='status-media', Limit=100)
    data = resp['Items']
    old_media = [normalize(x) for x in data]

    # WRITE NEW MEDIA ITEMS TO DYNAMODB
    new_media_d = [denormalize(x) for x in new_media]
    for item in new_media_d:
        ddb_client.put_item(TableName='status-media', Item=item)
    print('{} new items written to DynamoDB'.format(len(new_media_d)))

    # COMBINE OLD WITH NEW
    combined_media = sorted(new_media + old_media, key=lambda d: d['timestamp'], reverse=True)

    # BEGIN TO CONSTRUCT THE NEW NOW CONTENT
    now = '''{profile-picture}
    
# Michael Burkhardt

## What I’m Doing Now

<script src="https://status.lol/mihobu.js?time&fluent&pretty&link"></script>
    
These are the things I’ve been reading, watching, listening to, and tinkering with recently:

'''

    # LOOP OVER THE YAML CONTENT TO BUILD BULLET LIST
    uniq_titles = {}
    max_items = 20
    c = 0
    for item in combined_media:
        if item['title'] in uniq_titles.keys():
            # Already saw an item with this title -- SKIP
            next
        else:
            c = c + 1
            uniq_titles[item['title']] = 1
            icon2use = 'otter'
            if 'icon' in item.keys():
                icon2use = item['icon']
            if 'url' in item.keys():
                now += "- [{}]({}) {{{}}}\n".format(item['title'], item['url'], icon2use)
            else:
                now += "- {} {{{}}}\n".format(item['title'], icon2use)
        if c >= max_items:
            break

    now += '''
<div class="nowlol">BACK TO <a href="https://mihobu.monkeywalk.com/">ALL THINGS MIHOBU</a></div>
{last-updated}
'''

    # CALL THE OMG.LOL API TO UPDATE THE NOW PAGE CONTENTS
    payload2 = {
        'content': now,
        'listed': 1
    }
    resp2 = http.request('POST', omg_now_url, body=json.dumps(payload2), headers=omg_headers)
    
    # REPLACE PASTE WITH BLANK TEMPLATE
    template = f'''
# media4.yaml - Last updated {ts}
# * NEW ITEMS ONLY, TOP (OLDEST) TO BOTTOM (NEWEST)
-
  title: 
  icon: 
  url: 
'''
    payload3 = {
        'title': 'media4.yaml',
        'content': template
    }
    resp3 = http.request('POST', omg_paste_url, body=json.dumps(payload3), headers=omg_headers)