import urllib.request
import os
import re
import json
import jinja2
# Notes are here: https://pad.vvvvvvaria.org/volumetric-regimes-in-process.
STATIC_FOLDER_PATH = '.' # without trailing slash
PUBLIC_STATIC_FOLDER_PATH = '.' # without trailing slash
TEMPLATES_DIR = './templates'
# This uses a low quality copy of all the images
# (using a folder with the name "images-small",
# which stores a copy of all the images generated with:
# $ mogrify -quality 5% -adaptive-resize 25% -remap pattern:gray50 * )
fast = False
def API_request(url, pagename):
"""
url = API request url (string)
data = { 'query':
'pages' :
pageid : {
'links' : {
'?' : '?'
'title' : 'pagename'
}
}
}
}
"""
response = urllib.request.urlopen(url).read()
data = json.loads(response)
# Save response as JSON to be able to inspect API call
json_file = f'{ STATIC_FOLDER_PATH }/{ pagename }.json'
print('Saving JSON:', json_file)
with open(json_file, 'w') as out:
out.write(json.dumps(data, indent=4))
out.close()
return data
def download_media(html, images, wiki):
"""
html = string (HTML)
images = list of filenames (str)
"""
# check if 'images/' already exists
if not os.path.exists(f'{ STATIC_FOLDER_PATH }/images'):
os.makedirs(f'{ STATIC_FOLDER_PATH }/images')
# tmp list for filename replacements
replaced = []
images.sort()
images.reverse() # reverse to make sure that 01.png does not override Image01.png in the filename replacements later
# download media files
for filename in images:
filename = filename.replace(' ', '_') # safe filenames
# check if the image is already downloaded
# if not, then download the file
if not os.path.isfile(f'{ STATIC_FOLDER_PATH }/images/{ filename }'):
# first we search for the full filename of the image
url = f'{ wiki }/api.php?action=query&list=allimages&aifrom={ filename }&format=json'
response = urllib.request.urlopen(url).read()
data = json.loads(response)
# we select the first search result
# (assuming that this is the image we are looking for)
image = data['query']['allimages'][0]
# then we download the image
image_url = image['url']
image_filename = image['name']
print('Downloading:', image_filename)
image_response = urllib.request.urlopen(image_url).read()
# and we save it as a file
image_path = f'{ STATIC_FOLDER_PATH }/images/{ image_filename }'
out = open(image_path, 'wb')
out.write(image_response)
out.close()
import time
time.sleep(3) # do not overload the server
# replace src image link (from wiki folder structure to local folder)
image_path = f'{ PUBLIC_STATIC_FOLDER_PATH }/images/{ filename }' # here the images need to link to the / of the domain, for flask :/// confusing! this breaks the whole idea to still be able to make a local copy of the file
img_path_patterns = [rf'(? { image_path }') # for debugging: each image should have the correct match!
html = html.replace(match, image_path)
replaced.append(match)
return html
def add_item_inventory_links(html):
"""
html = string (HTML)
"""
# THROUGHOUT THE BOOK
# Find all references in the text to the item index
matches = re.findall(r'\w.*?Item \d\d\d.*?\w\w\w', html) # Dodgy attempt to find unique patterns for each mentioning of Item ###
index = {}
for match in matches:
item_match = re.search(r'Item \d\d\d', match).group()
number = item_match.replace('Item ', '').strip()
text_before = re.search(rf'\w.*?Item { number }', match).group().replace(f'Item { number }', '')
text_after = re.search(rf'Item { number }.*?\w\w\w', match).group().replace(f'Item { number }', '')
if not number in index:
index[number] = []
count = 1
else:
count = index[number][-1] + 1
index[number].append(count)
item_id = f'ii-{ number }-{ index[number][-1] }'
# print(f'match: { number } --> { item_id } --> { match }')
html = html.replace(match, f'{ text_before }Item { number }{ text_after }')
# IN THE ITEM INDEX
# Also add a around the index nr to style it
matches = re.findall(r'''', '''
References
''', html) # add id="references" to h3 and ul, so the elements can be selected with CSS
html = html.replace('src="./images/Userinfo.jpg"', 'src="./images/Userinfo.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Userinfo.jpg 1.5x, ./images/Userinfo.jpg 2x"', 'srcset="./images/Userinfo.svg 1.5x, ./images/Userinfo.svg 2x"') # This image is not on the wiki
html = html.replace('src="./images/Continuum_brighton.png"', 'src="./images/Continuum_brighton.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Continuum_brighton.png 1.5x, ./images/Continuum_brighton.png 2x"', 'srcset="./images/Continuum_brighton.svg 1.5x, ./images/Continuum_brighton.svg 2x"') # This image is not on the wiki
html = html.replace('src="./images/Topology-typography-1A.png"', 'src="./images/Topology-typography-1A.svg"') # This image is not on the wiki
html = html.replace('src="./images/Topology-typography-1B.png"', 'src="./images/Topology-typography-1B.svg"') # This image is not on the wiki
html = html.replace('src="./images/Topology-typography-2A.png"', 'src="./images/Topology-typography-2A.svg"') # This image is not on the wiki
html = html.replace('src="./images/Topology-typography-2B.png"', 'src="./images/Topology-typography-2B.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Topology-typography-1A.png"', 'srcset="./images/Topology-typography-1A.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Topology-typography-1B.png"', 'srcset="./images/Topology-typography-1B.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Topology-typography-2A.png"', 'srcset="./images/Topology-typography-2A.svg"') # This image is not on the wiki
html = html.replace('srcset="./images/Topology-typography-2B.png"', 'srcset="./images/Topology-typography-2B.svg"') # This image is not on the wiki
html = html.replace('trans*feminis', 'trans✶feminis') # changing stars
html = html.replace('Trans*feminis', 'Trans✶feminis') # changing stars
html = html.replace('star (*)', 'star (✶)') # changing stars
html = html.replace('Our trans*feminist lens is sharpened by queer and anti-colonial sensibilities, and oriented towards (but not limited to) trans*generational, trans*media, trans*disciplinary, trans*geopolitical, trans*expertise, and trans*genealogical forms of study.', 'Our trans✶feminist lens is sharpened by queer and anti-colonial sensibilities, and oriented towards (but not limited to) trans✶generational, trans✶media, trans✶disciplinary, trans✶geopolitical, trans✶expertise, and trans✶genealogical forms of study.') # changing stars
html = html.replace('
Invasive imagination and its agential cuts
', 'Invasive imagination
')
html = html.replace('
and its agential cutsVolumetric Regimes: Material cultures of quantified presence
', 'Volumetric Regimes:
')
html = html.replace('
Material cultures of
quantified presenceSomatopologies (materials for a movie in the making)
', 'Somatopologies (materials
')
html = html.replace('
for a movie in the making)Signs of clandestine disorder: The continuous aftermath of 3D-computationalism
', 'Signs of clandestine disorder:
')
html = html.replace('
The continuous
aftermath of 3D-
computationalismThe Industrial Continuum of 3D
', 'The Industrial Continuum
')
html = html.replace('
of 3DDepths and Densities: Accidented and dissonant spacetimes
', 'Depths and Densities:
')
html = html.replace('
Accidented
and dissonant
spacetimesOpen Boundary Conditions: a grid for intensive study
', 'Open Boundary Conditions:
')
html = html.replace('T*fRP', 'T✶fRP')
html = html.replace('trans*', 'trans✶')
html = html.replace('Trans*', 'trans✶')
html = html.replace('(*)', '(✶)')
html = html.replace('✶', '✶')
html = html.replace('
a grid for intensive study
we do!”') # force line break
html = html.replace('I find gestationality useful and very exciting.', 'I find gestationality useful and very
exciting.') # force line break
html = html.replace('world.html https://docs.blender.org/manual/en/dev/rende', 'world.html
https://docs.blender.org/manual/en/dev/rende') # force line break
html = html.replace('Nerea Calvillo, Eric Snodgrass', 'Nerea Calvillo, Eric
Snodgrass') # force line break
pattern1 = r'''
.*?
''' # title + author pattern2 = r'''.*?
''' # exceptions: custom running headers pattern3 = r'''Jara Rocha, Femke Snelting
''' pattern5 = r'''Possible Bodies \(Jara Rocha, Femke Snelting\)
''' pattern6 = r'''Maria Dada
''' pattern7 = r'''Phil Langley in conversation with Possible Bodies
''' results = re.findall(rf'{pattern1}|{pattern2}|{pattern3}|{pattern4}|{pattern5}|{pattern6}|{pattern7}', html) for match in results: html = html.replace(match, f'