Different Text Color On Each Line In Badgeyay

In this blog post I am going to explain about how to create different text color for each line in badges generation in Badgeyay. As the system now has option for different badge size and paper size, currently the system sets same color for each line by mutating the fill parameter in the SVG. The main challenge in mutating the SVG parameter for each badge is the Id. The ID identifies the element, in our case text, and gives access to iterate the SVG through libraries like lxml. So for implementing this feature we first need to manipulate the SVG and assign id’s to the text tag so that it can be easily manipulated through the algorithm.

Procedure

  1. Manipulating the text tag in SVG and assigning a proper ID according to the logic for iteration in the function.
<text

     id=“Person_color_1_1”

     ….>

Person_1_1

</text>

The id of the person in first badge and first line is represented as Person_color_1_1, where the first number denotes the number of badge and second number denotes the line number.

  1. Creating a class for the dimensions of the badges
class Dimen(object):
  def __init__(self, badges, badgeSize, paperSize):
      self.badges = badges
      self.badgeSize = badgeSize
      self.paperSize = paperSize
  1. Creating an initialiser function that stores the dimension objects
badge_config = {}


def init_dimen():
  paper_sizes = [‘A2’, ‘A3’, ‘A4’]
  for paper in paper_sizes:
      if paper == ‘A2’:
          badge_config.__setitem__(paper, {‘4×3’: Dimen(18, ‘4×3’, paper)})
          badge_config[paper][‘4.5×4’] = Dimen(15, ‘4.5×4’, paper)
      elif paper == ‘A3’:
          badge_config.__setitem__(paper, {‘4×3’: Dimen(8, ‘4×3’, paper)})
          badge_config[paper][‘4.5×4’] = Dimen(6, ‘4.5×4’, paper)
      elif paper == ‘A4’:
          badge_config.__setitem__(paper, {‘4×3’: Dimen(6, ‘4×3’, paper)})
          badge_config[paper][‘4.5×4’] = Dimen(2, ‘4.5×4’, paper) 
  1. Selecting the dimension config based on the parameters passed in the function.
dimensions = badge_config[paper_size][badge_size]
  1. Looping criteria is to loop through the number of badges mentioned in the dimension config and through the number of lines which will be five.
for idx in range(1, dimensions.badges + 1):

          for row in range(1, 6):
  1. Selecting the text element with the ID as provided above.
_id = ‘Person_color_{}_{}’.format(idx, row)
              path = element.xpath((“//*[@id='{}’]”).format(_id))[0]
  1. Fill the text color argument of the selected object by changing the value of fill.
style_detail[6] = “fill:” + str(fill[row])

That’s it and now when the loop runs each line will have its individual color as passed in the function. The choice of color is passed as the list named fill.

Resources

Continue Reading

Enhancing pagination in Badgeyay

A Badge generator like Badgeyay must be able to generate, store and export the user data as and when needed. This blog post covers the enhancement of pagination in the frontend of badgeyay project. There are small “next” and “previous” links to toggle between pages..

Enhancing the current way of links

The problem with the pagination links was that in case of no more badges/users etc, the links would always appear on the bottom right of the table. The previous link must not appear when no previous page is there and vice versa for the next link.

Step 1 : Adding the package to package.json

Image link is the link to the user’s uploaded image on remote firebase server.

{{#if allow}}
<tfoot>
<
tr>
<
th colspan=“5”>
<
div class=“ui right floated pagination menu”>
{{#if allow_prev}}
<
a class=“icon item” {{action ‘prevPage‘}}>
<
i class=“left chevron icon”></i>
</
a>
{{/if}}
{{#if allow_next}}
<
a class=“icon item” {{action ‘nextPage‘}}>
<
i class=“right chevron icon”></i>
</
a>
{{/if}}
</
div>
</
th>
</
tr>
<
/tfoot>
{{/i
f}}

Step 2 : Initializing the variables in setupController

Once we have added the if construct to the badgeyay frontend then we need to add the variable initialization in the setupController method in EmberJS.

setupController(controller, model) {
this._super(…arguments);
set(controller,
‘reports’, model);
if (model.length < 9) {
set(controller,
‘allow_prev’, false);
set(controller,
‘allow_next’, false);
set(controller,
‘allow’, false);
}
}

Step 3 : Implementing state changed in the controllers

Now we need to handle the situation when a user clicks the links and there are more or less links to display. This is done by checking the length of the model in the controller.

if (this.page === 1) {
this.set(‘allow_prev’, false);
}
else {
this.set(‘allow_prev’, true);
}
this..set(‘allow_next’, true);

Same needs to be done for all the controllers that have pagination available.

And finally we need to pass these variables in the component template. One such example is given below.

<div class=“ui grid user-grid”>
<
div class=“row”>
<
div class=“sixteen wide column”>
{{badge-table badges=badges user=user session=session sendbadgeId=(action ‘deleteBadge’ badge) prevPage=(action ‘prevPage’) nextPage=(action ‘nextPage’) allow_prev=allow_prev allow_next=allow_next allow=allow}}
</
div>
</
div>
<
/div>

Finally, we have the pagination links working as desired..

Screenshot of changes

Resources

 

Continue Reading

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

Continue Reading

Status Badges for Repositories Registered to Yaydoc

Yaydoc, our automatic documentation generation and deployment project, generates and deploys documentation for each of its registered repository at every commit. It is possible that due to any misconfiguration in users’ project the build process may fail. Hence, it is vital for an improved user experience to store the build status for at least the most recent build process.

There are different ways with which a user can be notified about the build status after a commit. At Yaydoc, we chose to notify the user by emailing a status report. Since sending an email at each at every commit can be quite annoying, we chose to limit it to specific scenarios. We decided that we will send the mail

  • On the first build after the repository is registered to Yaydoc, irrespective of the status
  • On every failed build
  • On the change of build status (Success to Failed or vice versa)
  • To the user who registered the repository to Yaydoc
exports.updateBuildStatus = function (name, buildStatus) {
  async.waterfall([
    function (callback) {
      Repository.setBuildStatusToRepository(name, buildStatus, 
      function (error, repository) {
        callback(error, repository);
      });
    },
    function (repository, callback) {
      if (repository.mailService === true && 
          (repository.buildStatus === false || buildStatus === false || 
           repository.buildStatus === undefined)) {
        User.getUserByUsername(repository.registrant.login, 
        function (error, user)) {
          callback(null, user, repository);
        }
      }
    }
  ], function (error, user, repository) {
    mailer.sendMailOnBuild(buildStatus, user.email, repository);
  });
};

Considering the fact that the user may not wish to receive build emails and hence made them configurable by adding a mailService: Boolean  key in repository’s collection.

Taking this forward, we then decided to generate status badges similar to how Travis and other Continuous Integration platform do. Since we now store a `buildStatus` for each repository, we can use it to generate an svg image to be added to README files of repositories. We generated  the status badges using Shields.io and added them to the route /<owner>/<reponame>.svg.  The dynamicity of image generated is achieved by retrieving the value of buildStatus and render the images with different constructs based on its value.

router.get(‘/:owner/:reponame.svg’, function (req, res, next) {
  var fullName = req.params.owner + ‘/’ + req.params.reponame;
  Repository.getBuildStatusByRepositoryName(fullName, function(error, result)) {
    var buildStatus = ‘invalid’; var width =94’; 
    var color = ‘#9f9f9f’; var x =70.5’;
    
    if (result.buildStatus) {
      buildStatus = ‘success’; width =102’; color = ‘#97CA00’; x =74.5’;
    } else {
      buildStatus = ‘failed’; width =88’; color = ‘#E05d44’; x =67.5’;
    }

    res.set(‘Content-Type’, ‘image/svg+xml’);
    res.render(“badge”, {
      status: buildStatus,
      width: width,
      color: color,
      x: x,
    });
  }
});

The status tags generated can then be added as:

[![Yaydoc Status] (https://yaydoc.herokuapp.com/imujjwal96/prelimQuiz.svg)] (https://yaydoc.herokuapp.com/imujjwal96/prelimQuiz)

Resources:

  1. Shields.io: Quality metadata badges for open source projects – https://shields.io
  2. Async utilities for node and browser – https://caolan.github.io/async/
Continue Reading
Close Menu