Setting up Codecov in Badgeyay

 

BadgeYaY already has Travis CI and Codacy to test code quality and Pull Request but there was no support for testing Code Coverage in repository against every Pull Request. So I decided to go with setting up Codecov to test the code coverage.

In this blog post, I’ll be discussing how I have set up codecov in BadgeYaY in my Pull Request.

First, let’s understand what is codecov and why do we need it. For that we have to first understand what is code coverage then we will move on to how to add Codecov with help of Travis CI .

Let’s get started and understand it step by step.

What is Code Coverage ?

Code coverage is a measurement used to express which lines of code were executed by a test suite. We use three primary terms to describe each lines executed.

  • hit indicates that the source code was executed by the test suite.
  • partial indicates that the source code was not fully executed by the test suite; there are remaining branches that were not executed.
  • miss indicates that the source code was not executed by the test suite.

Coverage is the ratio of hits / (hit + partial + miss). A code base that has 5 lines executed by tests out of 12 total lines will receive a coverage ratio of 41% . In BadgeYaY , Code Coverage is 100%.

How CodeCov helps in Code Coverage ?

Codecov focuses on integration and promoting healthy pull requests. Codecov delivers <<<or “injects”>>> coverage metrics directly into the modern workflow to promote more code coverage, especially in pull requests where new features and bug fixes commonly occur.

I am listing down top 5 Codecov Features:

We can change the configuration of how Codecov processes reports and expresses coverage information. Let’s see how we configure it according to BadgeYaY by integrating it with Travis CI.

Now generally, the codecov works better with Travis CI. With the one line

 bash <(curl -s https://codecov.io/bash)

 

the code coverage can now be easily reported.

Add a script for testing:

"scripts": {
   - nosetests app/tests/test.py -v --with-coverage
}

Here is a particular example of travis.yml from the project repository of BadgeYaY:

Script:
- python app/main.py >> log.txt 2>&1  &
- nosetts app/tests/test.py -v --with-coverage
- python3 -m pyflakes

after_success:
- bash <(curl -s https://codecov.io/bash)

 

Let’s have a look at Codecov.yml to check exact configuration that I have used for BadgeYaY.

Codecov:
  # yes: will delay sending notifications until all ci is finished
  notify:
    require_ci_to_pass: yes

coverage:
  # how many decimal places to display in the UI: 0 <= value <= 4
  precision: 2
  # how coverage is rounded: down/up/nearest
  round: down 
  # custom range of coverage colors from red -> yellow -> green 
  range: "70...100"

  status:
     # measuring the overall project coverage
    project: yes
     # pull requests only: this commit status will measure the
       entire pull requests Coverage Diff. Checking if the lines
       adjusted are covered at least X%.
    patch: yes
     # if there are any unexpected changes in coverage
    changes: no

Comment:

  layout: "reach, diff, flags, files, footer"
  behavior: default
  require_changes: no

 

Now when anyone makes a Pull Request to BadgeYaY, Codecov will analyze the Pull Request according to above configuration and generate a Report showing the code coverage of that Pull Request.

 

Below is the screenshot of all test passing in BadgeYaY repository

This is how we setup codecov in BadgeYaY repository. And like this way, it can be set up in other repositories as well.

The related PR of this work is https://github.com/fossasia/badgeyay/pull/400

Resources :

  • CodeCov Documentation – Link
Continue ReadingSetting up Codecov in Badgeyay

FOSSASIA Summit 2018 Highlights

The schedule for the FOSSASIA Summit is out. Our four-day open tech event starts on Thursday, March 22 with a grand opening of the exhibition at 12:00 PM and the conference at 1:00 PM in the Lifelong Learning Institute.

Developers, engineers and business representatives from FOSS projects and companies are joining the event. Thank you to Google Cloud, Daimler, Indeed, Microsoft, JPMorgan and the many partners and supporters for helping us to make the summit possible!

As a reader of FOSSASIA news you get a 15% discount on your ticket if you book before March 14 (after that 10%) with this link.

Here are some highlights of the event and a glance at participating FOSS projects, organizations and companies.

Highlights of the FOSSASIA Summit 2018

  • 200+ Tech Speakers in 12 Tracks are confirmed. Learn about latest technologies and Open Source business models in the Blockchain track, find out how to analyze data more efficiently in the Artificial Intelligence track or see how to deploy solutions with Kubernetes in the Cloud from engineers at leading cloud providers.
  • Executive Keynotes about “Daimler’s Open Source Strategy”, and “Machine Learning with TensorFlow and Cloud ML”
  • Leadership Panels about “AI, Machine Learning, Cloud, and the Conversational Web: Where is it all going?”, “Making Money with FOSS” and “Open Source Education”
  • The Exhibition and Career Fair runs from Thursday (March 22) till Saturday (March 24) with more than 50 company and project booths, where you can learn about technologies, job opportunities and participate in hands-on labs. Free hall passes are available until March 14.
  • The UNESCO Open Science and Open Data Hackathon takes place on Saturday and Sunday (March 24/25). Tickets and registration are free. Awesome prizes are waiting for the winners.
  • We put together a Cloud Training Day for Business Professionals in cooperation with Google. Apply for your spot here.
  • At the Young Developers Day on Saturday (March 24) there are many hands-on workshops in the exhibition hall, where participants of any age can build their own hardware and experiment with our Pocket Science Lab.
  • Vast variety of Deep Tech Sessions in tracks such as Artificial Intelligence,  Cloud, Container, DevOps, Blockchain, Cybersecurity, Web and Mobile, Open Design, IoT, Hardware, Imaging, Kernel & Platform,  Science Tech and Education and more.

FOSS Organizations at the FOSSASIA Summit

Speakers at the event come from amazing Free/Open Source organizations and projects like Debian, CentOS, FreeBSD, Videolan/VLC, Linux Foundation, Open Source Initiative, Python Software Foundation, Wikimedia, KDE, Apache Software Foundation, Open Source Design, Drupal, OpenTech, Ethical Hacking Club, Pocket Science Lab, Oman FOSS Initiative, LikeCoin Foundation and many more.

Companies at the FOSSASIA Summit

Tech Companies present at the event are Daimler/Mercedes, Google, Microsoft, Samsung, Singapore Press Holding, J.P. Morgan, Indeed, UNESCO, Oracle/MySQL, Gandi.net, Lazada, Viseo, Grab, SUSI.AI, BareOS, Platform.sh, Ulicious, SAP, Thoughtworks, Autodesk, KPMG, VMWare, Lionsforge, Fujitsu, Zendesk, McKinsey, Iomedia, IBM, Collabora, Manulife, Tata Consultancy Services and many startups like KyberNetwork, DataKind, Ethereum, Kamailio, Go-Jek, Canaan, StopStalk, ConsenSys, Chibitronics, Status.im, Attores and many others.

Continue ReadingFOSSASIA Summit 2018 Highlights

UNESCO Hackathon at FOSSASIA Summit in Singapore

Join the UNESCO Open Data Hackathon at the FOSSASIA Summit, create open source apps and games that tackle climate change, environment and sustainable development challenges, and win awesome prizes! The hackathon takes place from Saturday 24 March to Sunday 25 March 2018 at the Lifelong Learning Institute in Singapore.

We are specifically interested in applications and games that set an example for others who could replicate solutions in other countries, and in particular in the Mekong countries, to tackle the sustainable development challenges. It is our goal to engage the developer community to develop innovative applications in open source by leveraging the open data and knowledge available.

We are inviting developers, designers, open source contributors, bloggers, journalists and all FOSSASIA community members to be part of the UNESCO Hackathon. We are especially encouraging applications from the Mekong region to join the contest. The hackathon is open for all and awesome prizes are waiting for you!

For participants from outside of Singapore we have the possibility to host them in a Singapore hostel. Please apply here. The number is limited. UNESCO encourages the application of women and girls.

How do I sign up?

1. Get your ticket to the Event on eventyay.com.

2. Sign up on Devpost.

3. Join the Gitter channel at https://gitter.im/fossasia/hackathon (requires login with Github).

4. Find team members and create your team preferably at least 3 members and maximum 5 contributors. You are also welcome to sign up and then wait until the Presentation of Ideas on Saturday before deciding to join a team, however we’d encourage you to form/join a team in advance if you already have an idea that you’d like to work on.

5. Join the event at the Lifelong Learning Institute on Saturday, March 24 at the opening at 2.00 pm until 10.00 pm and on Sunday, March 25 from 9.00 am until 5.00 pm.

Visit the website at unesco.sciencehack.asia and stay connected, join the event on Facebook and Meetup and follow FOSSASIA on Twitter.

UNESCO Hackathon Schedule

Hackathon Opening: March 24, 2018

12.00 Registration Opens
14:00 Opening
14.10 Intro of Background, Rules and Prizes
14:20 Presentation of Ideas, Teams and Team Building Activities
15:00 Begin of Hacking Activities
19.30 Dinner
22:00 Closing of Space

Hackday: March 25, 2018

08:00 – 09:00 Breakfast
09:00 – 13:00 Hack Activities Continue
13:00 – 13:30 Lunch
13:30 – 15:00 Hacking Continues
14:00 Submission Form Closes
15:15 – 16:00 Presentation of Outcome
16:00 Judges Withdraw for Consultation
16:30 Award Announcement and Ceremony
17:00 Summit Closing

Location/Venue

Lifelong Learning Institute

Address: 11 Eunos Road 8, Singapore 408601

Prizes

Prizes are awarded for three teams, and each team prize with a value of 1000 SGD. Win cool gear, hardware, raspis, Arduinos and more!

Project Submission Requirements

For the expected outcome of the hack, the applications or games shall be open source and use open data to tackle the climate change, environment and sustainable development challenges.

They shall address one or several of the following requirements:

  1. Respond to pressing environmental challenges at local, national or regional levels in Asia

  2. Enable the visualization of data in an innovative and/or easy-to-understand way

  3. Mobilize and create engagement of variety of stakeholders and sectors in society on climate change, environment and sustainable development

  4. Gender-sensitive prototype, recognizing or encouraging women’s participation in sustainable development

Functioning App

An important point is, is the prototype or showcase functioning? We prefer real code and design implementations over mockups.

What to enter

Please submit a link to the app, a Github repo link and a short presentation as a download or on Google drive (ensure it is set to public sharing). You can also share anything else to demonstrate your work and let us test it.

  • Video: The platform accepts links to YouTube, Vimeo or Youku. If you like you can post a short video to demonstrate your work.

  • File Upload: There is also an option to upload a file. The platform allows submitters to upload one file, though they can combine files into a single ZIP file.

  • Other: The platform requires contestants to enter an entry name and description. Please also accept the the conditions of the contest including sharing your work under certified Open Source license.

Platform

Share information about what operating systems or devices can your hack run on.

Ressources

Include information about API, SDK, or data set, that are required to run the app.

New vs. Existing

Any work done need to be new for the competition. Existing apps are not eligible. However the specific details what is acceptable and what is not will be determined by the jury. For example existing apps that have been modified substantially and include entirely new functionality would still be eligible.

Submission Rights & Display

The submissions should be Open Source and licensed under a compliant Open Source/Free Software license. They should be upload to a Github repository.

We also request the right to use the winners’ names and work to promote the competition and hackathons in future.

Links

UNESCO Hackathon: https://unesco.sciencehack.asia

FOSSASIA Summit: https://2018.fossasia.org

Tickets: https://eventyay.com/e/db15e7db/

Project Signup: https://fossasia-unesco.devpost.com

Facebook: https://www.facebook.com/events/139329623548116/

Meetup: https://www.meetup.com/FOSSASIA-Singapore-Open-Technology-Meetup/events/247899257/

FOSSASIA: https://twitter.com/fossasia

List of Open Data Resources in Asia

Data portals across Asia: http://dataportals.org
China: http://opendatachina.com
Singapore http://data.gov.sg
Indonesia: https://petabencana.id/map/jakarta
Cambodia: https://opendevelopmentcambodia.net
Thailand https://data.go.th, http://catalog.opendata.in.th
Vietnam: https://vietnam.opendevelopmentmekong.net/data/
World Bank: https://data.worldbank.org
India http://data.gov.in

Continue ReadingUNESCO Hackathon at FOSSASIA Summit in Singapore

Maintaining Extension State in SUSI.AI Chrome Bot Using Chrome Storage API

SUSI Chrome Bot is a browser action chrome extension which is used to communicate with SUSI AI.The browser action extension in chrome is like any other web app that you visit. It will store all your preferences like theme settings and speech synthesis settings and data till you are interacting with it, but once you close it, it forgets all of your data unless you are saving it in some database or you are using cookies for the session. We want to be able to save the chats and other preferences like theme settings the user makes when interacting with SUSI AI through Susi Chrome Bot. In this blog, we’ll explore Chrome’s chrome.storage API for storing data.

What options do we have for storing data offline?

IndexedDB: IndexedDB is a low-level API for client-side storage of data. IndexedDB allows us to store a large amount of data and works like RDBMS but IndexedDB is javascript based Object-oriented database.

localStorage API: localStorage allows us to store data in key/value pairs which is much more effective than storing data in cookies. localStorage data persists even if the user closes and reopens the browser.

Chrome.storage: Chrome provides us with chrome.storage. It provides the same storage capabilities as localStorage API with some advantages.

For susi_chromebot we will use chrome.storage because of the following advantages it has over the localstorage API:

  1. User data can be automatically synced with Chrome sync if the user is logged in.
  2. The extension’s content scripts can directly access user data without the need for a background page.
  3. A user’s extension settings can be persisted even when using incognito mode.
  4. It’s asynchronous so bulk read and write operations are faster than the serial and blocking localStorage API.
  5. User data can be stored as objects whereas the localStorage API stores data in strings.

Integrating chrome.storage to susi_chromebot for storing chat data

To use chrome.storage we first need to declare the necessary permission in the extension’s manifest file. Add “storage” in the permissions key inside the manifest file.

"permissions": [
         "storage"
       ]

 

We want to store the chat user has made with SUSI. We will use a Javascript object to store the chat data.

var storageObj = {
senderClass: "",
content: ""
};

The storageObj object has two keys namely senderClass and content. The senderClass key represents the sender of the message(user or susi) whereas the content key holds the actual content of the message.

We will use chrome.storage.get and chrome.storage.set methods to store and retrieve data.

var susimessage = newDiv.innerHTML;
storageObj.content = susimessage;
storageObj.senderClass = "susinewmessage";
chrome.storage.sync.get("message",(items) => {
if(items.message){
storageArr = items.message;
}
storageArr.push(storageObj);
chrome.storage.sync.set({"message":storageArr},() => {
console.log("saved");
});
});

 

In the above code snippet, susimessage contains the actual message content sent by the SUSI server. We then set the correct properties of the storageObj object that we declared earlier. Now we can use chrome.storage.set to save the storageObj object but that would overwrite the current data that we have inside chrome’s StorageArea. To prevent the old message data from getting overwritten, we’ll first get all the message content in our storage using chrome.storage.sync.get. Notice how we are passing the “message” string as the first perimeter to the function. This is done because we only want our message content which was saved in the StorageArea. If we pass null instead, it will return all the content inside storageArea. Once we have our messages (which will be an array of objects that we store as storageObj), we will store that into a new array storageArr. We will then push our new storageObj that contains the message and the sender into the array. Finally, we use chrome.storage.sync.set to save the message content in chrome’s StorageArea which can later be retrieved using the “message” key.

storageArr.push(storageObj);
chrome.storage.sync.set({"message":storageArr},() => {
console.log("saved");
});

We use the same procedure to save messages sent by the user.

Note: chrome.storage is not very large, so we need to be careful about what we store or we may run out of storage space. Also, we should not store confidential data in storage since the storage area is not encrypted.

Resources:

Tags:

  • FOSSASIA, codeheat, Chrome extensions, Javascript, Chrome Storage, Chrome Sync, Susi Chrome Bot, SUSI AI, Bot Development
Continue ReadingMaintaining Extension State in SUSI.AI Chrome Bot Using Chrome Storage API

Leak Canary in Phimpme Android

Leak Canary is a memory detection library for Android and Java. A memory leak occurs when you hold an object for too long after its purpose has been served. If some object is holding another object then the Garbage collector will not be able to collect and this is known as Memory Leak. These memory leaks can be minor (in KB’s) or can lead to an app in ANR state with OutOfMemoryError.Hence to recover and capture this memory leak, Leak Canary is used for Android and Java.

For every functioning done in android, the system needs resource such as memory. Hence in Java the Garbage Collector(GC) plays a major role in deallocating the memory. The GC is mainly used to reclaim memory. Now the question arises, why do we need a memory leak detection library when GC is already present. The answer is sometimes the developers makes programming mistakes and that leads to inhibit the GC to collect the objects that are of no use and mark them as useful objects.

The GC starts from one point(root) and marks active to all the objects that holds references from GC root and the objects which are not marked are wiped out of memory.Hence when some unuseful objects is marked active, memory leak occurs.Hence to eliminate these problems  of memory leaks, we have employed the use of Leak Canary in our project.

The Phimpme project and every related project has possible memory leaks, like for instance we have used fragments in settings activity and to catch that memory leak we have added the refwatcher instance. Hence if any memory leaks occur we get the error such as ‘org.fossasia.phimpme’  leaked 40kb.This can also be checked by Leaks App in the android phone, which has features of showing and sharing the heap dump and info.

To add the Leak Canary in your android app, follow these steps:

  • Add the dependencies in build.gradle(app level)

    dependencies {
       debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
       releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
     }
  • Add the following code to your Application class

    public class MyApplication extends Application{
    @Override
    public void onCreate() {
       if (LeakCanary.isInAnalyzerProcess(this)) {
           // This process is dedicated to LeakCanary for heap analysis.
           // You should not init your app in this process.
           return;
       }
       LeakCanary.install(this);
    }
    
  • Leak canary now will automatically detect the memory leaks  from all activities.

For fragment a refwatcher is needed, hence

public class MYFragment extends Fragment {
    ...

    @Override
    public void onDestroy() {
        super.onDestroy();
        MainApplication.getRefWatcher(getActivity()).watch(this);
    }
}

Hence LeakCanary is setup finally, and now the memory leaks will be detected.

Resources

 

Continue ReadingLeak Canary in Phimpme Android

Adding Map Type Response to SUSI.AI Chromebot

SUSI.AI Chromebot has almost all sorts of reply that SUSI.AI Server can generate. But it still missed the Map Type response that was generated by the SUSI.AI Server.

This blog explains how the map type response was added to the chromebot.

Brief Introduction

The original issue was planned by Manish Devgan and Mohit Sharma as an advanced task for Google Code-In 2017. The link to which can be found here: #157

For a long time the issue remained untouched and after GCI got over I assigned the issue to myself as it was a priority issue since MAP type was a major response from the SUSI.AI Server.

How was Map Type response added?

There were a lot of things to be taken in mind before starting working on this issue.

  • Changing code scheme during GCI and other PRs
  • API Response from the SUSI.AI Server
  • Understanding the new codebase that got altered during GCI-17
  • Doing it quick

I will go through all the steps in detail

Changing Code Scheme

The code was altered numerous times with the addition of a number of pull requests during GCI-17 and there were no docstrings for any functions and methods. So I had to figure them out in order to start working on the map type response.

API Response from the SUSI.AI Server

To understand the JSON that server sent, I went to SUSI.AI API and did a simple search for

“Where is Berlin?” and the response generated is given below.

( Since the JSON is very big I am only posting the relevant data for this issue )

 

    "actions": [
      {
        "type": "answer",
        "language": "en",
        "expression": "Berlin (, German: [bɛɐ̯ˈliːn] ( listen)) is the capital and the largest city of Germany as well as one of its 16 constituent states."
      },
      {
        "type": "anchor",
        "link": "https://www.openstreetmap.org/#map=13/52.52436820069531/13.41053001275776",
        "text": "Here is a map",
        "language": "en"
      },
      {
        "type": "map",
        "latitude": "52.52436820069531",
        "longitude": "13.41053001275776",
        "zoom": "13",
        "language": "en"
      }
    ]

 

Here we see and understand that “actions” is an Array of JSONs and the third part has “type” as “map”. This is the relevant information that we require for generating the map-type response.

The important variables in this context are: “latitude” and “longitude”.

Understanding the Codebase

Now I had to figure out the new pattern of adding response types to the SUSI.AI Chromebot.

After having a talk with @ms10398 I figured out the route map.

The above image shows the correct flow of Javascript Code that generated the response. After this, I was good to go and start my work.

Adding the Map-Type Response

To start with I chose “LEAFLET.JS” as the Javascript Library that will be used to create maps.

  • So I added the LEAFLET.JS to the JS folder.
  • Now changes were made to the “index.html” file

 

<link rel=”stylesheet” href=”https://unpkg.com/leaflet@1.3.1/dist/leaflet.css” />

http://”js/leaflet.js”

 

Appropriate CSS was added along with a link to leaflet.js was added.

  • Adding CSS to the “mapClass
.mapClass{

    height : 200px;

    width : 200px;

}

 

  • Generating Maps with dynamic IDs

This part was where I applied brain, as to add the map to any div we required the div to have a proper and unique ID and so a way to generate unique IDs for div without using any external source was to be thought of.

I came with idea of using timestamp, as it will always be unique.

var timeStamp = new Date.now().toString();

 

Then I created the “composeMapReply()” function.

function composeReplyMap(response, action){

    var newDiv = messages.childNodes[messages.childElementCount];

    var mapDiv = document.createElement(“div”);

    var mapDivId = Date.now().toString();

    mapDiv.setAttribute(“id”, mapDivId);

    mapDiv.setAttribute(“class”, “mapClass”);

    newDiv.appendChild(mapDiv);

    messages.appendChild(newDiv);

    var newMap = L.map(mapDivId).setView([Number(action.latitude), Number(action.longitude)], 13);

 L.tileLayer(“https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}”,{

    /*

        This part contains the data for api call.

    */

}).addTo(newMap);

response.isMap = true;

response.newMap = mapDiv;

return response

    

}

 

The complete code can be found: here

At last after adding so many snippets of code we were able to generate the Map-Type response for SUSI.AI Chromebot

GIF

A gif showing the Map-Type response in action.

 

Resources

 

Continue ReadingAdding Map Type Response to SUSI.AI Chromebot

Generating Badges for Manual Data for Pre-Selected Badges

BadgeYay is a Badge Generator developed by FOSSASIA. In recent time there was a BUG that caused the badge generator to throw errors and malfunction while generating the badges.

This error was first reported by me, @gabru-md. And later when everyone seemed to have this bug it was resolved after a complete 48 hour of reverse engineering the code.

What was the Bug?

The bug with the generator was that the server side API did not function well and was not generating badges in cases of Manual Input and Pre-Selected Images.The issue was first made sure and then created on github as Issue number 314 .

Resolving the Bug

Resolving the bug this time was a hard task as the code was not properly maintained due to many PRs being merged and due to this it took me 48 hours to figure out what was wrong with the code.

After like 1 day of reading between the lines it was found out that the bug was caused due to improper “if…else” conditions. There were several  small bugs that arouse when this main bug was being dealt with.

How was it resolved?

Many changes were done to the code to resolve the bug. It was definitely the most time consuming and important fix that I had ever applied to any project.

The only changes were done to the main server file “main.py”.

  • Adding a missing line to the file.
text_on_image = request.form[“text_on_image”]

 

  • Removing unnecessary code for cleaning up the file.
if file.filename == ‘’  and csv ==  ‘’:

    flash(‘Please select a CSV field to upload’)

    return redirect(url_for(‘index’))

 

And

elif:

    if file.find(“png.csv”) != -1:

        if img == ‘’:

            flash(‘{Please upload an image in ...’)   

            return redirect(url_for(‘index’))

    else:

        flash(‘Please upload ...’)

 

  • Adding the relevant code to fix the bug.

 

if img == ‘’:

    img = request.filed[‘image’].filename

    filename = request.files[‘image’].filename + “.csv”

elif csv != ‘’:

Changing filename to “img + .csv” resolved the filename error that caused the badge generator not to recognize the files.

Saving the files to the correct places for the script to recognize them

image.save(os.path.join(app.config[‘UPLOAD_FOLDER’],image.filename))

 

Changing the rest of the code to comply with the changes and make Badgeyay BUG free.

elif eventyay_url != ‘’:

    filename = ‘speaker.png.csv’

    generate_csv_eventyay.tocsv(eventyay_url,filename)

if filename.find(‘png.csv’) != -1:

    if img == ‘’:

        flash(“Please Upload …”)

        return redirect(url_for(‘index’))

else:

    flash(‘Please Upload a CSV …’)

    return redirect(url_for(‘index’))

 

The last change was to change an “if” condition to a relevant one.

if csv == ‘’ and filename == img + ‘.csv’ and eventyay_url == ‘’:

 

All these changes helped resolve one of the major bugs in Badgeyay. With the merging of the associated PR the bug was immediately fixed and Badgeyay was up again.

Challenges

  • Lack of time since service was down for a long time
  • Improper code

 

But I took them as challenges and was able to fix it for once and for all.

Further Improvements

Further Improvements will be leading to a more fast and stable Badgeyay with more user friendly options and an improved UI and stronger UX.

Resources

 

Continue ReadingGenerating Badges for Manual Data for Pre-Selected Badges

Adding Preview Support to BadgeYay!

In an issue it was requested to add a Preview support for BadgeYay, i.e. Badges could be seen before they were generated.

Why Preview Support?

It is a nice question. But Preview support was needed in a badge generator like BadgeYay.

This can be easily answered by an example. Let us suppose that I want to generate hundreds-thousands of badges for a meetup/event that I have organized. But I am confused as to what will look the best on and as badges. So I can just try them all in the Preview section and then choose the one that I like and generate it.

How to add Preview Support?

Adding Preview Support was not an easy task. Although coding it was not the hard part, but thinking of a way that uses less of the server’s support was a thing to take care of.

I had two options to choose from.

Implement Preview Section from backend

This was the idea that first came to my mind when i thought of implementing something like preview section.

It included of generating badges everytime the user wanted a preview and then using the same SVGs generated to show as the preview of badges.

Problems it had

Using Backend to generate badges for every instance would result to a lot of load to the server prior to the actual badge generation. And making it faster and creating less load on server was the main problem to tackle. So I came up with another idea of using frontend to generate Preview(s).

Implementing Preview Section from frontend

This method of generating preview is far more faster and less load heaving to the server.

It uses technologies such as HTML, CSS and Javascript to  generate preview for badges.

The Pull Request for the same is : here

Changes in index.html

  • Adding a button to view preview
<button type=”button” disabled=”disabled” class=”btn btn-block btn-warning” id=”preview-btn”>Preview</button>

 

  • Adding the text areas for badge

Adding appropriate HTML for text areas.

  • Adding Appropriate CSS
.preview-image{

height: 250px;

width: 180px;

margin-left: 80px;

background-size: cover;

padding: 140px 0 0 5px;

text-align: center;

margin-top: 20px;

}

.preview-image-li{

list-style: none;

color: white;

font-size: 15px;

}

#preview-btn{

font-size: 18px;

}

 

  • Adding Javascript code for functionality
function readURL(input){

if(input.files && input.files[0]){

var reader = new FileReader();

reader.onload = function(e){

$(‘#preview’).css(‘background-image’,’url(‘ + e.target.result + ‘)’);

$(‘#preview’).css(background-size’,’cover’);

$(‘#preview-btn’).prop(“disabled”,false);

};

reader.readAsDataURL(input.files[0]);

}

}

 

The above snippet of code adds the image to the background of the preview div and stretches it to occupy full space.

var textValues = $(‘#textArea’).val();

textValues = textValues.split(“/n”)[0].strip(‘,’);

$(‘#preview-li-1’).text(textValue[0]);

$(‘#preview-li-2’).text(textValue[1]);

$(‘#preview-li-3’).text(textValue[2]);

$(‘#preview-li-4’).text(textValue[3]);

The above snippet of code adds the input from the textArea to the appropriate place on the preview badge.

Further Improvements

Adding a real-time preview feature that allows user to see the changes in real-time therefore making the application more flexible and enhancing user experience.

Resources

 

Continue ReadingAdding Preview Support to BadgeYay!

Toggling Voice On/Off in SUSI Chromebot

SUSI Chromebot has a lot of features that make it one of the best projects of FOSSASIA.

Recently Voice/Speech was added to SUSI Chromebot. But there was no option that controlled the fact that whether speech output is needed or not.

The latest addition to SUSI Chromebot is Toggling the Voice of SUSI On or Off.

How was it achieved?

Toggling Voice for SUSI required adding a button and a snippet of Javascript code to the main JS file. The code will take care of the fact whether the voice is to be toggled on or off.

I started off by adding a button to the main HTML file.

<a href=”javascript: void(0)” id=”speak” style=”color: white”><i class=”material-icons” id=”speak-icon”>volume_up</i></a>

The above snippet of HTML code adds a voice button to the top bar of chromebot.

Then there was the major part where the javascript code was to be added to add the functionality to the button.

var shouldSpeak = true;

I started off by creating a variable called as “shouldSpeak” which will determine whether or not SUSI should use the Chrome’s API to speak.

Then I changed the “speakOut()” function and added another parameter to it.

function speakOut(msg,speak=false){

if(speak){

var voiceMsg = new SpeechSynthesisUtterance(msg);

window.speechSynthesis.speak(voiceMsg);

}

}

The above code made sure that susi was only allowed to speak when and only “speak” variable was set to true.

Then “eventListeners” were added to buttons and other things to link the functionality.

document.getElementById(‘speak’).addEventListener(‘click’,changeSpeak);

It adds the events of click to “speak” and associates it with the function “changeSpeak”.

Now the function “changeSpeak” is created as follows. It toggles the on/off mechanism of voice in SUSI Chromebot.

function changeSpeak(){

shouldSpeak = !shouldSpeak;

var SpeakIcon = document.getElementById(‘speak-icon’);

if(!shouldSpeak){

SpeakIcon.innerText = “volume_off”;

}

else{

SpeakIcon.innerText = “volume_up”;

}

console.log(‘Should be speaking? ’ + shouldSpeak);

}

Everytime the user clicks on the icon to toggle on/off voice the icon must also change and this functionality was taken care of by the above piece of code.

Resources

 

Continue ReadingToggling Voice On/Off in SUSI Chromebot

Resolving Internal Error on Badgeyay

Badgeyay is in development stage and is frequently seen to encounter bugs. One such bug is the Internal Server Error in Badgeyay.

What was the bug?

The bug was with the badge generator’s backend code. The generator was trying to server the zip file that was not present. After going through the log I noticed that it was because a folder was missing from Badgeyay’s directory.

 

I immediately filed an issue #58 which stated the bug and how could it be resolved. After being assigned to the issue I did my work and created a Pull Request that was merged soon.

The Pull Request can be found here.

Resolving the bug

With the help of extensive error management and proper code and log analysis I was able to figure out a fix for this bug. It was in-fact due to a missing folder that was deleted by a subsequent code during zipfile/pdf generation. It was supposed to be recreated every time it was deleted. I quickly designed a function that solved this error for future usage of Badgeyay.

 

How was it resolved?

First I started by checking if the “BADGES_FOLDER” was not present. And if it was not present then the folder was created using the commands below

 

if not os.path.exists(BADGES_FOLDER):

    os.mkdir(BADGES_FOLDER)

 

Then, I added docstring to the remaining part of the code. It was used to empty all the files and folder inside the “BADGES_FOLDER”. We could have to delete two things, a folder or a file.

So proper instructions are added to handle file deletion and folder deletion.

 

for file in os.listdir(BADGES_FOLDER):

    file_path = os.path.join(BADGES_FOLDER, file)

    try:

        if os.path.isfile(file_path):

            os.unlink(file_path)

        elif os.path.isdir(file_path):

            shutil.rmtree(file_path)

    except Exception:

        traceback.print_exc()

 

Here “os.unlink” is a function that is used to delete a file. And “shutil.rmtree” is a function that deletes the whole folder at once. It is similar to “sudo rm -rf /directory”. Proper error handling is done as well to ensure stability of program as well.

Challenges

There were many problems that I had to face during this bug.

  • It was my first time solving a bug, so I was nervous.
  • I had no knowledge about “shutil” library.
  • I was a new-comer.

But I took these problems as challenges and was able to fix this bug that caused the INTERNAL SERVER ERROR : 500 .

Resources

 

 

Continue ReadingResolving Internal Error on Badgeyay