Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new branch with email functionality #7

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
FROM ubuntu:16.04
FROM ubuntu:18.04
FROM httpd:2.4

RUN groupadd container_users && useradd -ms /bin/bash -g container_users belmont
RUN echo "Acquire::Check-Valid-Until \"false\";\nAcquire::Check-Date \"false\";" | cat > /etc/apt/apt.conf.d/10no--check-valid-until
pmazumda marked this conversation as resolved.
Show resolved Hide resolved
RUN apt-get update && apt-get -y install software-properties-common
RUN apt-get -y install build-essential
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update && apt-get -y install python3.7
RUN rm /usr/bin/python3
RUN ln -s /usr/bin/python3.7 /usr/bin/python3
RUN apt-get -y install python3-pip
RUN python3 -m pip install --upgrade pip
RUN apt-get -y install curl
RUN apt-get -y install jq

USER belmont

ENV DEMETER_DIR /home/belmont/demeter/
ENV DEMETER_DIR /home/belmont/demeter
ENV PATH /home/belmont/.local/bin:$PATH
ENV FLASK_APP="api.py"
ENV FLASK_ENV="production"

RUN mkdir -p $DEMETER_DIR
RUN mkdir -p $DEMETER_DIR/files

ADD . $DEMETER_DIR

USER root
RUN chown -R belmont:container_users $DEMETER_DIR/files/

USER belmont
COPY ./files/ $DEMETER_DIR/files/

WORKDIR $DEMETER_DIR
COPY ./ui/ /usr/local/apache2/htdocs/

RUN python3 -m pip install -r requirements.txt

CMD flask run --port=8080 --host=0.0.0.0
CMD ["bash", "getNav.sh"]
1 change: 0 additions & 1 deletion MutualFund.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import json
import datetime


pmazumda marked this conversation as resolved.
Show resolved Hide resolved
class MutualFund:

def __init__(self):
Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,24 @@ This project requires Python 3.7+ and pip
### Alternatively, if you want to run it in docker

#### 1.Build the image
`docker build -t demeter:0.0.1 .`
`docker build -t demeter:0.0.2 .`

#### 2. Run the container
`docker run -p 8080:8080 -d demeter:0.0.1`
`docker run -p 8080:8080 -d demeter:0.0.2`


### Frontend
Demeter also offers a minimal UI to see the NAV of a scheme. If you want to run it locally, you can start the API
server as mentioned above and then expose the UI by serving the `ui` directory static files from any web server such as
Apache Web Server or Nginx Plus. Alternatively, if you want to serve it via Docker, you can follow the steps:

#### 1.Build the image
`docker build -t demeter:0.0.2 .`

#### 2. Run the container
`docker run -d --name demeter -p 8080:80 -p 5000:5000 demeter:0.0.2`

Demeter will start an Apache Web Server instance at port 8080 and serve the UI.

## REST Endpoints

Expand Down
8 changes: 6 additions & 2 deletions api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import datetime
from flask import Flask
from flask import request
from flask_cors import CORS,cross_origin
from MutualFund import MutualFund

app = Flask(__name__)

CORS(app, resources=r'/v1/*')

class Demeter:

Expand All @@ -22,7 +23,10 @@ def get_schemes(fund_house_id: int):

@app.route('/v1/nav', methods=["POST"])
def get_historic_nav():

req_body = request.json


pmazumda marked this conversation as resolved.
Show resolved Hide resolved
start_date_splitted = req_body["startDate"].split('-')
start_date = datetime.datetime(int(start_date_splitted[0]), int(start_date_splitted[1]),
int(start_date_splitted[2]))
Expand All @@ -31,4 +35,4 @@ def get_historic_nav():
response = app.make_response(MutualFund.get_historic_nav(
req_body["fundHouseId"], req_body["schemeId"], start_date, end_date))
response.content_type = "application/json"
return response
return response
1 change: 1 addition & 0 deletions files/contactslist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name email-id
Binary file added files/mutualfund.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions getNav.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash
###########################################################################################
#Purpose: Invoke historical NAV for a particular MF scheme everyday using a crontab job #
#Name: getNav.sh #
#Author: Pinak Mazumdar #
###########################################################################################
getFundHouseID()

{
URL="localhost:8080/v1/fundhouses"
FUND_HOUSES=`curl --location --request GET "$URL"`
FUND_HOUSE_ID=`echo $FUND_HOUSES | jq '.[] | select(.fund_house=="Mirae Asset Mutual Fund")' | jq '.fund_house_id'`
echo $FUND_HOUSE_ID
}

getSchemes()

{
id=${FUND_HOUSE_ID}
URL="localhost:8080/v1/fundhouse/${id}/schemes"
SCHEMES=`curl --location --request GET "$URL"`
SCHEME_ID=`echo $SCHEMES | jq '.[] | select(.scheme_name=="Mirae Asset Tax Saver Fund-Direct Plan -Growth")' | jq '.scheme_id'`
echo $SCHEME_ID
}


getNAV()
{

enddate=`date -d '1 day ago' +'%Y-%m-%d'`
startdate=`date -d '1 day ago' +'%Y-%m-%d'`
fundid="$FUND_HOUSE_ID"
schemeid="$SCHEME_ID"
CURLURL="localhost:8080/v1/nav"
CURLDATA="{\
"\"startDate"\": "\"${startdate}"\", \
"\"endDate"\": "\"${enddate}"\", \
"\"fundHouseId"\": "${fundid}", \
"\"schemeId"\": "${schemeid}"\
}"

RESPONSE=`curl --location --request POST "$CURLURL" --header 'Content-Type: application/json' --data-raw "$CURLDATA"`
#echo "Latest NAV: ${RESPONSE}"
}

getParsedOutput(){
date=`echo $RESPONSE | jq '.[].date'`
nav=`echo $RESPONSE | jq '.[].nav'`
#echo $date
#echo $nav
msg="Dear \${PERSON_NAME} \n\nThank you for showing interest in receiving daily NAV details for your selected mutual fund scheme. \n\nThe NAV(Net Asset Value) for the mutual fund scheme you selected is ${nav} as on ${date}. \n\nIf you want to unsubscribe from this service.Please send SMS STOP NAV to 9742061425.\n\nThanks,\nAnna-konda"
echo -e "$msg" >files/getNAV.out
}


##Main function
startProcess()
{
FLASK_APP=api.py flask run --port=8080
}

startProcess &
sleep 5
getFundHouseID
getSchemes $FUND_HOUSE_ID
getNAV $FUND_HOUSE_ID $SCHEME_ID
getParsedOutput $RESPONSE
python3 send_email.py
echo "-----End of Script------"

3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
requests-html==0.10.0
flask==2.0.1
flask==2.0.1
flask_cors==3.0.10
73 changes: 73 additions & 0 deletions send_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# import necessary packages
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import time
import smtplib
from string import Template

def get_contacts(filename):
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails

def read_template(filename):
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)

def sendemail():

MY_ADDRESS = "put real email id here"
PASSWORD = "put real password here"
files = ['files/mutualfund']

# set up the SMTP server
s = smtplib.SMTP(host='smtp.gmail.com', port=587)
s.starttls()
s.login(MY_ADDRESS, PASSWORD)

time.sleep(60) #Sleep for 5 minutes

names, emails = get_contacts('files/contactslist.txt') # read contacts
message_template = read_template('files/getNAV.out')
filename = "mutualfund.jpg"
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
print(name, email)
# add in the actual person name to the message template
message = message_template.substitute(PERSON_NAME=name.title())

# setup the parameters of the message
msg['From']=MY_ADDRESS
msg['To']=email
msg['Subject']="Daily Net Asset Value Mailer" #Change to Body ltr

# add in the message body
msg.attach(MIMEText(message, 'plain'))
# msg.attach(files)
attachment = open("files/mutualfund.jpg" , "rb")
p = MIMEBase('application', 'octet-stream')
# To change the payload into encoded form
p.set_payload((attachment).read())
# encode into base64
encoders.encode_base64(p)

p.add_header('Content-Disposition', "attachment; filename= %s" % filename)

# attach the instance 'p' to instance 'msg'
msg.attach(p)

# send the message via the server set up earlier.
s.send_message(msg)

del msg

if __name__ == '__main__':
sendemail()
7 changes: 7 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

flask run --port=5000 --host=0.0.0.0 &
P1=$!
httpd-foreground &
P2=$!
wait $P1 $P2
31 changes: 31 additions & 0 deletions ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<html>
<body>
<h1>Graph</h1>
<form>
<label for="fundHouse">Fund House</label>
<select id="fundHouse" name="fundHouse">
<option>Choose Fund House/AMC</option>
</select>
<br/>
<label for="schemeName">Scheme</label>
<select id="schemeName" name="schemeName">
<option>Choose a scheme</option>
</select>
<br/>
<label for="timeFrame">NAV Trend Duration</label>
<select id="timeFrame" name="timeFrame">
<option id="past-week">Past week</option>
<option id="past-month">Past 1 month</option>
<option id="past-six-months">Past 6 months</option>
<option id="past-one-year">Past 1 year</option>
<option id="past-three-years">Past 3 years</option>
<option id="past-five-years">Past 5 years</option>
</select>
</form>
<div>
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript" src="js/mygraph.js"></script>
</body>
</html>
Loading