Saturday, 12 May 2018

Flask RSS Feeder

Hi all,

Today i am uploading one of the new fun project i was working on.
As i am big fan of Manga, and its hard to keep track of them, when new ones are available.
So, i decided to create a RSS feeder.

What You'll learn,
- How to create a simple web app using FLASK.
- Using multi-threading for parallel processing.
- DB operations  on MY-SQL DB, it's what i have used.

Code Snippet :-

Below is the snippet of the project file structure.


HTML :-
1) layout.html :- This is the backbone of the application design.
2) home.html  :- Home page of the application.
3) article.html :- this one the list of the rss feeds.
4) includes folder consist app navigation bar and messages(to send flash notification).

Python :-
1) add_rss.py is the one where mostly everything is happening.


Importing functions from FLASK and SQLAlchemy.

#for flask and its functionality
from flask import Flask, render_template, flash, redirect, url_for, session, logging, request

#for mysql connection
from flask_sqlalchemy import SQLAlchemy

#for reading rss feeds
import feedparser

#for parallel processing

import threading

#DB configuration
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://<UserName>:<Password>@localhost/RSS_python"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ECHO'] = True

#do set your My-SQL username and password, also make sure to create the DB as given in DB.png.

db = SQLAlchemy(app)

url_data = []

#Function i am using to get the data from feed.

def get_source(feed):
    return {
        'title'     : feed['title'],
        'link'      : feed['link'],
        'published' : feed['published']

    }

#function to get feed from URL.

def get_feed(db_data):
    rss = db_data.url
    feed = feedparser.parse(rss)
    feed = feed["entries"][0]
    new_feed = get_source(feed)
    new_feed['name']    = db_data.name
    if db_data.title != new_feed.get('title'):
        db_data.title       = new_feed['title']
        db_data.link        = new_feed['link']
        db_data.published   = new_feed['published']
        new_feed['is_read']     = 1
        #update the row
        db.session.commit()
    url_data.append(new_feed)

    return

#DB model of my DB
class rss_model(db.Model):
    __tablename__ = "rss"
    id          = db.Column(db.Integer, primary_key=True)
    url         = db.Column(db.Unicode)
    name        = db.Column(db.Unicode)
    title       = db.Column(db.Unicode)
    link        = db.Column(db.Unicode)
    published   = db.Column(db.Unicode)

    def __init__(self,url,name, is_read=0):
      self.url          = url
      self.name         = name

      self.is_read      = is_read

#Route of home page. this is how to tell application, which page to load.
@app.route('/')
def show_all():
    return render_template('home.html')


#Function to get the feed, read the db and run the threads, so mostly everything is happening.
@app.route('/article')
def articles():
    global url_data
    url_data = []

          #Query to get all data from DB.
    data = rss_model.query.all()

    #empty list of same size as the number of rows fetched from DB.
    t = [None] * len(data)
    for i in range(len(data)):
                   # starting the same number of thread as the rows, so the processing will be faster.
        t[i] = threading.Thread(target=get_feed, args=(data[i],))
        print ("\n\n", "data:",data[i], "\n\n", file=sys.stdout)
        try:
            t[i] = threading.Thread(target=get_feed, args=(data[i],))
            t[i].start()
        except:
           print ("Error: unable to start thread", file=sys.stdout)

    for i in range(len(data)):
        #here we are waiting for all the threads to complete.
        t[i].join()
    return render_template('article.html', chapters = url_data)

#function to add new RSS feed.
@app.route('/add_rss', methods=['GET','POST'])
def add_rss():
    if request.method == 'POST':
        name = request.form['name']
        url = request.form['url']
        new_rss = rss_model(name = name, url = url)
        db.session.add(new_rss)
        db.session.commit()
        db.session.flush()
        msg="New Manga Added"
        return render_template('home.html',msg=msg)
    return render_template('add_rss.html')

#Setting debug to true so, the changes reflect ASAP in application, and manually setting the port to 5876.

if __name__ == '__main__':
    app.run(debug=True, port=5876)

#end of the rss_app.py


rss_python.sh

Just a script to start the application. i am using this in my bashrc to start it with alias.
ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0`
result=$(echo $ps_out | grep "$1")
if [ "$result" != "" ];then
    echo "Server already Running"
else
    ~/<path to virtualenv python>/python3 ~/<path to file>/rss_app.py &>/dev/null &
fi


FYI :- you can clone the repo from 
https://github.com/Shapboyz13/rssFeeder


Hope you'll enjoy it,
Comments, review, questions and suggestion are always welcome, 
you can also connect me here. shashank17nov@gmail.com
And at last, as always thanks to all the stack overflow sources for the help.

Thursday, 15 June 2017

Web Scraping

Web Scraping using Python

Hi all, i'll be telling how to start web scrapping in python. In this script we are using accuweather to scrap data, to check whats the current temperature of your city.


   We are going to use two module on this tutorial.

1) Beautiful soup is the module, that we will use for scrapping.
2) Requests is to get the data from webpage.

Make sure to check if Beautiful soup is installed in your system, as below. In case if it's not installed, google for how to install beautifulsoup and requests.

shanky@Unity:~$ pip list |grep beautifulsoup4
beautifulsoup4 (4.5.3)

Code:

#imports  

from bs4 import BeautifulSoup as bs
import requests

#requests.get() function connects to given url, and collects the web page data.
#change url with, go to accuweather, and select your city.
#example, if you were in banglore, URL would be "http://www.accuweather.com/en/in/bengaluru/204108/weather-forecast/204108"

page = requests.get("url")

#now we need to extract content from the data we just got. and parse it in html format. This will enable to use, search what we are looking for using html tags.

soup = bs(page.content, 'html.parser')

#Here we are searching for a class="large-temp" first instance in the HTML we just extracted. you can check HTML from website, just right click and choose Inspect element from your browser.
#get.text() collects the string, inside the searched tag.

x=soup.find_all('span', class_="large-temp")[0].get_text()

#here we need to use slicing to get the required data, also the string i got was encoded to UTF-8 format, so we need to encode it back to ascii.

print ("Current temperature is " + str(x[0:2].encode()) + "C")


This is it, for more information, contact me or research on BeautifulSoup for web scrapping, it packs way too many powerful functions.

FYI, i am using 
accuweather for educational purpose only. you need to modify the code as per the website, if you are using other website.

Sunday, 21 May 2017

How to Setup MAVEN on Windows

You can setup Maven framework on windows, link and Mac OS platforms. Here we will learn how to setup it in windows operating system:

To install Maven, you need to follow below steps:

1. Download Maven and extract it.
2. Setup JAVA_HOME and MAVEN_HOME environment variables.
3. Append Maven's bin path in the 'path' system variable.
4. Verify Maven by running 'mvn' command.

1. Download MAVEN:

Download Apache's maven latest version : apache-maven-3.5.0.
And extract it in your C-drive












2.  Setup new Environment variables and append 'path' variable  :

We will setup below Environment variables :

JAVA_HOME, MAVEN_HOME and MAVEN_OPTS

Please see below screenshots:

























































































3. Verify MAVEN

You can verify Maven configuration by running below command from command prompt.

mvn -version











Read Basics of Maven from the previous tutorial.  Comment below if you find any challenges in configuring maven.


Saturday, 20 May 2017

MAVEN Tool: Introduction

Maven is a framework for project management which manages project's build, reporting, documentation, releases and distributions. It provides developers a complete build life cycle framework.

Advantages of Maven:
1. No need to add jars files in each project.
2. Creates correct directory structure
3. Setup the multiple development team environment in a very short time.
4. Build and deploy the project.
5. Generate source code if auto-deploy mode is enable.
6. Compile Source Code.
7. Packages compiled code into JAR.

What is POM.XML file in Maven:

POM stands for Project Object Model. It is a XML file which contains information about project and configurations details which are used by maven to build the project. Maven reads the pom.xml file and then perform the tasks.

Maven has 3 type of repositories which contains all the JARs and POM.XML file which can help in building the project.

1.  Local Repository: It is located in the local system.By default, it is in %USER_HOME%/.m2 directory.
2. Central Repository: It is created by maven community itself. It contains a lot of common libraries.
3. Remote Repository: There can be possibilities that a libraries can't be available in central repository  so that we can take it from the web.  For those libraries we need to define remote repository in the pom.xml file.


Read: How to setup maven on windows.

Thursday, 18 May 2017

Text Based Adventure Game

Text Based Adventure Game

Hi All, this one is a text based adventure game, and the best thing is you can write the story as you like and the same code will work for it.

This one consist of 3 files.
1) Code
2) Story line input file in text format
3) Text file than contains all the information about story.

I'll come to code later, but first information text file.
This file contains one line for every scenario for you story.
Eg.

story.txt

Hi, I am Naruto. I want to be Hokage(Village leader).
Day 1, It's finally the day i'll become Genin. I need to take the test first.
(At Examination Hall) Oh no ! , I can't do this jutsu, do you know which jutsu is this.
1) Shadow Clone jutsu.
2) Fire ball jutsu.

lines.txt

3 2 1

lines.txt first line is 3 2 1, it provide information how to read story.txt. 3 means we have 3 line for story setup, like in above example. it can be any number as long as you take care of the screen size. 2 means we are going to provide 2 options for the user. And last 1 means that choice one is correct.

so you can create you own story, you just have to follow the rule as above.

Code:

import cursesfrom time import sleep

#function to read story and check if user is given the correct answers

def story(scr): scr.refresh()

#reads both the file in read only mode.

strText=open('/path/to/file/story.txt','r') strLine=open('/path/to/file/lines.txt','r')

#reads line by line from lines.txt

for x in strLine:

x=x.rstrip('\n')      #removes \n from end of line

x=x.split(' ')        #split all elements line by line, on the basis of space

#read line by line from story.txt on the basic of number of lines from lines.txt 

for y in range(len(x)):

#checks if the element is last one, also checks, if your input is correct

if y == len(x)-1: if chr(usr_input) == x[y]: continue else:

#in case user input is wrong, game end.

story_draw(15,scr, "Nope, wrong choice, you have to watch Naruto Again.") scr.getch() curses.endwin() exit() else: for y1 in range(int(x[y])): a=strText.readline().rstrip('\n') story_draw(y1+3,scr,a) usr_input=scr.getch() scr.clear() scr.border() scr.refresh() scr.refresh() scr.getch()

# function to print string for output on curses.

def story_draw(y,win,a): for x in range(len(a)): win.addstr(y,x+5,a[x])

#just to add little animation 😆

sleep(.01) win.refresh() return
def main(): screen = curses.initscr() screen.border() screen.keypad(1) curses.noecho() curses.cbreak() curses.curs_set(0) story(screen) curses.endwin()


if __name__ == "__main__":
    main()

Screenshot 1: This is how story looks.



Screenshot 2: Example of how the options can be.



Screenshot 3:Scene 2 starts, if you choose correct answer.



Screenshot 4: Just in case you loose.



Side note : Yes i like Naruto way too much.
Author Shanky.Rawat

Tuesday, 9 May 2017

Menu based Basic Calender Management System

Menu based Basic Calendar Management System

We will be working on super simple, hourly based, basic calendar management system. We will be using dictionary, data structure provided by python.


#function to display all events in calendar

def event_disp():
   system('clear')
   print ("\n\n#####################################\n\n")
   print ("Time : \t\tEvent")
   for key, value in hour.items():
      print key, "\t\t" + value
   print ("\n\n#####################################\n\n")
   return

#function to display main menu and taking user inputs

def disp():

   # using system in built command for clearing screen

   system('clear')

   print ("\n\n#####################################\n\n")
   print ("\t1. Add event to calander")
   print ("\t2. Remove event from calander")
   print ("\t3. View Events from yout calander")
   print ("\n\n#####################################\n\n")

   userInput = int(input("Choose 1,2 or 3 for options:\t"))

   if userInput == 1:
      inputTime = int(raw_input("Enter time in format (hh):\t"))
      if inputTime >= 24 or inputTime < 0:
         print "Time is only supported from 00 to 23 hours"
      else:

         #checking if the event already exist for the same time.

         if not hour.get(inputTime):
            inputEvent = raw_input("Enter event to store:\t")
hour[inputTime] = inputEvent
         else:
            print ("Event is already schedule for this time.")
   elif userInput == 2:
      event_disp()
      inputTime = int(raw_input("Enter the time you want to clear:\t"))

      #deleting the event using key from dictionary 

      del hour[inputTime]

      event_disp()

   elif userInput == 3:
      event_disp()

   cont=raw_input("Back to main menu(y/n):\t")
   if cont == 'y' or cont == 'yes':
      disp()
   else:
     exit()

#importing system from os, for clear command we used earlier

from os import system

#Adding some random input for our dictionary.

hour = {11:"This is sparta", 12 : "Sleep"}

disp()


Screenshots:

1 Main screen and adding event


2 View Events



3 Removing event


4 List after removing event

Analytic Functions in SQL

Functions :

1. LEAD

LEAD function is used to fetch the data from the next row. And provide a way to do the manipulation with the use of next row.

Syntax:  LEAD(value_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause) 

For example: If we need to find out the difference between quantity of all the products present in SALES table with respect to next year.

select product_id,year,quantity,
lead(quantity, 1, 0) over (partition by product_id order by year) as prev_quantity,
quantity-lag(quantity, 1, 0) over (partition by product_id order by year) as diff

from sales;

2. LAG

LAG function is used to fetch the data from previous row. And provide a way to do the manipulation with the use of previous row.

Syntax:  LAG (value_expression [,offset] [,default]) OVER ([query_partition_clause] order_by_clause) 

value_expression : It can be a column or builtin function.
offset: Number of rows preceding. Default value is 1
default: Value returned when offset will be out of scope.

For example: If we need to find out the difference between quantity of all the products present in SALES table with respect to previous year.

select product_id,year,quantity,
lag(quantity, 1, 0) over (partition by product_id order by year) as prev_quantity,
quantity-lag(quantity, 1, 0) over (partition by product_id order by year) as diff
from sales;




3. LISTAGG :

This function is used to aggregate the strings and can be use to sort them.

For Example: If we want to see the how many products are mapped with a particular product_id and we want to display the product names by comma separated. 

select product_id,listagg(product_name, ',') within group(order by product_name) product_list
from products
group by product_id;