211 lines
5.6 KiB
Python
211 lines
5.6 KiB
Python
import json
|
|
import random
|
|
import re
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
from socketserver import ThreadingMixIn
|
|
|
|
# SETUP #
|
|
#
|
|
hostAddress = "0.0.0.0"
|
|
hostPort = 8081
|
|
network = re.compile(r"(127)\.(0)\.(0)\..*")
|
|
#
|
|
#############
|
|
|
|
maxPicID = 7
|
|
|
|
|
|
class Account:
|
|
def __init__(self, realName, name, picID):
|
|
self.realName = realName
|
|
self.name = name
|
|
|
|
if maxPicID < picID or picID < 0:
|
|
picID = 0
|
|
|
|
self.picID = picID
|
|
|
|
def toJSON(self):
|
|
return '{{ "realName": "{}", "name": "{}", "picID": {} }}'.format(
|
|
self.realName, self.name, self.picID
|
|
)
|
|
|
|
|
|
fakeAccounts = [
|
|
Account("Andrew Melting", "lorip", 0),
|
|
Account("Donald Trump", "realDonaldTrump", 1),
|
|
Account("Dalai Lama", "realDonaldTrump", 2),
|
|
Account("Pope Francis", "Pontifex", 3),
|
|
Account("Barack Obama", "POTUS44", 4),
|
|
Account("Lorem Ipsum", "Andrew", 5),
|
|
Account("Lorem Ipsum", "lorip", 6),
|
|
Account("Lorem Ipsum", "lorip", 7),
|
|
]
|
|
|
|
|
|
def getFakeAccount():
|
|
return fakeAccounts[random.randint(0, len(fakeAccounts) - 1)]
|
|
|
|
|
|
class Tweet:
|
|
def __init__(self, account, message):
|
|
self.account = account
|
|
self.message = message
|
|
|
|
def toJSON(self):
|
|
return '{{ "account": {}, "message": "{}" }}'.format(
|
|
self.account.toJSON(), self.message
|
|
)
|
|
|
|
|
|
class TweetHandler:
|
|
def __init__(self):
|
|
self.tweets = []
|
|
|
|
def addTweetFromRandom(self, message):
|
|
self.tweets.append(Tweet(getFakeAccount(), message))
|
|
|
|
def getTweetCount(self):
|
|
return len(self.tweets)
|
|
|
|
def getTweetAtIndex(self, index):
|
|
if index == "last":
|
|
return self.getLastTweet()
|
|
|
|
index = int(index)
|
|
if 0 <= index and index < self.getTweetCount():
|
|
return self.tweets[index].toJSON()
|
|
else:
|
|
raise ValueError("Invalid index.")
|
|
|
|
def getLastTweet(self):
|
|
if len(self.tweets) > 0:
|
|
return self.tweets[len(self.tweets) - 1].toJSON()
|
|
|
|
return ""
|
|
|
|
def delete(self, index):
|
|
if index == "last":
|
|
self.tweets.pop()
|
|
|
|
index = int(index)
|
|
if 0 <= index and index < self.getTweetCount():
|
|
self.tweets.pop(index)
|
|
else:
|
|
raise ValueError("Invalid index.")
|
|
|
|
def toJSON(self):
|
|
json = "{ tweets: [ "
|
|
for tweet in self.tweets:
|
|
json += tweet.toJSON() + ", "
|
|
|
|
if json[-2:] == ", ":
|
|
json = json[:-2] + " "
|
|
json += "]}"
|
|
|
|
return json
|
|
|
|
|
|
tweetHandler = TweetHandler()
|
|
|
|
tweetHandler.addTweetFromRandom("this is a tweet")
|
|
tweetHandler.addTweetFromRandom("covfefe")
|
|
tweetHandler.addTweetFromRandom("love thy enemy")
|
|
tweetHandler.addTweetFromRandom("this is also a tweet")
|
|
tweetHandler.addTweetFromRandom("lorem ipsum dolor sit amet")
|
|
|
|
|
|
reTweets = re.compile(r"/tweets/d*")
|
|
|
|
|
|
class server(BaseHTTPRequestHandler):
|
|
def respondWith(self, code):
|
|
self.send_response(code)
|
|
self.send_header("Access-Control-Allow-Origin", "*")
|
|
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
|
|
self.send_header("Access-Control-Allow-Headers", "*")
|
|
self.send_header("Content-type", "application/json")
|
|
self.end_headers()
|
|
|
|
def do_GET(self):
|
|
|
|
if self.path == "/tweets/":
|
|
self.respondWith(200)
|
|
self.wfile.write(bytes(tweetHandler.toJSON(), "utf-8"))
|
|
|
|
elif self.path == "/tweetCount":
|
|
self.respondWith(200)
|
|
self.wfile.write(bytes(str(tweetHandler.getTweetCount()), "utf-8"))
|
|
|
|
elif reTweets.match(self.path):
|
|
index = self.path[8:]
|
|
|
|
try:
|
|
tweet = tweetHandler.getTweetAtIndex(index)
|
|
except Exception:
|
|
self.respondWith(404)
|
|
return
|
|
|
|
self.respondWith(200)
|
|
|
|
self.wfile.write(bytes(tweet, "utf-8"))
|
|
|
|
else:
|
|
self.respondWith(404)
|
|
|
|
def do_POST(self):
|
|
if not network.match(self.client_address[0]):
|
|
print(
|
|
"Unauthorized access: "
|
|
+ str(self.client_address[0])
|
|
+ ":"
|
|
+ str(self.client_address[1])
|
|
)
|
|
self.respondWith(401)
|
|
return
|
|
|
|
length = int(self.headers["Content-Length"])
|
|
data = self.rfile.read(length).decode("utf-8")
|
|
|
|
if self.path == "/tweets/":
|
|
tweetHandler.addTweetFromRandom(data)
|
|
self.respondWith(201)
|
|
self.wfile.write(bytes(tweetHandler.getLastTweet(), "utf-8"))
|
|
|
|
else:
|
|
self.respondWith(404)
|
|
|
|
def do_DELETE(self):
|
|
if reTweets.match(self.path):
|
|
index = self.path[8:]
|
|
|
|
try:
|
|
tweetHandler.delete(index)
|
|
|
|
except Exception:
|
|
self.respondWith(404)
|
|
return
|
|
|
|
self.respondWith(204)
|
|
|
|
else:
|
|
self.respondWith(404)
|
|
|
|
def do_OPTIONS(self):
|
|
self.respondWith(200)
|
|
|
|
def log_request(code="-", size="-"):
|
|
pass
|
|
|
|
|
|
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
|
|
"""Handle requests in a separate thread."""
|
|
|
|
|
|
try:
|
|
backendServer = ThreadedHTTPServer((hostAddress, hostPort), server)
|
|
print("The EVENT server has been started. {}:{}".format(hostAddress, hostPort))
|
|
backendServer.serve_forever()
|
|
except KeyboardInterrupt:
|
|
backendServer.server_close()
|
|
print("The EVENT server has been stopped.")
|