Weekly visits now held in db
parent
105a95f92e
commit
d22b7d4b33
64
botany.py
64
botany.py
|
@ -15,9 +15,6 @@ from menu_screen import *
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# - Switch from personal data file to table in DB
|
# - Switch from personal data file to table in DB
|
||||||
# - Table in DB would allow others to modify (personal files might be
|
|
||||||
# permission locked)
|
|
||||||
# - this is a good idea.
|
|
||||||
|
|
||||||
class Plant(object):
|
class Plant(object):
|
||||||
# This is your plant!
|
# This is your plant!
|
||||||
|
@ -147,10 +144,6 @@ class Plant(object):
|
||||||
self.watered_24h = False
|
self.watered_24h = False
|
||||||
# visitors are coming
|
# visitors are coming
|
||||||
self.visitors = []
|
self.visitors = []
|
||||||
# TODO: manually checking for pending visitors
|
|
||||||
# TODO: clear visitors when checking
|
|
||||||
self.weekly_visitors = {}
|
|
||||||
# TODO: clear weekly visitors on sunday 00:00:00
|
|
||||||
|
|
||||||
def migrate_properties(self):
|
def migrate_properties(self):
|
||||||
# Migrates old data files to new
|
# Migrates old data files to new
|
||||||
|
@ -158,8 +151,6 @@ class Plant(object):
|
||||||
self.generation = 1
|
self.generation = 1
|
||||||
if not hasattr(self, 'visitors'):
|
if not hasattr(self, 'visitors'):
|
||||||
self.visitors = []
|
self.visitors = []
|
||||||
if not hasattr(self, 'weekly_visitors'):
|
|
||||||
self.weekly_visitors = {}
|
|
||||||
|
|
||||||
def parse_plant(self):
|
def parse_plant(self):
|
||||||
# Converts plant data to human-readable format
|
# Converts plant data to human-readable format
|
||||||
|
@ -209,30 +200,49 @@ class Plant(object):
|
||||||
self.dead = True
|
self.dead = True
|
||||||
return self.dead
|
return self.dead
|
||||||
|
|
||||||
|
def update_visitor_db(self, visitor_names):
|
||||||
|
game_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
garden_db_path = os.path.join(game_dir, 'sqlite/garden_db.sqlite')
|
||||||
|
conn = sqlite3.connect(garden_db_path)
|
||||||
|
for name in (visitor_names):
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT * FROM visitors WHERE garden_name = '{}' AND visitor_name = '{}' ".format(self.owner, name))
|
||||||
|
data=c.fetchone()
|
||||||
|
if data is None:
|
||||||
|
sql = """ INSERT INTO visitors (garden_name,visitor_name,weekly_visits) VALUES('{}', '{}',1)""".format(self.owner, name)
|
||||||
|
c.execute(sql)
|
||||||
|
else:
|
||||||
|
sql = """ UPDATE visitors SET weekly_visits = weekly_visits + 1 WHERE garden_name = '{}' AND visitor_name = '{}'""".format(self.owner, name)
|
||||||
|
c.execute(sql)
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
def guest_check(self):
|
def guest_check(self):
|
||||||
user_dir = os.path.expanduser("~")
|
user_dir = os.path.expanduser("~")
|
||||||
botany_dir = os.path.join(user_dir,'.botany')
|
botany_dir = os.path.join(user_dir,'.botany')
|
||||||
visitor_filepath = os.path.join(botany_dir,'visitors.json')
|
visitor_filepath = os.path.join(botany_dir,'visitors.json')
|
||||||
guest_data = {'latest_timestamp': 0, 'visitors': []}
|
latest_timestamp = 0
|
||||||
|
visitors_this_check = []
|
||||||
if os.path.isfile(visitor_filepath):
|
if os.path.isfile(visitor_filepath):
|
||||||
with open(visitor_filepath, 'r') as visitor_file:
|
with open(visitor_filepath, 'r') as visitor_file:
|
||||||
data = json.load(visitor_file)
|
data = json.load(visitor_file)
|
||||||
for element in data:
|
for element in data:
|
||||||
if element['user'] not in self.visitors:
|
if element['user'] not in self.visitors:
|
||||||
self.visitors.append(element['user'])
|
self.visitors.append(element['user'])
|
||||||
# counter for weekly visitors
|
if element['user'] not in visitors_this_check:
|
||||||
if element['user'] not in self.weekly_visitors:
|
visitors_this_check.append(element['user'])
|
||||||
self.weekly_visitors[element['user']] = 1
|
if element['timestamp'] > latest_timestamp:
|
||||||
else:
|
latest_timestamp = element['timestamp']
|
||||||
self.weekly_visitors[element['user']] += 1
|
with open(visitor_filepath, 'w') as visitor_file:
|
||||||
if element['timestamp'] > guest_data['latest_timestamp']:
|
visitor_file.write('[]')
|
||||||
guest_data['latest_timestamp'] = element['timestamp']
|
try:
|
||||||
with open(visitor_filepath, 'w') as visitor_file2:
|
self.update_visitor_db(visitors_this_check)
|
||||||
visitor_file2.write('[]')
|
except:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
with open(visitor_filepath, mode='w') as f:
|
with open(visitor_filepath, mode='w') as f:
|
||||||
json.dump([], f)
|
json.dump([], f)
|
||||||
return guest_data['latest_timestamp']
|
return latest_timestamp
|
||||||
|
|
||||||
def water_check(self):
|
def water_check(self):
|
||||||
latest_visitor_timestamp = self.guest_check()
|
latest_visitor_timestamp = self.guest_check()
|
||||||
|
@ -456,11 +466,25 @@ class DataManager(object):
|
||||||
open(self.garden_json_path, 'a').close()
|
open(self.garden_json_path, 'a').close()
|
||||||
os.chmod(self.garden_json_path, 0666)
|
os.chmod(self.garden_json_path, 0666)
|
||||||
|
|
||||||
|
def migrate_database(self):
|
||||||
|
conn = sqlite3.connect(self.garden_db_path)
|
||||||
|
migrate_table_string = """CREATE TABLE IF NOT EXISTS visitors (
|
||||||
|
id integer PRIMARY KEY,
|
||||||
|
garden_name text,
|
||||||
|
visitor_name text,
|
||||||
|
weekly_visits integer
|
||||||
|
)"""
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(migrate_table_string)
|
||||||
|
conn.close()
|
||||||
|
return True
|
||||||
|
|
||||||
def update_garden_db(self, this_plant):
|
def update_garden_db(self, this_plant):
|
||||||
# insert or update this plant id's entry in DB
|
# insert or update this plant id's entry in DB
|
||||||
# TODO: make sure other instances of user are deleted
|
# TODO: make sure other instances of user are deleted
|
||||||
# Could create a clean db function
|
# Could create a clean db function
|
||||||
self.init_database()
|
self.init_database()
|
||||||
|
self.migrate_database()
|
||||||
age_formatted = self.plant_age_convert(this_plant)
|
age_formatted = self.plant_age_convert(this_plant)
|
||||||
conn = sqlite3.connect(self.garden_db_path)
|
conn = sqlite3.connect(self.garden_db_path)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
139
menu_screen.py
139
menu_screen.py
|
@ -7,6 +7,7 @@ import time
|
||||||
import random
|
import random
|
||||||
import getpass
|
import getpass
|
||||||
import json
|
import json
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
class CursedMenu(object):
|
class CursedMenu(object):
|
||||||
#TODO: name your plant
|
#TODO: name your plant
|
||||||
|
@ -86,6 +87,7 @@ class CursedMenu(object):
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
# Draw the menu and lines
|
# Draw the menu and lines
|
||||||
|
self.maxy, self.maxx = self.screen.getmaxyx()
|
||||||
self.screen.refresh()
|
self.screen.refresh()
|
||||||
try:
|
try:
|
||||||
self.draw_default()
|
self.draw_default()
|
||||||
|
@ -130,32 +132,7 @@ class CursedMenu(object):
|
||||||
def draw_plant_ascii(self, this_plant):
|
def draw_plant_ascii(self, this_plant):
|
||||||
ypos = 1
|
ypos = 1
|
||||||
xpos = int((self.maxx-37)/2 + 25)
|
xpos = int((self.maxx-37)/2 + 25)
|
||||||
# TODO: pull this from botany class
|
plant_art_list = this_plant.species_list
|
||||||
plant_art_list = [
|
|
||||||
'poppy',
|
|
||||||
'cactus',
|
|
||||||
'aloe',
|
|
||||||
'flytrap',
|
|
||||||
'jadeplant',
|
|
||||||
'fern',
|
|
||||||
'daffodil',
|
|
||||||
'sunflower',
|
|
||||||
'baobab',
|
|
||||||
'lithops',
|
|
||||||
'hemp',
|
|
||||||
'pansy',
|
|
||||||
'iris',
|
|
||||||
'agave',
|
|
||||||
'ficus',
|
|
||||||
'moss',
|
|
||||||
'sage',
|
|
||||||
'snapdragon',
|
|
||||||
'columbine',
|
|
||||||
'brugmansia',
|
|
||||||
'palm',
|
|
||||||
'pachypodium',
|
|
||||||
]
|
|
||||||
|
|
||||||
if this_plant.dead == True:
|
if this_plant.dead == True:
|
||||||
self.ascii_render('rip.txt', ypos, xpos)
|
self.ascii_render('rip.txt', ypos, xpos)
|
||||||
elif this_plant.stage == 0:
|
elif this_plant.stage == 0:
|
||||||
|
@ -175,18 +152,18 @@ class CursedMenu(object):
|
||||||
def draw_default(self):
|
def draw_default(self):
|
||||||
# draws default menu
|
# draws default menu
|
||||||
clear_bar = " " * (int(self.maxx*2/3))
|
clear_bar = " " * (int(self.maxx*2/3))
|
||||||
self.screen.addstr(2, 2, self.title, curses.A_STANDOUT) # Title for this menu
|
self.screen.addstr(1, 2, self.title, curses.A_STANDOUT) # Title for this menu
|
||||||
self.screen.addstr(4, 2, self.subtitle, curses.A_BOLD) #Subtitle for this menu
|
self.screen.addstr(3, 2, self.subtitle, curses.A_BOLD) #Subtitle for this menu
|
||||||
# clear menu on screen
|
# clear menu on screen
|
||||||
for index in range(len(self.options)+1):
|
for index in range(len(self.options)+1):
|
||||||
self.screen.addstr(5+index, 4, clear_bar, curses.A_NORMAL)
|
self.screen.addstr(4+index, 4, clear_bar, curses.A_NORMAL)
|
||||||
# display all the menu items, showing the 'pos' item highlighted
|
# display all the menu items, showing the 'pos' item highlighted
|
||||||
for index in range(len(self.options)):
|
for index in range(len(self.options)):
|
||||||
textstyle = self.normal
|
textstyle = self.normal
|
||||||
if index == self.selected:
|
if index == self.selected:
|
||||||
textstyle = self.highlighted
|
textstyle = self.highlighted
|
||||||
self.screen.addstr(5+index ,4, clear_bar, curses.A_NORMAL)
|
self.screen.addstr(4+index ,4, clear_bar, curses.A_NORMAL)
|
||||||
self.screen.addstr(5+index ,4, "%d - %s" % (index+1, self.options[index]), textstyle)
|
self.screen.addstr(4+index ,4, "%d - %s" % (index+1, self.options[index]), textstyle)
|
||||||
|
|
||||||
self.screen.addstr(12, 2, clear_bar, curses.A_NORMAL)
|
self.screen.addstr(12, 2, clear_bar, curses.A_NORMAL)
|
||||||
self.screen.addstr(13, 2, clear_bar, curses.A_NORMAL)
|
self.screen.addstr(13, 2, clear_bar, curses.A_NORMAL)
|
||||||
|
@ -215,7 +192,6 @@ class CursedMenu(object):
|
||||||
water_string = "(" + (")" * water_left) + ("." * (10 - water_left)) + ") " + str(int(water_left_pct * 100)) + "% "
|
water_string = "(" + (")" * water_left) + ("." * (10 - water_left)) + ") " + str(int(water_left_pct * 100)) + "% "
|
||||||
return water_string
|
return water_string
|
||||||
|
|
||||||
|
|
||||||
def update_plant_live(self):
|
def update_plant_live(self):
|
||||||
# updates plant data on menu screen, live!
|
# updates plant data on menu screen, live!
|
||||||
while not self.exit:
|
while not self.exit:
|
||||||
|
@ -522,50 +498,85 @@ class CursedMenu(object):
|
||||||
pass
|
pass
|
||||||
self.clear_info_pane()
|
self.clear_info_pane()
|
||||||
|
|
||||||
def build_visitor_output(self, visitors):
|
def build_weekly_visitor_output(self, visitors):
|
||||||
visitor_block = ""
|
visitor_block = ""
|
||||||
visitor_line = ""
|
visitor_line = ""
|
||||||
if len(visitors) == 1:
|
for visitor in visitors:
|
||||||
visitor_block += str(visitors[0])
|
this_visitor_string = str(visitor) + "({}) ".format(visitors[str(visitor)])
|
||||||
else:
|
if len(visitor_line + this_visitor_string) > self.maxx-3:
|
||||||
for visitor in visitors[:-1]:
|
|
||||||
if visitor_block.count('\n') > self.maxy-12:
|
|
||||||
visitor_block += "and more"
|
|
||||||
break
|
|
||||||
if len(visitor_line + visitor) > self.maxx-4:
|
|
||||||
visitor_block += '\n'
|
visitor_block += '\n'
|
||||||
visitor_line = ""
|
visitor_line = ""
|
||||||
visitor_block += str(visitor) + ', '
|
visitor_block += this_visitor_string
|
||||||
visitor_line += str(visitor) + ', '
|
visitor_line += this_visitor_string
|
||||||
else:
|
|
||||||
visitor_block += "& " + str(visitors[-1])
|
|
||||||
visitor_line += "& " + str(visitors[-1])
|
|
||||||
return visitor_block
|
return visitor_block
|
||||||
|
|
||||||
|
def build_latest_visitor_output(self, visitors):
|
||||||
|
visitor_line = ""
|
||||||
|
for visitor in visitors:
|
||||||
|
if len(visitor_line + visitor) > self.maxx-10:
|
||||||
|
visitor_line += "and more"
|
||||||
|
break
|
||||||
|
visitor_line += visitor + ' '
|
||||||
|
return [visitor_line]
|
||||||
|
|
||||||
|
def get_weekly_visitors(self):
|
||||||
|
game_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
garden_db_path = os.path.join(game_dir, 'sqlite/garden_db.sqlite')
|
||||||
|
conn = sqlite3.connect(garden_db_path)
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT * FROM visitors WHERE garden_name = '{}' ORDER BY weekly_visits".format(self.plant.owner))
|
||||||
|
# if c.rowcount:
|
||||||
|
visitor_data = c.fetchall()
|
||||||
|
conn.close()
|
||||||
|
visitor_block = ""
|
||||||
|
visitor_line = ""
|
||||||
|
if visitor_data:
|
||||||
|
for visitor in visitor_data:
|
||||||
|
visitor_name = visitor[2]
|
||||||
|
weekly_visits = visitor[3]
|
||||||
|
this_visitor_string = "{}({}) ".format(visitor_name, weekly_visits)
|
||||||
|
if len(visitor_line + this_visitor_string) > self.maxx-3:
|
||||||
|
visitor_block += '\n'
|
||||||
|
visitor_line = ""
|
||||||
|
visitor_block += this_visitor_string
|
||||||
|
visitor_line += this_visitor_string
|
||||||
|
else:
|
||||||
|
visitor_block = 'nobody :('
|
||||||
|
return visitor_block
|
||||||
|
|
||||||
|
def get_user_string(self, xpos=3, ypos=15):
|
||||||
|
user_string = ""
|
||||||
|
user_input = 0
|
||||||
|
while user_input != 10:
|
||||||
|
user_input = self.screen.getch()
|
||||||
|
if user_input == 127:
|
||||||
|
if len(user_string) > 0:
|
||||||
|
user_string = user_string[:-1]
|
||||||
|
self.screen.addstr(15, 3, " " * (self.maxx-2) )
|
||||||
|
if user_input in range(256):
|
||||||
|
if chr(user_input).isalnum():
|
||||||
|
user_string += chr(user_input)
|
||||||
|
self.screen.addstr(ypos, xpos, str(user_string))
|
||||||
|
self.screen.refresh()
|
||||||
|
return user_string
|
||||||
|
|
||||||
def visit_handler(self):
|
def visit_handler(self):
|
||||||
self.clear_info_pane()
|
self.clear_info_pane()
|
||||||
self.draw_info_text("whose plant would you like to visit?")
|
self.draw_info_text("whose plant would you like to visit?")
|
||||||
self.screen.addstr(15, 2, '~')
|
self.screen.addstr(15, 2, '~')
|
||||||
if self.plant.visitors:
|
if self.plant.visitors:
|
||||||
self.draw_info_text("you've been visited by: ", 4)
|
latest_visitor_string = self.build_latest_visitor_output(self.plant.visitors)
|
||||||
visitor_text = self.build_visitor_output(self.plant.visitors)
|
self.draw_info_text("since last time, you were visited by: ", 3)
|
||||||
self.draw_info_text(visitor_text, 5)
|
self.draw_info_text(latest_visitor_string, 4)
|
||||||
self.plant.visitors = []
|
self.plant.visitors = []
|
||||||
|
weekly_visitor_text = self.get_weekly_visitors()
|
||||||
guest_garden = ""
|
self.draw_info_text("this week you've been visited by: ", 6)
|
||||||
user_input = 0
|
self.draw_info_text(weekly_visitor_text, 7)
|
||||||
while user_input != 10:
|
# user input section (can't get getstr to work)
|
||||||
user_input = self.screen.getch()
|
guest_garden = self.get_user_string()
|
||||||
if user_input == 127:
|
if not guest_garden:
|
||||||
if len(guest_garden) > 0:
|
self.clear_info_pane()
|
||||||
guest_garden = guest_garden[:-1]
|
return None
|
||||||
self.screen.addstr(15, 3, " " * (self.maxx-2) )
|
|
||||||
if user_input in range(256):
|
|
||||||
if chr(user_input).isalnum():
|
|
||||||
guest_garden += chr(user_input)
|
|
||||||
self.screen.addstr(15, 3, str(guest_garden))
|
|
||||||
self.screen.refresh()
|
|
||||||
# test if user exists and has botany directory and file
|
|
||||||
home_folder = os.path.dirname(os.path.expanduser("~"))
|
home_folder = os.path.dirname(os.path.expanduser("~"))
|
||||||
guest_json = home_folder + "/{}/.botany/{}_plant_data.json".format(guest_garden, guest_garden)
|
guest_json = home_folder + "/{}/.botany/{}_plant_data.json".format(guest_garden, guest_garden)
|
||||||
guest_plant_description = ""
|
guest_plant_description = ""
|
||||||
|
|
Loading…
Reference in New Issue