If you’re a web administrator or website owner, then you are bound to know the ugly truth that is the Spam Bot. Someone, somewhere in the world must have made a deal with the Devil in hopes of a larger payout that didn’t exactly pan out the way they.
The goal of the volunteer system (Engelsystem) is to facilitate the work of event organizers and event volunteers. It would be creating problems if bots signup for shifts and fill all the vacancies.
Thanks to the mastermind behind them, those pesky little underlings crawl the web ready to cause mischief at every turn. This means more work and more time eaten up for the honest web admin/event organizer who is left to clean up the mess left in their wake.
What Is CAPTCHA?
CAPTCHAs are nothing new to the experienced web surfer. Sites/web apps, both large and small, use the system for one reason or another.
But, ever wonder where in the world the people who coined the phrase, CAPTCHA, came up with that nonsensical name? Well, you may find it interesting to know that the strange word is actually a clever acronym meaning the following:
Completely Automated Public Test to tell Computers and Humans Apart.
What a mouthful! Now aren’t you happy that they shortened it?
The actual meaning of the word essentially explains exactly what its purpose is: keeping pesky bots out and letting in well-meaning humans (or at least that is the hope).
We worked on implementing Google reCaptcha to the registration form and to the shifts signup page.
On websites using this new API, a significant number of users will be able to securely and easily verify they’re human without actually having to solve a CAPTCHA. Instead, with just a single click, they’ll confirm they are not a robot.
If the System is hosted on an online server, the user needs to register and get the API keys for implementing Google reCaptcha here.
Final Thoughts
Spam is a big issue for all websites, including sites ran on WordPress. Although CAPTCHA forms don’t completely eliminate spam mongers, when you use it with other popular spam blocking plugins like Akismet, you really do have the advantage on the spam bot battlefield.
For the Open Event android app we were using retofit 1.9 with an okhttp stack plus a gson parser but recently retrofit 2.0 was released and it was a major update in the sense that it a lot of things have been changed.
For starters, you don’t have to declare synchronous and asynchronous requests upfront and you can just decide that while executing. The code for that will look something like this. This is how we define our request methods in our api service
import retrofit.Call;
public interface APIService {
@POST(“/list”)
Call<Repo> loadRepo();
}
Now if we want to make a synchronous request, we can make it like
and for an asynchronous request, we can call enqueue()
Call<Repo> call = service.loadRepo();
call.enqueue(new Callback<Repo>() {
@Override
public void onResponse(Response<Repo> response) {
// Get result Repo from response.body()
}
@Override
public void onFailure(Throwable t) {
}
});
And another thing that changed in the async call throws a throwable on failure, so essentially the RetrofitError class is gone and since we were using that in our app, we had to modify the whole error handling in the app, basically from the grounds up.
So, when we decided to move to retrofit 2 after the stable version was released, we had to change a lot of code and the main part that was affected was the error handling. So, replacing the retrofitError class, I used the throwable directly to retrieve the error type something like this
This was ofcourse for all failure events. And to handle all response events I compared the HTTP status codes and displayed the errors :
Integer statusCode = response.getStatusCode();
if (statusCode.equals(404)) {
// Show Errors in a dialog
showErrorDialog(“HTTP Error”, statusCode + “Api Not Found”);
}
This is how we can compare other HTTP errors in retrofit and assign the correct status accordingly. I personally think that this is a better implementation than Retrofit 1.9 and the RetrofitError was a bit tedious to work with. It wasn’t very thought of before implementation because it was not easy to tell what kind of error exactly occured. With Response codes, one can see what are the exact error one faces and can gracefully handle these errors.
The import to git script was further enhanced to support the feature whereby a user can specify the name of the object in the sTeam directory when a single object is been imported.
The user can now import a single object to the steam work area using the import-from-git script.
The command works for objects of all mime-types.
Two formats for the command are supported.
Issue.
Github Issue
Github PR
Add utility to support single import in import-from-git script .
This would create an object with the name ab.mp3 in the sTeam directory. If the object exists from before, the contents of it will be over written with the contents of the object from the git-folder.
Note: Here ‘/’ at the end of the steam directory is used as a distinguishing factor between a directory and an object. Be careful while passing the steam directory in the command or it would throw error.
List User’s
The command to list all the existing user’s in the sTeam server was also added to the steam-shell.
The user after creation needs to be activated by the root user. Thus a user can then access his steam-shell command line by passing the parameters of user name, host name or port number.
./steam-shell.pike -u uname -h hname -p pno
Passing Arguments to the sTeam-shell
The sTeam shell was modified during it’s integration with vi. This had introduced a bug where by the above parameters where not been able to pass along when a command to the sTeam-shell was passed as an argument. The issue was addressed and resolved.
The user can pass arguments like user name, host and port-number to the steam-shell.pike along with the steam-commands.
Issue.
Github Issue
Github PR
Add utility to support passing arguments to the sTeam-shell.
The action create, delete and list now support user operations.
Example:
To create a user.
create user test
The terminal would ask for password and email-id.
To delete a user
delete user test
To list all the users
list users
Create a file
The command to create a file of any type was added to the sTeam-shell. The code for creation and deletion of objects in the sTeam shell was modified and optimized.
The user can now create a file of any type from the command line.
The mime-type of the file is auto-detected.
This would create a file with file name as specified in the given destination. The file name can be like xyz.txt / xyz.pike / xyz.jpg / xyz.mp3. The destination " . " means the current destination.
More commands for groups
The commands to create, join, leave and list groups were added by my colleague Siddhant Gupta. The branch was merged with my working repo. The merge conflicts were successfully resolved. More commands for operations of a group were added. A user can list all the members of a group, list groups that a user is member of and delete a group.
The steam-shell user can now send mails. The utility to support mails was added. The earlier web.spm package was analyzed to find the existing classes used in the web interface in order to support this utility. The browser.pike file can in handy.
The user will be notified about the logs and would be asked to input the name of the logs to open.
The log files include errors, events, fulltext.pike, graphic.pike, http, search.pike, security, server, slow_requests, smtp, spm..pike and tex.pike.
Enter the name of the log files you want to open.
Note: The filenames should be separated by ",".
Input the name of the log files to open. The log files would be then opened in a vi window. User can open multiple logs.
Opened Logs
Checkout the FOSSASIA Idea’s page for more information on projects supported by FOSSASIA.
So while making a sessions schedule for the open event app, I wanted to separate the sessions on the basis of the days they are scheduled for to improve the visual clarity. So to do this I had various approaches like add a filter to separate by date or add checkboxes to show only checked dates but I though they’d look ugly. Instead the best option was to add tabs in a fragment with a viewpager to scroll within them : It looks appealing, has simple and clean UI, easier to implement with the new design library. So, naturally I opted for using the Tablayout from the design Library.
Earlier, when the Support design library was not introduce, it was really a tedious job to add it to our app since we had to extend Listeners to check for tab changes and we had to manually open fragments when a tab was selected or unselected or even when it was reselected. Essentially this meant a lot of errors and memory leaks. In the design library we essentially need to add tablayout and a viewpager to our layout like this :
Next in our activity/ fragment, we can just inflate this view and create an adapter for the viewpager extending a FragmentPagerAdapter:
public class OurAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ScheduleViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title, int day) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Now I had to make dynamic number of tabs, since I wanted the app to customisable on the number of days listed in the json downloaded from the server. So, I made some changes in the traditional code. This is what we do in our activity/fragment’s onCreate/OnCreatView :
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
for (int i = 0; i < daysofEvent; i++) {
adapter.addFragment(new DayScheduleFragment(),title, dayNo);
}
viewPager.setAdapter(adapter);
scheduleTabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
scheduleTabLayout.setupWithViewPager(viewPager);
This is it. Now we have a basic working tablayout in a viewpager. This also has the capability to change according to the number of days specified in the json we have written.
Earlier without the design library, we would have to even add switch cases in the FragmentPagerAdapter like this :
public class OurAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
}
return null;
}
Then we would have to override methods to listen to activities in tabs :
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
And more code to listen for swiping within tabs in a viewpager:
/**
* on swiping the viewpager make respective tab selected
**/
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
You see how easy this got with the inclusion of TabLayout.
Now for the final product I made after inflating the fragments and adding recyclerviews for the schedule, I got this :
I urge you to try swipable tabs in your app as well. Adios till next time.
Have you seen a wizard form? I am sure you have. I think the usage of it is very common these days. I like it very much, too. I think its structure is extremely user-friendly, because it can help us to avoid discouraging users from filling the form with all data. As a user I don’t want to be pushed to fill long forms. It’s annoying. But while you use the wizard no matter how long the form is, firstly you can quickly see the progress of you work and then, don’t see it at once, just fill one field at a time.
To implement this on CommonsNet website I have decided to use AngularJS which makes it easy.
I have used Model View Controller which is a software design pattern for developing web applications. A Model View Controller pattern is made up of the following three parts
Model − It is the lowest level of the pattern responsible for maintaining data
View − It is responsible for displaying all or a portion of the data to the user
Controller − It is a software Code that controls the interactions between the Model and View.
This model helps us to isolate the application logic from the user interface layer and supports separation of concerns.
The ng-controller directive defines the application controller. A controller is a JavaScript Object
3. Then I have created views – five different html files for each wizard step. Please take a look at partials folder where you can find them.
4. Next, I have created a .Controller – WizardController in AngularJS.
var WizardController = app.controller("WizardController", function ($scope) {
// controller logic goes here
}
);
It is a JavaScript function. I have defined which view has to be displayed by .controller on each step. As you can see it’s quite easy and clear. You can quickly define and see which step is it , how is its name and which template should be used. It definitely enables you to maintain your app easier, because changes can be made quickly and does not influence on other part of code so you can take control over your code.
5. Then I have used this line of code to call to my WizardController to display and maintain my views and that’s it. See the progress on CommonsNet
<div id="wizard-container" ng-controller="WizardController as vm">
An important feature of websites these days with the advancement of smartphones is being responsive with device size. We nowadays not only worry about the various width of laptop or desktop, which don’t vary by a huge amount but also need to worry about tablets and phones which have a much lesser width. The website’s UI should not break and should be as easy to use on phones as it is on desktops/laptops. Using frameworks like bootstraps, Semantic-UI solves this problem to a large extent. But what if we need to modify certain parts by our own in case of mobile devices? How do we do that?
We can convert knitting patterns to svg (middle) which proves the concept but is still a different from the original (right)
Our goal is to create a knit-work exchange format. This includes the conversion to a scematic view of the knittting pattern as svg – to make it endlessly scalable and allow conversions to png, pdf and paper.
This week we ended the prototype of the SVG conversion. The positions are a bit off and instructions are placed above eachother. Most of the work is done.
We are also able to load and save knitting patterns a png files.
(1) (2)
(3)
We loaded them (1), converted them to a knitting pattern and then saved them again as png (2). This way we path our way towards using the ayab software and actually knitting the pattern. Also we can convert the knitting pattern to an svg consisting all of knit instructions (3). Here is the code for it in version 0.0.8.
>>> import knittingpattern
>>> from knittingpattern.convert.image_to_knittingpattern import *
>>> convert_image_to_knitting_pattern.path("head-band.png").temporary_path(".json")
"head-band.json"
>>> k = knittingpattern.load_from_path("head-band.json")
>>> k.to_svg(10).temporary_path(".svg")
"head-band.svg"
My objective was to write a script that will allow the user to open new files from inside the vim interface. There is a vim command available for normal files. However here I am not talking about normal files, these are files inside the steam structures, that is , inside rooms and containers. The commands that were doing this currently were edit.pike and the edit command from the steam-shell.
As I started working on it one of the issue I faced was that I could not use the code in edit.pike or the edit command in steam-shell because for that I would have had to start a new process and the vim window would have come up as an another new process. Due to these process using the same terminal window there would be an overlap and vim will not be able to function, this was one of the problems with the original implementation of the edit command, which I had solved in the first week of GsoC.
My colleague Ajinkya Wavare had finished his task wherein we could execute pike code from a vim terminal. For this he had modified steam-shell and was passing the pike code as an argument to the call of steam-shell. One advantage of executing pike code this way is that all the steam objects and variables are available to use with the pike code. Basically it is like executing code on debug.pike. I based my solution to the problem on this newly added feature. I was able to pass in pike code to steam-shell, this would start a new process, execute the code and return me the output.
The tasks that I needed to do with the pike code was:
Find the required object in the steam server.
Get the content of the object.
Save the content in a temporary file.
Once the file is saved by vim, update the file on the sever and the logs in the vim buffer.
I created a new steam command ‘Open’ and passed the full path of the object as an argument. Given the full path it was easy to find the object on the sever. I was able to fetch the contents and save it in a file. Now I had a big problem. The name of the temporary file was available in the pike script, I needed this name in the vim script to open the file in a new tab. I spend more than a day trying to come up with a solution for this problem. I was able to get the name of the file in the output of the pike script and this output could be read into a vim buffer. However this output had a lot of other content including the result of execution of other pike statements also. I had to use vim search and select tools to get the file name isolated and stored in a vim script variable. Once I achieved this my task was almost done. I used vim command to open this file and the log in a new vim tab.
The next step was to get this file to be uploaded to the server and the logs updated. Ideally when a file is opened from the steam-shell using the edit command, there is a piece of code that gets called every one second and performs this tasks, however this couldn’t be used when the file is opened from inside vim as the steam-shell process that gets the file closes before the file is opened in vim. So I couldn’t have a pike script constantly watching the file. The solution I came up with was using auto commands to execute a pike script when the file is saved and update the file on the server and also the logs. This completed my task.
Since I had a day left in the week I took up one more small task. This was due to a problem that arose due to my previous task that is letting users open multiple files for editing. There were too many vim buffers open at a time and it was a trouble closing them as :q used to be executed for each buffer. Therefore I made a used defined command in vim, :Q, that was able to close tabs at a time. :tabclose is a vim command that does the same thing however it cannot close the last tab, this shortcoming was overcome with :Q.
The command works for objects of all mime-types.
Two formats for the command are supported.
Format 1:
This would create the object in the sTeam directory. The new object would have the same name as the object in the git directory.
Format 2:
This would create an object with the name ab.mp3 in the sTeam directory. If the object exists from before, the contents of it will be over written with the contents of the object from the git-folder.