I’ve been working on some improvements and a couple of bugs since the last blog post.
I didn’t like the fact that Google was not working as a social login provider. It was raising a weird ‘Permission Denied’ exception after the user clicked the ‘Accept’ button for granting permission. Andrei Preda, my colleague from WHC project, pointed me out that I should look over the app settings in Google API Console. Indeed, the problem was that none of the available Google APIs were enabled. All I had to do was mark the Google+ API as active.
After fixing that issue, I came across an unpleasant bug. The player did not receive the initial points and gold if he used the social login feature. This was caused by the fact that the ‘user_login’ view, which handles the usual login mechanism, sent an ‘addActivity’ signal. The receiver connected to that signal was responsible for granting the points and gold. However, the ‘user_login’ view wasn’t called when using the social login, therefore, no signal was sent. I decided to remove the ‘addActivity’ signal and use Django’s built-in ‘user_logged_in’ signal, since both mechanisms were sending it after a successful login.
Another issue I came across was that the ‘magic disable’ button was not working as intended. It was merely removing the ‘cast’ button from the player’s profile page. But one could still cast spells if he went to the URL responsible for spell casting.
Finally, I have used signals and receivers to refactor two methods from god.py (post_cast and post_expire).
ROSEdu Summer of Code has come to an end. It was a great experience for me and if I were to choose I’d do it all over again. I’ve learned a lot of new useful things, including the required soft skills for working in a team project. I am highly indebted to my mentor Alex and the entire RSoC community for supporting me. Thank you!
Over the past two weeks I focused on refactoring views that were using a workaround for passing success and error messages to the next view. They were rendering the template with two additional context variables (‘message’ and ‘error’), leaving the template responsible for displaying those messages.
However, Django provides an easy way of achieving such functionality, through its django.contrib.messages module. After a quick scan of the code base I have found a function called ‘do_result’ in the challenge module, which was responsible for creating and passing those two extra variables to a certain template. Alex encouraged me to delete it and use the Django messages framework followed by a redirect to the challenges’ homepage, whenever the ‘do_result’ function was called.
While I was working at refactoring a view from the magic module which did not use the messages framework, I stumbled upon a weird issue which needs further investigation. I tried to turn some points into gold using the exchange feature. Unfortunately, after hitting the ‘exchange’ button, I ended up with a negative amount of gold.
I have also improved the social login feature by making it pluggable. It is as easy as setting SOCIAL_AUTH_ENABLED to ‘True’ or ‘False in settings.py to activate or deactivate social login. The tricky part was that I didn’t know how I could access a variable from settings.py in the templates. The solution was configuring an existent context processor to pass the needed value to the templates.
Don’t forget to check out this blog for more posts about this project!
I’m back to work, after a seaside vacation.
My current task is to make possible for the user to login through various social networks, such as Facebook, Twitter, Google. This is quite important because we might run World of USO in another context and users would be more likely to try our game if they had the possibility to login with an existing social account.
I started reading about the OAuth protocol and how the login mechanism works. I learned that you have to follow a bunch of steps before you are granted permission to access the user’s data. First, you register your app with the desired social network to get a unique ID. After that you make a GET request to their servers with some parameters (app_id, redirect_uri). They give you back a code (if the user authorizes your app) which you are going to exchange for an access token. Eventually, you use that access token to get the data you need using their API.
I was able to implement that routine myself for Facebook, after reading their documentation. But there are some pitfalls regarding user creation. Therefore, Alex and I decided to use a tested and well-known mechanism among Django users. It is called django-social-auth and it does exactly what we need.
I managed to integrate django-social-auth with World of USO. Now users are able to log in with Facebook and Twitter. It raised a weird exception when trying to authenticate with Google but I think it can be fixed. I am now waiting for Alex’s review and further instructions.
The thing I enjoyed most about working on the social login was that I got to talk with the man who wrote django-social-auth. I was confused about how the mechanism was authenticating its users, so I decided to send a mail to its creator. He responded very fast and was patient with me. That’s why I love the open source community!
Below is a screenshot with the newly added feature.
This week I managed to refactor the views from the interface module. This module contains a lot of form processing views and I thought it will be a burden to refactor them. Thankfully, I found out that Django already had the perfect tools for dealing with forms, the generic class based views FormView, CreateView and UpdateView.
Those classes rely on the Python’s object orientation and multiple inheritance. Therefore, the documentation for them is spread across multiple files and it takes a long time to decipher. You have to go to several other pages to find what attributes and methods each class inherits. Fortunately, I read on Stackoverflow about a very useful site, which does exactly what I needed. It lists all the methods and attributes of each generic class, along with their source code.
The only thing that I’m not sure about this refactor is whether two views (edit_spell and add_spell) handle image upload correctly. I couldn’t make them work because of a glitch with my WoUSO development environment. I think I have an issue with Python Imaging Library.
I had a problem with moving a form from the view to forms.py file. The form was defined inside the view. Consequently, it was generating its fields dynamically when the view got called. When I moved it to another file, it wasn’t generating the correct number of fields anymore. Eventually the solution was overriding the default constructor for that form.
Another interesting thing that I learned during this week was that Python’s super() method is very powerful. It delegates method calls not only to a parent class, but also to a sibling class.
Now it’s time for a short vacation, I will be in Costinești the following week. I’ll keep you posted as soon as I get back to work.
Over the past two weeks I’ve been working on the first objective of the project (refactoring views from games module). Last night I was able to accomplish it and I also started working on the second milestone, which consists of refactoring views from the interface module.
I gained some experience with class-based views and I can proudly say that I’m pretty confident using ListView, DetailView and View. The thing I like most at the Django project is that it’s very well documented. Therefore, I was able to find the method flowchart for each of those classes. It’s very important to know which method gets called and when.
Yesterday I stumbled upon a tricky view. After refactoring it, some features stopped working, such as displaying a message after a spell is bought. It crossed my mind to ask for help on the #django freenode channel. I was surprised that a bunch of people were willing to share their knowledge with me. They gave me some valuable suggestions. Eventually, I managed to fix the message displaying issue with django messages framework. They did exactly what I needed: store a message and pass it to the next view.
Another problem was paginating the view’s results. It had a back end implementation for it, but it lacked the front end part. I created a template for paginating those results and I rewrote the back end using the much simpler class-based view. It was as easy as assigning a number to the the class’ attribute paginate_by.
See you next post!
My name is Nicu Badescu and I am working on refactoring WoUSO’s code base, under the supervision of my mentor, Alex Eftimie. World of USO is an educational game well-known among the students which aims to improve their general knowledge about computers.
My goal is to replace some of the old function-based views with the newer, more versatile class-based views. I also have to move the logic which is tied to the model from the views.
Two weeks have passed since I began working on the project and I enjoy it so far. During the first week I went to Bucharest to celebrate the beginning of RSoC and talk to Alex, in order to get some important tips on how I should get started. I read about testing Django applications and managed to add unit tests to a feature I had previously implemented. After that, I skimmed through the code base and marked the chunks of code which are in need of refactoring.
I have set a couple of milestones with Alex and I am currently working on completing the first one, which consists of refactoring views from the games module. The basic work flow is as follows: write a test for a specific view, refactor that view, check if the test passes.
I am confident that I am going to learn a lot of useful things this summer. I’ll keep you posted!