diff --git a/.gitignore b/.gitignore index 935077e..c1a29ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__/* __pycache__ *.swp +*.json diff --git a/connect.py b/connect.py index d9e0adf..7bf2f16 100644 --- a/connect.py +++ b/connect.py @@ -8,14 +8,18 @@ class connect: def request(self, resource, host, itemtype, port=70): #connects to server and returns list with response type and body socket_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - socket_conn.settimeout(20.0) - socket_conn.connect((host, port)) - socket_conn.sendall((resource + '\r\n').encode('utf-8')) - if itemtype in ['I','p','g']: - response = socket_conn.makefile(mode = 'rb', errors = 'ignore') - else: - response = socket_conn.makefile(mode = 'r', errors = 'ignore') + try: + socket_conn.connect((host, port)) + socket_conn.sendall((resource + '\r\n').encode('utf-8')) + + if itemtype in ['I','p','g']: + response = socket_conn.makefile(mode = 'rb', errors = 'ignore') + else: + response = socket_conn.makefile(mode = 'r', errors = 'ignore') + except: + socket_conn.close() + return False try: self.raw_response = response.read() diff --git a/gui.py b/gui.py index 2ae690a..40431d4 100644 --- a/gui.py +++ b/gui.py @@ -20,6 +20,7 @@ class GUI: self.read_config() self.conn = conn() self.parser = parser() + self.search = None #colors self.FG = '#E0E2E4' @@ -92,7 +93,7 @@ class GUI: x.bind('', self.update_status) x.bind('', self.clear_status) x.config(activebackground=self.BG) - self.entry_url.bind('', self.execute_address) + self.entry_url.bind('', self.handle_request) self.btn_back.bind('', self.go_back) self.btn_forward.bind('', self.go_forward) self.btn_home.bind('', self.load_home_screen) @@ -139,36 +140,50 @@ class GUI: # ------------Start navigation methods---------------------------- + def handle_request(self,event=False, url=False, history=True): + url = url if url else self.entry_url.get() + parsed_url = self.parse_url(url) - def execute_address(self, event=False, btn_url=False, history=True): - url = btn_url if btn_url else self.entry_url.get() - if url == 'home': - adjust_history = None if btn_url else 1 - self.load_home_screen(adjust_history) - return True + if not parsed_url: + if url == 'home': + return self.load_home_screen(history) + else: + return False #error handling goes here + self.populate_url_bar(url) + + if history: + self.add_to_history(url) + + if parsed_url['type'] == '7': + self.show_search() + return False # display search + else: + data = self.execute_address(parsed_url) + if not data: + return False #error handling goes here + + self.send_to_screen(self.conn.raw_response,self.conn.filetype) + + + def parse_url(self, url=False): parsed_url = self.parser.parse_url(url) if not parsed_url: - # To do: build errors class to handle displaying errors - # return errors.url_error + # send error to screen + print('Error parsing URL') return False + return parsed_url - if parsed_url['type'] == '7': - self.send_to_screen(parsed_url, parsed_url['type']) - response = self.conn.request(self.parser.resource, self.parser.host, self.parser.filetype, self.parser.port) + def execute_address(self, url): + response = self.conn.request(url['resource'], url['host'], url['type'], url['port']) if not response: - # To do: build errors class to handle displaying errors - # return errors.connection_error_NUMBER + # send error to screen return False - if history: - self.history = self.history[:self.history_location+1] - self.history.append(url) - self.history_location = len(self.history) - 1 # Get the data to the screen self.site_display.focus_set() @@ -193,19 +208,17 @@ class GUI: element.tag_config(tag_name, background=self.ACTIVELINK) element.update_idletasks() # make sure change is visible time.sleep(.5) # optional delay to show changed text - self.entry_url.delete(0,tk.END) - self.entry_url.insert(tk.END,href) - success = self.execute_address() element.tag_config(tag_name, background=self.BG) # restore tag text style element.update_idletasks() + self.handle_request(False,href) - def load_home_screen(self,event=None): + def load_home_screen(self,event=False): with open('./home.gopher','r') as f: data = f.read() self.entry_url.delete(0, tk.END) self.entry_url.insert(tk.END, 'home') - if event is not None: + if event: self.add_to_history('home') self.send_to_screen(data, '1') @@ -216,8 +229,7 @@ class GUI: self.history_location -= 1 href = self.history[self.history_location] - self.populate_url_bar(href) - self.execute_address(False, href, False) + self.handle_request(False, href, False) def go_forward(self, event): @@ -226,8 +238,7 @@ class GUI: self.history_location += 1 href = self.history[self.history_location] - self.populate_url_bar(href) - self.execute_address(False, href, False) + self.handle_request(False, href, False) #-------------Start view methods---------------- @@ -238,6 +249,28 @@ class GUI: #soon add code to load in favorites here self.send_to_screen(data=header, clear=False) + def show_search(self): + text1 = ' __ ___ __ __\n/__` |__ /\ |__) / ` |__|\n.__/ |___ /~~\ | \ \__, | |\n\n\nPlease enter your search terms and press the enter key:\n\n' + self.search = tk.Entry(width='50') + self.search.bind('', self.query_search_engine) + self.site_display.config(state=tk.NORMAL) + self.site_display.delete(1.0, tk.END) + self.site_display.insert(tk.END,text1) + self.site_display.window_create(tk.END,window=self.search) + self.site_display.config(state=tk.DISABLED) + + + def query_search_engine(self, event): + base_url = self.entry_url.get() + base_url = base_url.replace('/7/','/1/',1) + query = self.search.get() + url = '{}\t{}'.format(base_url,query) + self.populate_url_bar(url) + self.handle_request(False, url) + self.search = None + + + def show_menu(self, data, clear=True): if not data: #error handling will go here @@ -318,13 +351,11 @@ class GUI: def send_to_screen(self, data, itemtype='1', clear=True): if itemtype == '0': self.show_text(data) - elif itemtype in ['1','3']: + elif itemtype in ['1','3','7']: data = self.parser.parse_menu(data) self.show_menu(data, clear) elif itemtype in ['p','I','g']: self.show_image(data) - elif itemtype == '7': - pass def update_status(self, event, href=False): diff --git a/parser.py b/parser.py index fc08caf..b6f8bc4 100644 --- a/parser.py +++ b/parser.py @@ -16,9 +16,13 @@ class parser: def parse_url(self, url): # Take in a URL and output a dict of the url parts - regex = r'^(?P(?:gopher:\/\/)?)?(?P[\w\.\d]+)(?P(?::\d+)?)?(?P(?:\/[\dgIp])?)?(?P(?:\/[\w\/\d\-?.]*)?)?$' + regex = r'^(?P(?:(gopher|http):\/\/)?)?(?P[\w\.\d]+)(?P(?::\d+)?)?(?P(?:\/[\dgIp])?)?(?P(?:\/.*)?)?$' match = re.match(regex, url) + + if not match: + return False + protocol = match.group('protocol') itemtype = match.group('type') host = match.group('host')