Adding Dredd Tests for Image Sizes on Open Event Flask Server

In this blog, we will talk about how to add dredd hooks for testing the API of Event Image Sizes and Speaker Image Sizes in Open Event Server. The focus is on adding the factory class and dredd hooks of these APIs using factory-boy python library and Dredd API testing framework.

Factory Creation

For the Event and Speaker Image Sizes, we’ll make our factory classes EventImageSizeFactory  and SpeakerImageSizeFactory as follows

Now, let’s try to understand this class.

In this class, we are writing the sample data two records of ImageSizes Model, these records corresponds to Event and Speaker Image Sizes.

  1. First of all, we inherit class factory.alchemy.SQLAlchemyModelFactory to build our sample data which for Image Sizes.
  2. Class Meta has model and sqlalchemy_session attributes. Model tells the factory class of to which model this factory class push the data to database and sqlalchemy_session is assigned with the current database session.
  3. Next, we add the attributes according to the model and Schema of Image Sizes.

Adding Dredd Hooks

For the ImageSizes, we’ll make our dredd hooks as follows

Now, let’s try to understand these tests.

In this tests, we check the API by matching the response after adding a record in these API to one which is present at API blueprint.

  1. First of all, we use decorator @hooks.before which means we first add a record in the database and then match the response we get from API say /v1/event-image-sizes with the response mentioned at Image Size > Event Image Size Details > Get Event Image Size Details in API blueprint.
  2. We create an instance of EventImageSizeFactory which is a record of model Image Sizes.
  3. This record is then returned as a response of API /v1/event-image-sizes and matches with the blueprint at Image Size > Event Image Size Details > Get Event Image Size Details

Similarly, we have added other dredd tests for PATCH method as well.

So, we saw how factory-boy python library and Dredd API testing framework helped us in testing the REST APIs on Open Event Server.

Resources

Continue ReadingAdding Dredd Tests for Image Sizes on Open Event Flask Server

Adding Event Roles Permission API on Open Event Server

The Open Event Server enables organizers to manage events from concerts to conferences and meetups. It offers features for events with several tracks and venues. Event managers can create invitation forms for speakers and build schedules in a drag and drop interface. The event information is stored in a database. The system provides API endpoints to fetch the data, and to modify and update it.

The Open Event Server is based on JSON 1.0 Specification and hence build on top of Flask Rest Json API (for building Rest APIs) and Marshmallow (for Schema).

In this blog, we will talk about how to add API for accessing and updating the events role permissions on Open Event Server. The focus is on Schema creation and it’s API creation.

Schema Creation

For the Events Role Permission, we’ll make our Schema as follows

 

Now, let’s try to understand this Schema.

In this feature, we are providing Admin the rights to get and update the permission given to a role concerning a service.

  1. First of all, we are provide the four fields in this Schema, which are can_create, can_read, can_update and can_delete which are Boolean.
  2. All these fields gives us idea whether a user with a role can create, read, update and delete a service or not respectively in the whole system.
  3. Next there is a relationship with role which is one of organizer, coorganizer, track_organizer, moderator, registrar or attendee.
  4. Next there is a relationship with service which is one of Track, Microlocation, Session, Speaker or Sponsor.

API Creation

For the Events Role Permissions, we’ll make our API as follows

Now, let’s try to understand this API.

In this feature, we are providing Admin the rights to get and update the permission given to a role concerning a service.

  1. First of all, there is the need to know that this API has two method GET and PATCH.
  2. Decorators shows us that only Admin has permissions to access PATCH method for this API i.e. only Admins can modify the events role permissions .
  3. In EventsRolePermissionList, we are inheriting ResourceList from Flask Rest JSONAPI which will allow us to get all the records for the model Permission.
  4. In EventsRolePermissionDetail, we are inheriting ResourceDetail from Flask Rest JSONAPI which will allow us to get and update attributes of a record of model Permission.
  5. In EventsRolePermissionRelationship, we are inheriting ResourceRelationship from Flask Rest JSONAPI which will allow us to get and update relationships of a record of model Permission.

So, we saw how Events Role Permission Schema and API is created to allow users to get it’s values and Admin users to modify it’s attributes and relationships.

Resources

Continue ReadingAdding Event Roles Permission API on Open Event Server

Building the API of Speaker Image Size on Open Event Server

The Open Event Server enables organizers to manage events from concerts to conferences and meetups. It offers features for events with several tracks and venues.It uses the JSON 1.0 Specification and build on top of Flask Rest Json API (for building Rest APIs) and Marshmallow (for Schema). In this blog, we will talk about how to add API for accessing and updating the Speaker Image Size on Open Event Server. The focus is on its API creation.

API Creation

For the SpeakerImageSizeDetail, we’ll make our Schema as follows

Now, let’s try to understand SpeakerImageSizeDetail.

In this feature, we are providing Admin the rights to Get and Update the SpeakerImageSizes

  1. kwargs[‘id’] = 2 states that Image Size model has 2 records and 1st record is used for Event Image Size and 2nd record is used for Speaker Image Size.
  2. decorators = (api.has_permission(‘is_admin’, methods=”PATCH”, id=”2″),) states that for Speaker Image Size, Update API is accessible to Admins only.
  3. methods = [‘GET’, ‘PATCH’] states that this API provides two methods i.e. GET and PATCH.
  4. schema = SpeakerImageSizeSchema states that the schema which is used to return the response is Speaker Image Size Schema.
  5. data_layer = {‘session’: db.session, ‘model’: ImageSizes} states the session and Model used to fetch the records.

Resources

Continue ReadingBuilding the API of Speaker Image Size on Open Event Server

Implementing API to allow Admins to modify config of devices of any user

As any user can add or remove devices from their account, there needed to be a way by which Admins can manage the user devices. The Admins and higher user roles should have the access to modify the config of devices of any user. This blog post explains how an API has been implemented to facilitate Admins and higher user roles to change config of devices of any user.

Implementing a servlet to allow changing review status of a Skill

The basic task of the servlet is to allow Admin and higher user roles to modify the config of devices of any user. The Admin should be allowed to edit the name of the device and also the room of the device, similar to how a user can edit his own devices.

Here is the implementation of the API:

  1. The API should be usable to only the users who have a user role Admin or higher. Only those with minimum Admin rights should be allowed to control what Skills are displayed on the CMS site. This is implemented as follows:

   @Override
    public UserRole getMinimalUserRole() {
        return UserRole.ADMIN;
    }

 

  1. The endpoint for the API is ‘/cms/modifyUserDevices.json’. This is implemented as follows:

   @Override
    public String getAPIPath() {
        return "/cms/modifyUserDevices.json";
    }

 

  1. The main method of the servlet is the serviceImpl() method. This is where the actual code goes which will be executed each time the API is called. This is implemented as follows:

    JSONObject result = new JSONObject(true);
    Collection<ClientIdentity> authorized = DAO.getAuthorizedClients();
    List<String> keysList = new ArrayList<String>();
    authorized.forEach(client -> keysList.add(client.toString()));
    String[] keysArray = keysList.toArray(new 
    String[keysList.size()]);

    List<JSONObject> userList = new ArrayList<JSONObject>();
    for (Client client : authorized) {
        JSONObject json = client.toJSON();

        if(json.get("name").equals(email)) {
            ClientIdentity identity = new ClientIdentity(ClientIdentity.Type.email, client.getName());
            Authorization authorization = DAO.getAuthorization(identity);

            ClientCredential clientCredential = new ClientCredential(ClientCredential.Type.passwd_login, identity.getName());
            Authentication authentication = DAO.getAuthentication(clientCredential);

            Accounting accounting = DAO.getAccounting(authorization.getIdentity());

            if(accounting.getJSON().has("devices")) {

                JSONObject userDevice = accounting.getJSON().getJSONObject("devices");
                if(userDevice.has(macid)) {
                    JSONObject deviceInfo = userDevice.getJSONObject(macid);
                    deviceInfo.put("name", name);
                    deviceInfo.put("room", room);
                }
                else {
                    throw new APIException(400, "Specified device does not exist.");
                }

            } else {
                json.put("devices", "");
            }
            accounting.commit();
        }
    }

 

Firstly, the list of authorized clients is fetched using DAO.getAuthorizedClients() and is put in an ArrayList. Then we traverse through each element of this ArrayList and check if the device exists by checking if there’s a key-value pair corresponding to the macid passed in the query parameter. If the device doesn’t exist, then an exception is thrown. However, if the macid exists in the traversed element of the ArrayList, then we put the name and the room of the device as passed as query parameters in that particular element of the ArrayList, so as to overwrite the existing name and room of the device of the user.

This is how an API has been implemented which allows Admins and higher user roles to modify the config of devices of any user.

Resources

Continue ReadingImplementing API to allow Admins to modify config of devices of any user

Implementing System Logs in SUSI.AI Admin Panel

The admin panel of SUSI.AI provides a lot of features required by system maintainers and admins to administer and maintain various activities of SUSI. Therefore system logs have been implemented on the admin panel so that admins can check whether SUSI server is working fine or throwing some errors. In this blog we will discuss about how logs are implemented on server and accounts.

Continue ReadingImplementing System Logs in SUSI.AI Admin Panel

Implementing API keys on SUSI.AI server

The clients of SUSI.AI need config keys to work with some APIs like captcha, maps and blog and these keys are stored in the server of SUSI and the clients fetch them using API calls to the server. The admins can add or delete api keys from the server using the

/aaa/apiKeys.json

 

API. This API stores the API keys in a json format in the apiKeys.json file in the system_keys_dir directory which is in the data directory on the susi server.

For the clients to fetch these API keys and use them in their respective APIs, they need to use

Continue ReadingImplementing API keys on SUSI.AI server

Adding Open Street Maps to PSLab Android

PSLab Android app is an open source app that uses fully open libraries and tools so that the community can use all it’s features without any compromises related to pricing or feature constraints. This will brings us to the topic how to implement a map feature in PSLab Android app without using proprietary tools and libraries. This is really important as now the app is available on Fdroid and they don’t allow apps to have proprietary tools in them if they are published there. In other words, it simply says we cannot use Google Maps APIs no matter how powerful they are in usage.

There is a workaround and that is using Open Street Maps (OSM). OSM is an open source project which is supported by a number of developers all around the globe to develop an open source alternative to Google Maps. It supports plenty of features we need in PSLab Android app as well. Starting from displaying a high resolution map along with caching the places user has viewed, we can add markers to show data points and locations in sensor data logging implementations.

All these features can be made available once we add the following dependencies in gradle build file. Make sure to use the latest version as there will be improvements and bug fixes in each newer version

implementation "org.osmdroid:osmdroid-android:$rootProject.osmVersion"
implementation "org.osmdroid:osmdroid-mapsforge:$rootProject.mapsforgeVersion"
implementation "org.osmdroid:osmdroid-geopackage:$rootProject.geoPackageVersion"

 

OSM will be functional only after the following permission states were granted.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"  />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

In a view xml file, add the layout org.osmdroid.views.MapView to initiate the map view. There is a known issue in OSM library. That is during the initiation, if the zoom factor is set to a small value, there will be multiple instances of maps as shown in Fig 1. The solution is to have a higher zoom value when the map is loaded.

Figure 1: Multiple map tiles in OSM

Once we initialize the map view inside an activity, a zoom level can be easily set using a map controller as follows;

map = findViewById(R.id.osmmap);
map.setTileSource(TileSourceFactory.MAPNIK);
map.setBuiltInZoomControls(true);
map.setMultiTouchControls(true);

IMapController mapController = map.getController();
mapController.setZoom((double) 9);
GeoPoint startPoint = new GeoPoint(0.00, 0.00);
mapController.setCenter(startPoint);

 

After successfully implementing the map view, we can develop the business logic to add markers and descriptions to improve the usability of OS Maps. They will be available in the upcoming blog posts.

Reference:

  1. https://github.com/osmdroid/osmdroid/wiki/How-to-add-the-osmdroid-library-via-Gradle
  2. https://www.openstreetmap.org/
Continue ReadingAdding Open Street Maps to PSLab Android

Basic Badge Preview in Badgeyay

A Badge generator like Badgeyay must be able to generate, store and export the user data as and when needed. This blog post covers the addition of a preview section in the badge generator. It is discussed as to how the attributes on preview section are added.

Adding the functionality to badgeyay

Let us see how we implemented this functionality into the frontend of the project.

Step 1 : Adding the helper function

We need to add a helper function for determining the font of the preview items. We define a function “rel”, as in relative, which defines the relative font size according to the chosen one.

export function rel(params) {
var [font_size] = params;
var iFont = parseInt(font_size);
if (iFont <= 10) {
return (iFont * 2.7).toString();
}
return (iFont * 2.15).toString();
}

Step 2 : Adding the styling in the scss file

Now we add the required styling in the SCSS file to ensure that the preview appears at the exactly as we desire it to be.

.bgImg {
border-radius: 5px;
height: 600px;
}

.preview.content {
margin-left: 50px;
padding-top: 200px;
}

Step 3 : Now we need to add attributes to controller

Now we need to define the attributes that will control the text inside the preview and the preview controller.

firstName      : ,
lastName       : ,
organization   : ,
socialHandle   : ,
designation    : ,
prevImageData  : ,

Now we define when will the preview be changed. In our case it will be changed when a user types in something or a new image is selected.

mutateText(txtData) {
this.manualClicked();
let prevData = txtData.split(‘\n’)[0].split(‘,’);
this.set(‘firstName’, prevData[0].toString());
this.set(‘lastName’, prevData[1].toString());
this.set(‘designation’, prevData[2].toString());
this.set(‘organization’, prevData[3].toString());
this.set(‘socialHandle’, prevData[4].toString());
this.set(‘textData’, txtData);
},
.
.
mutateCustomImage() {
this.set(‘prevImageData’, imageData);
}

The state of variables inside the preview section changes whenever the user types in a new name or designation etc. The image gets populated once the image is added either using the custom image input or by selecting the default image.

Screenshot of changes

Resources

Continue ReadingBasic Badge Preview in Badgeyay

Toggling preview section in Badgeyay

A Badge generator like Badgeyay must be able to generate, store and export the user data as and when needed. This blog post covers the addition of a preview section in the badge generator. It is discussed as to how the feature of toggling the preview section was implemented in the project

Adding the functionality to badgeyay

Let us see how we implemented this functionality into the frontend of the project.

Step 1 : Adding the toggle button to the frontend UI

We add the button to toggle the preview on and off the screen using the standard handlebars convention. We add a button with the action ‘togglePreview’ to toggle the preview section in frontend.

<div class=“right floated right aligned six wide column”>
<
div class=“ui”>
<
button {{action ‘togglePreview‘}} class=“ui basic orange button” data-tooltip=“Toggle Preview (WIP)” data-position=“right center”>{{prevButton}}</button>
</
div>
<
/div>

Step 2 : Adding the styling in the scss file

Now we add the required styling in the SCSS file to ensure that the preview button appears at the exact desired position only.

.ui{

.column{
color: black;

.create-badge {
position: relative;
padding-left: 6%;
padding-right: 6%;
top: –50px;
}
}
}

Step 3 : Now we need to define states

Now we need to define the states that will control the text inside the preview button and the preview controller.

previewToggled : false,
prevButton     : ‘<‘,

Now we add the method to control the toggle feature in the component.

togglePreview() {
this.set(‘previewToggled’, !this.previewToggled);
if (this.previewToggled) {
this.set(‘prevButton’, ‘>’);
}
else {
this.set(‘prevButton’, ‘<‘);
}
}

The ‘togglePreview’ function changes the state of the preview, either rendering it on screen or off the screen. This is how we control the preview section being displayed on the screen.

Screenshot of changes

Resources

Continue ReadingToggling preview section in Badgeyay

Enhancing pagination in Badgeyay

A Badge generator like Badgeyay must be able to generate, store and export the user data as and when needed. This blog post covers the enhancement of pagination in the frontend of badgeyay project. There are small “next” and “previous” links to toggle between pages..

Enhancing the current way of links

The problem with the pagination links was that in case of no more badges/users etc, the links would always appear on the bottom right of the table. The previous link must not appear when no previous page is there and vice versa for the next link.

Step 1 : Adding the package to package.json

Image link is the link to the user’s uploaded image on remote firebase server.

{{#if allow}}
<tfoot>
<
tr>
<
th colspan=“5”>
<
div class=“ui right floated pagination menu”>
{{#if allow_prev}}
<
a class=“icon item” {{action ‘prevPage‘}}>
<
i class=“left chevron icon”></i>
</
a>
{{/if}}
{{#if allow_next}}
<
a class=“icon item” {{action ‘nextPage‘}}>
<
i class=“right chevron icon”></i>
</
a>
{{/if}}
</
div>
</
th>
</
tr>
<
/tfoot>
{{/i
f}}

Step 2 : Initializing the variables in setupController

Once we have added the if construct to the badgeyay frontend then we need to add the variable initialization in the setupController method in EmberJS.

setupController(controller, model) {
this._super(…arguments);
set(controller,
‘reports’, model);
if (model.length < 9) {
set(controller,
‘allow_prev’, false);
set(controller,
‘allow_next’, false);
set(controller,
‘allow’, false);
}
}

Step 3 : Implementing state changed in the controllers

Now we need to handle the situation when a user clicks the links and there are more or less links to display. This is done by checking the length of the model in the controller.

if (this.page === 1) {
this.set(‘allow_prev’, false);
}
else {
this.set(‘allow_prev’, true);
}
this..set(‘allow_next’, true);

Same needs to be done for all the controllers that have pagination available.

And finally we need to pass these variables in the component template. One such example is given below.

<div class=“ui grid user-grid”>
<
div class=“row”>
<
div class=“sixteen wide column”>
{{badge-table badges=badges user=user session=session sendbadgeId=(action ‘deleteBadge’ badge) prevPage=(action ‘prevPage’) nextPage=(action ‘nextPage’) allow_prev=allow_prev allow_next=allow_next allow=allow}}
</
div>
</
div>
<
/div>

Finally, we have the pagination links working as desired..

Screenshot of changes

Resources

 

Continue ReadingEnhancing pagination in Badgeyay