SMILEConsortium / node-smile-server

3 stars 4 forks source link

Teachers would like an IQ content management web interface #26

Closed truedat101 closed 10 years ago

truedat101 commented 11 years ago

Does two things

truedat101 commented 11 years ago

5 is done, so we can now easily store off the session data in a structured JSON object.

truedat101 commented 11 years ago

Need to hook up the session saving feature. However, we don't have all the metadata required by the model. We need to be passing Teacher Name, Session Title, and Group Name into the START_MAKE_QUESTIONS phase. I've added an issue: https://github.com/SMILEConsortium/smile_teacher_android/issues/36 to handle.

truedat101 commented 11 years ago

I was wondering if we'd want some other TEACHER_HAIL type message, but I think not. Let's just pass it in. If the teacher client is older and doesn't behave this way, we'll set some bogus defaults. The most important is the Session Title.

truedat101 commented 11 years ago

Address changes in routes.handleStartMakeQuestionPut()

truedat101 commented 11 years ago

Need to detect if teacher metadata is somehow null so we pass back defaults if someone requests all session data.

truedat101 commented 11 years ago

ok, now we need to sort out posting the cvs file upload. What we'll do in the case of the IQManager Web UI is post the contents of the csv submission to the web. On the tablet, we load the content, and then disect the CSV data into JSON, and post to /smile/question

What I think we need to do is support file upload of the .csv and parse it into json on the server. This would persist each Question and persist into an IQSet. Do this first. That gives us the ability to manage uploads from the web or from an app.

So first create a /smile/csvupload. I thought that this is was what was created when I asked for a feature to upload csv files, but turns out the "easier" solution was implement to take raw csv data and post into a session.

truedat101 commented 11 years ago

Actually, let's try to make this more restful ...

/smile/iqset/id

is the route and the thing it deals with is the inquiry set.

We'll do post using method described in : https://github.com/felixge/node-formidable (we use formidable). This helps us handle form upload. The id is the key to upload the content. I'll assume that all contents uploaded will be stored somewhere reasonable ... I'm still not sure how our existing file upload works. It goes to /tmp I think. Need to verify. As for the ID, we'll just make this the UUID of the content. This is a little funky, since we don't want the app to deal with creation of the UUIDs. So if we pass in an ID for non-existent content, then it must be a create new inquiry set. However, I don't see us using this, since we key using the pouchdb uuid. That might change in the future. Instead, I think if we post without an ID, this would also create a new iqset. If we post to an existing iqset, it would simply update the contents. A successful create/update would return the UUID or contentID of the inquiry set.

The get request of ID would return the contents.

truedat101 commented 11 years ago

One problem here is that we are going to need to store images on the server. I'm thinking that we don't want our images in the DB.

So image upload would need to organize the images according to the current silly scheme of naming the images by question #. That simplifies some things in terms of storage, but makes business of managing images annoying, meaning if we change the order of the questions in an inquiry set, we'd need to rename images as well. Image 1.jpg -> 2.jpg.

truedat101 commented 11 years ago

So, probably what we want is to have /smile/iqset/:contentid instead. The contentid will be the URL encoded title from the session as the contentid. And if for some reason, contentid is not unique, we'll just tack on _ to the end of the contentid presented. Then we can use contentid to be the directory name under /content where we store images. So any images requested by the clients will, behind the scenes, be routed from /smile/current/:id.jpg , which actually maps down to .... /smile/questionview/id.jpg , which ... totally doesn't make sense. It drives me crazy. So I think what they did was store the image in the JSON passed in a question object of the request , in the PIC attribute. It's base64 encoded data. Clever, but means we have to do something else when it comes to persisting data and loading it from disk. I don't want to store it in the database. I think we just use local storage. What that means though is that database syncing operations won't be complete until physical image assets are sent over to some remote storage somewhere else.

truedat101 commented 11 years ago

This is way to complicated an effort for something we are going to abandon after this release supposedly.

truedat101 commented 11 years ago

I'm thinking for now, just store the uploaded images on disk. We'd need to manage moving them from disk into memory when we start a session. So if we have marked a question as a QUESTION_PIC then that means we'd be committed to loading the corresponding question number , let's say, question 1, plus load /content/:contentid from disk, into memory and store it in JSON object for the question. Seems way expensive approach, esp. if we have some big images. But it's a temporary solution.

truedat101 commented 11 years ago

So the only consideration for this basic version is, we'd load all images into the designated area, and if questions were deleted, or if questions changed ordering, we'd need to update the disk accordingly. If we must change the IQSet title, we'd rename the IQSet space on disk under /content if we have any images.

truedat101 commented 11 years ago

Ok, so I'll check in the ideas, commented out. I need to fix another problem.

truedat101 commented 11 years ago

Big problem. Last round of changes I modified the route /smile/all. This is broken now.

truedat101 commented 11 years ago

When I modify route behavior, I need to probably comment it well on what it's supposed to do.

truedat101 commented 11 years ago

Ok, so I messed this up in: e927e8adb784ded9aafa1ea256c303c4280ab967

restore: -js.get('/smile/all', routes.handleAllMessagesGet);

truedat101 commented 11 years ago

Let's restore the old route for all to proper implementation ... tests were breaking for a reason idiot. And add a route /smile/session/all with the new routine.

truedat101 commented 11 years ago

Back to handling the CSV upload (for persistence). So need to flesh out the implementation and persist. Then add a route to return all of the IQSets /smile/iqsets

Implementation will take in the CSV, parse it, and then persist.

The handling of the image uploads is tricky. We should eventually allow a user to submit with a URL to an image, though this may be too abstract for some teachers. The GUI for upload submissions should allow you to submit an image for /smile/iqset/:contentid/:questionnumber?type=image

or /smile/iqset/:contentid/:questionnumber?type=question I don't know whether it really makes sense to have routes to handle edits for individual questions or just focus on resubmit of the modified question set with all changes included?
truedat101 commented 11 years ago

So the final step here is that we can take a :contentid for an iqset and pass it into /smile/session/:contentid to create a new session. The response would be: { iqset: session: }

truedat101 commented 11 years ago

One complication, our server only takes a single token in the URL route parsing. Sigh. We should have implemented this before. I don't want to mess with it right now. We'll just use parametersfor specific operations on the questionnumber .

So /smile/iqset/:id?q= ... for example

truedat101 commented 11 years ago

I think after we post a csv to /smile/iqset we should return an IQSet. The client can use this to display the new IQSet as it exists.

truedat101 commented 11 years ago

Got basic test case for parsing the CSV for IQSets. Need to add the support for image uploads, but I'll ignore this for a bit because the initial requirement is to just upload questions.

truedat101 commented 11 years ago

Add a route now to get the iqsets /smile/iqsets . I believe for this we'll just use the default data that gets returned by persistius, which is the title, the date, and the ID.

truedat101 commented 11 years ago

After I do the /smile/iqsets, then we'll do /smile/iqset/:id

truedat101 commented 11 years ago

Next thing needed is /smile/iqset/:id

truedat101 commented 11 years ago

Ok, final things needed for this minimum viable set of things we need is /smile/sessions get and /smile/session/:id

truedat101 commented 11 years ago

Commit for /smile/sessions on 2d093c8..6f542b4 HEAD -> dev

truedat101 commented 10 years ago

Ok, should be time to start on UI/UX for IQManager. I'll circle back and fix the image upload once I get the basic UI done.

These won't work with the current server routing: /smile/iqset/:contentid/:questionnumber?type=image or /smile/iqset/:contentid/:questionnumber?type=question

But this will: So /smile/iqset/:id?q= ... for example to update a question, or /smile/iqset/:id?q=<-num->&type=image

<-BODY - Image->

truedat101 commented 10 years ago

Need to port all the gui to foundation 4.

truedat101 commented 10 years ago

In moving to foundation 4, we need to upgrade our Jquery plugins to be zepto friendly or we need to use jquery.

truedat101 commented 10 years ago

Ready to build the teacher interface for IQManager . Yay!

Was thinking to use the plugmin UI, but maybe not, since that will require a Foundation 3->4 overhaul. Boo.

truedat101 commented 10 years ago

URL will be: /smile/iqmanager

truedat101 commented 10 years ago

Will make it /smile/smile-iqmanager.html.

truedat101 commented 10 years ago

Here is the latest UI snapshot. Note, we'll have a cvs upload dialog that a teacher can use.

smileplug-server-iqmanager

truedat101 commented 10 years ago

Need to implement the IQSet detail page.

truedat101 commented 10 years ago

Need to upgrade js.js to include DELETE routes.

truedat101 commented 10 years ago

Ok, go the IQSet detail working. Need to switch to Session Detail.

truedat101 commented 10 years ago

Need to wrap up work on getting session detail. If we can get this done, then the rest here will be bug fixing minor things, and maybe a bit of functionality to support SMILE Teacher to load questions. I'll defer image handling and IQSet editing until a later date.

truedat101 commented 10 years ago

One problem we have as well is the iqsets data we get back isn't what we want. We get a JSON object back for iqdata, not questions array.

truedat101 commented 10 years ago

Switch to using Question.getList() to get the questions as an ordered array.

truedat101 commented 10 years ago

We will want or need to delete earlier session data, or if we can't find an array, then don't display the array of questions.

truedat101 commented 10 years ago

Time to plug in the session summary detail page.

truedat101 commented 10 years ago

Add missing metadata to model.

truedat101 commented 10 years ago

We are missing the linkage between a session and an iqset. We should iqset ID (iqid) and iq title (iqtitle) in session metadata. If we don't have it, let's just leave these out of the model, and we'll display Unknown in the UI.

truedat101 commented 10 years ago

Also, we have a redundant variable. We already have sessionName. No need to store title in the session object.

truedat101 commented 10 years ago

Missing the students object in the SessionSummary object model.

truedat101 commented 10 years ago

The session detail page is reasonably completed now. Of course, it all needs more testing. All that is left is to plug in the work on the android side to launch sessions from existing iqsets.

truedat101 commented 10 years ago

While I'm waiting for some of the Android work to wrap up, I need to update SMILE Student web and fix the file upload to have the image disappear.

truedat101 commented 10 years ago

@chrqls I'll add the code: GET /smile/iqset/< key >

This will get you back the complete details of the inquiry set: {"ducktype":"iqsetdoc","date":"2013-11-01T05:36:10.058Z","title":"JAMsj Barracks Set 2013","teachername":"Mrs. Parker","groupname":"MLK Elementary Grade 5","iqdata":[{"NAME":"teacher","IP":"127.0.0.1","Q":"question","O1":"choice1","O2":"choice2","O3":"choice3","O4":"choice4","TYPE":"QUESTION","A":"answers"},{"NAME":"teacher","IP":"127.0.0.1","Q":"How did internees NOT solve the problem of dirt and sand blowing in through the spaces between the floorboards and walls?","O1":"They laid large tiles on the floors","O2":"They laid linoleum over floorboards","O3":"They stuffed toilet paper in the wall spaces","O4":"They laid carpeting to cover the floor spaces","TYPE":"QUESTION","A":"1"},{"NAME":"teacher","IP":"127.0.0.1","Q":"What did the WRA NOT issue for each room in the barracks?","O1":"Tables and chairs","O2":"Metal Army cots (without mattresses) and at least two Army blankets per cot","O3":"One heating stove","O4":"One electric light","TYPE":"QUESTION","A":"1"},{"NAME":"teacher","IP":"127.0.0.1","Q":"What did internees NOT DO to make their barrack rooms more livable?","O1":"Used scrap lumber to build furniture and placed drop cloths around the cots","O2":"Created paintings, craft items, and curtains to decorate the rooms","O3":"Insulated walls with sheetrock and later painted them","O4":"Added plumbing so they wouldn't have to share the bathroom with others","TYPE":"QUESTION","A":"4"}],"id":"A5EDC9ED-410C-4421-A766-4F9022FC7D38","rev":"1-8405293dd495f0704e077418a973be2f"}

truedat101 commented 10 years ago

Need to make a note about the concatenation of iqsets.