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

 

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

 

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

 

 

Make Flask Fast and Reliable – Simple Steps

Flask is a microframework for Python, which is mostly used in web-backend development.There are projects in FOSSASIA that are using flask for development purposes such as Open Event Server, Query Server, Badgeyay. Optimization is indeed one of the most important steps for a successful software product. So, in this post some few off- the-hook tricks will be shown which will make your flask-app more fast and reliable.

Flask-Compress

  1. Flask-Compress is a python package which basically provides de-facto lossless compression  to your Flask application.
  2. Enough with the theory, now let’s understand the coding part:
    1. First install the module

2. Then for a basic setup

3.That’s it! All it takes is just few lines of code to make your flask app optimized .To know more about the module check out flask-compress module.

Requirements Directory

  1. A common practice amongst different FOSSASIA  projects which involves dividing requirements.txt files for development,testing as well as production.
  2. Basically when projects either use TRAVIS CI for testing or are deployed to Cloud Services like Heroku, there are some modules which are not really required at some places.  For example: gunicorn is only required for deployment purposes and not for development.
  3. So how about we have a separate directory wherein different .txt files are created for different purposes.
  4. Below is the image of file directory structure followed for requirements in badgeyay project.

  1. As you can see different .txt files are created for different purposes
    1. dev.txt – for development
    2. prod.txt – for production(i.e. deployment)
    3. test.txt – for testing.

Resources

Using Inkscape to create SVG Files for Background of Event Badges in Badgeyay

Inkscape is a free and open-source vector graphics editor. I used it in the FOSSASIA Badgeyay repository whose main purpose is to create badges for the event created using open-event. Badges were created in Scalable Vector Graphics (SVG) because of its advantages over JPEG, png etc. such as: scalability, Search Engine Optimization (SEO) friendly, easy editing ability (as it gets saved in an XML format) and resolution independence.

My task (issue #20) was to create the background in SVG format so that it can be edited using XML file. Aim was to create the background in such a way so that we just have to find and replace the color code to see the color change in the image/background. Following background was to be reproduced in SVG format using Inkscape whose color can be edited using a text editor.

badge

This was achieved using Inkscape (as suggested in the issue itself) which let us create an SVG file. I created 2 layers, 1 for plain background, and the other containing the triangles of Voronoi Diagram. General steps are included in this awesome video tutorial – AbstractBackground.

I found this quite helpful in understanding the interface of Inkscape. After following this tutorial, I had to do changes as follows:

  • Layer 1 rectangle was made using mesh, giving 4 different colors at corners. I set these colors as grey with different opacity/alpha factor.
  • Then just like in the video, I created a small circular object, set it to ‘path to object’, made duplicates of them, scattered them on the rectangle of 1st layer.
  • Used extensions menu to use ‘voronoi diagram‘, and then applied this to the selected circles.
  • Then I removed these circles, ungrouped all the triangles formed , changed their color, just by picking with the background (which was grey — with different opacities!). Grouped them together again, removed the lines which were separating the triangles by setting stroke to none.
  • Now all one have to do is change the color of 1st layer’ rectangle, and the final image/background will get changed .

This change of color can be changed using a text editor too. I just had to find layer 1 rectangle in the XML tree, replace the ‘fill’ attribute with the required color code.

This was achieved using INKSCAPE.

badge background

Now using text editor (here Sublime Text 3) , find layer 1, and change ‘fill’ value of rect with say ‘37C871’.

 <g
      inkscape:label="Layer 1"
      inkscape:groupmode="layer"
      id="layer1"
      style="display:inline;opacity:1">
     <rect
        id="rect4504"
        width="141.3569"
        height="200.82413"
        x="-63.25676"
        y="-14.052279"
        style="opacity:1;fill:#37C871;fill-opacity:1;stroke:url(#linearGradient2561);stroke-width:0.57644272" />
   </g>

changed badge background color
Then again opening the svg file, gives us the output as :

Results can be seen in my Pull request #152 which eventually got merged.

Using the similar background and adding logo of FOSSASIA on the top, also adding editable Headings like ‘VIP’, ‘BUSINESS PASS’  was done further in #PR167.

If you want to contribute to FOSSASIA/badgeyay, you can create an issue here.

Resources: