Générateur d'idées pour articles

This page is a translated version of the page API:Article ideas generator and the translation is 55% complete.

Présentation

Dans ce tutoriel, vous obtiendrez une démonstration d'une application génératrice d'idées d'articles qui suggère des articles de différentes catégories qui n'existent pas encore sur Wikipédia en anglais.

Ce tutoriel vous montrera comment le faire avec :

Processus pas à pas pour construire cette application :

Etape 1 : installer l'environnement de développement Python et Flask

Pour configurer l’environnement de développement Python pour une application Flask, vous devez installer Python, créer un environnement virtuel et installer Flask et Requests.

Cette application utilise Python3, la version recommandée pour les nouveaux projets Python.

Pour en savoir plus sur les différences entre Python2 et Python3, cliquez ici. Pour installer Python3 sur votre machine locale, suivez les instructions étape par étape dans ces guides d'installation .

Voici comment configurer l’environnement de développement pour la construction de l’application :

$ mkdir article-ideas-generator
$ cd article-ideas-generator/
Cela créera un nouveau répertoire et l'y changera
$ python3 --version #Python 3.6.5
Cette commande vérifie votre version de Python 
$ python3 -m venv venv
Cette commmande crée un environnement virtuel nommé 'venv'
$ source venv/bin/activate
Cela activera l’environnement virtuel
$ pip install Flask requests
Cette commande installera les packages Flask et Requests avec toutes leurs dépendances

Etape 2 : créer une application Flask simple

Générer une page statique simple

Mettre le code suivant dans $HOME/article-ideas-generator/articles.py

#!/usr/bin/python3

"""
    articles.py1

    Exemples de code de l'API Action de MediaWiki

    Application de génération d’idées d’articles : suggère des articles de diverses catégories qui n’existent pas encore sur Wikipédia en anglais.
    L’application utilise un module de action=parse et un module de prop=links comme générateur.

    license MIT
"""

from flask import Flask, request, render_template
import requests

APP = Flask(__name__)

@APP.route('/')
def index():
    """ Displays the index page accessible at '/'
    """
    return render_template('articles.html')

if __name__ == '__main__':
    APP.run()

Drop this one line of code ‎<h1>Article ideas generator‎</h1> in a HTML file inside the templates folder: $article-ideas-generator/templates/articles.html

In this simple application, we are using render_template method which renders the template named articles.html from the templates directory.

Next run your Flask app with the command python articles.py and open http://127.0.0.1:5000/ to view your app in the browser. You should be able to see "Article ideas generator" in your browser window.

Mettre en forme votre application

Remettons en forme un peu l'application. To do so, add link tags to load an external and internal stylesheet. External stylesheet, in this case, is the URL of a CSS file for the font Amatic.

Replace the existing code in $article-ideas-generator/templates/articles.html with the following:

<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans">
<link rel="stylesheet" href="/static/style.css">

<h1>Article ideas generator</h1>
<p>Some ideas for topics to write articles on:</p>

Mettre le code suivant dans $HOME/article-ideas-generator/static/style.css

h1 {
    color: black;
    font-family: 'Amatic SC', cursive;
    font-size: 4.5em;
    font-weight: normal;
}

p {
    font-family: 'Josefin Sans', sans-serif;
    font-size: 1.4em;
}
 
Article ideas generator demo app

Affichage des applications

$HOME/article-ideas-generator
├── templates/
│   └── articles.html
├── static/
│   └── style.css
├── articles.py
└── venv/

Etape 3 : atteindre les sections des pages de Wikipedia:Requested articles

Let's write some code in a get_page_sections() function in $HOME/article-ideas-generator/articles.py to fetch page sections from Wikipedia:Requested articles. This function takes page name as an argument and makes a GET request to the Action API to parse sections of the page. API call consists of an endpoint https://en.wikipedia.org/w/api.php and query string parameters. Voici quelques paramètres clés :

  • action=parse - module dont le contenu est à analyser sur une page
  • page=page - titre de page à analyser
  • prop=sections - tells which piece of information to retrieve, in this example it is sections
For more information on the parse module, see API:Analyse syntaxique du wikicode .
def get_page_sections(page):
    """ Get page sections
    """
    params = {
        "action": "parse",
        "page": page,
        "prop": "sections",
        "format": "json"
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()

    if 'error' in data:
        return

    parsed_sections = data and data['parse'] and data['parse']['sections']
    sections = []

    for section in parsed_sections:
        if section['toclevel'] == 1:
            sections.append(section['line'])

    return sections

Next, extend the Python Flask route / in $HOME/article-ideas-generator/articles.py to call the function defined above and also pass the results returned by the function to render_template.

APP = Flask(__name__)
SESSION = requests.Session()
API_ENDPOINT = 'https://en.wikipedia.org/w/api.php'
PAGE = {}

@APP.route('/')
def index():
    """ Displays the index page accessible at '/'
    """
    global PAGE
    results = []

    PAGE = {'name': 'Wikipedia:Requested_articles', 'type': 'category'}
    results = get_page_sections(PAGE['name'])

    return render_template(
        "articles.html",
        results=results,
        pagetype=PAGE['type'])

Place the following Jinja template code in $HOME/article-ideas-generator/templates/articles.html. It dynamically renders an array of category buttons based on page sections obtained via the API above.

{% if results %}
<p>Choose a {{ pagetype }}</p>
<form method="POST">
{% for pagename in results %}
<button name="{{ pagetype }}" class="{{ pagetype }}" value="{{ pagename }}">{{ pagename }}</button>
{% endfor %}
{% else %}
<p>Ooooops! We couldn't find any results.</p>
<button onclick="location.href='/'">Start over</button>
</form>
{% endif %}

Place the following code in $HOME/article-ideas-generator/static/style.css for button styling.

div {
    left: 10%;
    position: absolute;
    right: 10%;
    text-align: center;
    top: 5%;
}

button {
    background-color: #06b6c9;
    border: none;
    border-radius: 5px;
    color: white;
    font-size: 1.2em;
    margin: 5px;
    padding: 20px;
}
 
Choose a category page in the demo app

Etape 4 : obtenir plus de sections en fonction de la sélection de l'utilisateur

Based on a category or section selected by the user in the previous step, we want to fetch subsections from Wikipedia:Requested articles. Extend the Python Flask route / in $HOME/article-ideas-generator/articles.py to handle POST requests. You can do so by adding both GET and POST in the methods argument list in the route decorator. You can then obtain category selection available in a dictionary format from the request object, which is passed to get_page_sections() function for further processing.

# Modify the APP route to support both GET and POST requests
@APP.route('/', methods=['GET', 'POST'])

# Add these lines in the index() function
if request.method == 'POST':
    PAGE['name'] = PAGE['name'] + '/' + \
        request.form.to_dict()['category']
    PAGE['type'] = 'subcategory'
 
Choose a subcategory page in the demo app. Showing subcategories for category Natural Sciences (see screenshot above)

Etape 5 : regrouper et afficher les articles ayant des liens manquants

Let's write some code in a get_red_links() function in $HOME/article-ideas-generator/articles.py to fetch around 20 articles with missing links on a page. This function takes page name as an argument, makes a GET request to the Action API, and returns all links embedded on that page. From further extraction, you can obtain those links that are missing and don't yet exist on English Wikipedia. The API call consists of an endpoint https://en.wikipedia.org/w/api.php and query string parameters. Some of the key parameters are:

  • action=query - module to query information
  • titles=title - page title to collect links
  • generator=links - query module's submodule links used as a generator module to get a set of links embedded on a page
  • gpllimit=20 - number of links to fetch
For more information on the parse module, see API:Links .
def get_red_links(title):
    """ Get missing links on a page
    """
    params = {
        "action": "query",
        "titles": title,
        "generator": "links",
        "gpllimit": 20,
        "format": "json"
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()
    pages = data and data['query'] and data['query']['pages']
    links = []

    for page in pages.values():
        if 'missing' in page:
            links.append(page['title'])

    return links

Next, extend the if block for the POST method in the / route in $HOME/article-ideas-generator/articles.py to call the get_red_links() function if the page from which the request is issued is of type subcategory.

if request.method == 'POST':
    if 'category' in request.form:
        PAGE['name'] = PAGE['name'] + '/' + request.form.to_dict()['category']
        PAGE['type'] = 'subcategory'
        results = get_page_sections(PAGE['name'])
    elif 'subcategory' in request.form:
        PAGE['name'] = PAGE['name'] + '#' + request.form.to_dict()['subcategory']
        PAGE['type'] = 'links'
        results = get_red_links(PAGE['name'])

Place the following Jinja template code in $HOME/article-ideas-generator/templates/articles.html. Il affiche dynamiquement une liste de liens à l’aide de données obtenues via l’API ci-dessus.

{% if 'links' in pagetype %}
    <p>Some ideas for topics to write articles on:</p>
    {% for link in results %}
      <a href="//en.wikipedia.org/w/index.php?title={{ link }}&action=edit&redlink=1">{{ link }}</a><br>
    {% endfor %}
    <button onclick="location.href='/'">Take me to the homepage</button>
{% endif %}
 
Page de Missing links dans l’application de démonstration

Consultez le code complet Python, CSS et HTML.

$HOME/article-ideas-generator/articles.py
#!/usr/bin/python3

"""
    articles.py

    Exemples de code de l'API Action de MediaWiki

    Application de génération d’idées d’articles : suggère des articles de diverses catégories qui n’existent pas encore sur Wikipédia en anglais. L’application utilise un module de action=parse et un module de prop=links comme générateur.

    Licence MIT
"""

from flask import Flask, request, render_template
import requests

APP = Flask(__name__)
SESSION = requests.Session()
API_ENDPOINT = 'https://en.wikipedia.org/w/api.php'
PAGE = {}


@APP.route('/', methods=['GET', 'POST'])
def index():
    """ Affiche la page d’index accessible à '/'
    """
    global PAGE
    results = []

    if request.method == 'POST':
        if 'category' in request.form:
            PAGE['name'] = PAGE['name'] + '/' + \
                request.form.to_dict()['category']
            PAGE['type'] = 'subcategory'
            results = get_page_sections(PAGE['name'])
        elif 'subcategory' in request.form:
            PAGE['name'] = PAGE['name'] + '#' + \
                request.form.to_dict()['subcategory']
            PAGE['type'] = 'links'
            results = get_red_links(PAGE['name'])
    else:
        PAGE = {'name': 'Wikipedia:Requested_articles', 'type': 'category'}
        results = get_page_sections(PAGE['name'])

    return render_template(
        "articles.html",
        results=results,
        pagetype=PAGE['type'])


def get_page_sections(page):
    """ Obtenir des sections de page
    """
    params = {
        "action": "parse",
        "page": page,
        "prop": "sections",
        "format": "json"
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()

    if 'error' in data:
        return

    parsed_sections = data and data['parse'] and data['parse']['sections']
    sections = []

    for section in parsed_sections:
        if section['toclevel'] == 1:
            sections.append(section['line'])

    return sections


def get_red_links(title):
    """ Obtenir les liens manquants sur une page
    """
    params = {
        "action": "query",
        "titles": title,
        "generator": "links",
        "gpllimit": 20,
        "format": "json"
    }

    res = SESSION.get(url=API_ENDPOINT, params=params)
    data = res.json()
    pages = data and data['query'] and data['query']['pages']
    links = []

    for page in pages.values():
        if 'missing' in page:
            links.append(page['title'])

    return links


if __name__ == '__main__':
    APP.run()


$HOME/article-ideas-generator/static/style.css
h1 {
    color: black;
    font-family: 'Amatic SC', cursive;
    font-size: 4.5em;
    font-weight: normal;
}

div {
    left: 10%;
    position: absolute;
    right: 10%;
    text-align: center;
    top: 5%;
}

p {
    font-family: 'Josefin Sans', sans-serif;
    font-size: 1.4em;
}

button {
    background-color: #06b6c9;
    border: none;
    border-radius: 5px;
    color: white;
    font-size: 1.2em;
    margin: 5px;
    padding: 20px;
}

.subcategory {
    background-color: #EE6352;
}

a {
    color: red;
    font-size: 1.2em;
    line-height: 1.4em;
}
$HOME/article-ideas-generator/templates/articles.html
<title>Article ideas generator</title>

<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans">
<link rel="stylesheet" href="/static/style.css">

<div>
  <h1>Article ideas generator</h1>
  {% if 'links' in pagetype %}
    <p>Some ideas for topics to write articles on:</p>
    {% for link in results %}
      <a href="//en.wikipedia.org/w/index.php?title={{ link }}&action=edit&redlink=1">{{ link }}
    </a>
    <br>
  {% endfor %}
  <button onclick="location.href='/'">Take me to the homepage</button>
  {% else %}
  {% if results %}
  <p>Choose a {{ pagetype }}</p>
  <form method="POST">
    {% for pagename in results %}
    <button name="{{ pagetype }}" class="{{ pagetype }}" value="{{ pagename }}">{{ pagename }}</button>
  {% endfor %}
  {% else %}
  <p>Ooooops! We couldn't find any results.</p>
  <button onclick="location.href='/'">Start over</button>
  </form>
  {% endif %}
  {% endif %}
</div>


Étapes suivantes

Voir aussi