From 9ea0849db27460c27608b569c002d7f4bb565965 Mon Sep 17 00:00:00 2001 From: Landon Gaddy Date: Thu, 3 Nov 2022 21:30:59 -0400 Subject: [PATCH 1/7] Removed Unused file --- src/account_info.html | 1045 ----------------------------------------- 1 file changed, 1045 deletions(-) delete mode 100644 src/account_info.html diff --git a/src/account_info.html b/src/account_info.html deleted file mode 100644 index df0d5cb..0000000 --- a/src/account_info.html +++ /dev/null @@ -1,1045 +0,0 @@ - - - - - - -account_info API documentation - - - - - - - - - - - -
-
-
-

Module account_info

-
-
-
- -Expand source code - -
import numpy as np
-import pandas as pd
-import sys
-
-class AccountInfo:
-    def __init__(self):
-        try:
-            self.database = 'data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        except FileNotFoundError:
-            self.database = '../data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        
-    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = sorted(self.data.ID.tolist(), reverse=True)
-        lastID = id_list[0]
-        if name == '':
-            print('Name cannot be empty')
-            return -1
-        else:
-            account_dict = {
-                'ID': lastID+1,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            self.data = self.data.append(account_dict, ignore_index=True)
-            self.data.to_csv(self.database, index=False)
-            print('Account created successfully!')
-        return self.data[self.data['ID']==lastID+1]
-    
-    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('User ID:', ID, 'is not in the database!!!')
-            return -1
-        else:
-            data = self.data[self.data['ID']==ID]
-            # if name=='':
-            #     name = data.Name.values[0]
-            # if surname=='':
-            #     surname = data.Surname.values[0]
-            # if birthday=='':
-            #     birthday = data.Birthday.values[0]
-            # if interests=='':
-            #     interests = data.Interests.values[0]
-            # if wishlist=='':
-            #     wishlist = data.WishList.values[0]
-            #     print(wishlist)
-            # if friendlist=='':
-            #     friendlist = data.FriendList.values[0]
-            account_dict = {
-                'ID': ID,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            index = self.data[self.data['ID']==ID].index[0]
-            #self.data.at[index, 'WishList'] = account_dict
-            self.data.loc[index,'ID'] = ID
-            self.data.loc[index,'Name'] = name
-            self.data.loc[index, 'Surname'] = surname
-            self.data.loc[index, 'Birthday'] = birthday
-            self.data.loc[index, 'Interests'] = interests
-            self.data.loc[index, 'WishList'] = wishlist
-            print(type(wishlist))
-            self.data.loc[index, 'FriendList'] = friendlist
-            self.data.to_csv(self.database, index=False)
-            print('Account updated successfully!')
-        return self.data[self.data['ID']==ID]
-    
-    def get_database(self):
-        return self.data
-    
-    def delete_account(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            matched_data = self.data[self.data['ID']==ID]
-            self.data = self.data.drop(matched_data.index)
-            print('Account deleted successfully!')
-            self.data.to_csv(self.database, index=False)
-        return matched_data
-    
-    def get_info(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            return self.data[self.data['ID']==ID]
-        
-    def search_ID(self, ID):
-        if ID == None:
-            print("ID cannot be empty!!!")
-            return [0], -1
-        ID_result = self.data[self.data['ID']==ID]
-        if ID_result.values.size == 0:
-            print("ID not found! Try ID ranges from 0 to 10.")
-            return [0], -1
-        return ID_result, True
-        
-    def get_name(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][1]
-    
-    def get_surname(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][2]
-        
-    def get_birthday(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][3]
-    
-    def get_interests(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][4]
-        
-    def get_wishlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][5]
-        
-    def add_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                print('Item ID:', _item, 'is already in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.append(str(_item))
-                print('Item ID:', _item, 'is added successfully!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-    
-    def delete_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                if len(wl_str):
-                    print('There are no items in the wishlist!!!')
-                    flag = 0
-                else:
-                    wl_str.remove(str(_item))
-                    print('Item ID:', _item, 'is removed successfully!!!')
-            else:
-                print('Item ID:', _item, 'is not found in the wishlist!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-        
-    def get_friendlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == False:
-            return False
-        else:
-            result_dict = result.values
-            return result_dict[0][6]
-
-
-class Friends(AccountInfo):
-    def __init__(self):
-        super().__init__()
-    
-    def get_friend_names(self,ID):
-        friend_names = []
-        friend_ids = self.get_friendlist(ID)
-        for c in friend_ids:
-            try:
-                if int(c):
-                    friend_id = int(c)
-                    fname = self.get_name(friend_id)
-                    sname = self.get_surname(friend_id)
-                    aname = fname + " " + sname 
-                    friend_names.append(aname)
-            except:
-                pass
-            
-        return friend_names
-    
-    def add_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        if str(fl_str)=='nan':
-            fl_str = []
-        else:
-            fl_str = fl_str.replace('"','')
-            fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                print('ID:', _id, 'is Already friend!!!')
-            else:
-                fl_str.append(str(_id))
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-    def delete_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                fl_str.remove(str(_id))
-            else:
-                print('ID:', _id, 'not found in the friend list!!')
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class AccountInfo -
-
-
-
- -Expand source code - -
class AccountInfo:
-    def __init__(self):
-        try:
-            self.database = 'data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        except FileNotFoundError:
-            self.database = '../data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        
-    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = sorted(self.data.ID.tolist(), reverse=True)
-        lastID = id_list[0]
-        if name == '':
-            print('Name cannot be empty')
-            return -1
-        else:
-            account_dict = {
-                'ID': lastID+1,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            self.data = self.data.append(account_dict, ignore_index=True)
-            self.data.to_csv(self.database, index=False)
-            print('Account created successfully!')
-        return self.data[self.data['ID']==lastID+1]
-    
-    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('User ID:', ID, 'is not in the database!!!')
-            return -1
-        else:
-            data = self.data[self.data['ID']==ID]
-            # if name=='':
-            #     name = data.Name.values[0]
-            # if surname=='':
-            #     surname = data.Surname.values[0]
-            # if birthday=='':
-            #     birthday = data.Birthday.values[0]
-            # if interests=='':
-            #     interests = data.Interests.values[0]
-            # if wishlist=='':
-            #     wishlist = data.WishList.values[0]
-            #     print(wishlist)
-            # if friendlist=='':
-            #     friendlist = data.FriendList.values[0]
-            account_dict = {
-                'ID': ID,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            index = self.data[self.data['ID']==ID].index[0]
-            #self.data.at[index, 'WishList'] = account_dict
-            self.data.loc[index,'ID'] = ID
-            self.data.loc[index,'Name'] = name
-            self.data.loc[index, 'Surname'] = surname
-            self.data.loc[index, 'Birthday'] = birthday
-            self.data.loc[index, 'Interests'] = interests
-            self.data.loc[index, 'WishList'] = wishlist
-            print(type(wishlist))
-            self.data.loc[index, 'FriendList'] = friendlist
-            self.data.to_csv(self.database, index=False)
-            print('Account updated successfully!')
-        return self.data[self.data['ID']==ID]
-    
-    def get_database(self):
-        return self.data
-    
-    def delete_account(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            matched_data = self.data[self.data['ID']==ID]
-            self.data = self.data.drop(matched_data.index)
-            print('Account deleted successfully!')
-            self.data.to_csv(self.database, index=False)
-        return matched_data
-    
-    def get_info(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            return self.data[self.data['ID']==ID]
-        
-    def search_ID(self, ID):
-        if ID == None:
-            print("ID cannot be empty!!!")
-            return [0], -1
-        ID_result = self.data[self.data['ID']==ID]
-        if ID_result.values.size == 0:
-            print("ID not found! Try ID ranges from 0 to 10.")
-            return [0], -1
-        return ID_result, True
-        
-    def get_name(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][1]
-    
-    def get_surname(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][2]
-        
-    def get_birthday(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][3]
-    
-    def get_interests(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][4]
-        
-    def get_wishlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][5]
-        
-    def add_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                print('Item ID:', _item, 'is already in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.append(str(_item))
-                print('Item ID:', _item, 'is added successfully!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-    
-    def delete_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                if len(wl_str):
-                    print('There are no items in the wishlist!!!')
-                    flag = 0
-                else:
-                    wl_str.remove(str(_item))
-                    print('Item ID:', _item, 'is removed successfully!!!')
-            else:
-                print('Item ID:', _item, 'is not found in the wishlist!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-        
-    def get_friendlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == False:
-            return False
-        else:
-            result_dict = result.values
-            return result_dict[0][6]
-
-

Subclasses

- -

Methods

-
-
-def add_wishlist(self, ID, items) -
-
-
-
- -Expand source code - -
def add_wishlist(self, ID, items):
-    flag = 1
-    wl_str = self.get_wishlist(ID)
-    if str(wl_str)=='nan':
-        wl_str = []
-    else:
-        wl_str = wl_str.replace('"','')
-        wl_str = wl_str.split(', ')
-    for _item in items:
-        if str(_item) in wl_str:
-            print('Item ID:', _item, 'is already in the wishlist!!!')
-            flag = 0
-        else:
-            wl_str.append(str(_item))
-            print('Item ID:', _item, 'is added successfully!!!')
-    wl_str = ', '.join(i for i in wl_str)
-    wl_str = '"' + wl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'WishList'] = wl_str
-    self.data.to_csv(self.database, index=False)
-    return self.data[self.data['ID']==ID]
-
-
-
-def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-    id_list = sorted(self.data.ID.tolist(), reverse=True)
-    lastID = id_list[0]
-    if name == '':
-        print('Name cannot be empty')
-        return -1
-    else:
-        account_dict = {
-            'ID': lastID+1,
-            'Name': name,
-            'Surname': surname,
-            'Birthday': birthday,
-            'Interests': interests,
-            'WishList': wishlist,
-            'FriendList': friendlist
-        }
-        self.data = self.data.append(account_dict, ignore_index=True)
-        self.data.to_csv(self.database, index=False)
-        print('Account created successfully!')
-    return self.data[self.data['ID']==lastID+1]
-
-
-
-def delete_account(self, ID) -
-
-
-
- -Expand source code - -
def delete_account(self, ID):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        print('Invalid ID, please enter valid ID.')
-        return -1
-    else:
-        matched_data = self.data[self.data['ID']==ID]
-        self.data = self.data.drop(matched_data.index)
-        print('Account deleted successfully!')
-        self.data.to_csv(self.database, index=False)
-    return matched_data
-
-
-
-def delete_wishlist(self, ID, items) -
-
-
-
- -Expand source code - -
def delete_wishlist(self, ID, items):
-    flag = 1
-    wl_str = self.get_wishlist(ID)
-    if str(wl_str)=='nan':
-        wl_str = []
-    else:
-        wl_str = wl_str.replace('"','')
-        wl_str = wl_str.split(', ')
-    for _item in items:
-        if str(_item) in wl_str:
-            if len(wl_str):
-                print('There are no items in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.remove(str(_item))
-                print('Item ID:', _item, 'is removed successfully!!!')
-        else:
-            print('Item ID:', _item, 'is not found in the wishlist!!!')
-    wl_str = ', '.join(i for i in wl_str)
-    wl_str = '"' + wl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'WishList'] = wl_str
-    self.data.to_csv(self.database, index=False)
-    return self.data[self.data['ID']==ID]
-
-
-
-def get_birthday(self, ID) -
-
-
-
- -Expand source code - -
def get_birthday(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][3]
-
-
-
-def get_database(self) -
-
-
-
- -Expand source code - -
def get_database(self):
-    return self.data
-
-
-
-def get_friendlist(self, ID) -
-
-
-
- -Expand source code - -
def get_friendlist(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == False:
-        return False
-    else:
-        result_dict = result.values
-        return result_dict[0][6]
-
-
-
-def get_info(self, ID) -
-
-
-
- -Expand source code - -
def get_info(self, ID):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        print('Invalid ID, please enter valid ID.')
-        return -1
-    else:
-        return self.data[self.data['ID']==ID]
-
-
-
-def get_interests(self, ID) -
-
-
-
- -Expand source code - -
def get_interests(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][4]
-
-
-
-def get_name(self, ID) -
-
-
-
- -Expand source code - -
def get_name(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][1]
-
-
-
-def get_surname(self, ID) -
-
-
-
- -Expand source code - -
def get_surname(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][2]
-
-
-
-def get_wishlist(self, ID) -
-
-
-
- -Expand source code - -
def get_wishlist(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][5]
-
-
-
-def search_ID(self, ID) -
-
-
-
- -Expand source code - -
def search_ID(self, ID):
-    if ID == None:
-        print("ID cannot be empty!!!")
-        return [0], -1
-    ID_result = self.data[self.data['ID']==ID]
-    if ID_result.values.size == 0:
-        print("ID not found! Try ID ranges from 0 to 10.")
-        return [0], -1
-    return ID_result, True
-
-
-
-def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        print('User ID:', ID, 'is not in the database!!!')
-        return -1
-    else:
-        data = self.data[self.data['ID']==ID]
-        # if name=='':
-        #     name = data.Name.values[0]
-        # if surname=='':
-        #     surname = data.Surname.values[0]
-        # if birthday=='':
-        #     birthday = data.Birthday.values[0]
-        # if interests=='':
-        #     interests = data.Interests.values[0]
-        # if wishlist=='':
-        #     wishlist = data.WishList.values[0]
-        #     print(wishlist)
-        # if friendlist=='':
-        #     friendlist = data.FriendList.values[0]
-        account_dict = {
-            'ID': ID,
-            'Name': name,
-            'Surname': surname,
-            'Birthday': birthday,
-            'Interests': interests,
-            'WishList': wishlist,
-            'FriendList': friendlist
-        }
-        index = self.data[self.data['ID']==ID].index[0]
-        #self.data.at[index, 'WishList'] = account_dict
-        self.data.loc[index,'ID'] = ID
-        self.data.loc[index,'Name'] = name
-        self.data.loc[index, 'Surname'] = surname
-        self.data.loc[index, 'Birthday'] = birthday
-        self.data.loc[index, 'Interests'] = interests
-        self.data.loc[index, 'WishList'] = wishlist
-        print(type(wishlist))
-        self.data.loc[index, 'FriendList'] = friendlist
-        self.data.to_csv(self.database, index=False)
-        print('Account updated successfully!')
-    return self.data[self.data['ID']==ID]
-
-
-
-
-
-class Friends -
-
-
-
- -Expand source code - -
class Friends(AccountInfo):
-    def __init__(self):
-        super().__init__()
-    
-    def get_friend_names(self,ID):
-        friend_names = []
-        friend_ids = self.get_friendlist(ID)
-        for c in friend_ids:
-            try:
-                if int(c):
-                    friend_id = int(c)
-                    fname = self.get_name(friend_id)
-                    sname = self.get_surname(friend_id)
-                    aname = fname + " " + sname 
-                    friend_names.append(aname)
-            except:
-                pass
-            
-        return friend_names
-    
-    def add_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        if str(fl_str)=='nan':
-            fl_str = []
-        else:
-            fl_str = fl_str.replace('"','')
-            fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                print('ID:', _id, 'is Already friend!!!')
-            else:
-                fl_str.append(str(_id))
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-    def delete_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                fl_str.remove(str(_id))
-            else:
-                print('ID:', _id, 'not found in the friend list!!')
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-
-

Ancestors

- -

Methods

-
-
-def add_friend(self, ID: int, friend_IDs: list) -
-
-
-
- -Expand source code - -
def add_friend(self, ID: int, friend_IDs: list):
-    fl_str = self.get_friendlist(ID)
-    if str(fl_str)=='nan':
-        fl_str = []
-    else:
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-    for _id in friend_IDs:
-        if str(_id) in fl_str:
-            print('ID:', _id, 'is Already friend!!!')
-        else:
-            fl_str.append(str(_id))
-    fl_str = ', '.join(i for i in fl_str)
-    fl_str = '"' + fl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'FriendList'] = fl_str
-    return self.data[self.data['ID']==ID]
-
-
-
-def delete_friend(self, ID: int, friend_IDs: list) -
-
-
-
- -Expand source code - -
def delete_friend(self, ID: int, friend_IDs: list):
-    fl_str = self.get_friendlist(ID)
-    fl_str = fl_str.replace('"','')
-    fl_str = fl_str.split(', ')
-    for _id in friend_IDs:
-        if str(_id) in fl_str:
-            fl_str.remove(str(_id))
-        else:
-            print('ID:', _id, 'not found in the friend list!!')
-    fl_str = ', '.join(i for i in fl_str)
-    fl_str = '"' + fl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'FriendList'] = fl_str
-    return self.data[self.data['ID']==ID]
-
-
-
-def get_friend_names(self, ID) -
-
-
-
- -Expand source code - -
def get_friend_names(self,ID):
-    friend_names = []
-    friend_ids = self.get_friendlist(ID)
-    for c in friend_ids:
-        try:
-            if int(c):
-                friend_id = int(c)
-                fname = self.get_name(friend_id)
-                sname = self.get_surname(friend_id)
-                aname = fname + " " + sname 
-                friend_names.append(aname)
-        except:
-            pass
-        
-    return friend_names
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file From 04d07c0e5b9873a11f7980571bcc8ad55cf30433 Mon Sep 17 00:00:00 2001 From: Landon Gaddy Date: Wed, 9 Nov 2022 18:35:26 -0500 Subject: [PATCH 2/7] Added inital front-end changes --- data/people_data-copy.csv | 2 +- src/.streamlit/config.toml | 5 + src/PATHS.py | 17 + src/__pycache__/PATHS.cpython-39.pyc | Bin 0 -> 563 bytes src/__pycache__/account.cpython-39.pyc | Bin 1581 -> 1609 bytes src/__pycache__/account_info.cpython-39.pyc | Bin 7706 -> 7734 bytes src/__pycache__/item.cpython-39.pyc | Bin 1512 -> 1540 bytes src/__pycache__/item_manager.cpython-39.pyc | Bin 2175 -> 2203 bytes src/__pycache__/utils.cpython-39.pyc | Bin 0 -> 6035 bytes src/account.html | 227 ----------- src/assets/images/gift-flat.ico | Bin 0 -> 169884 bytes src/assets/images/gift-flat.png | Bin 0 -> 24448 bytes src/assets/images/github-logo.png | Bin 0 -> 8640 bytes src/assets/images/profile.png | Bin 0 -> 30310 bytes src/assets/images/settings.png | Bin 0 -> 87087 bytes src/assets/styles.css | 284 +++++++++++++ src/item.html | 230 ----------- src/item_manager.html | 272 ------------- src/main.py | 172 ++++++-- src/utils.py | 153 +++++++ src/wishlist.html | 419 -------------------- 21 files changed, 593 insertions(+), 1188 deletions(-) create mode 100644 src/.streamlit/config.toml create mode 100644 src/PATHS.py create mode 100644 src/__pycache__/PATHS.cpython-39.pyc create mode 100644 src/__pycache__/utils.cpython-39.pyc delete mode 100644 src/account.html create mode 100644 src/assets/images/gift-flat.ico create mode 100644 src/assets/images/gift-flat.png create mode 100644 src/assets/images/github-logo.png create mode 100644 src/assets/images/profile.png create mode 100644 src/assets/images/settings.png create mode 100644 src/assets/styles.css delete mode 100644 src/item.html delete mode 100644 src/item_manager.html create mode 100644 src/utils.py delete mode 100644 src/wishlist.html diff --git a/data/people_data-copy.csv b/data/people_data-copy.csv index 771f2df..a0cf4a7 100644 --- a/data/people_data-copy.csv +++ b/data/people_data-copy.csv @@ -1,5 +1,5 @@ ID,Name,Surname,Birthday,Interests,WishList,FriendList -1,Yagmur Basak,Bayraktar,12/17/1994,"Dancing, Reading, Cooking, Ballet, Writing","3,5,11,17"," 5, 6, 2, 3" +1,Yagmur Basak,Bayraktar,12/17/1994,"Dancing, Reading, Cooking, Ballet, Writing","3,5,11,17"," 5, 6, 2, 3,1,1,1,1,1,1,1,1,1" 2,Murat,Bayraktar,9/7/1995,"Basketball, Football, Electronics","3,5",1 3,Jane,Doe,1/1/2000,"Hiking, Climbing, Bungee Jumping",5,4 4,John,Doe,2/2/1999,"Painting, Sculpting, Art","2, 3","3, 5" diff --git a/src/.streamlit/config.toml b/src/.streamlit/config.toml new file mode 100644 index 0000000..88fd354 --- /dev/null +++ b/src/.streamlit/config.toml @@ -0,0 +1,5 @@ +[theme] +primaryColor="#C00000" +backgroundColor="#FFFFFF" +secondaryBackgroundColor="#F0F2F6" +textColor="#31333F" diff --git a/src/PATHS.py b/src/PATHS.py new file mode 100644 index 0000000..af8883c --- /dev/null +++ b/src/PATHS.py @@ -0,0 +1,17 @@ +NAVBAR_PATHS = { + 'HOME':'home', + 'WISHLIST': 'wishlist', + 'FRIENDLIST': 'friendlist' +} + +FOOTER_PATHS = { + # 'GitHub Repository':'https://github.com/landog893/Gifter-2', + 'Code of Conduct': 'https://github.com/landog893/Gifter-2/blob/main/CODE_OF_CONDUCT.md', + 'MIT License': 'https://github.com/landog893/Gifter-2/blob/main/LICENSE', + "Made with Streamlit": 'https://streamlit.io/' +} + +SETTINGS = { + 'PROFILE':'profile', + 'LOGOUT':'logout' +} \ No newline at end of file diff --git a/src/__pycache__/PATHS.cpython-39.pyc b/src/__pycache__/PATHS.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32536c6b703c69a9cf819b2beaba7c65b3270be9 GIT binary patch literal 563 zcmb7BU2EGg6m^^|@sf0X==ScXK^_|KgR!=ZvQ%*rgJYG**+wx0$5Ik8TMCl0Qva6z zf&H4j>$UwAV;hqLfxYeuoqG*<;PJ9xCx~G>rIYu6$_#Teya8 zT)(g1Sh#_o;3jSvUc(N4ire@0jg33V>UDKv!waIFTPim>l}fi)f)a)+-mB}z1WtYJ zd=Ahg3{b4wqgmib!-|(z8>P1L!t>TtZFb9k#tSb`8RqM=^S9oZt`rfcZ@gvBmtK)l z<^eeL7jU!yFdEK5+%ItX{(onL0q`T_moE;DQVEh4IaPhiyCJ zx*E(D*MoS1baw<{>>rea{5TGxG5T(aXU6_L{QLqglDQ;8CSm0ZOCTddLBA3A)Qz|> zOMq1HoU+txlPcoQnJEfM)m;J*aNoUtl^lFbq{x!})BWw8c0Lpw?{ac!S0Db|fL$}^ MchlMDU;F&$FBuxE7XSbN literal 0 HcmV?d00001 diff --git a/src/__pycache__/account.cpython-39.pyc b/src/__pycache__/account.cpython-39.pyc index 43990e0452fb6676d768ced169fd7a9e2c0f55ab..f736fe70b1bb324c9e6b22124bf6801af54286b5 100644 GIT binary patch delta 102 zcmZ3>bCQQUk(ZZ?0SH*4Q#NvYGWkR~Tg8MHrxq2*_$20~7#mZU0#<^d&(iZe?pW1NGX6-*5cV%#&+N>Yn-jW)M1tz-rO DE zJ&30Vf*yoj1P`JTa0i)Qy!r=E(u0Ec;Y|=>_`cD#B0DUQ58vOPm-o%@y@%t-fma)ZxW)ipMec>%v}#I zA?Op=g>l|M$Jl2v$rC@sXTk&$lWff|vDe`Tt+0o!M(%Hi@#ynyx#sV2zee8?l44I| z4#}{?@uGB`e?%2-*2=a+)sC|17%QHONAXn>Q?SD{5CLY`5owsrvZ8doKZOJ)L$gig zg(AW;9B&|UY*U(@$w20Tv%nlj!&fsbdH_nG#!8*fsDPRP^a1Ap8Snw;y&t{X^{Vwd z5-WE<&J3V>6c_?VfKk93*c4P6I02jjJUjDH7k~wp-TRFXWpLk@;sQ@Je5U2l*2054 zHxQ&j^mcNn;VLx^t5UY~6~k6Te$$wcEZ^@h>|%=Fv1^Xa z^rjVf`)`Wg04WUaG`%N6%QUURx%;+vlEnTwQLMbe#6)oyR<_WbV|NlK$2=>|v;1SK zgfb3vCo6QB#iLy;k~}?l5iKgP2!sIx&^a3IHIv`OtB9|$+sWjiOOW2B(zyD-Upv4N YAYor17VD%M+er2csL_yjMYfWO--JKXYXATM delta 901 zcma))%}*0S7{;A`(Pdj$psk1$^dvN)mHe zV8(dRg9lF}9yFV1JP?n>gL?4f9E|bk#Xo?AIL~UKhaT8ue|esF-`#okoq3mho|Ls< zu=|v_>iem;@&QSt({t*EX;4#rsFiC?b+J)s){MGks!J7Xxv8t^_4LeSBEL!-ca4HI zX|K8BF2e0cp2sdSZufS1g=1l9k0k7GQh^9FE5DCj5=+n-fn6_^p!)^5j~ZsPYH?4g zs+GCyIJV=7uy}y^E~9OZ?FU}B%bJ zI=KB{Q139Z-)FKX7}g&o%rb2#nMStuVZn|72uM3jZP#}knr?|EZvPybB}&`I;mvJ! zVK{e!D2HgyvRA{YDJROmEkn`S!CO#Ho(@qcW#OnA%cJKupaB7(0h9%}r&qzo;Zb!8x%gKPNLUQ6ab_u_RR?G!H0QRGe8- z8RH!6tYB(r5aXViR+3tzYcyG#X_7+}M`B7!d}c{%ZV|ezK>IYAiv&R~5C##_W0;@@3`>U9b(z z5F0o_)__b|$%N!OWE~kS3C2h|ZgHoi=ArD>L~wOM<32h$#RfBte8U oSO!EORD)S!lUrDoHKTYyK^LE!n3tHIS_E+)S~x*fUtpC006oHE(*OVf delta 470 zcmZqSdBM${$ji&c00aU4&KtRN85wU)u4D`m;0B5m@qh?k5WzS3E~BKW7?AnP+Sw{5 zv^ce>IHoc&J-0N*B|o_|H#M)MIL1A*#G^DR#yQy8)X*S4peR2pHMzuavOCixhg%$p zDJk)pC8@bZ=q3Zr)MPFa0@)%0BA7u0$R-FO4q^#TmSnDsl>{<1*^8J!B3Mkh#a&vE zl30=ov4$U{mfo;gDoYy&gI22h|BflOJ+gycG89W5*g#z;DDai^r_ zq$1m2BnvVFNehT8KUthLK~n<66a*16AVLl-10oQr!7TB~3s{vkZ}EVFEzmn6=#-I#yAH%E0`J@#JFdsm82Hw8f{+7xQ&r9 zYI6!RFC(MU&WPSE?qKZJ~E#}O;k|K4Gpbm)8pDe_Y3jj@?IynFU delta 196 zcmbO&_+NlKk(ZZ?0SK}poHue8F&a2KTg8MHrxq2*R3@h9md3c`Czs}?=9Lu3xM!Al zlqSVE2RoY@8pH<_xJbD~N><}K#T Wypkdfkf1JzFqoXrAwJoaBMbmK0x_Kc diff --git a/src/__pycache__/utils.cpython-39.pyc b/src/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c870cfd86cdde73a91c6dbb27230d6a3af728823 GIT binary patch literal 6035 zcmc&&TXWmS6$U_%1Sv|EoHTYaxu8fpCL4>iY&UgmlC3VblTL>2L`u^taycM(NkRev zdUr`xEcxWVW-@(k$20b0-um7@(!pz=`V;D2&n_+mMbdH`jSCJJz+TRN=j`q|=YzSt zoR#4E-HoH>cP~rQU-(P>QsCt$@TZ?bfg~i`(!MP2%Dw`3#ZGk9eO2ad2|L+M?Welw z{d8B`*Pu>C$=^!*8I(e4xMz`uGH_o)@~%|K{uLxjwSw%a9oDrA2`^XM{Q1`AXZ4?L z?tQ%Lfbg;W^$*4plMfZ7jHIWD zXVM=4+mi%G^OYh?UjSAWevcEf=7QbIYi6p?5stwmnN-?7)%1&%di%m+0 z>9TmK4z;phUETXe_SX6iHCwoD+O~UK7pkb9>h`eXDU^9y*Ca>CJ$5{mU=xA5a_bw3 zECbl*zu3Ng@HxeV9(-y#$aM}LICzIx1FWy>HJ7lCzHJiMwj5L6WhTS==MFRyYO#}p z?cHttha1-p?prN}$@=vJN}30KX4$mZJMq>m=MXnpz1gSC?bZQ3HxpH%kmRgPF2KFX ztruQ=7etnXr4yD!%46m0cgHf5pDH7nTk@GaR%Yy1oU&hHoM7tH&;_*m74Ne)r+<2!Mi)m3Xnk#zhVpfgpt0=X(nv$!L2vNg zfi8_REH}zLmV>=;xi)+=*b7$IY-3vL5w~U8xY%>roTr#V$i%h@jJtG_g8;w~`o7T+1WL$Ol$E+T^%E%go0}ye0 zd{5~e3t@kTP{s~4?Ld=Jof;hqD)&Me0JLUyu~99TdJFnm-FDcU&)8s&p~E(-7|3Mi zZDEZP7~xLCr1-;|SM}$~K5MPt8rF@{0*PD)ZjbH>$H`TQj1cOy-gF&?9kxILuE_Am z^K~nM_}Piev(=tja~(W1r^L)N@VB+?Jvi@4%R%_p!=Ij?orm3N;INe8I&tHfmV=27 zl?{{l3Ixw{Y}2>Hko zHi^|^lTOEAEcdwBGYM>gB66GkE`MlacGt%IaqHw0ls7sq?A$`pb(*%-Jkl$AtM4?K zKZE%t<*|hDvQKW3oY)~EUTYbh{M{kImQTX!O!=jicUx-AH zqo)NEoJM?X(T=e1D?`0;4yaqi!VY@1xUZiB?!ZOAx-D|!96;M{+wHSghxz6_%+bCs zl>!%{!ztk>k48-cQ@9taZSo^0PEAEW^BmBvlWiU&dDO{Aak6k{N^H}{rc)EHD}JiM zkp#2V12m`4`D~9O!CiNNHyI-q9A%up!b}3k^2)qZ9D!)LM9*^tEtvn>9k`Xb9b&o` zZS1sJ2bwQ^fHYPZ(^tE zB21Q`o+NlqUbL$kmfzu`#-kp;k!WnKMOWxw$vm&Rh^X%Tc z;6IzR9!!=4`$9%l7vjCd5kB#f1JmwfZza?sXiM|i_RO}IX}aAWWSS21ltU^=pI@x- z*;WIAQ729cX%z}d&dFC5RbG`Zi&BwS|D8%G3GJV1Qu(`<(G*3={Y#DBm4xEAXe+Y1 zLB0`jZ?@aTpw#7RA#ySs=oO6*? zP=KsKF?@T%yIQUbJUC9hh8K0i_xKf~-mp#Q$f%NwFwD#Xzm3i+cMN5JbeIZHl4!r) zPojh8Nv_IA@~b>aqWwM#^5_?V?J(A(w@W2o*CK3*5+Fuy`_@M{N+HLeQD;gC9}K{W z(KZnGali3m)<$0ArhKr7v)vcg*FVEO7d||=hab&U&60+4$v4>a@PH)z z2~M++F+&pkK`-M}{U8{u+$8S%^kT;%i)G9q2wfmnf(=BPxi&fr%K|xiRS!`Cy@&+D z&Z92GLD=hgqlS--3Fdgyg5ZDlT!CYrNaa!Z+e(8B>H6tJD6(+Ta^MRW+rp4o;k>W& zRXsA?1PR~1<7{LJpM1R_a?Vk9A%n|K&xXTo*AZn$ib@d5%WScUpW7qPRHu3h}Gl`?yWEJLWF4k36j8 - - - - - -account API documentation - - - - - - - - - - - -
-
-
-

Module account

-
-
-
- -Expand source code - -
from account_info import AccountInfo
-
-class Account():
-    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
-        if ID != None:
-            accountMan = AccountInfo()
-            info = accountMan.get_info(ID)
-            self.name = info['Name']
-            self.surname = info['Surname']
-            self.birthday = info['Birthday']
-            self.interests = info['Interests']
-            self.wishlist = info['WishList']
-            self.friendlist = info['FriendList']
-            self.ID = ID
-        else: 
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            self.ID = self.create_account()['ID']
-        
-
-    def create_account(self):
-        accountMan = AccountInfo()
-        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-        return acc
-    
-    def view_account(self):
-        accountMan = AccountInfo()
-        return accountMan.get_info(self.ID)
-
-    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            accountMan = AccountInfo()
-            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-
-
-# #acc = Account('Hannah', 'Montana', '05/05/1995', 'Singing, Dancing')
-# #acc.view_account()
-# acc = Account(ID=1)
-# ints = (acc.interests.to_string(index=False)).replace("\"", "")
-# ints += ", Ballet"
-# # print(ints)
-# wishes = (acc.wishlist.to_string(index=False))
-# acc.update_account(acc.name.to_string(index=False), acc.surname.to_string(index=False), acc.birthday.to_string(index=False), ints, acc.wishlist.to_string(index=False), acc.friendlist.to_string(index=False))
-
-        
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class Account -(name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID=None) -
-
-
-
- -Expand source code - -
class Account():
-    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
-        if ID != None:
-            accountMan = AccountInfo()
-            info = accountMan.get_info(ID)
-            self.name = info['Name']
-            self.surname = info['Surname']
-            self.birthday = info['Birthday']
-            self.interests = info['Interests']
-            self.wishlist = info['WishList']
-            self.friendlist = info['FriendList']
-            self.ID = ID
-        else: 
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            self.ID = self.create_account()['ID']
-        
-
-    def create_account(self):
-        accountMan = AccountInfo()
-        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-        return acc
-    
-    def view_account(self):
-        accountMan = AccountInfo()
-        return accountMan.get_info(self.ID)
-
-    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            accountMan = AccountInfo()
-            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-

Methods

-
-
-def create_account(self) -
-
-
-
- -Expand source code - -
def create_account(self):
-    accountMan = AccountInfo()
-    acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-    return acc
-
-
-
-def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        self.name = name
-        self.surname = surname
-        self.birthday = birthday
-        self.interests = interests
-        self.wishlist = wishlist
-        self.friendlist = friendlist
-        accountMan = AccountInfo()
-        accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-
-
-def view_account(self) -
-
-
-
- -Expand source code - -
def view_account(self):
-    accountMan = AccountInfo()
-    return accountMan.get_info(self.ID)
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file diff --git a/src/assets/images/gift-flat.ico b/src/assets/images/gift-flat.ico new file mode 100644 index 0000000000000000000000000000000000000000..0eff60fe2023b6997c4653e2e0e2f54a4165126c GIT binary patch literal 169884 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/gift-flat.png b/src/assets/images/gift-flat.png new file mode 100644 index 0000000000000000000000000000000000000000..f029f02921950400ead649e0cef165246e96edc9 GIT binary patch literal 24448 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/profile.png b/src/assets/images/profile.png new file mode 100644 index 0000000000000000000000000000000000000000..c84a0c7826506e85abed089fdfab0253091bbd53 GIT binary patch literal 30310 zcmeFZbx@V>_b&YGO@nkJASK-b0umdLl z2S1;0&3k6v`OTa&=bx`LID6mEo$FrfT5DbFnf*dtRUQ|c3L5|bTt$V)ngD=e4E}{< zqJu4s&v_#OfU3k_Ti;XD!iNs-?rQ7cY(wYi2e+ZK@pZ5T0N>f-EQ2&^5qH^}dTcJp z1M~j(zVY73wQY&V$tF1!txUE_NiQjv@uv6D!&;9dZ=THuAC!JIHQ}z-tDHPyF=`S% zFS#7fKe)z~=nP)We;s&nv57C~BOZLkaLD-V?3d)?_PSu;<*zA>j`qm+K5Mn)hGv}^ zlGojb>w>5G+$54biX3BSm)p{(UIiqQotS3i6!}koIksPU;T#2;c1qk}p#fV|%Z?b+Osbo6r6J#EFyEV$)&A>a!H1jj!|dZ?^6RKO?InMRksVueY3?lhUgZ=JOVx4i6t)ZRI zO$`U9PCZ7CDXb#ngFcc>&$#~^2W#w!=Sp0}l$umzQztj8Jl^ruBX7R^C1}oL_n+Dh9wV!sT%q&&ZI@Qpxz%tPw%owJ z^3vR(pRrHM=fAsjtbLtx>GbY7tBR;?y85+!&zdXHhO0w)Gj1o~>$!u|A~zu_i>wHv z#poLBbG9Z-N`7tNEYU;zN9qIDq#D*FS+X@}44c?HKZq^gE*tF{|F+i7ybN9&Z2T>= zuyP~lp;~?!m3b-X+Sxx#hFhIpuSU*ZCNcV~xsmYE&3m2Bj(283^{3ob*ktANp^eq& zbuRBJgMoXb<3zu=yuICE zz%E(>(G%xKB%4HLwvVzyg*`7bW8SepO>Wx`ct>_P?IQ=JoFk%05n#|8wy)t1emlQm zH{ev>l-<}>fp&@$m}6hvW0Y1bXuI(Ar^@|2Ei&2eZh0Gr_w%IdbTM!9XMG0e6}&bY zN%}E1-bHLT5xFO|ogYqeG}SUF{4)&9Nbgp9`r=3NDxY|&qp3#tu*^ywF!8`9?~_eD>RbC(->pDQs`Z)EZa7T_ML*zq7#Fe&%`rvikrweY2RCOfW*?j1m1c{_|3;a^%&0*}X=pE2RYGr5CSRxV~z{#`vT=)b%{RcpCAl zp*t#(eugvV!hG^66UFoIwY1s~Um&}B&b#DzFqdal`b6$#&se9P_Riv;VC49sC%{6cx=fo5$1cHmJ@4cu2(U$Ga0e++)cMU?J{?v z+2AoCH;K;(9TM^33Q#9xVboPJc$H=Qc4Tg)W1q8H4r{W72T8M3jTcG(L`Yn$h?oNN zw_f4vWs6a68VTeIZstdw_38}%&SsaUzFr(r*}Sd{RvuY0w|bh$J73#u#yGzlj8V35 zg;~s0Re0(VPF?JyBfgP}EUTTnzNjCb=a`|)cjbBn#)V#%`s$Z|!?RFw?#O@bvC^(B z(T@I@G-6RlIGSd70k1#*dW5rAowxmG*u->s84Zl3oJB2_OYRlHl*PKSbTI?r!OmT1 z5@Gbo=qAisLp;pA%pzXVQ6p7JUavC5gfH1pDPF9QO0lf6p$Wg7vzR6h=C>y6Ahsnd z#!>Y~3XiUZZs>`c_j!(cmqy|$(WPgcs$y9?%82@rxww6j{X=uKPwd4?57RFVEW?sh zrC+yh7T?)CO~N_wa$j|>p1w!I@eD|hm$5lf!jJ}Kktqm$^sHX`)K91@@^Sc=M|51Y zk3DI06)X^)Cz>+O1bmeGlBy7BvDF6yDj4RM5_xw2qIkUGuI`>4G`!VT6^|DNK*EC! z@{E+AU7LI zc~9RKYSF^q7XwMJChm+IxjwLZ;EkSHaG&H?1nx;h87orpWi&K~umEM%T@$apWo48V z@+nTKl(2lP<{fUCpXIk_rio`|Y2BeI-A-=U&nk~MhW99b1fezB#xV2fU2oF%ay1!4 zf_HV9jSE-C#@G@AqE*Q9nzj{^9@9IMN*Q@NxlD_ymzkHcrVPpAwkxZ_j_A#khz`Gu z$RQu;cdS}(Ds(nN~}FOhl)+vtgw5%(do&?u=pK6^kjx zJ36z5^mh&us!k}*W4X-}`?ILOWJy&x!-UC>4 zC1hSPUC{@AL{wxYvaW}2rv;>VXX1$xSUm6Q=}b{Ft1Sia429+g(c4Izx@s``4V;tM zgeN$fURfxX47J@a)nKs}pstMl5e?g$g7HkfNfiu(bo`NGQ7)UIWsV zz-!4KXNZ@pk9;si)#zS1*FHJk&2u614zE2&ERFV5V zR3noQPlNOlFJs#yXiGC6owx4)dT@s-L%$EGIv$1Z`p81z1Q^*Xv+Yk1LonLICu%cB zUhH>?TGZ_C3{nYsrpE1J)FDKxc2tS1>H XG1N{GPd!>x%FTN1qTai&->~hNzLCA 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 Jh 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%0D^=DOD? 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 G*8U&p-=K#8 literal 0 HcmV?d00001 diff --git a/src/assets/styles.css b/src/assets/styles.css new file mode 100644 index 0000000..bc517ee --- /dev/null +++ b/src/assets/styles.css @@ -0,0 +1,284 @@ +.navbar{ + font-family: 'Trebuchet MS', sans-serif; + position: fixed; + width: 100%; + background: #C00000; + z-index: 99999999999999999999; + left: 0rem; + top: 0rem; + height: 55px; + padding-left: 4rem; +} + + +.navitem{ + float: left; + display: block; + color: #f2f2f2 !important; + text-align: center; + padding: 17px 20px; + text-decoration: none !important; + border-bottom: 2px solid transparent; + font-size: 14px; + font-family: 'Trebuchet MS', sans-serif; +} + +.navitem:hover{ + background-color: rgba(221, 221, 221, 0.233); + height: 55px !important; + +} + + +.settings{ + height:1rem; +} + +.version-span{ + color: white; + position: absolute; + right: 1rem; + bottom: 1.75rem; + opacity: 0.5; + z-index: 9999; + border: 2px solid #333; + border-radius: 25px; + padding-right: 0.5rem; + padding-left: 0.5rem; + background: #333; +} + +.dropbtn { + background-color: transparent; + color: white; + padding: 10px; + font-size: 16px; + height: 55px; + opacity: 0.5; + filter: invert(1); + cursor: pointer; + transition: 0.3s; + display: inline-block; + margin: 0; +} + +.dropbtn:hover, .dropbtn:focus, .dropdown:hover .dropbtn { + opacity:1; +} + +.dropdown { + position: fixed; + display: block; + right: 0rem; + top: 0rem; + padding-left: 0.7rem; + user-select: none; + padding-right: 10px; +} + +.dropdown-content { + visibility: hidden; + position: fixed; + border-radius: 9px; + background-color: #C00000; + min-width: 160px; + overflow: auto; + right:0.3rem; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; +} + +.dropdown-content a { + color: white; + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.dropdown:hover{ + background-color: rgba(221, 221, 221, 0.233); + background: rgba(221, 221, 221, 0.233); +} + +.dropdown a:hover {background-color: rgba(221, 221, 221, 0.233);} + +iframe{ + height: 0rem; +} + +.stTabs { + display: none; +} + +.navName { + display: inline-block; + color: #f2f2f2 !important; + text-align: center; + text-decoration: none !important; + border-bottom: 2px solid transparent; + font-size: 14px; + font-family: 'Trebuchet MS', sans-serif; + position: static; + right: 4rem; + margin: 0; + +} + +.hide { + display: none !important; +} + +.footer{ + font-family: 'Trebuchet MS', sans-serif; + position: relative; + width: 100%; + background: #ededed; + z-index: 99999999999999999999; + left: 0rem; + bottom: 0rem; + height: 70px; + /* padding-left: 4rem; */ + +} + +.footerlist { + position: absolute; + width: 100%; + text-align: center; + background-color: #ededed; +} + +.footeritem{ + /* float: left; */ + /* display: block; */ + display: inline-block; + color: #000 !important; + text-align: center; + margin: 17px 20px; + text-decoration: none !important; + border-bottom: 2px solid transparent; + font-size: 14px; + font-family: 'Trebuchet MS', sans-serif; + filter: invert(.2); +} + +.footeritem:hover{ + filter: invert(.4); +} + +footer:last-child { + display: none; +} + +.gitHub { + display: inline-block; + width: 30px; + margin-top: -4px; + filter: invert(.2); + +} + +.block-container { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +[data-testid="stHeader"] { + display: none; +} + +[data-testid="stVerticalBlock"] > :nth-child(7) iframe { + height: unset; +} + +blockquote { + color: rgb(49, 51, 63); + font-family: "Source Sans Pro", sans-serif; + font-weight: bold; + font-size: 1.5rem; + margin: 0; + border: none; +} + +blockquote footer { + display: block !important; + text-align: right; + margin-top: 1rem; +} + +blockquote footer:before { + content: "-"; +} + +.buttonDiv { + margin: 20px 0; +} + +.block-container > div > [data-testid="stVerticalBlock"] { + display: block; +} + +.block-container { + margin-top: 55px; +} + +.show { + display: block !important; + background: pink !important; +} + +button[kind="primary"], button[kind="primaryFormSubmit"]{ + background-color: #C00000 !important; + color: white; +} + +button[kind="primary"]:hover, button[kind="primaryFormSubmit"]:hover{ + background-color: #c00000a3 !important; + color: white; +} + +button[kind="primary"]:active, button[kind="primaryFormSubmit"]:active { + background-color: #c00000a3 !important; + color: white; +} + +.horizontalDiv { + width: unset !important; + display: inline-block; +} + +.initial h2 { + text-align: center; + margin-bottom: 50px; + font-size: 3rem; +} + +.initial .buttonDiv { + text-align: center; +} + +.createaccount [data-testid="stVerticalBlock"] { + display: block; +} + +.createaccount [data-testid="stVerticalBlock"] > div { + margin: 10px 0; +} + +.createaccount [data-testid="stVerticalBlock"] > .horizontalDiv:last-child { + float: right; +} + +.createaccount button[kind="Secondary"] { + margin-right: 10px; +} + +.account .stMarkdown [data-testid="stMarkdownContainer"] > p { + margin-bottom: 3rem; + font-size: 20px; + margin-top: 1rem; +} + +.wishlist [data-testid="stVerticalBlock"] { + display: block; +} \ No newline at end of file diff --git a/src/item.html b/src/item.html deleted file mode 100644 index 5c0fdf5..0000000 --- a/src/item.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - -item API documentation - - - - - - - - - - - -
-
-
-

Module item

-
-
-
- -Expand source code - -
from item_manager import ItemManager
-class item():
-    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
-        if ID != None:
-            itemMan = ItemManager()
-            info = itemMan.get_item(ID)
-            self.title = info['Title']
-            self.desc = info['Description']
-            self.link = info['Link']
-            self.cost = info['Cost']
-            self.itemID = ID
-        else:
-            self.title = title
-            self.desc = desc
-            self.link = link
-            self.cost = cost
-            self.itemID = int(self.create_item()['ItemID'])
-
-    
-    def create_item(self):
-        itemMan = ItemManager()
-        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-        return item
-
-    def modify_item(self, title, desc, link, cost):
-        itemMan = ItemManager()
-        self.title = title
-        self.desc = desc
-        self.link = link
-        self.cost = cost
-        itemMan.update_item( self.itemID, title, desc, link, cost)
-    
-    def view_item(self):
-        itemMan = ItemManager()
-        return itemMan.get_item(self.itemID)
-
-    def delete_item(self):
-        itemMan = ItemManager()
-        itemMan.delete_item(self.itemID)
-
-
-
-# i = item('Football', 'NFL original', 'www.football.com', 50)
-# print(i.cost)
-# i.modify_item('Football', 'NFL original', 'www.football.com', 65)
-# print(i.view_item())
-# i.delete_item()
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class item -(title='', desc='', link='', cost='', ID=None) -
-
-
-
- -Expand source code - -
class item():
-    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
-        if ID != None:
-            itemMan = ItemManager()
-            info = itemMan.get_item(ID)
-            self.title = info['Title']
-            self.desc = info['Description']
-            self.link = info['Link']
-            self.cost = info['Cost']
-            self.itemID = ID
-        else:
-            self.title = title
-            self.desc = desc
-            self.link = link
-            self.cost = cost
-            self.itemID = int(self.create_item()['ItemID'])
-
-    
-    def create_item(self):
-        itemMan = ItemManager()
-        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-        return item
-
-    def modify_item(self, title, desc, link, cost):
-        itemMan = ItemManager()
-        self.title = title
-        self.desc = desc
-        self.link = link
-        self.cost = cost
-        itemMan.update_item( self.itemID, title, desc, link, cost)
-    
-    def view_item(self):
-        itemMan = ItemManager()
-        return itemMan.get_item(self.itemID)
-
-    def delete_item(self):
-        itemMan = ItemManager()
-        itemMan.delete_item(self.itemID)
-
-

Methods

-
-
-def create_item(self) -
-
-
-
- -Expand source code - -
def create_item(self):
-    itemMan = ItemManager()
-    item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-    return item
-
-
-
-def delete_item(self) -
-
-
-
- -Expand source code - -
def delete_item(self):
-    itemMan = ItemManager()
-    itemMan.delete_item(self.itemID)
-
-
-
-def modify_item(self, title, desc, link, cost) -
-
-
-
- -Expand source code - -
def modify_item(self, title, desc, link, cost):
-    itemMan = ItemManager()
-    self.title = title
-    self.desc = desc
-    self.link = link
-    self.cost = cost
-    itemMan.update_item( self.itemID, title, desc, link, cost)
-
-
-
-def view_item(self) -
-
-
-
- -Expand source code - -
def view_item(self):
-    itemMan = ItemManager()
-    return itemMan.get_item(self.itemID)
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file diff --git a/src/item_manager.html b/src/item_manager.html deleted file mode 100644 index 0f45af0..0000000 --- a/src/item_manager.html +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - -item_manager API documentation - - - - - - - - - - - -
-
-
-

Module item_manager

-
-
-
- -Expand source code - -
from pandas import *
-class ItemManager:
-    def __init__ (self):
-        try:
-            self.database = 'data/item_data - Copy.csv'
-            data = read_csv(self.database)
-        except: 
-            self.database = '../data/item_data - Copy.csv'
-
-    def add_item(self, title, desc = '', link = '',  cost = ''):
-        if title == '':
-            print('Title cannot be empty')
-            return -1
-        data = read_csv(self.database)
-        lastElement = data['ItemID'].tolist()[-1]+1
-        new_data = {'ItemID': lastElement, 'Title': title, 'Description': desc,'Link': link, 'Cost': [cost]}
-        df = DataFrame(new_data)
-        df.to_csv(self.database, mode='a', index=False, header=False)
-        print("Data appended successfully.")
-        return df
-
-
-    def get_item(self, ID: int):
-        data = read_csv(self.database)
-        if data.loc[data['ItemID']==ID].empty:
-            print("Item does not exist")
-            return -1
-        return (data.loc[data['ItemID'] == ID])
-
-    def delete_item(self, ID: int):
-        data = read_csv(self.database)
-        if data.index[data['ItemID'] == ID].empty:
-            print("Item does not exist")
-            return -1
-        data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-        data.to_csv(self.database, mode='w', index=False)
-        print("Item deleted.")
-        return 0
-
-    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-        data = read_csv(self.database)
-        item = data.loc[data['ItemID'] == ID]
-        ind = data['ItemID'] == ID
-        if data.loc[data['ItemID'] == ID].empty:
-            print('Item does not exist.')
-            return -1
-        data.loc[ind,'Title'] = title
-        data.loc[ind,'Description'] = desc
-        data.loc[ind, 'Link'] = link
-        data.loc[ind, 'Cost'] = cost
-        data.to_csv(self.database, mode='w', index=False)
-        print('Updated item')
-        return 0
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class ItemManager -
-
-
-
- -Expand source code - -
class ItemManager:
-    def __init__ (self):
-        try:
-            self.database = 'data/item_data - Copy.csv'
-            data = read_csv(self.database)
-        except: 
-            self.database = '../data/item_data - Copy.csv'
-
-    def add_item(self, title, desc = '', link = '',  cost = ''):
-        if title == '':
-            print('Title cannot be empty')
-            return -1
-        data = read_csv(self.database)
-        lastElement = data['ItemID'].tolist()[-1]+1
-        new_data = {'ItemID': lastElement, 'Title': title, 'Description': desc,'Link': link, 'Cost': [cost]}
-        df = DataFrame(new_data)
-        df.to_csv(self.database, mode='a', index=False, header=False)
-        print("Data appended successfully.")
-        return df
-
-
-    def get_item(self, ID: int):
-        data = read_csv(self.database)
-        if data.loc[data['ItemID']==ID].empty:
-            print("Item does not exist")
-            return -1
-        return (data.loc[data['ItemID'] == ID])
-
-    def delete_item(self, ID: int):
-        data = read_csv(self.database)
-        if data.index[data['ItemID'] == ID].empty:
-            print("Item does not exist")
-            return -1
-        data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-        data.to_csv(self.database, mode='w', index=False)
-        print("Item deleted.")
-        return 0
-
-    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-        data = read_csv(self.database)
-        item = data.loc[data['ItemID'] == ID]
-        ind = data['ItemID'] == ID
-        if data.loc[data['ItemID'] == ID].empty:
-            print('Item does not exist.')
-            return -1
-        data.loc[ind,'Title'] = title
-        data.loc[ind,'Description'] = desc
-        data.loc[ind, 'Link'] = link
-        data.loc[ind, 'Cost'] = cost
-        data.to_csv(self.database, mode='w', index=False)
-        print('Updated item')
-        return 0
-
-

Methods

-
-
-def add_item(self, title, desc='', link='', cost='') -
-
-
-
- -Expand source code - -
def add_item(self, title, desc = '', link = '',  cost = ''):
-    if title == '':
-        print('Title cannot be empty')
-        return -1
-    data = read_csv(self.database)
-    lastElement = data['ItemID'].tolist()[-1]+1
-    new_data = {'ItemID': lastElement, 'Title': title, 'Description': desc,'Link': link, 'Cost': [cost]}
-    df = DataFrame(new_data)
-    df.to_csv(self.database, mode='a', index=False, header=False)
-    print("Data appended successfully.")
-    return df
-
-
-
-def delete_item(self, ID: int) -
-
-
-
- -Expand source code - -
def delete_item(self, ID: int):
-    data = read_csv(self.database)
-    if data.index[data['ItemID'] == ID].empty:
-        print("Item does not exist")
-        return -1
-    data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-    data.to_csv(self.database, mode='w', index=False)
-    print("Item deleted.")
-    return 0
-
-
-
-def get_item(self, ID: int) -
-
-
-
- -Expand source code - -
def get_item(self, ID: int):
-    data = read_csv(self.database)
-    if data.loc[data['ItemID']==ID].empty:
-        print("Item does not exist")
-        return -1
-    return (data.loc[data['ItemID'] == ID])
-
-
-
-def update_item(self, ID: int, title, desc='', link='', cost='') -
-
-
-
- -Expand source code - -
def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-    data = read_csv(self.database)
-    item = data.loc[data['ItemID'] == ID]
-    ind = data['ItemID'] == ID
-    if data.loc[data['ItemID'] == ID].empty:
-        print('Item does not exist.')
-        return -1
-    data.loc[ind,'Title'] = title
-    data.loc[ind,'Description'] = desc
-    data.loc[ind, 'Link'] = link
-    data.loc[ind, 'Cost'] = cost
-    data.to_csv(self.database, mode='w', index=False)
-    print('Updated item')
-    return 0
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file diff --git a/src/main.py b/src/main.py index 463ee4b..9858ccd 100644 --- a/src/main.py +++ b/src/main.py @@ -6,23 +6,30 @@ from account import Account from account_info import AccountInfo from item import item +import streamlit.components.v1 as components +import utils as utl +import requests +from streamlit.components.v1 import html +extrajs = '''''' def initial_page(): st.header("Gift Finder!") - create = st.button('Create Account') - login = st.button('Log In') + create = st.button('Create Account', type="primary") + login = st.button('Log In', type="primary") if create: st.session_state.runpage = 'createaccount' st.experimental_rerun() if login: st.session_state.runpage = 'login' st.experimental_rerun() + def login_page(): + st.header("Login") form1 = st.form(key='Login form') userID = form1.text_input('UserID: ') - but = form1.form_submit_button('Log in') + but = form1.form_submit_button('Log in', type="primary") if but: acc = Account(ID=int(userID)) st.session_state.runpage = 'account' @@ -30,37 +37,54 @@ def login_page(): st.experimental_rerun() def create_account(): - st.write('Please fill out the form') + # st.write('Please fill out the form') form = st.form(key='Create_form') name = form.text_input('Name:') surname = form.text_input('Surname:') birthday = form.text_input('Birthday (MM/DD/YYYY):') interest = form.text_input('Interests (please enter them comma seperated):') - but1 = form.form_submit_button('Submit') + but1 = form.form_submit_button('Submit', type="primary") + but2 = form.form_submit_button("Back") if but1: acc = Account(name, surname, birthday, interest) acc = Account(ID = int(acc.ID)) st.session_state.runpage = 'account' st.session_state.account = acc st.experimental_rerun() - #return account + if but2: + st.session_state.runpage = 'initial' + st.experimental_rerun() + global extrajs + extrajs += ''' + forms = window.parent.document.querySelectorAll('[data-testid="stFormSubmitButton"]'); + for (const element of forms) { + element.classList.add("horizontalDiv"); + element.parentElement.classList.add("horizontalDiv"); + element.parentElement.parentElement.classList.add("horizontalDiv"); + } + ''' def account_page(): acc = st.session_state.account st.header('Welcome ' + acc.name.to_string(index=False) + '!') - st.write("What a beautiful day to gift!") - if st.button('Profile'): - st.session_state.runpage = 'profile' - st.experimental_rerun() - if st.button('Wishlist'): - st.session_state.runpage = 'wishlist' - st.experimental_rerun() - if st.button('Friendlist'): - st.session_state.runpage = 'friendlist' - st.experimental_rerun() - if st.button('Logout'): - st.session_state.runpage = 'initial' - st.experimental_rerun() + st.write("Quote of the day:") + if 'response' not in st.session_state: + st.session_state.response = requests.get('https://zenquotes.io/api/today') + st.markdown(st.session_state.response.json()[0]["h"].replace('—', ''), unsafe_allow_html=True) + + + # if st.button('Profile'): + # st.session_state.runpage = 'profile' + # st.experimental_rerun() + # if st.button('Wishlist'): + # st.session_state.runpage = 'wishlist' + # st.experimental_rerun() + # if st.button('Friendlist'): + # st.session_state.runpage = 'friendlist' + # st.experimental_rerun() + # if st.button('Logout'): + # st.session_state.runpage = 'initial' + # st.experimental_rerun() def profile_page(): @@ -71,7 +95,7 @@ def profile_page(): st.write('Surname: ' + acc.surname.to_string(index=False)) st.write('Birthday: ' + acc.birthday.to_string(index=False)) st.write('Interests: ' + (acc.interests.to_string(index=False)).replace("\"", "")) - if st.button("Edit Profile"): + if st.button("Edit Profile", type="primary"): st.session_state.runpage = 'editprofile' st.experimental_rerun() if st.button("Back"): @@ -87,7 +111,7 @@ def editprofile_page(): birthday = form.text_input('Birthday:', value= acc.birthday.to_string(index=False), placeholder= acc.birthday.to_string(index=False)) ints = (acc.interests.to_string(index=False)).replace("\"", "") interests = form.text_input('Interest:', value=ints, placeholder=ints) - if form.form_submit_button('Update'): + if form.form_submit_button('Update', type="primary"): acc.update_account(name, surname, birthday, interests, acc.wishlist.to_string(index=False), acc.friendlist.to_string(index=False)) acc = Account(ID = int(acc.ID)) st.session_state.account = acc @@ -116,18 +140,30 @@ def wishlist_page(): df.set_index('ID', inplace=True) st.table(df) - if st.button('Add item'): + if st.button('Add item', type="primary"): st.session_state.runpage = 'additem' st.experimental_rerun() - if st.button('Modify item'): + if st.button('Modify item', type="primary"): st.session_state.runpage = 'modifyitem' st.experimental_rerun() - if st.button('Remove item'): + if st.button('Remove item', type="primary"): st.session_state.runpage = 'deleteitem' st.experimental_rerun() if st.button('Back'): st.session_state.runpage = 'account' - st.experimental_rerun() + st.experimental_rerun() + global extrajs + extrajs += ''' + document.addEventListener('DOMContentLoaded', function(event) { + //the event occurred + forms = window.parent.document.querySelectorAll('.stButton'); + for (const element of forms) { + element.classList.add("horizontalDiv"); + element.parentElement.classList.add("horizontalDiv"); + } + + }) + ''' def additem_page(): form = st.form(key='AddItemForm') @@ -135,7 +171,7 @@ def additem_page(): desc = form.text_input('Description') link = form.text_input('Link') cost = form.text_input('Cost') - if form.form_submit_button('Add item'): + if form.form_submit_button('Add item', type="primary"): i = item(title, desc, link, cost) acc = st.session_state.account a_name = acc.name.to_string(index=False) @@ -169,7 +205,7 @@ def modifyitem_page(): desc = form.text_input('Description', value= i.desc.to_string(index=False), placeholder= i.desc.to_string(index=False)) link = form.text_input('Link', value= i.link.to_string(index=False), placeholder= i.link.to_string(index=False)) cost = form.text_input('Cost', value= i.cost.to_string(index=False), placeholder= i.cost.to_string(index=False)) - if form.form_submit_button('Modify item'): + if form.form_submit_button('Modify item', type="primary"): i.modify_item(title, desc, link, cost) st.session_state.runpage = 'wishlist' st.experimental_rerun() @@ -184,7 +220,7 @@ def deleteitem_page(): form = st.form(key='DeleteItemForm') id =form.text_input('Please enter ID of the item you want to delete', value=items[0]) i = item(ID=int(id)) - if form.form_submit_button('Delete item'): + if form.form_submit_button('Delete item', type="primary"): acc = st.session_state.account a_name = acc.name.to_string(index=False) a_surname = acc.surname.to_string(index=False) @@ -218,13 +254,13 @@ def friendlist_page(): df = pd.DataFrame(list(zip(friendlist,friendName,friendSur)), columns=('ID', 'Name', 'Surname')) df.set_index('ID', inplace=True) st.table(df) - if st.button('View Wishlist of friend'): + if st.button('View Wishlist of friend', type="primary"): st.session_state.runpage = 'friendwishlist' st.experimental_rerun() - if st.button('Add friend'): + if st.button('Add friend', type="primary"): st.session_state.runpage = 'addfriend' st.experimental_rerun() - if st.button('Delete friend'): + if st.button('Delete friend', type="primary"): st.session_state.runpage = 'deletefriend' st.experimental_rerun() if st.button('Back'): @@ -239,7 +275,7 @@ def viewwishlist_page(): form = st.form(key='Viewwishlistform') id =form.text_input('Please enter ID of the friend', value=friendlist[0]) friend = Account(ID=int(id)) - if form.form_submit_button('See wishlist'): + if form.form_submit_button('See wishlist', type="primary"): items = (friend.wishlist.to_string(index=False)).replace("\"", "").split(",") items = [int(item) for item in items] item_objs = [item(ID=id) for id in items] @@ -260,7 +296,7 @@ def addfriend_page(): friendlist = acc.friendlist.to_string(index=False) form = st.form(key='addfriend') id =form.text_input('Please enter ID of the friend') - if form.form_submit_button('Add friend'): + if form.form_submit_button('Add friend', type="primary"): if friendlist != 'NaN': friendlist += ',' + str(id) else: @@ -287,7 +323,7 @@ def deletefriend_page(): form = st.form(key='DeleteItemForm') id =form.text_input('Please enter ID of the friend want to delete', value=friends[0]) - if form.form_submit_button('Delete friend'): + if form.form_submit_button('Delete friend', type="primary"): a_name = acc.name.to_string(index=False) a_surname = acc.surname.to_string(index=False) a_birthday = acc.birthday.to_string(index=False) @@ -307,15 +343,57 @@ def deletefriend_page(): st.session_state.runpage = 'friendlist' st.experimental_rerun() +if 'account' not in st.session_state or st.session_state.runpage == 'initial': + st.session_state.account = 'None' +if 'runpage' not in st.session_state or (st.session_state.account == 'None' and not st.session_state.runpage == 'login' and not st.session_state.runpage == 'createaccount'): + st.session_state.runpage = 'initial' +# st.set_page_config(layout="wide", page_title='Navbar sample') +st.set_page_config(page_title='Gifter 2', page_icon='assets/images/gift-flat.ico') +st.set_option('deprecation.showPyplotGlobalUse', False) +utl.inject_custom_css() +utl.navbar_component(st.session_state.account) -if 'runpage' not in st.session_state: - st.session_state.runpage = 'initial' +navtab, tab2= st.tabs(["Navtab", "test"]) -if 'account' not in st.session_state: - st.session_state.account = 'None' +with navtab: + if st.button('home'): + st.session_state.runpage = 'account' + st.experimental_rerun() + if st.button('wishlist'): + st.session_state.runpage = 'wishlist' + st.experimental_rerun() + if st.button('friendlist'): + st.session_state.runpage = 'friendlist' + st.experimental_rerun() + if st.button('acount'): + st.session_state.runpage = 'profile' + st.experimental_rerun() + if st.button('logout'): + st.session_state.runpage = 'initial' + del st.session_state["account"] + st.experimental_rerun() +with tab2: + st.header("Placeholder") + + + +extrajs = ''' + buttonDivs = window.parent.document.querySelectorAll('[data-testid="stVerticalBlock"] > [data-stale="false"] > .stButton'); + console.log(buttonDivs) + while (!buttonDiv) { + buttonDivs = window.parent.document.querySelectorAll('[data-testid="stVerticalBlock"] > [data-stale="false"] > .stButton'); + console.log(buttonDivs) + } + console.log("Test") + for (const element of buttonDivs) { + element.parentElement.classList.add("show"); + } + ''' + +# navigation() if st.session_state.runpage == 'initial': initial_page() @@ -344,4 +422,20 @@ def deletefriend_page(): elif st.session_state.runpage == 'addfriend': addfriend_page() elif st.session_state.runpage == 'deletefriend': - deletefriend_page() \ No newline at end of file + deletefriend_page() + +extrajs += ''' + +''' +js = ''' + + ''' + html(js) + + +def footer_component(): + with open("assets/images/github-logo.png", "rb") as image_file: + image_as_base64 = base64.b64encode(image_file.read()) + + footer_items = '' + for key, value in FOOTER_PATHS.items(): + footer_items += (f'{key}') +# + component = rf''' + + ''' + st.markdown(component, unsafe_allow_html=True) + js = ''' + + ''' + html(js) \ No newline at end of file diff --git a/src/wishlist.html b/src/wishlist.html deleted file mode 100644 index ce1fd54..0000000 --- a/src/wishlist.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - -wishlist API documentation - - - - - - - - - - - -
-
-
-

Module wishlist

-
-
-
- -Expand source code - -
import pandas as pd
-import sys
-
-class wishlist():
-    def __init__(self, items):
-        self.items = items
-        #print(df['Title'])
-
-    def add_item(self, item):
-        self.items.append(item)
-    
-    def delete_item(self, itemID):
-        for i, item in enumerate(self.items):
-            pass 
-
-    def option(self):
-        print("============================================================")
-        print ("Enter index number to do follwing function")
-        print ("0 to View all item; 1 to view specific item; 2 to create item; 3 to delete item; 4 to EXIT CONSOLE")
-        input_decision = int(input())
-
-        if input_decision == 0:
-            self.view_all_items()
-            self.option()
-
-        elif input_decision == 1:
-            self.view_item()
-
-        elif input_decision == 2:
-            self.create_item()
-            print("ITEM HAS BEEN CREATED")
-            self.view_all_items()
-
-        elif input_decision == 3:
-            print("DELETING ITEM")
-            self.delete_item()
-            print("ITEM HAS BEEN DELETED")
-            self.view_all_items()
-
-        elif input_decision == 4:
-            sys.exit()
-
-        else:
-            print("INVALID INPUT")
-            self.option()
-
-    def view_all_items(self):
-        print("============================================================")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print(df['Title'])
-        self.option()
-
-    def view_item(self):
-
-        print("============================================================")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print("Enter index number of item you want to view")
-        input_choice = int(input())
-        if input_choice < len(df):
-            print("Item:  "+ str(df['ItemID'][input_choice]))
-            print("Title:  " + str(df['Title'][input_choice]))
-            print("Description:  " + str(df['Description'][input_choice]))
-            print("Link:  " + str(df['Link'][input_choice]))
-            print("Cost:  " + str(df['Cost'][input_choice]))
-            self.option()
-        else:
-            print ("=====================================")
-            print("INVALID INPUT")
-            self.view_item()
-
-    def create_item(self):
-        print("======================================================")
-        print("INSIDE CREATE ITEM")
-        df = pd.read_csv(r'./data/item_data.csv')
-        new_item = []
-        for i in df.columns:
-            print ("ENTER NEW "+ str(i) + " BELOW:")
-            input_element = input()
-            new_item.append(input_element)
-        df.loc[len(df.index)] = new_item
-        df.to_csv(r'./data/item_data.csv', index=False)
-
-    def delete_item(self):
-        print("======================================================")
-        print("INSIDE DELETE ITEM")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print("ENTER INDEX OF ITEM YOU WANT TO DELETE: ")
-        input_choice = int(input())
-        print (len(df.index))
-        if input_choice < len(df.index):
-            df = df.drop(labels=[input_choice], axis=0, inplace=False)
-            df.to_csv(r'./data/item_data.csv', index=False)
-        else:
-            print("INVALID INPUT")
-            self.option()
-#obj = wishlist()
-#obj.option()
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class wishlist -(items) -
-
-
-
- -Expand source code - -
class wishlist():
-    def __init__(self, items):
-        self.items = items
-        #print(df['Title'])
-
-    def add_item(self, item):
-        self.items.append(item)
-    
-    def delete_item(self, itemID):
-        for i, item in enumerate(self.items):
-            pass 
-
-    def option(self):
-        print("============================================================")
-        print ("Enter index number to do follwing function")
-        print ("0 to View all item; 1 to view specific item; 2 to create item; 3 to delete item; 4 to EXIT CONSOLE")
-        input_decision = int(input())
-
-        if input_decision == 0:
-            self.view_all_items()
-            self.option()
-
-        elif input_decision == 1:
-            self.view_item()
-
-        elif input_decision == 2:
-            self.create_item()
-            print("ITEM HAS BEEN CREATED")
-            self.view_all_items()
-
-        elif input_decision == 3:
-            print("DELETING ITEM")
-            self.delete_item()
-            print("ITEM HAS BEEN DELETED")
-            self.view_all_items()
-
-        elif input_decision == 4:
-            sys.exit()
-
-        else:
-            print("INVALID INPUT")
-            self.option()
-
-    def view_all_items(self):
-        print("============================================================")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print(df['Title'])
-        self.option()
-
-    def view_item(self):
-
-        print("============================================================")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print("Enter index number of item you want to view")
-        input_choice = int(input())
-        if input_choice < len(df):
-            print("Item:  "+ str(df['ItemID'][input_choice]))
-            print("Title:  " + str(df['Title'][input_choice]))
-            print("Description:  " + str(df['Description'][input_choice]))
-            print("Link:  " + str(df['Link'][input_choice]))
-            print("Cost:  " + str(df['Cost'][input_choice]))
-            self.option()
-        else:
-            print ("=====================================")
-            print("INVALID INPUT")
-            self.view_item()
-
-    def create_item(self):
-        print("======================================================")
-        print("INSIDE CREATE ITEM")
-        df = pd.read_csv(r'./data/item_data.csv')
-        new_item = []
-        for i in df.columns:
-            print ("ENTER NEW "+ str(i) + " BELOW:")
-            input_element = input()
-            new_item.append(input_element)
-        df.loc[len(df.index)] = new_item
-        df.to_csv(r'./data/item_data.csv', index=False)
-
-    def delete_item(self):
-        print("======================================================")
-        print("INSIDE DELETE ITEM")
-        df = pd.read_csv(r'./data/item_data.csv')
-        print("ENTER INDEX OF ITEM YOU WANT TO DELETE: ")
-        input_choice = int(input())
-        print (len(df.index))
-        if input_choice < len(df.index):
-            df = df.drop(labels=[input_choice], axis=0, inplace=False)
-            df.to_csv(r'./data/item_data.csv', index=False)
-        else:
-            print("INVALID INPUT")
-            self.option()
-
-

Methods

-
-
-def add_item(self, item) -
-
-
-
- -Expand source code - -
def add_item(self, item):
-    self.items.append(item)
-
-
-
-def create_item(self) -
-
-
-
- -Expand source code - -
def create_item(self):
-    print("======================================================")
-    print("INSIDE CREATE ITEM")
-    df = pd.read_csv(r'./data/item_data.csv')
-    new_item = []
-    for i in df.columns:
-        print ("ENTER NEW "+ str(i) + " BELOW:")
-        input_element = input()
-        new_item.append(input_element)
-    df.loc[len(df.index)] = new_item
-    df.to_csv(r'./data/item_data.csv', index=False)
-
-
-
-def delete_item(self) -
-
-
-
- -Expand source code - -
def delete_item(self):
-    print("======================================================")
-    print("INSIDE DELETE ITEM")
-    df = pd.read_csv(r'./data/item_data.csv')
-    print("ENTER INDEX OF ITEM YOU WANT TO DELETE: ")
-    input_choice = int(input())
-    print (len(df.index))
-    if input_choice < len(df.index):
-        df = df.drop(labels=[input_choice], axis=0, inplace=False)
-        df.to_csv(r'./data/item_data.csv', index=False)
-    else:
-        print("INVALID INPUT")
-        self.option()
-
-
-
-def option(self) -
-
-
-
- -Expand source code - -
def option(self):
-    print("============================================================")
-    print ("Enter index number to do follwing function")
-    print ("0 to View all item; 1 to view specific item; 2 to create item; 3 to delete item; 4 to EXIT CONSOLE")
-    input_decision = int(input())
-
-    if input_decision == 0:
-        self.view_all_items()
-        self.option()
-
-    elif input_decision == 1:
-        self.view_item()
-
-    elif input_decision == 2:
-        self.create_item()
-        print("ITEM HAS BEEN CREATED")
-        self.view_all_items()
-
-    elif input_decision == 3:
-        print("DELETING ITEM")
-        self.delete_item()
-        print("ITEM HAS BEEN DELETED")
-        self.view_all_items()
-
-    elif input_decision == 4:
-        sys.exit()
-
-    else:
-        print("INVALID INPUT")
-        self.option()
-
-
-
-def view_all_items(self) -
-
-
-
- -Expand source code - -
def view_all_items(self):
-    print("============================================================")
-    df = pd.read_csv(r'./data/item_data.csv')
-    print(df['Title'])
-    self.option()
-
-
-
-def view_item(self) -
-
-
-
- -Expand source code - -
def view_item(self):
-
-    print("============================================================")
-    df = pd.read_csv(r'./data/item_data.csv')
-    print("Enter index number of item you want to view")
-    input_choice = int(input())
-    if input_choice < len(df):
-        print("Item:  "+ str(df['ItemID'][input_choice]))
-        print("Title:  " + str(df['Title'][input_choice]))
-        print("Description:  " + str(df['Description'][input_choice]))
-        print("Link:  " + str(df['Link'][input_choice]))
-        print("Cost:  " + str(df['Cost'][input_choice]))
-        self.option()
-    else:
-        print ("=====================================")
-        print("INVALID INPUT")
-        self.view_item()
-
-
-
-
-
-
-
- -
- - - \ No newline at end of file From 3f88a87b988ef88c6f1a49404a96222875c45f20 Mon Sep 17 00:00:00 2001 From: Landon Gaddy Date: Sun, 13 Nov 2022 10:52:50 -0500 Subject: [PATCH 3/7] Added new color theme to the front-end --- src/assets/styles.css | 15 ++++++--------- src/main.py | 29 +++++++++++++++-------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/assets/styles.css b/src/assets/styles.css index bc517ee..e29d469 100644 --- a/src/assets/styles.css +++ b/src/assets/styles.css @@ -227,18 +227,18 @@ blockquote footer:before { background: pink !important; } -button[kind="primary"], button[kind="primaryFormSubmit"]{ - background-color: #C00000 !important; +button[kind="primary"], button[kind="formSubmit"]{ + background-color: #C00000; color: white; } -button[kind="primary"]:hover, button[kind="primaryFormSubmit"]:hover{ - background-color: #c00000a3 !important; +button[kind="primary"]:hover, button[kind="formSubmit"]:hover{ + background-color: #c00000a3; color: white; } -button[kind="primary"]:active, button[kind="primaryFormSubmit"]:active { - background-color: #c00000a3 !important; +button[kind="primary"]:active, button[kind="formSubmit"]:active { + background-color: #c00000a3; color: white; } @@ -267,9 +267,6 @@ button[kind="primary"]:active, button[kind="primaryFormSubmit"]:active { .createaccount [data-testid="stVerticalBlock"] > .horizontalDiv:last-child { float: right; -} - -.createaccount button[kind="Secondary"] { margin-right: 10px; } diff --git a/src/main.py b/src/main.py index 9858ccd..c9f1203 100644 --- a/src/main.py +++ b/src/main.py @@ -13,6 +13,17 @@ extrajs = '''''' +def horizontalButtons(): + global extrajs + extrajs += ''' + forms = window.parent.document.querySelectorAll('[data-testid="stFormSubmitButton"]'); + for (const element of forms) { + element.classList.add("horizontalDiv"); + element.parentElement.classList.add("horizontalDiv"); + element.parentElement.parentElement.classList.add("horizontalDiv"); + } + ''' + def initial_page(): st.header("Gift Finder!") create = st.button('Create Account', type="primary") @@ -54,15 +65,8 @@ def create_account(): if but2: st.session_state.runpage = 'initial' st.experimental_rerun() - global extrajs - extrajs += ''' - forms = window.parent.document.querySelectorAll('[data-testid="stFormSubmitButton"]'); - for (const element of forms) { - element.classList.add("horizontalDiv"); - element.parentElement.classList.add("horizontalDiv"); - element.parentElement.parentElement.classList.add("horizontalDiv"); - } - ''' + horizontalButtons() + def account_page(): acc = st.session_state.account @@ -382,14 +386,11 @@ def deletefriend_page(): extrajs = ''' buttonDivs = window.parent.document.querySelectorAll('[data-testid="stVerticalBlock"] > [data-stale="false"] > .stButton'); - console.log(buttonDivs) - while (!buttonDiv) { + while (!buttonDivs) { buttonDivs = window.parent.document.querySelectorAll('[data-testid="stVerticalBlock"] > [data-stale="false"] > .stButton'); - console.log(buttonDivs) } - console.log("Test") for (const element of buttonDivs) { - element.parentElement.classList.add("show"); + element.parentElement.classList.add("but"); } ''' From b0e60b3d231c69392580c0fc4c1951126f115d61 Mon Sep 17 00:00:00 2001 From: Landon Gaddy Date: Mon, 21 Nov 2022 08:44:20 -0500 Subject: [PATCH 4/7] Create .gitignore --- .gitignore | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ From 0b83be3dfb964e9d4a8a7130c9367d012b5f5161 Mon Sep 17 00:00:00 2001 From: Landog893 Date: Mon, 21 Nov 2022 08:48:57 -0500 Subject: [PATCH 5/7] Added HTML changes to wishlist and createAccount --- .gitignore | 128 ----- src/account.html | 233 --------- src/account_info.html | 1042 ----------------------------------------- src/item.html | 240 ---------- src/item_manager.html | 560 ---------------------- src/main.py | 13 - 6 files changed, 2216 deletions(-) delete mode 100644 src/account.html delete mode 100644 src/account_info.html delete mode 100644 src/item.html delete mode 100644 src/item_manager.html diff --git a/.gitignore b/.gitignore index b6e4761..c18dd8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,129 +1 @@ -# Byte-compiled / optimized / DLL files __pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ diff --git a/src/account.html b/src/account.html deleted file mode 100644 index fecade7..0000000 --- a/src/account.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - -account API documentation - - - - - - - - - - - -
-
-
-

Module account

-
-
-
- -Expand source code - -
from account_info import AccountInfo
-
-class Account():
-    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
-        if ID != None:
-            accountMan = AccountInfo()
-            info = accountMan.get_info(ID)
-            if isinstance(info, int):
-                raise ValueError
-            else: 
-                self.name = info['Name']
-                self.surname = info['Surname']
-                self.birthday = info['Birthday']
-                self.interests = info['Interests']
-                self.wishlist = info['WishList']
-                self.friendlist = info['FriendList']
-                self.ID = ID
-        else: 
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            self.ID = self.create_account()['ID']
-        
-
-    def create_account(self):
-        accountMan = AccountInfo()
-        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-        return acc
-    
-    def view_account(self):
-        accountMan = AccountInfo()
-        return accountMan.get_info(self.ID)
-
-    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            accountMan = AccountInfo()
-            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-
-
-# #acc = Account('Hannah', 'Montana', '05/05/1995', 'Singing, Dancing')
-# #acc.view_account()
-# acc = Account(ID=1)
-# ints = (acc.interests.to_string(index=False)).replace("\"", "")
-# ints += ", Ballet"
-# # print(ints)
-# wishes = (acc.wishlist.to_string(index=False))
-# acc.update_account(acc.name.to_string(index=False), acc.surname.to_string(index=False), acc.birthday.to_string(index=False), ints, acc.wishlist.to_string(index=False), acc.friendlist.to_string(index=False))
-
-        
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class Account -(name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID=None) -
-
-
-
- -Expand source code - -
class Account():
-    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
-        if ID != None:
-            accountMan = AccountInfo()
-            info = accountMan.get_info(ID)
-            if isinstance(info, int):
-                raise ValueError
-            else: 
-                self.name = info['Name']
-                self.surname = info['Surname']
-                self.birthday = info['Birthday']
-                self.interests = info['Interests']
-                self.wishlist = info['WishList']
-                self.friendlist = info['FriendList']
-                self.ID = ID
-        else: 
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            self.ID = self.create_account()['ID']
-        
-
-    def create_account(self):
-        accountMan = AccountInfo()
-        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-        return acc
-    
-    def view_account(self):
-        accountMan = AccountInfo()
-        return accountMan.get_info(self.ID)
-
-    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-            self.name = name
-            self.surname = surname
-            self.birthday = birthday
-            self.interests = interests
-            self.wishlist = wishlist
-            self.friendlist = friendlist
-            accountMan = AccountInfo()
-            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-

Methods

-
-
-def create_account(self) -
-
-
-
- -Expand source code - -
def create_account(self):
-    accountMan = AccountInfo()
-    acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
-    return acc
-
-
-
-def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        self.name = name
-        self.surname = surname
-        self.birthday = birthday
-        self.interests = interests
-        self.wishlist = wishlist
-        self.friendlist = friendlist
-        accountMan = AccountInfo()
-        accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
-
-
-
-def view_account(self) -
-
-
-
- -Expand source code - -
def view_account(self):
-    accountMan = AccountInfo()
-    return accountMan.get_info(self.ID)
-
-
-
-
-
-
-
- -
- - - diff --git a/src/account_info.html b/src/account_info.html deleted file mode 100644 index 34ec95a..0000000 --- a/src/account_info.html +++ /dev/null @@ -1,1042 +0,0 @@ - - - - - - -account_info API documentation - - - - - - - - - - - -
-
-
-

Module account_info

-
-
-
- -Expand source code - -
import numpy as np
-import pandas as pd
-import sys
-
-class AccountInfo:
-    def __init__(self):
-        try:
-            self.database = 'data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        except FileNotFoundError:
-            self.database = '../data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        
-    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = sorted(self.data.ID.tolist(), reverse=True)
-        lastID = id_list[0]
-        if name == '':
-            print('Name cannot be empty')
-            return -1
-        else:
-            account_dict = {
-                'ID': lastID+1,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            self.data = self.data.append(account_dict, ignore_index=True)
-            self.data.to_csv(self.database, index=False)
-            print('Account created successfully!')
-        return self.data[self.data['ID']==lastID+1]
-    
-    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('User ID:', ID, 'is not in the database!!!')
-            return -1
-        else:
-            data = self.data[self.data['ID']==ID]
-            # if name=='':
-            #     name = data.Name.values[0]
-            # if surname=='':
-            #     surname = data.Surname.values[0]
-            # if birthday=='':
-            #     birthday = data.Birthday.values[0]
-            # if interests=='':
-            #     interests = data.Interests.values[0]
-            # if wishlist=='':
-            #     wishlist = data.WishList.values[0]
-            #     print(wishlist)
-            # if friendlist=='':
-            #     friendlist = data.FriendList.values[0]
-            account_dict = {
-                'ID': ID,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            index = self.data[self.data['ID']==ID].index[0]
-            #self.data.at[index, 'WishList'] = account_dict
-            self.data.loc[index,'ID'] = ID
-            self.data.loc[index,'Name'] = name
-            self.data.loc[index, 'Surname'] = surname
-            self.data.loc[index, 'Birthday'] = birthday
-            self.data.loc[index, 'Interests'] = interests
-            self.data.loc[index, 'WishList'] = wishlist
-            print(type(wishlist))
-            self.data.loc[index, 'FriendList'] = friendlist
-            self.data.to_csv(self.database, index=False)
-            print('Account updated successfully!')
-        return self.data[self.data['ID']==ID]
-    
-    def get_database(self):
-        return self.data
-    
-    def delete_account(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            matched_data = self.data[self.data['ID']==ID]
-            self.data = self.data.drop(matched_data.index)
-            print('Account deleted successfully!')
-            self.data.to_csv(self.database, index=False)
-        return matched_data
-    
-    def get_info(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            return -1
-        else:
-            return self.data[self.data['ID']==ID]
-        
-    def search_ID(self, ID):
-        if ID == None:
-            print("ID cannot be empty!!!")
-            return [0], -1
-        ID_result = self.data[self.data['ID']==ID]
-        if ID_result.values.size == 0:
-            print("ID not found! Try ID ranges from 0 to 10.")
-            return [0], -1
-        return ID_result, True
-        
-    def get_name(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][1]
-    
-    def get_surname(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][2]
-        
-    def get_birthday(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][3]
-    
-    def get_interests(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][4]
-        
-    def get_wishlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][5]
-        
-    def add_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                print('Item ID:', _item, 'is already in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.append(str(_item))
-                print('Item ID:', _item, 'is added successfully!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-    
-    def delete_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                if len(wl_str):
-                    print('There are no items in the wishlist!!!')
-                    flag = 0
-                else:
-                    wl_str.remove(str(_item))
-                    print('Item ID:', _item, 'is removed successfully!!!')
-            else:
-                print('Item ID:', _item, 'is not found in the wishlist!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-        
-    def get_friendlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == False:
-            return False
-        else:
-            result_dict = result.values
-            return result_dict[0][6]
-
-
-class Friends(AccountInfo):
-    def __init__(self):
-        super().__init__()
-    
-    def get_friend_names(self,ID):
-        friend_names = []
-        friend_ids = self.get_friendlist(ID)
-        for c in friend_ids:
-            try:
-                if int(c):
-                    friend_id = int(c)
-                    fname = self.get_name(friend_id)
-                    sname = self.get_surname(friend_id)
-                    aname = fname + " " + sname 
-                    friend_names.append(aname)
-            except:
-                pass
-            
-        return friend_names
-    
-    def add_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        if str(fl_str)=='nan':
-            fl_str = []
-        else:
-            fl_str = fl_str.replace('"','')
-            fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                print('ID:', _id, 'is Already friend!!!')
-            else:
-                fl_str.append(str(_id))
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-    def delete_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                fl_str.remove(str(_id))
-            else:
-                print('ID:', _id, 'not found in the friend list!!')
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class AccountInfo -
-
-
-
- -Expand source code - -
class AccountInfo:
-    def __init__(self):
-        try:
-            self.database = 'data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        except FileNotFoundError:
-            self.database = '../data/people_data-copy.csv'
-            self.data = pd.read_csv(self.database)
-        
-    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = sorted(self.data.ID.tolist(), reverse=True)
-        lastID = id_list[0]
-        if name == '':
-            print('Name cannot be empty')
-            return -1
-        else:
-            account_dict = {
-                'ID': lastID+1,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            self.data = self.data.append(account_dict, ignore_index=True)
-            self.data.to_csv(self.database, index=False)
-            print('Account created successfully!')
-        return self.data[self.data['ID']==lastID+1]
-    
-    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('User ID:', ID, 'is not in the database!!!')
-            return -1
-        else:
-            data = self.data[self.data['ID']==ID]
-            # if name=='':
-            #     name = data.Name.values[0]
-            # if surname=='':
-            #     surname = data.Surname.values[0]
-            # if birthday=='':
-            #     birthday = data.Birthday.values[0]
-            # if interests=='':
-            #     interests = data.Interests.values[0]
-            # if wishlist=='':
-            #     wishlist = data.WishList.values[0]
-            #     print(wishlist)
-            # if friendlist=='':
-            #     friendlist = data.FriendList.values[0]
-            account_dict = {
-                'ID': ID,
-                'Name': name,
-                'Surname': surname,
-                'Birthday': birthday,
-                'Interests': interests,
-                'WishList': wishlist,
-                'FriendList': friendlist
-            }
-            index = self.data[self.data['ID']==ID].index[0]
-            #self.data.at[index, 'WishList'] = account_dict
-            self.data.loc[index,'ID'] = ID
-            self.data.loc[index,'Name'] = name
-            self.data.loc[index, 'Surname'] = surname
-            self.data.loc[index, 'Birthday'] = birthday
-            self.data.loc[index, 'Interests'] = interests
-            self.data.loc[index, 'WishList'] = wishlist
-            print(type(wishlist))
-            self.data.loc[index, 'FriendList'] = friendlist
-            self.data.to_csv(self.database, index=False)
-            print('Account updated successfully!')
-        return self.data[self.data['ID']==ID]
-    
-    def get_database(self):
-        return self.data
-    
-    def delete_account(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            print('Invalid ID, please enter valid ID.')
-            return -1
-        else:
-            matched_data = self.data[self.data['ID']==ID]
-            self.data = self.data.drop(matched_data.index)
-            print('Account deleted successfully!')
-            self.data.to_csv(self.database, index=False)
-        return matched_data
-    
-    def get_info(self, ID):
-        id_list = self.data.ID.tolist()
-        if ID not in id_list:
-            return -1
-        else:
-            return self.data[self.data['ID']==ID]
-        
-    def search_ID(self, ID):
-        if ID == None:
-            print("ID cannot be empty!!!")
-            return [0], -1
-        ID_result = self.data[self.data['ID']==ID]
-        if ID_result.values.size == 0:
-            print("ID not found! Try ID ranges from 0 to 10.")
-            return [0], -1
-        return ID_result, True
-        
-    def get_name(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][1]
-    
-    def get_surname(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][2]
-        
-    def get_birthday(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][3]
-    
-    def get_interests(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][4]
-        
-    def get_wishlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == -1:
-            return -1
-        else:
-            result_dict = result.values
-            return result_dict[0][5]
-        
-    def add_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                print('Item ID:', _item, 'is already in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.append(str(_item))
-                print('Item ID:', _item, 'is added successfully!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-    
-    def delete_wishlist(self, ID, items):
-        flag = 1
-        wl_str = self.get_wishlist(ID)
-        if str(wl_str)=='nan':
-            wl_str = []
-        else:
-            wl_str = wl_str.replace('"','')
-            wl_str = wl_str.split(', ')
-        for _item in items:
-            if str(_item) in wl_str:
-                if len(wl_str):
-                    print('There are no items in the wishlist!!!')
-                    flag = 0
-                else:
-                    wl_str.remove(str(_item))
-                    print('Item ID:', _item, 'is removed successfully!!!')
-            else:
-                print('Item ID:', _item, 'is not found in the wishlist!!!')
-        wl_str = ', '.join(i for i in wl_str)
-        wl_str = '"' + wl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'WishList'] = wl_str
-        self.data.to_csv(self.database, index=False)
-        return self.data[self.data['ID']==ID]
-        
-    def get_friendlist(self, ID):
-        result, flag = self.search_ID(ID)
-        if flag == False:
-            return False
-        else:
-            result_dict = result.values
-            return result_dict[0][6]
-
-

Subclasses

- -

Methods

-
-
-def add_wishlist(self, ID, items) -
-
-
-
- -Expand source code - -
def add_wishlist(self, ID, items):
-    flag = 1
-    wl_str = self.get_wishlist(ID)
-    if str(wl_str)=='nan':
-        wl_str = []
-    else:
-        wl_str = wl_str.replace('"','')
-        wl_str = wl_str.split(', ')
-    for _item in items:
-        if str(_item) in wl_str:
-            print('Item ID:', _item, 'is already in the wishlist!!!')
-            flag = 0
-        else:
-            wl_str.append(str(_item))
-            print('Item ID:', _item, 'is added successfully!!!')
-    wl_str = ', '.join(i for i in wl_str)
-    wl_str = '"' + wl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'WishList'] = wl_str
-    self.data.to_csv(self.database, index=False)
-    return self.data[self.data['ID']==ID]
-
-
-
-def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
-    id_list = sorted(self.data.ID.tolist(), reverse=True)
-    lastID = id_list[0]
-    if name == '':
-        print('Name cannot be empty')
-        return -1
-    else:
-        account_dict = {
-            'ID': lastID+1,
-            'Name': name,
-            'Surname': surname,
-            'Birthday': birthday,
-            'Interests': interests,
-            'WishList': wishlist,
-            'FriendList': friendlist
-        }
-        self.data = self.data.append(account_dict, ignore_index=True)
-        self.data.to_csv(self.database, index=False)
-        print('Account created successfully!')
-    return self.data[self.data['ID']==lastID+1]
-
-
-
-def delete_account(self, ID) -
-
-
-
- -Expand source code - -
def delete_account(self, ID):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        print('Invalid ID, please enter valid ID.')
-        return -1
-    else:
-        matched_data = self.data[self.data['ID']==ID]
-        self.data = self.data.drop(matched_data.index)
-        print('Account deleted successfully!')
-        self.data.to_csv(self.database, index=False)
-    return matched_data
-
-
-
-def delete_wishlist(self, ID, items) -
-
-
-
- -Expand source code - -
def delete_wishlist(self, ID, items):
-    flag = 1
-    wl_str = self.get_wishlist(ID)
-    if str(wl_str)=='nan':
-        wl_str = []
-    else:
-        wl_str = wl_str.replace('"','')
-        wl_str = wl_str.split(', ')
-    for _item in items:
-        if str(_item) in wl_str:
-            if len(wl_str):
-                print('There are no items in the wishlist!!!')
-                flag = 0
-            else:
-                wl_str.remove(str(_item))
-                print('Item ID:', _item, 'is removed successfully!!!')
-        else:
-            print('Item ID:', _item, 'is not found in the wishlist!!!')
-    wl_str = ', '.join(i for i in wl_str)
-    wl_str = '"' + wl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'WishList'] = wl_str
-    self.data.to_csv(self.database, index=False)
-    return self.data[self.data['ID']==ID]
-
-
-
-def get_birthday(self, ID) -
-
-
-
- -Expand source code - -
def get_birthday(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][3]
-
-
-
-def get_database(self) -
-
-
-
- -Expand source code - -
def get_database(self):
-    return self.data
-
-
-
-def get_friendlist(self, ID) -
-
-
-
- -Expand source code - -
def get_friendlist(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == False:
-        return False
-    else:
-        result_dict = result.values
-        return result_dict[0][6]
-
-
-
-def get_info(self, ID) -
-
-
-
- -Expand source code - -
def get_info(self, ID):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        return -1
-    else:
-        return self.data[self.data['ID']==ID]
-
-
-
-def get_interests(self, ID) -
-
-
-
- -Expand source code - -
def get_interests(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][4]
-
-
-
-def get_name(self, ID) -
-
-
-
- -Expand source code - -
def get_name(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][1]
-
-
-
-def get_surname(self, ID) -
-
-
-
- -Expand source code - -
def get_surname(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][2]
-
-
-
-def get_wishlist(self, ID) -
-
-
-
- -Expand source code - -
def get_wishlist(self, ID):
-    result, flag = self.search_ID(ID)
-    if flag == -1:
-        return -1
-    else:
-        result_dict = result.values
-        return result_dict[0][5]
-
-
-
-def search_ID(self, ID) -
-
-
-
- -Expand source code - -
def search_ID(self, ID):
-    if ID == None:
-        print("ID cannot be empty!!!")
-        return [0], -1
-    ID_result = self.data[self.data['ID']==ID]
-    if ID_result.values.size == 0:
-        print("ID not found! Try ID ranges from 0 to 10.")
-        return [0], -1
-    return ID_result, True
-
-
-
-def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist='') -
-
-
-
- -Expand source code - -
def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
-    id_list = self.data.ID.tolist()
-    if ID not in id_list:
-        print('User ID:', ID, 'is not in the database!!!')
-        return -1
-    else:
-        data = self.data[self.data['ID']==ID]
-        # if name=='':
-        #     name = data.Name.values[0]
-        # if surname=='':
-        #     surname = data.Surname.values[0]
-        # if birthday=='':
-        #     birthday = data.Birthday.values[0]
-        # if interests=='':
-        #     interests = data.Interests.values[0]
-        # if wishlist=='':
-        #     wishlist = data.WishList.values[0]
-        #     print(wishlist)
-        # if friendlist=='':
-        #     friendlist = data.FriendList.values[0]
-        account_dict = {
-            'ID': ID,
-            'Name': name,
-            'Surname': surname,
-            'Birthday': birthday,
-            'Interests': interests,
-            'WishList': wishlist,
-            'FriendList': friendlist
-        }
-        index = self.data[self.data['ID']==ID].index[0]
-        #self.data.at[index, 'WishList'] = account_dict
-        self.data.loc[index,'ID'] = ID
-        self.data.loc[index,'Name'] = name
-        self.data.loc[index, 'Surname'] = surname
-        self.data.loc[index, 'Birthday'] = birthday
-        self.data.loc[index, 'Interests'] = interests
-        self.data.loc[index, 'WishList'] = wishlist
-        print(type(wishlist))
-        self.data.loc[index, 'FriendList'] = friendlist
-        self.data.to_csv(self.database, index=False)
-        print('Account updated successfully!')
-    return self.data[self.data['ID']==ID]
-
-
-
-
-
-class Friends -
-
-
-
- -Expand source code - -
class Friends(AccountInfo):
-    def __init__(self):
-        super().__init__()
-    
-    def get_friend_names(self,ID):
-        friend_names = []
-        friend_ids = self.get_friendlist(ID)
-        for c in friend_ids:
-            try:
-                if int(c):
-                    friend_id = int(c)
-                    fname = self.get_name(friend_id)
-                    sname = self.get_surname(friend_id)
-                    aname = fname + " " + sname 
-                    friend_names.append(aname)
-            except:
-                pass
-            
-        return friend_names
-    
-    def add_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        if str(fl_str)=='nan':
-            fl_str = []
-        else:
-            fl_str = fl_str.replace('"','')
-            fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                print('ID:', _id, 'is Already friend!!!')
-            else:
-                fl_str.append(str(_id))
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-    
-    def delete_friend(self, ID: int, friend_IDs: list):
-        fl_str = self.get_friendlist(ID)
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-        for _id in friend_IDs:
-            if str(_id) in fl_str:
-                fl_str.remove(str(_id))
-            else:
-                print('ID:', _id, 'not found in the friend list!!')
-        fl_str = ', '.join(i for i in fl_str)
-        fl_str = '"' + fl_str + '"'
-        index = self.data[self.data['ID']==ID].index[0]
-        self.data.at[index, 'FriendList'] = fl_str
-        return self.data[self.data['ID']==ID]
-
-

Ancestors

- -

Methods

-
-
-def add_friend(self, ID: int, friend_IDs: list) -
-
-
-
- -Expand source code - -
def add_friend(self, ID: int, friend_IDs: list):
-    fl_str = self.get_friendlist(ID)
-    if str(fl_str)=='nan':
-        fl_str = []
-    else:
-        fl_str = fl_str.replace('"','')
-        fl_str = fl_str.split(', ')
-    for _id in friend_IDs:
-        if str(_id) in fl_str:
-            print('ID:', _id, 'is Already friend!!!')
-        else:
-            fl_str.append(str(_id))
-    fl_str = ', '.join(i for i in fl_str)
-    fl_str = '"' + fl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'FriendList'] = fl_str
-    return self.data[self.data['ID']==ID]
-
-
-
-def delete_friend(self, ID: int, friend_IDs: list) -
-
-
-
- -Expand source code - -
def delete_friend(self, ID: int, friend_IDs: list):
-    fl_str = self.get_friendlist(ID)
-    fl_str = fl_str.replace('"','')
-    fl_str = fl_str.split(', ')
-    for _id in friend_IDs:
-        if str(_id) in fl_str:
-            fl_str.remove(str(_id))
-        else:
-            print('ID:', _id, 'not found in the friend list!!')
-    fl_str = ', '.join(i for i in fl_str)
-    fl_str = '"' + fl_str + '"'
-    index = self.data[self.data['ID']==ID].index[0]
-    self.data.at[index, 'FriendList'] = fl_str
-    return self.data[self.data['ID']==ID]
-
-
-
-def get_friend_names(self, ID) -
-
-
-
- -Expand source code - -
def get_friend_names(self,ID):
-    friend_names = []
-    friend_ids = self.get_friendlist(ID)
-    for c in friend_ids:
-        try:
-            if int(c):
-                friend_id = int(c)
-                fname = self.get_name(friend_id)
-                sname = self.get_surname(friend_id)
-                aname = fname + " " + sname 
-                friend_names.append(aname)
-        except:
-            pass
-        
-    return friend_names
-
-
-
-
-
-
-
- -
- - - diff --git a/src/item.html b/src/item.html deleted file mode 100644 index 8333500..0000000 --- a/src/item.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - -item API documentation - - - - - - - - - - - -
-
-
-

Module item

-
-
-
- -Expand source code - -
from item_manager import ItemManager
-class item():
-    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
-        if ID != None:
-            itemMan = ItemManager()
-            info = itemMan.get_item(ID)
-            if isinstance(info, int):
-                raise ValueError
-            else:  
-                self.title = info['Title']
-                self.desc = info['Description']
-                self.link = info['Link']
-                self.cost = info['Cost']
-                self.itemID = ID
-    
-        else:
-            self.title = title
-            self.desc = desc
-            self.link = link
-            self.cost = cost
-            self.itemID = int(self.create_item()['ItemID'])
-
-
-    
-    def create_item(self):
-        itemMan = ItemManager()
-        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-        return item
-
-    def modify_item(self, title, desc, link, cost):
-        itemMan = ItemManager()
-        self.title = title
-        self.desc = desc
-        self.link = link
-        self.cost = cost
-        itemMan.update_item( self.itemID, title, desc, link, cost)
-    
-    def view_item(self):
-        itemMan = ItemManager()
-        return itemMan.get_item(self.itemID)
-
-    def delete_item(self):
-        itemMan = ItemManager()
-        itemMan.delete_item(self.itemID)
-
-
-
-# i = item('Football', 'NFL original', 'www.football.com', 50)
-# print(i.cost)
-# i.modify_item('Football', 'NFL original', 'www.football.com', 65)
-# print(i.view_item())
-# i.delete_item()
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class item -(title='', desc='', link='', cost='', ID=None) -
-
-
-
- -Expand source code - -
class item():
-    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
-        if ID != None:
-            itemMan = ItemManager()
-            info = itemMan.get_item(ID)
-            if isinstance(info, int):
-                raise ValueError
-            else:  
-                self.title = info['Title']
-                self.desc = info['Description']
-                self.link = info['Link']
-                self.cost = info['Cost']
-                self.itemID = ID
-    
-        else:
-            self.title = title
-            self.desc = desc
-            self.link = link
-            self.cost = cost
-            self.itemID = int(self.create_item()['ItemID'])
-
-
-    
-    def create_item(self):
-        itemMan = ItemManager()
-        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-        return item
-
-    def modify_item(self, title, desc, link, cost):
-        itemMan = ItemManager()
-        self.title = title
-        self.desc = desc
-        self.link = link
-        self.cost = cost
-        itemMan.update_item( self.itemID, title, desc, link, cost)
-    
-    def view_item(self):
-        itemMan = ItemManager()
-        return itemMan.get_item(self.itemID)
-
-    def delete_item(self):
-        itemMan = ItemManager()
-        itemMan.delete_item(self.itemID)
-
-

Methods

-
-
-def create_item(self) -
-
-
-
- -Expand source code - -
def create_item(self):
-    itemMan = ItemManager()
-    item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
-    return item
-
-
-
-def delete_item(self) -
-
-
-
- -Expand source code - -
def delete_item(self):
-    itemMan = ItemManager()
-    itemMan.delete_item(self.itemID)
-
-
-
-def modify_item(self, title, desc, link, cost) -
-
-
-
- -Expand source code - -
def modify_item(self, title, desc, link, cost):
-    itemMan = ItemManager()
-    self.title = title
-    self.desc = desc
-    self.link = link
-    self.cost = cost
-    itemMan.update_item( self.itemID, title, desc, link, cost)
-
-
-
-def view_item(self) -
-
-
-
- -Expand source code - -
def view_item(self):
-    itemMan = ItemManager()
-    return itemMan.get_item(self.itemID)
-
-
-
-
-
-
-
- -
- - - diff --git a/src/item_manager.html b/src/item_manager.html deleted file mode 100644 index 61f7329..0000000 --- a/src/item_manager.html +++ /dev/null @@ -1,560 +0,0 @@ - - - - - - -item_manager API documentation - - - - - - - - - - - -
-
-
-

Module item_manager

-
-
-
- -Expand source code - -
from pandas import *
-import psycopg2
-from config import config
-
-class ItemManager:
-    # def __init__ (self):
-    #     try:
-    #         self.database = 'data/item_data - Copy.csv'
-    #         data = read_csv(self.database)
-    #     except: 
-    #         self.database = '../data/item_data - Copy.csv'
-
-    def add_item(self, title, desc = '', link = '',  cost = ''):
-        if title == '':
-            print('Title cannot be empty')
-            return -1
-        
-        query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
-        conn = None
-        ID = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (title, desc, link, cost))
-            ID = cur.fetchone()[0]
-            cur.close()
-            conn.commit()
-            cur.close()
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-                
-        return ID
-
-
-    def get_item(self, ID: int):
-        query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
-        conn = None
-        item_info = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (ID,))
-            item_info = cur.fetchall()
-            cur.close()
-            conn.commit()
-            cur.close()
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        
-        return item_info[0] if item_info else None
-        
-        
-        # data = read_csv(self.database)
-        # if data.loc[data['ItemID']==ID].empty:
-        #     print("Item does not exist")
-        #     return -1
-        # return (data.loc[data['ItemID'] == ID])
-
-    def delete_item(self, ID: int):
-        
-        query = """Delete From "Item" Where "ID" = %s;"""
-        conn = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (ID,))
-            cur.close()
-            conn.commit()
-            cur.close()        
-            print("Item deleted.")
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        return 0
-    
-        # cur.execute(query,(_id,))
-        # data = read_csv(self.database)
-        # if data.index[data['ItemID'] == ID].empty:
-        #     print("Item does not exist")
-        #     return -1
-        # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-        # data.to_csv(self.database, mode='w', index=False)
-        # print("Item deleted.")
-        # return 0
-
-    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-        
-        query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
-        conn = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (title,desc,link,cost,ID))
-            cur.close()
-            conn.commit()
-            cur.close()
-            print("Item Updated.")
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        
-        return 0
-        
-        
-        
-        # data = read_csv(self.database)
-        # item = data.loc[data['ItemID'] == ID]
-        # ind = data['ItemID'] == ID
-        # if data.loc[data['ItemID'] == ID].empty:
-        #     print('Item does not exist.')
-        #     return -1
-        # data.loc[ind,'Title'] = title
-        # data.loc[ind,'Description'] = desc
-        # data.loc[ind, 'Link'] = link
-        # data.loc[ind, 'Cost'] = cost
-        # data.to_csv(self.database, mode='w', index=False)
-        # print('Updated item')
-        # return 0
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class ItemManager -
-
-
-
- -Expand source code - -
class ItemManager:
-    # def __init__ (self):
-    #     try:
-    #         self.database = 'data/item_data - Copy.csv'
-    #         data = read_csv(self.database)
-    #     except: 
-    #         self.database = '../data/item_data - Copy.csv'
-
-    def add_item(self, title, desc = '', link = '',  cost = ''):
-        if title == '':
-            print('Title cannot be empty')
-            return -1
-        
-        query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
-        conn = None
-        ID = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (title, desc, link, cost))
-            ID = cur.fetchone()[0]
-            cur.close()
-            conn.commit()
-            cur.close()
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-                
-        return ID
-
-
-    def get_item(self, ID: int):
-        query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
-        conn = None
-        item_info = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (ID,))
-            item_info = cur.fetchall()
-            cur.close()
-            conn.commit()
-            cur.close()
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        
-        return item_info[0] if item_info else None
-        
-        
-        # data = read_csv(self.database)
-        # if data.loc[data['ItemID']==ID].empty:
-        #     print("Item does not exist")
-        #     return -1
-        # return (data.loc[data['ItemID'] == ID])
-
-    def delete_item(self, ID: int):
-        
-        query = """Delete From "Item" Where "ID" = %s;"""
-        conn = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (ID,))
-            cur.close()
-            conn.commit()
-            cur.close()        
-            print("Item deleted.")
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        return 0
-    
-        # cur.execute(query,(_id,))
-        # data = read_csv(self.database)
-        # if data.index[data['ItemID'] == ID].empty:
-        #     print("Item does not exist")
-        #     return -1
-        # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-        # data.to_csv(self.database, mode='w', index=False)
-        # print("Item deleted.")
-        # return 0
-
-    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-        
-        query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
-        conn = None
-        try:
-        # initializing connection
-            params = config()
-            print('Connecting to the PostgreSQL database...')
-            conn = psycopg2.connect(**params)
-            cur = conn.cursor()
-        # execute a statement
-            cur.execute(query, (title,desc,link,cost,ID))
-            cur.close()
-            conn.commit()
-            cur.close()
-            print("Item Updated.")
-            
-        except (Exception, psycopg2.DatabaseError) as error:
-            print(error)
-        finally:
-            if conn is not None:
-                conn.close()
-                print('Database connection closed.')
-        
-        return 0
-        
-        
-        
-        # data = read_csv(self.database)
-        # item = data.loc[data['ItemID'] == ID]
-        # ind = data['ItemID'] == ID
-        # if data.loc[data['ItemID'] == ID].empty:
-        #     print('Item does not exist.')
-        #     return -1
-        # data.loc[ind,'Title'] = title
-        # data.loc[ind,'Description'] = desc
-        # data.loc[ind, 'Link'] = link
-        # data.loc[ind, 'Cost'] = cost
-        # data.to_csv(self.database, mode='w', index=False)
-        # print('Updated item')
-        # return 0
-
-

Methods

-
-
-def add_item(self, title, desc='', link='', cost='') -
-
-
-
- -Expand source code - -
def add_item(self, title, desc = '', link = '',  cost = ''):
-    if title == '':
-        print('Title cannot be empty')
-        return -1
-    
-    query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
-    conn = None
-    ID = None
-    try:
-    # initializing connection
-        params = config()
-        print('Connecting to the PostgreSQL database...')
-        conn = psycopg2.connect(**params)
-        cur = conn.cursor()
-    # execute a statement
-        cur.execute(query, (title, desc, link, cost))
-        ID = cur.fetchone()[0]
-        cur.close()
-        conn.commit()
-        cur.close()
-        
-    except (Exception, psycopg2.DatabaseError) as error:
-        print(error)
-    finally:
-        if conn is not None:
-            conn.close()
-            print('Database connection closed.')
-            
-    return ID
-
-
-
-def delete_item(self, ID: int) -
-
-
-
- -Expand source code - -
def delete_item(self, ID: int):
-    
-    query = """Delete From "Item" Where "ID" = %s;"""
-    conn = None
-    try:
-    # initializing connection
-        params = config()
-        print('Connecting to the PostgreSQL database...')
-        conn = psycopg2.connect(**params)
-        cur = conn.cursor()
-    # execute a statement
-        cur.execute(query, (ID,))
-        cur.close()
-        conn.commit()
-        cur.close()        
-        print("Item deleted.")
-    except (Exception, psycopg2.DatabaseError) as error:
-        print(error)
-    finally:
-        if conn is not None:
-            conn.close()
-            print('Database connection closed.')
-    return 0
-
-    # cur.execute(query,(_id,))
-    # data = read_csv(self.database)
-    # if data.index[data['ItemID'] == ID].empty:
-    #     print("Item does not exist")
-    #     return -1
-    # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
-    # data.to_csv(self.database, mode='w', index=False)
-    # print("Item deleted.")
-    # return 0
-
-
-
-def get_item(self, ID: int) -
-
-
-
- -Expand source code - -
def get_item(self, ID: int):
-    query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
-    conn = None
-    item_info = None
-    try:
-    # initializing connection
-        params = config()
-        print('Connecting to the PostgreSQL database...')
-        conn = psycopg2.connect(**params)
-        cur = conn.cursor()
-    # execute a statement
-        cur.execute(query, (ID,))
-        item_info = cur.fetchall()
-        cur.close()
-        conn.commit()
-        cur.close()
-        
-    except (Exception, psycopg2.DatabaseError) as error:
-        print(error)
-    finally:
-        if conn is not None:
-            conn.close()
-            print('Database connection closed.')
-    
-    return item_info[0] if item_info else None
-    
-    
-    # data = read_csv(self.database)
-    # if data.loc[data['ItemID']==ID].empty:
-    #     print("Item does not exist")
-    #     return -1
-    # return (data.loc[data['ItemID'] == ID])
-
-
-
-def update_item(self, ID: int, title, desc='', link='', cost='') -
-
-
-
- -Expand source code - -
def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
-    
-    query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
-    conn = None
-    try:
-    # initializing connection
-        params = config()
-        print('Connecting to the PostgreSQL database...')
-        conn = psycopg2.connect(**params)
-        cur = conn.cursor()
-    # execute a statement
-        cur.execute(query, (title,desc,link,cost,ID))
-        cur.close()
-        conn.commit()
-        cur.close()
-        print("Item Updated.")
-        
-    except (Exception, psycopg2.DatabaseError) as error:
-        print(error)
-    finally:
-        if conn is not None:
-            conn.close()
-            print('Database connection closed.')
-    
-    return 0
-    
-    
-    
-    # data = read_csv(self.database)
-    # item = data.loc[data['ItemID'] == ID]
-    # ind = data['ItemID'] == ID
-    # if data.loc[data['ItemID'] == ID].empty:
-    #     print('Item does not exist.')
-    #     return -1
-    # data.loc[ind,'Title'] = title
-    # data.loc[ind,'Description'] = desc
-    # data.loc[ind, 'Link'] = link
-    # data.loc[ind, 'Cost'] = cost
-    # data.to_csv(self.database, mode='w', index=False)
-    # print('Updated item')
-    # return 0
-
-
-
-
-
-
-
- -
- - - diff --git a/src/main.py b/src/main.py index 5abf9f4..0237bc3 100644 --- a/src/main.py +++ b/src/main.py @@ -78,19 +78,6 @@ def account_page(): st.markdown(st.session_state.response.json()[0]["h"].replace('—', ''), unsafe_allow_html=True) - # if st.button('Profile'): - # st.session_state.runpage = 'profile' - # st.experimental_rerun() - # if st.button('Wishlist'): - # st.session_state.runpage = 'wishlist' - # st.experimental_rerun() - # if st.button('Friendlist'): - # st.session_state.runpage = 'friendlist' - # st.experimental_rerun() - # if st.button('Logout'): - # st.session_state.runpage = 'initial' - # st.experimental_rerun() - def profile_page(): st.header('Profile') From b07a34c7e24141b94011087282c687e8e6980b00 Mon Sep 17 00:00:00 2001 From: Landon Gaddy Date: Sun, 27 Nov 2022 21:21:24 -0500 Subject: [PATCH 6/7] Fixed merge conflicts --- src/account.html | 233 +++++++++ src/account_info.html | 1042 +++++++++++++++++++++++++++++++++++++++++ src/item.html | 240 ++++++++++ src/item_manager.html | 560 ++++++++++++++++++++++ src/main.py | 15 +- src/utils.py | 8 +- src/wishlist.html | 419 +++++++++++++++++ 7 files changed, 2499 insertions(+), 18 deletions(-) create mode 100644 src/account.html create mode 100644 src/account_info.html create mode 100644 src/item.html create mode 100644 src/item_manager.html create mode 100644 src/wishlist.html diff --git a/src/account.html b/src/account.html new file mode 100644 index 0000000..b76dfd0 --- /dev/null +++ b/src/account.html @@ -0,0 +1,233 @@ + + + + + + +account API documentation + + + + + + + + + + + +
+
+
+

Module account

+
+
+
+ +Expand source code + +
from account_info import AccountInfo
+
+class Account():
+    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
+        if ID != None:
+            accountMan = AccountInfo()
+            info = accountMan.get_info(ID)
+            if isinstance(info, int):
+                raise ValueError
+            else: 
+                self.name = info['Name']
+                self.surname = info['Surname']
+                self.birthday = info['Birthday']
+                self.interests = info['Interests']
+                self.wishlist = info['WishList']
+                self.friendlist = info['FriendList']
+                self.ID = ID
+        else: 
+            self.name = name
+            self.surname = surname
+            self.birthday = birthday
+            self.interests = interests
+            self.wishlist = wishlist
+            self.friendlist = friendlist
+            self.ID = self.create_account()['ID']
+        
+
+    def create_account(self):
+        accountMan = AccountInfo()
+        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
+        return acc
+    
+    def view_account(self):
+        accountMan = AccountInfo()
+        return accountMan.get_info(self.ID)
+
+    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+            self.name = name
+            self.surname = surname
+            self.birthday = birthday
+            self.interests = interests
+            self.wishlist = wishlist
+            self.friendlist = friendlist
+            accountMan = AccountInfo()
+            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
+
+
+
+# #acc = Account('Hannah', 'Montana', '05/05/1995', 'Singing, Dancing')
+# #acc.view_account()
+# acc = Account(ID=1)
+# ints = (acc.interests.to_string(index=False)).replace("\"", "")
+# ints += ", Ballet"
+# # print(ints)
+# wishes = (acc.wishlist.to_string(index=False))
+# acc.update_account(acc.name.to_string(index=False), acc.surname.to_string(index=False), acc.birthday.to_string(index=False), ints, acc.wishlist.to_string(index=False), acc.friendlist.to_string(index=False))
+
+        
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class Account +(name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID=None) +
+
+
+
+ +Expand source code + +
class Account():
+    def __init__(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='', ID = None):
+        if ID != None:
+            accountMan = AccountInfo()
+            info = accountMan.get_info(ID)
+            if isinstance(info, int):
+                raise ValueError
+            else: 
+                self.name = info['Name']
+                self.surname = info['Surname']
+                self.birthday = info['Birthday']
+                self.interests = info['Interests']
+                self.wishlist = info['WishList']
+                self.friendlist = info['FriendList']
+                self.ID = ID
+        else: 
+            self.name = name
+            self.surname = surname
+            self.birthday = birthday
+            self.interests = interests
+            self.wishlist = wishlist
+            self.friendlist = friendlist
+            self.ID = self.create_account()['ID']
+        
+
+    def create_account(self):
+        accountMan = AccountInfo()
+        acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
+        return acc
+    
+    def view_account(self):
+        accountMan = AccountInfo()
+        return accountMan.get_info(self.ID)
+
+    def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+            self.name = name
+            self.surname = surname
+            self.birthday = birthday
+            self.interests = interests
+            self.wishlist = wishlist
+            self.friendlist = friendlist
+            accountMan = AccountInfo()
+            accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
+
+

Methods

+
+
+def create_account(self) +
+
+
+
+ +Expand source code + +
def create_account(self):
+    accountMan = AccountInfo()
+    acc = accountMan.create_account(self.name, self.surname, self.birthday, self.interests, self.wishlist, self.friendlist)
+    return acc
+
+
+
+def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist='') +
+
+
+
+ +Expand source code + +
def update_account(self, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+        self.name = name
+        self.surname = surname
+        self.birthday = birthday
+        self.interests = interests
+        self.wishlist = wishlist
+        self.friendlist = friendlist
+        accountMan = AccountInfo()
+        accountMan.update_account(self.ID, name, surname, birthday, interests, wishlist, friendlist)
+
+
+
+def view_account(self) +
+
+
+
+ +Expand source code + +
def view_account(self):
+    accountMan = AccountInfo()
+    return accountMan.get_info(self.ID)
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/src/account_info.html b/src/account_info.html new file mode 100644 index 0000000..f53f7f2 --- /dev/null +++ b/src/account_info.html @@ -0,0 +1,1042 @@ + + + + + + +account_info API documentation + + + + + + + + + + + +
+
+
+

Module account_info

+
+
+
+ +Expand source code + +
import numpy as np
+import pandas as pd
+import sys
+
+class AccountInfo:
+    def __init__(self):
+        try:
+            self.database = 'data/people_data-copy.csv'
+            self.data = pd.read_csv(self.database)
+        except FileNotFoundError:
+            self.database = '../data/people_data-copy.csv'
+            self.data = pd.read_csv(self.database)
+        
+    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
+        id_list = sorted(self.data.ID.tolist(), reverse=True)
+        lastID = id_list[0]
+        if name == '':
+            print('Name cannot be empty')
+            return -1
+        else:
+            account_dict = {
+                'ID': lastID+1,
+                'Name': name,
+                'Surname': surname,
+                'Birthday': birthday,
+                'Interests': interests,
+                'WishList': wishlist,
+                'FriendList': friendlist
+            }
+            self.data = self.data.append(account_dict, ignore_index=True)
+            self.data.to_csv(self.database, index=False)
+            print('Account created successfully!')
+        return self.data[self.data['ID']==lastID+1]
+    
+    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            print('User ID:', ID, 'is not in the database!!!')
+            return -1
+        else:
+            data = self.data[self.data['ID']==ID]
+            # if name=='':
+            #     name = data.Name.values[0]
+            # if surname=='':
+            #     surname = data.Surname.values[0]
+            # if birthday=='':
+            #     birthday = data.Birthday.values[0]
+            # if interests=='':
+            #     interests = data.Interests.values[0]
+            # if wishlist=='':
+            #     wishlist = data.WishList.values[0]
+            #     print(wishlist)
+            # if friendlist=='':
+            #     friendlist = data.FriendList.values[0]
+            account_dict = {
+                'ID': ID,
+                'Name': name,
+                'Surname': surname,
+                'Birthday': birthday,
+                'Interests': interests,
+                'WishList': wishlist,
+                'FriendList': friendlist
+            }
+            index = self.data[self.data['ID']==ID].index[0]
+            #self.data.at[index, 'WishList'] = account_dict
+            self.data.loc[index,'ID'] = ID
+            self.data.loc[index,'Name'] = name
+            self.data.loc[index, 'Surname'] = surname
+            self.data.loc[index, 'Birthday'] = birthday
+            self.data.loc[index, 'Interests'] = interests
+            self.data.loc[index, 'WishList'] = wishlist
+            print(type(wishlist))
+            self.data.loc[index, 'FriendList'] = friendlist
+            self.data.to_csv(self.database, index=False)
+            print('Account updated successfully!')
+        return self.data[self.data['ID']==ID]
+    
+    def get_database(self):
+        return self.data
+    
+    def delete_account(self, ID):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            print('Invalid ID, please enter valid ID.')
+            return -1
+        else:
+            matched_data = self.data[self.data['ID']==ID]
+            self.data = self.data.drop(matched_data.index)
+            print('Account deleted successfully!')
+            self.data.to_csv(self.database, index=False)
+        return matched_data
+    
+    def get_info(self, ID):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            return -1
+        else:
+            return self.data[self.data['ID']==ID]
+        
+    def search_ID(self, ID):
+        if ID == None:
+            print("ID cannot be empty!!!")
+            return [0], -1
+        ID_result = self.data[self.data['ID']==ID]
+        if ID_result.values.size == 0:
+            print("ID not found! Try ID ranges from 0 to 10.")
+            return [0], -1
+        return ID_result, True
+        
+    def get_name(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][1]
+    
+    def get_surname(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][2]
+        
+    def get_birthday(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][3]
+    
+    def get_interests(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][4]
+        
+    def get_wishlist(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][5]
+        
+    def add_wishlist(self, ID, items):
+        flag = 1
+        wl_str = self.get_wishlist(ID)
+        if str(wl_str)=='nan':
+            wl_str = []
+        else:
+            wl_str = wl_str.replace('"','')
+            wl_str = wl_str.split(', ')
+        for _item in items:
+            if str(_item) in wl_str:
+                print('Item ID:', _item, 'is already in the wishlist!!!')
+                flag = 0
+            else:
+                wl_str.append(str(_item))
+                print('Item ID:', _item, 'is added successfully!!!')
+        wl_str = ', '.join(i for i in wl_str)
+        wl_str = '"' + wl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'WishList'] = wl_str
+        self.data.to_csv(self.database, index=False)
+        return self.data[self.data['ID']==ID]
+    
+    def delete_wishlist(self, ID, items):
+        flag = 1
+        wl_str = self.get_wishlist(ID)
+        if str(wl_str)=='nan':
+            wl_str = []
+        else:
+            wl_str = wl_str.replace('"','')
+            wl_str = wl_str.split(', ')
+        for _item in items:
+            if str(_item) in wl_str:
+                if len(wl_str):
+                    print('There are no items in the wishlist!!!')
+                    flag = 0
+                else:
+                    wl_str.remove(str(_item))
+                    print('Item ID:', _item, 'is removed successfully!!!')
+            else:
+                print('Item ID:', _item, 'is not found in the wishlist!!!')
+        wl_str = ', '.join(i for i in wl_str)
+        wl_str = '"' + wl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'WishList'] = wl_str
+        self.data.to_csv(self.database, index=False)
+        return self.data[self.data['ID']==ID]
+        
+    def get_friendlist(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == False:
+            return False
+        else:
+            result_dict = result.values
+            return result_dict[0][6]
+
+
+class Friends(AccountInfo):
+    def __init__(self):
+        super().__init__()
+    
+    def get_friend_names(self,ID):
+        friend_names = []
+        friend_ids = self.get_friendlist(ID)
+        for c in friend_ids:
+            try:
+                if int(c):
+                    friend_id = int(c)
+                    fname = self.get_name(friend_id)
+                    sname = self.get_surname(friend_id)
+                    aname = fname + " " + sname 
+                    friend_names.append(aname)
+            except:
+                pass
+            
+        return friend_names
+    
+    def add_friend(self, ID: int, friend_IDs: list):
+        fl_str = self.get_friendlist(ID)
+        if str(fl_str)=='nan':
+            fl_str = []
+        else:
+            fl_str = fl_str.replace('"','')
+            fl_str = fl_str.split(', ')
+        for _id in friend_IDs:
+            if str(_id) in fl_str:
+                print('ID:', _id, 'is Already friend!!!')
+            else:
+                fl_str.append(str(_id))
+        fl_str = ', '.join(i for i in fl_str)
+        fl_str = '"' + fl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'FriendList'] = fl_str
+        return self.data[self.data['ID']==ID]
+    
+    def delete_friend(self, ID: int, friend_IDs: list):
+        fl_str = self.get_friendlist(ID)
+        fl_str = fl_str.replace('"','')
+        fl_str = fl_str.split(', ')
+        for _id in friend_IDs:
+            if str(_id) in fl_str:
+                fl_str.remove(str(_id))
+            else:
+                print('ID:', _id, 'not found in the friend list!!')
+        fl_str = ', '.join(i for i in fl_str)
+        fl_str = '"' + fl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'FriendList'] = fl_str
+        return self.data[self.data['ID']==ID]
+    
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class AccountInfo +
+
+
+
+ +Expand source code + +
class AccountInfo:
+    def __init__(self):
+        try:
+            self.database = 'data/people_data-copy.csv'
+            self.data = pd.read_csv(self.database)
+        except FileNotFoundError:
+            self.database = '../data/people_data-copy.csv'
+            self.data = pd.read_csv(self.database)
+        
+    def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
+        id_list = sorted(self.data.ID.tolist(), reverse=True)
+        lastID = id_list[0]
+        if name == '':
+            print('Name cannot be empty')
+            return -1
+        else:
+            account_dict = {
+                'ID': lastID+1,
+                'Name': name,
+                'Surname': surname,
+                'Birthday': birthday,
+                'Interests': interests,
+                'WishList': wishlist,
+                'FriendList': friendlist
+            }
+            self.data = self.data.append(account_dict, ignore_index=True)
+            self.data.to_csv(self.database, index=False)
+            print('Account created successfully!')
+        return self.data[self.data['ID']==lastID+1]
+    
+    def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            print('User ID:', ID, 'is not in the database!!!')
+            return -1
+        else:
+            data = self.data[self.data['ID']==ID]
+            # if name=='':
+            #     name = data.Name.values[0]
+            # if surname=='':
+            #     surname = data.Surname.values[0]
+            # if birthday=='':
+            #     birthday = data.Birthday.values[0]
+            # if interests=='':
+            #     interests = data.Interests.values[0]
+            # if wishlist=='':
+            #     wishlist = data.WishList.values[0]
+            #     print(wishlist)
+            # if friendlist=='':
+            #     friendlist = data.FriendList.values[0]
+            account_dict = {
+                'ID': ID,
+                'Name': name,
+                'Surname': surname,
+                'Birthday': birthday,
+                'Interests': interests,
+                'WishList': wishlist,
+                'FriendList': friendlist
+            }
+            index = self.data[self.data['ID']==ID].index[0]
+            #self.data.at[index, 'WishList'] = account_dict
+            self.data.loc[index,'ID'] = ID
+            self.data.loc[index,'Name'] = name
+            self.data.loc[index, 'Surname'] = surname
+            self.data.loc[index, 'Birthday'] = birthday
+            self.data.loc[index, 'Interests'] = interests
+            self.data.loc[index, 'WishList'] = wishlist
+            print(type(wishlist))
+            self.data.loc[index, 'FriendList'] = friendlist
+            self.data.to_csv(self.database, index=False)
+            print('Account updated successfully!')
+        return self.data[self.data['ID']==ID]
+    
+    def get_database(self):
+        return self.data
+    
+    def delete_account(self, ID):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            print('Invalid ID, please enter valid ID.')
+            return -1
+        else:
+            matched_data = self.data[self.data['ID']==ID]
+            self.data = self.data.drop(matched_data.index)
+            print('Account deleted successfully!')
+            self.data.to_csv(self.database, index=False)
+        return matched_data
+    
+    def get_info(self, ID):
+        id_list = self.data.ID.tolist()
+        if ID not in id_list:
+            return -1
+        else:
+            return self.data[self.data['ID']==ID]
+        
+    def search_ID(self, ID):
+        if ID == None:
+            print("ID cannot be empty!!!")
+            return [0], -1
+        ID_result = self.data[self.data['ID']==ID]
+        if ID_result.values.size == 0:
+            print("ID not found! Try ID ranges from 0 to 10.")
+            return [0], -1
+        return ID_result, True
+        
+    def get_name(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][1]
+    
+    def get_surname(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][2]
+        
+    def get_birthday(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][3]
+    
+    def get_interests(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][4]
+        
+    def get_wishlist(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == -1:
+            return -1
+        else:
+            result_dict = result.values
+            return result_dict[0][5]
+        
+    def add_wishlist(self, ID, items):
+        flag = 1
+        wl_str = self.get_wishlist(ID)
+        if str(wl_str)=='nan':
+            wl_str = []
+        else:
+            wl_str = wl_str.replace('"','')
+            wl_str = wl_str.split(', ')
+        for _item in items:
+            if str(_item) in wl_str:
+                print('Item ID:', _item, 'is already in the wishlist!!!')
+                flag = 0
+            else:
+                wl_str.append(str(_item))
+                print('Item ID:', _item, 'is added successfully!!!')
+        wl_str = ', '.join(i for i in wl_str)
+        wl_str = '"' + wl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'WishList'] = wl_str
+        self.data.to_csv(self.database, index=False)
+        return self.data[self.data['ID']==ID]
+    
+    def delete_wishlist(self, ID, items):
+        flag = 1
+        wl_str = self.get_wishlist(ID)
+        if str(wl_str)=='nan':
+            wl_str = []
+        else:
+            wl_str = wl_str.replace('"','')
+            wl_str = wl_str.split(', ')
+        for _item in items:
+            if str(_item) in wl_str:
+                if len(wl_str):
+                    print('There are no items in the wishlist!!!')
+                    flag = 0
+                else:
+                    wl_str.remove(str(_item))
+                    print('Item ID:', _item, 'is removed successfully!!!')
+            else:
+                print('Item ID:', _item, 'is not found in the wishlist!!!')
+        wl_str = ', '.join(i for i in wl_str)
+        wl_str = '"' + wl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'WishList'] = wl_str
+        self.data.to_csv(self.database, index=False)
+        return self.data[self.data['ID']==ID]
+        
+    def get_friendlist(self, ID):
+        result, flag = self.search_ID(ID)
+        if flag == False:
+            return False
+        else:
+            result_dict = result.values
+            return result_dict[0][6]
+
+

Subclasses

+ +

Methods

+
+
+def add_wishlist(self, ID, items) +
+
+
+
+ +Expand source code + +
def add_wishlist(self, ID, items):
+    flag = 1
+    wl_str = self.get_wishlist(ID)
+    if str(wl_str)=='nan':
+        wl_str = []
+    else:
+        wl_str = wl_str.replace('"','')
+        wl_str = wl_str.split(', ')
+    for _item in items:
+        if str(_item) in wl_str:
+            print('Item ID:', _item, 'is already in the wishlist!!!')
+            flag = 0
+        else:
+            wl_str.append(str(_item))
+            print('Item ID:', _item, 'is added successfully!!!')
+    wl_str = ', '.join(i for i in wl_str)
+    wl_str = '"' + wl_str + '"'
+    index = self.data[self.data['ID']==ID].index[0]
+    self.data.at[index, 'WishList'] = wl_str
+    self.data.to_csv(self.database, index=False)
+    return self.data[self.data['ID']==ID]
+
+
+
+def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist='') +
+
+
+
+ +Expand source code + +
def create_account(self, name, surname='', birthday='', interests='', wishlist='', friendlist=''):
+    id_list = sorted(self.data.ID.tolist(), reverse=True)
+    lastID = id_list[0]
+    if name == '':
+        print('Name cannot be empty')
+        return -1
+    else:
+        account_dict = {
+            'ID': lastID+1,
+            'Name': name,
+            'Surname': surname,
+            'Birthday': birthday,
+            'Interests': interests,
+            'WishList': wishlist,
+            'FriendList': friendlist
+        }
+        self.data = self.data.append(account_dict, ignore_index=True)
+        self.data.to_csv(self.database, index=False)
+        print('Account created successfully!')
+    return self.data[self.data['ID']==lastID+1]
+
+
+
+def delete_account(self, ID) +
+
+
+
+ +Expand source code + +
def delete_account(self, ID):
+    id_list = self.data.ID.tolist()
+    if ID not in id_list:
+        print('Invalid ID, please enter valid ID.')
+        return -1
+    else:
+        matched_data = self.data[self.data['ID']==ID]
+        self.data = self.data.drop(matched_data.index)
+        print('Account deleted successfully!')
+        self.data.to_csv(self.database, index=False)
+    return matched_data
+
+
+
+def delete_wishlist(self, ID, items) +
+
+
+
+ +Expand source code + +
def delete_wishlist(self, ID, items):
+    flag = 1
+    wl_str = self.get_wishlist(ID)
+    if str(wl_str)=='nan':
+        wl_str = []
+    else:
+        wl_str = wl_str.replace('"','')
+        wl_str = wl_str.split(', ')
+    for _item in items:
+        if str(_item) in wl_str:
+            if len(wl_str):
+                print('There are no items in the wishlist!!!')
+                flag = 0
+            else:
+                wl_str.remove(str(_item))
+                print('Item ID:', _item, 'is removed successfully!!!')
+        else:
+            print('Item ID:', _item, 'is not found in the wishlist!!!')
+    wl_str = ', '.join(i for i in wl_str)
+    wl_str = '"' + wl_str + '"'
+    index = self.data[self.data['ID']==ID].index[0]
+    self.data.at[index, 'WishList'] = wl_str
+    self.data.to_csv(self.database, index=False)
+    return self.data[self.data['ID']==ID]
+
+
+
+def get_birthday(self, ID) +
+
+
+
+ +Expand source code + +
def get_birthday(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == -1:
+        return -1
+    else:
+        result_dict = result.values
+        return result_dict[0][3]
+
+
+
+def get_database(self) +
+
+
+
+ +Expand source code + +
def get_database(self):
+    return self.data
+
+
+
+def get_friendlist(self, ID) +
+
+
+
+ +Expand source code + +
def get_friendlist(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == False:
+        return False
+    else:
+        result_dict = result.values
+        return result_dict[0][6]
+
+
+
+def get_info(self, ID) +
+
+
+
+ +Expand source code + +
def get_info(self, ID):
+    id_list = self.data.ID.tolist()
+    if ID not in id_list:
+        return -1
+    else:
+        return self.data[self.data['ID']==ID]
+
+
+
+def get_interests(self, ID) +
+
+
+
+ +Expand source code + +
def get_interests(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == -1:
+        return -1
+    else:
+        result_dict = result.values
+        return result_dict[0][4]
+
+
+
+def get_name(self, ID) +
+
+
+
+ +Expand source code + +
def get_name(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == -1:
+        return -1
+    else:
+        result_dict = result.values
+        return result_dict[0][1]
+
+
+
+def get_surname(self, ID) +
+
+
+
+ +Expand source code + +
def get_surname(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == -1:
+        return -1
+    else:
+        result_dict = result.values
+        return result_dict[0][2]
+
+
+
+def get_wishlist(self, ID) +
+
+
+
+ +Expand source code + +
def get_wishlist(self, ID):
+    result, flag = self.search_ID(ID)
+    if flag == -1:
+        return -1
+    else:
+        result_dict = result.values
+        return result_dict[0][5]
+
+
+
+def search_ID(self, ID) +
+
+
+
+ +Expand source code + +
def search_ID(self, ID):
+    if ID == None:
+        print("ID cannot be empty!!!")
+        return [0], -1
+    ID_result = self.data[self.data['ID']==ID]
+    if ID_result.values.size == 0:
+        print("ID not found! Try ID ranges from 0 to 10.")
+        return [0], -1
+    return ID_result, True
+
+
+
+def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist='') +
+
+
+
+ +Expand source code + +
def update_account(self, ID, name='', surname='', birthday='', interests='', wishlist='', friendlist=''):
+    id_list = self.data.ID.tolist()
+    if ID not in id_list:
+        print('User ID:', ID, 'is not in the database!!!')
+        return -1
+    else:
+        data = self.data[self.data['ID']==ID]
+        # if name=='':
+        #     name = data.Name.values[0]
+        # if surname=='':
+        #     surname = data.Surname.values[0]
+        # if birthday=='':
+        #     birthday = data.Birthday.values[0]
+        # if interests=='':
+        #     interests = data.Interests.values[0]
+        # if wishlist=='':
+        #     wishlist = data.WishList.values[0]
+        #     print(wishlist)
+        # if friendlist=='':
+        #     friendlist = data.FriendList.values[0]
+        account_dict = {
+            'ID': ID,
+            'Name': name,
+            'Surname': surname,
+            'Birthday': birthday,
+            'Interests': interests,
+            'WishList': wishlist,
+            'FriendList': friendlist
+        }
+        index = self.data[self.data['ID']==ID].index[0]
+        #self.data.at[index, 'WishList'] = account_dict
+        self.data.loc[index,'ID'] = ID
+        self.data.loc[index,'Name'] = name
+        self.data.loc[index, 'Surname'] = surname
+        self.data.loc[index, 'Birthday'] = birthday
+        self.data.loc[index, 'Interests'] = interests
+        self.data.loc[index, 'WishList'] = wishlist
+        print(type(wishlist))
+        self.data.loc[index, 'FriendList'] = friendlist
+        self.data.to_csv(self.database, index=False)
+        print('Account updated successfully!')
+    return self.data[self.data['ID']==ID]
+
+
+
+
+
+class Friends +
+
+
+
+ +Expand source code + +
class Friends(AccountInfo):
+    def __init__(self):
+        super().__init__()
+    
+    def get_friend_names(self,ID):
+        friend_names = []
+        friend_ids = self.get_friendlist(ID)
+        for c in friend_ids:
+            try:
+                if int(c):
+                    friend_id = int(c)
+                    fname = self.get_name(friend_id)
+                    sname = self.get_surname(friend_id)
+                    aname = fname + " " + sname 
+                    friend_names.append(aname)
+            except:
+                pass
+            
+        return friend_names
+    
+    def add_friend(self, ID: int, friend_IDs: list):
+        fl_str = self.get_friendlist(ID)
+        if str(fl_str)=='nan':
+            fl_str = []
+        else:
+            fl_str = fl_str.replace('"','')
+            fl_str = fl_str.split(', ')
+        for _id in friend_IDs:
+            if str(_id) in fl_str:
+                print('ID:', _id, 'is Already friend!!!')
+            else:
+                fl_str.append(str(_id))
+        fl_str = ', '.join(i for i in fl_str)
+        fl_str = '"' + fl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'FriendList'] = fl_str
+        return self.data[self.data['ID']==ID]
+    
+    def delete_friend(self, ID: int, friend_IDs: list):
+        fl_str = self.get_friendlist(ID)
+        fl_str = fl_str.replace('"','')
+        fl_str = fl_str.split(', ')
+        for _id in friend_IDs:
+            if str(_id) in fl_str:
+                fl_str.remove(str(_id))
+            else:
+                print('ID:', _id, 'not found in the friend list!!')
+        fl_str = ', '.join(i for i in fl_str)
+        fl_str = '"' + fl_str + '"'
+        index = self.data[self.data['ID']==ID].index[0]
+        self.data.at[index, 'FriendList'] = fl_str
+        return self.data[self.data['ID']==ID]
+
+

Ancestors

+ +

Methods

+
+
+def add_friend(self, ID: int, friend_IDs: list) +
+
+
+
+ +Expand source code + +
def add_friend(self, ID: int, friend_IDs: list):
+    fl_str = self.get_friendlist(ID)
+    if str(fl_str)=='nan':
+        fl_str = []
+    else:
+        fl_str = fl_str.replace('"','')
+        fl_str = fl_str.split(', ')
+    for _id in friend_IDs:
+        if str(_id) in fl_str:
+            print('ID:', _id, 'is Already friend!!!')
+        else:
+            fl_str.append(str(_id))
+    fl_str = ', '.join(i for i in fl_str)
+    fl_str = '"' + fl_str + '"'
+    index = self.data[self.data['ID']==ID].index[0]
+    self.data.at[index, 'FriendList'] = fl_str
+    return self.data[self.data['ID']==ID]
+
+
+
+def delete_friend(self, ID: int, friend_IDs: list) +
+
+
+
+ +Expand source code + +
def delete_friend(self, ID: int, friend_IDs: list):
+    fl_str = self.get_friendlist(ID)
+    fl_str = fl_str.replace('"','')
+    fl_str = fl_str.split(', ')
+    for _id in friend_IDs:
+        if str(_id) in fl_str:
+            fl_str.remove(str(_id))
+        else:
+            print('ID:', _id, 'not found in the friend list!!')
+    fl_str = ', '.join(i for i in fl_str)
+    fl_str = '"' + fl_str + '"'
+    index = self.data[self.data['ID']==ID].index[0]
+    self.data.at[index, 'FriendList'] = fl_str
+    return self.data[self.data['ID']==ID]
+
+
+
+def get_friend_names(self, ID) +
+
+
+
+ +Expand source code + +
def get_friend_names(self,ID):
+    friend_names = []
+    friend_ids = self.get_friendlist(ID)
+    for c in friend_ids:
+        try:
+            if int(c):
+                friend_id = int(c)
+                fname = self.get_name(friend_id)
+                sname = self.get_surname(friend_id)
+                aname = fname + " " + sname 
+                friend_names.append(aname)
+        except:
+            pass
+        
+    return friend_names
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/src/item.html b/src/item.html new file mode 100644 index 0000000..a4463cb --- /dev/null +++ b/src/item.html @@ -0,0 +1,240 @@ + + + + + + +item API documentation + + + + + + + + + + + +
+
+
+

Module item

+
+
+
+ +Expand source code + +
from item_manager import ItemManager
+class item():
+    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
+        if ID != None:
+            itemMan = ItemManager()
+            info = itemMan.get_item(ID)
+            if isinstance(info, int):
+                raise ValueError
+            else:  
+                self.title = info['Title']
+                self.desc = info['Description']
+                self.link = info['Link']
+                self.cost = info['Cost']
+                self.itemID = ID
+    
+        else:
+            self.title = title
+            self.desc = desc
+            self.link = link
+            self.cost = cost
+            self.itemID = int(self.create_item()['ItemID'])
+
+
+    
+    def create_item(self):
+        itemMan = ItemManager()
+        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
+        return item
+
+    def modify_item(self, title, desc, link, cost):
+        itemMan = ItemManager()
+        self.title = title
+        self.desc = desc
+        self.link = link
+        self.cost = cost
+        itemMan.update_item( self.itemID, title, desc, link, cost)
+    
+    def view_item(self):
+        itemMan = ItemManager()
+        return itemMan.get_item(self.itemID)
+
+    def delete_item(self):
+        itemMan = ItemManager()
+        itemMan.delete_item(self.itemID)
+
+
+
+# i = item('Football', 'NFL original', 'www.football.com', 50)
+# print(i.cost)
+# i.modify_item('Football', 'NFL original', 'www.football.com', 65)
+# print(i.view_item())
+# i.delete_item()
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class item +(title='', desc='', link='', cost='', ID=None) +
+
+
+
+ +Expand source code + +
class item():
+    def __init__(self, title = '', desc = '', link = '', cost = '', ID = None):
+        if ID != None:
+            itemMan = ItemManager()
+            info = itemMan.get_item(ID)
+            if isinstance(info, int):
+                raise ValueError
+            else:  
+                self.title = info['Title']
+                self.desc = info['Description']
+                self.link = info['Link']
+                self.cost = info['Cost']
+                self.itemID = ID
+    
+        else:
+            self.title = title
+            self.desc = desc
+            self.link = link
+            self.cost = cost
+            self.itemID = int(self.create_item()['ItemID'])
+
+
+    
+    def create_item(self):
+        itemMan = ItemManager()
+        item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
+        return item
+
+    def modify_item(self, title, desc, link, cost):
+        itemMan = ItemManager()
+        self.title = title
+        self.desc = desc
+        self.link = link
+        self.cost = cost
+        itemMan.update_item( self.itemID, title, desc, link, cost)
+    
+    def view_item(self):
+        itemMan = ItemManager()
+        return itemMan.get_item(self.itemID)
+
+    def delete_item(self):
+        itemMan = ItemManager()
+        itemMan.delete_item(self.itemID)
+
+

Methods

+
+
+def create_item(self) +
+
+
+
+ +Expand source code + +
def create_item(self):
+    itemMan = ItemManager()
+    item = itemMan.add_item(self.title, self.desc, self.link, self.cost)
+    return item
+
+
+
+def delete_item(self) +
+
+
+
+ +Expand source code + +
def delete_item(self):
+    itemMan = ItemManager()
+    itemMan.delete_item(self.itemID)
+
+
+
+def modify_item(self, title, desc, link, cost) +
+
+
+
+ +Expand source code + +
def modify_item(self, title, desc, link, cost):
+    itemMan = ItemManager()
+    self.title = title
+    self.desc = desc
+    self.link = link
+    self.cost = cost
+    itemMan.update_item( self.itemID, title, desc, link, cost)
+
+
+
+def view_item(self) +
+
+
+
+ +Expand source code + +
def view_item(self):
+    itemMan = ItemManager()
+    return itemMan.get_item(self.itemID)
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/src/item_manager.html b/src/item_manager.html new file mode 100644 index 0000000..c5ffeee --- /dev/null +++ b/src/item_manager.html @@ -0,0 +1,560 @@ + + + + + + +item_manager API documentation + + + + + + + + + + + +
+
+
+

Module item_manager

+
+
+
+ +Expand source code + +
from pandas import *
+import psycopg2
+from config import config
+
+class ItemManager:
+    # def __init__ (self):
+    #     try:
+    #         self.database = 'data/item_data - Copy.csv'
+    #         data = read_csv(self.database)
+    #     except: 
+    #         self.database = '../data/item_data - Copy.csv'
+
+    def add_item(self, title, desc = '', link = '',  cost = ''):
+        if title == '':
+            print('Title cannot be empty')
+            return -1
+        
+        query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
+        conn = None
+        ID = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (title, desc, link, cost))
+            ID = cur.fetchone()[0]
+            cur.close()
+            conn.commit()
+            cur.close()
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+                
+        return ID
+
+
+    def get_item(self, ID: int):
+        query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
+        conn = None
+        item_info = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (ID,))
+            item_info = cur.fetchall()
+            cur.close()
+            conn.commit()
+            cur.close()
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        
+        return item_info[0] if item_info else None
+        
+        
+        # data = read_csv(self.database)
+        # if data.loc[data['ItemID']==ID].empty:
+        #     print("Item does not exist")
+        #     return -1
+        # return (data.loc[data['ItemID'] == ID])
+
+    def delete_item(self, ID: int):
+        
+        query = """Delete From "Item" Where "ID" = %s;"""
+        conn = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (ID,))
+            cur.close()
+            conn.commit()
+            cur.close()        
+            print("Item deleted.")
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        return 0
+    
+        # cur.execute(query,(_id,))
+        # data = read_csv(self.database)
+        # if data.index[data['ItemID'] == ID].empty:
+        #     print("Item does not exist")
+        #     return -1
+        # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
+        # data.to_csv(self.database, mode='w', index=False)
+        # print("Item deleted.")
+        # return 0
+
+    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
+        
+        query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
+        conn = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (title,desc,link,cost,ID))
+            cur.close()
+            conn.commit()
+            cur.close()
+            print("Item Updated.")
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        
+        return 0
+        
+        
+        
+        # data = read_csv(self.database)
+        # item = data.loc[data['ItemID'] == ID]
+        # ind = data['ItemID'] == ID
+        # if data.loc[data['ItemID'] == ID].empty:
+        #     print('Item does not exist.')
+        #     return -1
+        # data.loc[ind,'Title'] = title
+        # data.loc[ind,'Description'] = desc
+        # data.loc[ind, 'Link'] = link
+        # data.loc[ind, 'Cost'] = cost
+        # data.to_csv(self.database, mode='w', index=False)
+        # print('Updated item')
+        # return 0
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class ItemManager +
+
+
+
+ +Expand source code + +
class ItemManager:
+    # def __init__ (self):
+    #     try:
+    #         self.database = 'data/item_data - Copy.csv'
+    #         data = read_csv(self.database)
+    #     except: 
+    #         self.database = '../data/item_data - Copy.csv'
+
+    def add_item(self, title, desc = '', link = '',  cost = ''):
+        if title == '':
+            print('Title cannot be empty')
+            return -1
+        
+        query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
+        conn = None
+        ID = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (title, desc, link, cost))
+            ID = cur.fetchone()[0]
+            cur.close()
+            conn.commit()
+            cur.close()
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+                
+        return ID
+
+
+    def get_item(self, ID: int):
+        query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
+        conn = None
+        item_info = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (ID,))
+            item_info = cur.fetchall()
+            cur.close()
+            conn.commit()
+            cur.close()
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        
+        return item_info[0] if item_info else None
+        
+        
+        # data = read_csv(self.database)
+        # if data.loc[data['ItemID']==ID].empty:
+        #     print("Item does not exist")
+        #     return -1
+        # return (data.loc[data['ItemID'] == ID])
+
+    def delete_item(self, ID: int):
+        
+        query = """Delete From "Item" Where "ID" = %s;"""
+        conn = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (ID,))
+            cur.close()
+            conn.commit()
+            cur.close()        
+            print("Item deleted.")
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        return 0
+    
+        # cur.execute(query,(_id,))
+        # data = read_csv(self.database)
+        # if data.index[data['ItemID'] == ID].empty:
+        #     print("Item does not exist")
+        #     return -1
+        # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
+        # data.to_csv(self.database, mode='w', index=False)
+        # print("Item deleted.")
+        # return 0
+
+    def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
+        
+        query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
+        conn = None
+        try:
+        # initializing connection
+            params = config()
+            print('Connecting to the PostgreSQL database...')
+            conn = psycopg2.connect(**params)
+            cur = conn.cursor()
+        # execute a statement
+            cur.execute(query, (title,desc,link,cost,ID))
+            cur.close()
+            conn.commit()
+            cur.close()
+            print("Item Updated.")
+            
+        except (Exception, psycopg2.DatabaseError) as error:
+            print(error)
+        finally:
+            if conn is not None:
+                conn.close()
+                print('Database connection closed.')
+        
+        return 0
+        
+        
+        
+        # data = read_csv(self.database)
+        # item = data.loc[data['ItemID'] == ID]
+        # ind = data['ItemID'] == ID
+        # if data.loc[data['ItemID'] == ID].empty:
+        #     print('Item does not exist.')
+        #     return -1
+        # data.loc[ind,'Title'] = title
+        # data.loc[ind,'Description'] = desc
+        # data.loc[ind, 'Link'] = link
+        # data.loc[ind, 'Cost'] = cost
+        # data.to_csv(self.database, mode='w', index=False)
+        # print('Updated item')
+        # return 0
+
+

Methods

+
+
+def add_item(self, title, desc='', link='', cost='') +
+
+
+
+ +Expand source code + +
def add_item(self, title, desc = '', link = '',  cost = ''):
+    if title == '':
+        print('Title cannot be empty')
+        return -1
+    
+    query = """Insert Into public."Item" ("Title","Description","Link","Cost") values(%s,%s,%s,%s) returning "ID" """
+    conn = None
+    ID = None
+    try:
+    # initializing connection
+        params = config()
+        print('Connecting to the PostgreSQL database...')
+        conn = psycopg2.connect(**params)
+        cur = conn.cursor()
+    # execute a statement
+        cur.execute(query, (title, desc, link, cost))
+        ID = cur.fetchone()[0]
+        cur.close()
+        conn.commit()
+        cur.close()
+        
+    except (Exception, psycopg2.DatabaseError) as error:
+        print(error)
+    finally:
+        if conn is not None:
+            conn.close()
+            print('Database connection closed.')
+            
+    return ID
+
+
+
+def delete_item(self, ID: int) +
+
+
+
+ +Expand source code + +
def delete_item(self, ID: int):
+    
+    query = """Delete From "Item" Where "ID" = %s;"""
+    conn = None
+    try:
+    # initializing connection
+        params = config()
+        print('Connecting to the PostgreSQL database...')
+        conn = psycopg2.connect(**params)
+        cur = conn.cursor()
+    # execute a statement
+        cur.execute(query, (ID,))
+        cur.close()
+        conn.commit()
+        cur.close()        
+        print("Item deleted.")
+    except (Exception, psycopg2.DatabaseError) as error:
+        print(error)
+    finally:
+        if conn is not None:
+            conn.close()
+            print('Database connection closed.')
+    return 0
+
+    # cur.execute(query,(_id,))
+    # data = read_csv(self.database)
+    # if data.index[data['ItemID'] == ID].empty:
+    #     print("Item does not exist")
+    #     return -1
+    # data = data.drop(data.index[data['ItemID'] == ID], axis = 0)
+    # data.to_csv(self.database, mode='w', index=False)
+    # print("Item deleted.")
+    # return 0
+
+
+
+def get_item(self, ID: int) +
+
+
+
+ +Expand source code + +
def get_item(self, ID: int):
+    query = """Select "Title","Description","Link","Cost" From "Item" WHERE "ID" = %s;"""
+    conn = None
+    item_info = None
+    try:
+    # initializing connection
+        params = config()
+        print('Connecting to the PostgreSQL database...')
+        conn = psycopg2.connect(**params)
+        cur = conn.cursor()
+    # execute a statement
+        cur.execute(query, (ID,))
+        item_info = cur.fetchall()
+        cur.close()
+        conn.commit()
+        cur.close()
+        
+    except (Exception, psycopg2.DatabaseError) as error:
+        print(error)
+    finally:
+        if conn is not None:
+            conn.close()
+            print('Database connection closed.')
+    
+    return item_info[0] if item_info else None
+    
+    
+    # data = read_csv(self.database)
+    # if data.loc[data['ItemID']==ID].empty:
+    #     print("Item does not exist")
+    #     return -1
+    # return (data.loc[data['ItemID'] == ID])
+
+
+
+def update_item(self, ID: int, title, desc='', link='', cost='') +
+
+
+
+ +Expand source code + +
def update_item(self, ID: int, title, desc = '', link = '', cost = ''):
+    
+    query = """UPDATE "Item" Set "Title" = %s, "Description" = %s, "Link" = %s, "Cost" = %s  Where "ID" = %s"""
+    conn = None
+    try:
+    # initializing connection
+        params = config()
+        print('Connecting to the PostgreSQL database...')
+        conn = psycopg2.connect(**params)
+        cur = conn.cursor()
+    # execute a statement
+        cur.execute(query, (title,desc,link,cost,ID))
+        cur.close()
+        conn.commit()
+        cur.close()
+        print("Item Updated.")
+        
+    except (Exception, psycopg2.DatabaseError) as error:
+        print(error)
+    finally:
+        if conn is not None:
+            conn.close()
+            print('Database connection closed.')
+    
+    return 0
+    
+    
+    
+    # data = read_csv(self.database)
+    # item = data.loc[data['ItemID'] == ID]
+    # ind = data['ItemID'] == ID
+    # if data.loc[data['ItemID'] == ID].empty:
+    #     print('Item does not exist.')
+    #     return -1
+    # data.loc[ind,'Title'] = title
+    # data.loc[ind,'Description'] = desc
+    # data.loc[ind, 'Link'] = link
+    # data.loc[ind, 'Cost'] = cost
+    # data.to_csv(self.database, mode='w', index=False)
+    # print('Updated item')
+    # return 0
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/src/main.py b/src/main.py index cf32b43..35f05ee 100644 --- a/src/main.py +++ b/src/main.py @@ -95,20 +95,6 @@ def create_account(): def account_page(): acc = st.session_state.account st.header('Welcome ' + acc.name + '!') - st.write("What a beautiful day to gift!") - if st.button('Profile'): - st.session_state.runpage = 'profile' - st.experimental_rerun() - if st.button('Wishlist'): - st.session_state.runpage = 'wishlist' - st.experimental_rerun() - if st.button('Friendlist'): - st.session_state.runpage = 'friendlist' - st.experimental_rerun() - if st.button('Logout'): - st.session_state.runpage = 'initial' - st.experimental_rerun() - st.header('Welcome ' + acc.name.to_string(index=False) + '!') st.write("Quote of the day:") if 'response' not in st.session_state: st.session_state.response = requests.get('https://zenquotes.io/api/today') @@ -220,6 +206,7 @@ def wishlist_page(): for (const element of forms) { element.classList.add("horizontalDiv"); element.parentElement.classList.add("horizontalDiv"); + } }) diff --git a/src/utils.py b/src/utils.py index a6ab4ad..bf58940 100644 --- a/src/utils.py +++ b/src/utils.py @@ -6,12 +6,12 @@ def inject_custom_css(): - with open('assets/styles.css') as f: + with open('src/assets/styles.css') as f: st.markdown(f'', unsafe_allow_html=True) def navbar_component(name): - with open("assets/images/profile.png", "rb") as image_file: + with open("src/assets/images/profile.png", "rb") as image_file: image_as_base64 = base64.b64encode(image_file.read()) navbar_items = '' @@ -36,7 +36,7 @@ def navbar_component(name): # nameTag = f'' nameTag = rf'''