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 ReadingMake Flask Fast and Reliable – Simple Steps

How to Store Mobile Settings in the Server from SUSI Web Chat Settings Page

While we are adding new features and capabilities to SUSI Web Chat application, we wanted to provide settings changing capability to SUSI users. SUSI team decided to maintain a settings page to give that capability to users.

This is how it’s interface looks like now.

In this blog post I’m going to add another setting category to our setting page. This one is for  saving mobile phone number and dial code in the server.

UI Development:

First we need to  add new category to settings page and it should be invisible when user is not logged in. Anonymous users should not get mobile phone category in settings page.

     let menuItems = cookies.get('loggedIn') ?
            <div>
                <div className="settings-list">
                    <Menu
                        onItemTouchTap={this.loadSettings}
                        selectedMenuItemStyle={blueThemeColor}
                        style={{ width: '100%' }}
                        value={this.state.selectedSetting}
                    >
                       <MenuItem value='Mobile' className="setting-item" leftIcon={<MobileIcon />}>Mobile<ChevronRight className="right-chevron" /></MenuItem>
                        <hr className="break-line" />
                    </Menu>
                </div>
            </div>

 

Next we have to show settings UI when user clicks on the category name.

 if (this.state.selectedSetting === 'Mobile' && cookies.get('loggedIn')) {}
                currentSetting = (
  <Translate text="Country/region : " />
                            <DropDownMenu maxHeight={300}
               value={this.state.countryCode?this.state.countryCode:'US'}

 

Show US if the state does not deines the country code

                                onChange={this.handleCountryChange}>
                                {countries}
                            </DropDownMenu>
<Translate text="Phone number : " />
                            <TextField name="selectedCountry"
                            disabled={true}
                            value={countryData.countries[this.state.countryCode?this.state.countryCode:'US'].countryCallingCodes[0] }
                         	/>
                            <TextField name="serverUrl"
                                onChange={this.handleTelephoneNoChange}
                                value={this.state.phoneNo }
 />
)}

 

Then we need to get list of country names and country dial codes to show in the above drop down. We used country-data node module for that.

To install country-data module use this  command.

npm install --save country-data

 

We have used it in the settings page as below.

import countryData from 'country-data';
    	countryData.countries.all.sort(function(a, b) {
            if(a.name < b.name){ return -1};
            if(a.name > b.name){ return 1};
            return 0;
        });
        let countries = countryData.countries.all.map((country, i) => {
         	return (<MenuItem value={countryData.countries.all[i].alpha2} key={i} primaryText={ countryData.countries.all[i].name+' '+ countryData.countries.all[i].countryCallingCodes[0] } />);
        });

 

First we sort the country data list from it’s name. After that we made a list of “”s from this list of data.
Then we have to check whether the user changed or added the phone number and region (dial code).
It handles by this function mentioned above. ( onChange={this.handleCountryChange}> and
onChange={this.handleTelephoneNoChange} )

    handleCountryChange = (event, index, value) => {
        this.setState({'countryCode': value });
    }

 

Then we have to get the phone number using below function.

    handleTelephoneNoChange = (event, value) => {
        this.setState({'phoneNo': value});
    }

 

Next we have to update the function that triggers when user clicks the save button.

    handleSubmit = () => {
        let newCountryCode = !this.state.countryCode?
        this.intialSettings.countryCode:this.state.countryCode;
        let newCountryDialCode = !this.state.countryDialCode?
        this.intialSettings.countryDialCode:this.state.countryDialCode;
        let newPhoneNo = this.state.phoneNo;
        let vals = {
            countryCode: newCountryCode,
            countryDialCode: newCountryDialCode,
            phoneNo: newPhoneNo
}
let settings = Object.assign({}, vals);
cookies.set('settings', settings);
 this.implementSettings(vals);
 }

 

This code snippet stores Country Code, Country Dial code and phone no in the server.
Now we have to update the Store. Here we are going to change UserPreferencesStore “UserPreferencesStore” .
First we have to setup default values for things we are going to store.

let _defaults = {
	  CountryCode: 'US',
   	  CountryDialCode: '+1',
   	  PhoneNo: ''
}

 

Finally we have to update the dispatchToken to change and get these new data

UserPreferencesStore.dispatchToken = ChatAppDispatcher.register(action => {
   switch (action.type) {
       case ActionTypes.SETTINGS_CHANGED: {
           let settings = action.settings;
           if(settings.hasOwnProperty('theme')){
                   _defaults.Theme = settings.theme;
           }
           if(settings.hasOwnProperty('countryDialCode')){
               _defaults.countryDialCode = settings.countryDialCode;
           }
           if(settings.hasOwnProperty('phoneNo')){
               _defaults.phoneNo = settings.phoneNo;
           }
           if(settings.hasOwnProperty('countryCode')){
               _defaults.countryCode = settings.countryCode;
           }
           UserPreferencesStore.emitChange();
           break;
}
}

 

Finally application is ready to store and update Mobile phone number and region code in the server.

Resources:

Continue ReadingHow to Store Mobile Settings in the Server from SUSI Web Chat Settings Page
Read more about the article FOSSASIA Summit 2018 Singapore – Call for Speakers
Too big Crowd for only One Photo / One of Many Group Photos by Michael Cannon

FOSSASIA Summit 2018 Singapore – Call for Speakers

The FOSSASIA Open Tech Summit is Asia’s leading Open Technology conference for developers, companies, and IT professionals. The event will take place from Thursday, 22nd – Sunday, 25th March at the Lifelong Learning Institute in Singapore.

During four days developers, technologists, scientists, and entrepreneurs convene to collaborate, share information and learn about the latest in open technologies, including Artificial Intelligence software, DevOps, Cloud Computing, Linux, Science, Hardware and more. The theme of this year’s event is “Towards the Open Conversational Web“.

For our feature event we are looking for speaker submissions about Open Source for the following areas:

  • Artificial Intelligence, Algorithms, Search Engines, Cognitive Experts
  • Open Design, Hardware, Imaging
  • Science, Tech and Education
  • Kernel and Platform
  • Database
  • Cloud, Container, DevOps
  • Internet Society and Community
  • Open Event Solutions
  • Security and Privacy
  • Open Source in Business
  • Blockchain

There will be special events celebrating the 20th anniversary of the Open Source Initiative and its impact in Open Source business. An exhibition space is available for company and project stands.

Submission Guidelines

Please propose your session as early as possible and include a description of your session proposal that is as complete as possible. The description is of particular importance for the selection. Once accepted, speakers will receive a code for a speakers ticket. Speakers will receive a free speakers ticket and two standard tickets for their partner or friends. Sessions are accepted on an ongoing basis.

Submission Link: 2018.fossasia.org/speaker-registration

Dates & Deadlines

Please send us your proposal as soon as possible via the FOSSASIA Summit speaker registration.

Deadline for submissions: December 27th, 2017

Late submissions: Later submissions are possible, but early submissions have priority

Notification of acceptance: On an ongoing basis

Schedule Announced: January 20, 2018

FOSSASIA Open Tech Summit: March 22nd – 25th, 2018

Sessions and Tracks

Talks and Workshops

Talk slots are 20 minutes long plus 5-10 minutes for questions and answers. The idea is, that participants will use the sessions to get an idea of the work of others and are able to follow up in more detail in break-out areas, where they discuss more and start to work together. Speakers can also sign up for either a 1-hour long or a 2-hours workshop sessions. Longer sessions are possible in principle. Please tell us the proposed length of your session at the time of submission.

Lightning talks

You have some interesting ideas but do not want to submit a full talk? We suggest you go for a lightning talk which is a 5 minutes slot to present your idea or project. You are welcome to continue the discussion in breakout areas. There are tables and chairs to serve your get-togethers.

Stands and assemblies

We offer spaces in our exhibition area for companies, projects, installations, team gatherings and other fun activities. We are curious to know what you would like to make, bring or show. Please add details in the submission form.

Developer Rooms/Track Hosts

Get in touch early if you plan to organize a developer room at the event. FOSSASIA is also looking for team members who are interested to co-host and moderate tracks. Please sign up to become a host here.

Publication

Audio and video recordings of the lectures will be published in various formats under the Creative Commons Attribution 4.0 International (CC BY 4.0) license. This license allows commercial use by media institutions as part of their reporting. If you do not wish for material from your lecture to be published or streamed, please let us know in your submission.

Sponsorship & Contact

If you would like to sponsor FOSSASIA or have any questions, please contact us via office@fossasia.org.

Suggested Topics

  • Artificial Intelligence (SUSI.AI, Algorithms, Cognitive Expert Systems AI on a Chip)
  • Hardware (Architectures, Maker Culture, Small Devices)
  • 20 years Impact of Open Source in Business
  • DevOps (Continuous Delivery, Lean IT, Moving at Cloud-speed)
  • Networking (Software Defined Networking, OpenFlow, Satellite Communication)
  • Security (Coding, Configuration, Testing, Malware)
  • Cloud & Microservices (Containers – Libraries, Runtimes, Composition; Kubernetes; Docker, Distributed Services)
  • Databases (Location-aware and Mapping, Replication and Clustering, Data Warehousing, NoSQL)
  • Science and Applications (Pocket Science Lab, Neurotech, Biohacking, Science Education)
  • Business Development (Open Source Business Models, Startups, Kickstarter Campaigns)
  • Internet of Everything (Smart Home, Medical Systems, Environmental Systems)
  • Internet Society and Culture (Collaborative Development, Community, Advocacy, Government, Governance, Legal)​
  • Kernel Development and Linux On The Desktop (Meilix, Light Linux systems, Custom Linux Generator)
  • Open Design and Libre Art (Open Source Design)
  • Open Event (Event Management systems, Ticketing solutions, Scheduling, Event File Formats)

Links

Speaker Registration and Proposal Submission:
2018.fossasia.org/speaker-registration

FOSSASIA Summit: 2018.fossasia.org

FOSSASIA Summit 2017: Event Wrap-Up

FOSSASIA Photos: flickr.com/photos/fossasia/

FOSSASIA Videos: Youtube FOSSASIA

FOSSASIA on Twitter: twitter.com/fossasia

Continue ReadingFOSSASIA Summit 2018 Singapore – Call for Speakers

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:

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

How App Social Links are specified in Open Event Frontend

This blog article will illustrate how the various social links are specified in the the footer of Open Event Frontend, using the settings API. Open Event Frontend, offers high flexibility to the admins regarding the settings of the App, and hence the media links are not hard coded, and can be changed easily via the admin settings panel.

The primary end point of Open Event API with which we are concerned with for fetching the settings  for the app is

GET /v1/settings

The model for settings has the following fields which concern the social links.

 googleUrl              : attr('string'),
 githubUrl              : attr('string'),
 twitterUrl             : attr('string')

Next we define them as segmented URL(s) so that they can make use of the link input widget.

segmentedTwitterUrl    : computedSegmentedLink.bind(this)('twitterUrl'),
 segmentedGoogleUrl     : computedSegmentedLink.bind(this)('googleUrl'),
 segmentedGithubUrl     : computedSegmentedLink.bind(this)('githubUrl'),

Now it is required for us to fetch the data from the API, by making the corresponding call to the API. Since the footer is present in every single page of the app, it is necessary that we make the call from the application route itself. Hence we add the following to the application route modal.

socialLinks: this.get('store').queryRecord('setting', {
})

Next we need to iterate over these social links, and add them to the footer as per their availability.So we will do so by first passing the model to the footer component, and then iterating over it in footer.hbs

{{footer-main socialLinks=model.socialLinks footerPages=footerPages}}


And thus we have passed the socialLinks portion of the model, under the alias socialLinks.Next, we iterate over them and each time check, if the link exists before rendering it.

<div class="three wide column">
     <div class="ui inverted link list">
       <strong class="item">{{t 'Connect with us'}}</strong>
       {{#if socialLinks.supportUrl}}
         <a class="item" href="{{socialLinks.supportUrl}}" target="_blank" rel="noopener noreferrer">
           <i class="info icon"></i> {{t 'Support'}}
         </a>
       {{/if}}
       {{#if socialLinks.facebookUrl}}
         <a class="item" href="{{socialLinks.facebookUrl}}" target="_blank" rel="noopener noreferrer">
           <i class="facebook f icon"></i> {{t 'Facebook'}}
         </a>
       {{/if}}
       {{#if socialLinks.youtubeUrl}}
         <a class="item" href="{{socialLinks.youtubeUrl}}" target="_blank" rel="noopener noreferrer">
           <i class="youtube icon"></i> {{t 'Youtube'}}
         </a>
       {{/if}}
       {{#if socialLinks.googleUrl}}
         <a class="item" href="{{socialLinks.googleUrl}}" target="_blank" rel="noopener noreferrer">
           <i class="google plus icon"></i> {{t 'Google +'}}
         </a>
       {{/if}}
     </div>
   </div>

Thus all the links in the app are easily manageable, from the admin settings menu, without the need of hard coding them. This approach also, makes it easy to preserve the configuration in a central location.

Resources

Continue ReadingHow App Social Links are specified in Open Event Frontend

Implementing Session and Speaker Creation From Event Panel In Open Event Frontend

Open-Event Front-end uses Ember data for handling Open Event Orga API which abides by JSON API specs. It allows the user to manage the event using the event panel of that event. This panel lets us create or update sessions & speakers. Each speaker must be associated with a session, therefore we save the session before saving the speaker.
In this blog we will see how to Implement the session & speaker creation via event panel. Lets see how we implemented it?

Passing the session & speaker models to the form
On the session & speaker creation page we need to render the forms using the custom form API and create new speaker and session entity. We create a speaker object here and we pass in the relationships for event and the user to it, likewise we create the session object and pass the event relationship to it.

These objects along with form which contains all the fields of the custom form, tracks which is a list of all the tracks & sessionTypes which is a list of all the session types of the event is passed in the model.

return RSVP.hash({
  event : eventDetails,
  form  : eventDetails.query('customForms', {
    'page[size]' : 50,
    sort         : 'id'
  }),
  session: this.get('store').createRecord('session', {
    event: eventDetails
  }),
  speaker: this.get('store').createRecord('speaker', {
    event : eventDetails,
    user  : this.get('authManager.currentUser')
  }),
  tracks       : eventDetails.query('tracks', {}),
  sessionTypes : eventDetails.query('sessionTypes', {})
});

We bind the speaker & session object to the template which has contains the session-speaker component for form validation. The request is only made if the form gets validated.

Saving the data

In Open Event API each speaker must be associated with a session, i.e we must define a session relationship for the speaker. To accomplish this we first save the session into the server and once it has been successfully saved we pass the session as a relation to the speaker object.

this.get('model.session').save()
  .then(session => {
    let speaker = this.get('model.speaker');
    speaker.set('session', session);
    speaker.save()
      .then(() => {
        this.get('notify').success(this.l10n.t('Your session has been saved'));
        this.transitionToRoute('events.view.sessions', this.get('model.event.id'));
      });
  })

We save the objects using the save method. After the speakers and sessions are save successfully we notify the user by showing a success message via the notify service.

Thank you for reading the blog, you can check the source code for the example here.

Resources

Continue ReadingImplementing Session and Speaker Creation From Event Panel In Open Event Frontend

Implementing “Change Password” API in Open Event Frontend

In Open Event Frontend, users can change the password for their account in the ‘Settings’ section. Changing one’s password will require the previous password of the same account which ensures the security. To implement change in password API, we created a REST endpoint here since the password cannot be included in the user model and thereby exposed to the client.

There is also a check on the server side of the old password. Thus, if the old password entered matches the one on the server, the post is successful and the server saves the new password. We achieve this as follows:

We have a change password form located at ‘settings/change-password’, which contains three input fields for old password, new password and confirm new password.

On submitting the form, we pass the action from the component to the controller.

Components consist of two parts: a template written in Handlebars, and a source file written in JavaScript that defines the component’s behavior.

Controllers behave like a specialized type of Component that is rendered by the router when entering a Route.

We could have handled this action in component itself. But, Ember JS’ main principle is DDAU i.e data down actions up. That is the main reason why we handle the action in out controller.

submit() {
      this.onValid(() => {
      this.sendAction('changePassword', this.getProperties('passwordCurrent', 'passwordNew'));
      });
}

Thus, we handle the action in our controller as follows:

 changePassword(passwordData) {
      this.set('isLoading', true);
      let payload = {
        'data': {
          'old-password' : passwordData.passwordCurrent,
          'new-password' : passwordData.passwordNew
        }
      };
      this.get('loader')
        .post('/auth/change-password', payload)
        .then(() => {
          this.get('notify').success(this.l10n.t('Password updated successfully'));
        })
        .catch(error => {
          if (error.error) {
            this.get('notify').error(this.l10n.t(error.error));
          } else {
            this.get('notify').error(this.l10n.t('Unexpected error. Password did not change.'));
          }
        })
        .finally(() => {
          this.set('isLoading', false);
          this.setProperties({ 'passwordCurrent': '', 'passwordNew': '', 'passwordRepeat': '' });
        });
    }

Here, we are getting the old password and the new password passed from the form and making a POST to the endpoint:

v1/auth/change-password

If the old password check goes successful on the server side, the server returns a successful response:

{ 
 "email": "example@example.com",
 "id": "1",
 "name": "example",
 "password-changed": true
}

Thus, the user can change password in Open Event Frontend.
Resources: Docs on loader service in Ember JS

Continue ReadingImplementing “Change Password” API in Open Event Frontend

Showing “Get started” button in SUSI Viber bot

When we start a chat with SUSI.AI on Viber i.e. SUSI Viberbot, there should be an option on how to get started with the bot. The response to it are some options like “Visit repository”, “How to contribute” which direct the user to check how SUSI.AI bot is made and prompts him/her to contribute to it. Along with that an option of “start chatting” can be shown to add up some sample queries for the user to try.

To accomplish the task at hand, we will accomplish these sub tasks:

  1. To show the “Get started” button.
  2. To show the reply to “Get started” query.
  3. To respond to the queries, nested in the response of “Get started”

Showing “Get started”:

The Viber developers platform notifies us when a user starts a conversation with our bot. To be exact, a conversation_started event is sent to our webhook and can be handled accordingly. The Viberbot shows a welcome message to the user along with a Get started button to help him/her start.

To send just the welcome message:

if (req.body.event === 'conversation_started') {
       // Welcome Message
       var options = {
           method: 'POST',
           url: 'https://chatapi.viber.com/pa/send_message',
           headers: headerBody,
           body: {
               // some required body properties here
               text: 'Welcome to SUSI.AI!, ' + req.body.user.name + '.',
               // code for showing the get started button here.
        }
           json: true
       };
 
       request(options, function(error, res, body) {
           // handle error
       });
   }

The next step is to show the “Get started” button. To show that we use a keyboard tool, provided by Viber developers platform. So after the “text” key we have the “keyboard” key and a value for it:

keyboard: {
             "Type": "keyboard",
             "DefaultHeight": true,
             "Buttons": [{
                 "ActionType": "reply",
                 "ActionBody": "Get started",
             }]
         }

The action type as shown in the code, can be “reply” or “open-url”. The “reply” action type, triggers an automatic query sent back with “Get started” (i.e. the value of “ActionBody” key), when that button gets clicked.

Hence, this code helps us tackle our first sub task:

Reply to “Get started”:

We target to make each SUSI.AI bot generic. The SUSI FBbot and SUSI Tweetbot shows some options like “Visit repository”, “Start chatting” and “How to contribute?” for the “Get started” query. We render the same answer structure in Viberbot.

The “rich_media” type helps us send buttons in our reply message. As we ought to use three buttons in our message, the button rows are three in the body object:

if(message === "Get started"){
                   var options = {
                       method: 'POST',
                       url: 'https://chatapi.viber.com/pa/send_message',
                       headers: headerBody,
                       body: {
                           // some body object properties here
                           type: 'rich_media',
                           rich_media: {
                               Type: "rich_media",
                               ButtonsGroupColumns: 6,
                               ButtonsGroupRows: 3,
                               BgColor: "#FFFFFF",
                               Buttons: buttons
                           }
                       },
                       json: true
                   };
 
                   request(options, function(error, res, body) {
                       if (error) throw new Error(error);
                       console.log(body);
                   });

As said before, 2 type of Action types are available – “open-url” and “reply”. “Visit repository” button has an “open-url” action type and “How to contribute?” or “start chatting” has a “reply” action type.

Example of “Visit repository” button:

var buttons = [{
                Columns: 6,
                Rows: 1,
                Text: "Visit repository",
                "ActionType": "open-url",
                "ActionBody": "https://www.github.com/fossasia/susi_server",
                // some text styling properties here
             }];

To respond to the “reply” action type queries:

When the “reply” action type button gets clicked, it triggers an automatic query sent back to the bot with the value same as that of the “ActionBody” key. So we just need to apply a check if the message string recieved is “Start chatting” or “How to contribute?”

For the response to “Start chatting”, we plan to show sample queries for the user to try. This can be shown by using buttons with the action type as “reply”.

Code snippet to show a button with the text as “What is FOSSASIA?”:

var buttons = [{
                        Columns: 6,
                        Rows: 1,
                        Text: "What is FOSSASIA? ",
                        "ActionType": "reply",
                        "ActionBody": "What is FOSSASIA?",
                        // text styling here
                    }];

For the response to “How to contribute”, we show some messages to help the user contribute to SUSI.AI. These messages also just need buttons with it, to be able to apply the necessary action.

We respond with 2 messages to the user, both the messages have a button.

For example, a button to visit the SUSI.AI Gitter channel:

var buttons = [{
                    Columns: 6,
                    Rows: 1,
                       Text: "<font color=#323232><b>Chat on Gitter</b></font>",
                      ActionType: "open-url",
                      ActionBody: "https://www.gitter.im/fossasia/susi_server",
                      // text styling here
            }];

This way we have successfully added the “Get started” option to our Viberbot and handled all the subsequent steps.

Resources:

  1. Viber video managing chat extensions by Ingrid Lunden from Tech crunch.
  2. Develop a chat bot with node js by Slobodan Stojanović from smashing magazine.
Continue ReadingShowing “Get started” button in SUSI Viber bot

Join Codeheat Coding Contest 2017/18

Codeheat is a coding contest for developers interested in contributing to Open Source software and hardware projects at FOSSASIA.  Join development of real world software applications, build up your developer profile, learn new new coding skills, collaborate with the community and make new friends from around the world! Sign up for #CodeHeat here now and follow Codeheat on Twitter.

The contest runs until 1st February 2018. All FOSSASIA projects take part in Codeheat including:

Grand prize winners will be invited to present their work at the FOSSASIA OpenTechSummit in Singapore from March 23rd -25th 2018 and will get 600 SGD in travel funding to attend, plus a free speaker ticket and beautiful Swag.

Our jury will choose three winners from the top 10 contributors according to code quality and relevance of commits for the project. The jury also takes other contributions like submitted weekly scrum reports and monthly technical blog posts into account, but of course awesome code is the most important item on the list.

Other participants will have the chance to win Tshirts, Swag and vouchers to attend Open Tech events in the region and will get certificates of participation.

codeheat-logo

Team mentors and jury members from 10 different countries support participants of the contest.

Participants should take the time to read through the contest FAQ and familiarize themselves with the introductory information and Readme.md of each project before starting to work on an issue.

Developers interested in the contest can also contact mentors through project channels on the FOSSASIA gitter.

Additional Links

Website: codeheat.org

Codeheat Twitter: twitter.com/codeheat_

Codeheat Facebook: facebook.com/codeheat.org

Participating Projects: All FOSSASIA Repositories on GitHub at github.com/fossasia

Continue ReadingJoin Codeheat Coding Contest 2017/18

Handling Data Requests in Open Event Organizer Android App

Open Event Organizer is a client side application of Open Event API Server created for event organizers and entry managers. The app maintains a local database and syncs it with the server when required. I will be talking about handling data requests in the app in this blog.

The app uses ReactiveX for all the background tasks including data accessing. When a user requests any data, there are two possible ways the app can perform. The one where app fetches the data directly from the local database maintained and another where it requests data from the server. The app has to decide one of the ways. In the Organizer app, AbstractObservableBuilder class takes care of this. The relevant code is:

final class AbstractObservableBuilder<T> {

   private final IUtilModel utilModel;
   private boolean reload;
   private Observable<T> diskObservable;
   private Observable<T> networkObservable;

   ...
   ...

   @NonNull
   private Callable<Observable<T>> getReloadCallable() {
       return () -> {
           if (reload)
               return Observable.empty();
           else
               return diskObservable
                   .doOnNext(item -> Timber.d("Loaded %s From Disk on Thread %s",
                       item.getClass(), Thread.currentThread().getName()));
       };
   }

   @NonNull
   private Observable<T> getConnectionObservable() {
       if (utilModel.isConnected())
           return networkObservable
               .doOnNext(item -> Timber.d("Loaded %s From Network on Thread %s",
                   item.getClass(), Thread.currentThread().getName()));
       else
           return Observable.error(new Throwable(Constants.NO_NETWORK));
   }

   @NonNull
   private <V> ObservableTransformer<V, V> applySchedulers() {
       return observable -> observable
           .subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread());
   }

   @NonNull
   public Observable<T> build() {
       if (diskObservable == null || networkObservable == null)
           throw new IllegalStateException("Network or Disk observable not provided");

       return Observable
               .defer(getReloadCallable())
               .switchIfEmpty(getConnectionObservable())
               .toList()
               .flatMap(items -> diskObservable.toList())
               .flattenAsObservable(items -> items)
               .compose(applySchedulers());
   }
}

 

DiskObservable is a data request to the local database and networkObservable is a data request to the server. The build function decides which one to use and returns a correct observable accordingly. The class object takes a boolean field reload which is used to decide which observable to subscribe. If reload is true, that means the user wants data from the server, hence networkObservable is returned to subscribe. Also switchIfEmpty in the build method checks whether the data fetched using diskObservable is empty, if found empty it switches the observable to the networkObservable to subscribe.

This class object is used for every data access in the app. For example, this is a code snippet of the gettEvents method in EventRepository class.

@Override
public Observable<Event> getEvents(boolean reload) {
   Observable<Event> diskObservable = Observable.defer(() ->
       databaseRepository.getAllItems(Event.class)
   );

   Observable<Event> networkObservable = Observable.defer(() ->
       eventService.getEvents(JWTUtils.getIdentity(getAuthorization()))
           ...
           ...
           .flatMapIterable(events -> events));

   return new AbstractObservableBuilder<Event>(utilModel)
       .reload(reload)
       .withDiskObservable(diskObservable)
       .withNetworkObservable(networkObservable)
       .build();
}

 

Links:
1. Documentation of ReactiveX API
2. Github repository link of RxJava – Reactive Extension for JVM

Continue ReadingHandling Data Requests in Open Event Organizer Android App