This is the second project in Udacity's Intermediate Python Nanodegree program.
This project will create a meme by overlaying a quote with an author's name at a random position over an image.
The user can customize the output by providing an image, a quote, and an author's name. If any of these are omitted, one will be randomly provided.
Clone the project repository.
git clone https://github.com/johnshea/nd303_project_02_meme_generator.git
Change into the project directory.
cd nd303_project_02_meme_generator
Create a virtual environment.
python3 -m venv env
Activate the virtual environment.
source env/bin/activate
Change into the src
directory.
cd src
Install the required project dependencies.
pip install -r requirements.txt
Create the required output directories.
mkdir static
mkdir tmp
Follow the steps below for running this as a command line application or as a Flask application.
NOTE: When finished, to exit the virtual environment run:
deactivate
From the command line, run:
python3 meme.py
Additional runtime configuration options:
usage: meme.py [-h] [-p PATH] [-b BODY] [-a AUTHOR]
Create a meme
optional arguments:
-h, --help show this help message and exit
-p PATH, --path PATH path to an image file
-b BODY, --body BODY quote body to add to the image
-a AUTHOR, --author AUTHOR
quote author to add to the image
From the command line, run:
$ export FLASK_APP=app.py
$ flask run --host 0.0.0.0 --port 3000
Open your browser.
Open http://localhost:3000/
NOTE - Generated memes will be saved in directory static
.
Dependencies: PIL
, random
, os
A class to generate a meme.
Method make_meme
will generate a meme from optionally provided arguments. This method will return the path of the generated meme.
Example:
>>> from MemeGenerator import MemeEngine
>>> meme = MemeEngine('./output')
>>> meme.make_meme('./_data/photos/dog/xander_3.jpg', 'Go big or go home!', 'Slugger', width=250)
'./output/8943911.png'
>>>
Dependencies: abc
, QuoteModel
, typing
An abstract base class upon which concrete ingestor classes are realized.
An ingestor class is a concrete subclass which will parse file types based on their file extension.
Concrete classes must implement:
- abstract method
parse
. This method parses the provided file and returns a list ofQuoteModel
objects. - override class variable
allowed_extensions
which is a list of file extensions types which is can parse. Example:allowed_extensions = ['txt']
Dependencies: IngestorInterface
, TextIngestor
, DocxIngestor
, CSVIngestor
, PDFIngestor
, QuoteModel
, typing
A general class that is capable of ingesting multiple file types by delegating to individual ingestor classes.
A call to method parse
will returns a list of QuoteModel
objects.
Example:
>>> from QuoteEngine import Ingestor
>>> print(Ingestor.parse('./_data/DogQuotes/DogQuotesTXT.txt'))
[<QuoteModel author='Bork' body='To bork or not to bork'>, <QuoteModel author='Stinky' body='He who smelt it...'>]
>>>
Dependencies: IngestorInterface
, QuoteModel
, typing
, pandas
A concrete class to ingest a csv
file.
A call to method parse
will return a list of QuoteModel
objects.
File Format:
body,author
Line 1,Author 1
Line 2,Author 2
Example:
>>> from QuoteEngine import CSVIngestor
>>> print(CSVIngestor.parse('./_data/DogQuotes/DogQuotesCSV.csv'))
[<QuoteModel author='Skittle' body='Chase the mailman'>, <QuoteModel author='Mr. Paws' body='When in doubt, go shoe-shopping'>]
>>>
Dependencies: IngestorInterface
, QuoteModel
, typing
, docx
A concrete class to ingest a docx
file.
A call to method parse
will return a list of QuoteModel
objects.
File format:
"Line 1" - Author 1
"Line 2" - Author 2
Example:
>>> from QuoteEngine import DocxIngestor
>>> quotes = DocxIngestor.parse('./_data/DogQuotes/DogQuotesDOCX.docx')
>>> print(quotes)
[<QuoteModel author='Rex' body='Bark like no one’s listening'>, <QuoteModel author='Chewy' body='RAWRGWAWGGR'>, <QuoteModel author='Peanut' body='Life is like peanut butter: crunchy'>, <QuoteModel author='Tiny' body='Channel your inner husky'>]
>>>
Dependencies: IngestorInterface
, QuoteModel
, typing
, subprocess
, random
, tempfile
, os
A concrete class to ingest a pdf
file.
A call to method parse
will return a list of QuoteModel
objects.
File format:
"Line 1" - Author 1
"Line 2" - Author 2
Example:
>>> from QuoteEngine import PDFIngestor
>>> quotes = PDFIngestor.parse('./_data/DogQuotes/DogQuotesPDF.pdf')
>>> print(quotes)
[<QuoteModel author='Fluffles' body='Treat yo self'>, <QuoteModel author='Forrest Pup' body='Life is like a box of treats'>, <QuoteModel author='Bark Twain' body='It's the size of the fight in the dog'>]
>>>
Dependencies: IngestorInterface
, QuoteModel
, typing
A concrete class to ingest a txt
file.
A call to method parse
will return a list of QuoteModel
objects.
File format:
"Line 1" - Author 1
"Line 2" - Author 2
Example:
>>> from QuoteEngine import TextIngestor
>>> print(TextIngestor.parse('./_data/DogQuotes/DogQuotesTXT.txt'))
[<QuoteModel author='Bork' body='To bork or not to bork'>, <QuoteModel author='Stinky' body='He who smelt it...'>]
>>>
Dependencies: None
A data class to hold a quote which contains a quote body and quote author.
Example:
>>> from QuoteEngine import QuoteModel
>>> quote = QuoteModel("Body of Quote", "Author name")
>>> print(quote)
<QuoteModel author='Author name' body='Body of Quote'>
>>>