Skip to content

Commit

Permalink
Merge pull request #43 from Xpirix/category_filter
Browse files Browse the repository at this point in the history
Category filter
  • Loading branch information
Xpirix authored Feb 5, 2025
2 parents 9a1d4ab + 14ba367 commit 8cef39c
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 18 deletions.
45 changes: 40 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,58 @@ By Tim Sutton and QGIS Contributors.
Project stars:
![Stars](https://starchart.cc/qgis/QGIS-Planet-Website.svg)

## 🏃Before you start
## Subscriber Model

The file `data/subscribers.json` is the main entry to fetch all feeds for the QGIS Planet Website. **You can add or update a feed by editing this file and submitting a Pull Request to this repository.** Below is the recommended data structure:

```json
{
// The RSS Feed URL
"feed": "https://geotribu.fr/feed_rss_created.xml",
// Name of the subscriber
"name": "Geotribu",
// Shortname of the subscriber
"shortname": "geotribu_fr",
// Show on the Website
"is_active": true,
// Optional: Filter the category of the posts to be fetch.
// It corresponds to the <category> tag on the RSS XML.
// If not set, the default value will be ["QGIS"].
"filter_categories": [
"QGIS",
"QField",
"QGIS Server",
"PyQGIS",
"Mergin",
],
// Availables and main language of the feed.
// The list of supported language is in the file
// data/languages.json. Please add yours there if not listed.
"languages": {
"available": [
"fr_fr"
],
"main": "fr_fr"
}
},
```

## 🧑💻 Development

### 🏃Before you start

This web site is a static site built using [Hugo](https://gohugo.io/).

![Hugo Logo](./img/hugo-logo.png) and using the [hugo bulma blocks theme](https://github.com/kartoza/hugo-bulma-blocks-theme).

## 🛒 Getting the Code
### 🛒 Getting the Code

development
```
git clone https://github.com/qgis/QGIS-Planet-Website.git
cd QGIS-Planet-Website
```


## 🧑💻 Development

### Using Nix
The development environment is using Nix flakes. Please visit https://nixos.wiki/wiki/Flakes for more details.

Expand Down
45 changes: 45 additions & 0 deletions data/languages.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,50 @@
"name": "Français",
"code": "fr_fr",
"flag": "🇫🇷"
},
{
"name": "Español",
"code": "es_es",
"flag": "🇪🇸"
},
{
"name": "Deutsch",
"code": "de_de",
"flag": "🇩🇪"
},
{
"name": "Italiano",
"code": "it_it",
"flag": "🇮🇹"
},
{
"name": "Português",
"code": "pt_pt",
"flag": "🇵🇹"
},
{
"name": "中文",
"code": "zh_cn",
"flag": "🇨🇳"
},
{
"name": "日本語",
"code": "ja_jp",
"flag": "🇯🇵"
},
{
"name": "한국어",
"code": "ko_kr",
"flag": "🇰🇷"
},
{
"name": "Русский",
"code": "ru_ru",
"flag": "🇷🇺"
},
{
"name": "العربية",
"code": "ar_sa",
"flag": "🇸🇦"
}
]
48 changes: 35 additions & 13 deletions fetch_feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
SUBSCRIBERS_JSON_PATH = os.path.join(os.path.dirname(__file__), 'data', 'subscribers.json')
ALL_POSTS_FOLDER = os.path.join("content", "posts")

DEFAULT_AVAILABLE_LANG = ["en_GB"]
DEFAULT_MAIN_LANG = "en_GB"
DEFAULT_CATEGORIES = ["QGIS"]

class FeedProcessor:
def __init__(
Expand All @@ -22,7 +25,8 @@ def __init__(
shortname: str,
feed_url: str,
available_lang: list,
main_lang: str):
main_lang: str,
filter_categories: list):

"""
Initializes a new instance of the class.
Expand All @@ -33,6 +37,7 @@ def __init__(
feed_url (str): The URL of the feed to be fetched.
available_lang (list): A list of languages available for the feed.
main_lang (str): The default language for the feed.
filter_categories (list): A list of categories to filter the feed by.
Description:
This class is responsible for initializing the subscriber's details
Expand All @@ -44,6 +49,7 @@ def __init__(
self.feed_url = feed_url
self.available_lang = available_lang
self.main_lang = main_lang
self.filter_categories = filter_categories

def fetch_and_create_post(self):
try:
Expand All @@ -57,10 +63,11 @@ def process_entry(self, entry):
try:
dest_folder = self.get_dest_folder()
title = entry.title
image_url = next((link.href for link in entry.links if 'image' in link.type), entry.links[-1].href)
if image_url.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp')):
file_name = self.get_image_name(image_url)
self.download_image(image_url, file_name, dest_folder)
# I don't think we need to download images because the images are already in the feed
# image_url = next((link.href for link in entry.links if 'image' in link.type), entry.links[-1].href)
# if image_url.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp')):
# file_name = self.get_image_name(image_url)
# self.download_image(image_url, file_name, dest_folder)

post_url = entry.link

Expand All @@ -72,11 +79,13 @@ def process_entry(self, entry):
content = self.get_summary(entry)
tags = self.get_tags(entry)

content = self.generate_markdown_content(title, entry_date, post_url, content, tags)

# Copy the markdown file to the posts/lang folder
markdown_filename = os.path.join(dest_folder, f"{file_name}.md")
self.write_to_file(markdown_filename, content)
are_tags_present = any(str(category).lower() in tags for category in self.filter_categories)
if are_tags_present:
content = self.generate_markdown_content(title, entry_date, post_url, content, tags)

# Copy the markdown file to the posts folder
markdown_filename = os.path.join(dest_folder, f"{file_name}.md")
self.write_to_file(markdown_filename, content)

except Exception as e:
print(f"Failed to process entry for {self.subscriber_name}: {e}")
Expand Down Expand Up @@ -244,21 +253,34 @@ def process_funder(item):
with open(SUBSCRIBERS_JSON_PATH, 'r') as f:
subscribers = json.load(f)

# Remove all files inside the content/posts folder
for filename in os.listdir(ALL_POSTS_FOLDER):
file_path = os.path.join(ALL_POSTS_FOLDER, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print(f"Failed to delete {file_path}. Reason: {e}")

# Iterate over the subscribers and fetch posts for active ones
for subscriber in subscribers:
if not subscriber.get('is_active'):
continue

languages = subscriber.get('languages', {})
available_lang = languages.get('available', ["en_GB"])
main_lang = languages.get('main', "en_GB")
available_lang = languages.get('available', DEFAULT_AVAILABLE_LANG)
main_lang = languages.get('main', DEFAULT_MAIN_LANG)
filter_categories = subscriber.get('filter_categories', DEFAULT_CATEGORIES)

processor = FeedProcessor(
subscriber['name'],
subscriber['shortname'],
subscriber['feed'],
available_lang,
main_lang
main_lang,
filter_categories
)
processor.fetch_and_create_post()

Expand Down

0 comments on commit 8cef39c

Please sign in to comment.