forked from Ugric/Komodo-Hub
Merge remote-tracking branch 'refs/remotes/origin/main'
This commit is contained in:
commit
9284f4e3b1
12 files changed
+223
-8
No files matched your search
@@ -92,6 +92,16 @@ def get_all_species():
|
||||
with get_db() as conn:
|
||||
rows = conn.execute("SELECT * FROM species").fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def get_all_articles():
|
||||
with get_db() as conn:
|
||||
rows = conn.execute("SELECT * FROM articles").fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def get_article_by_id(id):
|
||||
with get_db() as conn:
|
||||
row = conn.execute("SELECT * FROM articles WHERE article_id = ? LIMIT 1", (id,)).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def get_species_by_name(species_english):
|
||||
@@ -127,6 +137,18 @@ WHERE
|
||||
(query.lower(),)
|
||||
).fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def search_articles(query):
|
||||
with get_db() as conn:
|
||||
rows = conn.execute("""SELECT * FROM articles WHERE
|
||||
instr(LOWER(COALESCE(CAST(article_id AS TEXT), '')), ?1) > 0
|
||||
OR instr(LOWER(COALESCE(CAST(title AS TEXT), '')), ?1) > 0
|
||||
OR instr(LOWER(COALESCE(CAST(subtitle AS TEXT), '')), ?1) > 0
|
||||
OR instr(LOWER(COALESCE(CAST(author AS TEXT), '')), ?1) > 0
|
||||
OR instr(LOWER(COALESCE(CAST(publish_date AS TEXT), '')), ?1) > 0;""",
|
||||
(query.lower(),)
|
||||
).fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def delete_species(species_id):
|
||||
with get_db() as conn:
|
||||
|
||||
+62
-1
@@ -91,7 +91,27 @@ SEED_SPECIES = [
|
||||
"photoid": "celebes crested macaque"
|
||||
},
|
||||
]
|
||||
|
||||
test_article = [
|
||||
{
|
||||
"article_id":"a-starrier-night",
|
||||
"title" :"A Starrier Night",
|
||||
"subtitle" :("In the past decade, our planet has rapidly lost its night sky. In response,"
|
||||
"West Texas created the largest international dark-sky reserve on Earth."),
|
||||
"main_text" :("Light pollution has been growing rapidly, with the sky brightening nearly 10% each year "
|
||||
"since 2011. In West Texas, the McDonald Observatory—the darkest observatory in the "
|
||||
"continental US—faced an operational threat as development crept into the region. "
|
||||
"Superintendent Teznie Pugh and colleagues partnered with local landowners, parks, and "
|
||||
"The Nature Conservancy to protect the night sky. In 2022, DarkSky International certified "
|
||||
"the Greater Big Bend International Dark Sky Reserve, covering 9.6 million acres and "
|
||||
"spanning the US-Mexico border—the largest International Dark Sky Reserve in the world. "
|
||||
"The Davis Mountains Preserve (33,000 acres) forms the core of the reserve. The greatest "
|
||||
"ongoing threat comes from oil and gas development in the Permian Basin. The reserve also "
|
||||
"supports ecological research into the effects of light pollution on nocturnal wildlife, "
|
||||
"plants, and ecosystems."),
|
||||
"author" :"Jenny Rogers",
|
||||
"publish_date":"2026-02-13"
|
||||
}
|
||||
]
|
||||
|
||||
def init_database():
|
||||
with get_db() as conn:
|
||||
@@ -110,6 +130,46 @@ def init_database():
|
||||
print("Database initialised.")
|
||||
seed_species()
|
||||
|
||||
def init_articles():
|
||||
with get_db() as conn:
|
||||
# table for articles in library
|
||||
conn.execute("""
|
||||
CREATE TABLE IF NOT EXISTS articles (
|
||||
article_id TEXT PRIMARY KEY UNIQUE,
|
||||
title TEXT,
|
||||
subtitle TEXT,
|
||||
main_text TEXT,
|
||||
author TEXT,
|
||||
publish_date);""")
|
||||
print("Successfully created/found articles table.")
|
||||
# table to store links relevant to articles (e.g. sources or original article)
|
||||
conn.execute("""
|
||||
CREATE TABLE IF NOT EXISTS article_links (
|
||||
link_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
article_id TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
link_text TEXT,
|
||||
FOREIGN KEY (article_id) REFERENCES articles(article_id)
|
||||
ON DELETE CASCADE);""")
|
||||
print("Succesfully found/created article_links table.")
|
||||
for article in test_article:
|
||||
table_exists = conn.execute(
|
||||
"SELECT article_id FROM articles WHERE article_id = ?",
|
||||
(article["article_id"],)).fetchone()
|
||||
if table_exists:
|
||||
print(f" SKIP {article['article_id']} (already exists)")
|
||||
continue
|
||||
conn.execute("""
|
||||
INSERT INTO articles
|
||||
(article_id, title, subtitle, main_text, author, publish_date)
|
||||
VALUES (?, ?, ?, ?, ?, ?)""",
|
||||
(article["article_id"],
|
||||
article["title"],
|
||||
article["subtitle"],
|
||||
article["main_text"],
|
||||
article["author"],
|
||||
article["publish_date"],))
|
||||
print(f" ADD {article['article_id']}")
|
||||
|
||||
def seed_species():
|
||||
with get_db() as conn:
|
||||
@@ -224,4 +284,5 @@ init_database()
|
||||
init_accounts_database()
|
||||
init_classes_database()
|
||||
init_programs_database()
|
||||
init_articles()
|
||||
register_user("admin", "admin@komodohub.org", "admin", "admin")
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
from flask import render_template, Blueprint, send_from_directory
|
||||
from database.db_commands import get_article_by_id, get_species_by_id
|
||||
import sqlite3
|
||||
|
||||
page = Blueprint("article", __name__)
|
||||
|
||||
# this page works by taking the species name (in english) from the url and using that to read the database.
|
||||
# Because of this we are able to create one page and simply generate links based on the contents of the database
|
||||
# i.e. we can create a button with the hyperlink /species/iguana and this will
|
||||
# allow the user to view the information about the species
|
||||
# please be aware the page expects a .jpg at:
|
||||
# /static/images/species_database/{{photoid}}.jpg but this will be generated automatically
|
||||
# so long as you use the species_portal or species editor pages I created - CS
|
||||
|
||||
|
||||
@page.route("/articles/<article_id>")
|
||||
def data(article_id):
|
||||
database_entry = get_article_by_id(article_id)
|
||||
if database_entry is None:
|
||||
raise TypeError(f"No species named '{species_english}' found in the database.")
|
||||
return render_template(
|
||||
"library/article.jinja",
|
||||
article_id =database_entry["article_id" ].capitalize(),
|
||||
title =database_entry["title" ].capitalize(),
|
||||
subtitle =database_entry["subtitle" ],
|
||||
main_text =database_entry["main_text" ].capitalize(),
|
||||
author =database_entry["author" ],
|
||||
publish_date=database_entry["publish_date" ])
|
||||
|
||||
@page.route("/species/image/<photoid>")
|
||||
def image(photoid):
|
||||
return send_from_directory("database/images", photoid)
|
||||
@@ -0,0 +1,30 @@
|
||||
from flask import render_template, Blueprint, request
|
||||
import configparser
|
||||
|
||||
from database.db_commands import get_all_articles, search_articles, get_species_by_name
|
||||
from utilities.featured_species import featured_species_function
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
page = Blueprint("articles", __name__, url_prefix="/articles")
|
||||
|
||||
# article library page
|
||||
@page.route("")
|
||||
def all_species():
|
||||
article_list = get_all_articles()
|
||||
|
||||
article_list = sorted(article_list, key=lambda sp: sp["title"])
|
||||
|
||||
for sp in article_list:
|
||||
print(sp['title'])
|
||||
|
||||
return render_template("library/library.jinja", articles=article_list)
|
||||
|
||||
# search page
|
||||
@page.route("/search")
|
||||
def search():
|
||||
query = request.args.get("search-query")
|
||||
|
||||
results = search_articles(query)
|
||||
print(results)
|
||||
return render_template("/library/article_search.jinja", results=results, query=query)
|
||||
@@ -73,7 +73,7 @@
|
||||
Create a free account to track species, contribute to our database, and connect with the conservation community.
|
||||
</p>
|
||||
<div class="homepage-buttons">
|
||||
{{ button(url='/accounts/user_registration', button_text='Create an Account', extra_classes='homepage-btn') }}
|
||||
{{ button(url='/register', button_text='Create an Account', extra_classes='homepage-btn') }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% macro display_all_items(items)%}
|
||||
{% macro display_all_species(items)%}
|
||||
{# Displays all species in the provided 'items' array #}
|
||||
{# Used in the species database and species results pages #}
|
||||
{# Used in the species database and search species results pages #}
|
||||
<section class="species-grid">
|
||||
{% for item in items %}
|
||||
<a href="/species/{{ item['species_english'] }}" class="container-lite">
|
||||
@@ -15,4 +15,20 @@
|
||||
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endmacro %}
|
||||
{% macro display_all_articles(items)%}
|
||||
{# Displays all articles in the provided 'items' array #}
|
||||
{# Used in the article library and article search results pages #}
|
||||
<section class="species-grid">
|
||||
{% for item in items %}
|
||||
<a href="/articles/{{ item['article_id'] }}" class="container-lite">
|
||||
<h3 class="plain-white-text">{{ item['title'] }}</h3>
|
||||
<p style="color: var(--text)">
|
||||
Main category: {{ item['author'] }}
|
||||
Date published: {{ item["publish_date"] }}
|
||||
</p>
|
||||
</a>
|
||||
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endmacro %}
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block title %}{{ english_name }} {% endblock %}
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% from 'button.jinja' import button %}
|
||||
<div class="species-layout">
|
||||
<section id="summary" style="padding: 10px 20px; text-align: center; margin-top:1rem" class="container">
|
||||
<h1>{{ title }}</h1>
|
||||
<h2><em>{{ subtitle }}</em></h2>
|
||||
<p>Category: {{author}}</p>
|
||||
<p>Category: {{publish_date}}</p>
|
||||
|
||||
</section>
|
||||
<section id="info" style="padding: 10px 20px; text-align: center;" class="container">
|
||||
<p>{{ main_text }}</p>
|
||||
</section>
|
||||
</div>
|
||||
{# this button should only be visible to certain account types #}
|
||||
{# <div style="text-align: right;">
|
||||
{{ button(url='/species/editor/'+species_id, button_text='Edit Species') }}
|
||||
</div> #}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,15 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block title %}Species Database{% endblock %}
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% from 'button.jinja' import button %}
|
||||
{% from 'display_items.jinja' import display_all_articles %}
|
||||
{% from 'search_bar.jinja' import search_bar%}
|
||||
<section class="title">
|
||||
Article Library
|
||||
</section>
|
||||
{# All Species #}
|
||||
{{search_bar("/articles/search", query)}}
|
||||
{{display_all_articles(results)}}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block title %}Species Database{% endblock %}
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% from 'button.jinja' import button %}
|
||||
{% from 'display_items.jinja' import display_all_articles %}
|
||||
{% from 'search_bar.jinja' import search_bar%}
|
||||
<section class="title">
|
||||
Article Library
|
||||
</section>
|
||||
{# All Articles #}
|
||||
{{search_bar("/articles/search", "")}}
|
||||
<h2 style="text-align: center; margin-top: 30px;">All Articles</h2>
|
||||
{{display_all_articles(articles)}}
|
||||
{% endblock %}
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
{% from 'button.jinja' import button %}
|
||||
{% from 'featured_species.jinja' import featured_species_section %}
|
||||
{% from 'display_items.jinja' import display_all_items %}
|
||||
{% from 'display_items.jinja' import display_all_species %}
|
||||
{% from 'search_bar.jinja' import search_bar%}
|
||||
<section class="title">
|
||||
Species Database
|
||||
@@ -16,5 +16,5 @@ Species Database
|
||||
{# All Species #}
|
||||
{{search_bar("/species/search", "")}}
|
||||
<h2 style="text-align: center; margin-top: 30px;">All Species</h2>
|
||||
{{display_all_items(species)}}
|
||||
{{display_all_species(species)}}
|
||||
{% endblock %}
|
||||
@@ -4,12 +4,12 @@
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% from 'button.jinja' import button %}
|
||||
{% from 'display_items.jinja' import display_all_items %}
|
||||
{% from 'display_items.jinja' import display_all_species %}
|
||||
{% from 'search_bar.jinja' import search_bar%}
|
||||
<section class="title">
|
||||
Species Database
|
||||
</section>
|
||||
{# All Species #}
|
||||
{{search_bar("/species/search", query)}}
|
||||
{{display_all_items(results)}}
|
||||
{{display_all_species(results)}}
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user