diff --git a/infinywiki2.py b/infinywiki2.py new file mode 100644 index 0000000..421b08d --- /dev/null +++ b/infinywiki2.py @@ -0,0 +1,291 @@ +from flask import Flask, render_template_string, request, jsonify +import wikipedia +import requests +import warnings +from bs4 import GuessedAtParserWarning +from wikipedia.exceptions import DisambiguationError, PageError + +# Disable BeautifulSoup parser warnings +warnings.filterwarnings("ignore", category=GuessedAtParserWarning) + +app = Flask(__name__) + +# Configure Wikipedia language and user agent +wikipedia.set_lang("en") +user_agent = "WikiFlow/1.0 (jelnique@gmail.com)" +wikipedia.set_user_agent(user_agent) + +# A set to keep track of pages that have already been loaded +visited_pages = set() + +# Global variables to cache search results +cached_search_results = [] +current_search_term = "" +current_search_index = 0 + +def get_wikipedia_page(title, visited=None): + """ + Attempts to fetch a Wikipedia page for a given title. + If a DisambiguationError is raised, iterates through the options, + skipping those containing 'disambiguation' and avoiding loops. + """ + if visited is None: + visited = set() + if title in visited: + print(f"Already visited '{title}', stopping recursion.") + return None + visited.add(title) + try: + # Use auto_suggest=False for a more exact match + page = wikipedia.page(title, auto_suggest=False) + return page + except DisambiguationError as e: + print(f"Disambiguation error for '{title}': {e.options}") + # Try each option that does not contain "disambiguation" + for option in e.options: + if "disambiguation" in option.lower(): + continue + candidate = get_wikipedia_page(option, visited) + if candidate: + return candidate + print(f"No suitable disambiguation found for '{title}'") + return None + except PageError as e: + print(f"Page error for '{title}': {e}") + return None + +@app.route('/search', methods=['POST']) +def search(): + """ + Performs a search using the provided term and caches a list of titles. + Returns the first two valid articles from the cached results. + """ + global current_search_term, cached_search_results, current_search_index, visited_pages + search_term = request.json.get('search_term') + if not search_term: + return jsonify({'articles': []}) + + current_search_term = search_term + try: + # Get up to 50 search results for better filtering options + results = wikipedia.search(search_term, results=50) + except Exception as e: + print("Search error:", e) + return jsonify({'articles': []}) + + cached_search_results = results + current_search_index = 0 # reset the index for a new search + articles = [] + + # Loop through cached results until we have two valid articles + while current_search_index < len(cached_search_results) and len(articles) < 2: + title = cached_search_results[current_search_index] + current_search_index += 1 + page = get_wikipedia_page(title) + if page and page.title not in visited_pages: + articles.append({ + 'title': page.title, + 'url': f"https://en.wikipedia.org/wiki/{page.title.replace(' ', '_')}" + }) + visited_pages.add(page.title) + return jsonify({'articles': articles}) + +@app.route('/next_article', methods=['POST']) +def next_article(): + """ + Returns the next two valid articles from the cached search results. + """ + global current_search_term, cached_search_results, current_search_index, visited_pages + if not current_search_term: + return jsonify({'articles': []}) + + articles = [] + while current_search_index < len(cached_search_results) and len(articles) < 2: + title = cached_search_results[current_search_index] + current_search_index += 1 + page = get_wikipedia_page(title) + if page and page.title not in visited_pages: + articles.append({ + 'title': page.title, + 'url': f"https://en.wikipedia.org/wiki/{page.title.replace(' ', '_')}" + }) + visited_pages.add(page.title) + return jsonify({'articles': articles}) + +@app.route('/') +def index(): + return render_template_string(TEMPLATE) + +def is_valid_article(title): + """ + A basic validation to rule out empty or purely numeric titles. + (Spaces are allowed since most Wikipedia articles include them.) + """ + return bool(title) and not title.isdigit() + +TEMPLATE = """ + + + + + + WikiFlow - Infinite Wikipedia + + + + + +
+ + +
+ + +
Welcome! Search an article.
+
+ + +
+ + +
Scroll for more articles
+ + + + + +""" + +if __name__ == '__main__': + app.run(debug=True) diff --git a/infywiki.py b/infywiki.py new file mode 100644 index 0000000..b16dffe --- /dev/null +++ b/infywiki.py @@ -0,0 +1,241 @@ +from flask import Flask, render_template_string, request, jsonify +import wikipedia +import requests +import warnings +from bs4 import GuessedAtParserWarning +from wikipedia.exceptions import DisambiguationError, PageError + +# Disable BeautifulSoup parser warnings +warnings.filterwarnings("ignore", category=GuessedAtParserWarning) + +app = Flask(__name__) + +# Configure Wikipedia language and user agent +wikipedia.set_lang("en") +user_agent = "WikiFlow/1.0 (jelnique@gmail.com)" +wikipedia.set_user_agent(user_agent) + +# A set to keep track of pages that have already been loaded +visited_pages = set() + +# Global variables to cache search results +cached_search_results = [] +current_search_term = "" +current_search_index = 0 + +def get_wikipedia_page(title, visited=None): + """ + Attempts to fetch a Wikipedia page for a given title. + If a DisambiguationError is raised, iterates through the options, + skipping those containing 'disambiguation' and avoiding loops. + """ + if visited is None: + visited = set() + if title in visited: + print(f"Already visited '{title}', stopping recursion.") + return None + visited.add(title) + try: + # Use auto_suggest=False for a more exact match + page = wikipedia.page(title, auto_suggest=False) + return page + except DisambiguationError as e: + print(f"Disambiguation error for '{title}': {e.options}") + # Try each option that does not contain "disambiguation" + for option in e.options: + if "disambiguation" in option.lower(): + continue + candidate = get_wikipedia_page(option, visited) + if candidate: + return candidate + print(f"No suitable disambiguation found for '{title}'") + return None + except PageError as e: + print(f"Page error for '{title}': {e}") + return None + +@app.route('/search', methods=['POST']) +def search(): + """ + Performs a search using the provided term and caches a list of titles. + Returns the first two valid articles from the cached results. + """ + global current_search_term, cached_search_results, current_search_index, visited_pages + search_term = request.json.get('search_term') + if not search_term: + return jsonify({'articles': []}) + + current_search_term = search_term + try: + # Get up to 50 search results for better filtering options + results = wikipedia.search(search_term, results=50) + except Exception as e: + print("Search error:", e) + return jsonify({'articles': []}) + + cached_search_results = results + current_search_index = 0 # reset the index for a new search + articles = [] + + # Loop through cached results until we have two valid articles + while current_search_index < len(cached_search_results) and len(articles) < 2: + title = cached_search_results[current_search_index] + current_search_index += 1 + page = get_wikipedia_page(title) + if page and page.title not in visited_pages: + articles.append({ + 'title': page.title, + 'url': f"https://en.wikipedia.org/wiki/{page.title.replace(' ', '_')}" + }) + visited_pages.add(page.title) + return jsonify({'articles': articles}) + +@app.route('/next_article', methods=['POST']) +def next_article(): + """ + Returns the next two valid articles from the cached search results. + """ + global current_search_term, cached_search_results, current_search_index, visited_pages + if not current_search_term: + return jsonify({'articles': []}) + + articles = [] + while current_search_index < len(cached_search_results) and len(articles) < 2: + title = cached_search_results[current_search_index] + current_search_index += 1 + page = get_wikipedia_page(title) + if page and page.title not in visited_pages: + articles.append({ + 'title': page.title, + 'url': f"https://en.wikipedia.org/wiki/{page.title.replace(' ', '_')}" + }) + visited_pages.add(page.title) + return jsonify({'articles': articles}) + +@app.route('/') +def index(): + return render_template_string(TEMPLATE) + +def is_valid_article(title): + """ + A basic validation to rule out empty or purely numeric titles. + (Spaces are allowed since most Wikipedia articles include them.) + """ + return bool(title) and not title.isdigit() + +TEMPLATE = """ + + + + + + WikiFlow - Infinite Wikipedia + + + + +
+ + +
Welcome! Search an article.
+
+ +
+

Loading next articles...

+
+ +
+ + + + + +""" + +if __name__ == '__main__': + app.run(debug=True) diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..d9b7b87 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,99 @@ + + + + + + WikiFlow - Infinite Wikipedia + + + +
+
+ + +
+
+ + + diff --git a/templates/indexWikiold.html b/templates/indexWikiold.html new file mode 100644 index 0000000..48fe3da --- /dev/null +++ b/templates/indexWikiold.html @@ -0,0 +1,145 @@ + + + + + + Wikipedia Infinite Scroll + + + + +

Wikipedia Infinite Scroll

+ +
+ + +
+ +
+
+

Loading next article...

+
+ +
+ + + + +