Saturday, June 25, 2011

GSoC 2011 Melange Testing Project: CP W5

Hi,

This was quite a busy week. Learned a lot and worked a lot. I worked on writing the tests for soc.logic.tags and soc.logic.models.base. I had attempted to test soc.logic.tags during the pre-GSoC era but failed because I did not understand properly what 'scope' and 'fields' parameters were. I asked Madhu what a 'scope' is and he explained it to me that it was a solution adapted by Melange during the early days of development to define a relation such as a GSoC project belongs to a Student. So, a GSoC project entity was scoped under a Student profile. But, as the developers understood more about the Transactionality and other stuff in GAE, they switched to using 'parent' argument of an entity to define the scope. But, scoping will stay for tagging.

   Earlier during the week, after Leo reviewed my patch for soc.logic.accounts, I pushed the code without first updating my local repo. So, I first pushed the patch and then pulled. But, then I could not find the test I had written in the online repository. So, I pushed it again and as a result to this, I ended up creating two heads in the repository. Sverre asked me to take care of the extra head I had created. I did not know how to do that. So, I googled and asked some friends. Some suggested using the 'strip' extension, 'merge' and some 'mercurial queues'.
Ultimately, I asked Madhu how to revert what I had done. He looked at the case and asked me if I do not rebase my patches after pulling. rebase!!!???What is it??. I then asked him what rebase here refers to. He gave a very nice tutorial on the concepts behind rebasing and the two schools of thought which I will never forget, the 'Purists' and the 'Whatever-ists'. :). I like Madhu's way of explaining things. Things get so easily printed in the mind.

   What I learnt about the 'parent' argument from the discussion with Madhu, helped me to extend the old tests for soc.logic.models.base authored by Sverre and Leo. The tests reported errors when I ran because it could not find test_model module which I also thought does not exists and may be it has been removed. So, I defined my own dummy class TestModel extended from soc.models.base.modelWithAttributes, added some more tests to the module and submitted them for review. After this, when I was looking for other module to test, I saw that there was a test_model in old_app.soc.logic.models and this was the reason why it gave ImportError. So, lets see what Leo says :).

 I now plan to re-use the old tests which Leo had written last year. The goal of my project has been re-scoped to write the unit tests until mid-term evaluations. I had written in my proposal that I will start writing functional tests in June. But, there are modules which have to be unit tested before. So, the target until mid-terms is to add as much unit tests as I can.


Monday, June 20, 2011

GCI 2011 GCI with New Architecture

Hi all !

This week I have committed the GCIProfile and GCIStudentInfo models.And currently I'm working on the script to convert GCIStudent data to GCIStudentInfo and as I had some troubling understanding certain things I spent a couple of days in going through the Oreilly - Programming Google Apps Engine book.I've spoken to my mentors sometime back and got a better idea as to what to do.Instead of querying for the profile that each student entity points while creating the GCIStudentInfo entity, it can be created when the Profile for each entity is created,the parent-child relationship can be obtained easily like this.Besides this I have also written a basic RequestData object that will be created for each request in GCI and will add more properties and fields as we go ahead in the project.The patch is under review along with the script to convert roles and update references in the models.This week I haven't worked upto the mark.I will finish the conversion works and start with views at the earliest this week.

GSoC 2011 Integration with External APIs: OAuth Demo - Week 4

This week i'm finishing Open Auth integration and will start to work on proposal syncing with Google Documents next week.

A demo view that uses Google Docs Service is available here. I made a few modifications for OAuth workflow diagram that you can see here.


After login process is complete, Google documents of user are listed.
Currently, tokens are stored by memcache. Access tokens are long-lived. So i marked a TODO to store access tokens in datastore (with Sverre's suggestion). Memcache is not a convenient way to store  a token for such a long period. After talking to Mario (my mentor), we decided to put a 'remember me' checkbox with login button, so when user logs out access token will be preserved for next login ( that  is also current behaviour). These are changes that i can work asynchronously while i work on proposal syncing feature.

Proposal syncing feature is the first deliverable of my project. There are few potential problems awaiting:
  • Integrating a full-html document which also has seperate image, css files. 
  • To sync proposal without user signs to site, a task must be implemented to sync proposals when user is offline.

GSoC 2011 Melange Testing Project : CP W4

Hi!
I had submitted two patches last week: one for test of app.soc.logic.dicts and the other for app.soc.logic.accounts. There were lot of mistakes and issues pointed out in the review. I have corrected soc.logic.accounts and submitted it again for review today. I also missed some functions to test in soc.logic.dicts and will do it this week.
  I wrote the test for app.soc.logic.system this week and I had a long discussion with Madhu whether to use DjangoTestCase or unittest.DjangoTestCase. Madhu suggested using the DjangoTestCase and I insisted that I could test the functions with the help of unittest.TestCase itself. I had to test the soc.logic.system.getHostname(data=None) function and for this I needed a data object which had a 'site.hostname' attribute. After some grepping and exploration, I came to the conclusion that it should be a soc.views.helper.request_data.RequestData() object and the 'site' should be a soc.models.site.Site() entity which Sverre told me. But then I had a problem in instantiating the Site entity and the traceback reported that a link_id property is missing. So, after struggling for some time I told Madhu the problem and he referred me to test_utils.DjangoTestCase which had a site and data attribute which he said I use in my tests. He also said that RequestData entity should be populated and seeded to efficiently test it. My point was that all the entities of RequestData object are set to either False or None and also I do not need all of its attributes in testing. I only need the data.site and data.site.hostname attributes and this I could accomplish without using the DjangoTestCase and directly handling the RequestData and Site objects. Finally he asked me to go ahead and write the test with unittest.TestCase.
    85% of my time is spent on reading codes and there are multiple windows that remain open almost all the time. I have to hibernate my system to avoid opening so many windows again.
   I did not do much coding this week but hope to do more this week. Me and a friend of mine are planning to participate in ACM-ICPC regionals this year. So, we spent most of the time in studying for ICPC only.

Friday, June 17, 2011

GSoC 2011 GUI Overhaul: Redesigned Admin Dashboard

Hi everyone,

As I promised from last post, I'll talk about redesigned admin dashboard in this post. Currently, admin dashboard is just a page with list, without any information, to other pages. I've provided mockup for admin dashboard with iconic information. There will be also new functionalities such as manage organizations with another sub functionalities to manage org, proposal, mentors, and students, participant locations, etc. There are two approaches to render child page in admin dashboard. These approaches is discussed in the following section :

Admin Dashboard with AHAH for Child Page

From last conference, Sverre told that Carol needs page in scope of admin should be stay on same page with parent page, that's admin dashboard. He said, it could be achieved with AJAX request/response. I tried the AJAX approach by making a div container to hold the HTML response. It's better to call this AHAH rather than AJAX. So, this div container is a hidden one and will be displayed after the HTML response injected to the container. The container was placed below the iconic information. To make the request handled with a minimum HTML responded, I created another blank template, base_ahah.html which contains following code :

{% block main_content %}
{% if ds_write_disabled %}
<div id=user-message class=error>
<strong>ALERT: </strong>Google Appengine datastore write
capability has been disabled at the moment. You will
<strong>NOT</strong> be able to save your changes at this
time. We are sorry for the inconvenience caused. Please visit
<a href=http://code.google.com/status/appengine>
http://code.google.com/status/appengine</a> to check
Appengine datastore status.
</div>
{% endif %}
{% block page_content %}
{{ tmpl.render }}
{% endblock page_content %}
{% endblock main_content %}

Page requested via AHAH must extends this template. We also need to modify form_base.html to check whether it was requested via AHAH or regular request with full base layout. If a page requested via AHAH, the JS code will add another query string, ?ahah=1. In the AHAH base template, we don't request any CSS or JS asset. I don't know if there's a way for LABjs loads once for the same script, and skip injecting the head for subsequent script calls. To be safe, any assets should be provided first when admin dashboard page requested. The form submission should be changed with AJAX. This was easily done with jQuery.post function. Any response, either invalid or valid, will be injected again in the AHAH container. With this approach, any admin sub page that need to be added later must exclude the asset its needed to parent page, admin dashboard. This make any sub page coupled to its parent page, which is not good.

Admin Dashboard with Iframed Colorbox for Child Page

Colorbox is yet another thickbox-like jQuery plugin. Colorbox provides a way to hold the content of external page in iframed container. For iframed template we need to create another base layout again, say base_colorbox, with minimum markup and variabel template. In iframed container we could extend block stylesheet and add melange script dependencies. Here's what admin dashboard with colorbox looked alike :


Within iframe, we need to specify the width and height for colorbox. We can specify the width and height in URL query string. Colorbox approach seems the easy way to implement without coupling to the parent page.

In the next day I'll provide the live instance to experiment with the new dashboard, so stay tunned.

Tuesday, June 14, 2011

GSoC 2011 Integration with External APIs: OAuth Roundtrip - Week 3

I've been developing generic methods to handle OAuth. When developing software it's important to create meaningful abstractions so a method can refer to these abstractions without need to understand low-level details what they do. For the OAuth part of my project a helper module handles this low-level details and caller that refers to these abstractions is an access_checker. It asks following questions:

  • Get access token for user.
  • Create a service for user.
  • Generate a OAuth authorization URL.
  • Process URL for OAuth verifications.
Low-level helper module does following operations for questions above:

Get access token for user:
  • Generate a unique key consists of user's key and current host (different consumer key,secret so different services and access tokens are used for each hosts). 
  • Ask memcache or a storage mechanism to fetch token corresponding to that key.
  • Return token.
  • If there isn't a token return None.
Create a service for user:
Service is a GDocsService object that is used to make API calls.
  • Create a service for the current host. 
  • Set service's input parematers to host's consumer_key and consumer_secret. 
  • Set encryption method to sha or rsa.
  • Return service.
Generate a OAuth authorization URL:
  • Fetch a request token. 
  • Save request token's secret to memcache for later use (when validating token).
  • Generate a authorization URL from request token.
  • Return URL.
Process URL for OAuth verifications:
  • If request URL contains a verification key as GET parameter, parse it.
  • Verify previously stored access token with parsed verification key.
  • Store verified access token to memcache or datastore.

Monday, June 13, 2011

GSoC 2011 GUI Overhaul: Toggleable List

Hi everyone,

Today I'll talk about toggleable list for regular dashboard. To make you clear, there are two dashboards in Melange, one is regular dashboard and the other one is admin dashboard. The regular dashboard is the page that we see if we clicking the "My Dashboard" link on the left sidebar menu, or if you visit the url at gsoc/dashboard/(host)/(program_name). The admin dashboard is available in the left sidebar menu as "Admin Dashboard" if you have a role as a host. If you're login with account that listed as an administrator of melange instance, you have access to that admin dashboard. Admin dashboard can be visited at gsoc/admin/(host)/(program_name)

Currently, regular dashboard is loading a bunch of list at one time. Each list, or called component in dashboard view, in regular dashboard is fetching a lot of entities from datastore in the background. Each role gets different components. If someone has a role both as a host and a mentor, Carol's case, then she gets much components. Too much component will reduce usability. User needs to scroll hardly if she/he looks for component at the bottom. Fetching all list at one time is inefficient too. I've provided three ideas with mockups to handle this problem, one is with tab, two is with iconic page (the same as admin dashboard that I'll talk in the next post) and the last is with toggleable button. Carol agreed with toggleable button. The reason for toggleable button is user can toggle which list/component she/he wants to show without leaving the dashboard page.


I've provided the patch to melange-soc-dev. The implementation is quite simple. To make a component toggleable we just set toggleable and collapse to True inside the context. The list template will check this variable. If we ignore toggleable and collapse then the list will be requested when loading the page. We can set a component toggleable but doesn't collapse at first load by set the toggleable to True and collapse to False. With this approach, other pages with list, such as accepted_orgs, wouldn't be affected. In the next post I'll talk about admin dashboard that being redesigned right now.