Creating Middle Section of Listing Page for loklak Apps Store

The Loklak applications website that is apps.loklak.org now has a fully functional store listing page where users and developers can find various information about the app they have selected including information about getting started with the app, use of the app and other relevant information. Developers can showcase their apps and promote their apps with promo image and preview images. Before beginning with the actual topic let me provide a brief overview of the various components on the page. The page consists of a left sidebar which contains various categories for app filtering. There is a right column showing suggested apps so that users can easily view apps which are similar to the one they have chosen. Finally there is a middle section containing app promo image, app title, short description, author’s name, a carousel showing preview images, a getting started section, an app use section and an other relevant information section and finally some additional information. The main feature and requirement of the middle section is that it needs to be dynamic, that is, it should dynamically show information for a given selected app. No content should be hardcoded. Now apps.loklak.org is entirely a front end project, there is no centralised data base from where the content can be loaded. How to solve this problem? From where to get the data related to each app. Well, here comes in the app.json file present in each app. Each application present on apps.loklak.org contains an app.json file which contains some metadata about the apps. Now the app.json can be modified by the developer of the app to contain relevant information and references to assets which will be used for app store listing. Getting started with the middle section page At first, let us have a look at a sample app.json file. { "@context":"http://schema.org", "@type":"SoftwareApplication", "permissions":"/api/search.json", "name":"sentimentVisualizer", "headline":"Sentiment Visualizer", "alternativeHeadline":"Tool for visualizing the sentiment of a tweet", "applicationCategory":"Visualizer", "applicationSubCategory":"Text Retrieval", "operatingSystem":"http://loklak.org", "promoImage":"promo.png", "appImages":["disp1.png", "disp2.png", "disp3.png"], "getStarted":"getStarted.md", "appUse":"appUse.md", "oneLineDescription":"Application to visualise sentiment related to tweets", "appSource": "https://github.com/fossasia/apps.loklak.org/tree/master/sentimentVisualizer", "contributors": [{"name": "Damini Satya", "url": "https://github.com/daminisatya"}], "techStack": ["HTML", "CSS", "AngularJs", "Bootstrap", "Loklak API"], "license": {"name": "LGPL 2.1", "url": "https://www.gnu.org/licenses/old-licenses/lgpl-2.1"}, "version": "1.0", "updated": "June 14,2017", "author":{ "@type":"Person", "name":"Damini Satya", "email":"daminisatya@gmail.com", "url":"https://github.com/daminisatya", "sameAs":"https://github.com/daminisatya" } } Each of the apps must have an app.json like the above one. As it can be seen, it contains all the necessary information for sore listing, like app name, version, oneLineDescription, etc. It also contains paths to important assets. Before proceeding we need to know the name of the app which has been selected. This is obtained from the url as shown below. var addr = window.location + ""; if (addr.indexOf("?") !== -1) { $scope.appName = addr.split("?")[1].split("=")[1]; } Once we get the app name, next thing which we need to do is load the contents of app.json. This is done using AngularJs’s http service. $http.get($scope.appName + "/app.json").success(function (data) { $scope.appData = data; $scope.setupCarousel(); $scope.getStarted(); $scope.appUse(); $scope.others(); }); A http ajax call is made to app.json of the corresponding app and the entire data…

Continue ReadingCreating Middle Section of Listing Page for loklak Apps Store

Creating a store listing page for Loklak Apps Store

The various apps built with the loklak api is presently hosted at apps.loklak.org. On visiting the site, the users are presented with an app wall from where users can select any app and the user will be taken to the live version of the app. However there is no store listing page available like other app sites (for ex. Google playstore) where information about the app like how to use the app, what the app does, getting started with the app can be found. The first part of my GSOC project is to create such an app store listing page where users/developers can find  all relevant information about the selected app. Proposed design of the store listing page The store listing page will be designed in three column format. There will be a left sidebar which will contain a list of categories for navigation, the category to which the selected app belongs will be highlighted. There will be a right side bar which will contain a list of similar apps for suggestion. The middle section will contain all the necessary information about the selected application, promo image and app preview images. Apart from this the page will contain a navbar for basic navigation. Getting started with the store listing page implementation Let's get started with the left sidebar. Target is to make the entire page as dynamic as possible. Minimum information will be hard coded in html  and js code. Maximum data will be fetched from external json files using ajax requests. In this way if we need to make any change to data, it can be done by simply changing the data in the json files, the html and js code can be left intact. First the store listing page has to know which app has been selected by the user. For this the app name is sent as an url parameter to the store listing page. The store listing page itself will have url like this http://apps.loklak.org/details.html?q=<app_name>. From here we can easily get the app name as shown below. var addr = window.location + ""; if (addr.indexOf("?") !== -1) { $scope.appName = addr.split("?")[1].split("=")[1]; } The category names, icon, and color are loaded from apps.json file. The apps.json file is one of the most important files in the repository which manages app and site meta data. It contains list of category objects each of which contains category name, category style and category icon reference. $http.get('apps.json').success(function (data) { $scope.categories = data.categories; $scope.apps = data.apps; $scope.categories.unshift({"name": "All","image":"all.png","style" : {"background-color": "#ED3B3B"}}); $scope.getSelectedApp(); $scope.getSimilarApps(); }); Using the above code we get all the categories and apps and bind them with the scope variable so that we can access them from the corresponding HTML. Next we need to actually setup the UI for the sidebar using the data we have acquired. Well here comes in AngularJs’s one of the most useful feature - two way data binding. Using two way data binding we can easily access the category list from HTML code, iterate over…

Continue ReadingCreating a store listing page for Loklak Apps Store

Creating a Script to Review loklak Apps

The Loklak applications site now has a functional store listing page where developers can showcase their apps and users and other developers can get all sorts of information about an app. However, for an app to be showcased properly on store listing page, the app must contain a properly configured app.json file and some necessary assets. But while creating an app a developer might miss out some vital information from app.json or forget to provide some of the required assets, which he will later come to know from his co-developers or reviewers. Now this will cause inconvenience, both for the developer and reviewer. So to overcome this apps.loklak.org has now got a new script to review a given app. It checks whether the necessary fields are present in app.json or not. If present then it checks whether the fields are empty or not. If any invalid or missing information problem is encountered then it is reported to the developer along with information on what should be the actual case. If the app passes all the checks then the developer is informed that his app is ready to be published. In order to use this script all the developer needs to do is open his app directory in terminal and execute the following command ../bin/review.sh This will present the developer with all the necessary informations. How the script works? Now let us delve into the working of the script. The initial call to the shell script review.sh calls a python script review.py. This python script performs all the checks on the app and displays necessary informations. The first thing the script does is, it checks whether there is an app.json present in the app directory or not, if yes then the process continues otherwise it ends immediately with an error. if "app.json" not in dir_contents: print_info("Please include a well configured app.json") print_problem("review failed") exit(0) Next it performs one of the most important checks. It verifies whether the name of the app and app directory name is same or not. If it is same then there is no problem else it shows the corresponding error message. app_dir_name = os.getcwd().split("/")[-1] if app_dir_name != app_json.get("name"): print_problem("app directory name and name mentioned in app.json are different") print_info("app directory name and name mentioned in app.json must be same") problems_no += 1 Next the script checks whether there is an index.html present or not. Index.html is a must as it serves as the entry point of the app. if "index.html" not in dir_contents: print_problem("index.html is missing") print_info("app must contain index.html") problems_no += 1 After this the script checks whether a number of key fields are present or not. These field includes applicationCategory, oneLineDescription, author. If they are present, it checks whether the fields are empty or not. If the fields are either absent or empty, error is shown to the developer. if app_json.get("applicationCategory") == None: print_problem("key applicationCategory missing in app.json") print_info("app.json must contain key applicationCategory with category as value") problems_no += 1 else: if app_json.get("applicationCategory") == "":…

Continue ReadingCreating a Script to Review loklak Apps

Creating a command line tool to initiate loklak app development

There are various apps presently hosted on apps.loklak.org, which shows several interesting and awesome stuff that can be done using the loklak API. Now the question is how to create a loklak app? Well previously there were two ways to create a loklak app, you could either create an app from scratch creating all the necessary files including index.html (app entry point), app.json (required for maintaining app metadata and store listing), getStarted.md, appUse.md and other necessary files, or you could use the boilerplate app which provides you with a ready to go app template which you have to edit to create your app. Recently there has been a new addition to the repository, a command line tool called loklakinit, built with python which will automate the process of initiating a loklak app on the go. The tool creates the entire loklak app directory structure including app.json with all the necessary details (as provided by the user) and defaults, index.html, a css and js subdirectory with a style.css and script.js in the respective folders, getStarted.md file, appUse.md file and others.md file with proper references in app.json. All that the developer needs to do is, execute the following from the root of the apps.loklak.org repository. bin/loklakinit.sh This will start the process and initiate the app. Creating loklakinit tool Now let us delve into the code. So what actually the script does? How it works? Well the tool acts very much like the popular npm init command. At first the script creates a dictionary which stores the defaults for app.json. Next the script takes a number of inputs from the user and predicts some default values, if the user refuses to provide any input for a particular parameter then the default value for that parameter is used. app_json = collections.OrderedDict() app_json["@context"] = "http://schema.org" app_json["@type"] = "SoftwareApplication" app_json["permissions"] = "/api/search.json" app_json["name"] = "myloklakapp" app_json["headline"] = "My first loklak app" app_json["alternativeHeadline"] = app_json["headline"] app_json["applicationCategory"] = "Misc" app_json["applicationSubCategory"] = "" app_json["operatingSystem"] = "http://loklak.org" app_json["promoImage"] = "promo.png" app_json["appImages"] = "" app_json["oneLineDescription"] = "" app_json["getStarted"] = "getStarted.md" app_json["appUse"] = "appUse.md" app_json["others"] = "others.md" author = collections.OrderedDict() author["@type"] = "Person" author["name"] = "" author["email"] = "" author["url"] = "" author["sameAs"] = "" app_json["author"] = author The first part of the script inserts some default values into the app_json dictionary. Now what is an OrderedDict? Well, it is nothing but a python dictionary in which the order in which the keys are inserted is maintained. A ordinary python dictionary does not maintain the order of the keys. while True : app_name = raw_input("name (" + app_json["name"] + ") : ") if app_name : app_json["name"] = app_name app_context = raw_input("@context (" + app_json["@context"] + ") : ") if app_context : app_json["@context"] = app_context app_type = raw_input("@type (" + app_json["@type"] + ") : ") if app_type : app_json["@type"] = app_type app_permissions = raw_input("permissions (" + app_json["permissions"] + ") : ") if app_permissions : app_json["permissions"] = app_permissions.split(",") app_headline = raw_input("headline (" + app_json["headline"] + ") : ") if app_headline : app_json["headline"] = app_headline…

Continue ReadingCreating a command line tool to initiate loklak app development

Enhancing Github profile scraper service in loklak

The Github profile scraper is one of the several scrapers present in the loklak project, some of the other scrapers being Quora profile scraper, Wordpress profile scraper, Instagram profile scraper, etc.Github profile scraper scrapes the profile of a given github user and provides the data in json format. The scraped data contains user_id, followers, users following the given user, starred repositories of an user, basic information like user’s name, bio and much more. It uses the popular Java Jsoup library for scraping. The entire source code for the scraper can be found here. Changes made The scraper previously provided very limited information like, name of the user, description, starred repository url, followers url, following url, user_id, etc. One of the major problem was the api accepted only the profile name as a parameter and it returned the entire data, that is, the scraper scraped all the data even if the user did not ask for it. Moreover the service provided certain urls as data for example starred repository url, followers url, following url instead of providing the actual data present at those urls. The scraper contained only one big function where all the scraping was performed. The code was not modular. The scraper has been enhanced in the ways mentioned below. The entire code has been refactored.Code scraping user specific data has been separated from code scraping organization specific data. Also separate method has been created for accessing the Github API. Apart from profile parameter, the api now accepts another parameter called terms. It is a list of fields the user wants information on. In this way the scraper scrapes only that much data which is required by the user. This allows better response time and prevents unnecessary scraping. The scraper now provides more information like user gists, subscriptions, events, received_events and repositories. Code refactoring The code has been refactored to smaller methods. ‘getDataFromApi’ method has been designed to access Github API. All the other methods which want to make request to api.github.com/ now calls ‘getDatFromApi’ method with required parameter. The method is shown below. private static JSONArray getDataFromApi(String url) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e1) { e1.printStackTrace(); } JSONTokener tokener = null; try { tokener = new JSONTokener(uri.toURL().openStream()); } catch (Exception e1) { e1.printStackTrace(); } JSONArray arr = new JSONArray(tokener); return arr; }   For example if we want to make a request to the endpoint https://api.github.com/users/djmgit/followers then we can use the above method and we will get a JSONArray in return. All the code which scrapes user related data has been moved to ‘scrapeGithubUser’ method. This method scrapes basic user information like full name of the user, bio, user name, atom feed link, and location. String fullName = html.getElementsByAttributeValueContaining("class", "vcard-fullname").text(); githubProfile.put("full_name", fullName); String userName = html.getElementsByAttributeValueContaining("class", "vcard-username").text(); githubProfile.put("user_name", userName); String bio = html.getElementsByAttributeValueContaining("class", "user-profile-bio").text(); githubProfile.put("bio", bio); String atomFeedLink = html.getElementsByAttributeValueContaining("type", "application/atom+xml").attr("href"); githubProfile.put("atom_feed_link", "https://github.com" + atomFeedLink); String worksFor = html.getElementsByAttributeValueContaining("itemprop", "worksFor").text(); githubProfile.put("works_for", worksFor); String homeLocation = html.getElementsByAttributeValueContaining("itemprop", "homeLocation").attr("title"); githubProfile.put("home_location", homeLocation);…

Continue ReadingEnhancing Github profile scraper service in loklak

Displaying error notifications in whatsTrending? app

The issue I am solving in the whatsTrending app is to display error notifications when the date fields and the count field are not validated and when a user enters invalid data. Specifically we want to display error notifications for junk values and dates with formats other than YYYY-MM-DD and any other invalid data in the whatsTrending app’s filter option. The whatsTrending app is a web app that shows the top trending hashtags of twitter messages in a given date range using tweets collected by the loklak search engine. Users can also limit the number of top hash tags they want to see and use filters with start and end dates. What is the problem? The date fields and the count field are not validated which means junk values and date with formats other than YYYY-MM-DD do not show any error. So how can the problem be solved? Well the format (pattern) of the date can be verified by regular expression. A regular expression describes a pattern in a given text.So the format checking problem can be described as finding the pattern YYYY-MM-DD in the input date where Y, M and D are numbers.The Regex should specify that the pattern should be present at the beginning of the text. More detailed information about regex can be found here. The regex for this pattern is : /^\d{4}-\d{2}-\d{2}$/ The pattern says there should be 4 numbers followed by ‘-’ then two numbers then again ‘-’ and then again two numbers. This can be implemented the following way : $scope.isValidDate = function(dateString) { var regEx = /^\d{4}-\d{2}-\d{2}$/; if (dateString.match(regEx) === null) { return false; } dateComp = dateString.split('-'); var i=0; for (i=0; i<dateComp.length; i++) { dateComp[i] = parseInt(dateComp[i]); } if (dateComp.length > 3) { return false; } if (dateComp[1] > 12 || dateComp[1] <= 0) { return false; } if (dateComp[2] > 31 || dateComp[2] <= 0) { return false; } if (((dateComp[1] === 4) || (dateComp[1] === 6) || (dateComp[1] === 9) || (dateComp[1] === 11)) && (dateComp[2] > 30)) { return false; } if (dateComp[1] ===2) { if (((dateComp[0] % 4 === 0) && (dateComp[0] % 100 !== 0)) || (dateComp[0] % 400 === 0)) { if (dateComp[2] > 29) { return false; } } else { if (dateComp[2] > 28) { return false; } } } return true; } So the first part of the code checks for the above mentioned pattern in the input. If not found it returns false.If found then we split the entire date into a list containing year, month and day and the remaining part if any is removed.Each component is converted to integer.Then further validation is done on the month and day as can be seen from the code above.The range of the month and date is checked.Also leap year checking is done. In the same way the count field is also validated. The regex for this field is much simpler. We just need to check that the input consists only of numbers and…

Continue ReadingDisplaying error notifications in whatsTrending? app