Giter VIP home page Giter VIP logo

raintale's Introduction

Raintale

Raintale is a utility for publishing social media stories from groups of archived web pages (mementos). Raintale uses MementoEmbed to extract memento information and then publishes a story to the given storyteller, a static file or an online social media service.

Raintale accepts the following inputs:

  • a file containing a list of memento URLs (URI-Ms) (required)
  • a title for your story (required)
  • the URL of the underlying collection (optional)
  • the author, organization, or algorithm that generated the story (optional)
  • the storyteller to use when generating the story (e.g., HTML, Twitter, Markdown)
  • an output file for saving the story (if applicable)
  • a credential file for the a social media service (if applicable)
  • a template file allowing the user to format their story differently than the defaults (optional, and not supported by all storytellers)

Raintale supports the following storytellers:

  • facebook - (EXPERIMENTAL) publishes a story as a Facebook thread, with titles, snippets, URLs, and memento-datetimes supplied by MementoEmbed
  • html - the HTML that makes up a story, suitable for pasting into a web page or a blogging application such as Blogger
  • twitter - publishes a story as a Twitter thread, with titles, URLs, memento-datetimes, and images supplied by MementoEmbed
  • template - given input data and a template file, this storyteller generates a story formatted based on the template and saves it to the given output file, allowing the end user to format their own stories
  • jekyll-html - writes output to Jekyll HTML file format, suitable for use with Jekyll and GitHub pages
  • jekyll-markdown - writes output to Jekyll Markdown file format, suitable for use with Jekyll and GitHub pages
  • markdown - writes output to the GitHub Flavored Markdown file format, suitable for pasting into GitHub
  • mediawiki - writes output to this MediaWiki file format, suitable for pasting into MediaWiki pages

Railtale also supports a number of presets for formatting a story for output to a specific file format:

  • default - provides a default set of fields like those seen in the social cards from social networking; may also provide an approximation, depending on file format (html, markdown, mediawiki, and jekyll storytellers)
  • thumbnails3col - provides a 3 column layout containing thumbnails of the submitted mementos (HTML storyteller only)
  • thumbnails4col - provides a 4 column layout containing thumbnails of the submitted mementos (HTML storyteller only)

Note that not all file formats support all presets.

Installing Raintale

Before installing Raintale, make sure that the MementoEmbed service is installed and running somewhere.

Installing Raintale on Linux or Unix

Before installing Raintale, you must have an instance of MementoEmbed running on a machine, either locally or elsewhere. If you do not have MementoEmbed, please install the latest release of MementoEmbed.

To install Raintale on Linux or Unix, choose your target platform below.

CentOS 8

If you would like to use the RPM installer for RHEL 8 and CentOS 8 systems:

  1. Download the RPM and save it to the Linux server (e.g., raintale-0.20211106041644-1.el8.x86_64.rpm)
  2. Type dnf install raintale-0.20211106041644-1.el8.x86_64.rpm
  3. Type systemctl start raintale-django.service

To stop Raintale, type systemctl stop raintale-django.service.

To remove Raintale, type dnf remove raintale. Removing Raintale stops the associated raintale service and its celery companion. Be patient, sometimes celery takes a long time to stop.

During removal, the directory /opt/raintale/raintale_with_wooey/raintale_with_wooey/user_uploads is saved to /opt/raintale/user_uploads-backup-[DATE].tar.gz where [DATE] was the date and time of removal. This is where all story outputs are stored. The administrator may wish to delete or backup this file for future use.

Ubuntu 21.04

If you would like to use the DEB installer for RHEL 8 and CentOS 8 systems:

  1. Download the RPM and save it to the Linux server (e.g., raintale-0.20211113202900.deb)
  2. Type apt-get install raintale-0.20211113202900.deb
  3. Type systemctl enable raintale-celery.service
  4. Type systemctl enable raintale-django.service
  5. Type systemctl start raintale-django.service

To stop Raintale, type systemctl stop raintale-django.service.

To remove Raintale, type apt-get remove raintale.

Generic Unix

We also support a generic Unix installer which downloads many dependencies from the web. Unfortunately, these dependencies are not always version-locked and results on your system may vary.

  1. Download the generic Unix installer (e.g., install-raintale.sh)
  2. Type install-raintale.sh
  3. To start the Raintale WUI, type /opt/raintale/start-raintale-wui.sh

To stop raintale, type /opt/raintale/stop-raintale-wui.sh.

Installing Raintale in a Python Environment

Raintale uses pip for build and installation. Clone this repository and type the following from the root of the source code:

  1. Clone this repository.
  2. Change into the directory where it was cloned.
  3. Create a virtualenv to separate Raintale's install from other Python installations.
  4. Type pip install .

Installing the Raintale Web User Interface (WUI) in a Python Environment

To install the Raintale WUI, do the following:

  1. Follow the above instructions for installing Raintale in a Python Environment.
  2. Type raintale-gui/install-gui.sh

This installation script will install Wooey and other dependencies required to run the Raintale WUI.

To stop Raintale WUI, type raintale-gui/stop-gui.sh.

Improving the performance of the Raintale WUI

Once installed, Raintale's WUI performance can be improved in a few ways.

Configuring Raintale WUI for Postgres

By default, the Raintale WUI uses SQLite, which does not perform well for multiple users logging into the same Raintale WUI system. For optimial user experience, the Raintale WUI can be connected to a Postgres database.

  1. Install Postgres on a system accessible to the server that on which the Raintale WUI is running. Record that system's host and the port Postgres is running on -- the default port is 5432.
  2. Log into Postgres and create a database with postgres for Raintale.
  3. Create a user and password.
  4. Grant all privileges on the database from step 2 in step 3.
  5. Run /opt/raintale/raintale-gui/set-raintale-database.sh --dbuser [DBUSER] --dbname [DBNAME] --dbhost [DBHOST] --dbport [DBPORT] -- with DBUSER created from step 3, DBNAME replaced by the database you created in step 2, DBHOST and DBPORT recorded from step 1. The script will prompt you for the password.
  6. Restart Raintale as appropriate for your system.

Configuring the Raintale WUI for RabbitMQ

For optimal process control, the Raintale WUI can use a queueing service like RabbitMQ.

  1. Install RabbitMQ on a system accessible to the server that the Raintale WUI is running on. Record that system's hostname and the port that RabbitMQ is running on -- the default port is 5672.
  2. Run /opt/raintale/raintale-gui/set-raintale-queueing-service.sh --amqp-url amqp://[HOST]:[PORT]/ where HOST is the host of the RabbitMQ server and PORT is its port

Enabling Raintale's Experimental Video Stories for the Raintale WUI on CentOS 8

By default, Raintale's video stories are not enabled in the Raintale WUI in CentOS 8 installs. Generating these stories requires ffmpeg. Installing ffmpeg on Ubuntu is easy. Installing ffmpeg on CentOS 8 requires using YUM/DNF repositories outside of those provided by CentOS, as detailed in [https://linuxize.com/post/how-to-install-ffmpeg-on-centos-8/](these instructions). Rather than force all Centos 8 Raintale administrators to go through this process, we have disabled video stories through the Raintale WUI.

To enable them:

  1. install ffmpeg
  2. Open /opt/raintale/raintale-gui/add-raintale-scripts.sh in an editor and remove the # and space from the line containing Create Video Story.py so it looks like this (spaces are significant):
python ${WOOEY_DIR}/manage.py addscript "${SCRIPT_DIR}/scripts/Create Video Story.py"
  1. Run /opt/raintale/raintale-gui/add-raintale-scripts.sh

raintale's People

Contributors

himarshaj avatar ibnesayeed avatar machawk1 avatar shawnmjones avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

raintale's Issues

Add image as a story element type

Raintale already supports the link and text story element types in JSON input. An image story element type would allow users to handle images in a special way with their templates. It should not be handled that differently from text. This would just give users an additional key with which to control the look of output in templates.

A potential additional key is video. Because the user may need to other key types, this may require more thought than just adding if statements.

Remove Raintale GUI's Download button

Wooey has a confusing setup with respect to Downloads. We will be implementing a "View Story" button in #26 which will make the existing Download button redundant. We should remove the Download button so that it does not confuse users.

The code to do so is here:

<div class="btn-group status-completed-toggle">
<a href="{{ job_info.archives.0.url }}" role="button" class="btn btn-primary">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span> {% trans "Download" %}
</a>
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">{% trans "Toggle Dropdown" %}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for archive in job_info.archives %}
<li><a href="{{ archive.url }}"><span class="glyphicon glyphicon-compressed"></span> {% if archive.url|endswith:"zip" %}.zip{% else %}.tar.gz{% endif %}</a></li>
{% endfor %}
</ul>
</div>

Support Jinja2 filters

Raintale templates are based on Jinja2 templates. With the addition of preferences, Raintale templates are no longer Jinja2 compatible, but Jinja2 filters would still be useful to users.

The differences:

  • Preferences instruct Raintale how to generate the value for a variable. Example: choosing the 3rd best sentence from the document.
  • Filters instruct Jinja2 how to alter the value of a variable after creation. Example: converting the text to uppercase.

Raintale should still support Jinja2 filters.

Preferences are handled like so:
{{ variable|prefer key=value,key2=value2 }}

Jinja2 filters could be added to the mix like so:
{{ variable|prefer key=value,key2=value2|filter1|filter2(arg1, arg2)|filter3 }}

Ensure Raintale GUI documentation contains details for setting it up on a production server

The Raintale GUI production environment needs more robust infrastructure than provided by our Docker installation.

By default Wooey/Django uses SQLite as a database. SQLite allows for concurrent reads, but locks and queues concurrent writes. This is great for a single user, but not so good for a system that will satisfy multiple users. Django supports changing the backend database to something else.

Based on the Wooey documentation, it will use the default database for queuing, but RabbitMQ is "a more robust system" than the default database because RabbitMQ is specially designed for this queuing.

We should at least point to documentation that helps users set this up. We could also update our installer to alter the correct Django settings files as needed by administrators.

set-raintale-database.sh: No module named 'psycopg2'

Following the postgres instructions after installing from RPM on a fresh CentOS install running set-raintale-database.sh fails with this error:

changing to /opt/raintale/raintale-gui/../raintale_with_wooey
Traceback (most recent call last):
  File "/opt/raintale/raintale-virtualenv/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 25, in <module>
    import psycopg2 as Database
ModuleNotFoundError: No module named 'psycopg2'

Installing the system python38-psychopg2 package did not help. Installing it with pip inside the raintale-virtualenv resolves the error:

sudo dnf group install -y 'Development Tools'
sudo dnf install -y python38-devel postgresql-devel
sudo /opt/raintale/raintale-virtualenv/bin/pip install psycopg2

Recommend either adding this step to the section about configuring raintale for postgres or shipping psycopg2 in the package.

Finish Raintale GUI script for Create Video Story

We can finish the Create Video Story script by adapting what we've learned from the existing Create Story From Template script. Much of the structure is the same.

The storyteller class we need to use is VideoStoryTeller as found in raintale/storytellers/video.py.

Video stories do not support a template, so the code does not need to support one as input.

set-raintale-database.sh: references non-existent hypercane_with_wooey directory

writing database information to /opt/raintale/raintale-gui/../hypercane_with_wooey/hypercane_with_wooey/settings/user_settings.py
/opt/raintale/raintale-gui/set-raintale-database.sh: line 118: /opt/raintale/raintale-gui/../hypercane_with_wooey/hypercane_with_wooey/settings/user_settings.py: No such file or directory

I assume that should be raintale_with_wooey not hypercane_with_wooey. There are some other references to hypercane in the script that probably don't belong:

echo "the command '$command' is required to install Hypercane; it was not detected in your PATH"

WOOEY_DIR="${SCRIPT_DIR}/../hypercane_with_wooey"

settings_file=${WOOEY_DIR}/hypercane_with_wooey/settings/user_settings.py

# add Hypercane scripts

Add caching support to Raintale

Raintale was originally built without caching support because it only issued calls to MementoEmbed. Storytellers like the video storyteller require making additional HTTP(S) requests to web archives. Caching may also help with testing.

The requests-cache library is used elsewhere in the DSA toolkit for this purpose.

Provide meaningful error message if the user provides the Twitter template for "Create Story with Template" script.

If the user provides the Twitter template for the "Create Story with Template" script, the script will fail with no useful error message currently. We have to make sure a meaningful error message is provided in such a scenario.

We can update the storyteller code to account for this.

https://github.com/oduwsdl/raintale/blob/master/raintale/storytellers/storyteller.py

if template_contents[0:34] == '{# RAINTALE MULTIPART TEMPLATE #}\n':
 display error message

Create a "View Story" button in Raintale's GUI

A user can view their Raintale story if they know which file link to click on, but this is not friendly.

A better way would be to have a "View Story" button as @himarshaj and I have discussed. It would have to be aware of how to handle different story types, for example:

  • for Create Story From Preset, Create Story From Template, and Create Video Story this button will link to the file that was generated as part of the storytelling process
  • for Tell Story With Facebook and Tell Story With Twitter this button will link to the associated social media post

We need to figure out how Django's template engine can tell the difference. Maybe there is a control flow statement we can use that will change behavior based on the job type. A second challenge is how to read the URL from the output in the case of social media stories so we can alter the behavior of this button.

The template controlling this behavior is in raintale-gui/templates/jobs/job_view.html.

Systemd service definition for Raintale

Our existing start-gui.sh and stop-gui.sh scripts work well for Docker deployment, but, as noted by @ato, we need something more robust for general server installation.

@ato has provided a Gist here that provides this capability:
https://gist.github.com/ato/69fc6952ce57d329a402a6f9f128f6e1

We need to include these as separate files in the raintale/raintale-gui/ folder to be included in a future installer. Several people, including Olga from the IIPC, have asked that we attempt to make services like the Raintale GUI easier to install, and @ato's systemd work goes a long way to making this happen.

We will have to independently test this on another systemd-capable machine as well.

Optionally allow the Raintale GUI to require user authentication for all users after install

As identified by @ato, an organization may only wish to accept Raintale templates from trusted individuals.

This will require two actions:

  1. when completing the documentation for the Raintale GUI, we will have to provide at least a link to instructions for creating a superuser and adding users via the Django administrator interface
  2. we will need to disable the Registration link on the main page if a user requests it during or after installation

Addressing #1 will not be accomplished until we complete the Raintale GUI documentation.

Addressing #2 requires that an installer disable the /accounts/register/ endpoint with the following steps.

After reviewing Wooey's source code and testing locally, I've determined that the installer can disable that by setting WOOEY_REGISTER_URL to None. inside settings/user_settings.py.

Finally, to ensure that only authenticated users are allowed to execute Raintale scripts, the installer will set WOOEY_ALLOW_ANONYMOUS from settings/user_settings.py to False.

So, to summarize, install-gui.sh should:

  • accept a flag indicating that the user wishes to install the system without registration
  • if that flag is set, it will set WOOEY_REGISTER_URL to None inside settings/user_settings.py
  • if that flag is set, it will set WOOEY_ALLOW_ANONYMOUS to False inside settings/user_settings.py

set-raintale-database.sh: hang due to grep without input

set-raintale-database.sh hangs after printing:

verifying that database is empty
discovered 0 tables in the database
database is empty, continuing
writing database information to /opt/raintale/raintale-gui/../hypercane_with_wooey/hypercane_with_wooey/settings/user_settings.py

It appears to be stuck with this grep command reading from stdin:

ME_line=`grep MEMENTOEMBED_ENDPOINT`

New Preset Request: Tweets with Imagereel

This is a request for a new template to be included with Raintale.

Storyteller: Twitter

Template code is below:

{# RAINTALE MULTIPART TEMPLATE #}
{# RAINTALE TITLE PART #}
{{ title }}

{% if generated_by is not none %}Story By: {{ generated_by }}{% endif %}

{% if collection_url is not none %}{{ collection_url }}{% endif %}
{# RAINTALE ELEMENT PART #}

{{ element.surrogate.title }}

{{ element.surrogate.memento_datetime }}

{{ element.surrogate.urim }}

{# RAINTALE ELEMENT MEDIA #}
{{ element.surrogate.imagereel }}

Update Raintale GUI installer to support newest version of Django

Wooey does not currently support Django 3.2.5 and the Raintale GUI installer downgrades Django to 3.1.8 so that our system will work. The author of Wooey assures me that a fix will be included in the next Wooey version. Once that version is available, we need to remove the lines downgrading Django from our installer.

if [ $INSTALL_ALL -eq 0 ]; then
echo "installing specific Django version"
pip install Django==3.1.8 # see https://github.com/wooey/Wooey/issues/334
else
pip freeze | grep Django==3.1.8 > /dev/null
status=$?
if [ $status -eq 0 ]; then
echo "Django already installed, skipping install of Django"
else
echo "installing specific Django version"
pip install Django==3.1.8 # see https://github.com/wooey/Wooey/issues/334
fi
fi

postgres support: raintale-celery.service missing EnvironmentFile=/etc/raintale.conf

After enabling postgres support according to the documentation jobs get stuck with status "Waiting" and raintale-celery service logs the following error:

Nov 16 07:52:32 localhost.localdomain celery[71877]: psycopg2.OperationalError: FATAL: password authentication failed for user "raintale"

Fixed by adding this line to [Service] section in /etc/systemd/system/raintale-celery.service:

EnvironmentFile=/etc/raintale.conf

and then restarting with:

sudo systemctl daemon-reload
sudo systemctl restart raintale-celery

Remove Wooey's Re-run and Resubmit buttons from the Raintale GUI

They are confusing to us and will likely be so for users. Until we can articulate how to use them, we should remove them.

We just need someone to remove the lines from raintale-gui/templates/jobs/job_view.html:

<button class="btn btn-primary btn-warning status-completed-toggle status-revoked-toggle status-failure-toggle" name="celery-command" value="rerun" type="submit">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span> {% trans "Re-run" %}
</button>
<button class="btn btn-warning" name="celery-command" value="resubmit" type="submit">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span> {% trans "Resubmit" %}
</button>

Update celery multiprocessing options in Raintale GUI start script

The Wooey documentation states that users start it by running both Django and Celery. The commands they provide for starting Wooey are:

# celery -A your_project_name worker -c 1 --beat -l info
# python manage.py runserver

We've been trying to determine why jobs in Wooey appear to be blocking and thus only execute sequentially. The problem is with the -c 1 argument, which tells Celery to only start 1 process to process the queue. If we remove -c 1 then it will start a number of processes equal to the number of CPUs present in the system, allowing for Wooey (and Raintale) to execute more than one process at a time.

We need to remove -c 1 from the GUI startup script in start-gui.sh:

celery -A ${CELERY_PROJECT_NAME} worker -c 1 --beat -l info > celery-output.log 2>&1 &

For reference, I have already done this with Hypercane's GUI startup.

For Raintale GUI, remove user option to specify output filename

Per feedback from @ato, if we allow users to specify an output file, they could abuse the server and overwrite existing system files. We really do not need to provide this option. To avoid this security issue, we should do two things for all Raintale scripts that have output files:

  1. remove the option of specifying an output filename from all GUI scripts - this addresses the security concern
  2. make the default output filename output.dat or story-file.dat with an appropriate extension - I'm leaning toward story-file.dat or story.dat or something like that -- just make sure it is descriptive and matches the work done in #26

This should not affect stories that use social media because there is no output filename.

Create a Linux install for Raintale

This script should take into account the lessons learned from #19, #20, and #21.

Ideally, we would create an RPM install for RedHat-based systems and a DEB install for Debian-based systems, but that may be a bit too much to test for the duration of the IIPC Grant. A tarball containing the necessary files and an installation script is likely enough. To make it administrator-friendly, we could apply Makeself as well. This way the user can download a single file, execute it, and it will extract our content, execute our script, and start up the Raintale GUI.

Implement http retries with MementoEmbed

Sometimes MementoEmbed has a transient error when processing memento content. Right now Raintale crashes and instructs the user to just rerun the program if something goes wrong. It should, instead, retry n times before giving up, like the OTMT does.

Write Documentation for Raintale WUI

The Raintale WUI needs to be documented once completed. The documentation should include screenshots and descriptions of how to use Raintale as well as how to install the system.

set-raintale-database.sh calls `manage.py migrate` with placeholder db config

set-raintale-database.sh creates a file /etc/raintale.conf containing the database details supplied by the command-line and password prompt. It then adds a section to user_settions.py that references these as environment variables. However it never actually sets these as environment variables when calling manage.py migrate, so the placeholder values like "raintale_password" are used instead of the values entered by the user. The migrate command therefore fails with:

psycopg2.OperationalError: FATAL:  password authentication failed for user "raintale"

I worked around this by adding this to set-raintale-database.sh before the migrate command:

source "${raintale_conf}"
export DATABASE_NAME DATABASE_PORT DATABASE_HOST DATABASE_USER DATABASE_PASSWORD

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.