Drop unused jobs page.
Last job was posted on january 2022, 10 month ago.
This commit is contained in:
parent
1da49c227e
commit
754f4178d3
|
@ -47,18 +47,15 @@ def page_not_found(e):
|
||||||
|
|
||||||
from afpy.routes.home import home_bp
|
from afpy.routes.home import home_bp
|
||||||
from afpy.routes.posts import posts_bp, post_render
|
from afpy.routes.posts import posts_bp, post_render
|
||||||
from afpy.routes.jobs import jobs_bp, jobs_render
|
|
||||||
from afpy.routes.rss import rss_bp
|
from afpy.routes.rss import rss_bp
|
||||||
|
|
||||||
application.register_blueprint(home_bp)
|
application.register_blueprint(home_bp)
|
||||||
application.register_blueprint(posts_bp)
|
application.register_blueprint(posts_bp)
|
||||||
application.register_blueprint(jobs_bp)
|
|
||||||
application.register_blueprint(rss_bp)
|
application.register_blueprint(rss_bp)
|
||||||
|
|
||||||
|
|
||||||
from afpy.models.AdminUser import AdminUser, AdminUser_Admin
|
from afpy.models.AdminUser import AdminUser, AdminUser_Admin
|
||||||
from afpy.models.NewsEntry import NewsEntry, NewsEntry_Admin
|
from afpy.models.NewsEntry import NewsEntry, NewsEntry_Admin
|
||||||
from afpy.models.JobPost import JobPost, JobPost_Admin
|
|
||||||
from afpy.models.Slug import Slug, SlugAdmin
|
from afpy.models.Slug import Slug, SlugAdmin
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +63,6 @@ from afpy.routes.admin import (
|
||||||
AdminIndexView,
|
AdminIndexView,
|
||||||
NewAdminView,
|
NewAdminView,
|
||||||
ChangePasswordView,
|
ChangePasswordView,
|
||||||
JobsModerateView,
|
|
||||||
NewsModerateView,
|
NewsModerateView,
|
||||||
CustomFileAdmin,
|
CustomFileAdmin,
|
||||||
)
|
)
|
||||||
|
@ -81,10 +77,8 @@ admin = Admin(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Registers the views for each table
|
# Registers the views for each table
|
||||||
admin.add_view(JobsModerateView(name="Moderate Jobs", endpoint="jobs_moderation", category="Moderate"))
|
|
||||||
admin.add_view(NewsModerateView(name="Moderate News", endpoint="news_moderation", category="Moderate"))
|
admin.add_view(NewsModerateView(name="Moderate News", endpoint="news_moderation", category="Moderate"))
|
||||||
admin.add_view(NewsEntry_Admin(NewsEntry))
|
admin.add_view(NewsEntry_Admin(NewsEntry))
|
||||||
admin.add_view(JobPost_Admin(JobPost))
|
|
||||||
admin.add_view(SlugAdmin(Slug))
|
admin.add_view(SlugAdmin(Slug))
|
||||||
admin.add_view(CustomFileAdmin(config.IMAGES_PATH, "/images/", name="Images Files"))
|
admin.add_view(CustomFileAdmin(config.IMAGES_PATH, "/images/", name="Images Files"))
|
||||||
admin.add_view(NewAdminView(name="New Admin", endpoint="register_admin", category="Admin"))
|
admin.add_view(NewAdminView(name="New Admin", endpoint="register_admin", category="Admin"))
|
||||||
|
@ -107,10 +101,7 @@ def get_slug_url(item):
|
||||||
url_root = request.url_root
|
url_root = request.url_root
|
||||||
slug = item.slug.where(Slug.canonical == True).first() # noqa
|
slug = item.slug.where(Slug.canonical == True).first() # noqa
|
||||||
if not slug:
|
if not slug:
|
||||||
if isinstance(item, JobPost):
|
return url_root[:-1] + "/actualites/" + str(item.id)
|
||||||
return url_root[:-1] + "/emplois/" + str(item.id)
|
|
||||||
else:
|
|
||||||
return url_root[:-1] + "/actualites/" + str(item.id)
|
|
||||||
else:
|
else:
|
||||||
return url_root[:-1] + slug.url
|
return url_root[:-1] + slug.url
|
||||||
|
|
||||||
|
@ -122,5 +113,3 @@ def slug_fallback(slug):
|
||||||
abort(404)
|
abort(404)
|
||||||
if slug.newsentry:
|
if slug.newsentry:
|
||||||
return post_render(slug.newsentry.id)
|
return post_render(slug.newsentry.id)
|
||||||
elif slug.jobpost:
|
|
||||||
return jobs_render(slug.jobpost.id)
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
from flask_pagedown.fields import PageDownField
|
|
||||||
from flask_wtf import FlaskForm
|
|
||||||
from wtforms import FileField
|
|
||||||
from wtforms import StringField
|
|
||||||
from wtforms import validators
|
|
||||||
from wtforms.validators import DataRequired
|
|
||||||
|
|
||||||
|
|
||||||
def validate_email_or_phone(form, field):
|
|
||||||
if not form.email.data and not form.phone.data:
|
|
||||||
raise validators.ValidationError("Must have phone or email")
|
|
||||||
|
|
||||||
|
|
||||||
class JobPostForm(FlaskForm):
|
|
||||||
title = StringField("Titre", validators=[DataRequired()])
|
|
||||||
summary = StringField("Résumé (optionnel)")
|
|
||||||
content = PageDownField("Contenu de l'offre", validators=[DataRequired()])
|
|
||||||
company = StringField("Entreprise", validators=[DataRequired()])
|
|
||||||
location = StringField("Addresse", validators=[DataRequired()])
|
|
||||||
contact_info = StringField("Personne à contacter", validators=[DataRequired()])
|
|
||||||
email = StringField("Email", validators=[validate_email_or_phone])
|
|
||||||
phone = StringField("Téléphone", validators=[validate_email_or_phone])
|
|
||||||
image = FileField("Image (optionnel)")
|
|
|
@ -1,111 +0,0 @@
|
||||||
from datetime import datetime
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from flask_admin.contrib.peewee import ModelView
|
|
||||||
from flask_login import current_user
|
|
||||||
from peewee import CharField
|
|
||||||
from peewee import DateTimeField
|
|
||||||
from peewee import ForeignKeyField
|
|
||||||
from peewee import TextField
|
|
||||||
|
|
||||||
from afpy.models import BaseModel
|
|
||||||
from afpy.models.AdminUser import AdminUser
|
|
||||||
|
|
||||||
|
|
||||||
class JobPost(BaseModel):
|
|
||||||
title = TextField(null=False, help_text="Title of the job post", verbose_name="Title")
|
|
||||||
summary = TextField(null=True, help_text="Summary of the job post", verbose_name="Summary")
|
|
||||||
content = TextField(null=False, help_text="Content of the job post", verbose_name="Content")
|
|
||||||
dt_submitted = DateTimeField(
|
|
||||||
null=False,
|
|
||||||
default=datetime.now,
|
|
||||||
help_text="When was the job post submitted",
|
|
||||||
verbose_name="Datetime Submitted",
|
|
||||||
index=True,
|
|
||||||
)
|
|
||||||
dt_updated = DateTimeField(
|
|
||||||
null=False, default=datetime.now, help_text="When was the job post updated", verbose_name="Datetime Updated"
|
|
||||||
)
|
|
||||||
dt_published = DateTimeField(
|
|
||||||
null=True, help_text="When was the job post published", verbose_name="Datetime Published"
|
|
||||||
)
|
|
||||||
state = CharField(
|
|
||||||
null=False,
|
|
||||||
default="waiting",
|
|
||||||
choices=[("waiting", "waiting"), ("published", "published"), ("rejected", "rejected")],
|
|
||||||
help_text="Current state of the job post",
|
|
||||||
verbose_name="State",
|
|
||||||
)
|
|
||||||
approved_by = ForeignKeyField(
|
|
||||||
AdminUser,
|
|
||||||
null=True,
|
|
||||||
default=None,
|
|
||||||
backref="adminuser",
|
|
||||||
help_text="Who approved the job post",
|
|
||||||
verbose_name="Approved by",
|
|
||||||
)
|
|
||||||
|
|
||||||
company = CharField(null=False, help_text="Company that posted the job", verbose_name="Company")
|
|
||||||
phone = CharField(null=True, help_text="Phone number to contact", verbose_name="Phone Number")
|
|
||||||
location = CharField(null=False, help_text="Where is the job located", verbose_name="Job Location")
|
|
||||||
email = CharField(null=True, help_text="Email to contact", verbose_name="Email Address")
|
|
||||||
contact_info = CharField(null=False, help_text="Person to contact", verbose_name="Contact info")
|
|
||||||
image_path = CharField(null=True, help_text="Image for the job post", verbose_name="Image Path in filesystem")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def create(
|
|
||||||
cls,
|
|
||||||
title: str,
|
|
||||||
content: str,
|
|
||||||
company: str,
|
|
||||||
location: str,
|
|
||||||
contact_info: str,
|
|
||||||
email: Optional[str] = None,
|
|
||||||
phone: Optional[str] = None,
|
|
||||||
summary: Optional[str] = None,
|
|
||||||
dt_submitted: Optional[datetime] = None,
|
|
||||||
dt_updated: Optional[datetime] = None,
|
|
||||||
dt_published: Optional[datetime] = None,
|
|
||||||
state: str = "waiting",
|
|
||||||
approved_by: Optional[AdminUser] = None,
|
|
||||||
image_path: Optional[str] = None,
|
|
||||||
):
|
|
||||||
if not dt_submitted:
|
|
||||||
dt_submitted = datetime.now()
|
|
||||||
if not dt_updated:
|
|
||||||
dt_updated = datetime.now()
|
|
||||||
|
|
||||||
if not email and not phone:
|
|
||||||
raise ValueError("One of email or phone must be provided")
|
|
||||||
|
|
||||||
new_job = super().create(
|
|
||||||
title=title,
|
|
||||||
content=content,
|
|
||||||
company=company,
|
|
||||||
location=location,
|
|
||||||
contact_info=contact_info,
|
|
||||||
email=email,
|
|
||||||
phone=phone,
|
|
||||||
summary=summary,
|
|
||||||
dt_submitted=dt_submitted,
|
|
||||||
dt_updated=dt_updated,
|
|
||||||
dt_published=dt_published,
|
|
||||||
state=state,
|
|
||||||
approved_by=approved_by,
|
|
||||||
image_path=image_path,
|
|
||||||
)
|
|
||||||
new_job.save()
|
|
||||||
return new_job
|
|
||||||
|
|
||||||
|
|
||||||
class JobPost_Admin(ModelView):
|
|
||||||
model_class = JobPost
|
|
||||||
column_list = ("state", "title", "dt_published")
|
|
||||||
column_default_sort = ("id", True)
|
|
||||||
|
|
||||||
def is_accessible(self):
|
|
||||||
return current_user.is_authenticated
|
|
||||||
|
|
||||||
|
|
||||||
if not JobPost.table_exists():
|
|
||||||
JobPost.create_table()
|
|
|
@ -5,13 +5,11 @@ from peewee import CharField
|
||||||
from peewee import ForeignKeyField
|
from peewee import ForeignKeyField
|
||||||
|
|
||||||
from afpy.models import BaseModel
|
from afpy.models import BaseModel
|
||||||
from afpy.models.JobPost import JobPost
|
|
||||||
from afpy.models.NewsEntry import NewsEntry
|
from afpy.models.NewsEntry import NewsEntry
|
||||||
|
|
||||||
|
|
||||||
class Slug(BaseModel):
|
class Slug(BaseModel):
|
||||||
url = CharField(null=False, help_text="From URL", verbose_name="From URL", unique=True, index=True)
|
url = CharField(null=False, help_text="From URL", verbose_name="From URL", unique=True, index=True)
|
||||||
jobpost = ForeignKeyField(JobPost, backref="slug", null=True)
|
|
||||||
newsentry = ForeignKeyField(NewsEntry, backref="slug", null=True)
|
newsentry = ForeignKeyField(NewsEntry, backref="slug", null=True)
|
||||||
canonical = BooleanField(default=True)
|
canonical = BooleanField(default=True)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ from afpy.forms.auth import ChangePasswordForm
|
||||||
from afpy.forms.auth import LoginForm
|
from afpy.forms.auth import LoginForm
|
||||||
from afpy.forms.auth import RegistrationForm
|
from afpy.forms.auth import RegistrationForm
|
||||||
from afpy.models.AdminUser import AdminUser
|
from afpy.models.AdminUser import AdminUser
|
||||||
from afpy.models.JobPost import JobPost
|
|
||||||
from afpy.models.NewsEntry import NewsEntry
|
from afpy.models.NewsEntry import NewsEntry
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,11 +128,6 @@ class _ModerateView(admin.BaseView):
|
||||||
return redirect(url_for(".moderate_view"))
|
return redirect(url_for(".moderate_view"))
|
||||||
|
|
||||||
|
|
||||||
class JobsModerateView(_ModerateView):
|
|
||||||
model = JobPost
|
|
||||||
edit_view = "jobpost.edit_view"
|
|
||||||
|
|
||||||
|
|
||||||
class NewsModerateView(_ModerateView):
|
class NewsModerateView(_ModerateView):
|
||||||
model = NewsEntry
|
model = NewsEntry
|
||||||
edit_view = "newsentry.edit_view"
|
edit_view = "newsentry.edit_view"
|
||||||
|
|
|
@ -8,7 +8,6 @@ from flask import render_template
|
||||||
from flask import send_from_directory
|
from flask import send_from_directory
|
||||||
from peewee import DoesNotExist
|
from peewee import DoesNotExist
|
||||||
|
|
||||||
from afpy.models.JobPost import JobPost
|
|
||||||
from afpy.models.NewsEntry import NewsEntry
|
from afpy.models.NewsEntry import NewsEntry
|
||||||
from afpy import config
|
from afpy import config
|
||||||
|
|
||||||
|
@ -56,9 +55,6 @@ def status():
|
||||||
"actualites": {
|
"actualites": {
|
||||||
"waiting": NewsEntry.select().where(NewsEntry.state == "waiting").count(),
|
"waiting": NewsEntry.select().where(NewsEntry.state == "waiting").count(),
|
||||||
},
|
},
|
||||||
"emplois": {
|
|
||||||
"waiting": JobPost.select().where(JobPost.state == "waiting").count(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,33 +18,15 @@ jobs_bp = Blueprint("jobs", __name__)
|
||||||
|
|
||||||
@jobs_bp.route("/emplois/<int:post_id>")
|
@jobs_bp.route("/emplois/<int:post_id>")
|
||||||
def jobs_render(post_id: int):
|
def jobs_render(post_id: int):
|
||||||
try:
|
return redirect("https://discuss.afpy.org/c/emplois/14")
|
||||||
job = JobPost.get_by_id(post_id)
|
|
||||||
except DoesNotExist:
|
|
||||||
abort(404)
|
|
||||||
return render_template("pages/job.html", body_id="emplois", job=job, name=job.title)
|
|
||||||
|
|
||||||
|
|
||||||
@jobs_bp.route("/emplois")
|
@jobs_bp.route("/emplois")
|
||||||
@jobs_bp.route("/emplois/page/<int:current_page>")
|
@jobs_bp.route("/emplois/page/<int:current_page>")
|
||||||
def jobs_page(current_page: int = 1):
|
def jobs_page(current_page: int = 1):
|
||||||
total_pages = (JobPost.select().where(JobPost.state == "published").count() // config.NEWS_PER_PAGE) + 1
|
return redirect("https://discuss.afpy.org/c/emplois/14")
|
||||||
jobs = (
|
|
||||||
JobPost.select()
|
|
||||||
.where(JobPost.state == "published")
|
|
||||||
.order_by(JobPost.dt_submitted.desc())
|
|
||||||
.paginate(current_page, config.NEWS_PER_PAGE)
|
|
||||||
)
|
|
||||||
return render_template(
|
|
||||||
"pages/jobs.html",
|
|
||||||
body_id="emplois",
|
|
||||||
jobs=jobs,
|
|
||||||
title="Offres d'emploi",
|
|
||||||
current_page=current_page,
|
|
||||||
total_pages=total_pages,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@jobs_bp.route("/emplois/new", methods=["GET"])
|
@jobs_bp.route("/emplois/new", methods=["GET"])
|
||||||
def new_job():
|
def new_job():
|
||||||
return render_template("pages/edit_job.html")
|
return redirect("https://discuss.afpy.org/c/emplois/14")
|
||||||
|
|
|
@ -6,8 +6,8 @@ from flask import abort
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
|
from flask import redirect
|
||||||
|
|
||||||
from afpy.models.JobPost import JobPost
|
|
||||||
from afpy.models.NewsEntry import NewsEntry
|
from afpy.models.NewsEntry import NewsEntry
|
||||||
from afpy import config
|
from afpy import config
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ def feed_rss(type):
|
||||||
name = ""
|
name = ""
|
||||||
entries = []
|
entries = []
|
||||||
if type == "emplois":
|
if type == "emplois":
|
||||||
name = "Emplois"
|
return redirect("https://discuss.afpy.org/c/emplois/14.rss")
|
||||||
entries = JobPost.select().where(JobPost.state == "published")
|
|
||||||
elif type == "actualites":
|
elif type == "actualites":
|
||||||
name = "Actualités"
|
name = "Actualités"
|
||||||
entries = NewsEntry.select().where(NewsEntry.state == "published")
|
entries = NewsEntry.select().where(NewsEntry.state == "published")
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(url_for('home.home_page'), 'index', 'Accueil'),
|
(url_for('home.home_page'), 'index', 'Accueil'),
|
||||||
(url_for('home.render_rest', name='a-propos'), 'a-propos', 'Qui sommes-nous ?'),
|
(url_for('home.render_rest', name='a-propos'), 'a-propos', 'Qui sommes-nous ?'),
|
||||||
(url_for('posts.posts_page'), 'actualites', 'Actualités'),
|
(url_for('posts.posts_page'), 'actualites', 'Actualités'),
|
||||||
(url_for('jobs.jobs_page'), 'emplois', 'Offres d\'emplois'),
|
("https://discuss.afpy.org/c/emplois/14", 'emplois', 'Offres d\'emplois'),
|
||||||
(url_for('home.community_page'), 'communaute', 'Communauté'),
|
(url_for('home.community_page'), 'communaute', 'Communauté'),
|
||||||
('https://discuss.afpy.org', 'discussion', 'Discussion'),
|
('https://discuss.afpy.org', 'discussion', 'Discussion'),
|
||||||
('https://www.afpy.org/discord', 'discord', 'Discord'),
|
('https://www.afpy.org/discord', 'discord', 'Discord'),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<h1>AFPy Backend Admin</h1>
|
<h1>AFPy Backend Admin</h1>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Bienvenue dans le backoffice de l'AFPy. Vous avez accès à la création, modification et suppression d'articles, jobs et admins, ainsi qu'aux tables.<br>
|
Bienvenue dans le backoffice de l'AFPy. Vous avez accès à la création, modification et suppression d'articles et admins, ainsi qu'aux tables.<br>
|
||||||
Ne touchez à rien si vous ne savez pas ce que vous faites.
|
Ne touchez à rien si vous ne savez pas ce que vous faites.
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
{% extends '_parts/base.jinja2' %}
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h1>Création d'un job</h1>
|
|
||||||
{% endblock header %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<h2>Pour plus de visibilité, la job board de l'AFPy bouge ici : <a href="https://discuss.afpy.org/c/emplois/14">https://discuss.afpy.org/c/emplois</a> !</h2>
|
|
||||||
<p>
|
|
||||||
Pour créer une offre d'emploi là bas, deux solutions :<br/>
|
|
||||||
<ul>
|
|
||||||
<li>Envoyer un email à jobs at afpy point org, le titre de votre offre en sujet, le message de votre offre en corps de message, c'est tout.</li>
|
|
||||||
<li>Publier l'offre directement <a href="https://discuss.afpy.org">sur le forum</a>, dans la catégorie « <a href="https://discuss.afpy.org/c/emplois/14">Offres d'emploi</a> » en cliquant sur le bouton « Créer un sujet »</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
<h2>C'est quoi https://discuss.afpy.org?</h2>
|
|
||||||
<p>
|
|
||||||
C'est une instance de <a href="https://discourse.org">Discourse</a>, un forum <a href="https://github.com/discourse/discourse">open source</a> qu'on héberge en france chez <a href="https://www.gandi.net/fr">Gandi</a>.
|
|
||||||
</p>
|
|
||||||
</article>
|
|
||||||
{% endblock main %}
|
|
|
@ -1,51 +0,0 @@
|
||||||
{% extends '_parts/base.jinja2' %}
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h1>{{ job.title }}</h1>
|
|
||||||
{% endblock header %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
|
|
||||||
{% if preview %}
|
|
||||||
<a href="{{ url_for("jobs_moderation.moderate_view") }}">Retour à l'interface d'administration</a>
|
|
||||||
{# <p><a class="btn btn-warning" href="http://127.0.0.1:5000/admin/jobpost/edit/?id={{ job.id }}" role="button">Edit</a></p>#}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<article>
|
|
||||||
{% if preview %}
|
|
||||||
<time pubdate datetime="">
|
|
||||||
Pas publié
|
|
||||||
</time>
|
|
||||||
{% else %}
|
|
||||||
<time pubdate datetime="{{ job.dt_published }}">
|
|
||||||
Posté le {{ job.dt_published.strftime('%d/%m/%Y') }} à {{ job.dt_published.strftime('%H:%M:%S') }}
|
|
||||||
</time>
|
|
||||||
{% endif %}
|
|
||||||
<p>
|
|
||||||
<em>
|
|
||||||
{{ job.summary | safe if job.summary }}
|
|
||||||
</em>
|
|
||||||
</p>
|
|
||||||
{% if job.image_path %}
|
|
||||||
<img src="{{ url_for('home.get_image', path=job.image_path) }}" alt="{{ job.title }}" />
|
|
||||||
{% endif %}
|
|
||||||
{{ job.content | md2html | safe }}
|
|
||||||
<aside>
|
|
||||||
<h2>{{ job.company or "(Société inconnue)" }}</h2>
|
|
||||||
<dl>
|
|
||||||
<dt>Adresse</dt>
|
|
||||||
<dd>{{ job.location }}</dd>
|
|
||||||
<dt>Personne à contacter</dt>
|
|
||||||
<dd>{{ job.contact_info }}</dd>
|
|
||||||
{% if job.phone %}
|
|
||||||
<dt>Téléphone</dt>
|
|
||||||
<dd><a href="tel:{{ job.phone }}">{{ job.phone }}</a></dd>
|
|
||||||
{% endif %}
|
|
||||||
{% if job.email %}
|
|
||||||
<dt>Adresse e-mail</dt>
|
|
||||||
<dd><a href="mailto:{{ job.email }}">{{ job.email }}</a></dd>
|
|
||||||
{% endif %}
|
|
||||||
</dl>
|
|
||||||
</aside>
|
|
||||||
</article>
|
|
||||||
{% endblock main %}
|
|
|
@ -1,41 +0,0 @@
|
||||||
{% extends '_parts/base.jinja2' %}
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h1>{{ title }}</h1>
|
|
||||||
{% endblock header %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
<aside>
|
|
||||||
<h2>Pour plus de visibilité, la job board de l'AFPy bouge ici : <a href="https://discuss.afpy.org/c/emplois/14">https://discuss.afpy.org/c/emplois</a> !</h2>
|
|
||||||
<p>
|
|
||||||
Pour créer une offre d'emploi là bas, deux solutions :<br/>
|
|
||||||
<ul>
|
|
||||||
<li>Envoyer un email à jobs at afpy point org, le titre de votre offre en sujet, le message de votre offre en corps de message, c'est tout.</li>
|
|
||||||
<li>Publier l'offre directement <a href="https://discuss.afpy.org">sur le forum</a>, dans la catégorie « <a href="https://discuss.afpy.org/c/emplois/14">Offres d'emploi</a> » en cliquant sur le bouton « Créer un sujet »</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
</aside>
|
|
||||||
{% for job in jobs %}
|
|
||||||
<article>
|
|
||||||
<h2>{{ job.title }}</h2>
|
|
||||||
<time pubdate datetime="{{ job.dt_published }}">
|
|
||||||
{{ job.dt_published.strftime('%d/%m/%Y') }}
|
|
||||||
</time>
|
|
||||||
{% if job.image_path %}
|
|
||||||
<img src="{{ url_for('home.get_image', path=job.image_path) }}" alt="{{ job.title }}" />
|
|
||||||
{% endif %}
|
|
||||||
{% if job.summary %}{{ job.summary |safe }}{% else %}{{ job.content|truncate(50)|safe }}{% endif %}
|
|
||||||
<p><a href="{{ job|slug_url }}">Lire la suite…</a></p>
|
|
||||||
</article>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<aside>
|
|
||||||
{% if current_page != 1 %}
|
|
||||||
<a href="{{ url_for('jobs.jobs_page', current_page=(current_page - 1)) }}">Précedente</a>
|
|
||||||
{% endif %}
|
|
||||||
Page {{ current_page }}/{{ total_pages }}
|
|
||||||
{% if current_page != total_pages %}
|
|
||||||
<a href="{{ url_for('jobs.jobs_page', current_page=(current_page + 1)) }}">Suivante</a>
|
|
||||||
{% endif %}
|
|
||||||
</aside>
|
|
||||||
{% endblock main %}
|
|
|
@ -7,7 +7,6 @@
|
||||||
{% block main %}
|
{% block main %}
|
||||||
{% if preview %}
|
{% if preview %}
|
||||||
<a href="{{ url_for("news_moderation.moderate_view") }}">Retour à l'interface d'administration</a>
|
<a href="{{ url_for("news_moderation.moderate_view") }}">Retour à l'interface d'administration</a>
|
||||||
{# <p><a class="btn btn-warning" href="http://127.0.0.1:5000/admin/jobpost/edit/?id={{ post.id }}" role="button">Edit</a></p>#}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
|
|
|
@ -8,11 +8,7 @@
|
||||||
<item>
|
<item>
|
||||||
<title><![CDATA[ {{ entry.title | safe }} ]]></title>
|
<title><![CDATA[ {{ entry.title | safe }} ]]></title>
|
||||||
<description><![CDATA[ {{ (entry.description or entry.summary) | safe }} ]]></description>
|
<description><![CDATA[ {{ (entry.description or entry.summary) | safe }} ]]></description>
|
||||||
{% if type == "emplois" %}
|
<link>{{ url_for("posts.post_render", post_id=entry.id, _external=True) }}</link>
|
||||||
<link>{{ url_for("jobs.jobs_render", post_id=entry.id, _external=True) }}</link>
|
|
||||||
{% else %}
|
|
||||||
<link>{{ url_for("posts.post_render", post_id=entry.id, _external=True) }}</link>
|
|
||||||
{% endif %}
|
|
||||||
<pubDate>{{ entry.dt_published }}</pubDate>
|
<pubDate>{{ entry.dt_published }}</pubDate>
|
||||||
</item>
|
</item>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
31
xml2sql.py
31
xml2sql.py
|
@ -8,16 +8,14 @@ from dateutil.parser import parse
|
||||||
from html2text import html2text
|
from html2text import html2text
|
||||||
|
|
||||||
from afpy.models.AdminUser import AdminUser
|
from afpy.models.AdminUser import AdminUser
|
||||||
from afpy.models.JobPost import JobPost
|
|
||||||
from afpy.models.NewsEntry import NewsEntry
|
from afpy.models.NewsEntry import NewsEntry
|
||||||
from afpy.models.Slug import Slug
|
from afpy.models.Slug import Slug
|
||||||
|
|
||||||
PAGINATION = 12
|
PAGINATION = 12
|
||||||
|
|
||||||
CATEGORY_ACTUALITIES = "actualites"
|
CATEGORY_ACTUALITIES = "actualites"
|
||||||
CATEGORY_JOBS = "emplois"
|
|
||||||
|
|
||||||
CATEGORIES = {CATEGORY_ACTUALITIES: "Actualités", CATEGORY_JOBS: "Offres d’emploi"}
|
CATEGORIES = {CATEGORY_ACTUALITIES: "Actualités"}
|
||||||
|
|
||||||
STATE_WAITING = "waiting"
|
STATE_WAITING = "waiting"
|
||||||
STATE_PUBLISHED = "published"
|
STATE_PUBLISHED = "published"
|
||||||
|
@ -110,30 +108,3 @@ if __name__ == "__main__":
|
||||||
post_id = post.get("id")
|
post_id = post.get("id")
|
||||||
if post_id:
|
if post_id:
|
||||||
Slug.create(url=post_id.split("afpy.org")[-1], newsentry=new_post)
|
Slug.create(url=post_id.split("afpy.org")[-1], newsentry=new_post)
|
||||||
else:
|
|
||||||
email = post.get("email", "")
|
|
||||||
phone = post.get("phone", "")
|
|
||||||
if not email and not phone:
|
|
||||||
phone = "(no phone)"
|
|
||||||
new_job = JobPost.create(
|
|
||||||
title=post.get("title", "(untitled)"),
|
|
||||||
summary=post.get("summary"),
|
|
||||||
content=html2text(post.get("content", "")),
|
|
||||||
company=post.get("company", ""),
|
|
||||||
email=email,
|
|
||||||
phone=phone,
|
|
||||||
location=post.get("address", ""),
|
|
||||||
contact_info=post.get("contact", ""),
|
|
||||||
dt_published=parse(post.get("published")).replace(tzinfo=None)
|
|
||||||
if state == "published"
|
|
||||||
else None,
|
|
||||||
dt_submitted=parse(post.get("published")).replace(tzinfo=None),
|
|
||||||
dt_updated=parse(post.get("published")).replace(tzinfo=None),
|
|
||||||
state=state,
|
|
||||||
approved_by=admin_1 if state == "published" or state == "rejected" else None,
|
|
||||||
image_path=post.get("image"),
|
|
||||||
)
|
|
||||||
Slug.create(url=f"/posts/emplois/{post.get(FIELD_TIMESTAMP)}", jobpost=new_job)
|
|
||||||
post_id = post.get("id")
|
|
||||||
if post_id:
|
|
||||||
Slug.create(url=post_id.split("afpy.org")[-1], jobpost=new_job)
|
|
||||||
|
|
Loading…
Reference in New Issue