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 Reading

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 Reading

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 Reading

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 Reading

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 Reading

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 Reading

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 Reading

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 Reading

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 Reading

Badge Generation : Adding Progress Bar

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 ember-progress-bar in the badgeyay project. This progress bar shows real-time progress of the badge generation process.

Adding the functionality to badgeyay

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

Step 1 : Adding the package to package.json

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

ember install ember-progress-bar

or

npm install ember-progress-bar –save

Step 2 : Adding the progressbar to the frontend

Once we have installed the progress bar, we need to display it onto the frontend of the project.

To do that we use the handlebars templating engine to render the progress bar.

{{#if showProgress}}
<
div class=“ui segment”>
<
div class=“ui centered aligned grid”>{{progressState}}</div>
<
div class=“ui divider”></div>
{{ember-progress-bar progress=progress options=(hash color=’orange’)}}
</
div>
{{/if}}

Step 3 : Now we need to define states

We need to define the states that the progress bar will take up in realtime. And to do so, we make changes to the create-badges controller

showProgress   : false,
progress       : 0,
progressState  : ,

Now we manage the states according to the functionality that has been done.

this.set(‘showProgress’, true);
this.set(‘progress’, 0.1);
this.set(‘progressState’, ‘Setting Paper Size’);

this.set(
‘progress’, 0.4);
this.set(‘progressState’, ‘Gathering background’);

this.set(
‘progress’, 0.7);
this.set(‘progressState’, ‘Preparing your badges’);

this.set(
‘showProgress’, false);
this.set(‘progress’, 0);
this.set(‘progressState’, );

Finally, we have our basic progress bar ready for the users to view.

Screenshot of changes

Resources

Continue Reading
Close Menu
%d bloggers like this: