Using TabLayouts in your Android app

So while making a sessions schedule for the open event app, I wanted to separate the sessions on the basis of the days they are scheduled for to improve the visual clarity. So to do this I had various approaches like add a filter to separate by date or add checkboxes to show only checked dates but I though they’d look ugly. Instead the best option was to add tabs in a fragment with a viewpager to scroll within them : It looks appealing, has simple and clean UI, easier to implement with the new design library. So, naturally I opted for using the Tablayout from the design Library.

Earlier, when the Support design library was not introduce, it was really a tedious job to add it to our app since we had to extend Listeners to check for tab changes and we had to manually open fragments when a tab was selected or unselected or even when it was reselected. Essentially this meant a lot of errors and memory leaks. In the design library we essentially need to add tablayout and a viewpager to our layout like this :

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white" />

</android.support.design.widget.AppBarLayout>

Next in our activity/ fragment, we can just inflate this view and create an adapter for the viewpager extending a FragmentPagerAdapter:

public class OurAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ScheduleViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title, int day) {

        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

Now I had to make dynamic number of tabs, since I wanted the app to customisable on the number of days listed in the json downloaded from the server. So, I made some changes in the traditional code. This is what we do in our activity/fragment’s onCreate/OnCreatView :

viewPager = (ViewPager) view.findViewById(R.id.viewpager);

for (int i = 0; i < daysofEvent; i++) {
    adapter.addFragment(new DayScheduleFragment(),title, dayNo);
}

viewPager.setAdapter(adapter);
scheduleTabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
scheduleTabLayout.setupWithViewPager(viewPager);

This is it. Now we have a basic working tablayout in a viewpager. This also has the capability to change according to the number of days specified in the json we have written.

Earlier without the design library, we would have to even add switch cases in the FragmentPagerAdapter like this :

public class OurAdapter extends FragmentPagerAdapter {
 
 public TabsPagerAdapter(FragmentManager fm) {
    super(fm);
 }
 
 @Override
 public Fragment getItem(int index) {
 
 switch (index) {
 case 0:
    return new FirstFragment();
 case 1:
    return new SecondFragment();
 case 2:
    return new ThirdFragment();
 }
 
 return null;
 }

Then we would have to override methods to listen to activities in tabs :

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
   viewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}

And more code to listen for swiping within tabs in a viewpager:

/**
* on swiping the viewpager make respective tab selected
**/
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
public void onPageSelected(int position) {

// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}

@Override
public void onPageScrollStateChanged(int arg0) {
}
});

You see how easy this got with the inclusion of TabLayout.

Now for the final product I made after inflating the fragments and adding recyclerviews for the schedule, I got this :

Swipable tabs

I urge you to try swipable tabs in your app as well. Adios till next time.

Continue ReadingUsing TabLayouts in your Android app

Open-Event Permissions System and integrating it with decorators

All the large scale applications require a permissions system. Thus we also implemented a permissions system in our open-event organization server. It consists of certain pre-decided roles:

  1. Super-Admin
  2. Admin
  3. Organizer
  4. Co organizer
  5. Track organizer
  6. Anonymous user

Now we had to decide the permissions which each role would have. Hence we created a documentation regarding what URLs can be accessed by each role. We developed a list of services which the roles could use their permissions to access:

  1. Tracks
  2. Microlocations
  3. Speakers
  4. Sessions
  5. Sponsors

Thus the final step was to implement the permissions system to the appropriate views or URLs. Here comes the power of Flask decorators . I created a individual decorators @is_organizer, @is_admin, @is_super_admin etc… to check the respective roles. I created one main decorator @can_access to see whether the role can access the particular URL or view function

decorator

So in the above decorator I have simply take in the url and check whether it has ‘create’, ‘edit’ or ‘delete’ words in it. Depending on that the control goes in the particular IF statement. Now once it is decided what operation is being performed it checks what service is being accessed by the user. For example: if the operation is edit then it will check whether the service being edited is an event, session, sponsor etc…

Similar checks are performed by each operation. A check is performed of the request.url to see whether the string for that service is present in it. After it knows what service is being accessed its just a matter of using the CRUD functions of user table to check if the role accessing the resource has the requested permission using the functions:

  1. user.can_create()
  2. user.can_read()
  3. user.can_update()
  4. user.can_delete()

After this its just a matter of adding the decorator to each of the view functions and the system is implemented.  🙂

Continue ReadingOpen-Event Permissions System and integrating it with decorators

Testing with Jasmine-Node

This week I have started testing my own code with Jasmine-Node. Testing seems beneficial only when we do it with a right approach. I have gone through various articles and find out Jasmine as one of the best frameworks for testing Javascript applications.

For specifically NodeJS, a better option will be to use Jasmine-Node.

How to start with Jasmine-Node ?

For a quick-start, you need to have Jasmine-Node installed with npm.

npm install jasmine-node -g

After the installation, make a folder say spec/ in the root directory of the project. This will contain all the tests for the node app.

We can include the command  to run the tests in package.json file of the project.

./node_modules/.bin/jasmine-node spec

 

script

Like here it is included with the key tester. Now, we are ready to write our first test file.

So, in the Open-event-webapp spec/ folder I have created a file serverSpec.js. The file will test a basic function written in fold.js which is the file that includes all the functions of Open-event-webapp.

//fold.js

'use strict';


var exports = module.exports = {};

const fs = require('fs-extra');
const moment = require('moment');
const handlebars = require('handlebars');
const async = require('async');
const archiver = require('archiver');

//function to test

function speakerNameWithOrg(speaker) {
 return speaker.organisation ?
 `${speaker.name} (${speaker.organisation})` :
 speaker.name;
}

To test the above function, I have written the test like this

//serverSpec.js

'use strict'

const request = require("request");
const fold = require(__dirname +'/../src/generator/backend/fold.js');
const port = process.env.PORT || 5000;
const base_url = "http://localhost:"+ port +"/"

describe("Open Event Server", function() {
  describe("GET /", function() {
    it("returns status code 200", function(done) {
      request.get(base_url, function(error, response, body) {
      expect(response.statusCode).toBe(200);
      done();
    });
   });
 }); 
}); 

describe("Testing Fold.js",function() {
  describe("Testing SpeakerWithOrg function",function(){
    it("it will test speakername", function(){
       let speaker= {
          name: "speakername",
        }
    expect(fold.speakerNameWithOrg(speaker)).toEqual("speakername");
   });

    it("it will test speakername and organisation", function(){
       let speakerWithOrg= {
          name:"speakername",
          organisation:"Organisation",
        }
       expect(fold.speakerNameWithOrg(speakerWithOrg)).toEqual("speakername (Organisation)");
    });
 });
 
 });

There are two describe blocks here one to test if the server is running properly and the second block includes two ‘it’ statements which are used to test the function behavior.

The describe blocks are nested which is a nice feature provided by Node-Jasmine.

To run the above test in Open-event-webapp , use the command:

1. npm run start
2. npm run tester

On success, The output will be something like this

test

Other Sources

  1. Jasmine Presentation
  2. HTML goodies

 

 

Continue ReadingTesting with Jasmine-Node

How do we work? Agile

It’s not typical team. We don’t meet face-to-face each other on daily basis, one trouble is that we have to work from different time zones, and we have different operating system, the way of working, or even culture. But we are FOSSASIA Open Event team of six amazing developers so it does not discourage us to achieve our goals.

But even if we experience all these things we have to learn how to work together successfully. We are trying, and I think it is becoming better and better every day, the Agile methodology.

So first of all, before coding started, we had prepared user stories in issues. Every issue had been very well documented, and we had divided each issue to smaller ones. It brings us a lot of benefits, because it doesn’t matter where you work. If sub issue is empty you can take it. Due to the fact that issue is very well documented you don’t need to even ask someone what to do. This case saves a lot of time. I know that writing clear issues is very boring and It could seemed not to be beneficial, but it’s. We are still trying to improve our performance and we are looking for new opportunities where and how we can improve our work, without lost quality of our development process.

Then, we have one week sprint (milestones). It helps us to control our work and we know where are we, what have we done, and what is still to do. We know if our speed is enough or we have to move faster. And it also enables us to see our progress.Screen Shot 2016-06-25 at 11.27.08.png

Moreover, we have daily scrums. We answer three following questions – what did you do yesterday, what do you plan to do today and what is preventing you from achieving your goals. Furthermore, we follow continues integration system. We push code to our common Open Event repository on daily basis. It helps us to control our code and fix bugs quickly. I am sure we will continue along this path, and successfully finish to code an amazing Open Event web app.

Continue ReadingHow do we work? Agile

AngularJS makes coding CommonsNet easy

Wizard form

Have you seen a wizard form? I am sure you have.  I think the usage of it is very common these days. I like it very much, too. I think its structure is extremely user-friendly, because it can help us to avoid discouraging users from filling the form with all data. As a user I don’t want to be pushed to fill long forms. It’s annoying. But while you use the wizard no matter how long the form is, firstly you can quickly see the progress of you work and then,  don’t see it at once, just fill one field at a time.

That’s the result why have I decided to use it in CommonsNet project, too.

CommonsNet wizard

Angular JS

To implement this on CommonsNet website I have decided to use AngularJS which makes it easy.

I have used Model View Controller which  is a software design pattern for developing web applications. A Model View Controller pattern is made up of the following three parts

Model − It is the lowest level of the pattern responsible for maintaining data

View − It is responsible for displaying all or a portion of the data to the user

Controller − It is a software Code that controls the interactions between the Model and View.

This model helps us to isolate the application logic from the user interface layer and supports separation of concerns.

The ng-controller directive defines the application controller. A controller is a JavaScript Object

Steps to create AngularJS app

1. Load AngularJS on your webiste.

 src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">

2. Define AngularJS app using ng-app.

<body ng-app = "app">
   ...
</body>

3. Then I have created views – five different html files for each wizard step. Please take a look at partials folder where you can find them. partials.png

4. Next, I have created a .Controller –  WizardController in AngularJS.

var WizardController = app.controller("WizardController", function ($scope) {
// controller logic goes here
}
);
wizard controller.png


 

It is a JavaScript function. I have defined which  view has to be displayed by .controller on each step. As you can see it’s quite easy and clear. You can quickly define and see which step is it , how is its name and which template should be used. It definitely enables you to maintain your app easier, because changes can be made quickly and does not influence on other part of code so you can take control over your code.

5. Then I have used  this line of code to call to my WizardController to display and maintain my views and that’s it.  See the progress on CommonsNet

<div id="wizard-container" ng-controller="WizardController as vm">
Continue ReadingAngularJS makes coding CommonsNet easy

Organizer Server Permissions System

This post discusses about the Organizer Server Permissions System and how it has been implemented using database models.

The Organizer Server Permissions System includes Roles, and Services that these roles can access. Roles can broadly be classified into Event-specific Roles and System-wide Roles.

System-Wide Roles

System-wide roles can be considered a part of the staff maintaining the platform. We define two such roles: Admin and Super Admin. The Super Admin is the highest level user with permissions to access system logs, manage event-specific roles, etc.

System-wide roles are the easiest to implement. Since they’re directly related to a user we can add them as class variables in the User models.

class User(db.Model):
    # other stuff

    is_admin = db.Column(db.Boolean, default=False)
    is_super_admin = db.Column(db.Boolean, default=False)

    @property
    def is_staff(self):
        return self.is_admin or self.is_super_admin

Staff groups Admin and Super Admin roles. So to check if a user is a part of the staff (an admin or a super admin), the is_staff property can directly be used.

user.is_staff

Event-Specific Roles

An Event itself can contain many entities like Tracks, Sponsors, Sessions, etc. Our goal was to define permissions for Roles to access these entities. We grouped these entities and put them under “Services”. Services are nothing but database models associated with an event, that need to have restricted access for the Roles.

We define the following Services for an Event:

  • Track
  • Session
  • Speaker
  • Sponsor
  • Microlocation

Each of these services can either be created, read, updated or deleted. And depending on the Role a user has been assigned for a particular event, he or she can perform such operations.

There are four Event-Specific Roles:

  • Organizer
  • Co-organizer
  • Track Organizer
  • Moderator

As soon as the user creates an event, he is assigned the role of an Organizer, giving him access to all the services for that event. An Organizer can perform any operation on any of the services. A Co-organizer also has access to all the services but can only update them. A Track Organizer can just read and update already created Tracks. The Moderator can only read Tracks.

Although the initial distribution of permissions is kept as above, the Super Admin can (has permissions to) edit them later.

Screenshot from 2016-06-24 02:41:47

To implement permissions for Event specific roles, three new database models were required: Role, Service and Permission.

Role and Service would contain the above mentioned Roles and Services respectively. Permission would contain a Role column, a Service column and four other columns specifying what operation (create/read/update/delete) that Role is allowed to perform on the Service.

The final objective was to define these methods for the User class:

user.can_create(service, event_id)
user.can_read(service, event_id)
user.can_update(service, event_id)
user.can_delete(service, event_id)

Before this we needed a table specifying what Event Roles have been created for an event, and which users have been assigned these roles. The `UsersEventsRoles` model maintained this relationship.

We also needed to check if a user has been assigned a particular role for an event. For this I created a method for each of the roles.

# Event-specific Roles
ORGANIZER = 'organizer'
COORGANIZER = 'coorganizer'
TRACK_ORGANIZER = 'track_organizer'
MODERATOR = 'moderator'

class User(db.Model):
    # other stuff

    def _is_role(self, role_name, event_id):
        role = Role.query.filter_by(name=role_name).first()
        uer = UsersEventsRoles.query.filter_by(user=self,
                                               event_id=event_id,
                                               role=role).first()
        if not uer:
            return False
        else:
            return True

    def is_organizer(self, event_id):
        return self._is_role(ORGANIZER, event_id)

    def is_coorganizer(self, event_id):
        return self._is_role(COORGANIZER, event_id)

    def is_track_organizer(self, event_id):
        return self._is_role(TRACK_ORGANIZER, event_id)

    def is_moderator(self, event_id):
        return self._is_role(MODERATOR, event_id)

Here _is_role helps reduce code redundancy.

Like I said, our final objective was to create methods that determine if a user has permission to perform a particular operation on a service based on the role, I defined the following methods:

    # ...`User` class

    def _has_perm(self, operation, service_class, event_id):
        # Operation names and their corresponding permission in `Permissions`
        operations = {
            'create': 'can_create',
            'read': 'can_read',
            'update': 'can_update',
            'delete': 'can_delete',
        }
        if operation not in operations.keys():
            raise ValueError('No such operation defined')

        try:
            service_name = service_class.get_service_name()
        except AttributeError:
            # If `service_class` does not have `get_service_name()`
            return False

        service = Service.query.filter_by(name=service_name).first()

        uer_querylist = UsersEventsRoles.query.filter_by(user=self,
                                                         event_id=event_id)
        for uer in uer_querylist:
            role = uer.role
            perm = Permission.query.filter_by(role=role,
                                              service=service).first()
            if getattr(perm, operations[operation]):
                return True

        return False

    def can_create(self, service_class, event_id):
        return self._has_perm('create', service_class, event_id)

    def can_read(self, service_class, event_id):
        return self._has_perm('read', service_class, event_id)

    def can_update(self, service_class, event_id):
        return self._has_perm('update', service_class, event_id)

    def can_delete(self, service_class, event_id):
        return self._has_perm('delete', service_class, event_id)

The can_create, can_read, etc. defined in operations are the four columns in the Permission db model. Like _is_role, _has_perm method helps implementing the DRY philosophy.

Continue ReadingOrganizer Server Permissions System

Responsive UI: Modifying Designs with Device Width

An important feature of websites these days with the advancement of smartphones is being responsive with device size. We nowadays not only worry about the various width of laptop or desktop, which don’t vary by a huge amount but also need to worry about tablets and phones which have a much lesser width. The website’s UI should not break and should be as easy to use on phones as it is on desktops/laptops. Using frameworks like bootstraps, Semantic-UI solves this problem to a large extent. But what if we need to modify certain parts by our own in case of mobile devices? How do we do that?

Continue ReadingResponsive UI: Modifying Designs with Device Width

Knitting Pattern Conversion

conversion_273cdef7c-3747-11e6-8ece-a573d396521917-diag

We can convert knitting patterns to svg (middle) which proves the concept but is still a different from the original (right)

Our goal is to create a knit-work exchange format. This includes the conversion to a scematic view of the knittting pattern as svg – to make it endlessly scalable and allow conversions to png, pdf and paper.

This week we ended the prototype of the SVG conversion. The positions are a bit off and instructions are placed above eachother. Most of the work is done.

We are also able to load and save knitting patterns a png files.

(1)a34e6d2c-372d-11e6-9bbd-71c846ead7f9 (2)f6a6bf82-372e-11e6-9467-8bab0e07c099

(3)39e5a556-380b-11e6-8999-726fea9b6078

We loaded them (1), converted them to a knitting pattern and then saved them again as png (2). This way we path our way towards using the ayab software and actually knitting the pattern. Also we can convert the knitting pattern to an svg consisting all of knit instructions (3). Here is the code for it in version 0.0.8.

>>> import knittingpattern
>>> from knittingpattern.convert.image_to_knittingpattern import *
>>> convert_image_to_knitting_pattern.path("head-band.png").temporary_path(".json")
"head-band.json"
>>> k = knittingpattern.load_from_path("head-band.json")
>>> k.to_svg(10).temporary_path(".svg")
"head-band.svg"

Here you can see a proof of concept video:

 

Continue ReadingKnitting Pattern Conversion

Writing vim scripts to open files in the steam structure

My objective was to write a script that will allow the user to open new files from inside the vim interface. There is a vim command available for normal files. However here I am not talking about normal files, these are files inside the steam structures, that is , inside rooms and containers. The commands that were doing this currently were edit.pike and the edit command from the steam-shell.

Issue opened: https://github.com/societyserver/sTeam/issues/53

As I started working on it one of the issue I faced was that I could not use the code in edit.pike or the edit command in steam-shell because for that I would have had to start a new process and the vim window would have come up as an another new process. Due to these process using the same terminal window there would be an overlap and vim will not be able to function, this was one of the problems with the original implementation of the edit command, which I had solved in the first week of GsoC.

Issue with edit command: https://github.com/societyserver/sTeam/issues/34
Solution: https://github.com/societyserver/sTeam/pull/36

My colleague Ajinkya Wavare had finished his task wherein we could execute pike code from a vim terminal. For this he had modified steam-shell and was passing the pike code as an argument to the call of steam-shell. One advantage of executing pike code this way is that all the steam objects and variables are available to use with the pike code. Basically it is like executing code on debug.pike. I based my solution to the problem on this newly added feature. I was able to pass in pike code to steam-shell, this would start a new process, execute the code and return me the output.

The tasks that I needed to do with the pike code was:

  • Find the required object in the steam server.
  • Get the content of the object.
  • Save the content in a temporary file.
  • Once the file is saved by vim, update the file on the sever and the logs in the vim buffer.

I created a new steam command ‘Open’ and passed the full path of the object as an argument. Given the full path it was easy to find the object on the sever. I was able to fetch the contents and save it in a file. Now I had a big problem. The name of the temporary file was available in the pike script, I needed this name in the vim script to open the file in a new tab. I spend more than a day trying to come up with a solution for this problem. I was able to get the name of the file in the output of the pike script and this output could be read into a vim buffer. However this output had a lot of other content including the result of execution of other pike statements also. I had to use vim search and select tools to get the file name isolated and stored in a vim script variable. Once I achieved this my task was almost done. I used vim command to open this file and the log in a new vim tab.

Result of execution of pike script containing the file name.
Result of execution of pike script containing the file name.

The next step was to get this file to be uploaded to the server and the logs updated. Ideally when a file is opened from the steam-shell using the edit command, there is a piece of code that gets called every one second and performs this tasks, however this couldn’t be used when the file is opened from inside vim as the steam-shell process that gets the file closes before the file is opened in vim. So I couldn’t have a pike script constantly watching the file. The solution I came up with was using auto commands to execute a pike script when the file is saved and update the file on the server and also the logs. This completed my task.

opening from vim
File being opened from inside vim.

 

file opened from vim
File opened in new tab.

Since I had a day left in the week I took up one more small task. This was due to a problem that arose due to my previous task that is letting users open multiple files for editing. There were too many vim buffers open at a time and it was a trouble closing them as :q used to be executed for each buffer. Therefore I made a used defined command in vim, :Q, that was able to close tabs at a time. :tabclose is a vim command that does the same thing however it cannot close the last tab, this shortcoming was overcome with :Q.

Issue: https://github.com/societyserver/sTeam/issues/62

solution: https://github.com/societyserver/sTeam/pull/65

Continue ReadingWriting vim scripts to open files in the steam structure

LearnJS

week4gsoc1

LearnJs is an attempt to portray the best parts of Javasript that are pretty tough and hard to find. It is to be noted that this is not a book/guide in any form, but a congregation of best practices, language constructs, and other simple yet effective snippets that gives us an essence of how we can harness the best out of the language.

So what are all covered in the cheatsheet ?

  • Intro
  • Arrays
  • Strings
  • Objects
  • Functions
  • Conventions
  • Closures
  • Currying
  • Tail Calls

Intro : Declarations

week4gsoc2

We have to understand the fact that in Javascript everything is an object, so for suppose if we declare a string using the String object and compare it with var a = “” then the outcome of the comparision would be false. This is simply because if we declare a string using the bad way and compare it with a string declared using the good way then fundamentally we are comparing a string with an Object(String).
Intro : Semicolons

week4gsoc3

Code Snippet one and two are the same. but the fundamental difference between both the code samples is that one uses semicolons in the lang- -uage semantics but whereas the other doesnot. Basically we are taught to use semicolons in languages such as C, C++, Java etc since lines of code are terminated using ‘;’ but in Javascript the entire scenario is different. There is absolutely no difference in execution of code with or without semicolons.

Objects

week4gsoc4

So basically except the primitive values all are objects in Javascript

Tail Calls

week4gsoc5

Tail calls are nothing but essentially replacing the concept of recursive functions with loop. In a way this can not only save time but also saves space i.e better time complexity and space complexity.Observing both the algorithms above written for factorial we can understand that f() is the traditional recursive method used for finding the factorial, but f1() is the tail call optimized algorithm which is better and fast.

The work is going in progress, since there is still a lot to cover.
Github : Click here
Source : Click here

Thats it folks,
Happy Hacking !!

Continue ReadingLearnJS