Integration Testing of an Ember Component in Open Event Frontend

Open Event Frontend uses ember components which are reused several times throughout the project, making these components is one thing but we should also ensure they work as expected. To ensure this we need integration tests.How to write an integration test for event-map component? Three files are generated when we generate our event-map component from the command shell. They are namely:

event-map.js

event-map.hbs

event-map-test.js

We are familiar with the above three files as:

  1. event-map.js helps us to provide properties to our event-map.hbs
  2. event-map.hbs is where we define the structure of our component.
  3. event-map-test.js is where we define integration test for our component. Also, which is the current topic for discussion.

Testing

In order to test the rendering of the component, we define an integration test for that component. In integration tests we don’t have to launch our whole application and navigate to the location where our component is present. This makes it ideal for testing components. Have a look at the following sample integration test file.

import { test } from 'ember-qunit';
import moduleForComponent from 'open-event-frontend/tests/helpers/component-helper';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('public/event-map', 'Integration | Component | public/event map');

let event = Object.create({ latitude: 37.7833, longitude: -122.4167, locationName: 'Sample event location address' });

test('it renders', function(assert) {
  this.set('event', event);
  this.render(hbs `{{public/event-map event=event}}`);
  assert.equal(this.$('.address p').text(), 'Sample event location address');
});

So let’s break down this code line by line-

In the first line we have imported test from ‘ember-qunit’ (default unit testing helper suite     for Ember) which contains all the required test functions. For example, here we are using test function to check to check the rendering of our component. We can use test function multiple times to check multiple components.

Next, we are importing moduleForComponent from ‘open-event-frontend/tests/helpers/component-helper’ helper which helps in finding the component by its name.

Next,  we are importing hbs from ‘htmlbars-inline-precompile’ which basically imports precompile HTMLBars template strings within the tests via ES6 tagged template strings.

The moduleForComponent helper will find the component by name (event-map) and its template. The component we are testing here is a map-related. Therefore, to test this, we need to pass a dummy object consisting of latitude, longitude and locationName. The object data must render correctly in our app.

Inside our test function, this.set(‘event’, event) assigns a variable ( here event ) to our test context.

this.render (hbs `{{public/event-map event=event}}`) lets us create a new instance of the component by declaring the component in template syntax, as we would in our application.

assert.equal(this.$(‘.address p’).text(), ‘Sample event location address’) is basically a check between actual and expected arguments.

For a simple component like a table or a basic UI only component, it is not necessary to pass any object to the component. Only the rendered component can be tested as well. Apart from checking the component rendering we can perform tests on it by using test functions as described above. After writing the integration tests for components, simply run ember test –server on the terminal to see if all the tests have passed or not.      

Find out more about Integration testing in ember –

Ember guides, EmberIgniter

Continue ReadingIntegration Testing of an Ember Component in Open Event Frontend

Using Dynamic segments to Reduce Code Redundancy of Recurring HTML in Open Event ember Frontend

While developing web apps, at times we require the same HTML for different pages in our app. This leads to redundancy and low code-reusability. This can be well managed in ember.js by using dynamic segments in our routes.

In Open Event Front-end we have a route named /sessions where we want to show the details of the event’s sessions and we want to categorize the sessions in all, pending, accepted, confirmed and rejected sessions hence want to create the following subroutes under it.

events/<event-id>/sessions
events/<event-id>/sessions/pending
events/<event-id>/sessions/accepted
events/<event-id>/sessions/confirmed
events/<event-id>/sessions/rejected

All of these subroutes show different data based on the routes in a table with exactly same fields. So if we use dynamic segments, we can decrease code redundancy and increase code reusability. So let us see how to add these subroutes as dynamic segments.

Firstly, we have to add a dynamic part (pending, accepted, confirmed, rejected) under our URL /sessions . For this, edit the following code snippet to the router.js file. In place of list write the name of route handler which handles our subroutes and in place of session_status write any identifier you want as session_status is the dynamic part which changes according to subroutes. In our case it will be pending, accepted, confirmed or rejected.

     this.route('sessions', function() {
        this.route('list', { path: '/:session_status' });
      });

To display all the sessions in our /sessions route, we have to edit index route handler and return data from model hook. Now when we hit  /sessions end point, the template which we are using redundantly, i.e. list.hbs, gets data from a model hook of this route handler.

Next we need to define a model hook in our list.js file which returns data for the dynamic routes. In list.js, we would want to change the title of our page according to the dynamic segments. These dynamic segments are available under model hook in this route under param parameter. We are using this.set which sets the provided key or path to the value. Make this available in titleToken function and by applying simple switch case, we can change the title dynamically.

Till now, we could access our dynamic segments by manually changing the URL. Let’s add a link to do this transition automatically for us. For this, we edit our session.hbs file and provide links using a linkto helper. One thing to take care here is that we should pass the dynamic segments along with the link-to helper.

{{#link-to 'events.view.sessions.list' 'pending' class='item'}}

Here, pending is the dynamic segment which we are passing to our route handler. Similarly, we can make the links for all our dynamic segments. Also in this template, we should provide outlets for the common template i.e list.hbs which will be reused by other dynamic subroutes. And finally, we define our reusable template in list.hbs file.

Now when we hit on different links we are redirected to different routes which are using different data but same templates. Also, we can see this transition in our URL and title.

To know more about dynamic segments refer to Ember guide.

Continue ReadingUsing Dynamic segments to Reduce Code Redundancy of Recurring HTML in Open Event ember Frontend

Uploading Images via APIs in the Open Event Server

APIs help us to send and receive data in some particular data format that can then be used individually or integrated with a frontend UI. In our case, the entire API server is used to manage all the requests from the frontend and send back the necessary response. Usually, the application is to send simple form data which is then stored into the backend database and a valid jsonapi response is shown. However other than normal text, url, datetime data one very important data is media files, in our case event images, user images, slides, etc. In this blog, we will particularly deal with how we can upload images in the server using API.

Sending Data

Firstly, we need to decide how do we send the data in the post request of the API. So we are sending a base64 encoded string representing the image along with the image extension appended to it, for example, data:image/png;base64,iVBORw0KGgoAAAANS. This is a widely used format for showing images over the web. So when we send a POST request we send a json encoded body like:

{
    "data": "data:image/png;base64,iVBORw0KGgoAAAANS"
}

Converting Base64 Data to Image

There are 2 parts of the data in the string that we receive. The first part basically tells us the format of the image(.gif in this case) and string encoding(base64 in this case), the second part gives us the encoded string. So, from the first part, we extract the file extension for the image file to be created. We use uuid.uuid4() for a random filename.

filename = '{}.{}'.format(str(uuid.uuid4()).data.split(";")[0].split("/")[1])

Now to write the base64 encoded string as an image file, we first need to get only the encoded string part from the data and then decode it. We use string decode function of python for the decoding purpose. Then we write the data to the image file and save it.

file.write(data.split(",")[1].decode("base64")

API Response

Finally using whatever logic you are using for serving your static files, you generate the static file path for the image saved. And then create another json encoded response which returns you the url for the saved image in the server.

{
    "url": "https://xyz.storage.com/asd/fgh/hjk/1233456.png"
}

And there you have your image uploaded and served.

Continue ReadingUploading Images via APIs in the Open Event Server

Decorators in Open Event API Server

One of the interesting features of Python is the decorator. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.

Open Event API Server makes use of decorator in various ways. The ability to wrap a function and run the decorator(s) before executing that function solves various purpose in Python. Earlier before decoupling of Orga Server into API Server and Frontend, decorators were being used for routes, permissions, validations and more.

Now, The API Server mainly uses decorators for:

  • Permissions
  • Filtering on the basis of view_kwargs or injecting something into view_kwargs
  • Validations

We will discuss here first two because validations are simple and we are using them out of the box from marshmall-api

The second one is custom implementation made to ensure no separate generic helpers are called which can add additional database queries and call overheads in some scenarios.

Permissions Using Decorators

Flask-rest-jsonapi provides an easy way to add decorators to Resources. This is as easy as defining this into Resource class

  1. decorators = (some_decorator, )

On working to event role decorators to use here, I need to follow only these 3 rules

  • If the user is admin or super admin, he/she has full access to all event roles
  • Then check the user’s role for the given event
  • Returns the requested resource’s view if authorized unless returns Forbidden Error response.

One of the examples is:

def is_organizer(view, view_args, view_kwargs, *args, **kwargs):
  user = current_identity
 
  if user.is_staff:
      return view(*view_args, **view_kwargs)
 
  if not user.is_organizer(kwargs['event_id']):
      return ForbiddenError({'source': ''}, 'Organizer access is required').respond()
 
  return view(*view_args, **view_kwargs)

From above example, it is clear that it is following those three guidelines

Filtering on the basis of view_kwargs or injecting something into view_kwargs

This is the main point to discuss, starting from a simple scenario where we have to show different events list for different users. Before decoupling API server, we had two different routes, one served the public events listing on the basis of event identifier and other to show events to the event admins and managers, listing only their own events to their panel.

In API server there are no two different routes for this. We manage this with a single route and served both cases using the decorator. This below is the magic decorator function for this purpose

def accessible_role_based_events(view, view_args, view_kwargs, *args, **kwargs):
  if 'POST' in request.method or 'withRole' in request.args:
      _jwt_required(app.config['JWT_DEFAULT_REALM'])
      user = current_identity
      if 'GET' in request.method and user.is_staff:
          return view(*view_args, **view_kwargs)
      view_kwargs['user_id'] = user.id
  return view(*view_args, **view_kwargs)

It works simply by looking for ‘withRole’ in requests and make a decision to include user_idinto kwargs as per these rules

  1. If the request is POST then it has to be associated with some user so add the user_id
  2. If the request is GET and ‘withRole’ GET parameter is present in URL then yes add the user_id. This way user is asking to list the events in which I have some admin or manager role
  3. If the request is GET and ‘withRole’ is defined but the logged in user is admin or super_adminthen there is no need add user_id since staff can see all events in admin panel
  4. The last one is GET and no ‘withRole’ parameter is defined therefore ignores and continues the same request to list all events.

The next work is of query method of EventList Resource

if view_kwargs.get('user_id'):
          if 'GET' in request.method:
              query_ = query_.join(Event.roles).filter_by(user_id=view_kwargs['user_id']) \
                  .join(UsersEventsRoles.role).filter(Role.name != ATTENDEE)

This query joins the UsersEventsRoles model whenever user_id is defined. Thus giving role-based events only.

The next interesting part is the Implementation of permission manager to ensure permission decorators doesn’t break at any point. We will see it in next post.

References:

https://wiki.python.org/moin/PythonDecorators

Continue ReadingDecorators in Open Event API Server

Relationships and its usage in Open Event Orga Server

JSON API is a specification for writing RESTFul APIs (CRUD interfaces). This specification basically sets the standard for a client to request the resources and how a server is supposed to response minimizing the redundancy and number of requests.

If we look at the general implementation of RESTful APIs, we see that we are working on creating every endpoint manually, there are no relations. Sometimes different endpoints are being created for some slightly different business logic than other. We solve this purpose specifically the relationships using JSON API spec.

Features of JSON API

Apart from CRUD interface, JSON-API-Spec provides

  • Fetching Resources
  • Fetching Relationships
  • Inclusion of Related Resources
  • Sparse Fieldsets
  • Sorting
  • Pagination
  • Filtering

For Open Event API Server we need these below

  • Proper relationship definitions
  • Sorting
  • Filtering
  • Pagination

So JSON-API spec is a good choice for us at Orga Server since it solves our every basic need.

Overview of Changes

Firstly the main task was shifting to the library flask-rest-jsonapi because this library stands to our four needs in API. The changes included:

  • ensuring JSON-API spec in our requests and responses (although the most of the work is done by the library)
  • Reusing the current implementation of JWT authorization.
  • To locate the new API to /v1. Since Orga server is going to be API server with Open Event system following the API-centric approach, therefore, there is no need to have /api/v1
  • Now out timestamps in response and request will be timezone aware thus following ISO 8601 with timezone information (Eg. 2017-05-22T09:12:44+00:00)

Media type to use: application/vnd.api+json

A Relationship in JSON API

To begin with APIs, I started working on Sessions API of Orga server and the relation of a session with the event was represented as one of the attribute of Schema of the Session API like this below,

event = Relationship(attribute='event',
                        self_view='v1.session_event',
                        self_view_kwargs={'id': '<id>'},
                        related_view='v1.event_detail',
                        related_view_kwargs={'session_id': '<id>'},
                        schema='EventSchema',
                        type_='event')


  • attribute: name of the attribute with which this will be referenced in response API
  • self_view: A view name which represents the view of this relationship. This is a relationship endpoint of sessions API.
  • self_view_kwargs: view_kwargs for self_view, this is used to provide ID of the specific record to the relationship endpoint.
  • related_view: An endpoints to the related API/Object. Here the related object is ‘event’ so I have provided the endpoint to get the event detail.
  • related_view_kwargs: Here we can provide kwargs to the related object’s endpoint. Here we are sending the value of <Session_id> URL parameter on the related endpoint by mapping it with “id” of the current session object.
  • Schema: this is the schema of the related object. Since we have related object is event, therefore, added EventSchema of it.
  • type_: this is the type of related object which is event here.

After defining them, the magic here is no need to define and inject the relationship endpoints in the responses. We just need to add one route to v1.event_detail and we have relationship ready.

To make this work, I added these on routes file:

  • ‘/sessions/<int:session_id>/event’ to the v1.event_detail
  • api.route(SessionRelationship, ‘session_event’,
             ‘/sessions/<int:id>/relationships/event’)

And we have Relationship ready as Session -> Event in the API ready. We can use these relationships to Get the relationship Object(s), Updated them or Delete them. This helps Orga Server is a very efficient scale since many of our endpoints are related with events directly so instead of separately defining relationships we are able to do this with the help of JSON API and flask-rest-jsonapi

An Example Response

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": {
    "relationships": {
      "event": {
        "links": {
          "self": "/v1/speakers-calls/3/relationships/event",
          "related": "/v1/speakers-calls/3/event"
        }
      }
    },
    "attributes": {
      "announcement": "Google",
      "ends-at": "2023-05-30T09:30:10+00:00",
      "hash": null,
      "starts-at": "2022-05-30T09:30:10+00:00",
      "privacy": "public"
    },
    "type": "speakers-call",
    "id": "3",
    "links": {
      "self": "/v1/speakers-calls/3"
    }
  },
  "jsonapi": {
    "version": "1.0"
  },
  "links": {
    "self": "/v1/speakers-calls/3"
  }
}

Above example shows the relationships in the response object. We can directly check in the application using these APIs that to which type of objects this object is related with and endpoints to get related data.

Next steps in the implementation are Docs for APIs, permissions implementations to secure the endpoints and setting up unit testing of the endpoints which will be discussed in next posts.

Continue ReadingRelationships and its usage in Open Event Orga Server

Open Event Server: Dealing with environment variables

FOSSASIA‘s Open Event Server uses some environment variables to maintain different configuration for different deployment. However one con of it was, for local development, developers have to run many export commands.

It all started with the “It is not convenient, we humans are lazy.” phrase. A recent suggestion was to read this environment variables with files rather than running commands every time.
This few example environment variable commands were:

export DATABASE_URL=postgresql://open_event_user:test@127.0.0.1:5432/test

and

export INTEGRATE_SOCKETIO=false

 

Open Event Server now uses .env file and envparse to handle this.

The changes were:

  1. We store the variables in .env file, let it get ignored by git, and
  2. Use envparse to parse the file.

What is envpase:
       envparse is a simple utility to parse environment variables. It aims to eliminate duplicated, often inconsistent parsing code and instead provide a single, easy-to-use wrapper.

So instead of reading the string from the command line everytime:

export DATABASE_URL=postgresql://open_event_user:password@127.0.0.1:5432/open_event_db

We read it from the file:

To read from command line we had:

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', None)

Which now was parsed using envparse as:

SQLALCHEMY_DATABASE_URI =  env('DATABASE_URL', default=None)

In the above example, DATABASE_URL is a string and we store this string in SQLALCHEMY, setting the default by the default parameter(None in this case).

The type of environment variable is originally string, we can simply use env to parse these strings. For simplicity and understanding we can also use env.str. For different types, we can simply type cast them like env.bool (for boolean), env.int (for integer) etc. One good advantage of this envparse feature is the direct use of these type cast rather than checking for strings (i.e. reading the string from command line).

For example, earlier we had something like this:

socketio_integration = os.environ.get('INTEGRATE_SOCKETIO’)
if socketio_integration == true’:
INTEGRATE_SOCKETIO =True

Using envparse, we can have something like this:

INTEGRATE_SOCKETIO = env.bool('INTEGRATE_SOCKETIO’, default=False)

This helps in parsing as boolean instead of string. So, if we have INTEGRATE_SOCKETIO=true in .env file, we can write INTEGRATE_SOCKETIO = env.bool(‘INTEGRATE_SOCKETIO’, default=False). This automatically converts the true to boolean True in python.

In order to use envparse we install envparse with:

$ pip install envparse


In the case of
Open Event Server project, you only have to install the requirements.txt and copy the .env.example already mentioned in installation doc.

This is how we finally remove the headache of writing big exports again and again and fairly helps beginners to start off with Open Event Server  project much more easily and quickly.

Continue ReadingOpen Event Server: Dealing with environment variables

Permission Dependent Schema for Admin Settings in Open Event Server

For implementing the next version of the API in Open Event, the schema is a very important thing. It tells you exactly what all information you need to send in the body and how the response will look. In flask-rest-jsonapi, we usually mention a schema for an API which is then used for validating requests and sending response. Using decorators, we restrict who all can create, edit or get responses from a particular API endpoint. However, a scenario may so arise that you need to show data to users at different permissions level, but the amount of data shown significantly varies with the permission.

For example, for the settings API in our case. There are few informations like the app name, app tagline that we want to be available to users at all permission levels. However, informations such as aws secret key, or mailing secret keys or any other secret key, we want that to be available only to the admin and super admin. And the responses should be such that users at different permission level should feel that whatever information shown to them is complete and not missing.

So, what we do is we create different schemas, in our case 2 different schemas. Depending on the permission of the user, we show them a particular schema. In our case, the two schemas are SettingSchemaAdmin and SettingSchemaNonAdmin. In SettingSchemaAdmin, we have all the attributes or fields that are present and is accessible to the Admin and Super Admin. In the SettingSchemaNonAdmin however, we have only those fields and attributes that we want to show to all non admin users.

from flask_jwt import current_identity
 
class SettingDetail(ResourceDetail):
    """
    setting detail by id
    """
 
    def before_get(self, args, kwargs):
        kwargs['id'] = 1
        if current_identity.is_admin or current_identity.is_super_admin:
            self.schema = SettingSchemaAdmin
        else:
            self.schema = SettingSchemaNonAdmin

 

The above code helps us achieve this. If you have read previous blogs about the API server, you would already know that we are using JWT for authenticating our users. In this code, we are importing current_identity from flask_jwt. Current_identity, returns us an object of the User type which has properties such as is_admin, is_super_admin, etc. to help us identify the permission level of that user.
Using this object, we check whether the user who is making the request via jwt authentication is an admin or super admin, or just a normal registered user.

        if current_identity.is_admin or current_identity.is_super_admin:
            self.schema = SettingSchemaAdmin
        else:
            self.schema = SettingSchemaNonAdmin

 

So, if the current user sending the request is an admin, then we set the schema for the Resource manager class of the flask-rest-jsonapi as SettingSchemaAdmin, which we have already declared before containing all the fields, else, we set it as SettingSchemaNonAdmin which has limited number of attributes.

Continue ReadingPermission Dependent Schema for Admin Settings in Open Event Server

Preparing a release for Phimpme Android

Most of the essential features are now in a stable state in our Phimpme Android app. So we decided to release a beta version of the app. In FOSSASIA we follow branch policy where in development all current development will take place and in master branch the stable code resides.

Releasing an app is not just building an apk and submitting to the distribution platform, certain guidelines should follow.

How I prepare a released apk for Phimpme

List down the feature

We discussed on our public channel what features are now in stable state and can be released. Features such as account manager and Share Activity is excluded because it is not complete and in under development mode. We don’t want to show and under development feature. So excluded them. And made a list of available features in different category of Camera, Gallery and Share.

Follow the branch policy.

The releasable and stable codebase should be on master branch. It is good to follow the branch policy because it helps if we encounter any problem with the released apk. We can directly go to our master branch and check there. Development branch have very volatile because of active development going on.

Every Contributor’s contribution is important

When we browse our old branches such as master in case of ours. We see generally it is behind 100s of commits to the development. In case of that when we create a PR for that then it generally contains all the old commits to make the branch up to the latest.

In this case while opening and merging do not squash the commits.

Testing from Developer’s end

Testing is very essential part in development. Before releasing it is a good practice that Developer should test the app from their end. We tested app features in different devices with varying Android OS version and screen size.

  • If there is any compatibility issue, report it right away and there are several tools in Android to fix.
  • Support variety of devices and screen sizes

Changing package name, application ID

Package name, application ID are vitals of an app. Which uniquely identifies them as app in world. Like I changed the package name of Phimpme app to org.fossasia.phimpme. Check all the permission app required.

Create Release build type

Build types are great to way categorize the apps. Debug and Release are two. There are various things in codebase which we want only in Debug modes. So when we create Release mode it neglect that part of the code.

Add build types in you application build.gradle

buildTypes {
   release {
       minifyEnabled false
   }

Rebuild app again and verify from the left tab bar

Generate Signed apk and Create keystore (.jks) file

Navigate to Build → Generate Signed APK

Fill all details and proceed further to generate the signed apk in your home directory.

Adding Signing configurations in build.gradle

Copy the keystore (.jks) file to the root of the project and add signing configurations

signingConfigs {
       config {
           keyAlias 'phimpme'
           keyPassword 'phimpme'
           storeFile file('../org.fossasia.phimpme.jks')
           storePassword 'XXXXXXX'
       }
   }

InstallRelease Gradle task

Navigate to the right sidebar of Android Studio click on Gradle


Click on installRelease to install the released apk. It take all the credentials from the signing configurations.

Resources

Continue ReadingPreparing a release for Phimpme Android

Sentiment Data in Emoji-Heatmapper loklak App

Analysing emojis can uncover meaning and sentiment in ways regular text analytics cannot. So this was the main idea to introduce sentiment data into the Emoji-Heatmapper app. LokLak Search API has features such as classification and categorization of tweets. The emotions, for instance, can be joy, anticipation, sad etc.

So, in the Emoji-heatmapper app, I am displaying the occurrence of emojis on the map according to the location traced and also the sentiment related to the emoji i.e., search query as follows:

How to get the sentiment data:

One should simply enter the emoji into the search box for the results. The following code shows part of the LokLak Search API results (JSONObject):

      "hashtags_count": 0,
      "classifier_emotion": "anger",
      "classifier_emotion_probability": 
      1.2842921170985733E-9,
      "classifier_language": "english",
      "classifier_language_probability": 
      1.4594549568869297E-8,
      "without_l_len": 49,
      "without_lu_len": 49,
      "without_luh_len": 49,

I am using the above field name ”classifier_emotion” to display the results.

Till here getting the data relevant to query part is done. Next, the classifier_emotion of each tweet containing the query is collected into an array and sorted to get a unique list.

var emotion = [];
var emotions_array = [];

for (var i = 0; i  <  tweets.statuses.length; i++) {
    if (tweets.statuses[i].classifier_emotion) {
        emotion = tweets.statuses[i].classifier_emotion;
        emotions_array.push(emotion);
    }

    emotions_array.sort();
    emotion_array = jQuery.unique( emotions_array );

Loading the Sentiment data onto the Screen

When the query has a single emotion, or if multiple emotions or no emotions. These use cases/situations are displayed as follows:

Fig: Single Emotion

Fig: Multiple Emotions

Fig: No Emotions data

The code which creates the data dynamically on the output screen is as follows:

//Loading the sentiment
$(document).ready(function() {
    var listItems= "";
    if (emotions_array.length == 0) {
        listItems = "No Sentiment data is available for " + query
    }
    if (emotion_array.length == 1) {
        listItems += "<h3> Sentiment of " + query + " is ";
    } else if (emotion_array.length > 1) {
        listItems += "<h3> Sentiments of " + query + " are ";
    }

    var emotion_data = emotion_array.join(", ") + "."
    listItems += emotion_data + "</h3>"

    $("#sentiment").html(listItems);
});

Conclusion

The Emoji-Heatmapper app displays the sentiment data of the query being searched for which populates data dynamically using LokLak Search API.

Resources

Continue ReadingSentiment Data in Emoji-Heatmapper loklak App

Viewing an Event in Giggity

Giggity is an Android app that loads xCal, pentabarf, frab, wafer and iCal files (that contain schedules of conferences, festivals and other events) and lets you browse them in various convenient formats. It is a generic app that can be used for any event that publishes their schedule in an open format. Recently support to see Open Event JSON format has been added in the Giggity. In this blog I describe the simple steps you need to follow to see the event that is created in the Open Event server and can be seen in the Giggity app. Although the process of creating an event is quite detailed but the UI is very user friendly and simple to use so here I describe the process after creating the event and adding it in Giggity app

1. Go to your event dashboard

2. Click on the export button

3. Select sessions and microlocations by clicking the switch buttons. Get the url generated and copy it. Skipping the microlocations will disable the option to navigate to the location in map opening from the app.

4. Click on the “+” button on the toolbar and paste the link.

   

5. Now you can see the sessions with locations. Slide the navigation drawer to see the links and signup url or create the home screen shortcut.

   

So here you can see your event following these five simple steps. Watch this video to see this in action.

https://www.youtube.com/watch?v=RairLTXqqDI

Continue ReadingViewing an Event in Giggity