Compare commits

28 Commits
master ... api

Author SHA1 Message Date
ecc71972e2 Started adding api information to main page. 2020-03-14 14:49:46 -04:00
Dan Dembinski
b31d8f3fcc Tweaks 2020-03-09 16:48:46 -04:00
Dan Dembinski
eaefe02988 Trying to import podcasts with no artworkURL 2020-03-09 16:42:52 -04:00
Dan Dembinski
a3b27e1dea Accounted for no artworkURL 2020-03-09 16:34:28 -04:00
Dan Dembinski
32fd101e5a Tweaks 2020-03-09 15:58:26 -04:00
Dan Dembinski
9abe918906 added '/' after addFeed 2020-03-09 14:41:40 -04:00
Dan Dembinski
900084f493 added note to main about resetting autoincrement. Added podcast.opml file back in. wrote small console helper app to load in opml files for testing 2020-03-09 14:30:43 -04:00
Dan Dembinski
f5d66e8c0b Started reworking the login scrip to actually have logic. Can now update individual shows. Added json input to some methods. Finished user delete method. Finished remove feed method. 2020-03-09 13:30:57 -04:00
63841a2ba0 Added a few future methods 2020-03-07 20:02:58 -05:00
0d17739bbd Updated Dockerfile 2020-03-07 19:50:47 -05:00
94fd726873 Removed unneeded files for API version. Cleaned up main.py. Removed unnecessary packages from requirements.txt. 2020-03-07 19:49:24 -05:00
d4e2319045 Reworked addFeed method and have that working correctly now. Started adding updateStatus method. 2020-03-07 19:39:09 -05:00
0e0222d645 Updated requirements.txt 2020-03-07 18:25:48 -05:00
9f3ab3cb38 Updated feedUpdate method 2020-03-07 18:23:51 -05:00
d7dcf943f5 Moved from flaskAPI to regular flask. Started reworking SQL queries from sql.text to straight sqlalchemy ORM. Login, listShows, register methods have been reworked to comply. Also have listShows returning nicely formatted json now. 2020-03-07 01:24:59 -05:00
Dan Dembinski
3bfdd126ba API mostly working. Added register method. List show methods sort of works. Add Feed is not working. Think it needs some sort of URL de/encode. 2020-03-06 16:44:24 -05:00
Dan Dembinski
a36d735ec2 Made changes to allow internet access 2020-03-06 14:06:38 -05:00
Dan Dembinski
56b84fea08 Made changes to allow internet access 2020-03-06 14:05:09 -05:00
Dan Dembinski
e76ab4c74b Started setting this up as an API 2020-03-06 13:54:51 -05:00
Dan Dembinski
4c7fdaf66a modified db URI 2020-03-06 13:01:32 -05:00
Dan Dembinski
d493b02326 modified db URI 2020-03-06 12:56:23 -05:00
Dan Dembinski
15e3c13609 modified db URI 2020-03-06 12:52:51 -05:00
Dan Dembinski
cafdd3d094 modified dockerfile 2020-03-06 12:39:01 -05:00
Dan Dembinski
024ff141f6 modified dockerfile 2020-03-06 12:36:14 -05:00
Dan Dembinski
cedb173b63 modified dockerfile 2020-03-06 12:32:21 -05:00
Dan Dembinski
feb4408f2b renamed captain file 2020-03-06 12:28:37 -05:00
Dan Dembinski
8b40ae1cab Added docker and captain files 2020-03-06 12:25:51 -05:00
Dan Dembinski
b5dbe40365 Started remote docker setup. Should update list of shows hourly. 2020-03-06 12:20:28 -05:00
9 changed files with 301 additions and 163 deletions

117
Feed.py
View File

@@ -1,117 +0,0 @@
import opml
import feedparser as fp
import database as db
def feedImport (userID):
outline = opml.parse("podcast_republic_podcasts.opml")
#get the number of shows from the OPML file
x = len(outline)
y=0
#loops through each podcast and parses out relevant information
while y < x:
title = outline[y].title
url = outline[y].xmlUrl
artwork = outline[y].pr_artwork
desc = outline[y].pr_desc
#checks to see if the podcast URL already exists for logged in user and skips it if it has already been imported.
query = db.sql.text("""select URL from Podcasts where URL = \"%s\" and userID = %i""" % (url, userID))
exists = db.con.execute(query).fetchone()
#if the show doesn't already exist for the logged in user it gets added
if exists is None or exists[0] != url:
query = db.sql.text("""insert into Podcasts (userID, title, URL, artworkURL) values(%i, \"%s\", \"%s\", \"%s\") """ % (userID, title, url, artwork))
db.con.execute(query)
print("%s added" % title)
else:
print("%s already exists" % title)
y=y+1
def updateFeeds(userID):
showCheck = []
#grabs podcast urls from logged in user
query = db.sql.text("""select URL, podcastID, title from Podcasts where userID = %i""" % userID)
shows = db.con.execute(query).fetchall()
#loops through the returned urls and parses each rss feed
y=0
for x in shows:
#Here we're grabbing all the show urls for each podcast and moving them into a separate array.
query = db.sql.text("""select link from Shows where userID = %i and podcastID = %i""" % (userID, shows[y][1]))
showGrab = db.con.execute(query).fetchall()
z=0
for each in showGrab:
showCheck.append(showGrab[z][0])
z=z+1
parsed = fp.parse(shows[y][0])
count = 0
for items in parsed['entries']:
url = parsed.entries[count].enclosures[0].get('href')
#after parsing out the show URL we check if it already exists by comparing it against the showCheck array containing all show URLs
if url not in showCheck:
query = db.sql.text("""insert into Shows (podcastID, userID, link) values (%i, %i, \"%s\")""" % (shows[y][1], userID, url))
db.con.execute(query)
print("%s has a new show" % shows[y][2])
else:
continue
count = count + 1
y=y+1
showCheck = [] #Clear out the array for the next podcast
def addFeed(userID):
newURL = input("Enter Feed URL: ")
count = 0
parsed = fp.parse(newURL)
title = parsed.feed.title
artwork = parsed.feed.image
# checks to see if the podcast URL already exists for logged in user and skips it if it has already been imported.
query = db.sql.text("""select URL from Podcasts where URL = \"%s\" and userID = %i""" % (newURL, userID))
exists = db.con.execute(query).fetchone()
# if the show doesn't already exist for the logged in user it gets added
if exists is None or exists[0] != newURL:
query = db.sql.text("""insert into Podcasts (userID, title, URL, artworkURL) values(%i, \"%s\", \"%s\", \"%s\") """ % (userID, title, newURL, artwork))
db.con.execute(query)
print("%s added" % title)
# Once the podcast is added we grab the podcastID so we can import the shows
query = db.sql.text("""select podcastID from Podcasts where userID = %i and URL = \"%s\"""" % (userID, newURL))
result = db.con.execute(query).fetchone()
podcastID = result[0]
# Import the new shows. No need to check if the show URLS already exist since it's new
for items in parsed['entries']:
itemURL = parsed.entries[count].enclosures[0].get('href')
query = db.sql.text("""insert into Shows (podcastID, userID, link) values (%i, %i, \"%s\")""" % (podcastID, userID, itemURL))
db.con.execute(query)
count = count + 1
else:
print("%s already exists" % title)
def deleteFeed(userID):
podcasts=[]
y=0
# grabs podcast urls from logged in user
query = db.sql.text("""select podcastID, title from Podcasts where userID = %i""" % userID)
results = db.con.execute(query).fetchall()
for each in results:
print("%i. %s" % (y+1, results[y][1]))
y=y+1
val = input("Delete which podcast? ")
deletedID = results[val-1][1]
print(deletedID)
query = db.sql.text("""delete * from Podcasts where podcastID = %i and userID = %i""" % (deletedID, userID))
db.con.execute(query)
query = db.sql.text("""delete * from Shows where podcastID = %i and userID = %i""" % (deletedID, userID))
db.con.execute(query)
print("%s has been deleted" % results[val][0])

4
captain-definition Normal file
View File

@@ -0,0 +1,4 @@
{
"schemaVersion": 2,
"dockerfilePath": "./docker"
}

View File

@@ -1,10 +0,0 @@
import sqlalchemy as sql
db_URI = 'mysql+pymysql://pc:pc@192.168.86.198/Podcast'
# db_URI = 'mysql+pymysql://pc:pc@dandembinski.duckdns.org:80/Podcast'
engine = sql.create_engine(db_URI)
con = engine.connect()
metadata = sql.MetaData()

9
docker Normal file
View File

@@ -0,0 +1,9 @@
FROM python:3
ADD main.py /
ADD requirements.txt /
RUN pip install -r ./requirements.txt
CMD ["python", "./main.py"]

27
helper.py Normal file
View File

@@ -0,0 +1,27 @@
import opml
import requests
API_URL = '''http://podcast-api.caprover.dandev.us'''
def feedImport ():
# outline = opml.parse("podcast_republic_podcasts.opml")
outline = opml.parse("test.opml")
#get the number of shows from the OPML file
x = len(outline)
y=0
#loops through each podcast and parses out relevant information
while y < x:
title = outline[y].title
url = outline[y].xmlUrl
artwork = outline[y].pr_artwork
desc = outline[y].pr_desc
#checks to see if the podcast URL already exists for logged in user and skips it if it has already been imported.
r = requests.post(API_URL+'/addFeed/', json={"userID" : 1, "newURL" : url.href})
print(r.text)
# print(url)
y=y+1
feedImport()

281
main.py
View File

@@ -1,46 +1,259 @@
import database as db
import Feed
import feedparser as fp
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
userID = None
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://pc:pc@67.149.14.121:3306/Podcast'
db = SQLAlchemy(app)
#############
# ALTER TABLE shows AUTO_INCREMENT = 1;
# ALTER TABLE podcasts AUTO_INCREMENT = 1;
# ALTER TABLE users AUTO_INCREMENT = 1;
#############
class users(db.Model):
userID = db.Column(db.Integer, primary_key=True)
username = db.Column(db.Text, unique=True)
password = db.Column(db.Text)
name = db.Column(db.Text)
email = db.Column(db.Text)
# token = db.column(db.Text)
class shows(db.Model):
showID = db.Column(db.Integer, primary_key=True)
podcastID = db.Column(db.Integer)
userID = db.Column(db.Integer)
link = db.Column(db.Text)
started = db.Column(db.Boolean, default=0)
position = db.Column(db.Text, default=0)
class podcasts(db.Model):
podcastID = db.Column(db.Integer, primary_key=True)
userID = db.Column(db.Integer)
title = db.Column(db.Text)
URL = db.Column(db.Text)
artworkURL = db.Column(db.Text, default=None)
@app.route('/', methods=['GET'])
def index():
stuff = """<b> /login </b<br>Method: 'GET' JSON: 'username', 'password'<br>
<b>/updateFeeds</b><br>Method: 'PUT', JSON:: 'podcastID' <i>note leave podcastID blank to update all feeds</i><br><br>
<b>/addFeed</b>to Come</b><br><br>
<b>/listPoddcasts/<userID><b><br><br>
"""
return 'stuff'
@app.route('/login/', methods=['GET'])
def login():
username = 'Dan'
password = 'password'
data = request.get_json()
query = db.sql.text(""" select userID from Users where username = \'%s\'""" % username)
result = db.con.execute(query).fetchone()
user = users.query.filter_by(username=data['username']).first()
print(result[0])
if data['password'] != user.password:
return jsonify(message='Login Failed')
else:
return jsonify(message='User logged in', userID=user.userID)
return result[0]
@app.route('/updateFeeds/', methods={'PUT'})
def updateFeeds():
data = request.get_json()
showCheck = []
updatedShows = []
if data['podcastID'] is None or data['podcastID'] == '':
# grabs podcast urls from logged in user
pc = podcasts.query.filter_by(userID=data['userID']).all()
# loops through the returned urls and parses each rss feed
for show in pc:
parsed = fp.parse(show.URL)
query = shows.query.filter_by(userID=data['userID'], podcastID=show.podcastID).all()
for x in query:
showCheck.append(x.link)
count = 0
for items in parsed['entries']:
url = parsed.entries[count].enclosures[0].get('href')
# after parsing out the show URL we check if it already exists by comparing it against the showCheck array containing all show URLs
if url not in showCheck:
query = shows(podcastID=show.podcastID, userID=data['userID'], link=url)
db.session.add(query)
new_show = {}
new_show['title'] = show.title
updatedShows.append(new_show)
else:
continue
count = count + 1
# Clear out the array for the next podcast
showCheck = []
db.session.commit()
return jsonify(newShows=updatedShows)
else:
pc = podcasts.query.filter_by(userID=data['userID'], podcastID=data['podcastID']).first()
parsed = fp.parse(pc.URL)
query = shows.query.filter_by(userID=data['userID'], podcastID=data['podcastID']).all()
for x in query:
showCheck.append(x.link)
count = 0
for items in parsed['entries']:
url = parsed.entries[count].enclosures[0].get('href')
# after parsing out the show URL we check if it already exists by comparing it against the showCheck array containing all show URLs
if url not in showCheck:
query = shows(podcastID=pc.podcastID, userID=data['userID'], link=url)
db.session.add(query)
db.session.commit()
new_show = {}
new_show['title'] = pc.title
updatedShows.append(new_show)
else:
continue
count = count + 1
return jsonify(singleShow=updatedShows)
while True:
print("1. Login\n2. Upload\n3. Update feeds\n4. Add Feed\n9. Exit\n")
val = input(">>>")
if val == "1":
userID = login()
elif val == "2":
if userID is None or userID == '':
print("Please login first")
else:
Feed.feedImport(userID)
elif val == "3":
if userID is None or userID == '':
print("Please login first")
else:
Feed.updateFeeds(userID)
elif val == "4":
if userID is None or userID == '':
print("Please login first")
else:
Feed.addFeed(userID)
elif val == "5":
if userID is None or userID == '':
print("Please login first")
else:
Feed.deleteFeed(userID)
elif val == "9":
exit()
@app.route('/addFeed/', methods=['POST'])
def addFeed():
count = 0
data = request.get_json()
parsed = fp.parse(data['newURL'])
title = str(parsed.feed.title)
if not parsed.feed.title:
artwork = str(parsed.feed.image)
else:
artwork = ''
# checks to see if the podcast URL already exists for logged in user and skips it if it has already been imported.
# if the show doesn't already exist for the logged in user it gets added
if not podcasts.query.filter_by(URL=data['newURL'], userID=data['userID']).first():
query = podcasts(userID=data['userID'], title=title, URL=data['newURL'], artworkURL=artwork)
db.session.add(query)
db.session.commit()
# Once the podcast is added we grab the podcastID so we can import the shows
result = podcasts.query.filter_by(URL=data['newURL'], userID=data['userID']).first()
# Import the new shows. No need to check if the show URLS already exist since it's new
for items in parsed['entries']:
itemURL = parsed.entries[count].enclosures[0].get('href')
query = shows(podcastID=result.podcastID, userID=data['userID'], link=itemURL)
db.session.add(query)
count = count + 1
db.session.commit()
return jsonify(title=title, added=1)
else:
return jsonify(title=title, added=0)
# @app.route('/importFeed/', methods=['POST'])
# def importFeed():
#
# count = 0
# data = request.get_json()
# parsed = fp.parse(data['newURL'])
#
# title = str(parsed.feed.title)
# artwork = str(parsed.feed.image)
#
# # checks to see if the podcast URL already exists for logged in user and skips it if it has already been imported.
# # if the show doesn't already exist for the logged in user it gets added
# if not podcasts.query.filter_by(URL=data['newURL'], userID=data['userID']).first():
# query = podcasts(userID=data['userID'], title=title, URL=data['newURL'], artworkURL=artwork)
# db.session.add(query)
# db.session.commit()
# # Once the podcast is added we grab the podcastID so we can import the shows
# result = podcasts.query.filter_by(URL=data['newURL'], userID=data['userID']).first()
# # Import the new shows. No need to check if the show URLS already exist since it's new
# for items in parsed['entries']:
# itemURL = parsed.entries[count].enclosures[0].get('href')
# query = shows(podcastID=result.podcastID, userID=data['userID'], link=itemURL)
# db.session.add(query)
# count = count + 1
# db.session.commit()
# return jsonify(message='Podcast added')
# else:
# return jsonify(message='Podcast already exists')
@app.route('/listPodcasts/<int:userID>/', methods=['GET'])
def listPodcasts(userID):
output = []
y = 0
# grabs podcast urls from logged in user
pc = podcasts.query.filter_by(userID=userID).all()
for each in pc:
result = {}
result['podcastID'] = each.podcastID
result['Title'] = each.title
output.append(result)
return jsonify(shows=output)
@app.route('/register/', methods=['POST'])
def register():
data = request.get_json()
# checks to see if the username already exists
if not users.query.filter_by(username=data['username']).first():
new_user = users(username=data['username'], password=data['password'], name=data['name'], email=data['email'])
db.session.add(new_user)
db.session.commit()
# Returns the new userID
newID = users.query.filter_by(username=data['username']).first()
return jsonify(userid=newID.userID)
# if the username doesn't already exist it will be added
else:
return jsonify(message='Username already exists')
@app.route('/updateStatus/<int:userID>/<int:podcastID>/<int:status>')
def updateStatus(userID, podcastID, status):
return ''
@app.route('/updateTime/<int:userID>/<int:podcastID>/<int:time>')
def updateTime(userID, podcastID,time):
return ''
@app.route('/deleteUser/<int:userID>/', methods=['DELETE'])
def deleteUser(userID):
users.query.filter_by(userID=userID).delete()
podcasts.query.filter_by(userID=userID).delete()
shows.query.filter_by(userID=userID).delete()
db.session.commit()
return jsonify(message="User deleted")
@app.route('/removeFeed/')
def removeFeed():
data = request.get_json()
podcasts.query.filter_by(userID=data['userID'], podcastID=data['podcastID']).delete()
shows.query.filter_by(userID=data['userID'], podcastID=data['podcastID']).delete()
return jsonify(message='Show delete')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,12 @@
Click==7.0
feedparser==5.2.1
Flask==1.1.1
Flask-SQLAlchemy==2.4.1
itsdangerous==1.1.0
Jinja2==2.11.1
lxml==4.5.0
MarkupSafe==1.1.1
opml==0.5
PyMySQL==0.9.3
SQLAlchemy==1.3.13
Werkzeug==1.0.0

5
test.opml Normal file
View File

@@ -0,0 +1,5 @@
<?xml version='1.0' encoding='UTF-8' standalone='no' ?><opml version="1.0"><head><title>Podcast Republic Subscribed Feeds</title></head><body>
<outline text="Mountain Radio Astronomy" title="Mountain Radio Astronomy" type="rss" xmlUrl="http://www.gb.nrao.edu/epo/mra.xml" pr_Id="153540555" pr_artwork="https://is4-ssl.mzstatic.com/image/thumb/Features/v4/5f/88/96/5f8896e9-9be5-529a-af14-cc807367568a/mza_1382744875394257421.png/60x60bb.jpg" pr_artwork_large="https://is4-ssl.mzstatic.com/image/thumb/Features/v4/5f/88/96/5f8896e9-9be5-529a-af14-cc807367568a/mza_1382744875394257421.png/600x600bb.jpg" pr_desc="Ever wonder about radio astronomy? Join us at the National Radio Astronomy Observatory in Green Bank, WV for fascinating interviews with astronomers who are using the largest fully steerable telescope in the world: The Robert C. Byrd Green Bank Telelscope. Each episode is about 20-30 minutes in length." pr_au="0" meidaType="0" PodSourceType="0" PodUniqueCriteria="0" playbackSpeed="1.0" />
</body></opml>