Skip to content

irfanhakim-as/mango

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mango

Mango (previously deriving from "Mastodon" and "Django") is a Federated Social Network Bot Framework for Django.

Table of Contents

Features

  • Extensible framework for serving content to federated social platforms like Mastodon and Bluesky
  • A robust API for seamless integration across diverse federated platforms
  • Crossposting support to multiple accounts with custom feed configurations
  • Streamlined post and account management for effortless maintenance
  • Containerised in Ubuntu or minimal Alpine flavours for a reliable and secure deployment strategy
  • Enables applications that serve local news from RSS feeds and real-time prayer times for multiple countries

Use cases

The Mango framework is actively being used as the underlying framework for the following applications:

  • Rizz: A simple web application that tracks and posts content from RSS feeds to Federated Social Networks
  • WaktuSolat: A simple web application that offers real-time prayer time notifications on Federated Social Networks

Requirements

Note

Mango is built on top of Dim (a custom slim image of Django), hence its list of requirements also applies.

Mango's list of requirements are as stipulated in the application's requirements.txt file.

Development

Mango is primarily designed to be deployed and developed upon in a containerised environment.

For the best development and deployment strategy, please use the provided container image as the base of your application:

    FROM ghcr.io/irfanhakim-as/mango:latest as base

    # perform any additional steps required by your application

Mango is comprised of several key modules:

  • base: Base module containing most of Mango's core functionality
  • models: Mango database
  • conf: Mango application settings
  • data: Mango model data source
  • lib: Mango libraries and module extensions
  • commands: Mango management commands

Base

Important

Typically, the extending application is not expected to make any direct changes to the base module.

Design your application around what has been implemented and established in the base module, and extend upon it in the lib module which can then be used in your application in its place or in addition. This way, core functionalities of Mango could be reused or enhanced upon according to your application's requirements.

Some notable components of the base module are as follows:

  • base.apps: Application registry. By default, it is used to initialise Mango's signals upon application start. It is currently not possible to modify this module without replacing it entirely.
  • base.messages: Core message and icon dictionaries used by Mango. Changes and enhancements can be made through its existing extension, lib.messages.
  • base.methods: Core methods used by Mango. A custom module (i.e. lib.methods) could be implemented as an alternative or extension of this module in your application.
  • base.post: Core post methods used by Mango. Changes and enhancements can be made through its existing extension, lib.post.
  • base.scheduler: Core module responsible for post scheduling. Changes and enhancements can be made through its existing extension, lib.scheduler.
  • base.signals: Core module containing Mango's critical signals logic responsible for features such as scheduling newly created posts and updating managed accounts. It is currently not possible to modify this module without replacing it entirely.
  • base.urls: Core URL routing module for Mango. This module defines the main URL patterns for the base application. It is currently not possible to modify this module without replacing it entirely.

Models

In Django's words:

A model is the single, definitive source of information about your data. Generally, each model maps to a single database table.

By default, Mango's core models are comprised of:

... Each of which are extensions of base or template models implemented in models.base.

In some cases, you may want to add, remove, or replace certain models in your application. To do so:

Adding a new model

  1. Add your new model to the models module (i.e. models/examplemodel.py). The model itself can be an original model or an extension of a models.base model.

  2. Add your new model to the models.__init__ module:

        from .examplemodel import ExampleModel
  3. In your application, you can then import and use the model as follows:

        from base.methods import get_model
    
        # import the newly created model
        ExampleModel = get_model("ExampleModel")
    
        # use the model
        example_model_objects = ExampleModel.objects.all()

Removing a model

  1. It is generally not recommended to remove a core model from Mango entirely.

    If you are deleting your own model or a core model with the intent of replacing it, simply remove the model from the models.__init__ module:

        from .account import AccountObject
        from .feed import FeedObject
    -   from .post import PostItem
        from .schedule import PostSchedule

    This is an example of removing the default Post model (i.e. PostItem) to replace it with your own.

Replacing a core model

  1. Create the new model by extending the appropriate base model from models.base:

    • Account model: ObjectAccount
    • Feed model: ObjectFeed
    • Post model: ObjectItem
    • Schedule model: ObjectSchedule

    It is strongly recommended that you refer to any of the core models you are replacing to see how you can extend these base models.

  2. After adding the replacement model to the models.__init__ module, remove the model that it is replacing.

    For example:

    -   from .post import PostItem
    +   from .custompost import CustomPostModel
  3. The Mango application needs to be aware of the new model that is replacing a core model.

    To do so, you will need to update the (default) value of the following setting variable, depending on the core model you are replacing:

    • Account model: ACCOUNT_MODEL
    • Feed model: FEED_MODEL
    • Post model: POST_MODEL
    • Schedule model: SCHEDULE_MODEL

    For example, if you are replacing the core Post model with your own (i.e. CustomPostModel), update the corresponding setting's default value as follows:

    • POST_MODEL: base.CustomPostModel

    Doing so will ensure that the application uses your new model (i.e. CustomPostModel) in place of the core model (i.e. PostItem).

Conf

Most configurable settings in a Mango application are defined in a settings file that resides in the conf module. This way, these settings can be read and accessed from anywhere in your application in a consistent manner.

By default, Mango's core settings are defined in the conf.base module. An extension of this module exists as conf.main, which is the central location where the application settings are read from. To update a core setting or add new settings, do so through the conf.main module accordingly.

Adding a new setting

  1. Add the new setting required by your application to the conf.main module:

        from base.conf.base import *
    +
    +   EXAMPLE_SETTING = os.getenv("EXAMPLE_SETTING_ENV", "default_value")

    This example adds a new setting called EXAMPLE_SETTING that has the default value of default_value and can be supplied a value at runtime to its environment variable, EXAMPLE_SETTING_ENV.

  2. Defining the setting this way allows the setting's value to be supplied as an environment variable to the application at runtime.

    For example, to do so right in the Dockerfile packaging the application:

        ENV EXAMPLE_SETTING_ENV=custom_value

    In doing so, the EXAMPLE_SETTING setting will take on the value of custom_value at runtime.

  3. The setting you have defined can then be read in your application as follows:

        from django.conf import settings
    
        # get the setting
        EXAMPLE_SETTING = getattr(settings, "EXAMPLE_SETTING")
    
        # use the setting
        print(EXAMPLE_SETTING)

Updating a setting

  1. Identify the setting you wish to update from the conf.base module.

    For example, you wish to update the default value of the setting that defines the timezone used by the scheduler (i.e. SCHEDULER_TIMEZONE):

        SCHEDULER_TIMEZONE = os.getenv("SCHEDULER_TIMEZONE", "Asia/Kuala_Lumpur")
  2. Update the setting by redefining it in the conf.main module with your changes:

        from base.conf.base import *
    
    +   SCHEDULER_TIMEZONE = os.getenv("SCHEDULER_TIMEZONE", "UTC")
  3. At runtime, the setting you have updated should now take the place of the default setting.

Making the setting compulsory

In Mango, it is possible to flag a setting as required or compulsory. In doing so, the application will fail to start if the setting is not defined or has not been supplied a value.

  1. Update the setting COMPULSORY_SETTINGS in the conf.main module:

        COMPULSORY_SETTINGS.extend([
            "EXAMPLE_SETTING",
        ])

    Instead of redefining it from scratch, simply extend the list to include additional settings you wish to make compulsory.

  2. Now, the application will fail the required tests to start if the required setting (i.e. EXAMPLE_SETTING) is not defined or has not been supplied a value.

Data

The data module is home to core data files, in JSON, used by Mango. This list includes:

These data files are essential and offer a simple way for system administrators to configure managed social network accounts, as well as content feeds such as RSS or API endpoints, and supply them to the application at runtime.

Any additional data files needed by your application can be added to this module as well. In such cases, if you intend to use the data file as a data source and have it sync to i.e. a custom model at runtime, update the SYNC_CONFIG setting like so:

    SYNC_CONFIG["example_key"] = {
        "model": EXAMPLE_MODEL,
        "data": EXAMPLE_DATA_FILE,
        # include the following if your model has fields that require uniqueness
        # "object_id": ("example_id",),
    }

Lib

Important libraries such as all the necessary integrations for Bluesky and Mastodon are defined in the lib module:

Any additional libraries and future integrations for enhancing Mango should be placed in this module.

Extensions to Mango's core base modules could also be found in this module, such as:

These extensions, and any additional extension you wish to add can be used to modify or add functionalities to the core modules safely.

Commands

Django management commands act as a way to customise or add additional commands that can be used to perform certain tasks while the application is running.

By default, Mango's commands module contains the following commands:

Should your application require any additional commands, you may refer to these commands on how to easily create your own and add them to this module accordingly.

To run a management command, do the following while the Mango application is running:

python3 manage.py <command>

Replace <command> with the name of the command module you wish to run (i.e. example_command).

License

This project is licensed under the AGPL-3.0-only license. Please refer to the LICENSE file for more information.

About

Mastodon bot module for Django

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages