<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhanush Gopinath</title>
    <description>The latest articles on DEV Community by Dhanush Gopinath (@dhanushgopinath).</description>
    <link>https://dev.to/dhanushgopinath</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1610%2FLsSfQY8y.jpg</url>
      <title>DEV Community: Dhanush Gopinath</title>
      <link>https://dev.to/dhanushgopinath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhanushgopinath"/>
    <language>en</language>
    <item>
      <title>Concurrent HTTP downloads using Go</title>
      <dc:creator>Dhanush Gopinath</dc:creator>
      <pubDate>Mon, 05 Feb 2018 13:37:03 +0000</pubDate>
      <link>https://dev.to/dhanushgopinath/concurrent-http-downloads-usinggo-122n</link>
      <guid>https://dev.to/dhanushgopinath/concurrent-http-downloads-usinggo-122n</guid>
      <description>&lt;p&gt;Recently for an implementation of feature in Geektrust, we had to download multiple images from the internet and use it. This had to be an efficient implementation. This post is a brief explanation of the simple implementation done using goroutines and channels.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82t4deit4osk35qlcjbr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82t4deit4osk35qlcjbr.jpeg" alt="Image courtesy — https://hackernoon.com/why-we-love-concurrency-and-you-should-too-c64c2d08a059" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go has an http package which has simple APIs to do HTTP operations. For e.g. if you want to download a page all you need to do is this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Given below is the implementation of downloading a file from a public URL and using it as bytes.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;For downloading multiple files concurrently you can use the help of goroutines and channels.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the above code snippet, we initialise two channels, one for sending the file downloaded as []byte type and another for sending any errors that happened while downloading.&lt;/p&gt;

&lt;p&gt;We then loop though all the urls and call the downloadFile method for each of them in a goroutine. These goroutines are executed concurrently and so the for loop is finished processing in no time. Inside the goroutine each file is downloaded and we get back bytes and error.&lt;/p&gt;

&lt;p&gt;If there is an error in the download, then the error is pushed to the error channel and nil value is pushed to the done channel. If there is no error then the bytes are pushed to the done channel and a nil entry is pushed to the error channel.&lt;/p&gt;

&lt;p&gt;An array of byte arrays is declared to collect the downloaded files back. We again loop through as many times as there are URLs to collect the byte array back from the done channel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytesArray = append(bytesArray, &amp;lt;-done)  
if err := &amp;lt;-errch; err != nil {   
   errStr = errStr + " " + err.Error()  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two lines inside the for loop wait for the done and the error channel to receive data. Once the data has arrived, it increments the loop count. Bytes are appended to the array of bytes while error string is appended, if there are any errors.&lt;/p&gt;

&lt;p&gt;You have now downloaded the files concurrently and they are available as an array of bytes. All just using simple Go code.&lt;/p&gt;

&lt;p&gt;This article was first published on my &lt;a href="https://medium.com/@dhanushgopinath/concurrent-http-downloads-using-go-32fecfa1ed27" rel="noopener noreferrer"&gt;personal tech blog&lt;/a&gt;.  &lt;/p&gt;

</description>
      <category>go</category>
      <category>goroutines</category>
      <category>channels</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Sending HTML emails using templates in Golang</title>
      <dc:creator>Dhanush Gopinath</dc:creator>
      <pubDate>Wed, 21 Jun 2017 07:05:22 +0000</pubDate>
      <link>https://dev.to/dhanushgopinath/sending-html-emails-using-templates-in-golang</link>
      <guid>https://dev.to/dhanushgopinath/sending-html-emails-using-templates-in-golang</guid>
      <description>&lt;p&gt;In the &lt;a href="https://geektrust.in"&gt;Geektrust&lt;/a&gt; application (built on NodeJS) we send a lot of emails that are auto-generated at runtime using HTML Templates. In a new application, which we have developed in &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt;, we needed the same feature. &lt;/p&gt;

&lt;p&gt;This post is a short read about reading an HTML template file and sending email using Go’s &lt;code&gt;html/template&lt;/code&gt; and &lt;code&gt;net/smtp&lt;/code&gt; packages.&lt;/p&gt;

&lt;p&gt;The code is as given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "bytes"
    "fmt"
    "html/template"
    "net/smtp"
)

var auth smtp.Auth

func main() {
    auth = smtp.PlainAuth("", "iamwho@whoami.com", "password", "smtp.gmail.com")
    templateData := struct {
        Name string
        URL  string
    }{
        Name: "Dhanush",
        URL:  "http://geektrust.in",
    }
    r := NewRequest([]string{"junk@junk.com"}, "Hello Junk!", "Hello, World!")
    err := r.ParseTemplate("template.html", templateData)
    if err != nil {
        ok, _ := r.SendEmail()
        fmt.Println(ok)
    }
}

//Request struct
type Request struct {
    from    string
    to      []string
    subject string
    body    string
}

func NewRequest(to []string, subject, body string) *Request {
    return &amp;amp;Request{
        to:      to,
        subject: subject,
        body:    body,
    }
}

func (r *Request) SendEmail() (bool, error) {
    mime := "MIME-version: 1.0;\nContent-Type: text/plain; charset=\"UTF-8\";\n\n"
    subject := "Subject: " + r.subject + "!\n"
    msg := []byte(subject + mime + "\n" + r.body)
    addr := "smtp.gmail.com:587"

    if err := smtp.SendMail(addr, auth, "dhanush@geektrust.in", r.to, msg); err != nil {
        return false, err
    }
    return true, nil
}

func (r *Request) ParseTemplate(templateFileName string, data interface{}) error {
    t, err := template.ParseFiles(templateFileName)
    if err != nil {
        return err
    }
    buf := new(bytes.Buffer)
    if err = t.Execute(buf, data); err != nil {
        return err
    }
    r.body = buf.String()
    return nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this I encapsulate the smtp request in a struct &lt;code&gt;Request&lt;/code&gt;. It contains basic things like To, Subject, Body. This template file has the data placeholders which will be replaced with actual data values by Go’s &lt;code&gt;html/template&lt;/code&gt; package &lt;a href="https://golang.org/pkg/html/template/#Template.Execute"&gt;Execute&lt;/a&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    Hello {{.Name}}
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{.URL}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Confirm email address&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template data is a struct which has &lt;code&gt;Name&lt;/code&gt; &amp;amp; &lt;code&gt;URL&lt;/code&gt; as the field values. It is initialised with values and passed to the NewRequest method to create an object of Request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;templateData&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
 &lt;span class="p"&gt;}{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Dhanush"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"http://geektrust.in"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the instance of &lt;code&gt;Request&lt;/code&gt; is created, then &lt;code&gt;ParseTemplate&lt;/code&gt; method is called on it. This method receives a template filename and template data. It parses the template file and executes it with the template data supplied. A &lt;code&gt;bytes.Buffer&lt;/code&gt; is passed to the &lt;code&gt;Execute&lt;/code&gt; method as &lt;code&gt;io.Writer&lt;/code&gt; so that we get back the HTML string with the data replaced.This HTML string is then set as the Email Body.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SendEmail&lt;/code&gt; method sets the MIME encoding as &lt;code&gt;text/html&lt;/code&gt; and calls smtp package’s &lt;code&gt;SendMail&lt;/code&gt; method to send the email. When the email is sent successfully the SendEmail method returns a true value.&lt;/p&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you return the Request in ParseTemplate method, instead of the error, then we make the call in one line.
&lt;code&gt;ok,err := NewRequest([]string{“junk@junk.com”}, “Hello Junk!”, “Hello, World!”, “template.html”, templateData).ParseTemplate().SendEmail()&lt;/code&gt; But then any error coming out of ParseTemplate may have to be tracked inside the method.&lt;/li&gt;
&lt;li&gt;Read the package documentation of &lt;code&gt;html/template&lt;/code&gt; to understand how Go replaces the HTML with actual data.&lt;/li&gt;
&lt;li&gt;Thanks to &lt;a href="https://github.com/jijeshmohan/"&gt;Jijesh Mohan&lt;/a&gt; and &lt;a href="https://github.com/navaneeth"&gt;Navaneeth K. N&lt;/a&gt; in making the Go code more idiomatic, than it was before :)&lt;/li&gt;
&lt;li&gt;This post was first published in my &lt;a href="https://medium.com/@dhanushgopinath/sending-html-emails-using-templates-in-golang-9e953ca32f3d"&gt;personal blog&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>smtp</category>
      <category>templates</category>
      <category>go</category>
    </item>
    <item>
      <title>Hi, I'm Dhanush Gopinath</title>
      <dc:creator>Dhanush Gopinath</dc:creator>
      <pubDate>Sat, 18 Mar 2017 07:46:18 +0000</pubDate>
      <link>https://dev.to/dhanushgopinath/hi-im-dhanush-gopinath</link>
      <guid>https://dev.to/dhanushgopinath/hi-im-dhanush-gopinath</guid>
      <description>&lt;p&gt;I have been coding for close to 14 years.&lt;/p&gt;

&lt;p&gt;You can find me on Twitter as &lt;a href="https://twitter.com/dhanushgopinath" rel="noopener noreferrer"&gt;@dhanushgopinath&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Bangalore, the Garden City and Silicon Valley of India, but I am  a &lt;a href="https://en.wikipedia.org/wiki/Malayali" rel="noopener noreferrer"&gt;Malayali&lt;/a&gt; from Calicut - where Vasco da Gama set foot in 1498 - in North Kerala.&lt;/p&gt;

&lt;p&gt;I started &lt;a href="http://geektrust.in" rel="noopener noreferrer"&gt;Geektrust&lt;/a&gt; 2 years back along with 2 friends and am currently the CTO there. &lt;/p&gt;

&lt;p&gt;I mostly program in Go, Javascript &amp;amp; Python for the last 2 years. Before that I was a Java programmer for over 10 years. But I have been in love with Go now. &lt;/p&gt;

&lt;p&gt;I am currently learning more about Machine Learning &amp;amp; NLP and I would love to learn Elixir as my next Programming language. &lt;/p&gt;

&lt;p&gt;Apart from programming I am a voracious reader with Gabriel Garcia Marquez, Jose Saramago &amp;amp; &lt;a href="https://en.wikipedia.org/wiki/M._T._Vasudevan_Nair" rel="noopener noreferrer"&gt;M.T. Vasudevan Nair&lt;/a&gt; being my favourite writers&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
