This commit is contained in:
AndrewTrieu
2023-03-11 17:54:51 +02:00
commit 2353eec18f
4 changed files with 239 additions and 0 deletions

45
README.md Normal file
View File

@@ -0,0 +1,45 @@
# Note-Taking Application with XML-RPC
This is a simple note-taking application that allows users to add notes to different topics and retrieve them later. The application uses XML-RPC to communicate between the client and server.
## Getting Started
To use the application, you need to run the `server.py` script first. This starts the XML-RPC server on `localhost:7777`. Once the server is running, you can start the client by running the `client.py` script. The client will prompt you to choose an option:
1. Add note
2. Get notes
3. Quit
## Adding a Note
To add a note, choose option 1 and enter the topic, note name, note text, and optionally a link to a Wikipedia page related to the topic. If the topic already exists, the note will be added to it. Otherwise, a new topic will be created and the note added to it. If a Wikipedia link is added, it will be stored along with the note in the database.
## Getting Notes
To get notes, choose option 2 and enter the topic. The application will retrieve all the notes for the topic and display them on the console. If a Wikipedia link was added to a note, it will be displayed along with the note.
## Quitting
To quit the application, choose option 3.
## Demonstration
This video is recorded for the course CT30A3401 Distributed Systems at LUT University, Finland.
## File Structure
`client.py`: The client script that communicates with the server.
`server.py`: The server script that handles the XML-RPC server and database operations.
`db.xml`: The XML file that stores the notes and topics data.
## Dependencies
`xmlrpc.client`: Required for client-server communication using XML-RPC.
`xmlrpc.server`: Required for server-side XML-RPC implementation.
`requests`: Required for making HTTP requests to retrieve data from Wikipedia API.
`datetime`: Required for generating timestamps for notes.

99
client.py Normal file
View File

@@ -0,0 +1,99 @@
import xmlrpc.client
import requests
from datetime import datetime
# Create a client class
class Client:
def __init__(self):
self.server = None
def connect_server(self):
try:
self.server = xmlrpc.client.ServerProxy('http://localhost:7777')
except ConnectionRefusedError:
print("Error: Could not connect to server.")
exit()
# Start the client
def start_client(self):
while True:
action = input(
"Options:\n1) Add note\n2) Get notes\n3) Quit\nEnter your choice: ")
if action == "1":
# Get user input
topic = input("Enter the topic: ")
note = input("Enter the note topic: ")
text = input("Enter the note text: ")
date_time = datetime.now()
timestamp = date_time.strftime("%m/%d/%Y - %H:%M:%S")
result = self.server.check_topic(topic)
# Check if the topic exists
if result:
# Append note to existing topic
adding = self.server.add_note(topic, note, text, timestamp)
if (not adding):
print("Error: Could not add note to topic.")
return
else:
# Create new topic and add note
create = self.server.create_topic(topic)
if (not create):
print("Error: Could not create topic.")
return
adding = self.server.add_note(topic, note, text, timestamp)
if (not adding):
print("Error: Could not add note to topic.")
return
# Ask if user wants to add a link from Wikipedia
wiki_query = input(
"Do you want to add a link to the note topic from Wikipedia? (y/n): ")
if wiki_query == 'y':
search_term = input("Enter search term for Wikipedia: ")
wiki_data = requests.get(
f"https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search={search_term}").json()
if wiki_data[3]:
link = wiki_data[3][0]
else:
no_wiki = print(
"No Wikipedia article found!")
link = 'No link'
else:
link = "No link"
# Add the link to the note topic
add_link = self.server.add_link(topic, link)
if (not add_link):
print("Error: Could not add link to note.")
return
elif action == "2":
# Get all the notes of a topic
topic = input("Enter the topic: ")
notes = self.server.get_notes(topic)
if (not notes):
print("Error: Could not get notes.")
return
print()
for note in notes:
print(
f"{note['name']} - {note['text']} ({note['timestamp']}): {note['info']}")
print()
elif action == "3":
# Quit the client
break
else:
print("Invalid option!")
# Run the client
if __name__ == '__main__':
client = Client()
client.connect_server()
client.start_client()

21
db.xml Normal file
View File

@@ -0,0 +1,21 @@
<data>
<topic name="Finland">
<note name="Lahti">
<text>Nice city</text>
<timestamp>03/11/2023 - 17:45:33</timestamp>
<info>https://en.wikipedia.org/wiki/Lahti</info>
</note>
<note name="Helsinki">
<text>Capital</text>
<timestamp>03/11/2023 - 17:49:27</timestamp>
<info>https://en.wikipedia.org/wiki/Helsinki</info>
</note>
</topic>
<topic name="Students">
<note name="Lahti campus">
<text>Sad</text>
<timestamp>03/11/2023 - 17:49:50</timestamp>
<info>No link</info>
</note>
</topic>
</data>

74
server.py Normal file
View File

@@ -0,0 +1,74 @@
import xmlrpc.server
import xml.etree.ElementTree as ET
# Class to handle the server side of the XML-RPC server
class Server:
def __init__(self):
self.db = ET.parse('db.xml')
self.root = self.db.getroot()
# Check if the topic exists
def check_topic(self, topic):
for child in self.root:
if child.attrib['name'] == topic:
return True
return False
# Create a new topic if it doesn't exist
def create_topic(self, topic):
new_topic = ET.Element('topic', {'name': topic})
self.root.append(new_topic)
self.db.write('db.xml')
return True
# Add a note of a topic to the database
def add_note(self, topic, note, text, timestamp):
for child in self.root:
if child.attrib['name'] == topic:
new_note = ET.Element('note', {'name': note})
new_text = ET.Element('text')
new_text.text = text
new_note.append(new_text)
new_timestamp = ET.Element('timestamp')
new_timestamp.text = timestamp
new_note.append(new_timestamp)
child.append(new_note)
self.db.write('db.xml')
return True
return False
# Add a Wikipedia link to the note
def add_link(self, topic, info):
for child in self.root:
if child.attrib['name'] == topic:
# get the last note element
last_note = child.findall('note')[-1]
new_info = ET.Element('info')
new_info.text = info
last_note.append(new_info)
self.db.write('db.xml')
return True
return False
# Get all the notes of a topic
def get_notes(self, topic):
for child in self.root:
if child.attrib['name'] == topic:
notes = []
for note in child.findall('note'):
notes.append({
'name': note.attrib['name'],
'text': note.find('text').text,
'timestamp': note.find('timestamp').text,
'info': note.find('info').text
})
return notes
# Start the server
if __name__ == '__main__':
server = xmlrpc.server.SimpleXMLRPCServer(('localhost', 7777))
server.register_instance(Server())
server.serve_forever()