Read/write to files

This commit is contained in:
Ian Jauslin 2021-10-16 16:19:22 -04:00
parent 2d9e816980
commit bf26ef22a5
3 changed files with 146 additions and 2 deletions

View File

@ -77,7 +77,7 @@ class Command_prompt(Label):
# process command # process command
if keycode[1]=="enter": if keycode[1]=="enter":
self.insert=False self.insert=False
self.parse_argv() self.run_command()
self.set_text("") self.set_text("")
# move # move
@ -246,7 +246,7 @@ class Command_prompt(Label):
# check that cursor is in first argument # check that cursor is in first argument
if cursor[0]==1: if cursor[0]==1:
# complete filesystem path # complete filesystem path
self.append_text_at_cursor(self.complete_path(self.argv[1],cursor[1])) self.append_text_at_cursor(self.complete_path(self.argv[cursor[0]],cursor[1]))
# complete filesystem path # complete filesystem path
def complete_path(self,base,end): def complete_path(self,base,end):
@ -271,3 +271,72 @@ class Command_prompt(Label):
self.app.status_bar.raw_text+=name+" " self.app.status_bar.raw_text+=name+" "
self.app.status_bar.draw() self.app.status_bar.draw()
return os.path.commonprefix(paths)[end:] return os.path.commonprefix(paths)[end:]
# run command
def run_command(self):
# parse command line
self.parse_argv()
# write
if self.argv[0]=="w" or self.argv[0]=="w!" or self.argv[0]=="wq":
if len(self.argv)>2:
self.app.status_bar.set_text("error: could not write to file: too many arguments -- usage: ':w [path to file]'")
return
elif len(self.argv)==1:
if os.path.isfile(self.app.openfile):
self.app.painter.write(self.app.openfile)
else:
self.app.status_bar.set_text("error: no file is open for editing, specify a path")
return
else:
# check that the file is not a directory
if os.path.isdir(self.argv[1]):
self.app.status_bar.set_text("error: '"+self.argv[1]+"' is a directory")
return
# check that file does not already exist
elif self.argv[0]!="w!" and self.argv[1]!= self.app.openfile and os.path.isfile(self.argv[1]):
self.app.status_bar.set_text("error: '"+self.argv[1]+"' already exists (use ':w!' to overwrite)")
return
# check that the containing directory exists
elif len(os.path.dirname(self.argv[1]))>0 and not os.path.isdir(os.path.dirname(self.argv[1])):
self.app.status_bar.set_text("error: could not find directory '"+os.path.dirname(self.argv[1])+"'")
return
# check permissions
elif (len(os.path.dirname(self.argv[1]))>0 and not os.access(os.path.dirname(self.argv[1]),os.W_OK)) or (len(os.path.dirname(self.argv[1]))==0 and not os.access(os.getcwd(),os.W_OK)):
self.app.status_bar.set_text("error: permission denied")
return
else:
self.app.painter.write(self.argv[1])
# open file
if self.argv[0]=="e":
if len(self.argv)>2:
self.app.status_bar.set_text("error: could not open file: too many arguments -- usage: ':e <path to file>'")
return
elif len(self.argv)==1:
self.app.status_bar.set_text("error: could not open file: no argument found -- usage: ':e <path to file>'")
return
else:
# check that the file is not a directory
if os.path.isdir(self.argv[1]):
self.app.status_bar.set_text("error: '"+self.argv[1]+"' is a directory")
return
# check that the file exists
elif not os.path.isfile(self.argv[1]):
self.app.status_bar.set_text("error: could not find file '"+self.argv[1]+"'")
return
# check permissions
elif not os.access(self.argv[1],os.R_OK):
self.app.status_bar.set_text("error: permission denied")
return
else:
# select openfile
self.app.openfile=self.argv[1]
# read the file
self.app.painter.read(self.argv[1])
# quit
if self.argv[0]=="q" or self.argv=="wq":
self.app.stop()

View File

@ -310,4 +310,73 @@ class Cross_painter(Widget):
return self.check_move(candidate,cross) return self.check_move(candidate,cross)
# write configuration to file
def write(self,file):
ff=open(file,"w")
for cross in self.crosses:
ff.write("{:05.2f},{:05.2f};{:3.1f},{:3.1f},{:3.1f}\n".format(cross.pos.x,cross.pos.y,cross.color[0],cross.color[1],cross.color[2]))
ff.close()
# read configuration from file
def read(self,file):
self.crosses=[]
ff=open(file,"r")
# counter
i=0
for line in ff.readlines():
i+=1
# remove newline
line=line[:len(line)-1]
# ignore comments
if '#' in line:
line=line[:line.find('#')]
# ignore empty lines
if len(line)==0:
continue
entries=line.split(";")
# skip line if improperly formatted
if len(entries)>2:
print("warning: ignoring line "+str(i)+" in file '"+file+"': more than two ';' spearated entries in '"+line+"'",file=sys.stderr)
continue
# position
pos_str=entries[0].split(",")
# skip line if improperly formatted
if len(pos_str)!=2:
print("warning: ignoring line "+str(i)+" in file '"+file+"': position '"+entries[0]+"' does not have two components",file=sys.stderr)
continue
try:
pos=Point(float(pos_str[0]),float(pos_str[1]))
except:
print("warning: ignoring line "+str(i)+" in file '"+file+"': position '"+entries[0]+"' cannot be read",file=sys.stderr)
continue
# color
color=(0,0,1)
if len(entries)==2:
color_str=entries[1].split(",")
# skip line if improperly formatted
if len(color_str)!=3:
print("warning: ignoring line "+str(i)+" in file '"+file+"': color '"+entries[1]+"' does not have three components",file=sys.stderr)
continue
try:
color=(float(color_str[0]),float(color_str[1]),float(color_str[2]))
except:
print("warning: ignoring line "+str(i)+" in file '"+file+"': color '"+entries[1]+"' cannot be read",file=sys.stderr)
continue
if self.check_interaction_any(pos,None):
# add to list
self.crosses.append(Cross(pos.x,pos.y,color=color))
else:
print("warning: ignoring line "+str(i)+" in file '"+file+"': particle overlaps with existing particles",file=sys.stderr)
ff.close()
self.draw()

View File

@ -15,8 +15,14 @@ class Jam_app(App):
def build(self): def build(self):
layout=BoxLayout(orientation="vertical") layout=BoxLayout(orientation="vertical")
# the file open for editing
self.openfile=""
# painter
self.painter=Cross_painter(self) self.painter=Cross_painter(self)
# status bar
self.status_bar=Status_bar(self) self.status_bar=Status_bar(self)
# command prompt
self.command_prompt=Command_prompt(self) self.command_prompt=Command_prompt(self)
layout.add_widget(self.painter) layout.add_widget(self.painter)