Ejemplo n.º 1
0
def check_newest_version(release_repo):
    try:
        from packaging import version as pk_version
        latest = get_releases('oskros/MF_counter_releases')[0]
        latest_ver = latest['tag_name']
        if pk_version.parse(version) < pk_version.parse(latest_ver):
            mbox(b1='OK', b2='', msg='Your version is not up to date. Get the newest release from', title='New version', hyperlink=release_repo)
    except Exception as e:
        print(e)
        pass
Ejemplo n.º 2
0
    def delete_archived_session(self):
        chosen = self.archive_dropdown.get()
        if chosen == '':
            # If nothing is selected the function returns
            return
        if chosen == 'Profile history':
            tk.messagebox.showerror('Error', 'You cannot delete profile history from here. Please delete all sessions manually, or delete the profile instead')
            return

        resp = tk_utils.mbox(msg='Type "DELETE" to confirm you wish to delete the session "%s" from archive\n\nIt will be permanently deleted' % chosen, title='WARNING', disabled_btn_input='DELETE')
        if resp == 'DELETE':
            if chosen == 'Active session':
                # Here we simply reset the timer module
                self.main_frame.ResetSession()
                self.main_frame.SaveActiveState()
                self.selected_archive.set('Profile history')
                self.update_descriptive_statistics()
            else:
                # Load the profile .json, delete the selected session and save the modified dictionary back to the .json
                cache = self.main_frame.load_state_file()
                removed = cache.pop(chosen, None)
                file = 'Profiles/%s.json' % self.active_profile.get()
                other_utils.atomic_json_dump(file, cache)

                # Update archive dropdown and descriptive statistics
                self.available_archive.remove(chosen)
                self.archive_dropdown['values'] = self.available_archive
                self.selected_archive.set('Profile history')
                self.tot_laps -= len(removed.get('laps', []))
                self.main_frame.timer_tab._set_laps(self.main_frame.timer_tab.is_running)
                self.update_descriptive_statistics()
            self.profile_dropdown['values'] = self.main_frame.sorted_profiles()
Ejemplo n.º 3
0
def check_newest_version(release_repo):
    try:
        from packaging import version as pk_version
        releases = get_releases('oskros/MF_run_counter')
        latest_ver = releases[0]['tag_name']
        if pk_version.parse(version) < pk_version.parse(latest_ver):
            mbox(b1='OK',
                 b2='',
                 msg=
                 'Your version is not up to date. Get the newest release from',
                 title='New version',
                 hyperlink=release_repo)
        return str(sum(r['assets'][0]['download_count'] for r in releases))
    except Exception as e:
        logging.debug(str(e))
        return ''
Ejemplo n.º 4
0
    def add_drop(self):
        drop = autocompletion.acbox(enable=True, title='Add drop')
        if not drop or drop['input'] == '':
            return
        if drop['item_name'] is not None:
            for i, item in enumerate(self.main_frame.grail_tab.grail):
                if item['Item'] == drop['item_name']:
                    if item.get('Found', False) is False:
                        if self.main_frame.auto_upload_herokuapp:
                            resp = self.main_frame.grail_tab.upload_to_herokuapp(
                                upd_dict={item['Item']: True},
                                show_confirm=False,
                                pop_up_msg="Congrats, a new drop! Add it to grail?\n\nHerokuapp login info:",
                                pop_up_title="Grail item")
                        else:
                            resp = tk_utils.mbox(msg="Congrats, a new drop! Add it to local grail?", title="Grail item")
                        if resp is not None:
                            self.main_frame.grail_tab.update_grail_from_index(i)
                            drop['input'] = '(*) ' + drop['input']
                    break

        run_no = len(self.main_frame.timer_tab.laps)
        if self.main_frame.timer_tab.is_running:
            run_no += 1

        self.drops.setdefault(str(run_no), []).append(drop)
        self.display_drop(drop=drop, run_no=run_no)
Ejemplo n.º 5
0
    def delete_archived_session(self):
        chosen = self.archive_dropdown.get()
        if chosen == '':
            # If nothing is selected the function returns
            return
        if chosen == 'Profile history':
            tk.messagebox.showerror('Error', 'You cannot delete profile history from here. Please delete all sessions manually, or delete the profile instead')
            return

        resp = tk_utils.mbox(msg='Do you really want to delete this session from archive? It will be permanently deleted', title='WARNING')
        if resp:
            if chosen == 'Active session':
                # Here we simply reset the timer module
                self.main_frame.ResetSession()
                self.main_frame.SaveActiveState()
                self.selected_archive.set('Profile history')
                self.update_descriptive_statistics()
            else:
                # Load the profile .json, delete the selected session and save the modified dictionary back to the .json
                cache = self.main_frame.load_state_file()
                # cache.setdefault('extra_data', dict())['Last update'] = time.time()
                removed = cache.pop(chosen, None)
                file = 'Profiles/%s.json' % self.active_profile.get()
                with open(file, 'w') as fo:
                    json.dump(cache, fo, indent=2)

                # Update archive dropdown and descriptive statistics
                self.available_archive.remove(chosen)
                self.archive_dropdown['values'] = self.available_archive
                self.selected_archive.set('Profile history')
                self.tot_laps -= len(removed.get('laps', []))
                self.main_frame.timer_tab._set_laps(self.main_frame.timer_tab.is_running)
                self.update_descriptive_statistics()
            self.profile_dropdown['values'] = self.main_frame.sorted_profiles()
Ejemplo n.º 6
0
    def delete_selected_run(self):
        if not self.m.curselection():
            return
        sel = self.m.selection_get()
        if tk_utils.mbox(msg='Do you want to delete the run:\n%s' % sel,
                         title='Warning'):
            all_runs = self.m.get(0, tk.END)
            sel_idx = all_runs.index(sel)

            self.laps.pop(sel_idx)
            self.m.delete(sel_idx, tk.END)

            for run in all_runs[sel_idx + 1:]:
                tmp = run[:run.find(':')]
                run_no = tmp[tmp.rfind(' ') + 1:]
                prev_no = str(int(run_no) - 1)
                if len(prev_no) < len(run_no):
                    self.m.insert(tk.END, run.replace(run_no, ' ' + prev_no,
                                                      1))
                else:
                    self.m.insert(tk.END, run.replace(run_no, prev_no, 1))
            self.m.yview_moveto(1)

            self._set_laps(add_lap=self.is_running)
            self._set_fastest()
            self._set_average()
Ejemplo n.º 7
0
 def reset_grail(self):
     resp = tk_utils.mbox(msg='Are you sure you want to reset the locally stored grail file?', title='WARNING')
     if resp:
         self.grail = self.create_empty_grail()
         self.update_statistics()
         if self.grail_table_open:
             self.select_from_filters()
         for var in dir(self):
             if var.startswith('grail_item'):
                 getattr(self, var).set(0)
Ejemplo n.º 8
0
    def ArchiveReset(self,
                     skip_confirm=False,
                     notify_msg=None,
                     stamp_from_epoch=None):
        """
        If any laps or drops have been recorded, this function saves the current session to the profile archive, and
        resets all info in the active session. In case no runs/drops are recorded, the session timer is simply reset
        """
        if not self.timer_tab.laps and not self.drops_tab.drops:
            self.ResetSession()
            return

        xc = self.root.winfo_rootx() - self.root.winfo_width() // 12
        yc = self.root.winfo_rooty() + self.root.winfo_height() // 3
        if notify_msg is not None:
            tk.messagebox.showinfo(title='Archive', message=notify_msg)
        if skip_confirm or tk_utils.mbox(
                'Would you like to save and reset session?',
                b1='Yes',
                b2='No',
                coords=[xc, yc],
                master_root=self.root):
            # Stop any active run and load current session info from timer and drop module.
            self.timer_tab.stop()
            active = self.timer_tab.save_state()
            self.profile_tab.tot_laps += len(active['laps'])
            active.update(self.drops_tab.save_state())
            active.update(self.advanced_stats_tracker.save_state())

            # Update session dropdown for the profile
            if stamp_from_epoch is None:
                stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            else:
                stamp = time.strftime("%Y-%m-%d %H:%M:%S",
                                      time.localtime(stamp_from_epoch))
            self.profile_tab.available_archive.append(stamp)
            self.profile_tab.archive_dropdown[
                'values'] = self.profile_tab.available_archive
            # self.profile_tab.update_descriptive_statistics()

            # Update profile .json with the session
            state = self.load_state_file()
            state['active_state'] = dict()
            state[stamp] = active
            state.setdefault('extra_data', dict())['Last update'] = time.time()

            file = 'Profiles/%s.json' % self.active_profile
            with open(file, 'w') as fo:
                json.dump(state, fo, indent=2)

            # When session has been successfully saved, the session is reset
            self.ResetSession()
Ejemplo n.º 9
0
    def _delete_profile(self):
        chosen = self.profile_dropdown.get()
        if chosen == '':
            # If nothing is selected the function returns
            return
        if len(self.profile_dropdown['values']) <= 1:
            tk.messagebox.showerror('Error', 'You need to have at least one profile, create a new profile before deleting this one.')
            return

        resp1 = tk_utils.mbox(msg='Are you sure you want to delete this profile?\nThis will permanently delete all records stored for the profile.', title='WARNING')
        if resp1 is True:
            resp2 = tk_utils.mbox(msg='Are you really really sure you want to delete the profile?\nFinal warning!', b1='Cancel', b2='OK', title='WARNING')
            if resp2 is False:  # False here because we switch buttons around in second confirmation
                file = 'Profiles/%s.json' % chosen
                os.remove(file)
                self.main_frame.profiles.remove(chosen)

                # We change active profile to an existing profile
                self.main_frame.active_profile = self.main_frame.profiles[0]
                self.active_profile.set(self.main_frame.profiles[0])
                self.profile_dropdown['values'] = self.main_frame.profiles
                self._change_active_profile()
Ejemplo n.º 10
0
    def delete_selected_drops(self):
        if self.focus_get()._name == 'droplist':
            cur_row = self.m.get('insert linestart', 'insert lineend+1c').strip()
            resp = tk_utils.mbox(msg='Do you want to delete the row:\n%s' % cur_row, title='Warning')
            if resp is True:
                sep = cur_row.find(':')
                run_no = cur_row[:sep].replace('Run ', '')
                drop = cur_row[sep+2:]
                try:
                    self.drops[run_no].remove(next(d for d in self.drops[run_no] if d['input'] == drop))
                    self.m.config(state=tk.NORMAL)
                    self.m.delete('insert linestart', 'insert lineend+1c')
                    self.m.config(state=tk.DISABLED)
                except StopIteration:
                    pass

            self.main_frame.img_panel.focus_force()
Ejemplo n.º 11
0
    def search_statistics(self):
        if not self.tabcontrol.select().endswith('frame'):
            return
        search_inp = tk_utils.mbox(msg="Search", entry=True)
        if search_inp is not None:
            cvar = tk.StringVar()
            start_pos = self.last_pos if self.last_src == search_inp else 1.0
            pos = self.txt_list.search(search_inp,
                                       start_pos,
                                       stopindex=tk.END,
                                       count=cvar)
            if pos:
                line = int(pos.split('.')[0])
                self.txt_list.see(pos)

                self.txt_list.tag_remove("search", 1.0, tk.END)
                self.txt_list.tag_add("search", f'{line}.0', f'{line+1}.0')
                self.last_src = search_inp
                self.last_pos = str(float(pos) + 0.1)
Ejemplo n.º 12
0
    def _delete_profile(self):
        chosen = self.profile_dropdown.get()
        if chosen == '':
            # If nothing is selected the function returns
            return
        if len(self.profile_dropdown['values']) <= 1:
            tk.messagebox.showerror('Error', 'You need to have at least one profile, create a new profile before deleting this one.')
            return

        resp = tk_utils.mbox(msg='Type "DELETE" to confirm you wish to delete the profile "%s"\n\nThis will permanently delete all records stored for the profile.' % chosen, title='WARNING', disabled_btn_input='DELETE')
        if resp == 'DELETE':
            file = 'Profiles/%s.json' % chosen
            os.remove(file)
            self.main_frame.profiles.remove(chosen)
            self.profile_dropdown['values'] = self.main_frame.profiles

            # We change active profile to an existing profile
            self.active_profile.set(self.main_frame.profiles[0])
            self._change_active_profile()
Ejemplo n.º 13
0
    def add_drop(self):
        drop = autocompletion.acbox(enable=True, title='Add drop', unid_mode=self.main_frame.autocompletion_unids, add_to_last_run=self.main_frame.add_to_last_run)
        if not drop or drop['input'] == '':
            return

        if drop['item_name'] is not None:
            for i, item in enumerate(self.main_frame.grail_tab.grail):
                if self.main_frame.autocompletion_unids:
                    base = ' '.join(drop['item_name'].split(' ')[:-1])
                    if base in NO_UNIQUE_MAP:
                        drop['TC'] = NO_UNIQUE_MAP[base].get('TC', '')
                        drop['Item Class'] = NO_UNIQUE_MAP[base].get('Item Class', '')
                        break
                    if base == item['Base Item']:
                        drop['TC'] = item.get('TC', '')
                        drop['Item Class'] = item.get('Item Class', '')
                        break

                if item['Item'] == drop['item_name']:
                    prefix = ''
                    drop['Grailer'] = 'False'
                    drop['Eth Grailer'] = ''
                    if item.get('Found', False) is False:
                        if self.main_frame.auto_upload_herokuapp:
                            resp = self.main_frame.grail_tab.upload_to_herokuapp(
                                upd_dict={item['Item']: True},
                                show_confirm=False,
                                pop_up_msg="Congrats, a new drop! Add it to grail?\n\nHerokuapp login info:",
                                pop_up_title="Grail item")
                        else:
                            resp = tk_utils.mbox(msg="Congrats, a new drop! Add it to local grail?", title="Grail item")
                        if resp is not None:
                            self.main_frame.grail_tab.update_grail_from_index(i)
                            prefix += '(*)'
                            drop['Grailer'] = 'True'

                    if drop.get('eth', False) is True:
                        drop['Eth Grailer'] = 'False'

                    if drop.get('eth', False) is True and item.get('FoundEth', False) is False:
                        if self.main_frame.auto_upload_herokuapp:
                            resp = self.main_frame.grail_tab.upload_to_herokuapp(
                                eth_dict={item['Item']: True},
                                show_confirm=False,
                                pop_up_msg="Congrats, a new eth drop! Add it to eth grail?\n\nHerokuapp login info:",
                                pop_up_title="Eth grail item")
                        else:
                            resp = tk_utils.mbox(msg="Congrats, a new eth drop! Add it to local eth grail?", title="Eth grail item")
                        if resp is not None:
                            self.main_frame.grail_tab.grail[i].update({'FoundEth': True})
                            prefix += '(*)'
                            drop['Eth Grailer'] = 'True'

                    drop['input'] = (prefix + ' ' + drop['input']).strip()
                    drop['TC'] = item.get('TC', '')
                    drop['QLVL'] = item.get('QLVL', '')
                    drop['Item Class'] = item.get('Item Class', '')
                    break

        last_run = drop.pop('last_run', False)
        run_no = len(self.main_frame.timer_tab.laps)
        if self.main_frame.timer_tab.is_running:
            run_no += 1
        if last_run and run_no > 0:
            run_no -= 1
        self.main_frame.add_to_last_run = last_run

        drop['Real time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        drop['Profile'] = self.main_frame.active_profile

        self.drops.setdefault(str(run_no), []).append(drop)
        self.display_drop(drop=drop, run_no=run_no)
Ejemplo n.º 14
0
try:
    import win32gui
    import logging
    import sys
    from utils import tk_utils
    from master_frame import MasterFrame

    if win32gui.FindWindow(None, 'MF run counter'):
        resp = tk_utils.mbox(msg='It seems like you already have an instance of MF Run Counter open.\n'
                                 'Opening another instance will make the app unstable (If this is a false positive, just ignore it)\n\n'
                                 'Do you wish to continue anyway?', title='WARNING')
        if not resp:
            sys.exit(0)

    MasterFrame()
except Exception as e:
    logging.exception(e)
    raise e
Ejemplo n.º 15
0
    def toggle_automode_btn(self, first=False, show_error=True):
        got_val = other_utils.safe_eval(self.automode_var.get())
        if first is False and self.main_frame.automode == got_val:
            return
        self.main_frame.automode = got_val

        if got_val == 1:
            self.gamemode_frame.pack(expand=False, fill=tk.X)
            self.gamemode_lab.pack(side=tk.LEFT)
            self.gamemode_cb.pack(side=tk.RIGHT)

            self.charname_frame.pack(expand=False, fill=tk.X)
            self.charname_text_lab.pack(side=tk.LEFT)
            self.charname_val_lab.pack(side=tk.RIGHT)

            self.sp_path_lab.pack(pady=[0, 0])
            self.sp_path_entry.pack(fill=tk.BOTH, padx=4)
            self.sp_path_frame.pack()
            self.sp_path_get.pack(side=tk.LEFT, padx=1)
            self.sp_path_apply.pack(side=tk.LEFT)

            self.mp_path_lab.pack(pady=[0, 0])
            self.mp_path_entry.pack(fill=tk.BOTH, padx=4)
            self.mp_path_frame.pack()
            self.mp_path_get.pack(side=tk.LEFT, padx=1)
            self.mp_path_apply.pack(side=tk.LEFT)
        else:
            self.gamemode_frame.forget()
            self.gamemode_lab.forget()
            self.gamemode_cb.forget()

            self.charname_frame.forget()
            self.charname_text_lab.forget()
            self.charname_val_lab.forget()

            self.sp_path_lab.forget()
            self.sp_path_entry.forget()
            self.sp_path_frame.forget()
            self.sp_path_get.forget()
            self.sp_path_apply.forget()

            self.mp_path_lab.forget()
            self.mp_path_entry.forget()
            self.mp_path_frame.forget()
            self.mp_path_get.forget()
            self.mp_path_apply.forget()

        if got_val == 2:
            if first is False and not tk_utils.mbox(
                    msg=
                    'Activating "Advanced automode" is highly discouraged when playing multiplayer, as it might result in a ban.\n\n'
                    'Explanation: Advanced automode utilizes "memory reading" of the D2 process\n'
                    'to discover information about the current game state, and this could be deemed cheating\n\n'
                    'If you still wish to continue, click "OK"'):
                self.automode_var.set('0')
                return self.toggle_automode_btn(first=first,
                                                show_error=show_error)
            else:
                self.main_frame.load_memory_reader(show_err=show_error)
                if self.main_frame.advanced_error_thrown:
                    self.automode_var.set('0')
                    return self.toggle_automode_btn(first=first,
                                                    show_error=show_error)
                else:
                    self.advanced_mode_stop.pack(expand=False,
                                                 fill=tk.X,
                                                 pady=[4, 0])
                    self.advanced_pause_on_esc_menu.pack(expand=False,
                                                         fill=tk.X)
                    self.advanced_automode_warning.pack(pady=6)
        else:
            if not first and self.main_frame.advanced_stats_caret.active:
                self.main_frame.advanced_stats_caret.invoke()
            self.advanced_automode_warning.forget()
            self.advanced_mode_stop.forget()
            self.advanced_pause_on_esc_menu.forget()
            self.main_frame.d2_reader = None

        if not first:
            self.main_frame.toggle_automode()