Browse Source

[enh] Adds a status update script

master
alban 1 year ago
parent
commit
6668f5f719
2 changed files with 129 additions and 0 deletions
  1. 2
    0
      .gitignore
  2. 127
    0
      statusUpdateByDatetime.py

+ 2
- 0
.gitignore View File

@@ -0,0 +1,2 @@
1
+status.csv
2
+template.jinja

+ 127
- 0
statusUpdateByDatetime.py View File

@@ -0,0 +1,127 @@
1
+#!/usr/bin/python3
2
+# -*- coding: utf-8 -*-
3
+"""
4
+Updates a mastodon account based on a CSV file containing status 
5
+
6
+Status are defined using 
7
+ - date 
8
+ - time 
9
+ - any number of fields usable in jinja2 templates as variables whose name
10
+   is the column name 
11
+
12
+"""
13
+
14
+import codecs
15
+import csv
16
+from datetime import datetime, timezone
17
+import io
18
+import operator
19
+import os
20
+from os.path import isfile, isdir, dirname, join, realpath
21
+import sys
22
+
23
+# Templates
24
+import jinja2 
25
+
26
+# Toot
27
+from toot.console import main
28
+
29
+# Command line Arguments
30
+from argparse import ArgumentParser
31
+parser = ArgumentParser()
32
+parser.add_argument("-f", "--csv-file", type=str, default="status.csv", help="Which file to use for future status")
33
+parser.add_argument("-a", "--account", type=str, default="default", help="Which name for your bot (if multiple)")
34
+parser.add_argument("-p", "--lastseen-path", type=str, default="/var/cache/newTopics", help="Which path to use for storing ")
35
+parser.add_argument("-pt", "--template-file", type=str, default="template.jinja", help="Which template file to use ")
36
+args = parser.parse_args()
37
+
38
+
39
+def sort_csv(csv_filename):
40
+    """Read and return CSV data sorted by first two fields
41
+    """
42
+    data = []
43
+    global headers
44
+    with open(csv_filename, 'rb') as f:
45
+      for row in csv.reader(codecs.iterdecode(f, 'utf-8'), delimiter=';'):
46
+        if( row[0] == "Date"):
47
+          headers = row
48
+        else:
49
+          data.append( row  )
50
+    data = sorted(data, key = operator.itemgetter(0,1))
51
+    return data
52
+
53
+def recordUpdate():
54
+  """ Helper for updating lastseen 
55
+  """
56
+  handle = open(last_updated_file, 'w')
57
+  handle.write(str(last_updated_at.strftime('%Y-%m-%d %H:%M:%S.%f%z')))
58
+  handle.close()
59
+
60
+# Variables
61
+headers             = []
62
+date_now            = datetime.now(timezone.utc)              # Now()
63
+account             = args.account                            # The tag file lastseen path
64
+lastseen_path       = args.lastseen_path                         # The tag file lastseen path
65
+csv_file            = args.csv_file                           # The status file
66
+template_file       = args.template_file                           # The status file
67
+last_updated_at     = date_now                                # The last time we updated the status
68
+last_updated_file   = join(lastseen_path, "{}.lastseen".format(account))   # lastseen file 
69
+
70
+
71
+templateLoader = jinja2.FileSystemLoader(searchpath="./")
72
+templateEnv = jinja2.Environment(loader=templateLoader)
73
+
74
+
75
+# Exit if lastseen path doesn't exist
76
+if( not isdir( lastseen_path) ):
77
+  print( "Critical error: please create directory {}".format( lastseen_path) )
78
+  os._exit(2)
79
+
80
+# Touch last seen file if not exists
81
+if( isfile( last_updated_file ) ):
82
+  wrapper = open(last_updated_file, 'r',encoding="utf-8")
83
+  try:
84
+    record = next(wrapper)
85
+  except IOError as e:
86
+    print("Couldn't open or write to file (%s)." % e)
87
+  last_updated_at = datetime.strptime(record.rstrip(), '%Y-%m-%d %H:%M:%S.%f%z')
88
+  print( last_updated_at )
89
+
90
+else:
91
+  try:
92
+    recordUpdate()
93
+  except IOError as e:
94
+    print("Couldn't open or write to file (%s)." % e)
95
+
96
+# Read CSV file
97
+statusList = sort_csv(csv_file)
98
+
99
+# Walk through records until a date is strictly superior to previous action and inferior to now
100
+for status in statusList: 
101
+  status_date = datetime.strptime("{} {}-+0000".format(status[0],status[1]), '%Y-%m-%d %H:%M:%S-%z')
102
+  status_date.replace(tzinfo=timezone.utc)
103
+
104
+  # Debug
105
+  print( "status:{} last_updated_at:{} now:{}".format(status_date, last_updated_at, date_now) )
106
+
107
+  # Status should be published
108
+  if( status_date > last_updated_at and status_date < date_now ):
109
+    template = templateEnv.get_template(template_file)
110
+    template_vars =  dict(zip(headers, status)) 
111
+    outputText = template.render( template_vars )
112
+
113
+    # Toot 
114
+    sim_args = [sys.argv[0],  'post' ]
115
+
116
+    if ( account ) :
117
+      sim_args.extend( ( '-u', account ))
118
+
119
+    sim_args.append( outputText )
120
+    sys.argv = sim_args
121
+    main()
122
+
123
+    last_updated_at = date_now
124
+    # recordUpdate()
125
+    os._exit(1)
126
+
127
+os._exit(0)

Loading…
Cancel
Save