We are going to make a SUSI skill that fetches information about a bank when the IFSC (Indian Financial System Code) is known. Here is a detailed explanation of how we going about doing this.
Getting started with the skill creation
API endpoint that returns the bank details
Before going to the skill development, we need to find an API that would return the bank details from the IFSC, On browsing through various open source projects. I found an apt endpoint by Razorpay. Razorpayis a payment gateway for India which allows businesses to accept, process and disburse payments with ease. The Github link to the repository is https://github.com/razorpay/ifsc.
Now, head over to the SUSI Etherpad, which is the current SUSI Skill Development Environment and create a new Pad.
Here, we need to define the skill in the Etherpad. We will now write rules/intents for the skill. An intent represents an action that fulfills a user’s spoken request.
Intents consist of 2 parts –
User query – It contains different patterns of query that user can ask.
Answer – It contains the possible answer to the user query.
The main intent that our skill focuses on is, returning the bank name and address from the IFSC code. Here is how it looks –
Name of bank with IFSC code * | Bank's name with IFSC code *
!example:Name of bank with IFSC code SBIN0007245
!expect: The name of bank is State Bank of India
!console:The name of bank with IFSC code $1$ is $object$
{
"url":"https://ifsc.razorpay.com/$1$",
"path":"$.BANK"
}
eol
Part-wise explanation of the intent
The first line contains the query pattern that the user can use while querying. You can see that a wildcard character (*) is used in the pattern. It contains the IFSC of the bank that we wish to know, and will later on use to fetch the details via the API.
The second line contains an example query, followed by third line that contains the expected answer.
Last part of the rule contains the answer that is fetched from an external API – https://ifsc.razorpay.com/<:ifsc> ,via the console service provided by SUSI Skills. Here, <:ifsc> refers to the IFSC that the user wants to know about. We get it from the user query itself, and can access it by the variable name $1$ as it matches with the 1st wildcard present in the query. If there would be 2 wildcards, we could have accessed them by $1$and $2$respectively.
The console service provides us with an option to enter the url of the API that we want to hit and path of the key we want to use.
The sample response of the endpoint looks like this :
Since, we want to extract the name of the bank, the BANK key contains our desired value and we will use $.BANK in the path of the console service. And it can be accessed by $object$ in the answer. We frame the answer using $object$and $1$variables, and it like the one mentioned in the expected answer. eol marks the end of the console service.
Similarly, the intent that gives us the address of the bank looks like this –
Address of bank with IFSC code * | Bank's address with IFSC code *
!example:Address of bank with IFSC code SBIN0007245
!expect: The address of bank is TILAK ROAD HAKIMPARA, P.O.SILIGURI DARJEELING, WEST BENGAL ,PIN - 734401
!console:The address of bank with IFSC code $1$ is $object$
{
"url":"https://ifsc.razorpay.com/$1$",
"path":"$.BANK"
}
eol
Testing the skill
Open any SUSI Client and then write dream <your dream name> so that dreaming is enabled for SUSI. We will write down dream ifsc. Once dreaming is enabled, you can now test any skills which you’ve made in your Etherpad.
We can test the skills by asking queries and matching it with the expected answer. Once the testing is done, write stop dreaming to disable dreaming for SUSI.
After the testing was successful completely, we will go ahead and add it to the susi_skill_data.
We will add the basic skill details and author details to the etherpad file and make it in the format as mentioned above. The final text file looks like this –
::name IFSC to Bank Details
::author Akshat Garg
::author_url https://github.com/akshatnitd
::description It is a bank lookup skill that takes in IFSC code from the user and provides you all the necessary details for the Bank. It is valid for banks in India only
::dynamic_content Yes
::developer_privacy_policy
::image images/download.jpeg
::terms_of_use
Name of bank with IFSC code * | Bank's name with IFSC code *
!example:bank with IFSC code *
!expect: The name of bank is SBI
!console:The name of bank with IFSC code $1$ is $object$
{
"url":"https://ifsc.razorpay.com/$1$",
"path":"$.BANK"
}
eol
Address of bank with IFSC code * | Bank's address with IFSC code *
!example:Address of bank with IFSC code *
!expect: The address of bank is
!console:The address of bank with IFSC code $1$ is $object$
{
"url":"https://ifsc.razorpay.com/$1$",
"path":"$.ADDRESS"
}
eol
Submitting the skill
The final part is adding the skill to the list of skills for SUSI. We can do it by 2 ways:
Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.
Badgeyay has many features related to enhancement in the generation of badges. It gives the choice of uploading data entries i.e by CSV or manually. There are options available for choosing Badge Background and font specifications. But there is an important feature missing which will make the service more user-friendly in terms of creation of badges for different types of events i.e, Badge Size.
Badge Size feature is implemented in Backend. I need to send the data in the backend in the desired format for creation of Badges with different sizes.
In this Blog, I will be discussing how I implemented Badge Size feature in Badgeyay Frontend in my Pull Request.
Let’s get started and understand it step by step.
Step 1:
Create Badge Size component with Ember CLI.
$ ember g component badge-component/badge-size
Step 2:
Write the HTML required in the badge-size component:
In the Phimpme Android application, users can perform various operations on the albums available such as creating a zip file of the album, rename an album and many more. However, one another useful functionality that has been added to the Phimpme Android application is the option to secure particular albums. So in this post, I will be discussing the implementation of this security feature.
Step 1
Firstly, a view item for providing the option to enable security for particular albums is required to be added to the security settings layout. The two-state toggle switch widget provided by the Android framework along with a textview has been added as the required view item. A screenshot depicting the layout change is provided below.
The code snippet representing the operation is provided below.
Now we need to keep track of the albums selected by the user to secure. This can be done by storing the selected album/albums paths in an ArrayList<String> which can be referred later when required in the process.
The required code snippet to perform the above mentioned operation is provided below.
holder.foldercheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
securedfol.add(a.getPath());
a.setsecured(true);
}else{
securedfol.remove(a.getPath());
a.setsecured(false);
}
}
});
Step 3
Now we need to store the selected albums preference in the SharedPreference so that the user’s security preference persists even when the user exits the application and the user doesn’t have to redo the securing operation the next time user launches the application. The ArrayList<String> object containing the path of the user choice albums are converted to JSON representation by the use of the Gson Java library and the string key denoting the JSON representation of the list is saved in the SharedPreference thereafter.
Now at the time of performing other operations on the secured folders, the list containing the secured folder paths is retrieved from SharedPreference and the choosen folder’s path is searched in the obtained list, then the user is asked to authenticate accordingly.
This is how we have implemented the functionality to secure particular albums in the Phimpme Android application. To get the full source code, please refer to the Phimpme Android Github repository listed in the resource section below.
In the Phimpme Android application, users are provided with options to perform various operations on the albums available such as move, creating a zip file of the album, rename an album and many more. However, one another useful functionality that has been added to the Phimpme Android application is the option to search albums. So in this post, I will be discussing the implementation of search functionality.
Step 1
Android framework provides developers with a search widget called SearchView that provides a user interface for the user to search a query and submit the request. So first setting up the widget in the action bar of the activity is required. The searchview widget can be added to the action bar as a menu item by adding the following lines in the XML menu resource file menu_albums.xml.
Now SearchView.OnQueryTextListener interface is used for initiating the search operation and listening to the callbacks for changes to the query text. For the purpose of listening to the querytext, two methods are used here both of which are listed below.
onQueryTextChanged(String Text) – This method is called every time the query text is changed by the user and returns a boolean value, false if SearchView should perform the default action of showing any suggestions and true if the action was handled by the listener.
onQueryTextSubmit(String query) – This method is called when the user submits a query which could be done with a key press on the keyboard or by pressing the submit button. It also returns a boolean value which is true if the query has been handled by the listener, otherwise false.
The code snippet for the implementation of the above mentioned interface is provided below.
In the final step, with the use of the onQueryTextChange method of the SearchView.onQueryTextListener interface the search operation and displaying the search results in the UI can be achieved. The onQueryTextChange method is called every time the search-query text changes. From the onQueryTextChange method, another method named searchTitle is invoked. Inside the searchTitle method the album names matching the search-query are searched from an Arraylist<Albums> containing all the albums displayed in the application. The albums obtained as a result of the search operation are then stored in another Arraylist<Album> which is thereafter passed as a parameter to the swapDataSet method of the AlbumsAdapter class to display the searched albums in the album view. The code snippet used for the above operations is provided below.
publicbooleansearchTitle(String newText) { if (!fromOnClick) { String queryText = newText; queryText = queryText.toLowerCase(); final ArrayList<Album> newList = new ArrayList<>(); for (Album album : albList) { String name = album.getName().toLowerCase(); if (name.contains(queryText)) { newList.add(album); } } if(newList.isEmpty()){ checkNoSearchResults(newText); } else{ if(textView.getVisibility() == View.VISIBLE){ textView.setVisibility(View.INVISIBLE); } } albumsAdapter.swapDataSet(newList); } else { fromOnClick = false; } returntrue; }
This is how we have implemented the search functionality in the Phimpme Android application. To get the full source code, please refer to the Phimpme Android Github repository.
The screenshot for displaying the search result in album view is provided below.
A vulnerability is a problem in a project’s code that could be exploited to damage the confidentiality, integrity, or availability of the project or other projects that use its code. Depending on the severity level and the way your project uses the dependency, vulnerabilities can cause a range of problems for your project or the people who use it.GitHub tracks public vulnerabilities in Ruby gems and NPM packages on MITRE’s Common Vulnerabilities and Exposures (CVE) List.
What were vulnerabilities in SUSPER ?
SUSPER was having vulnerability in Gemfile.lock,Gemfile.lock makes our application a single package of both your own code and the third-party code it ran the last time you know for sure that everything worked. Specifying exact versions of the third-party code you depend on in your Gemfile would not provide the same guarantee, because gems usually declare a range of versions for their dependencies.
What were vulnerable dependencies in Gemfile.lock ?
Two dependency namely Nokogiri and Yajl-Ruby were having security vulnerability.
Nokogiri is an HTML, XML, SAX, and Reader parser. Among Nokogiri’s many features is the ability to search documents via XPath or CSS3 selectors whereas
Yajl-Ruby gem is a C binding to the excellent YAJL JSON parsing and generation library. Older versions of both the dependencies were having security vulnerability.
Security alerts for a vulnerable dependency in our repository include a severity level and a link to the affected file in our project. When available, the alerts also include a link to the CVE record and a suggested fix.
What was the suggested fix ?
One way to fix this problem was to update the vulnerable dependencies to latest versions.
The versions of Nokogiri and Yajl-Ruby which were used in SUSPER are:
Nokogiri (~>1.5)
Yajl-Ruby (1.1.0)
What are the best ways to update dependencies without breaking
the project ?
The best way to update a dependency is to check where those dependencies are used in project and what are breaking changes which are introduced within the dependencies.
How vulnerable dependencies were updated ?
Firstly we updated the Bundler the tool we use to update our gems in Gemfile.lock,from version 1.13.6 to 1.16.0.
We then updated Nokogiri dependency and other sub dependencies using bundle update nokogirii.e:
mini_portile2 (2.1.0) -> mini_portile2 (2.3.0)
nokogiri (1.6.8.1) ->nokogiri (1.8.2)
Then we checked the project for integrity , and the project was working well.
We then tried to update Yajl-Ruby, but there was a problem in updating Yajl-Ruby,
We later found that Yajl-Ruby was replaced by many other dependencies.
We therefore updated whole Gemfile.lock . Following are two simple steps to update Gemfile.lock
bundle update
bundle install
We later checked that whether the new dependencies do not break the current project and we found that there were no breaking changes involved in updated dependencies.
Security alerts for vulnerable dependencies list the affected dependency and, in some cases, use machine learning to suggest a fix from the GitHub community. By default, we receive a weekly email summarizing security alerts for up to 10 of our repositories. We can choose to receive security alerts individually by email, in a daily digest email, in our web notifications, or in the GitHub user interface.
SUSPER is a search interface that uses P2P search engine YaCy . Search results are displayed using Solr server which is embedded into YaCy. The retrieval of search results is done using YaCy search API. When a search request is made in one of the search templates, an HTTP request is made to YaCy and the response is done in JSON. In this blog post I will show how to setup YaCy Grid locally.
What is YaCy Grid ?
The YaCy Grid is the second-generation implementation of YaCy, a peer-to-peer search engine. The required storage functions of the YaCy Grid are:
An asset storage, basically a file sharing environment for YaCy components,an ftp server is used for asset storage.
A message system providing an Enterprise Integration Framework using a message-oriented middleware,RabbitMQ message queues for the message system.
A database system providing search-engine related retrieval functions.It uses Elasticsearch for database operations.
How to setup YaCy Grid locally ?
YaCy Grid have 4 components MCP(Master Connect Program), Loader, Crawler and Parser.
Now to starting YaCy Grid requires starting Elasticsearch, RabbitMQ with Username `anonymous` and Password `yacy` and an ftp server(it can be omitted as MCP can take over).
All the above steps can also be done in a single step by running a python script in `bin` folder `run_all.py`
Checks whether Elasticsearch is running or not, if not then runs Elasticsearch.
if checkportopen(15672):
print "RabbitMQ is Running"
print "If you have configured it according to YaCy setup press N"
print "If you have not configured it according to YaCy setup or Do not know what to do press Y"
n=raw_input()
if(n=='Y'or n=='y'):
os.system('service rabbitmq-server stop')
ifnot checkportopen(15672):
print "rabbitmq is not running"
os.system('python bin/start_rabbitmq.py')
Checks whether RabbitMQ is running or not, if yes then asks user to configure it according to YaCy Grid setup by pressing Y or else ignore,if not then starts RabbitMQ according to required configuration.
subprocess.call('bin/update_all.sh')
.Updates all the Grid components including MCP.
ifnot checkportopen(2121):
print "ftp server is not Running"
Checks for an ftp server and prints message accordingly.
Runs all components of YaCy Grid in separate terminal.
Once user starts it, then he can start using YaCy Grid through terminal.
If a YaCy Grid service has used the MCP once, it learns from the MCP to connect to the infrastructure itself. For example:
a YaCy Grid service starts up and connects to the MCP
the Grid service pushes a message to the message queue using the MCP
the MCP fulfils the message send operation and response with the actual address of the message broker
the YaCy Grid service learns the direct connection information
whenever the YaCy Grid service wants to connect to the message broker again, it can do so using a direct broker connection. This process is done transparently, the Grid service does not need to handle such communication details itself. The routing is done automatically. To use the MCP inside other grid components the git submodule functionality is used.
This article illustrates how the Pages API has been designed and implemented on the server side, i.e., FOSSASIA‘s Open Event Server. Pages endpoint is used to create static pages such as “About Page” or any other page that doesn’t need to be updated frequently and only a specific content is to be shown.
Parameters
name – This stores the name of the page.
Type – String
Required – Yes
title – This stores the title of the page.
Type – String
Required – No
url – This stores the url of the page.
Type – String
Required – Yes
description – This stores the description of the page.
Type – String
Required – Yes
language – This stores the language of the page.
Type – String
Required – No
index – This stores the position of the page.
Type – Integer
Required – No
Default – 0
place – Location where the page will be placed.
Type – String
Required – No
Accepted Values – ‘footer’ and ‘event’
These are the allowed parameters for the endpoint.
Model
Lets see how we model this API. The ORM looks like this :
As you can see, we created a table called “pages”. This table has 8 columns, 7 of which are the parameters that I have mentioned above. The column “id” is an Integer column and is the primary key column. This will help to differentiate between the various entries in the table.
The visualisation for this table looks as follows :
API
We support the following operations:
GET all the pages in the database
POST create a new page
GET details of a single page as per id
PATCH a single page by id
DELETE a single page by id
To implement this we first add the routes in our python file as follows :
FOSSASIA‘s Open Event Frontend uses the Ember Models Table for rendering all its tables. This provides features like easy sorting, pagination etc. Another major feature is that it can be modified to meet our styling needs. As we use Semantic UI for styling, we added the required CSS classes to our table.
In version 1 this was done by overriding the classes, as shown below :
But in version 2, some major changes were introduced as follows:
All partials inside a models-table were replaced with components
models-table can now be used with block content
New themes mechanism introduced for styling
Here, I will talk about how the theming mechanism has been changed. As I mentioned above, in version 1 we used custom classes and icons. In version 2 the idea itself has changed. A new type called Theme was added. It provides four themes out of the box – SemanticUI, Bootstrap4, Bootstrap3, Default.
We can create our custom theme based on any of the predefined themes. To suit our requirements we decided to modify the SemanticUI theme. We created a separate file to keep our custom theme so that code remains clean and short.
The last three are same as customClasses and customIcons and customMessages in version 1. Components is the map for components used internally in the models-table. In case you need to use a custom component, that can be done as follows:
Make a new JavaScript file and provide its path in your theme file.
Now just create the theme file object and pass it to themeInstance in the ui-table file (can also be passed in the template and the controller, but this has to be done for each table individually).
Hence, version 2 introduces many new styling options and requires some refactoring for those who were using version 1. It is totally worth it though considering how easy and well managed it is now.
For a new comer in Loklak, it’s not really easy to understand the complete codebase to just get results for a query without explicitly using navigation route i.e. ‘/search’. In order to help newcomers to easily understand a simple way to get results for a query in the codebase, I am writing this blog post.
Setting up a query
A sample searchQuery will be created of type Query. And following discussion will provide a way to get the results for a sample query – ‘from:Fossasia’ (Last 30 days tweets from FOSSASIA).
Note: No need to import OnInit, if the class already implements it (OnInit is one of the Angular’s Lifecycle Hooks which controls the changes when the component containing it gets loaded initially).
The Query is used to define the type of searchQuery variable created above. And ApiResponseResult is the type of result which will be obtained on searching the searchQuery.
Declaring response variables and store object
Next step would be to declare the variables with the type of response and create store object of type Store with the current State of the application.
isSearching$ holds an Observable which can be subscribed to get a boolean value which states the current status of searching of query. apiResponseResults$ holds the actual response of query.
Dispatching a SearchAction
The most crucial part comes here to dispatch a SearchAction with the created searchQuery as payload. A new method would be created with void as return type to dispatch the SearchAction.
A new method would be created to store the current searching status along with the response of input query in isSearching$ and apiResponseResults$ respectively. Now the selector for the reducer function corresponding to the search and api response entities would be called.
Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.
Badgeyay frontend has many features like Login and Sign up features and Login with OAuth and the most important, the badge generation feature is also up and running but the important thing from the User’s perspective is to get notified of all the actions performed in the application so that user can proceed easily further after performing a specific action in the Application..
In this Blog, I will be discussing how I integrated ember-notify in Badgeyay frontend to notify user about the actions performed in my Pull Request.
Ember-notify displays a little notification message down the bottom of our application.
Let’s get started and understand it step by step.
Step 1:
This module is an ember-cli addon, so installation is easy:
npm install ember-notify --save-dev
Step 2:
Inject the notify service in the controller of the template. Here, I will showing how I added it in showing Log In and Logout messages and you can check the whole code in my Pull request for other controllers also.
// controllers/login.js import Ember from 'ember';
import Controller from '@ember/controller';
const { inject } = Ember;
exportdefault Controller.extend({
session : inject.service(),
notify : inject.service('notify'),
..........
this_.transitionToRoute('/');
this_.get('notify').success('Log In Successful');
}).catch(function(err) {
console.log(err.message);
this_.get('notify').error('Log In Failed ! Please try again');
});
............
this_.transitionToRoute('/');
this_.get('notify').success('Log In Successful');
})
.catch(err => {
console.log(err);
});
}).catch(function(err) {
console.log(err.message);
this_.get('notify').error('Log In Failed ! Please try again');
});
..........
// controllers/logout.jsimport Ember from 'ember';
import Controller from '@ember/controller';
const { inject } = Ember;
exportdefault Controller.extend({
session : inject.service(),
notify : inject.service('notify'),
beforeModel() {
returnthis.get('session').fetch().catch(function() {});
},
actions: {
logOut() {
this.get('session').close();
this.transitionToRoute('/');
this.get('notify').warning('Log Out Successful');
}
}
});
I have implemented ember-notify for Logging In and Out feature & in the similar way I have implemented it for other controllers and complete code can be seen in my Pull Request.
Step 3::
Now run the server to see the implemented changes by following command.
$ ember serve
Navigate to localhost and perform login and logout actions to see the changes.
Successful Log In
Successful Log out
Successful CSV Upload
Now, we are done with the integration of ember-notify in Badgeyay frontend to notify user about the actions performed in the Application.
You must be logged in to post a comment.