FOSSASIA at Google Code-In 2016 Grand Prize Trip

This year FOSSASIA came up with a whopping number of GCI participants, making it to the top. FOSSASIA is a mentor organization at the Google Code-In contest, which introduces pre-university students towards open source development.

Every year Google conducts the grand prize trip to all the GCI winners and I represented FOSSASIA as a mentor.

FOSSASIA GCI winners and Mentor at Google Mountain View Campus.

Day 1: Meet and Greet with the Diverse Communities

We all headed towards the San Francisco Google office and had a great time interacting with members from diverse open source organizations from different parts of the world. I had some interactive conversations with the kids, on how they scheduled their sleep hours in order to complete the task and got feedback from the mentors from different time zones! I was also overwhelmed while listening to their interests apart from open source contributions.

“I am a science enthusiast, mainly interested in Computer Science and its wide range of applications. I also enjoy playing the piano, reading, moving, and having engaging conversations with my friends. As a participant in the GCI contest, I got the chance to learn by doing, I got an insight of how it is like to work on a real open-source project, met some great people, helped others (and received help myself). Shortly, it was amazing, and I’m proud to have been a part of it. ” Shared by one of our Winner Oana Rosca.

There were people from almost 14 different countries, in fact, FOSSASIA, as a team, was the most diverse group 🙂

Day 2: Award Ceremony

We had two winners from FOSSASIA, Arkhan Kaiser from Indonesia and Oana Rosca from Romania. There were 8 organizations with 16 winners. The award ceremony was celebrated on day 2 and each winner was felicitated by Chris DiBona, the director of the Google open source team.

Talks by Googlers

We had amazing speakers from Google who spoke about their work, experiences, and journey to Google. Our first speaker was Jeremy Allison, a notable contributor to “Samba” which is a free software re-implementation of the SMB/CIFS networking protocol. He spoke on “How the Internet works” and gave a deeper view of the internet magic.

We had various speakers from different domains such as Grant Grundler from the Chrome team, Lyman Missimer from Google Expeditions, Katie Dektar from the Making and Science team, Sean Lip from Oppia(Googler and Oppia org admin), Timothy Papandreou from Waymo and Andrew Selle from TensorFlow.

Day 3: Fun Activities

We had various fun activities organized by the Google team. I had a great time cruising towards the Alcatraz island.  Later we had a walk on the Golden Gate bridge. Here comes the fun part of the tour “the cruise dinner” which was the best part of the day.

Day 4: End of the trip

Oana, Arkhan and I gave a nice presentation about our work during GCI. We spoke about all the amazing projects under FOSSASIA. One cool thing we did is that we “Doodled” our presentation 🙂 Here are few images from the actual presentation.

The day ended well with loads of good memories and information. Thanks to the open source technologies and their availability along with a beautiful friendly community, these memories and connections will now remain for a lifetime.

Creating A Dockerfile For Yacy Grid MCP

The YaCy Grid is the second-generation implementation of YaCy, a peer-to-peer search engine. A YaCy Grid installation consists of a set of micro-services which communicate with each other using a common infrastructure for data persistence. The task was to deploy the second-generation of YaCy Grid. To do so, we first had created a Dockerfile. This dockerfile should start the micro services such as rabbitmq, Apache ftp and elasticsearch in one docker instance along with MCP. The microservices perform following tasks:

  • Apache ftp server for asset storage.
  • RabbitMQ message queues for the message system.
  • Elasticsearch for database operations.

To launch these microservices using Dockerfile, we referred to following documentations regarding running these services locally: https://github.com/yacy/yacy_grid_mcp/blob/master/README.md

For creating a Dockerfile we proceeded as follows:

FROM ubuntu:latest
MAINTAINER Harshit Prasad# Update
RUN apt-get update
RUN apt-get upgrade -y# add packages
# install jdk package for java
RUN apt-get install -y git openjdk-8-jdk

#install gradle required for build
RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository ppa:cwchien/gradle
RUN apt-get update
RUN apt-get install -y wget
RUN wget https://services.gradle.org/distributions/gradle-3.4.1-bin.zip
RUN mkdir /opt/gradle
RUN apt-get install -y unzip
RUN unzip -d /opt/gradle gradle-3.4.1-bin.zip
RUN PATH=$PATH:/opt/gradle/gradle-3.4.1/bin
ENV GRADLE_HOME=/opt/gradle/gradle-3.4.1
ENV PATH=$PATH:$GRADLE_HOME/bin
RUN gradle -v

# install apache ftp server 1.1.0
RUN wget http://www-eu.apache.org/dist/mina/ftpserver/1.1.0/dist/apache-ftpserver-1.1.0.tar.gz
RUN tar xfz apache-ftpserver-1.1.0.tar.gz

# install RabbitMQ server
RUN wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-generic-unix-3.6.6.tar.xz
RUN tar xf rabbitmq-server-generic-unix-3.6.6.tar.xz

# install erlang language for RabbitMQ
RUN apt-get install -y erlang

# install elasticsearch
RUN wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.0.tar.gz
RUN sha1sum elasticsearch-5.5.0.tar.gz
RUN tar -xzf elasticsearch-5.5.0.tar.gz

# clone yacy_grid_mcp repository
RUN git clone https://github.com/nikhilrayaprolu/yacy_grid_mcp.git
WORKDIR /yacy_grid_mcp

RUN cat docker/configftp.properties > ../apacheftpserver1.1.0/res/conf/users.properties

# compile
RUN gradle build
RUN mkdir data/mcp-8100/conf/ -p
RUN cp docker/config-mcp.properties data/mcp-8100/conf/config.properties
RUN chmod +x ./docker/start.sh

# Expose web interface ports
# 2121: ftp, a FTP server to be used for mass data / file storage
# 5672: rabbitmq, a rabbitmq message queue server to be used for global messages, queues and stacks
# 9300: elastic, an elasticsearch server or main cluster address for global database storage
EXPOSE 2121 5672 9300 9200 15672 8100

# Define default command.
ENTRYPOINT [“/bin/bash”, “./docker/start.sh”]

 

We have created a start.sh file to start RabbitMQ and Apache FTP services. At the end, for compilation gradle run will be executed.

adduser –disabled-password –gecos ” r
adduser r sudo
echo ‘%sudo ALL=(ALL) NOPASSWD:ALL’ >> /etc/sudoers
chmod a+rwx /elasticsearch-5.5.0 -R
su -m r -c ‘/elasticsearch-5.5.0/bin/elasticsearch -Ecluster.name=yacygrid &’
cd /apacheftpserver1.1.0
./bin/ftpd.sh res/conf/ftpdtypical.xml &
/rabbitmq_server-3.6.6/sbin/rabbitmq-server -detached
sleep 5s;
/rabbitmq_server-3.6.6/sbin/rabbitmq-plugins enable rabbitmq_management
/rabbitmq_server3.6.6/sbin/rabbitmqctl add_user yacygrid password4account
echo [{rabbit, [{loopback_users, []}]}]. >> /rabbitmq_server-3.6.6/etc/rabbitmq/rabbitmq.config
/rabbitmq_server-3.6.6/sbin/rabbitmqctl set_permissions -p / yacygrid “.*” “.*” “.*”
cd /yacy_grid_mcp
sleep 5s;
gradle run

 

start.sh will first add username and then password. Then it will start RabbitMQ along with Apache FTP.  For username and password, we have created a separate files to configure their properties during Docker run which can be found here:

The logic behind running all the microservices in one docker instance was: creating each container for microservice and then link those containers with the help of docker-compose.yml file.

The Dockerfile which we have created was corresponding to one image. Another image was elasticsearch which was linked to this Dockerfile. The latest version of elasticsearch image was already available on their site: https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html

We configured the docker-compose.yml file according to the reference link provided above. The docker-compose file can be found here: https://github.com/yacy/yacy_grid_mcp/blob/master/docker/docker-compose.yml

The source code for the implementation of whole structure can be found here: https://github.com/yacy/yacy_grid_mcp/tree/master/docker

Resources

 

How to Parse HTML Tags and Anchor Clickable Links in SUSI Android App

Html tags are used to define how contents of a webpage should be formatted and displayed. Sometimes the SUSI answer type response contains some html tags but showing these html tags without parsing would distort the normal text flow in SUSI Android.

For the query ‘Ask me something’ SUSI’s reply is

“data”: [
     {
      “question”: “Which soccer team won the Copa América 2015 Championship ? “,                                          
     }]

In SUSI Android this message looks like

As you can see that showing html tags without parsing distort the normal text flow. So we need to parse html tags properly. We use Html class for this purpose. Html class is present in android.text package and you can import it in the class where you want to use it.

import android.text.Html

fromHtml method of Html class is used to parse html tags. But for API level less than 24 and equal to or greater than 24 we use different parameters in fromHtml method.

For API level less than 24 we used

Html.fromHtml(model.getContent())

But for API level equal to or greater than 24 we have to use

Html.fromHtml(model.getContent(), Html.FROM_HTML_MODE_COMPACT)

Here the second parameter is legacy flags which decides how text inside a tag will be shown after parsing.

In case of Html.fromHtml(String string) legacy flag is by default FROM_HTML_MODE_LEGACY. It indicates that separate block-level elements with blank lines.

So after parsing html tags using fromHtml

But return type of fromHtml method is Spanned so if you need String then you have to convert it into string using toString() method.

Anchor action type in susi response contains link and text.

       “link”: “https://www.openstreetmap.org/#map=13/1.2896698812440377/103.85006683126556”,
       “text”: “Link to Openstreetmap: Singapore”

Here the text is the text we show in textview and link is used to show web content in the browser when user click on text. So first link and text are attached together like

“<a href=\”” +susiResponse.getAnswers().get(0).getActions().get(i).getAnchorLink() + “\”>”
+ susiResponse.getAnswers().get(0).getActions().get(1).getAnchorText() + “</a>”

Here text between the tag is description of link and after parsing we show this text in textview. It can be parsed using fromHtml method of Html class and textview is made clickable by

chatTextView.setMovementMethod(LinkMovementMethod.getInstance());

Resources

Reset Password Option in SUSI Android App

Login and signup are an important feature for some android apps like chat apps because the user will want to save and secure personal messages from others. In SUSI Android app we provide a token to a logged-in user for a limit period of time so that once the user logs in and someone else gets access to the device, then he/she can’t use the user account for a long period of time. It is a security provided from our side but the user also has to maintain some security. Cyber security risks have increased and hacking technologies have improved a lot in the past 10 years. So, using the same password for a long period of time absolutely puts your account security at risk. So to keep your account secure you should change/reset your password regularly. In this blog post, I will show you how reset password option is implemented in SUSI Android app.

Layout design for reset password

Reset password option is added in the setting. When the user clicks on reset password option a dialog box pops up. There are three textinputlayout boxes – each for the current password, new password and confirm password. I have used textinputlayout instead of simple edittext box because it helps user to show first “hint” and when user taps on, hint will come up with text over it as floating label so that the user can understand what to add in that box and also in case of error we can show that error to user.

Reset Password implementation

On clicking reset password option a dialog box appears in which user inserts the current password, new password and confirm password to confirm the new password. Before sending new password to the server we perform two checks

  1. New password should not be empty and length of new password should be at least six.
  2. New password and confirm password must be same.
if (!CredentialHelper.isPasswordValid(newPassword)) {

settingView?.passwordInvalid(Constant.NEW_PASSWORD)

return

}

if (newPassword != conPassword) {

settingView?.invalidCredentials(false, Constant.NEW_PASSWORD)

return

}

And when these two checks are passed we send “new password” to server.

Endpoint use to reset password is

http://api.susi.ai/aaa/changepassword.json?changepassword=your mail id&password=current password&newpassword=newpassword

As you can see it needed three parameters

  • changepassword: Your email id
  • password : Your current password
  • newpassword: Your new password

When user logs in, we save user’s email id so that the user doesn’t have to provide it again and again when the user wants to change the password.

utilModel.saveEmail(email)

The user provides current password and new password through dialog box. We used resetPassword method to reset the password. We send these three parameters to the server using resetPassword method and if the password changed successfully then server sends a message.

override fun resetPassword(password: String, newPassword: String, listener: ISettingModel.onSettingFinishListener) {

  val email = PrefManager.getString(Constant.SAVE_EMAIL, null)

  resetPasswordResponseCall = ClientBuilder().susiApi

          .resetPasswordResponse(email,password,newPassword)

  resetPasswordResponseCall.enqueue(object : Callback<ResetPasswordResponse> {

  } )

}

We used retrofit library for network call and resetPasswordResponse is a model class using which we are retrieving server response.

Reference

Displaying essential features when the Phimpme Application starts

In this blog, I will explain how I implemented showcase View to display all the essential features of the Phimpme Android application when the application starts first. In this, the users will know which activity is used for what purpose.  

Importing material design Showcase View

I used material design showcase in Phimpme  Android application to take the benefit of the latest Android design and to add more text on the screen which is easily visible by the users. We need to add the following to our gradle.

compile 'com.github.deano2390:MaterialShowcaseView:1.1.0'

There is a very good repository in Github for material design Showcase view which we have used here.

Implementing Material design showcaseView on the desired activity

In Phimpme Android application we have three main activity on the home screen. Namely:

  • Camera
  • Gallery
  • Accounts Activity

Camera Activity and Gallery Activity is used to take pictures and select the picture respectively. Accounts Activity contains more than 10 accounts of various social media platforms and storage platform. When the application starts my aim is to display the function of all three activities in a showcase View. it is implemented in the following Steps:

Step 1

Import all the module from the Material showcase view we have used in the gradle.

import uk.co.deanwild.materialshowcaseview.MaterialShowcaseSequence;
import uk.co.deanwild.materialshowcaseview.MaterialShowcaseView;
import uk.co.deanwild.materialshowcaseview.ShowcaseConfig;

Step 2

Get the reference all the buttons you want to show the features. These buttons will be highlighted when the showcase View is displayed.

nav_home = (BottomNavigationItemView) findViewById(R.id.navigation_home);
nav_cam = (BottomNavigationItemView) findViewById(R.id.navigation_camera);
nav_acc = (BottomNavigationItemView) findViewById(R.id.navigation_accounts);

Step 3

In Phimpme Android application I have used to display the features of three navigation buttons. So, to display the features of more than one button or View we have to use MaterialShowcaseSequence class to display the features of the buttons in a sequence, that is one after the other.

In the onCreate activity, I am calling presentShowcaseSequence function. This function has a delay time. This delay time is required to wait for four seconds until the splash screen activity is over and the activity is started.

private void presentShowcaseSequence() {
   ShowcaseConfig config = new ShowcaseConfig();
   config.setDelay(4000); // half second between each showcase view
   MaterialShowcaseSequence sequence = new MaterialShowcaseSequence(this, SHOWCASE_ID);
   sequence.setOnItemShownListener(new MaterialShowcaseSequence.OnSequenceItemShownListener() {
       @Override
       public void onShow(MaterialShowcaseView itemView, int position) {
       }
   });
   sequence.setConfig(config);

Step 4

Set the initial target Button. This target button will be pointed first when the app is launched for the first time.

sequence.addSequenceItem(nav_home, getResources().getString(R.string.home_button), getResources().getString(R.string.ok_button));

 

Step 5

Add subsequent target buttons to display the features of that buttons. To add more subsequent target buttons we will use function addSequenceitem. To set the target we have specify the button which we want to focus in setTarget(Button). We need to display the text which will show the important features in regarding that activity in setContentText(text to be displayed). For a dismiss button we need to specify the a string in setDismissText(Dismiss button string)

sequence.addSequenceItem(
       new MaterialShowcaseView.Builder(this)
               .setTarget(nav_cam)
               .setDismissText(getResources().getString(R.string.ok_button))
               .setContentText(getResources().getString(R.string.camera_button))
               .build()
);
sequence.addSequenceItem(
       new MaterialShowcaseView.Builder(this)
               .setTarget(nav_acc)
               .setDismissText(getResources().getString(R.string.ok_button))
               .setContentText(getResources().getString(R.string.accounts_button))
               .build()
);
sequence.start();

Sequence.start is used to display the showcase.

Conclusion

Using this method users can easily have the knowledge of the functionality of the application and can navigate through the activities without wasting a lot of time in figuring out the functionality of the application.

Github

Resources

 

Adding download feature to LoklakWordCloud app on Loklak apps site

One of the most important and useful feature that has recently been added to LoklakWordCloud app is enabling the user to download the generated word cloud as a png/jpeg image. This feature will allow the user to actually use this app as a tool to generate a word cloud using twitter data and save it on their disks for future use.

All that the user needs to do is generate the word cloud, choose an image type (png or jpeg) and click on export as image, a preview of the image to be downloaded will be displayed. Just hit enter and the word cloud will be saved on your disk. Thus users will not have to use any alternative process like taking a screenshot of the word cloud generated, etc.

Presently the complete app is hosted on Loklak apps site.

How does it work?

What we are doing is, we are exporting a part of the page (a div) as image and saving it. Apparently it might seem that we are taking a screenshot of a particular portion of a page and generating a download link. But actually it is not like that. The word cloud that is being generated by this app via Jqcloud is actually a collection of HTML nodes. Each node contains a word (part of the cloud) as a text content with some CSS styles to specify the size and color of that word. As user clicks on export to image option, the app traverses the div containing the cloud. It collects information about all the HTML nodes present under that div and creates a canvas representation of the entire div. So rather than taking a screenshot of the div, the app recreates the entire div and presents it to us. This entire process is accomplished by a lightweight JS library called html2canvas.

Let us have a look into the code that implements the download feature. At first we need to create the UI for the export and download option. User should be able to choose between png and jpeg before exporting to image. For this we have provided a dropdown containing the two options.

<div class="dropdown type" ng-if="download">
                <div class="dropdown-toggle select-type" data-toggle="dropdown">
                  {{imageType}}
                <span class="caret"></span></div>
                <ul class="dropdown-menu">
                  <li ng-click="changeType('png', 'png')"><a href="">png</a></li>
                  <li ng-click="changeType('jpeg', 'jpg')"><a href="">jpeg</a></li>
                </ul>
              </div>
              <a class="export" ng-click="export()" ng-if="download">Export as image</a>

In the above code snippet, firstly we create a dropdown menu with two list items, png and jpeg. With each each list item we attach a ng-click event which calls changeType function and passes two parameters, image type and extension.

The changeType function simply updates the current image type and extension with the selected ones.

$scope.changeType = function(type, ext) {
        $scope.imageType = type;
        $scope.imageExt = ext;
    }

The ‘export as image’ on clicking calls the export function. The export function uses html2canvas library’s interface to generate the canvas representation of the word cloud and also generates the download link and attaches it to the modal’s save button (described below). After everything is done it finally opens a modal with preview image and save option.

$scope.export = function() {
        html2canvas($(".wordcloud"), {
          onrendered: function(canvas) {
            var imgageData = canvas.toDataURL("image/" + $scope.imageType);
            var regex = /^data:image\/jpeg/;
            if ($scope.imageType === "png") {
                regex = /^data:image\/png/;
            }
            var newData = imgageData.replace(regex, "data:application/octet-stream");
            canvas.style.width = "80%";
            $(".wordcloud-canvas").html(canvas);
            $(".save-btn").attr("download", "Wordcloud." + $scope.imageExt).attr("href", newData);
            $("#preview").modal('show');
          },
          background: "#ffffff"
        });
    }

At the very beginning of this function, a call is made to html2canvas module and the div containing the word cloud is passed as a parameter. An object is also passed which contains a callback function defined for onrendered key. Inside the callback function we check the current image type and generate the corresponding url from the canvas. We display this canvas in the modal and set this download url as the href value of the modal’s save button.

Finally we display the modal.

The modal simply contains the preview image and a button to save the image on disk.

A sample image produced by the app is shown below.

Important resources

  • Know more about html2canvas here.
  • Know more about Jqcloud here.
  • View the app source here.
  • View loklak apps site source here.
  • View Loklak API documentation here
  • Learn more about AngularJS here.

Implementing Feedback Feature in SUSI Android App

Recently, on SUSI Server, a new servlet was added which is used to rate SUSI Skills either positive or negative. The server stores the rating of a particular skill in a JSON file. These ratings help in improving answers provided by SUSI. So, the server part is done and it was required to implement this in the SUSI Android App. In this blog, I will cover the topic of implementation of the Rating or Feedback feature in SUSI Android App. This will including all the cases when feedback should be sent, when it should not be sent, when to send positive feedback, when to send negative feedback, etc.

API Information

For rating a SUSI Skill, we have to call on  /cms/rateSkill.json providing 5 parameters which are:

  1. model: The model of SUSI Skill. (String)
  2. group: The Group under the model in which that particular skill resides. (String)
  3. language: The language of skill. (String)
  4. skill: This is skill name. (String)
  5. rating: This can be two strings, either “positive” or “negative”. String)

Basically, in the SUSI Skill Data repo (in which all the skills are stored), models, groups language etc are part of folder structure.

So, if a skill is located here

https://github.com/fossasia/susi_skill_data/blob/master/models/general/Knowledge/en/news.txt

This would mean

model = general

group = Knowledge

language = en

skill = news

rating = positive/negative

Implementation in SUSI Android App

    

So, when the like button on a particular skill is clicked, a positive call is made and when the dislike button is clicked, a negative call is made.

Let’s see example when the thumbs up button or like button is clicked.

There can be three cases possible:

  1. None of Like button or dislike button is clicked already: In this case, initially, both like and dislike button will be transparent/hollow. So, when like button is clicked, the like button will be colored blue and a call will be made with positive feedback.
  2. Like button is already clicked: In this case, like button is already clicked. So, it will already be blue. So, when user clicks again on positive button, it should get back to normal/hollow indicating rating which was sent is cancelled and a a call will be made with negative feedback thus cancelling or neutralizing the earlier, positive feedback.
  3. Dislike button is already clicked: In this case, the dislike button is already blue, indicating a negative call is already made. So, now when the like button is clicked, we need to cancel the earlier negative feedback call and sending another negative feedback call. Thus, sending two negative feedback calls. And after that coloring dislike button as blue.

Look at the code below. It is self explanatory. There are three if-else conditions covering all the above mentioned three cases.

thumbsUp.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       thumbsUp.setImageResource(R.drawable.thumbs_up_solid);
       if(!model.isPositiveRated() && !model.isNegativeRated()) {
           rateSusiSkill(Constant.POSITIVE, model.getSkillLocation(), context);
           setRating(true, true);
       } else if(!model.isPositiveRated() && model.isNegativeRated()) {
           setRating(false, false);
           thumbsDown.setImageResource(R.drawable.thumbs_down_outline);
           rateSusiSkill(Constant.POSITIVE, model.getSkillLocation(), context);
           sleep(500);
           rateSusiSkill(Constant.POSITIVE, model.getSkillLocation(), context);
           setRating(true, true);
       } else if (model.isPositiveRated() && !model.isNegativeRated()) {
           rateSusiSkill(Constant.NEGATIVE, model.getSkillLocation(), context);
           setRating(false, true);
           thumbsUp.setImageResource(R.drawable.thumbs_up_outline);
       }
   }
});

Similarly for when dislike button is clicked, the above three mentioned cases still hold resulting in this code snippet.

thumbsDown.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       thumbsDown.setImageResource(R.drawable.thumbs_down_solid);
       if(!model.isPositiveRated() && !model.isNegativeRated()) {
           rateSusiSkill(Constant.NEGATIVE, model.getSkillLocation(), context);
           setRating(true, false);
       } else if(model.isPositiveRated() && !model.isNegativeRated()) {
           setRating(false, true);
           thumbsUp.setImageResource(R.drawable.thumbs_up_outline);
           rateSusiSkill(Constant.NEGATIVE, model.getSkillLocation(), context);
           sleep(500);
           rateSusiSkill(Constant.NEGATIVE, model.getSkillLocation(), context);
           setRating(true, false);
       } else if (!model.isPositiveRated() && model.isNegativeRated()) {
           rateSusiSkill(Constant.POSITIVE, model.getSkillLocation(), context);
           setRating(false, false);
           thumbsDown.setImageResource(R.drawable.thumbs_down_outline);
       }
   }
});

Summary

So, this blog talked about how the Feedback feature in SUSI Android App is implemented. This included how a network call is made, logic for sending positive/negative feedback, logic to withdraw feedback etc. So, If you are looking forward to contribute to SUSI Android App, this can help you a little. But if not so, this may also help you in understanding and how rating mechanism in social media websites like Facebook, Twitter, Quora, Reddit, etc work.

References

  1. To know about servlets https://en.wikipedia.org/wiki/Java_servlet
  2. To see how to implement one https://www.javatpoint.com/servlet-tutorial
  3. To see how to make network calls in android using Retrofit https://guides.codepath.com/android/Consuming-APIs-with-Retrofit
  4. To see how to implement click listeners on button https://developer.android.com/reference/android/view/View.OnClickListener.html

Reset Password Functionality in SUSI iOS

Reset Password as the name suggests is one of the features in the SUSI iOS app which allows a user to change his/her password when they are logged in. This feature was added because a user would want to change his password sometimes to prevent unauthorized access or make his account security stronger. We can find many popular apps online such as Facebook, Gmail, which allow the user to reset their password. The way this is done is pretty simple and all we need from the user is his current and the new password he/she wants to set. In this blog post, I am going to explain step by step how this is implemented in the iOS client.

Implementation

The option to Reset Password is provided to the user under the Settings Controller. On selecting the row, the user is presented with another view which asks the user for his/her current password, new password, and another field to confirm the newly entered password.

First, the user needs to provide his current password followed by the new password. The user’s current password is required just to authenticate that the account’s owner is requesting the password change. The new password field is followed by another field called confirm password just to make sure there isn’t any typo.

Now when the field is filled, the user clicks the `Reset password` button at the bottom. What happens here is, first, the fields are validated to ensure the correct length of the passwords followed by an API request to update the same. The endpoint for the same is as below:

http://api.susi.ai/aaa/changepassword.json?changepassword=user_email&password=current _pass&newpassword=new_pass&access_token=user_access_token

This endpoint requires 3 things:

  • Current Password
  • New Password
  • User’s email
  • Access Token obtained at the time of login
func validatePassword() -> [Bool:String] {
        if let newPassword = newPasswordField.text,
            let confirmPassword = confirmPasswordField.text {
            if newPassword.characters.count > 5 {
                if newPassword == confirmPassword {
                    return [true: ""]
                } else {
                    return [false: ControllerConstants.passwordDoNotMatch]
                }
            } else {
                return [false: ControllerConstants.passwordLengthShort]
            }
        }
        return [false: Client.ResponseMessages.ServerError]
    }

Initially, we were not saving the user’s email, so we added the user’s email to the User’s object which is saved at the time of login.

if var userData = results {
userData[Client.UserKeys.EmailOfAccount] = user.email
UserDefaults.standard.set(userData, forKey: ControllerConstants.UserDefaultsKeys.user)
self.saveUserGlobally(user: currentUser)
}

At last, the API call is made which is implemented as below:

let params = [
  Client.UserKeys.AccessToken: user.accessToken,
  Client.UserKeys.EmailOfAccount: user.emailID,
  Client.UserKeys.Password: currentPasswordField.text ?? "",
  Client.UserKeys.NewPassword: newPasswordField.text ?? ""
]
Client.sharedInstance.resetPassword(params as [String : AnyObject], { (_, message) in
  DispatchQueue.main.async {
    self.view.makeToast(message)
    self.setUIActive(active: false)
  }
})

Below is the final UI.

Reference

Performing Diode Clipping and Clamping Experiment in PSLab Android

We can perform experiments like diode clipping and clamping using PSLab Android. A circuit which removes the peak of a waveform is known as a clipper. Diode clipper cuts off the top half or lower half or both top and lower half of the input signal. 

Different types of clipping circuits listed below

Different Clipping Experiments

A clamper circuit adds the positive dc component to the input signal to push it to the positive side. Similarly, a clamper circuit adds the negative dc component to the input signal to push it to the negative side. It basically shifts the input signal without changing the shape of the signal.

Different Clamping Experiments

Apparatus

Diode, Resistance, Capacitor (only for diode clamping), Breadboard, Wires and PSLab

Adding Diode Clipping Experiment support in PSLab Android App

To support Diode Clipping Experiment we require generating a sine wave and a dc component. This can be done using W1 and PV1 pins in PSLab device. Both input and output signals can be read using CH1 and CH2. So, when the Diode Clipping Experiment needs to be performed the following code needs to be implemented

scienceLab.setSine1(5000);
scienceLab.setPV1(//progress of the seekbar);

The signals are recorded using Oscilloscope Activity.

Adding Diode Clamping Experiment support in PSLab Android App

Diode Clamping Experiment was implemented similarly to Diode Clipping Experiment. The following are the screenshots of the experiment.     

The following is a glimpse of Diode Clamping Experiment performed using PSLab device using PSLab Android App.

Resources

  1. Read more about Clipper Circuits –
  2. Read more information about Clamping Circuits –