Adding Filters for Lists of Skills on the SUSI.AI Server

In this blog post, we will learn how to add filters to the API responsible for fetching the list of skills i.e. the endpoint - https://api.susi.ai/cms/getSkillList.json. The purpose of adding filters is to return a list of skills based on some parameters associated with the skill, that would be required to allow the user to get the desired response that s/he may be using to display it on the UI. Overview of the API API to fetch the list of skills - URL -  https://api.susi.ai/cms/getSkillList.json It takes 5 optional parameters - model - It is the name of the model that user is requesting group - It is the name of the group that user is requesting language - It is the name of the language that user is requesting skill - It is the name of the skill that user is requesting applyFilter - It has true/false values, depending whether filtering is required If the request URL contains the parameter applyFilter as true, in that case the other 2 compulsory parameters are - filter_name - ascending/descending, depending upon the type of sorting the user wants filter_type - lexicographical, rating, etc based on what basis the filtering is going to happen So, we will now look into adding a new filter_type to the API. Detailed explanation of the implementation We can add filters based on the key values of the Metadata object of individual skills. The Metadata object for each skill is similar to the following object - { "model": "general", "group": "Knowledge", "language": "en", "developer_privacy_policy": null, "descriptions": "A skill that returns the anagrams for a word", "image": "images/anagrams.jpg", "author": "vivek iyer", "author_url": "https://github.com/Remorax", "author_email": null, "skill_name": "Anagrams", "protected": false, "terms_of_use": null, "dynamic_content": true, "examples": ["Anagram for best"], "skill_rating": { "negative": "0", "positive": "0", "stars": { "one_star": 0, "four_star": 0, "five_star": 0, "total_star": 0, "three_star": 0, "avg_star": 0, "two_star": 0 }, "feedback_count": 0 }, "creationTime": "2017-12-17T14:32:15Z", "lastAccessTime": "2018-06-19T17:50:01Z", "lastModifiedTime": "2017-12-17T14:32:15Z" }   We will now add provision for URL parameter, filter_type=feedback in the API, which will filter the results based on the feedback_count key, which tells the number of feedback/comments a skill has received. In the serviceImpl method of the ListSkillService class, we can see a code snippet that handles the filtering part, It checks the filter_type parameter received in the URL on if-else block. The code snippet looks like this - if (filter_type.equals("date")) { . . } else if (filter_type.equals("lexicographical")) { . . } else if (filter_type.equals("rating")) { . . }   Similarly, we will need to add an else if condition with feedback_type=feedback and write the code block inside it. Here is the code for it, which is explained in detail. . . else if (filter_type.equals("feedback")) { if (filter_name.equals("ascending")) { Collections.sort(jsonValues, new Comparator<JSONObject>() { @Override public int compare(JSONObject a, JSONObject b) { Integer valA; Integer valB; int result=0; try { valA = a.getJSONObject("skill_rating").getInt("feedback_count"); valB = b.getJSONObject("skill_rating").getInt("feedback_count"); result = Integer.compare(valA, valB); } catch (JSONException e) { e.printStackTrace(); } return result; } }); } else { Collections.sort(jsonValues, new Comparator<JSONObject>() {…

Continue ReadingAdding Filters for Lists of Skills on the SUSI.AI Server

Showing only Logged-in Accounts in the Sharing Page of Phimpme Android

In Phimpme Android application, users can edit their pictures and share them to a number of platforms ranging from social networking sites like Facebook, Twitter etc to cloud storage and image hosting sites like Box, Dropbox, Imgur etc. Desired flow of the application According to the flow of the application, the user has to add an account first i.e. log in to the particular account that needs to be connected to the application. After that when the user enters the share page for sharing the image, a button corresponding to the connected account is visible in that page which on clicking will share the image to that platform directly. What was happening previously? The list of accounts which is present in the account manager of Phimpme Android application is also getting displayed in the share image page. As the list is large, it is difficult for the user to find the connected account from the list. There is not even an indicator whether a particular account is connected or not. On clicking the button corresponding to the non-connected account, an error dialog instructing the user to log in from the account manager first, will get displayed. How we solved it? We first thought of just adding an indicator on the buttons in the accounts page to show whether it is connected or not. But this fix solves only a single issue. Find the connected account in that large list will be difficult for the user even then. So we decided to remove the whole list and show only the accounts which are connected previously in account manager. This cleans the flow of the accounts and share in  Phimpme Android application When a user logins from the account manager, the credentials, tokens and other details corresponding to that accounts gets saved in database. We used realm database for saving the details in our application. As the details are present in this database, the list can be dynamically generated when the user opens share image page. We implemented a function in Utils class for getting the list of logged in accounts. Its implementation is shown below. public static boolean checkAlreadyExist(AccountDatabase.AccountName s) {   Realm realm = Realm.getDefaultInstance();   RealmQuery<AccountDatabase> query = realm.where(AccountDatabase.class);   query.equalTo("name", s.toString());   RealmResults<AccountDatabase> result1 = query.findAll();   return (result1.size() > 0); } public static ArrayList<AccountDatabase.AccountName> getLoggedInAccountsList(){   ArrayList<AccountDatabase.AccountName> list = new ArrayList<>();   for (AccountDatabase.AccountName account : AccountDatabase.AccountName.values()){       if (checkAlreadyExist(account))           list.add(account);   }   return list; } Additional changes There are few accounts which don’t need authentication. Those accounts need their respective application to be installed in the user’s device. So for adding those accounts to the list, we added another function which checks whether a particular package is installed in user’s device or not. Using that it adds the account to the list. The implementation for checking whether a package is installed or not is shown below. public static boolean isAppInstalled(String packageName, PackageManager pm) {   boolean installed;   try {       pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);       installed = true;   } catch (PackageManager.NameNotFoundException e) {       installed = false;   }   return installed; }…

Continue ReadingShowing only Logged-in Accounts in the Sharing Page of Phimpme Android