The Basics

This is a basic tutorial on using fpclib to curate games for Flashpoint.

If you’ve never coded in python before, you should check out the official python tutorial page first.

This tutorial assumes that you already know the basics of curating for Flashpoint. If you do not know how to curate games/animations for Flashpoint, please follow the Curation Tutorial before using fpclib.

Purpose

As stated on the Home page, there are numerous benefits of using fpclib to help you curate:

  • By default, fpclib downloads main game/animation files and puts them in the right file format based upon your launch commands.

  • Logos and screenshots can be automatically downloaded from online and converted to PNG files.

  • Curating similar games/animations from one or more websites is simple and easy thanks to the fpclib.curate() function.

  • Nearly every kind of Curation is possible to make with this library! This library and documentation were created with the intent of making it easy to overwrite the Curation class to make it do different things. Anything you can do in the “Curate” tab in Flashpoint Core you can do with fpclib, except test games.

Ultimately, fpclib is not meant to replace other curating tools such as Flashpoint Core; it is meant to be used alongside of them. Always make sure any curation you make with fpclib is tested in Flashpoint Core before you submit it.

Usage

You can install the library with

pip install fpclib

or you can put the “fpclib.py” script (check the releases page on github) in the same directory as your script.

If you choose the second option, you’ll also need to install these libraries through pip:

pip install requests
pip install beautifulsoup4
pip install pillow
pip install ruamel.yaml

Once you have all of that set up, you can put import fpclib at the top of your script to use it’s methods.

Special Functions

To help you with common curating tasks, fpclib comes packaged with several useful module-level functions. Here’s a quick list of all of them; you can click on any of them for more details about what they do:

Internet

download(url[, loc, name])

Downloads the webpage or file at url to the location loc.

download_all(urls[, loc, preserve, ...])

Downloads a list of files with their website folder structure to the location loc.

download_image(url[, loc, name])

Downloads the image from url to the location loc as a PNG file.

normalize(url[, preserve, keep_vars, keep_prot])

Formats url to a normalized format.

read_url(url[, ignore_errs, content])

Reads the webpage or file at url and returns its contents as a text string.

get_soup(url[, parser, ignore_errs])

Reads the webpage at url and creates a BeautifulSoup object with it.

get_fpdata(page[, ignore_errs])

Reads the Flashpoint online datahub at https://flashpointarchive.org/datahub/{page} and returns a list of possible values; you can use this to get the most up-to-date tags and platforms.

File IO

read(file_name)

Reads the contents of the file file_name into a string.

read_lines(file_name[, ignore_lines])

Reads the lines of the file file_name into a list of strings split by any new line character (rn, r, or n).

read_table(file_name[, delimiter, ignore_lines])

Reads the contents of the file file_name into a two dimensional list of strings with rows split by any new line character (rn, r, or n) and columns split by delimiter.

make_dir(folder[, change, overwrite])

Makes a folder at folder, along will all parent folders.

delete(file_name)

Deletes the file or folder file_name recursively.

write(file_name[, contents, force])

Writes contents to the file file_name in utf-8.

write_line(file_name[, line, force])

Append line to the file file_name.

write_table(file_name, table[, delimiter, force])

Writes the two-dimensional list table to the file file_name.

scan_dir([folder, regex, recursive])

Scans the directory folder recursively and returns all files and sub-folders as two lists.

replace(files, old, new[, regex, ignore_errs])

Replaces all instances of old with new in files.

hash256(obj)

Serializes obj and then returns a sha256 HASH object of it.

hash(obj)

Serializes obj and then gets a four-byte integer representation of those bytes with the first four bytes of it's sha256.

Curating

test()

Tests the library to make sure it works.

update()

Initializes or updates variables that are generated from online.

debug(text, mode, *items[, pre])

Prints text depending on mode and DEBUG_LEVEL.

clear_save([loc])

Deletes the "c-info.tmp" file generated by curate() and curate_regex() in the current working directory or loc.

curate(items, curation_class[, use_title, ...])

Curates form a list of urls given by items with a sub-class of Curation specified by curation_class.

curate_regex(items, links[, use_title, ...])

Curates from a list of urls given by items with a list of links.

load(curation)

Loads the curation in the folder curation into Curation object using ruamel.yaml.

A Single Curation

Before curating entire lists of games/animations with fpclib, it’s important to understand how to use the library to curate a single game/animation by itself first. As shown on the Home page, here’s some very basic code you can use to curate a game:

# Import fpclib curation
from fpclib import Curation

# Create a curation from a given url
curation = Curation(url='https://www.newgrounds.com/portal/view/218014')
# Set the logo of the curation
curation.logo = 'https://picon.ngfiles.com/218000/flash_218014_medium.gif'

# You can set metadata through the object directly or through the set_meta method
curation.set_meta(title='Interactive Buddy', tags=['Simulation', 'Toy'])
curation.set_meta(dev='Shock Value', pub='Wrong Publisher')
curation.pub = 'Newgrounds'
curation.ver = '1.01'
curation.date = '2005-02-08'

# Add an additional app
curation.set_meta(cmd='http://uploads.ungrounded.net/218000/218014_DAbuddy_latest.swf')
curation.add_app('Kongregate v1.02', 'http://chat.kongregate.com/gamez/0003/0303/live/ib2.swf?kongregate_game_version=1363985380')

# Export this curation to the current working directory
curation.save()

Here’s what each step in this code does:

  1. Import the library with import fpclib

  2. Create a new Curation object. You don’t have to set it’s url immediately, but it should be set before you call Curation.save().

  3. Set the url of the curation’s logo. You can also set the screenshot with Curation.ss. Note that this will automatically be converted to a png file when the curation is saved. You do not need to set the logo or screenshot for every curation.

  4. Set the curation’s metadata using Curation.set_meta() or directly through the object. You can put as many or little arguments into the function as you want. To see what arguments (or attributes) map to which parts of the curation’s metadata, see Curation.ARGS. Note that descriptions and notes support multiple line strings (split lines with \n).

  5. Add an additional app with Curation.add_app(). You can also create extras, a message, or delete additional applications with other functions too (see the functions after Curation.add_app()).

  6. Finally, Save the curation to a folder with Curation.save(). This accepts an argument named use_title which if you set to True, will generate the curation folder with the curation’s title instead of its id (see Curation.id).

You can find a full listing of every function in the Curation class in the Classes page.

Editing Curations

It’s also possible to load and edit existing curations by using the fpclib.load() function. Here’s an example of that function in action:

import fpclib

c = fpclib.Curation(url='https://www.newgrounds.com/portal/view/218014', title='Interactive Buddy', cmd='http://uploads.ungrounded.net/218000/218014_DAbuddy_latest.swf')
c.save(True)

d = fpclib.load('Interactive Buddy')
d.logo = 'https://picon.ngfiles.com/218000/flash_218014_medium.gif'
d.add_app('Kongregate v1.02', 'http://chat.kongregate.com/gamez/0003/0303/live/ib2.swf?kongregate_game_version=1363985380')
d.save(True, overwrite=True)

Note that if you want to mix new curations together with older curations with the same folder name, you have to set overwrite to True.

Debugging

As of version 1.3, fpclib supports printing debugging information about what it’s doing. You’ll normally see this when running fpclib.test(), fpclib.curate(), or fpclib.curate_regex(). If you want to change what gets printed, modify the DEBUG_LEVEL variable like so:

fpclib.DEBUG_LEVEL = 2

This is by default set to 1, and only prints basic information from fpclib.test(), fpclib.curate(), and fpclib.curate_regex().

Further Reading

If you fully understand how to make one curation at a time, you should move on to the Advanced Stuff page to figure out how to curate in bulk.