User:WigoBot/Source
Jump to navigation
Jump to search
#!/usr/bin/env python3
# encoding: utf8
#
# Copyright © 2016 Martin Tournoij <martin@arp242.net>
# See below for full copyright
import re, sys, json, collections
import pywikibot
_site = pywikibot.Site()
# Pages to archive
_wigos = [
'RationalWiki:What_is_going_on_in_the_world?',
'RationalWiki:What is going on in the blogosphere?',
'RationalWiki:What is going on in the clogosphere?',
#'RationalWiki:What is going on with the elections?',
]
# Find an entry
_start_entry = r'^\s*(?:<vote poll=.*?|<!--)'
_end_entry = r'(?:<\/vote>|-->)\s*$'
_entry = _start_entry + r'.*?' + _end_entry
# Find current section
_section = r'==(.*?)=='
# Find instructions
_config = r'<!-- wigobot: (\d+) -->'
def pp(*ds):
for d in ds:
json.dump(d, sys.stdout, sort_keys=True, indent=4)
print()
def main():
for wigo in _wigos:
#text = open('test.txt', 'r').read()
page = pywikibot.Page(_site, wigo)
text = page.text
# Extract the number of archives to keep
m = re.search(_config, text)
if m is None:
keep_num = 100
else:
keep_num = int(m.groups()[0])
if keep_num == 0:
print('Archiving has been disabled for {}'.format(wigo))
continue
# Store everything before the first section
m = re.search(_section, text, re.MULTILINE)
head = text[:m.start()]
text = text[m.start():]
# ... and the same for everything after the last entry
m = re.search(r'.*' + _end_entry, text, re.MULTILINE + re.DOTALL)
foot = text[m.end():]
text = text[:m.end()].strip()
# Split by sections and entries
sections_tmp = []
c = re.compile(_section)
off = 0
while True:
m = c.search(text, off)
if m is None: break
off = m.end()
sections_tmp.append(m)
sections = []
for i, s in enumerate(sections_tmp):
if i + 2 > len(sections_tmp):
end = len(text)
else:
end = sections_tmp[i + 1].start()
section_text = text[s.end():end].strip()
sections.append([s.groups()[0].strip(),
re.findall(_entry, section_text, re.MULTILINE + re.DOTALL)])
# Split in what we want to keep and archive
keep = collections.OrderedDict()
archives = collections.OrderedDict()
n_archiving = 0
n = 0
for section, entries in sections:
for entry in entries:
n += 1
if n > keep_num:
if archives.get(section) is None: archives[section] = []
archives[section].append(entry)
n_archiving += 1
else:
if keep.get(section) is None: keep[section] = []
keep[section].append(entry)
def p(s):
print('+-')
for l in s.split('\n'): print('|', l[:120])
print('+-\n')
page.text = '{}\n{}\n\n{}'.format(
head.strip(),
'\n'.join(['\n=={}==\n{}'.format(k, '\n'.join(v)) for k, v in keep.items()]),
foot.strip())
#print('==> Updating the current page to this:'); p(page.text)
page.save(summary='Bot: archiving {} entries'.format(n_archiving))
archives = list(archives.items())
archives.reverse()
for k, v in archives:
title = '{}/{}'.format(wigo, k)
page = pywikibot.Page(_site, title, 4)
if page.text == '':
page.text = '=={}==\n'.format(k)
else:
page.text = page.text.strip() + '\n'
page.text += '\n'.join(v)
#print('==> Updating {} to this:'.format(k)); p(page.text)
page.save(summary='Bot: archiving {} entries'.format(len(v)))
# Purge cache for the archives
pywikibot.Page(_site, '{}/Archive_list'.format(wigo), 4).purge()
if __name__ == '__main__':
main()
# The MIT License (MIT)
#
# Copyright © 2016 Martin Tournoij
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# The software is provided "as is", without warranty of any kind, express or
# implied, including but not limited to the warranties of merchantability,
# fitness for a particular purpose and noninfringement. In no event shall the
# authors or copyright holders be liable for any claim, damages or other
# liability, whether in an action of contract, tort or otherwise, arising
# from, out of or in connection with the software or the use or other dealings
# in the software.