Ashutosh Chaudhary My Personal Blog http://aboutashu.com/ Mon, 13 Aug 2018 16:57:52 +0000 Mon, 13 Aug 2018 16:57:52 +0000 Jekyll v3.7.3 Getting started with Serverless and AWS <h1 id="serverless-setup-with-aws">Serverless setup with AWS</h1> <p>Setting up a completely automated serverless setup on AWS can be a very hefty task. It will require a lot of efforts, configuring various services, keeping a note of what to link where, IAM roles etc. This not only requires a lot of research but consumes a lot of time as well.</p> <p>Serverless solves all the problem of configurations, linking and creating roles and permissions, letting you focus on business logic and getting things done in few keystrokes.</p> <p>In this tutorial, I will be creating a sample “hello world” program in <em>Lambda</em> (NodeJS), using <em>API Gateway</em> which will output the results on browser. In the next tutorial, I will help setting up dynamodb so you can have a datastore. We can also use RDS.</p> <h2 id="prerequisites">Prerequisites</h2> <ol> <li>An AWS account</li> <li>Any local machine (I use linux)</li> </ol> <h2 id="setting-up-aws">Setting up AWS</h2> <p>Setting up AWS is the easy part. You just have to goto <a href="http://console.aws.amazon.com">console.aws.amazon.com</a> and signup for an account. You have to link a credit card for verification. Its free for an year so you won’t be charged and test out things for sake of this tutorial.</p> <p>Once account setup is done, go to IAM section and create a new user, making the access type <code class="highlighter-rouge">programmatic</code> (NOTE: it is going to provide you with access key id and secret which will be used later on).</p> <p>Next screen will take you to add permission to this user, where you can create a new group or choose from any existing one. Click <em>Create Group</em> to begin, which will bring a popup asking for name and roles. Since you are new, create a new group with any name of your choice. <strong>Select Administrator access</strong> as role for this user since it will be easiest route to go. Hit <em>Create Group</em> button.</p> <p>Move on to next step <em>Review</em> where you can tally if user have the administrator access and programmatic authentication type. Finally, hit <em>Create User</em> which will suffice and complete the process.</p> <p>You will be presented with the accesskey and secret which you should copy down somewhere safe. There is also a <em>download</em> option to download them in csv.</p> <blockquote> <p>ETA: 5 mins</p> </blockquote> <h2 id="setting-up-serverless">Setting up Serverless</h2> <p>We are going to need following AWS entities to get things rolling:</p> <ul> <li>Lambda (for processing)</li> <li>API Gateway (for API)</li> <li>CloudWatch (for logging)</li> <li>IAM roles (for permissions)</li> </ul> <p>This will be enough to get a presentable state of our demo up and running in minutes. Lets get things going.</p> <p>All serverless need is a config files which will determine how to configure things on AWS. To do so, First, it needs to know AWS account and region so it can use it to deploy applications.</p> <h3 id="1-setting-up-local-aws-credentials">1. Setting up local aws credentials</h3> <p><strong>Manual Way</strong></p> <ol> <li>Create a directory .aws in your home directory (~/.aws on *nix, C:\Users\USER_NAME\.aws).</li> <li>Create config file in .aws with following contents <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[default] output = json region = us-west-2 </code></pre></div> </div> </li> <li>Create credentials file in .aws with following contents <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[default] aws_access_key_id = &lt;your-access-key-id&gt; aws_secret_access_key = &lt;your-secret-access-key&gt; </code></pre></div> </div> <p>Read More: https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html</p> </li> </ol> <p>** Automated Way**</p> <ol> <li>Download and set AWS CLI on your machine. <a href="https://docs.aws.amazon.com/lambda/latest/dg/setup-awscli.html">Instructions here</a></li> <li>run <code class="highlighter-rouge">aws configure</code> and answer the prompt questions.</li> </ol> <h3 id="creating-serverless-configuration-file">Creating Serverless configuration file</h3> <ol> <li>Create a project directory and enter it</li> <li>Create a file called <code class="highlighter-rouge">serverless.yml</code></li> <li>Enter following content:</li> </ol> <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">service</span><span class="pi">:</span> <span class="s">serverless-helloworld</span> <span class="na">frameworkVersion</span><span class="pi">:</span> <span class="s2">"</span><span class="s">&gt;=1.1.0</span><span class="nv"> </span><span class="s">&lt;2.0.0"</span> <span class="na">provider</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">aws</span> <span class="na">runtime</span><span class="pi">:</span> <span class="s">nodejs8.10</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">SERVICE_NAME</span><span class="pi">:</span> <span class="s">${self:service}</span> <span class="na">WORLD</span><span class="pi">:</span> <span class="s1">'</span><span class="s">world'</span> <span class="na">functions</span><span class="pi">:</span> <span class="na">helloworld</span><span class="pi">:</span> <span class="na">handler</span><span class="pi">:</span> <span class="s">hello/index.hello</span> <span class="na">events</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">http</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">hello</span> <span class="na">method</span><span class="pi">:</span> <span class="s">get</span> <span class="na">cors</span><span class="pi">:</span> <span class="no">true</span> </code></pre></div></div> <p>Although, pretty much self explanatory, let me summarize this for you.</p> <p><code class="highlighter-rouge">provider</code> key tells serverless what aws providers are we going to use and which versions of them, such as lambda runner, dynamodb etc. This is kind of versioning aspect of the</p> <p>This is a good place to set <strong>environment variables</strong> too. For instance, we are setting up <em>SERVICE_NAME</em>, <em>WORLD</em> as variables, which can be accessed inside our lambda node functions as <code class="highlighter-rouge">process.env.SERVICE_NAME</code>, <code class="highlighter-rouge">process.env.WORLD</code>.</p> <p>Serverless supports <em>event per function</em> kinda configuration. Hence, we write the lambda handlers and the events on which it is going to respond. Various types of events are supported such as API Gateway, S3, SQS, CloudWatch etc. Since we are going to process as soon as we get an API request, we will be using API gateway event.</p> <p>We can respond to same kind of process in response to various kind of events. For ex- You may want to write logs if file is uploaded to s3, but also when certain API request is being made, same lambda handler can be used to handle both the events. For now, we will only respond to API event(HTTP).</p> <p>Hence, the basic configuration may look like:</p> <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">...</span> <span class="na">functions</span><span class="pi">:</span> <span class="s">&lt;custom-name&gt;</span><span class="pi">:</span> <span class="na">handler</span><span class="pi">:</span> <span class="s">&lt;file-location-without-js-suffix&gt;.&lt;method-name&gt;</span> <span class="na">events</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">&lt;event-name&gt;</span><span class="pi">:</span> <span class="s">&lt;event-configurations&gt;</span> <span class="pi">-</span> <span class="s">&lt;another-event-name&gt;</span><span class="pi">:</span> <span class="s">&lt;event-configurations&gt;</span> </code></pre></div></div> <p>Serverless configures events</p> <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">http</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">hello</span> <span class="na">method</span><span class="pi">:</span> <span class="s">get</span> <span class="na">cors</span><span class="pi">:</span> <span class="no">true</span> </code></pre></div></div> <p>This tells the event type will be http and values provides the configurations, such as for which path the event should be triggered etc. You got this gist.</p> <blockquote> <p>ETA: 10-15 mins</p> </blockquote> <h3 id="writing-actual-code">Writing actual code</h3> <p>Lets again look at the configuration, specifically this part:</p> <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="na">helloworld</span><span class="pi">:</span> <span class="na">handler</span><span class="pi">:</span> <span class="s">hello/index.hello</span> <span class="na">events</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">http</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">hello</span> <span class="na">method</span><span class="pi">:</span> <span class="s">get</span> <span class="na">cors</span><span class="pi">:</span> <span class="no">true</span> </code></pre></div></div> <p>This can be translated to:</p> <blockquote> <p>Create a file in the <code class="highlighter-rouge">hello</code> directory (relative to config file), called <code class="highlighter-rouge">index.js</code> which will have the function <code class="highlighter-rouge">hello</code> to handle the request and will provide the response.</p> </blockquote> <p>Lets write some code.</p> <p>NOTE: Since we are using node 8.9.0 (check config again), we can use ES6 features.</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// index.js</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="c1">// Getting query string parameters. It looks something like {a: 'b', c: 1}</span> <span class="kd">const</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">queryStringParameters</span> <span class="p">?</span> <span class="nx">event</span><span class="p">.</span><span class="nx">queryStringParameters</span> <span class="p">:</span> <span class="p">{}</span> <span class="kd">const</span> <span class="nx">body</span> <span class="o">=</span> <span class="s1">'Hello '</span> <span class="o">+</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">WORLD</span> <span class="kd">const</span> <span class="nx">responseType</span> <span class="o">=</span> <span class="p">{</span><span class="na">success</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> <span class="na">client_error</span><span class="p">:</span> <span class="mi">400</span><span class="p">,</span> <span class="na">server_error</span><span class="p">:</span> <span class="mi">500</span><span class="p">};</span> <span class="c1">// Success response</span> <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span> <span class="na">statusCode</span><span class="p">:</span> <span class="nx">responseType</span><span class="p">.</span><span class="nx">success</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span><span class="nx">body</span><span class="p">,</span> <span class="nx">params</span><span class="p">})</span> <span class="p">});</span> <span class="c1">// Or Error response like</span> <span class="cm">/* //let error = new TypeError('some error') callback(error, { statusCode: responseType.client_error, body: JSON.stringify({ error: 'Any error message' }), }); */</span> <span class="p">}</span> </code></pre></div></div> <p>Thats it. You are nearly ready to deploy all this. Just execute the following command and hit <code class="highlighter-rouge">Enter</code> key to deploy.</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>serverless deploy <span class="c"># or</span> <span class="nv">$ </span>sls deploy </code></pre></div></div> <p>Before making ourselves much happier and comfortable, lets first see what are we getting as input in our lambda handler and what and how are we outputting.</p> <p>Starting with the first line:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="c1">// shorthand for:</span> <span class="c1">// module.exports = function (event, context, callback) {</span> <span class="c1">// ...</span> </code></pre></div></div> <p>We get three parameters to lambda handler (for nodejs):</p> <ol> <li>event: Provides event sources and variables attached to any of <a href="https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html">AWS Event Sources</a></li> <li>context: This provides lambda context so that you can extract out any piece of information related to this function such as configurations, runtime operations etc. <a href="https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html">Read more</a></li> <li>callback: An optional parameter, which will be called after event loop becomes empty. In layman terms, this is the place which will be called “finally” and this is where your response should be.</li> </ol> <p>Lets dive straightaway into the code now.</p> <p>Getting query parameters of an Gateway request is quite easy. You can get them using <code class="highlighter-rouge">event.queryStringParameters</code>. <code class="highlighter-rouge">event</code> also provides other necessary info related to requests such as headers. Here is how a sample event object looks like:</p> <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="s2">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/test/hello"</span><span class="p">,</span><span class="w"> </span><span class="s2">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"Accept"</span><span class="p">:</span><span class="w"> </span><span class="s2">"application/json;q=0.9,image/webp,*/*;q=0.8"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Accept-Encoding"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gzip, deflate, lzma, sdch, br"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Accept-Language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"en-US,en;q=0.8"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"pathParameters"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"proxy"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hello"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"requestContext"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"accountId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123456789012"</span><span class="p">,</span><span class="w"> </span><span class="s2">"resourceId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"us4z18"</span><span class="p">,</span><span class="w"> </span><span class="s2">"stage"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dev"</span><span class="p">,</span><span class="w"> </span><span class="s2">"requestId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9"</span><span class="p">,</span><span class="w"> </span><span class="s2">"identity"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="s2">"userAgent"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"resourcePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/{proxy+}"</span><span class="p">,</span><span class="w"> </span><span class="s2">"httpMethod"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GET"</span><span class="p">,</span><span class="w"> </span><span class="s2">"apiId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxxx"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"resource"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/{proxy+}"</span><span class="p">,</span><span class="w"> </span><span class="s2">"httpMethod"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GET"</span><span class="p">,</span><span class="w"> </span><span class="s2">"queryStringParameters"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"a"</span><span class="p">:</span><span class="w"> </span><span class="s2">"b"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>Setting response body is also quite easy. You just have to pass it as <strong>second parameter</strong> of <code class="highlighter-rouge">callback</code> function. This is because the <strong>First parameter</strong> is reserved for <code class="highlighter-rouge">Error</code> and should be <code class="highlighter-rouge">null</code> if you want to indicate a success response.</p> <p>I think its very straighforward. Moving on…</p> <h3 id="deploying-services">Deploying services</h3> <p>Like I’ve said, deployment is easy. Just execute <code class="highlighter-rouge">serverless deploy</code> or <code class="highlighter-rouge">sls deploy</code> command and serverless will create the necessary cloudformation stack, upload the package to s3 and cloudformation will take care of creating the necessary architecture. You can sit and relax and have a coffee instead.</p> <p>It hardly took 1 hour to get things up and running and having a response, which might’ve took you more if you’re planning to go manual way.</p> <p>Hope you’ve liked my efforts. Will keep posting new articles and more on architectures and orchestration. Comment below if you need any help.</p> Fri, 10 Aug 2018 04:53:38 +0000 http://aboutashu.com/get-started-serverless-aws/ http://aboutashu.com/get-started-serverless-aws/ serverless aws serverless aws Implement Xmpp Chat Client Android Part 2 Tue, 21 Jun 2016 00:00:00 +0000 http://aboutashu.com/2016/06/21/implement-xmpp-chat-client-android-part-2.html http://aboutashu.com/2016/06/21/implement-xmpp-chat-client-android-part-2.html Implement series post in Jekyll <p>This is a series of posts explaining how to implement a post series in plain simple style, within your favorutie static site generator - <code class="highlighter-rouge">Jekyll</code>.</p> <p>This post also shows how I already used the system that I am about to explain, to show the post you are reading, as a part of series.</p> <p>This post acts as index file for series of posts, i.e. it will list all sub-posts of the series and you can reach any part of it, anytime. A link to this post will also show up in the individual sub-posts, so you can get back here easily. Also, your blog index can list this post as a single entity, rather than listing all sub-posts.</p> <p>Below you will find releavent posts explaining the implementation.</p> Wed, 15 Jun 2016 00:00:00 +0000 http://aboutashu.com/implement-series-post-jekyll/ http://aboutashu.com/implement-series-post-jekyll/ jekyll Implement series post in Jekyll - Part 2 <p>In the last post of this series, I explained how you can make a series of post and connect it to a singular post, maintaing series index. We also learnt how I made a bare layout which listed all posts within series.</p> <p>This post will explain how to list only series index post on blog index page.</p> <p>Open the page where you are showing your blog index. For me, its <code class="highlighter-rouge">index.html</code>. It will probably contain a paginator loop, something like this:</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">...</span> <span class="n">rest</span> <span class="n">of</span> <span class="n">index</span><span class="p">.</span><span class="nf">html</span> <span class="o">&lt;</span><span class="n">ul</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% for </span><span class="n">post</span> <span class="k">in</span> <span class="n">paginator</span><span class="p">.</span><span class="nf">posts</span> <span class="sx">%} &lt;li&gt;&lt;a href="{{ post.url }</span><span class="p">}</span><span class="s2">"&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt; {% endfor %} &lt;/ul&gt; </span></code></pre></div></div> <p>Since we need to show posts which are either not a part of any series, or the series index posts, we have to filter out the sub-posts. Quite simple. We just need to check if a post in the loop is series sub-post or not. Still unsure? Check out code below-</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">...</span> <span class="n">rest</span> <span class="n">of</span> <span class="n">index</span><span class="p">.</span><span class="nf">html</span> <span class="o">&lt;</span><span class="n">ul</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% for </span><span class="n">post</span> <span class="k">in</span> <span class="n">paginator</span><span class="p">.</span><span class="nf">posts</span> <span class="sx">%} {% if post.series == nil %}</span> <span class="o">&lt;</span><span class="n">li</span><span class="o">&gt;&lt;</span><span class="n">a</span> <span class="n">href</span><span class="o">=</span><span class="s2">"{{ post.url }}"</span><span class="o">&gt;</span><span class="p">{{</span> <span class="n">post</span><span class="p">.</span><span class="nf">title</span> <span class="p">}}</span><span class="o">&lt;</span><span class="sr">/a&gt;&lt;/</span><span class="n">li</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% endif </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% endfor </span><span class="o">%</span><span class="p">}</span> <span class="o">&lt;</span><span class="sr">/ul&gt; </span></code></pre></div></div> <p>Done.</p> Wed, 15 Jun 2016 00:00:00 +0000 http://aboutashu.com/implement-series-post-jekyll-part-2/ http://aboutashu.com/implement-series-post-jekyll-part-2/ jekyll Implement series post in Jekyll - Part 1 <p>This is first post in the series explaining how I implemented post series without any ruby-gem or anything, just simple liquid syntaxes.</p> <p>The purpose has been stated earlier. I am only going to talk about the implementation now on. Lets get started.</p> <p>Since we need a single index page for series post, lets make one. Create a file and fill releavent front matter. Since we need a way to recognize if this is the series page that holds all the sub-posts within, we need to add a variable. I found <code class="highlighter-rouge">series-slug</code> more intimidating, since it is more human readable and makes sense to sub-posts. Thus, the front matter may now look like:</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">---</span> <span class="ss">title: </span><span class="s1">'Some series title'</span> <span class="ss">layout: </span><span class="n">post</span> <span class="ss">categories: </span><span class="p">[</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">]</span> <span class="ss">series_slug: </span><span class="n">some</span><span class="o">-</span><span class="n">series</span> <span class="o">---</span> </code></pre></div></div> <p>Fill in the content for the post. You have created an index page. Lets create sub-posts (parts of series) that series will contain. Lets make two posts to start with. I am calling it <code class="highlighter-rouge">post A</code> and <code class="highlighter-rouge">post B</code>. Create another two files for these and fill in releavent YAML front matter. Now, to link the post to the series post, I am declaring a variable within these posts which will connect them. So, I declared the variable <code class="highlighter-rouge">series</code> in front matter and fill in the series slug I declared earlier. Thus, the front matter for these posts will look like:</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">---</span> <span class="ss">title: </span><span class="s1">'Part of series post - Part 1'</span> <span class="ss">layout: </span><span class="n">post</span> <span class="ss">categories: </span><span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="ss">series: </span><span class="n">some</span><span class="o">-</span><span class="n">series</span> <span class="o">---</span> </code></pre></div></div> <p>Good enough. Not so much!! We did declared a series and posts linking to it. However, we still need to show above posts in the series index. Since series has the <code class="highlighter-rouge">layout: post</code>, edit <code class="highlighter-rouge">post.html</code> in your <code class="highlighter-rouge">_layouts</code> directory. Enter the following line just below YAML front matter in <code class="highlighter-rouge">post.html</code> :</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">---</span> <span class="ss">layout: </span><span class="n">default</span> <span class="o">---</span> <span class="p">{</span><span class="sx">% include </span><span class="n">post</span><span class="o">-</span><span class="n">series</span><span class="p">.</span><span class="nf">html</span> <span class="sx">%} </span></code></pre></div></div> <p>If you are familier with jekyll, you must know that <code class="highlighter-rouge">include</code> tag includes a file with the name following it, from <code class="highlighter-rouge">_includes</code> directory. In the above code, I just told jekyll to look for a file <code class="highlighter-rouge">post-series.html</code> in <code class="highlighter-rouge">_includes</code> directory, and include the code within it to current file. Thus would help me keep my code modular, in a separate place. This will enable me to write the code for post series thing in a single file called <code class="highlighter-rouge">post-series.html</code> and I can just call releavent variables whereever I like to.</p> <p>For the series index page, we would like to show up all the sub-posts it contains. Quite easy. We will use a for loop to go threw each posts and check if it has a <code class="highlighter-rouge">series</code> variable in their front matter and if that matches our current series index’s <code class="highlighter-rouge">series_slug</code>. Open up <code class="highlighter-rouge">post-series.html</code> and write the code below:</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="sx">% comment </span><span class="o">%</span><span class="p">}</span> <span class="no">We</span> <span class="n">need</span> <span class="n">an</span> <span class="n">array</span> <span class="n">to</span> <span class="n">hold</span> <span class="nb">sub</span> <span class="n">posts</span> <span class="n">of</span> <span class="n">the</span> <span class="n">series</span><span class="o">.</span> <span class="no">Below</span> <span class="n">line</span> <span class="n">is</span> <span class="n">kind</span> <span class="n">of</span> <span class="n">hack</span> <span class="n">to</span> <span class="n">make</span> <span class="n">one</span> <span class="p">{</span><span class="sx">% endcomment </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% assign </span><span class="n">seriesarray</span> <span class="o">=</span> <span class="s1">'|'</span> <span class="o">|</span> <span class="nb">split</span> <span class="p">:</span> <span class="s1">'|'</span> <span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% for </span><span class="n">post</span> <span class="k">in</span> <span class="n">site</span><span class="p">.</span><span class="nf">posts</span> <span class="sx">%} {% comment %}</span> <span class="no">Is</span> <span class="n">this</span><span class="p">(</span><span class="kp">loop</span><span class="p">)</span> <span class="n">a</span> <span class="nb">sub</span><span class="o">-</span><span class="n">post</span> <span class="n">and</span> <span class="n">does</span> <span class="n">it</span> <span class="n">match</span> <span class="n">the</span> <span class="n">series</span> <span class="n">index</span> <span class="n">slug?</span> <span class="p">{</span><span class="sx">% endcomment </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% if </span><span class="n">post</span><span class="p">.</span><span class="nf">series</span> <span class="n">and</span> <span class="n">page</span><span class="p">.</span><span class="nf">series_slug</span> <span class="o">!=</span> <span class="kp">nil</span> <span class="n">and</span> <span class="n">post</span><span class="p">.</span><span class="nf">series</span> <span class="o">==</span> <span class="n">page</span><span class="p">.</span><span class="nf">series_slug</span> <span class="sx">%} {% capture postitem %}</span> <span class="o">&lt;</span><span class="n">li</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">a</span> <span class="n">href</span><span class="o">=</span><span class="s2">"{{ site.url }}{{ post.url }}"</span><span class="o">&gt;</span><span class="p">{{</span> <span class="n">post</span><span class="p">.</span><span class="nf">title</span> <span class="p">}}</span><span class="o">&lt;</span><span class="sr">/a&gt; &lt;/</span><span class="n">li</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% endcapture </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% assign </span><span class="n">seriesarray</span> <span class="o">=</span> <span class="n">seriesarray</span> <span class="o">|</span> <span class="ss">push: </span><span class="n">postitem</span> <span class="sx">%} {% endif %}</span> <span class="p">{</span><span class="sx">% endfor </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% comment </span><span class="o">%</span><span class="p">}</span> <span class="no">At</span> <span class="n">this</span> <span class="n">point</span><span class="p">,</span> <span class="n">seriesarray</span> <span class="n">will</span> <span class="n">hold</span> <span class="n">all</span> <span class="n">the</span> <span class="nb">sub</span><span class="o">-</span><span class="n">posts</span> <span class="k">for</span> <span class="n">this</span> <span class="n">series</span><span class="o">.</span> <span class="no">Just</span> <span class="n">iterate</span> <span class="n">threw</span> <span class="n">them</span> <span class="n">to</span> <span class="n">like</span> <span class="n">below</span><span class="o">.</span> <span class="p">{</span><span class="sx">% endcomment </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% if </span><span class="n">seriesarray</span><span class="p">.</span><span class="nf">size</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">%</span><span class="p">}</span> <span class="o">&lt;</span><span class="n">ul</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% endif </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% for </span><span class="n">post</span> <span class="k">in</span> <span class="n">seriesarray</span> <span class="sx">%} {{ post }</span><span class="p">}</span> <span class="p">{</span><span class="sx">% endfor </span><span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="sx">% if </span><span class="n">seriesarray</span><span class="p">.</span><span class="nf">size</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">%</span><span class="p">}</span> <span class="o">&lt;</span><span class="n">ul</span><span class="o">&gt;</span> <span class="p">{</span><span class="sx">% endif </span><span class="o">%</span><span class="p">}</span> </code></pre></div></div> <p>We can use <code class="highlighter-rouge">seriesarray</code> in <code class="highlighter-rouge">post.html</code> to show the posts. I’d to show the list after the post content. Thus used the above for loop after <code class="highlighter-rouge">{{ content }}</code> in <code class="highlighter-rouge">post.html</code>.</p> <p>If this works out for you, you can check part 2 of the post where I’ve explained how to list only series index post (instead of sub-posts individually) on the blog index page.</p> Wed, 15 Jun 2016 00:00:00 +0000 http://aboutashu.com/implement-series-post-jekyll-part-1/ http://aboutashu.com/implement-series-post-jekyll-part-1/ jekyll WordPress: HTML encoded image alternate text <p>One problem with wordpress is that it doesn’t allow HTML encoded strings in image alternate text. Even if you provide your image alternate text as a HTML string, wordpress will covert it down to plaintext, removing any HTML attributes and the image will then have only plaintext of your alternate text.</p> <p>i.e even if you write your image alternate section such as this</p> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Hey, I am <span class="nt">&lt;i&gt;</span> italic text <span class="nt">&lt;/i&gt;</span> </code></pre></div></div> <p>this would output in frontend as</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Hey, I am italic text </code></pre></div></div> <p>This is not cool. Sometimes, you rely on some plugins which reads image alternate text and display below the images in pretty cool style.</p> <h2 id="options">Options</h2> <p>One option which came to my mind is to leave alternate text blank and provide the image <em>caption</em> in HTML format. For ex, check below image:</p> <p><img src="/assets/wordpess_caption.png" alt="Wp Caption" /></p> <p>Wordpres has this feature where if you leave the alternate text blank, it would fill the caption text in alternate text. I thought it would work since I can provide HTML in captions. But again, the same problem. Captions were turned back into plaintext.</p> <p>Thus, for the above image, the output was something like this:</p> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"http://yourwebsite.com/path/to/image/image.jpg"</span> <span class="na">alt=</span><span class="s">"Hello, this is sample caption. This text is in bold"</span> <span class="nt">/&gt;</span> </code></pre></div></div> <h3 id="the-solution">The solution</h3> <p>Luckily, WordPress provides image hooks which you can use to modify image attributes on the fly. The one which I want to use is <a href="https://developer.wordpress.org/reference/hooks/wp_get_attachment_image_attributes/">wp_get_attachment_image_attributes</a></p> <p>We can use this hook to see what image attribute we want to change, read its value, format it in HTML and return back our new value.</p> <p>Hence, open up your theme’s <code class="highlighter-rouge">functions.php</code> and create a new function where you want to attach this hook. I am calling the function <code class="highlighter-rouge">custom_filter_gallery_img_atts</code>.</p> <figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="cp">&lt;?php</span> <span class="c1">//Filename: functions.php </span><span class="k">function</span> <span class="nf">custom_filter_gallery_img_atts</span><span class="p">(</span> <span class="nv">$atts</span><span class="p">,</span> <span class="nv">$attachment</span> <span class="p">)</span> <span class="p">{</span> <span class="nv">$atts</span><span class="p">[</span><span class="s2">"alt"</span><span class="p">]</span> <span class="o">=</span> <span class="nx">get_post</span><span class="p">(</span><span class="nv">$attachment</span><span class="o">-&gt;</span><span class="na">ID</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">post_excerpt</span><span class="p">;</span> <span class="c1">//This returns image caption (which is in HTML format) </span><span class="k">return</span> <span class="nv">$atts</span><span class="p">;</span> <span class="p">}</span> <span class="nx">add_filter</span><span class="p">(</span> <span class="s2">"wp_get_attachment_image_attributes"</span><span class="p">,</span> <span class="s2">"custom_filter_gallery_img_atts"</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">2</span> <span class="p">);</span> <span class="cp">?&gt;</span></code></pre></figure> <p>What we did above is attaching <code class="highlighter-rouge">wp_get_attachment_image_attributes</code> to our custom defined function <code class="highlighter-rouge">custom_filter_gallery_img_atts</code> inside which we read the image caption and stored the value in image alternate text.</p> <p>Hope you enjoyed the article. If you have any doubts, please comment below. See you soon.</p> Sat, 07 May 2016 07:20:59 +0000 http://aboutashu.com/wordpress-html-encoded-image-alternate-text/ http://aboutashu.com/wordpress-html-encoded-image-alternate-text/ filter image wordpress Wordpress Implement XMPP chat client in Android <p>Since it would take more than one post to share how to implement XMPP client in android, I made a series post which would explain in better way, the structure of XMPP client. I have tried to keep the code modular such that any part can be reused in any other application. The actual code for whole application can be found at <a href="https://github.com/ashutosh2k12/XmppDemo">https://github.com/ashutosh2k12/XmppDemo</a></p> Sun, 01 May 2016 08:39:37 +0000 http://aboutashu.com/implement-xmpp-chat-client-android/ http://aboutashu.com/implement-xmpp-chat-client-android/ Uncategorized Implement XMPP chat client in Android &#8211; Part 1 <h2 id="part-1---xmpp-basics">Part 1 - XMPP Basics</h2> <p>In the <a href="http://aboutashu.com/blog/xmpp-chat-server/">last post</a> of this series, I talked about setting up XMPP based chat server, using ejabberd. In this post, I will be talking about how to implement XMPP chat client in android and let two users talk to each other. After reading this post series, you’ll be able to</p> <ol> <li>Implement chat system such as whatsapp in your own android app</li> <li>Allow yourself to chat with online users (roasters)</li> <li>Making the chat as service so that chat messages still come through even while app is in background</li> </ol> <p>Since it would be too long to explain everything within a single post, I am going to explain part by part code structure and basics of XMPP here.</p> <h2 id="xmpp-client">XMPP Client</h2> <p>XMPP Clients is a software or application which allows you to connect to XMPP servers for instant messaging with other people. Simple enough!! If you are a frequent internet user, you must’ve used one to many XMPP clients such as pidgin, gtalk, Yahoo! IM etc. which allows you to send Instant Message to other users you are connected to. What we will do this in post is to make one such client in android.</p> <h2 id="what-you-will-need">What You will need</h2> <ol> <li>An android IDE for app development. While I prefer <a href="http://developer.android.com/sdk/index.html">Android Studio</a>, <a href="https://eclipse.org/">Eclipse</a> also does the job.</li> <li>Decent Working internet.</li> </ol> <h2 id="starting-the-project">Starting the Project</h2> <p>Lets begin!!</p> <h4 id="creating-the-project">Creating the project:</h4> <p>Create a blank project in android studio. Once you get to editor screen, add following dependencies to your app specific <code class="highlighter-rouge">build.gradle</code>:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>compile 'org.igniterealtime.smack:smack-android-extensions:4.1.0' compile 'org.igniterealtime.smack:smack-tcp:4.1.0' compile 'com.google.code.gson:gson:2.6.2' </code></pre></div></div> <p>The first two lines are mandatory for getting smack to work on android. The third line (about gson) allows you to convert raw messages in GSON format. Since we will be sending messages in GSON format, I added it to my needs. Check out <a href="https://github.com/ashutosh2k12/XmppDemo/blob/master/app/build.gradle">build.gradle</a> of my app to get an idea.</p> <h2 id="basics">Basics</h2> <p>Before diving straight into the code, lets understand few things about XMPP and in what manner are we going to implement them.</p> <h4 id="what-is-xmpp">What is XMPP?</h4> <p>XMPP is basically a set of protocols (or rules) to allow communication based on XML. Thus, whenever you send a message, or your presence (available, unavailable etc.) to some other user (or server), it goes out in XML format, like this:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;presence&gt; &lt;show&gt;dnd&lt;/show&gt; &lt;/presence&gt; </code></pre></div></div> <p>But we don’t have to go threw this right now. You just need to know that whenever you are seeing someone online, or sending a message, the client communicates with each other in this mannar. Read more about these <a href="https://xmpp.org/rfcs/rfc3921.html">here</a></p> <h4 id="jabber-id">Jabber ID</h4> <p>Jabber Id or simply JID is a unique ID (just like your username on facebook) which helps you recognize in XMPP environments. Jabber ID is usually in the format <code class="highlighter-rouge">username@domain</code>. Sometimes, you may see your JID in form of <code class="highlighter-rouge">username@domain/resource</code> .Resource is nothing but a string representing your chat environment.</p> <p><code class="highlighter-rouge">username@domain</code> sometimes is reffered to as <em>Bare JID</em> while <code class="highlighter-rouge">username@domain/resource</code> as <em>Full JID</em>.</p> <h4 id="roasters">Roasters</h4> <p>Just like you have facebook friends, that only they can check out your shared items, XMPP too does have this security thing of its own kind. Whenever you gets connected to a XMPP server, few things about you travels along to server. So, for example, whenever you login to your GTalk, or pidgin, you instantly gets this “green” button to show you are online. You also see your last status that you’ve put up. you see your friendlist and online friends from them.</p> <p>The information associated with you, as soon as you login to any XMPP client, includes mainly:</p> <ol> <li>Your presence information (wether you are available or not)</li> <li>Your status</li> <li>Whom you are subscribed to (and who subscribed to you)</li> </ol> <p>These informations are kept on server in database. XMPP have certain security features that decides who is going to see those informations. For ex, if you are subscribed to User A, and user A is also subscribed to you, then you both can see each other’s presences. However, if only user A has subscribed to you, only you can see his presence.</p> <p><strong>Roasters</strong> are people (or group of people) who are subscribed to you (or you are subscribed to them). They are like your friends on facebook, with limited access depending upon the subscription status between you both.</p> <p>To put it simply, the online users that you see in your gtalk are roasters. Any user whom you have added as contact on XMPP clients are roasters.</p> <h4 id="subscriptions">Subscriptions</h4> <p>Subscriptions is one way of saying <em>sending friend requests</em>. Just like, when you send someone a friend request on facebook, you subscribe to someone on XMPP. You subscribe to someone by sending them a subscription presence packet to their JID. While I will begin with code, I will show you how to send a subscription packets and receive one. Thus, subscription state exists between two users.</p> <p>For sake of simplicity, you just need to know that in order to make someone friends on XMPP, or allowing someone to make you a friend, you need subscription.</p> <p>Subscriptions have 4 modes: <code class="highlighter-rouge">subscribe_none</code>, <code class="highlighter-rouge">subscribe_to</code>, <code class="highlighter-rouge">subscribe_from</code>, <code class="highlighter-rouge">subscribe_both</code>.</p> <ol> <li><strong>subscribe_none</strong> - When you are not subscribed in any way to a given user.</li> <li><strong>subscribe_to</strong> - When only you are subscribed to a given user (one way).</li> <li><strong>subscribe_from</strong> - When you are not subscribed in any way to a given user.</li> <li><strong>subscribe_both</strong> - When you are not subscribed in any way to a given user.</li> </ol> Sun, 01 May 2016 08:39:37 +0000 http://aboutashu.com/implement-xmpp-chat-client-android-part-1/ http://aboutashu.com/implement-xmpp-chat-client-android-part-1/ Uncategorized Creating XMPP chat server <p>In this part of series, I am going to show you how to create an XMPP chat server.</p> <p>To build your own XMPP based chat solution in android, you need to have two important things:</p> <ol> <li>XMPP based chat server</li> <li>XMPP integration in your android code</li> </ol> <p>XMPP chat server or XMPP server is the one that handles chat database, configurations, user, options etc. Basically, it is a chat server that handles your chat backend. What remains is to implement the chat in your own language and have fun.</p> <p>There are many variations of XMPP chat servers available today. You can use any of them depending on your requirements and available configurations. What I would recommend are <a href="http://www.igniterealtime.org/projects/openfire/">openfire</a> and <a href="https://www.ejabberd.im/">ejabberd</a>.</p> <p>Personally, I am going to use ejabberd to setup XMPP chat server. Let’s get into action. First, you will need a web server.For now, I am using <a href="https://www.digitalocean.com">DigitalOcean VPS</a> with Ubuntu Server 14.04 LTS installed, to host the server. Don’t worry if you do not have a VPS right now. You can still test it with your own localhost machine.</p> <h2 id="installing-ejabberd">Installing Ejabberd</h2> <p>Run following command in your terminal to update current package list.</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get update </code></pre></div></div> <p>To install <strong>ejabberd</strong>, just enter the below command and you are done. So easy.</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nt">-y</span> install ejabberd </code></pre></div></div> <p>This will install ejabberd and will also create a configuration file which you can edit to have your own jabberd configuration. The ejabberd configuration file can be found at <code class="highlighter-rouge">/etc/ejabberd/ejabberd.cfg</code>. Lets edit it. Back on your terminal screen, enter this command to edit the file:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>nano /etc/ejabberd/ejabberd.cfg </code></pre></div></div> <p>This will bring up <code class="highlighter-rouge">nano</code> editor, where you can use up and down keys on your keyboard to edit the file. For Ubuntu desktops or other graphical environments, you can use <code class="highlighter-rouge">gedit</code>. Hence, use this command instead <code class="highlighter-rouge">sudo gedit /etc/ejabberd/ejabberd.cfg</code></p> <p>In the editor screen, You’ll see a lot of text there and lot of options. Don’t panic. You only have edit 3-4 options overall. I will be doing them below, so pay attention.</p> <p>The ejabberd.cfg file will look something like this:</p> <p><img src="/assets/ejabberd_cfg.png" alt="ejabberd.cfg" /></p> <p>Use your cursor to move below and find the line which has this text:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>%% Admin user {acl, admin, {user, "admin", "localhost"}}. %% Hostname {hosts, ["localhost"]}. </code></pre></div></div> <p>Lets decode what’s written line by line so that you can get confortable enough to do this on your own next time.</p> <p><strong>Admin user</strong> defines what user (user must be registered with ejabberd) holds the administrative privilages of ejabberd server. <code class="highlighter-rouge">{acl, admin, {user, "admin", "localhost"}}.</code> This line tells that user with username <strong>admin@localhost</strong> is admin of ejabberd configuration. We can add multiple users here to make them admin. Let’s add one. So, press enter key and add similar line with different username.</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{acl, admin, {user, "myusername", "localhost"}}. </code></pre></div></div> <p>The file will now look like:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>%% Admin user {acl, admin, {user, "admin", "localhost"}}. {acl, admin, {user, "myusername", "localhost"}}. %% Hostname {hosts, ["localhost"]}. </code></pre></div></div> <p>You might be wondering the user “myusername” isn’t yet registered with ejabberd, how come we defined here. We will registered him shortly after we are done with editing configuration file.</p> <p><strong>Hostname</strong> defines the server at which ejabberd should listen and connect. If you are not using a local machine (i.e you are using VPS such as DigitalOcean) to host the XMPP chat server, you can mention the domain name or IP address here. I am assuming example.com as my VPS domain name, hence I will modify this line as:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{hosts, ["localhost","example.com"]}. </code></pre></div></div> <p>Thats all the changes you have to make for now. Wasn’t that simple? Once you have made the above changes, the cfg file will now look like:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>%% Options which are set by Debconf and managed by ucf %% Admin user {acl, admin, {user, "admin", "localhost"}}. {acl, admin, {user, "myusername", "localhost"}} %% Hostname {hosts, ["localhost","example.com"]}. </code></pre></div></div> <p>Now exit the nano editor by pressing CTRL + X. This will prompt you if you want to overwrite the previous cfg file, press <strong>Y</strong>, then press Enter again to confirm. This will bring you back to terminal screen.</p> <p>We have mentioned that “myusername” is another user holding administrative rights to ejabberd, but we still haven’t registered him yet. Lets register him as well. Enter following command to register:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ejabberdctl register myusername localhost password </code></pre></div></div> <p>Replace “password” with whatever password you want to use to login. Once you are done with this, You have to re-start your ejabberd server by issuing this command:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service ejabberd restart </code></pre></div></div> <p>Congradulations, We have successfully setup our ejabberd chat server. Lets visit the administrative control panel and see what we got there. Fire up your public domain name in your favorite browser on port 5280 to login to ejabberd server: http://example.com:5280 .This will bring up webpage asking you for username and password. Login with username: myusername@localhost, password: whatever you mentioned earlier.</p> <p><strong>NOTE</strong>- The <em>localhost</em> in above username <em>myusername@localhost</em> represents domain name of user. If you are not sure, edit <em>ejabberd.cfg</em> and check for user. The line, for “myusername” looks like <code class="highlighter-rouge">{acl, admin, {user, "myusername", "localhost"}}</code>, the last part is domain name.</p> <p><strong>EDIT</strong>- For users running on local machines, you can simple use http://localhost:5280. To find your locally accessible ip address, run following command (<code class="highlighter-rouge">ipconfig</code> for windows user):</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ifconfig </code></pre></div></div> <p>and look for address in the form <code class="highlighter-rouge">192.168.0.xxx</code>.</p> <p>Once done, following screen will show up:</p> <p><img src="https://assets.digitalocean.com/articles/community/eJabberdAdmin1.png" alt="ejabberd admin panel" /></p> <p>You have now successfully installed ejabberd on your machine and can be used to connect to any XMPP based chat client. In the next post, you’ll learn how to implement XMPP chat client in android code. Have fun!!</p> <p>Thanks for going threw entire long post. Please like and share if you like the article. Ask anything in comments below.</p> <h3 id="troubleshooting">Troubleshooting:</h3> <p>Sometimes, ejabberd might not open up in your browser and will give <code class="highlighter-rouge">Connection timed out</code> error. It usually happens if firewall is blocking ports on which ejabberd relies for communication stuffs. Usually those ports are 5222, 5269, 5280. You can try opening those ports like I did below:</p> <ul> <li>Enter following commands in terminal:</li> <li> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>iptables <span class="nt">-A</span> INPUT <span class="nt">-p</span> tcp <span class="nt">--dport</span> 5222 <span class="nt">-j</span> ACCEPT iptables <span class="nt">-A</span> INPUT <span class="nt">-p</span> tcp <span class="nt">--dport</span> 5269 <span class="nt">-j</span> ACCEPT iptables <span class="nt">-A</span> INPUT <span class="nt">-p</span> tcp <span class="nt">--dport</span> 5280 <span class="nt">-j</span> ACCEPT </code></pre></div> </div> </li> <li>Open up <code class="highlighter-rouge">/etc/hosts</code> file. <code class="highlighter-rouge">sudo nano /etc/hosts</code>  and add your domain name into it (assuming your public ip address is 123.123.10.210) :</li> <li> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>123.123.10.210 example.com </code></pre></div> </div> </li> <li>Allow ubuntu firewall</li> <li> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>ufw allow 5222 <span class="nb">sudo </span>ufw allow 5269 <span class="nb">sudo </span>ufw allow 5280 </code></pre></div> </div> </li> </ul> <p>This will open the ports and allow public connections, which should fix the issue.</p> Sat, 30 Apr 2016 10:02:06 +0000 http://aboutashu.com/xmpp-chat-server/ http://aboutashu.com/xmpp-chat-server/ Uncategorized Get video links from Coursera <p>I have gone threw coursera classes now and then. What I felt is need for a coursera video downloader. I searched but couldn’t found any good working one.</p> <p>Hence here is a small script I developed which would give you all video links from coursera. Here is what you’ll have to do:</p> <ul> <li>Goto your class. For ex- Mine was  <a href="https://www.coursera.org/course/startup">https://www.coursera.org/course/startup</a></li> <li>Enroll and go to video lectures from left tab. Here is the screenshot</li> <li>in chrome, press <kbd>f12</kbd> to bring up chrome inspector. You can also right click anywhere on webpage and click <strong>inspect element</strong>. Go to <strong>console</strong> tab.</li> <li>Paste the following script into the console:</li> <li> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">){</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"ul.course-item-list-section-list &gt; li"</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">link</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">find</span><span class="p">(</span><span class="s2">"a[data-link-type=</span><span class="se">\"</span><span class="s2">lecture:download.mp4</span><span class="se">\"</span><span class="s2">]"</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'href'</span><span class="p">);</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">link</span><span class="p">)</span> <span class="p">});</span> <span class="p">})(</span><span class="nx">jQuery</span><span class="p">);</span> </code></pre></div> </div> </li> <li>Press enter and hopefully, it will parse every video link in the page.</li> </ul> <p>Hope you’ve liked the article and it helped you. Please do comment if I owe any explanations. Share, it might be helpful to others.</p> Wed, 27 Jan 2016 05:50:23 +0000 http://aboutashu.com/get-video-links-from-coursera/ http://aboutashu.com/get-video-links-from-coursera/ coursera download javascript jquery Javascript