[enh] Adds a status update script
このコミットが含まれているのは:
		
						コミット
						6668f5f719
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										ノーマルファイル
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										ノーマルファイル
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
status.csv
 | 
			
		||||
template.jinja
 | 
			
		||||
							
								
								
									
										127
									
								
								statusUpdateByDatetime.py
									
									
									
									
									
										ノーマルファイル
									
								
							
							
						
						
									
										127
									
								
								statusUpdateByDatetime.py
									
									
									
									
									
										ノーマルファイル
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
"""
 | 
			
		||||
Updates a mastodon account based on a CSV file containing status 
 | 
			
		||||
 | 
			
		||||
Status are defined using 
 | 
			
		||||
 - date 
 | 
			
		||||
 - time 
 | 
			
		||||
 - any number of fields usable in jinja2 templates as variables whose name
 | 
			
		||||
   is the column name 
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import codecs
 | 
			
		||||
import csv
 | 
			
		||||
from datetime import datetime, timezone
 | 
			
		||||
import io
 | 
			
		||||
import operator
 | 
			
		||||
import os
 | 
			
		||||
from os.path import isfile, isdir, dirname, join, realpath
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
# Templates
 | 
			
		||||
import jinja2 
 | 
			
		||||
 | 
			
		||||
# Toot
 | 
			
		||||
from toot.console import main
 | 
			
		||||
 | 
			
		||||
# Command line Arguments
 | 
			
		||||
from argparse import ArgumentParser
 | 
			
		||||
parser = ArgumentParser()
 | 
			
		||||
parser.add_argument("-f", "--csv-file", type=str, default="status.csv", help="Which file to use for future status")
 | 
			
		||||
parser.add_argument("-a", "--account", type=str, default="default", help="Which name for your bot (if multiple)")
 | 
			
		||||
parser.add_argument("-p", "--lastseen-path", type=str, default="/var/cache/newTopics", help="Which path to use for storing ")
 | 
			
		||||
parser.add_argument("-pt", "--template-file", type=str, default="template.jinja", help="Which template file to use ")
 | 
			
		||||
args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sort_csv(csv_filename):
 | 
			
		||||
    """Read and return CSV data sorted by first two fields
 | 
			
		||||
    """
 | 
			
		||||
    data = []
 | 
			
		||||
    global headers
 | 
			
		||||
    with open(csv_filename, 'rb') as f:
 | 
			
		||||
      for row in csv.reader(codecs.iterdecode(f, 'utf-8'), delimiter=';'):
 | 
			
		||||
        if( row[0] == "Date"):
 | 
			
		||||
          headers = row
 | 
			
		||||
        else:
 | 
			
		||||
          data.append( row  )
 | 
			
		||||
    data = sorted(data, key = operator.itemgetter(0,1))
 | 
			
		||||
    return data
 | 
			
		||||
 | 
			
		||||
def recordUpdate():
 | 
			
		||||
  """ Helper for updating lastseen 
 | 
			
		||||
  """
 | 
			
		||||
  handle = open(last_updated_file, 'w')
 | 
			
		||||
  handle.write(str(last_updated_at.strftime('%Y-%m-%d %H:%M:%S.%f%z')))
 | 
			
		||||
  handle.close()
 | 
			
		||||
 | 
			
		||||
# Variables
 | 
			
		||||
headers             = []
 | 
			
		||||
date_now            = datetime.now(timezone.utc)              # Now()
 | 
			
		||||
account             = args.account                            # The tag file lastseen path
 | 
			
		||||
lastseen_path       = args.lastseen_path                         # The tag file lastseen path
 | 
			
		||||
csv_file            = args.csv_file                           # The status file
 | 
			
		||||
template_file       = args.template_file                           # The status file
 | 
			
		||||
last_updated_at     = date_now                                # The last time we updated the status
 | 
			
		||||
last_updated_file   = join(lastseen_path, "{}.lastseen".format(account))   # lastseen file 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
templateLoader = jinja2.FileSystemLoader(searchpath="./")
 | 
			
		||||
templateEnv = jinja2.Environment(loader=templateLoader)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Exit if lastseen path doesn't exist
 | 
			
		||||
if( not isdir( lastseen_path) ):
 | 
			
		||||
  print( "Critical error: please create directory {}".format( lastseen_path) )
 | 
			
		||||
  os._exit(2)
 | 
			
		||||
 | 
			
		||||
# Touch last seen file if not exists
 | 
			
		||||
if( isfile( last_updated_file ) ):
 | 
			
		||||
  wrapper = open(last_updated_file, 'r',encoding="utf-8")
 | 
			
		||||
  try:
 | 
			
		||||
    record = next(wrapper)
 | 
			
		||||
  except IOError as e:
 | 
			
		||||
    print("Couldn't open or write to file (%s)." % e)
 | 
			
		||||
  last_updated_at = datetime.strptime(record.rstrip(), '%Y-%m-%d %H:%M:%S.%f%z')
 | 
			
		||||
  print( last_updated_at )
 | 
			
		||||
 | 
			
		||||
else:
 | 
			
		||||
  try:
 | 
			
		||||
    recordUpdate()
 | 
			
		||||
  except IOError as e:
 | 
			
		||||
    print("Couldn't open or write to file (%s)." % e)
 | 
			
		||||
 | 
			
		||||
# Read CSV file
 | 
			
		||||
statusList = sort_csv(csv_file)
 | 
			
		||||
 | 
			
		||||
# Walk through records until a date is strictly superior to previous action and inferior to now
 | 
			
		||||
for status in statusList: 
 | 
			
		||||
  status_date = datetime.strptime("{} {}-+0000".format(status[0],status[1]), '%Y-%m-%d %H:%M:%S-%z')
 | 
			
		||||
  status_date.replace(tzinfo=timezone.utc)
 | 
			
		||||
 | 
			
		||||
  # Debug
 | 
			
		||||
  print( "status:{} last_updated_at:{} now:{}".format(status_date, last_updated_at, date_now) )
 | 
			
		||||
 | 
			
		||||
  # Status should be published
 | 
			
		||||
  if( status_date > last_updated_at and status_date < date_now ):
 | 
			
		||||
    template = templateEnv.get_template(template_file)
 | 
			
		||||
    template_vars =  dict(zip(headers, status)) 
 | 
			
		||||
    outputText = template.render( template_vars )
 | 
			
		||||
 | 
			
		||||
    # Toot 
 | 
			
		||||
    sim_args = [sys.argv[0],  'post' ]
 | 
			
		||||
 | 
			
		||||
    if ( account ) :
 | 
			
		||||
      sim_args.extend( ( '-u', account ))
 | 
			
		||||
 | 
			
		||||
    sim_args.append( outputText )
 | 
			
		||||
    sys.argv = sim_args
 | 
			
		||||
    main()
 | 
			
		||||
 | 
			
		||||
    last_updated_at = date_now
 | 
			
		||||
    # recordUpdate()
 | 
			
		||||
    os._exit(1)
 | 
			
		||||
 | 
			
		||||
os._exit(0)
 | 
			
		||||
		読み込み中…
	
	
			
			x
			
			
		
	
		新しいイシューから参照
	
	ユーザーをブロックする