<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://photonwiki.ifi.unicamp.br/wiki/index.php?action=history&amp;feed=atom&amp;title=Wiki_Bot_Example</id>
	<title>Wiki Bot Example - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://photonwiki.ifi.unicamp.br/wiki/index.php?action=history&amp;feed=atom&amp;title=Wiki_Bot_Example"/>
	<link rel="alternate" type="text/html" href="https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;action=history"/>
	<updated>2026-07-02T08:06:16Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=797&amp;oldid=prev</id>
		<title>Jarschel at 19:35, 3 February 2025</title>
		<link rel="alternate" type="text/html" href="https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=797&amp;oldid=prev"/>
		<updated>2025-02-03T19:35:11Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:35, 3 February 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l464&quot;&gt;Line 464:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 464:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     credsfile = &amp;quot;photonbot.txt&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     credsfile = &amp;quot;photonbot.txt&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;else:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;else:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     wiki_url = &quot;http://&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;143&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;106&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;153&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;11&lt;/del&gt;/media_wiki_demo/api.php&quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     wiki_url = &quot;http://&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;beltza&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;ifi&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;unicamp&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;br&lt;/ins&gt;/media_wiki_demo/api.php&quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     credsfile = &amp;quot;testbot.txt&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     credsfile = &amp;quot;testbot.txt&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;with open(credsfile, &amp;#039;r&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as file:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;with open(credsfile, &amp;#039;r&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as file:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Jarschel</name></author>
	</entry>
	<entry>
		<id>https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=796&amp;oldid=prev</id>
		<title>Jarschel at 19:34, 3 February 2025</title>
		<link rel="alternate" type="text/html" href="https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=796&amp;oldid=prev"/>
		<updated>2025-02-03T19:34:28Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:34, 3 February 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l437&quot;&gt;Line 437:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 437:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# Main definitions&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# Main definitions&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;lco_url = &quot;http://&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;143&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;106&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;153&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;11&lt;/del&gt;/LCOSys&quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;lco_url = &quot;http://&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;beltza&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;ifi&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;unicamp&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;br&lt;/ins&gt;/LCOSys&quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;wiki_type = &amp;quot;prod&amp;quot;  # test or prod&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;wiki_type = &amp;quot;prod&amp;quot;  # test or prod&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;test_on_random_id = False  # To test on a random equipment. Overrides id set on test_id.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;test_on_random_id = False  # To test on a random equipment. Overrides id set on test_id.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Jarschel</name></author>
	</entry>
	<entry>
		<id>https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=795&amp;oldid=prev</id>
		<title>Jarschel: Created page with &quot;This code is an example of how to automate wiki page creation.  It also features integration with Perplexity AI-Powered web search to generate instrument pages base text.&lt;syntaxhighlight lang=&quot;python&quot; line=&quot;1&quot;&gt; &#039;&#039;&#039; This script scrapes info of all equipments in the old LCO database, including pictures and manuals, uses AI to generate a summary about each equipment using web searches to improve accuracy, and then creates a wiki article about it.  Created by pfjarschel Dec...&quot;</title>
		<link rel="alternate" type="text/html" href="https://photonwiki.ifi.unicamp.br/wiki/index.php?title=Wiki_Bot_Example&amp;diff=795&amp;oldid=prev"/>
		<updated>2025-02-03T14:29:09Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;This code is an example of how to automate wiki page creation.  It also features integration with Perplexity AI-Powered web search to generate instrument pages base text.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; This script scrapes info of all equipments in the old LCO database, including pictures and manuals, uses AI to generate a summary about each equipment using web searches to improve accuracy, and then creates a wiki article about it.  Created by pfjarschel Dec...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This code is an example of how to automate wiki page creation.&lt;br /&gt;
&lt;br /&gt;
It also features integration with Perplexity AI-Powered web search to generate instrument pages base text.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
This script scrapes info of all equipments in the old LCO database,&lt;br /&gt;
including pictures and manuals, uses AI to generate a summary about each&lt;br /&gt;
equipment using web searches to improve accuracy, and then creates a&lt;br /&gt;
wiki article about it.&lt;br /&gt;
&lt;br /&gt;
Created by pfjarschel&lt;br /&gt;
Dec 2024  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# Basic imports&lt;br /&gt;
import os&lt;br /&gt;
import time&lt;br /&gt;
import numpy as np  # For random number generation&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
# Specific imports&lt;br /&gt;
import pandoc&lt;br /&gt;
from PIL import Image&lt;br /&gt;
from openai import OpenAI&lt;br /&gt;
&lt;br /&gt;
# To try and suppress some useless warnings&lt;br /&gt;
import warnings&lt;br /&gt;
&lt;br /&gt;
# Suppress https warnings&lt;br /&gt;
from urllib3.exceptions import InsecureRequestWarning&lt;br /&gt;
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)&lt;br /&gt;
&lt;br /&gt;
# This file&amp;#039;s path&lt;br /&gt;
main_directory = os.path.dirname(os.path.abspath(__file__)).replace(&amp;quot;\\&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ScrapedEquip:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    This class simply holds all the information found on a certain equipment&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
    raw = requests.Response()&lt;br /&gt;
    id = &amp;quot;LCO000000&amp;quot;&lt;br /&gt;
    inst_type = &amp;quot;&amp;quot;&lt;br /&gt;
    name = &amp;quot;Brand Model&amp;quot;&lt;br /&gt;
    status = &amp;quot;OK&amp;quot;&lt;br /&gt;
    location = &amp;quot;&amp;quot;&lt;br /&gt;
    serial = &amp;quot;&amp;quot;&lt;br /&gt;
    patrimonio = &amp;quot;&amp;quot;&lt;br /&gt;
    date = &amp;quot;&amp;quot;&lt;br /&gt;
    keywords = &amp;quot;&amp;quot;&lt;br /&gt;
    summary = &amp;quot;&amp;quot;&lt;br /&gt;
    summary_citations = []&lt;br /&gt;
    img_url = &amp;quot;&amp;quot;&lt;br /&gt;
    img_file = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class PPLX:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    This class is the interface to Perplexity&amp;#039;s API&lt;br /&gt;
    A valid API key is needed ¯\_(ツ)_/¯&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
    def __init__(self, key):&lt;br /&gt;
        self.key = key&lt;br /&gt;
        self.url = &amp;quot;https://api.perplexity.ai&amp;quot;&lt;br /&gt;
        self.client = OpenAI(api_key=self.key, base_url=self.url)&lt;br /&gt;
        &lt;br /&gt;
    def build_msgs(self, msg, system_msg=&amp;quot;&amp;quot;) -&amp;gt; list:&lt;br /&gt;
        msgs = [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;role&amp;quot;: &amp;quot;system&amp;quot;,&lt;br /&gt;
                &amp;quot;content&amp;quot;: (system_msg)&lt;br /&gt;
            },&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
                &amp;quot;content&amp;quot;: (msg)&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
        &lt;br /&gt;
        return msgs&lt;br /&gt;
&lt;br /&gt;
    def request(self, msg: str, system_msg=&amp;quot;&amp;quot;, model=&amp;quot;llama-3.1-sonar-small-128k-online&amp;quot;):&lt;br /&gt;
        msgs = self.build_msgs(msg, system_msg)&lt;br /&gt;
        citations = []&lt;br /&gt;
        response = self.client.chat.completions.create(&lt;br /&gt;
            model=model,&lt;br /&gt;
            messages=msgs,&lt;br /&gt;
        )&lt;br /&gt;
        reply = response.choices[0].message.content&lt;br /&gt;
        &lt;br /&gt;
        try:&lt;br /&gt;
            for cit in response.citations:&lt;br /&gt;
                if not cit in citations:&lt;br /&gt;
                    citations.append(cit)&lt;br /&gt;
        except:&lt;br /&gt;
            pass&lt;br /&gt;
        &lt;br /&gt;
        return reply, response, citations&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class Scraper:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    This class is responsible for all scraping operations&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
    def __init__(self, lco_url: str, pplx: PPLX):&lt;br /&gt;
        self.lco_url = lco_url&lt;br /&gt;
        self.lco_equips = f&amp;quot;{lco_url}/ubrowse.php&amp;quot;&lt;br /&gt;
        self.dl_folder = f&amp;quot;{main_directory}/scraped_files&amp;quot;&lt;br /&gt;
        self.imgs_folder = f&amp;quot;{self.dl_folder}/imgs&amp;quot;&lt;br /&gt;
        self.others_folder = f&amp;quot;{self.dl_folder}/other&amp;quot;&lt;br /&gt;
        self.equips_ids = []&lt;br /&gt;
        self.pplx = pplx&lt;br /&gt;
        &lt;br /&gt;
        if not os.path.isdir(self.dl_folder):&lt;br /&gt;
            os.makedirs(self.dl_folder)&lt;br /&gt;
        if not os.path.isdir(self.imgs_folder):&lt;br /&gt;
            os.makedirs(self.imgs_folder)&lt;br /&gt;
        if not os.path.isdir(self.others_folder):&lt;br /&gt;
            os.makedirs(self.others_folder)&lt;br /&gt;
    &lt;br /&gt;
    def get_equips_id_list(self) -&amp;gt; list:&lt;br /&gt;
        equips_raw = requests.get(self.lco_equips)&lt;br /&gt;
        self.equips_ids = []&lt;br /&gt;
        if equips_raw.status_code == 200:&lt;br /&gt;
            try:&lt;br /&gt;
                equips_list_raw = equips_raw.text.split(&amp;quot;&amp;lt;a href=&amp;#039;equip.php?id=&amp;quot;)&lt;br /&gt;
                for span in equips_list_raw:&lt;br /&gt;
                    if span[:3] == &amp;quot;LCO&amp;quot;:&lt;br /&gt;
                        self.equips_ids.append(span[:9])&lt;br /&gt;
            except:&lt;br /&gt;
                print(&amp;quot;Error parsing data. are you sure the site is up and the ID is correct?&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        return self.equips_ids&lt;br /&gt;
&lt;br /&gt;
    def get_equip_data(self, id: str, print_data=False) -&amp;gt; ScrapedEquip:&lt;br /&gt;
        equip = ScrapedEquip()&lt;br /&gt;
        equip.id = id&lt;br /&gt;
        equip_link = f&amp;quot;{self.lco_url}/equip.php?id={equip.id}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        equip.raw = requests.get(equip_link, verify=False)&lt;br /&gt;
        if equip.raw.status_code == 200:&lt;br /&gt;
            equip.raw.encoding = &amp;#039;utf-8&amp;#039;&lt;br /&gt;
            &lt;br /&gt;
            # Get basic information&lt;br /&gt;
            try:&lt;br /&gt;
                equip.inst_type = equip.raw.text.split(&amp;quot;Tipo: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0].split(&amp;quot;: &amp;quot;)[1]&lt;br /&gt;
                equip.name = equip.raw.text.split(&amp;quot;Nome Completo: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.status = equip.raw.text.split(&amp;quot;Status: &amp;lt;/td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;span&amp;quot;)[1].split(&amp;quot;;&amp;#039;&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.location = equip.raw.text.split(&amp;quot;Local: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.serial = equip.raw.text.split(&amp;quot;Serial: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.patrimonio = equip.raw.text.split(&amp;quot;Patrimônio: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.date = equip.raw.text.split(&amp;quot;Data de Entrada: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                equip.keywords = equip.raw.text.split(&amp;quot;Keywords: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;)[1].split(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;)[0]&lt;br /&gt;
                &lt;br /&gt;
                try:&lt;br /&gt;
                    imgurl_split_l = &amp;quot;&amp;lt;image src=&amp;#039;&amp;quot;&lt;br /&gt;
                    imgurl_split_r = &amp;quot;&amp;#039;&amp;quot;&lt;br /&gt;
                    equip.img_url = f&amp;quot;{self.lco_url}/{equip.raw.text.split(imgurl_split_l)[1].split(imgurl_split_r)[0]}&amp;quot;&lt;br /&gt;
                except:&lt;br /&gt;
                    pass&lt;br /&gt;
            except:&lt;br /&gt;
                print(&amp;quot;Error parsing some data. are you sure the site is up and the ID is correct?&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        if print_data:&lt;br /&gt;
            print(equip.id)&lt;br /&gt;
            print(equip.inst_type)&lt;br /&gt;
            print(equip.name)&lt;br /&gt;
            print(equip.status)&lt;br /&gt;
            print(equip.location)&lt;br /&gt;
            print(equip.serial)&lt;br /&gt;
            print(equip.patrimonio)&lt;br /&gt;
            print(equip.date)&lt;br /&gt;
            print(equip.keywords)&lt;br /&gt;
            print(equip.img_url)&lt;br /&gt;
        &lt;br /&gt;
        return equip&lt;br /&gt;
&lt;br /&gt;
    def save_equip_img(self, equip: ScrapedEquip):&lt;br /&gt;
        if equip.img_url != &amp;quot;&amp;quot;:&lt;br /&gt;
            try:&lt;br /&gt;
                response = requests.get(equip.img_url)&lt;br /&gt;
                if response.status_code == 200:&lt;br /&gt;
                    filename = f&amp;quot;{self.imgs_folder}/{equip.id}&amp;quot;&lt;br /&gt;
                    if &amp;quot;jpg&amp;quot; in equip.img_url.lower() or &amp;quot;jpeg&amp;quot; in equip.img_url:&lt;br /&gt;
                        filename = f&amp;quot;{filename}.jpg&amp;quot;&lt;br /&gt;
                    elif &amp;quot;png&amp;quot; in equip.img_url.lower():&lt;br /&gt;
                        filename = f&amp;quot;{filename}.png&amp;quot;&lt;br /&gt;
                    equip.img_file = filename.split(&amp;quot;/&amp;quot;)[-1]&lt;br /&gt;
                    if not os.path.isfile(filename):&lt;br /&gt;
                        with open(filename, &amp;#039;wb&amp;#039;) as file:&lt;br /&gt;
                            file.write(response.content)&lt;br /&gt;
                        print(f&amp;quot;Image downloaded as: {filename}&amp;quot;)&lt;br /&gt;
                    else:&lt;br /&gt;
                        print(f&amp;quot;Image {filename} already exists.&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    print(&amp;quot;Failed to download image&amp;quot;)&lt;br /&gt;
            except:&lt;br /&gt;
                pass&lt;br /&gt;
&lt;br /&gt;
    def create_ai_summary(self, equip: ScrapedEquip, wiki_conv=True):&lt;br /&gt;
        model = &amp;quot;llama-3.1-sonar-huge-128k-online&amp;quot;&lt;br /&gt;
        system_msg = &amp;quot;You are a technology test and measurement expert, a brilliant scientist that knows a lot about scientific experiments, &amp;quot; + \&lt;br /&gt;
                    &amp;quot;especially in the fields of electronics, photonics, optics, and telecommunications, &amp;quot; + \&lt;br /&gt;
                    &amp;quot;and also has access to all kowledge available in the internet.&amp;quot; + \&lt;br /&gt;
                    &amp;quot;Your job is to search the internet and find information about the equipments and instruments that are going to be input in the prompt.&amp;quot; + \&lt;br /&gt;
                    &amp;quot;There are going to be some keywords that can help and the type of instrument it is, that can contain some typos or weird characters &amp;quot; + \&lt;br /&gt;
                    &amp;quot;due to text encoding. Ignore them if it harms more than help.&amp;quot; + \&lt;br /&gt;
                    &amp;quot;Summarize all the information you can find, but in a way that can be useful for students and researchers to quickly know what that &amp;quot; + \&lt;br /&gt;
                    &amp;quot;equipment or instrument can and cannot do, and on which scenarios it could be best used.&amp;quot; + \&lt;br /&gt;
                    &amp;quot;Always reply in english, and only the summary of your findings, please ommit interactions with the user.&amp;quot;              &lt;br /&gt;
        prompt = f&amp;quot;Please find information and summarize it for me, about {equip.name}. It should be of the type {equip.inst_type}. &amp;quot; + \&lt;br /&gt;
                 f&amp;quot;Some keywords that may or may not help: {equip.keywords}. Try to format the summary on a way that will look good in a wiki page.&amp;quot; + \&lt;br /&gt;
                 f&amp;quot;Also please, create a References section at the end of the reply, with all the info about the sources used, even if it would be empty! &amp;quot; + \&lt;br /&gt;
                 f&amp;quot;Some information here may be in portuguese, use it, but please write everything in english.&amp;quot; &lt;br /&gt;
&lt;br /&gt;
        try:&lt;br /&gt;
            print(f&amp;quot;Getting AI summary for {equip.name}. This can take a little while...&amp;quot;)&lt;br /&gt;
            reply, response, citations = self.pplx.request(prompt, system_msg, model)&lt;br /&gt;
            print(f&amp;quot;AI summary request for {equip.name} completed successfully.&amp;quot;)&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            print(f&amp;quot;Error getting AI summary for {equip.name}.&amp;quot;)&lt;br /&gt;
            print(e)&lt;br /&gt;
        &lt;br /&gt;
        if wiki_conv:&lt;br /&gt;
            with warnings.catch_warnings():&lt;br /&gt;
                warnings.simplefilter(&amp;quot;ignore&amp;quot;)&lt;br /&gt;
                md_doc = pandoc.read(reply, format=&amp;#039;markdown&amp;#039;)&lt;br /&gt;
                reply = pandoc.write(md_doc, format=&amp;#039;mediawiki&amp;#039;).replace(&amp;quot;===&amp;quot;, &amp;quot;==&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        equip.summary = reply&lt;br /&gt;
        equip.summary_citations = citations&lt;br /&gt;
&lt;br /&gt;
    def get_lorem_ipsum_filler(ps = 5) -&amp;gt; str:&lt;br /&gt;
        raw = requests.get(&amp;quot;https://loremipsum.io/generator?n=5&amp;amp;t=p&amp;quot;).text.split(&amp;#039;id=&amp;quot;text&amp;quot;&amp;#039;)[1].split(&amp;quot;&amp;lt;/div&amp;gt;&amp;quot;)[0]&lt;br /&gt;
        paragraphs = raw.replace(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;&amp;quot;).replace(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;, &amp;quot;\n&amp;quot;).replace(&amp;quot;&amp;lt;&amp;quot;, &amp;quot;&amp;quot;).replace(&amp;quot;&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        return paragraphs&lt;br /&gt;
    &lt;br /&gt;
    def scrape_equip(self, id: str, ai_summary=False) -&amp;gt; ScrapedEquip:&lt;br /&gt;
        equip = self.get_equip_data(id)&lt;br /&gt;
        self.save_equip_img(equip)&lt;br /&gt;
        if ai_summary:&lt;br /&gt;
            self.create_ai_summary(equip, True)&lt;br /&gt;
        else:&lt;br /&gt;
            equip.summary = self.get_lorem_ipsum_filler()&lt;br /&gt;
            &lt;br /&gt;
        return equip&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
class WikiAPI:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    This class is the interface to MediaWiki Action API&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
    def __init__(self, url, user, passwd):&lt;br /&gt;
        self.url = url&lt;br /&gt;
        self.csrf_token = &amp;quot;&amp;quot;&lt;br /&gt;
        self.session = requests.Session()&lt;br /&gt;
        &lt;br /&gt;
        self.login(user, passwd)&lt;br /&gt;
        &lt;br /&gt;
    def login(self, user, passwd) -&amp;gt; str:        &lt;br /&gt;
        try:&lt;br /&gt;
            PARAMS_0 = {&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;query&amp;quot;,&lt;br /&gt;
                &amp;quot;meta&amp;quot;: &amp;quot;tokens&amp;quot;,&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;login&amp;quot;,&lt;br /&gt;
                &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
            R = self.session.get(url=self.url, params=PARAMS_0, verify=False)&lt;br /&gt;
            DATA = R.json()&lt;br /&gt;
            LOGIN_TOKEN = DATA[&amp;#039;query&amp;#039;][&amp;#039;tokens&amp;#039;][&amp;#039;logintoken&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
            PARAMS_1 = {&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;login&amp;quot;,&lt;br /&gt;
                &amp;quot;lgname&amp;quot;: user,&lt;br /&gt;
                &amp;quot;lgpassword&amp;quot;: passwd,&lt;br /&gt;
                &amp;quot;lgtoken&amp;quot;: LOGIN_TOKEN,&lt;br /&gt;
                &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
            R = self.session.post(url=self.url, data=PARAMS_1, verify=False)&lt;br /&gt;
&lt;br /&gt;
            PARAMS_2 = {&lt;br /&gt;
                &amp;quot;action&amp;quot;: &amp;quot;query&amp;quot;,&lt;br /&gt;
                &amp;quot;meta&amp;quot;: &amp;quot;tokens&amp;quot;,&lt;br /&gt;
                &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
            R = self.session.get(url=self.url, params=PARAMS_2, verify=False)&lt;br /&gt;
            DATA = R.json()&lt;br /&gt;
            self.csrf_token = DATA[&amp;#039;query&amp;#039;][&amp;#039;tokens&amp;#039;][&amp;#039;csrftoken&amp;#039;]&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            print(&amp;quot;Error logging in:&amp;quot;)&lt;br /&gt;
            print(e)&lt;br /&gt;
            &lt;br /&gt;
    def send_edit(self, params) -&amp;gt; bool:&lt;br /&gt;
        R = self.session.post(self.url, data=params)&lt;br /&gt;
        DATA = R.json()&lt;br /&gt;
        try:&lt;br /&gt;
            return DATA[&amp;#039;edit&amp;#039;][&amp;#039;result&amp;#039;] == &amp;#039;Success&amp;#039;&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            try:&lt;br /&gt;
                if DATA[&amp;#039;error&amp;#039;][&amp;#039;code&amp;#039;] == &amp;#039;articleexists&amp;#039;:&lt;br /&gt;
                    print(&amp;quot;Page already exists, moving to override sections&amp;quot;)&lt;br /&gt;
            except Exception as e2:&lt;br /&gt;
                print(e2)&lt;br /&gt;
                print(DATA)&lt;br /&gt;
            return False&lt;br /&gt;
&lt;br /&gt;
    def create_page(self, name: str, text: str) -&amp;gt; bool:&lt;br /&gt;
        PARAMS = {&lt;br /&gt;
            &amp;quot;action&amp;quot;: &amp;quot;edit&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: name,&lt;br /&gt;
            &amp;quot;token&amp;quot;: self.csrf_token,&lt;br /&gt;
            &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;,&lt;br /&gt;
            &amp;quot;text&amp;quot;: text,&lt;br /&gt;
            &amp;quot;createonly&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return self.send_edit(PARAMS)&lt;br /&gt;
        &lt;br /&gt;
    def edit_page(self, name: str, text: str, section = 0, new_section = False, section_title=&amp;quot;&amp;quot;) -&amp;gt; bool:&lt;br /&gt;
        if new_section:&lt;br /&gt;
            section = &amp;quot;new&amp;quot;&lt;br /&gt;
        elif section != 0:&lt;br /&gt;
            text = f&amp;quot;== {section_title} ==\n{text}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        PARAMS = {&lt;br /&gt;
            &amp;quot;action&amp;quot;: &amp;quot;edit&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: name,&lt;br /&gt;
            &amp;quot;token&amp;quot;: self.csrf_token,&lt;br /&gt;
            &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;,&lt;br /&gt;
            &amp;quot;section&amp;quot;: section,&lt;br /&gt;
            &amp;quot;sectiontitle&amp;quot;: section_title,&lt;br /&gt;
            &amp;quot;text&amp;quot;: text,&lt;br /&gt;
            &amp;quot;nocreate&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return self.send_edit(PARAMS)&lt;br /&gt;
        &lt;br /&gt;
    def prepend_to_page(self, name: str, text: str, section = 0) -&amp;gt; bool:&lt;br /&gt;
        PARAMS = {&lt;br /&gt;
            &amp;quot;action&amp;quot;: &amp;quot;edit&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: name,&lt;br /&gt;
            &amp;quot;token&amp;quot;: self.csrf_token,&lt;br /&gt;
            &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;,&lt;br /&gt;
            &amp;quot;section&amp;quot;: section,&lt;br /&gt;
            &amp;quot;prependtext&amp;quot;: text,&lt;br /&gt;
            &amp;quot;nocreate&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return self.send_edit(PARAMS)&lt;br /&gt;
        &lt;br /&gt;
    def append_to_page(self, name: str, text: str, section = 0) -&amp;gt; bool:&lt;br /&gt;
        PARAMS = {&lt;br /&gt;
            &amp;quot;action&amp;quot;: &amp;quot;edit&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: name,&lt;br /&gt;
            &amp;quot;token&amp;quot;: self.csrf_token,&lt;br /&gt;
            &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;,&lt;br /&gt;
            &amp;quot;section&amp;quot;: section,&lt;br /&gt;
            &amp;quot;appendtext&amp;quot;: text,&lt;br /&gt;
            &amp;quot;nocreate&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return self.send_edit(PARAMS)&lt;br /&gt;
        &lt;br /&gt;
    def upload_file(self, file_path: str, comment=&amp;quot;&amp;quot;, text=&amp;quot;&amp;quot;) -&amp;gt; bool:&lt;br /&gt;
        name = file_path.replace(&amp;quot;\\&amp;quot;, &amp;quot;/&amp;quot;).split(&amp;quot;/&amp;quot;)[-1]&lt;br /&gt;
        text = text.encode(&amp;#039;utf-8&amp;#039;)&lt;br /&gt;
        PARAMS = {&lt;br /&gt;
            &amp;quot;action&amp;quot;: &amp;quot;upload&amp;quot;,&lt;br /&gt;
            &amp;quot;filename&amp;quot;: name,&lt;br /&gt;
            &amp;quot;comment&amp;quot;: comment,&lt;br /&gt;
            &amp;quot;text&amp;quot;: text,&lt;br /&gt;
            &amp;quot;format&amp;quot;: &amp;quot;json&amp;quot;,&lt;br /&gt;
            &amp;quot;token&amp;quot;: self.csrf_token,&lt;br /&gt;
            &amp;quot;ignorewarnings&amp;quot;: 0&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        FILE = {&amp;#039;file&amp;#039;:(name, open(file_path, &amp;#039;rb&amp;#039;), &amp;#039;multipart/form-data&amp;#039;)}&lt;br /&gt;
&lt;br /&gt;
        try:&lt;br /&gt;
            R = self.session.post(self.url, files=FILE, data=PARAMS, verify=False)&lt;br /&gt;
            DATA = R.json()&lt;br /&gt;
            return DATA[&amp;#039;upload&amp;#039;][&amp;#039;result&amp;#039;] == &amp;#039;Success&amp;#039;&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            print(e)&lt;br /&gt;
            return False&lt;br /&gt;
        &lt;br /&gt;
def create_equip_wiki(equip: ScrapedEquip, abort_if_exists=True, stages_to_override=10*[False]):&lt;br /&gt;
    # Create page and add main text&lt;br /&gt;
    page_created = wiki.create_page(equip.name, &amp;quot;&amp;quot;)&lt;br /&gt;
    if page_created or (not abort_if_exists):       &lt;br /&gt;
        # Set main text&lt;br /&gt;
        s = 0&lt;br /&gt;
        if page_created or (not page_created and stages_to_override[s]):&lt;br /&gt;
            wiki.edit_page(equip.name, equip.summary)&lt;br /&gt;
&lt;br /&gt;
        # Add other scraped info&lt;br /&gt;
        s = 1&lt;br /&gt;
        other_text = f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Status&amp;#039;&amp;#039;&amp;#039;: {equip.status}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Last known location&amp;#039;&amp;#039;&amp;#039;: {equip.location}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Serial&amp;#039;&amp;#039;&amp;#039;: {equip.serial}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Inventory ID&amp;#039;&amp;#039;&amp;#039;: {equip.patrimonio}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Arrival Date&amp;#039;&amp;#039;&amp;#039;: {equip.date}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Keywords&amp;#039;&amp;#039;&amp;#039;: {equip.keywords}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Old LCO ID&amp;#039;&amp;#039;&amp;#039;: {equip.id}\n&amp;quot; + \&lt;br /&gt;
                     f&amp;quot;* &amp;#039;&amp;#039;&amp;#039;Old LCO Category&amp;#039;&amp;#039;&amp;#039;: {equip.inst_type}\n&amp;quot;&lt;br /&gt;
        if page_created or (not page_created and stages_to_override[s]):&lt;br /&gt;
            wiki.edit_page(equip.name, text=other_text.replace(&amp;quot;  &amp;quot;, &amp;quot;&amp;quot;), new_section=True, section_title=&amp;quot;Other info&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        # Upload Image&lt;br /&gt;
        s = 2&lt;br /&gt;
        if page_created or (not page_created and stages_to_override[s]):&lt;br /&gt;
            img_file = f&amp;quot;{scraper.imgs_folder}/{equip.img_file}&amp;quot;&lt;br /&gt;
            &lt;br /&gt;
            # Resize image to 2160 px high (4K)&lt;br /&gt;
            target_height = 2160&lt;br /&gt;
            img = Image.open(img_file)&lt;br /&gt;
            if img.size[1] &amp;gt; target_height:&lt;br /&gt;
                height_percent = (target_height / float(img.size[1]))&lt;br /&gt;
                target_width = int((float(img.size[0]) * float(height_percent)))&lt;br /&gt;
                resized_image = img.resize((target_width, target_height), Image.Resampling.LANCZOS)&lt;br /&gt;
                resized_image.save(img_file)&lt;br /&gt;
            &lt;br /&gt;
            wiki.upload_file(img_file, comment=f&amp;quot;Photo of {equip.name}&amp;quot;, text=f&amp;quot;Photo of {equip.name}&amp;quot;)&lt;br /&gt;
        &lt;br /&gt;
        # Place image in text&lt;br /&gt;
        s = 3&lt;br /&gt;
        if page_created or (not page_created and stages_to_override[s]):&lt;br /&gt;
            img_text = f&amp;quot;[[File:{equip.img_file}|alt={equip.name}|thumb|{equip.name}]]&amp;quot;&lt;br /&gt;
            wiki.prepend_to_page(equip.name, text=img_text, section=0)&lt;br /&gt;
        &lt;br /&gt;
        # Set Category&lt;br /&gt;
        s = 4&lt;br /&gt;
        if page_created or (not page_created and stages_to_override[s]):&lt;br /&gt;
            wiki.append_to_page(equip.name, &amp;quot;\n\n[[Category:Instruments]]&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Main definitions&lt;br /&gt;
lco_url = &amp;quot;http://143.106.153.11/LCOSys&amp;quot;&lt;br /&gt;
wiki_type = &amp;quot;prod&amp;quot;  # test or prod&lt;br /&gt;
test_on_random_id = False  # To test on a random equipment. Overrides id set on test_id.&lt;br /&gt;
test_id = &amp;quot;LCO110101&amp;quot;&lt;br /&gt;
ai_summary = True&lt;br /&gt;
abort_if_exists = False&lt;br /&gt;
overrides = [False, False, False, False, False]  # [Main text, Extra text, Image upload, Image in text, Category set]&lt;br /&gt;
&lt;br /&gt;
# Enable this to run for many equipments&lt;br /&gt;
# To do ALL, set start_i to 0, and end_i to -1&lt;br /&gt;
DO_MANY = True&lt;br /&gt;
start_i = 100&lt;br /&gt;
end_i = -1&lt;br /&gt;
&lt;br /&gt;
# Connect to Perplexity&lt;br /&gt;
with open(&amp;quot;pplx_api.txt&amp;quot;, &amp;#039;r&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as file:&lt;br /&gt;
    pplx_key = file.readline()&lt;br /&gt;
pplx = PPLX(pplx_key)&lt;br /&gt;
&lt;br /&gt;
# Create Scraper&lt;br /&gt;
scraper = Scraper(lco_url, pplx)&lt;br /&gt;
&lt;br /&gt;
# Switch between test and prod Wiki&lt;br /&gt;
if wiki_type == &amp;quot;prod&amp;quot;:&lt;br /&gt;
    wiki_url = &amp;quot;https://photonwiki.ifi.unicamp.br/wiki/api.php&amp;quot;&lt;br /&gt;
    credsfile = &amp;quot;photonbot.txt&amp;quot;&lt;br /&gt;
else:&lt;br /&gt;
    wiki_url = &amp;quot;http://143.106.153.11/media_wiki_demo/api.php&amp;quot;&lt;br /&gt;
    credsfile = &amp;quot;testbot.txt&amp;quot;&lt;br /&gt;
with open(credsfile, &amp;#039;r&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as file:&lt;br /&gt;
    bot_login = file.readline()[:-1]&lt;br /&gt;
    bot_passwd = file.readline()&lt;br /&gt;
&lt;br /&gt;
# Connect to Wiki&lt;br /&gt;
wiki = WikiAPI(wiki_url, bot_login, bot_passwd)&lt;br /&gt;
&lt;br /&gt;
# Get equipment id list&lt;br /&gt;
scraper.get_equips_id_list()&lt;br /&gt;
if end_i &amp;lt; 0:&lt;br /&gt;
    end_i = len(scraper.equips_ids) - 1&lt;br /&gt;
if DO_MANY:&lt;br /&gt;
    n_equips = end_i - start_i + 1&lt;br /&gt;
else:&lt;br /&gt;
    n_equips = 1&lt;br /&gt;
    &lt;br /&gt;
if not DO_MANY:&lt;br /&gt;
    # Specify equip to test, or try a random one&lt;br /&gt;
    if test_on_random_id:&lt;br /&gt;
        id_idx = np.random.randint(0, len(scraper.equips_ids))&lt;br /&gt;
        test_id = scraper.equips_ids[id_idx]&lt;br /&gt;
&lt;br /&gt;
    # Scrape data for selected equipment(s)&lt;br /&gt;
    test_equip = scraper.scrape_equip(test_id, ai_summary=ai_summary)&lt;br /&gt;
&lt;br /&gt;
    # Create Wiki page and fill it&lt;br /&gt;
    create_equip_wiki(test_equip, abort_if_exists, overrides)&lt;br /&gt;
else:&lt;br /&gt;
    # Do the above for the range of equipments selected&lt;br /&gt;
    t00 = time.time()&lt;br /&gt;
    t0 = time.time()&lt;br /&gt;
    for i in range(start_i, end_i + 1):&lt;br /&gt;
        equip_id = scraper.equips_ids[i]&lt;br /&gt;
        equip = scraper.scrape_equip(equip_id, ai_summary=ai_summary)&lt;br /&gt;
        create_equip_wiki(equip, abort_if_exists, overrides)&lt;br /&gt;
        perc = (i - start_i + 1)/(n_equips)&lt;br /&gt;
        t1 = time.time()&lt;br /&gt;
        dt = t1 - t0&lt;br /&gt;
        el_t = t1 - t00&lt;br /&gt;
        tt = el_t/perc&lt;br /&gt;
        rt = tt - el_t&lt;br /&gt;
        t0 = time.time()&lt;br /&gt;
        print(f&amp;quot;{i - start_i + 1}/{n_equips} pages done ({100.0*perc:.2f}%). {rt:.2f} s left.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jarschel</name></author>
	</entry>
</feed>