SWE 432, Fall 2018, Homework 2, Due Oct 9 Oct 10, 10 am

Tests will now print out the server error if there is one (rather than just crashing and saying there was an error)

npm pack will now ignore the uploads directory, and the previous tar file.

Project Overview

This semester, while you learn the key concepts of web application development, you will apply these skills to build a meme generator, which we will refer to as the Memebase. A meme is a cultural phenomenon that combines some popular graphic (for example, a cat or TV/movie character) with large-block text. As an example, here is a meme generated by combining a graphic called “news cat” with some text relevant to this project:

You will build the Memebase in four different components; each assignment will be one component. Each component will conform to a common interface, allowing them to be independently developed and tested. The final result will be a working website that allows users to generate memes, create accounts to share and track their memes.

This Assignment

For the second component, you will build a backend service that manages meme generation.

Getting Started

It is not required that you use an IDE, but it’s a really really really really good idea. JetBrains’ IntelliJ/WebStorm is a great choice — if you already have IntelliJ you can add the NodeJS component to it, or simply download WebStorm. You can get a free license to use any of the JetBrains IDEs by filling out this simple form.

Then, you are ready to get started. Download the handout, extract it, and then open a terminal in the handout directory. Run the command
npm install, which will download all of the JavaScript modules that the assignment will use.

Important note: DO NOT MAKE CHANGES TO PACKAGE.JSON; DO NOT INSTALL NEW PACKAGES. When we grade your project, we will grade it using the original package.json file!

Overview

This time around, you will not be directly generating images (e.g. no need to install or use gm). Instead, you’ll use a web service that we are providing to do the image generation.

Our web service lives at http://central.thememebase.com/ and exposes two endpoints:

PUT http://central.thememebase.com/resources – Uploads a base-image for later use in meme generation. Responds with a unique filename to use in the future to refer to this image
Request parameters: This endpoint allows you to upload a single file (using the form field
file). Do not send any additional data with your file.
Response (success):
{status:"OK",fileName:"theNewNameAssignedToYourFile"}
Response (failure):
{status:"ERROR",message:"SomeHopefullyDescriptiveErrorMessage"}

POSThttp://central.thememebase.com/memes – Generates a meme. The MemeBase service does not know about your meme templates – so for each request, you’ll provide all of the formatting information. The MemeBase service will automatically handle watermarking, etc. The returned data will be a PNG image.
Sample request:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

{

"graphic":"cd6028d5f8cd474a50de82f6bc9ae2de",

"text":[{

"font":"Verdana.ttf",

"size":12,

"strokeWidth":0,

"fillColor":"#000000",

"strokeColor":"#FFFFFF",

"location":{

"x":175,

"y":60,

"gravity":null

},

"text":"Make a new NPM\\nProject"

},

{

"font":"Verdana.ttf",

"size":12,

"strokeWidth":0,

"fillColor":"#000000",

"strokeColor":"#FFFFFF",

"location":{

"x":475,

"y":60,

"gravity":null

},

"text":"Generate lots\nof memes"

},

{

"font":"Verdana.ttf",

"size":12,

"strokeWidth":0,

"fillColor":"#000000",

"strokeColor":"#FFFFFF",

"location":{

"x":175,

"y":250,

"gravity":null

},

"text":"Forget to actually\ndo the\nassignment"

},

{

"font":"Verdana.ttf",

"size":12,

"strokeWidth":0,

"fillColor":"#000000",

"strokeColor":"#FFFFFF",

"location":{

"x":475,

"y":250,

"gravity":null

},

"text":"Forget to actually\\ndo the\\nassignment"

}

]

}

Sample Response (scaled down to take up less space on page):

Your MemeBase server will support the following URL endpoints:

/templates – This endpoint will be used for managing list of of meme templates, supporting the following operations:

GET: Return a listing of all of the meme templates that exist
Request Parameters: None
Response sample:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

{

"Doge":{

"graphic":"dbce44312027ca7f16631937e62ff5e9",

"text":{

"bottom":{

"fillColor":"#FFF",

"font":"Impact.ttf",

"location":{

"gravity":"South",

"x":0,

"y":20

},

"size":54,

"strokeWidth":1.5,

"strokeColor":"#000"

},

"top":{

"fillColor":"#FFF",

"font":"Impact.ttf",

"location":{

"gravity":"North",

"x":0,

"y":50

},

"size":54,

"strokeWidth":1.5,

"strokeColor":"#000"

}

}

},

"Gru":{

"graphic":"cd6028d5f8cd474a50de82f6bc9ae2de",

"text":{

"step1":{

"fillColor":"#000000",

"font":"Verdana.ttf",

"location":{

"gravity":null,

"x":175,

"y":60

},

"size":12,

"strokeColor":"#FFFFFF",

"strokeWidth":0

},

"step2":{

"fillColor":"#000000",

"font":"Verdana.ttf",

"location":{

"gravity":null,

"x":475,

"y":60

},

"size":12,

"strokeColor":"#FFFFFF",

"strokeWidth":0

},

"step3":{

"fillColor":"#000000",

"font":"Verdana.ttf",

"location":{

"gravity":null,

"x":175,

"y":250

},

"size":12,

"strokeColor":"#FFFFFF",

"strokeWidth":0

},

"step4":{

"fillColor":"#000000",

"font":"Verdana.ttf",

"location":{

"gravity":null,

"x":475,

"y":250

},

"size":12,

"strokeColor":"#FFFFFF",

"strokeWidth":0

}

}

}

}

POST: Add a new meme template
Parameters: Request body is a JSON object with a single key, which will become the name of the new meme template. That template must have one key: text. The text block will use the same format as before, but note that it is always required (no “default” text layout). The graphic must be specified after the meme is created (see below). If the template already exists, it is overwritten (overwriting all data that exists for that template).
Example request:

/templates/<template-name> – This endpoint will be used for manipulating a given template

GET: Returns statistics about the template
Request parameters: name of template (to match the key provided when it was created)
Response: JSON info about the meme, including a reference to the graphic, the text block, and a count of how many memes have been generated from that template. If the specified template does not exist, returns an empty object ({}).
Sample request:
GET http://localhost:3000/templates/doge
Sample response:

none

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

{

"Doge":{

"graphic":"dbce44312027ca7f16631937e62ff5e9",

"text":{

"bottom":{

"fillColor":"#FFF",

"font":"Impact.ttf",

"location":{

"gravity":"South",

"x":0,

"y":20

},

"size":54,

"strokeWidth":1.5,

"strokeColor":"#000"

},

"top":{

"fillColor":"#FFF",

"font":"Impact.ttf",

"location":{

"gravity":"North",

"x":0,

"y":50

},

"size":54,

"strokeWidth":1.5,

"strokeColor":"#000"

}

}

}

}

Sample response (no such meme template or other error):
{}

PUT: Uploads an image to use as the base-image for this template
This endpoint will set (or overwrite) the base-image associated with the template.
Request parameters: This endpoint must accept a single file upload (form encoded) which will be uploaded using the form field
file; the template ID is passed as part of the URI.
Example response (success):
{"Status":"OK"}
Example response (error):
{"Status":"ERROR","Message":"Unable to connect to firebase"}

DELETE: Removes a meme template. Does NOT need to worry about deleting the base image that’s stored on the TheMemeBase.com server – just needs to delete the template from your records.
Request parameters: The template ID is passed as part of the URI.
Example response (success): {
"Status":"OK"}
Example response (error):
{"Status":"ERROR","Message":"Unable to connect to firebase"}

/memes – This endpoint will be used for creating memes, it will support only one action verb:

POST: Create a new meme, returning the graphic to the client (as a PNG).
Request parameters: a JSON object describing the meme with exactly two properties:
memeTemplate and
text
Example request:

none

1

2

3

4

5

6

7

8

9

{

memeTemplate:"Gru",

text:{

step1:"Make a new NPM\nProject",

step2:"Generate lots\nof memes",

step3:"Forget to actually\ndo the\nassignment",

step4:"Forget to actually\ndo the\nassignment"

}

}

Example response (scaled down for simplicity):

:

General Requirements

Your server must use Firebase to persist all meme template information except for the base image itself (this should be relayed once to the TheMemeBase.com server.

You will implement your entire server in the app.js file.

Important tips, tricks and suggestions for getting started

Creating a Firebase App

You will need to create a (free) Firebase application in order to complete this assignment.

Once the project is created, click “continue,” which will open up the Firebase console for your project. Click on “Database”

Click “Create database” under “Cloud firestore” (do NOT select “Realtime Database”), and then select “start in test mode” and then “Enable”

Get your API authentication tokens: click on “Project Overview” in the left menu, and then on the “
</>” icon under “Get started by adding Firebase to your app”. Copy the code snippet that sets
config, and paste it in your app.js, overwriting the config that exists there.

Testing:

You can test your code by running the included tests (which is how it will be graded). Each time that a test runs, it will launch a new server and run a test against it, then stop the server.

You can also use the simple driver driver that we’ve provided (simpleDriver.js) to do more intense debugging. Start the server (
node server.js), and then you can mess around and run the simpleDriver.js code, set breakpoints, etc. If you would like the server to automatically restart as you make changes to the server code, then start the server using the command
npmrun dev.

Part 1 (60 points): Managing Templates

You will implement your entire server in the app.js file.

We suggest that you get started by implementing your meme template managing endpoints, starting with
POST/templates,GET/templates and
DELETE/templates.

You will store all of your meme templates in Firebase, using a collection called
template. Remember that Firebase’s API is asynchronous: make sure that you do not send a response back to the client until your data is stored/retrieved.

To implement
PUT/templates, you will need to send the uploaded file to the TheMemeBase.com server (by making an HTTP PUT request to it, see example above for the endpoint –
PUT http://central.thememebase.com/resources). You can find the uploaded file at
"uploads/"+req.file.filename. You will need to update the
graphic parameter of your meme template in Firebase with the returned value
fileName from TheMemeBase.com. You might find the following code snippet useful as an example for updating part of a Firebase document (without removing what’s already there):

JavaScript

1

2

3

4

5

varcityRef=db.collection('cities').doc('BJ');

varsetWithOptions=cityRef.set({

capital:true

},{merge:true});

You might also find this snippet useful for making a PUT request with an upload:

Make sure to return appropriate errors (error code 400) in the event that a client request is malformed (e.g. a
PUT request without a file attached, a
PUT request for a template that doesn’t exist,
POST requests to create new templates that are malformed).

Grading for Part 1:

11 automated tests x 5 points per test
5 points manual inspection

Part 2 (40 points): Generating Memes

Implement
POST/memes. Your implementation must assemble a request to TheMemeBase.com to generate the meme graphic. Since you are the only one keeping track of meme templates (and not the TheMemeBase.com server), you will need to compose a request that includes the text layout information and the actual textual content in one object (see example above). You should return the generated image back to the client.

Add a new property,
count, to each meme template.
Count is initialized to zero, and every time that a meme is generated, the corresponding template’s
countfield should be incremented by one.

Be sure to handle error conditions such as:

Invalid or missing meme template

Server error at TheMemeBase.com

Grading for Part 2:

6 automated tests x 6 points per test
4 points manual inspection

Grading

Your meme generator will be graded for correctness using a series of automated tests, and also by hand (as described in each section above). When you submit to Autolab, it will assume that you receive full marks from the manual grading component; this may of course go down when we actually grade your final submission. We are primarily looking for basic code quality (naming, indentation, etc), as well as correctness with handling asynchronous operations (which are incredibly tricky to check automatically). You will not receive the manual score for a component if you have not implemented anything for it.

Hand In Instructions

You must turn in your assignment using Autolab (You MUST be on the campus network, or connected to the GMU VPN to connect to Autolab). If you did not receive a confirmation email from Autolab to set a password, enter your @gmu.edu (NOT @masonlive) email, and click “forgot password” to get a new password.

To prepare your code to be submitted, run
npm pack in the assignment directory. This will create an archive
thememebase-2.0.0.tgz – this is what you will submit to Autolab. Do not try and generate this archive without using
npm; it’s highly likely to cause Autolab to reject it. When you upload your assignment, Autolab will automatically compile and test it. You should verify that the result that Autolab generates is what you expect. Your code is built and tested in a Linux VM. Assignments that do not compile using our build environment will receive a maximum of 50%. Note that we have provided ample resources for you to verify that our view of your assignment is the same as your own: you will see the result of the compilation and test execution for your assignment when you submit it.

You can resubmit your assignment an unlimited number of times before the deadline. Note the course late-submission policy: assignments will be accepted up until 24 hours past the deadline at a penalty of 10%; after 24 hours, no late assignments will be accepted, no exceptions.