Exemple #1
0
class view:
    def __init__(self, f):
        self.bgc = "white"
        self.form = f
        self.presenter = present(self)
        self.place_startpage()

##############################################################################
# 1. Start page

    def init_startpage(self):
        table_headings = ["Название", "Длина", "Дата создания"]

        self.route_table = Treeview(self.form, selectmode="browse", \
         show='headings', height = 25)

        self.route_table["columns"] = table_headings
        self.route_table["displaycolumns"] = table_headings

        for head in table_headings:
            self.route_table.heading(head, text=head, anchor=CENTER)

        colomn_width = 200
        self.route_table.column("Название", anchor=CENTER, width=colomn_width)
        self.route_table.column("Длина", anchor=CENTER, width=colomn_width)
        self.route_table.column("Дата создания",
                                anchor=CENTER,
                                width=colomn_width)

        self.about_route_button = Button(self.form, text="Подробно",\
         width=15,height=3, command=self.about_route)

        self.delete_route_button = Button(self.form, text='Удалить',\
         width=15,height=3, command=self.delete_route)

        self.create_route_button = Button(self.form, text='Создать',\
         width=15,height=3, command=self.create_route)

        self.import_route_button = Button(self.form, text='Импорт',\
         width=15,height=3, command=self.import_route)

        self.presenter.fill_routes_table()

    def about_route(self):
        self.remove_startpage()
        self.place_about_route()

    def delete_route(self):
        pass

    def create_route(self):
        self.remove_startpage()
        self.place_create_route()

    def import_route(self):
        pass

    def place_startpage(self):
        self.init_startpage()
        but_y = 530
        self.route_table.place(x=100, y=0)
        self.about_route_button.place(x=0, y=but_y)
        self.delete_route_button.place(x=220, y=but_y)
        self.create_route_button.place(x=430, y=but_y)
        self.import_route_button.place(x=650, y=but_y)

    def remove_startpage(self):
        self.route_table.destroy()
        self.about_route_button.destroy()
        self.delete_route_button.destroy()
        self.create_route_button.destroy()
        self.import_route_button.destroy()

##############################################################################
# 2. About route

    def init_about_route(self):
        table_headings = ["№ точки", "Долгота", "Широта", "Высота"]

        self.point_table = Treeview(self.form, selectmode="browse", \
         show='headings', height = 25)

        self.point_table["columns"] = table_headings
        self.point_table["displaycolumns"] = table_headings

        for head in table_headings:
            self.point_table.heading(head, text=head, anchor=CENTER)

        colomn_width = 150
        self.point_table.column("№ точки", anchor=CENTER, width=colomn_width)
        self.point_table.column("Долгота", anchor=CENTER, width=colomn_width)
        self.point_table.column("Широта", anchor=CENTER, width=colomn_width)
        self.point_table.column("Высота", anchor=CENTER, width=colomn_width)

        self.edit_point_button = Button(self.form, text="Редактировать",\
         width=15,height=3, command=self.edit_point)

        self.back_from_point_to_start_button = Button(self.form, text='Назад',\
         width=15,height=3, command=self.back_from_point_to_start)

        self.point_edit_entry = Text(self.form,
                                     height=1.2,
                                     width=16,
                                     font='Arial 12')

        #self.presenter.

    def edit_point(self):
        pass

    def back_from_point_to_start(self):
        self.remove_about_route()
        self.place_startpage()

    def place_about_route(self):
        self.init_about_route()
        self.point_table.place(x=100, y=0)
        self.edit_point_button.place(x=250, y=530)
        self.back_from_point_to_start_button.place(x=550, y=530)
        self.point_edit_entry.place(x=70, y=547)

    def remove_about_route(self):
        self.point_table.destroy()
        self.edit_point_button.destroy()
        self.back_from_point_to_start_button.destroy()
        self.point_edit_entry.destroy()

##############################################################################
# 2. About route

    def init_create_route(self):
        table_headings = ["№ точки", "Долгота", "Широта", "Высота"]

        self.point_table_create = Treeview(self.form, selectmode="browse", \
         show='headings', height = 25)

        self.point_table_create["columns"] = table_headings
        self.point_table_create["displaycolumns"] = table_headings

        for head in table_headings:
            self.point_table_create.heading(head, text=head, anchor=CENTER)

        colomn_width = 150
        self.point_table_create.column("№ точки",
                                       anchor=CENTER,
                                       width=colomn_width)
        self.point_table_create.column("Долгота",
                                       anchor=CENTER,
                                       width=colomn_width)
        self.point_table_create.column("Широта",
                                       anchor=CENTER,
                                       width=colomn_width)
        self.point_table_create.column("Высота",
                                       anchor=CENTER,
                                       width=colomn_width)

        self.add_point_button = Button(self.form, text="Добавить",\
         width=15,height=3, command=self.add_point)

        self.save_route_button = Button(self.form, text='Сохранить',\
         width=15,height=3, command=self.save_route)

        self.new_route_name_entry = Text(self.form,
                                         height=1.2,
                                         width=16,
                                         font='Arial 12')

        self.new_route_name_label = Label(text='Имя маршрута:',\
                font = 'Arial 16', bg = self.bgc)

        self.new_point_entry = Text(self.form,
                                    height=1.2,
                                    width=16,
                                    font='Arial 12')

    def add_point(self):
        pass

    def save_route(self):
        pass

    def place_create_route(self):
        self.init_create_route()
        self.point_table_create.place(x=100, y=50)
        self.add_point_button.place(x=200, y=610)
        self.save_route_button.place(x=450, y=600)
        self.new_route_name_label.place(x=225, y=0)
        self.new_route_name_entry.place(x=380, y=4)
        self.new_point_entry.place(x=200, y=580)

##############################################################################
# Interfaces

    def insert_into_route_table(self, routes):
        for i in range(len(routes)):
            self.route_table.insert('', END, values=tuple(routes[i]))
Exemple #2
0
class user:
    def __init__(self, root, background_color, user_login, cursor):
        self.r = root
        self.bgc = background_color
        self.login = user_login
        self.cur = cursor

        self.cur.execute(
            "select client_id from client where client_login = '******';")
        tmp = self.cur.fetchall()
        self.userid = tmp[0][0]

        self.today_date = '{0:%Y-%m-%d %H:%M:%S} '.format(
            datetime.datetime.now())

##############################################################################
# 1. START

# 1.1 INIT

    def init_start_widgets(self):
        self.choose_button = Button(self.r,
                                    text="Записаться",
                                    width=20,
                                    height=7,
                                    command=self.choose)
        self.my_workouts_button = Button(self.r,
                                         text="Мои занятия",
                                         width=20,
                                         height=7,
                                         command=self.show_my_workouts)

    # 1.2 PLACE
    def place_start(self):
        self.init_start_widgets()
        self.choose_button.place(x=200, y=240)
        self.my_workouts_button.place(x=400, y=240)

    # 1.3 REMOVE
    def remove_start(self):
        self.choose_button.destroy()
        self.my_workouts_button.destroy()

    # 1.4 COMMANDS
    def choose(self):
        self.remove_start()
        self.place_choose()

    def show_my_workouts(self):
        self.remove_start()
        self.place_my_worklouts()

##############################################################################

##############################################################################
# 2. CHOOSE CLUB AND KIND OF SPORT

# 2.1 INIT

    def init_choose_widgets(self, root):
        self.choose_label = Label(text='Выберите клуб и вид спорта:',\
                font = 'Arial 20', bg = self.bgc)

        q = get_all_clubs()
        self.cur.execute(q)
        tmp = self.cur.fetchall()

        clubs = []

        for i in range(len(tmp)):
            clubs.append(tmp[i][0])

        self.variable_c = StringVar(root)
        self.variable_c.set(clubs[0])  # default value
        self.clubs_option_menu = OptionMenu(root, self.variable_c, *clubs)
        self.clubs_option_menu.config(width=20, height=3, bg=self.bgc, font=16)

        q = get_all_sports()
        self.cur.execute(q)
        tmp = self.cur.fetchall()

        kind_of_sport = []

        for i in range(len(tmp)):
            kind_of_sport.append(tmp[i][0])

        self.variable_k = StringVar(root)
        self.variable_k.set(kind_of_sport[0])
        self.kind_of_sport_option_menu = OptionMenu(root, self.variable_k,
                                                    *kind_of_sport)
        self.kind_of_sport_option_menu.config(width=20,
                                              height=3,
                                              bg=self.bgc,
                                              font=16)

        self.next_in_choose_button = Button(root, text='Далее',width=15,\
         height=3,command=self.next_in_choose)

        self.back_to_start_button = Button(root, text='Назад',width=15,height=3,\
         command=self.back_to_start)

    # 2.2 PLACE
    def place_choose(self):
        self.init_choose_widgets(self.r)
        self.choose_label.place(x=200, y=160)
        self.clubs_option_menu.place(x=260, y=200)
        self.kind_of_sport_option_menu.place(x=260, y=300)
        self.next_in_choose_button.place(x=305, y=400)
        self.back_to_start_button.place(x=305, y=500)

    # 2.3 REMOVE
    def remove_choose(self):
        self.choose_label.destroy()
        self.clubs_option_menu.destroy()
        self.kind_of_sport_option_menu.destroy()
        self.next_in_choose_button.destroy()
        self.back_to_start_button.destroy()

    # 2.3 COMMANDS
    def next_in_choose(self):
        club = self.variable_c.get()
        kind_of_sport = self.variable_k.get()
        self.remove_choose()
        self.place_trainlist(club, kind_of_sport)

    def back_to_start(self):
        self.remove_choose()
        self.place_start()

##############################################################################

##############################################################################
# 3. TRAINLIST

# 3.1 INIT

    def init_trainlist_widgets(self, root, club, sport):
        headings = ["вид спорта", "тренер", "рейтинг","тип", "места", "дата",\
        "длительность"]

        self.trains_table = Treeview(root,
                                     selectmode="browse",
                                     show='headings',
                                     height=25)
        self.trains_table["columns"] = headings
        self.trains_table["displaycolumns"] = headings

        for head in headings:
            self.trains_table.heading(head, text=head, anchor=CENTER)

        self.trains_table.column("вид спорта", anchor=CENTER, width=180)
        self.trains_table.column("тренер", anchor=CENTER, width=180)
        self.trains_table.column("рейтинг", anchor=CENTER, width=70)
        self.trains_table.column("тип", anchor=CENTER, width=40)
        self.trains_table.column("места", anchor=CENTER, width=60)
        self.trains_table.column("дата", anchor=CENTER, width=145)
        self.trains_table.column("длительность", anchor=CENTER, width=120)

        q = get_actual_workouts(self.userid, self.today_date, club, sport)
        self.cur.execute(q)
        tmp = self.cur.fetchall()
        self.w_ids = []

        for train in tmp:
            train = list(train)
            poped = train.pop(len(train) - 1)
            self.w_ids.append(poped)
            self.trains_table.insert('', END, values=tuple(train))

        self.choose_train_button = Button(root,
                                          text="Выбрать",
                                          width=15,
                                          height=3,
                                          command=self.choose_train)
        self.back_to_choose_button = Button(root, text='Назад',width=15,height=3,\
         command=self.back_to_choose)

    # 3.2 PLACE
    def place_trainlist(self, club, kind_of_sport):
        self.init_trainlist_widgets(self.r, club, kind_of_sport)
        self.trains_table.place(x=0, y=0)
        self.choose_train_button.place(x=320, y=530)
        self.back_to_choose_button.place(x=0, y=530)

    # 3.3 REMOVE
    def remove_trainlist(self):
        self.trains_table.destroy()
        self.choose_train_button.destroy()
        self.back_to_choose_button.destroy()

    # 3.4 COMMANDS
    def choose_train(self):
        indd = self.trains_table.focus()
        if indd == "":
            messagebox.showinfo("", "Выберите тренировку")
        else:
            ind = int(convert_base(indd[1:], to_base=10, from_base=16)) - 1
            curr_workout_id = self.w_ids[ind]

            q = generate_insert_into_client_workout(self.userid,
                                                    curr_workout_id)
            self.cur.execute(q)

            q = generate_update_for_places_count(curr_workout_id)
            self.cur.execute(q)

            self.remove_trainlist()
            self.place_start()
            messagebox.showinfo("", "Подтверждено")

    def back_to_choose(self):
        self.remove_trainlist()
        self.place_choose()

##############################################################################

##############################################################################
# 4. MY_WORKOUTS

# 4.1 INIT

    def init_my_workouts_widgets(self, root):
        self.my_workouts_label = Label(text='Мои занятия:',\
                font = 'Arial 20', bg = self.bgc)
        self.past_workouts_button = Button(root,text="Прошедшие",width=17,height=10,\
         command=self.show_past)
        self.future_workouts_button = Button(root,text="Предстоящие",width=17,height=10,\
         command=self.show_future)
        self.back_to_start_button2 = Button(root, text='Назад',width=17,height=3,\
         command=self.back_to_start2)

    # 4.2 PLACE
    def place_my_worklouts(self):
        self.init_my_workouts_widgets(self.r)
        self.my_workouts_label.place(x=315, y=80)
        self.past_workouts_button.place(x=315, y=120)
        self.future_workouts_button.place(x=315, y=300)
        self.back_to_start_button2.place(x=315, y=500)

    # 4.3 REMOVE
    def remove_my_workouts(self):
        self.my_workouts_label.destroy()
        self.past_workouts_button.destroy()
        self.future_workouts_button.destroy()
        self.back_to_start_button2.destroy()

    # 4.4 COMMANDS
    def show_past(self):
        self.remove_my_workouts()
        self.place_past_workouts()

    def show_future(self):
        self.remove_my_workouts()
        self.place_future_workouts()

    def back_to_start2(self):
        self.remove_my_workouts()
        self.place_start()

##############################################################################

##############################################################################
# 5. PAST WORKOUTS

# 5.1 INIT

    def init_past_workouts_widgets(self, root):
        self.past_workouts_table = Treeview(root,
                                            selectmode="browse",
                                            show='headings',
                                            height=25)

        headings = [
            "клуб", "вид спорта", "тренер", "дата", "длительность",
            "ваша оценка"
        ]

        self.past_workouts_table["columns"] = headings
        self.past_workouts_table["displaycolumns"] = headings

        for head in headings:
            self.past_workouts_table.heading(head, text=head, anchor=CENTER)

        self.past_workouts_table.column("клуб", anchor=CENTER, width=115)
        self.past_workouts_table.column("вид спорта", anchor=CENTER, width=155)
        self.past_workouts_table.column("тренер", anchor=CENTER, width=165)
        self.past_workouts_table.column("дата", anchor=CENTER, width=135)
        self.past_workouts_table.column("длительность",
                                        anchor=CENTER,
                                        width=110)
        self.past_workouts_table.column("ваша оценка",
                                        anchor=CENTER,
                                        width=125)

        q = get_user_past_workouts(self.userid, self.today_date)
        self.cur.execute(q)
        tmp = self.cur.fetchall()
        self.w_ids_for_rating = []

        for train in tmp:
            train = list(train)
            poped = train.pop(len(train) - 1)
            self.w_ids_for_rating.append(poped)
            self.past_workouts_table.insert('', END, values=tuple(train))

        self.set_rating_button = Button(root,text="Поставить оценку",width=15,height=1, \
         command=self.set_rating)
        self.back_to_my_workouts_button = Button(root, text='Назад',width=15,height=3,\
         command=self.back_to_my_workouts)

        self.rating_entry = Text(root, height=1.2, width=16, font='Arial 12')

    # 5.2 PLACE
    def place_past_workouts(self):
        self.init_past_workouts_widgets(self.r)
        self.past_workouts_table.place(x=0, y=0)
        self.set_rating_button.place(x=320, y=530)
        self.back_to_my_workouts_button.place(x=0, y=530)
        self.rating_entry.place(x=320, y=560)

    # 5.3 REMOVE
    def remove_past_workouts(self):
        self.past_workouts_table.destroy()
        self.set_rating_button.destroy()
        self.back_to_my_workouts_button.destroy()
        self.rating_entry.destroy()

    # 5.4 COMMANDS
    def set_rating(self):
        indd = self.past_workouts_table.focus()

        if indd == "":
            messagebox.showinfo("", "Выберите тренировку")
        else:
            ind = int(convert_base(indd[1:], to_base=10, from_base=16)) - 1
            curr_workout_id = self.w_ids_for_rating[ind]

            q = get_current_workout_rating(self.userid, curr_workout_id)
            self.cur.execute(q)
            tmp = self.cur.fetchall()
            current_train_rating = tmp[0][0]

            if current_train_rating == " ":
                input_rating = self.rating_entry.get('1.0', 'end-1c')
                if input_rating.replace(".", "", 1).isdigit() == False:
                    messagebox.showinfo("", "Оценка введена некоректно")
                elif float(input_rating) < 0 or float(input_rating) > 5:
                    messagebox.showinfo(
                        "", "Оценка ставиться по пятибальной шкале")
                else:
                    input_rating = round(float(input_rating), 2)
                    q = update_rating(self.userid, curr_workout_id,
                                      input_rating)
                    self.cur.execute(q)

                    q = get_current_coach_id_rating(curr_workout_id)
                    self.cur.execute(q)
                    tmp = self.cur.fetchall()

                    tmp_coach_id = int(tmp[0][0])
                    tmp_coach_rating = tmp[0][1]
                    tmp_coach_marked_w_count = tmp[0][2]

                    new_rating = (tmp_coach_rating * tmp_coach_marked_w_count +
                                  input_rating) / (tmp_coach_marked_w_count +
                                                   1)
                    q = update_coach_rating(tmp_coach_id, new_rating)
                    self.cur.execute(q)

                    self.remove_past_workouts()
                    self.place_past_workouts()
            else:
                messagebox.showinfo(
                    "",
                    "Оценка уже выставлена. В соответствии с нашими правилами оценка выставляется один раз и не подлежит изменению"
                )

    def back_to_my_workouts(self):
        self.remove_past_workouts()
        self.place_my_worklouts()

##############################################################################

##############################################################################
# 6. FUTURE WORKOUTS

# 6.1 INIT

    def init_future_workouts_widgets(self, root):
        self.future_workouts_table = Treeview(root,
                                              selectmode="browse",
                                              show='headings',
                                              height=25)

        headings = [
            "клуб", "вид спорта", "тренер", "дата", "длительность", "рейтинг"
        ]

        self.future_workouts_table["columns"] = headings
        self.future_workouts_table["displaycolumns"] = headings

        for head in headings:
            self.future_workouts_table.heading(head, text=head, anchor=CENTER)

        self.future_workouts_table.column("клуб", anchor=CENTER, width=115)
        self.future_workouts_table.column("вид спорта",
                                          anchor=CENTER,
                                          width=155)
        self.future_workouts_table.column("тренер", anchor=CENTER, width=165)
        self.future_workouts_table.column("дата", anchor=CENTER, width=150)
        self.future_workouts_table.column("длительность",
                                          anchor=CENTER,
                                          width=110)
        self.future_workouts_table.column("рейтинг", anchor=CENTER, width=110)

        q = get_user_future_workouts(self.userid, self.today_date)
        self.cur.execute(q)
        tmp = self.cur.fetchall()
        self.w_ids_for_remove_workout = []

        for train in tmp:
            train = list(train)
            poped = train.pop(len(train) - 1)
            self.w_ids_for_remove_workout.append(poped)
            self.future_workouts_table.insert('', END, values=tuple(train))

        self.remove_workout_button = Button(root,
                                            text="Отменить тренировку",
                                            width=15,
                                            height=3,
                                            command=self.remove_workout)
        self.back_to_my_workouts_button2 = Button(root, text='Назад',width=15,height=3,\
         command=self.back_to_my_workouts2)

    # 6.2 PLACE
    def place_future_workouts(self):
        self.init_future_workouts_widgets(self.r)
        self.future_workouts_table.place(x=0, y=0)
        self.remove_workout_button.place(x=300, y=530)
        self.back_to_my_workouts_button2.place(x=0, y=530)

    # 6.3 REMOVE
    def remove_future_workouts(self):
        self.future_workouts_table.destroy()
        self.remove_workout_button.destroy()
        self.back_to_my_workouts_button2.destroy()

    # 6.4 COMMANDS
    def remove_workout(self):
        indd = self.future_workouts_table.focus()
        if indd == "":
            messagebox.showinfo("", "Выберите тренировку")
        else:
            ind = int(convert_base(indd[1:], to_base=10, from_base=16)) - 1
            curr_workout_id = self.w_ids_for_remove_workout[ind]

            q = delete_cancel_workout(self.userid, curr_workout_id)
            self.cur.execute(q)

            q = update_places(curr_workout_id)
            self.cur.execute(q)

            self.remove_future_workouts()
            self.place_future_workouts()

    def back_to_my_workouts2(self):
        self.remove_future_workouts()
        self.place_my_worklouts()
Exemple #3
0
class SearchFrame(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

        self.analyzer = analysis.Analyzer()

        self.controller = controller  # set the controller
        self.title = "Article Search"  # ttile of the window

        #title
        path = 'cyspider.jpg'
        self.img = ImageTk.PhotoImage(Image.open(path))
        self.panel = Label(self, image=self.img)
        self.panel.pack()
        self.searchwindow()

    #search window populates the window with widgets for searching
    def searchwindow(self):
        #keyword entry
        self.largefont = ('Veranda', 24)
        self.ent_keyword = Entry(self,
                                 width=40,
                                 relief='raised',
                                 font=self.largefont,
                                 bd=1)
        #todo <Return> and entry is not empty call search()

        self.ent_keyword.bind('<Escape>', self.clear_text)
        self.ent_keyword.bind(
            '<Key>', lambda event: self.callEnable(event, 'DefaultSearch'))

        self.var = IntVar()
        self.var.set(0)
        self.check_filter = Checkbutton(self,
                                        text="Advanced Filter",
                                        variable=self.var,
                                        onvalue=1,
                                        offvalue=0,
                                        command=self.filter_op,
                                        font="Veranda 16")

        if self.var.get() is 0:
            self.but_search = Button(
                self,
                text='Search',
                width=15,
                state='disable',
                font="Veranda 16",
                command=lambda: self.search(
                    'http://cbrown686-test.apigee.net/cyberapi/articles?q=keywordtitlebody&title='
                    + self.ent_keyword.get() + '&body=' + self.ent_keyword.get(
                    )))
            self.but_search.place(relx=.505, rely=.6, anchor=W)
        else:
            self.searchButton()

        #window placements
        #ENTRY BOX for keyword
        self.ent_keyword.place(relx=.5, rely=.5, anchor=CENTER)

        #check button
        self.check_filter.place(relx=.495, rely=.6, relheight=.059, anchor=E)

    #todo if the user selects to load a search it will simply jump to results

    def searchButton(self, event):
        if self.box.current() is 0:
            self.but_search = Button(
                self,
                text='Search',
                width=15,
                state='disable',
                command=lambda: self.search(
                    'http://cbrown686-test.apigee.net/cyberapi/articles?q=keywordtitlebody&title='
                    + self.ent_keyword.get() + '&body=' + self.ent_keyword.get(
                    )))
            self.but_search.place(relx=.505, rely=.6, anchor=W)
            self.enableSearch2()
        elif self.box.current() is 1:
            self.but_search = Button(
                self,
                text='Search',
                width=15,
                state='disable',
                command=lambda: self.search(
                    'http://cbrown686-test.apigee.net/cyberapi/articles?q=keywordtitle&title='
                    + self.ent_keyword.get()))
            self.but_search.place(relx=.505, rely=.6, anchor=W)
            self.enableSearch2()
        elif self.box.current() is 2:
            self.but_search = Button(
                self,
                text='Search',
                width=15,
                state='disable',
                command=lambda: self.search(
                    'http://cbrown686-test.apigee.net/cyberapi/articles?q=bodyonly&body='
                    + self.ent_keyword.get()))
            self.but_search.place(relx=.505, rely=.6, anchor=W)
            self.enableSearch2()
        elif self.box.current() is 3:
            self.but_search = Button(
                self,
                text='Search',
                width=15,
                state='disable',
                command=lambda: self.search(
                    'http://cbrown686-test.apigee.net/cyberapi/articles?q=uri&uripath='
                    + self.ent_keyword.get()))
            self.but_search.place(relx=.505, rely=.6, anchor=W)
            self.enableSearch2()

    #Hitting escape when editing the ENTRY box will clear it and disable the search button from being able to be used.
    def clear_text(self, event):
        self.ent_keyword.delete(0, 'end')
        self.but_search.configure(state='disable')

    #filter options populate uppon check box of Advanced search option
    def filter_op(self):
        if self.var.get() == 1:
            #appearing
            self.appearing_label = Label(self,
                                         text='Appearing In:',
                                         background='#282828',
                                         font=15,
                                         foreground='#5DE0DC')
            self.box_value = StringVar()
            self.box = Combobox(self, textvariable=self.box_value)
            self.box['values'] = ('Default', 'Title', 'Body', 'URL')
            self.box.current(0)
            self.box.bind('<<ComboboxSelected>>', self.searchButton)
            #author
            self.author_label = Label(self,
                                      text='Author:',
                                      background='#282828',
                                      font=15,
                                      foreground='#5DE0DC')
            self.author_entry = Entry(self,
                                      width=22,
                                      bd=2,
                                      background='#9A9A9A')
            #subjectivity
            self.fsub_label = Label(self,
                                    text='Subjectivity:',
                                    background='#282828',
                                    font=15,
                                    foreground='#5DE0DC')
            self.var2 = IntVar()
            self.var2.set(1)
            self.fsub_nv = Radiobutton(self,
                                       text="Don't Care",
                                       variable=self.var2,
                                       value=1,
                                       background='#282828',
                                       foreground='#5DE0DC')
            self.fsub_gt = Radiobutton(self,
                                       text='More Subjective',
                                       variable=self.var2,
                                       value=2,
                                       background='#282828',
                                       foreground='#5DE0DC')
            self.fsub_lt = Radiobutton(self,
                                       text='More Objective',
                                       variable=self.var2,
                                       value=3,
                                       background='#282828',
                                       foreground='#5DE0DC')
            #date
            self.fD_label = Label(self,
                                  text='Date:',
                                  background='#282828',
                                  font=15,
                                  foreground='#5DE0DC')
            self.fD_format = Label(self,
                                   text='00/00/0000',
                                   background='#282828',
                                   foreground='#BBBBBB')
            self.fD_format.configure(foreground='grey')
            self.fD_beinlab = Label(self,
                                    text='From:',
                                    background='#282828',
                                    foreground='#BBBBBB')
            self.fD_endlab = Label(self,
                                   text='To:',
                                   background='#282828',
                                   foreground='#BBBBBB')
            self.fD_ent = Entry(self, width=10, bd=2, background='#9A9A9A')
            self.fD_ent.insert('end', '01/01/0001')
            self.fD_ent2 = Entry(self, width=10, bd=2, background='#9A9A9A')
            self.fD_ent2.insert('end', strftime('%m/%d/%Y'))

            # window placements
            #appearing labael
            offset = 100
            self.appearing_label.place(x=400, y=380 + offset)
            #appearing pick
            self.box.place(x=510, y=380 + offset)
            #author label
            self.author_label.place(x=400, y=405 + offset)
            #author entry
            self.author_entry.place(x=510, y=405 + offset)
            #subjectivity
            self.fsub_label.place(x=400, y=430 + offset)
            self.fsub_nv.place(x=510, y=430 + offset)
            self.fsub_gt.place(x=510, y=455 + offset)
            self.fsub_lt.place(x=510, y=480 + offset)

            #date
            self.fD_label.place(x=400, y=505 + offset)
            self.fD_format.place(x=440, y=507 + offset)
            self.fD_beinlab.place(x=510, y=505 + offset)
            self.fD_ent.place(x=555, y=505 + offset)
            self.fD_endlab.place(x=590, y=505 + offset)
            self.fD_ent2.place(x=625, y=505 + offset)

            # if the button gets unchecked it will destroy the labels and entry widgets.
        elif self.var.get() == 0:
            self.appearing_label.destroy()
            self.box.destroy()
            self.author_label.destroy()
            self.author_entry.destroy()
            self.fsub_label.destroy()
            self.fsub_nv.destroy()
            self.fsub_gt.destroy()
            self.fsub_lt.destroy()
            self.fD_label.destroy()
            self.fD_format.destroy()
            self.fD_ent.destroy()
            self.fD_beinlab.destroy()
            self.fD_endlab.destroy()
            self.fD_ent2.destroy()

    # does just that clears some shit bra
    def clearshit(self):
        # check to see if the lables and entry boxes exist from a previous search options
        # if they do then destroy them then create the new search label and entry box
        self.ent_keyword.destroy()
        self.check_filter.destroy()
        self.but_search.destroy()
        if hasattr(self, 'appearing_label'):
            self.ent_keyword.destroy()
            self.check_filter.destroy()
            self.but_search.destroy()
            self.appearing_label.destroy()
            self.box.destroy()
            self.author_label.destroy()
            self.author_entry.destroy()
            self.fsub_label.destroy()
            self.fsub_nv.destroy()
            self.fsub_gt.destroy()
            self.fsub_lt.destroy()
            self.fD_label.destroy()
            self.fD_format.destroy()
            self.fD_ent.destroy()
            self.fD_beinlab.destroy()
            self.fD_endlab.destroy()
            self.fD_ent2.destroy()

    #undoes the hide of the seach buttons so that they can edit the search
    def undohide(self):
        self.ent_keyword.place(relx=.5, rely=.5, anchor=CENTER)
        self.check_filter.place(relx=.495, rely=.6, relheight=.059, anchor=E)
        self.but_search.place(relx=.505, rely=.6, anchor=W)
        offset = 100
        if self.var.get() == 1:
            # window placements
            # appearing labael
            self.appearing_label.place(x=400, y=380 + offset)
            # appearing pick
            self.box.place(x=510, y=380 + offset)
            # author label
            self.author_label.place(x=400, y=405 + offset)
            # author entry
            self.author_entry.place(x=510, y=405 + offset)
            # subjectivity
            self.fsub_label.place(x=400, y=430 + offset)
            self.fsub_nv.place(x=510, y=430 + offset)
            self.fsub_gt.place(x=510, y=455 + offset)
            self.fsub_lt.place(x=510, y=480 + offset)

            # date
            self.fD_label.place(x=400, y=505 + offset)
            self.fD_format.place(x=440, y=507 + offset)
            self.fD_beinlab.place(x=510, y=505 + offset)
            self.fD_ent.place(x=555, y=505 + offset)
            self.fD_endlab.place(x=590, y=505 + offset)
            self.fD_ent2.place(x=625, y=505 + offset)

    #hides the widgets to display the search results
    def hideshit(self):
        self.ent_keyword.place_forget()
        self.check_filter.place_forget()
        self.but_search.place_forget()
        if self.var.get() == 1:
            # self.ent_keyword.place(x=(-100), y=(-100))
            # self.check_filter.place(x=(-100), y=(-100))
            # self.but_search.place(x=(-100), y=(-100))
            self.appearing_label.place(x=(-100), y=(-100))
            self.box.place(x=(-100), y=(-100))
            self.author_label.place(x=(-100), y=(-100))
            self.author_entry.place(x=(-100), y=(-100))
            self.fsub_label.place(x=(-100), y=(-100))
            self.fsub_nv.place(x=(-100), y=(-100))
            self.fsub_gt.place(x=(-100), y=(-100))
            self.fsub_lt.place(x=(-100), y=(-100))
            self.fD_label.place(x=(-100), y=(-100))
            self.fD_format.place(x=(-100), y=(-100))
            self.fD_ent.place(x=(-100), y=(-100))
            self.fD_beinlab.place(x=(-100), y=(-100))
            self.fD_endlab.place(x=(-100), y=(-100))
            self.fD_ent2.place(x=(-100), y=(-100))

    #search for that almighty data mine.
    def search(self, url):
        print(url)
        if self.var.get():
            au = self.author_entry.get()
            au = au.replace(' ', '+')
            # var2 is the state of the radio check button
            if self.var2.get() == 2:
                url = url + '&author=' + au + '&sub=gt&sdate=' + self.fD_ent.get(
                ) + '&edate=' + self.fD_ent2.get()
                # print(url)
            elif self.var2.get() == 3:
                url = url + '&author=' + au + '&sub=gt&sdate=' + self.fD_ent.get(
                ) + '&edate=' + self.fD_ent2.get()
            else:
                url = url + '&author=' + au + '&sub=&sdate=' + self.fD_ent.get(
                ) + '&edate=' + self.fD_ent2.get()
        else:
            url = url + '&author=&sub=&sdate=01/01/0001&edate=' + strftime(
                '%m/%d/%Y')

        print(url)
        self.data = requests.get(url).json()
        #print(data)

        self.hideshit()
        style = Style(self)
        style.configure("Treeview", rowheight=30)
        self.tree = Treeview(self)
        self.tree.heading('#0', text='Results by Title')
        self.tree.column('#0', stretch=True)
        self.tree.place(relx=.3, relheight=1, relwidth=.7)

        # sunken box that topics print out into
        self.style = Style()
        self.style.configure('My.TFrame', background='#383838')

        # frame for individual analysis
        self.sf = Frame(self, width=550, height=150, style='My.TFrame')
        self.sf['relief'] = 'sunken'
        self.sf.place(relx=0, rely=.055, relwidth=.3, relheight=.4)

        # labels for article topics
        self.topicsHead = Label(self,
                                text='Key Article Subjects',
                                font="times 16 underline",
                                background='#282828',
                                foreground='#5DE0DC')
        self.topics = Label(self,
                            text='Click on an article to see more info',
                            wraplength=500,
                            font='times 14',
                            background='#383838',
                            foreground='#5DE0DC',
                            anchor=W,
                            justify=LEFT)

        self.topicsHead.place(relx=.01, rely=.01, relwidth=.28)
        self.topics.place(relx=.01, rely=.065, relwidth=.28)

        # frame for results analysis
        self.sf2 = Frame(self, width=550, height=150, style='My.TFrame')
        self.sf2['relief'] = 'sunken'
        self.sf2.place(relx=0, rely=.51, relwidth=.3, relheight=.4)

        self.resultTopicHead = Label(self,
                                     text='Most Mentioned Phrases in Results',
                                     font="times 16 underline",
                                     background='#282828',
                                     foreground='#5DE0DC')
        self.resultTopics = Label(self,
                                  text='',
                                  wraplength=500,
                                  font='times 14',
                                  background='#383838',
                                  foreground='#5DE0DC',
                                  anchor=W,
                                  justify=LEFT)

        self.resultTopicHead.place(relx=.01, rely=.465, relwidth=.28)
        self.resultTopics.place(relx=.01, rely=.52, relwidth=.28)

        # New Search Edit Search Save Search
        self.new_search = Button(self,
                                 text='New Search',
                                 background='#383838',
                                 foreground='#5DE0DC',
                                 command=self.NewSearch)
        self.edit_search = Button(self,
                                  text='Edit Search',
                                  background='#383838',
                                  foreground='#5DE0DC',
                                  command=self.EditSearch)
        self.save_search = Button(self,
                                  text='Save Search',
                                  background='#383838',
                                  foreground='#5DE0DC',
                                  command=self.saveMenu)

        if self.data:
            for item in self.data:
                # remove BOM images first from body >uffff
                item['body'] = ''.join(
                    c for c in unicodedata.normalize('NFC', item['body'])
                    if c <= '\uFFFF')
                self.tree.insert(
                    '',
                    'end',
                    text=item['title'],
                    values=(item['uri'], item['body'],
                            item['title'], item['author'],
                            parser.parse(item['date']).strftime('%B, %d, %Y')),
                    tag='data')

            self.tree.tag_configure('data', font='Verdana 14')
            self.tree.bind('<Double-1>', self.on_click)
            self.tree.bind('<<TreeviewSelect>>', self.on_single_click)

            results = '\n\n'.join([
                '\n'.join(
                    textwrap.wrap('*({}): '.format(phrase[1]) + str(phrase[0]),
                                  width=33)) for phrase in
                self.master.master.analyzer.getMostCommonNounPhrases(
                    5, [item['body'] for item in self.data])
            ])
            self.resultTopics.config(text=results)

            self.new_search.place(x=1, y=675)
            self.edit_search.place(x=75, y=675)
            self.save_search.place(x=145, y=675)

        else:
            self.edit_search = Button(self,
                                      text='Edit Search',
                                      background='#383838',
                                      foreground='#5DE0DC',
                                      command=self.EditSearch)
            self.edit_search.place(x=1, y=675)
            self.topics.config(text='No Articles Matching Search')
            self.resultTopics.config(text='')

            # on_click "double clicking on the article from the tree window opens up the article to be viewed"
    def NewSearch(self):
        self.deletesearch()
        self.searchwindow()

    def EditSearch(self):
        self.deletesearch()
        self.undohide()

    def saveMenu(self):
        # create main directory and subdir(current date) if not made already
        path = os.getcwd() + "/Sessions/" + str(datetime.date.today())
        if not os.path.exists(path):
            os.makedirs(path)
        # get a filename from the user or default to current time
        currentTime = datetime.datetime.now().strftime("%H_%M_%S")

        filename = filedialog.asksaveasfilename(defaultextension="txt",
                                                initialdir=path,
                                                initialfile=currentTime)
        if filename:
            self.saveFilename = filename
            with open(filename, 'w') as outfile:
                json.dump(self.data, outfile)
            # with open(filename, 'w') as f:
            #     f.write("Testing Save As/No Current Save")

    #defind clear search
    def deletesearch(self):
        self.tree.destroy()
        self.sf.destroy()
        self.topicsHead.destroy()
        self.topics.destroy()
        self.sf2.destroy()
        self.resultTopicHead.destroy()
        self.resultTopics.destroy()
        self.new_search.destroy()
        self.edit_search.destroy()
        self.save_search.destroy()

    #on click gets the articles information and displays it in the Key Article Subjects window
    def on_single_click(self, event):
        self.topicsHead.config(text="Key Article Subjects")
        item = self.tree.item(self.tree.selection()[0], 'values')
        topicStr = '\n\n'.join([
            '\n'.join(textwrap.wrap('*' + phrase[0], width=33))
            for phrase in self.master.master.analyzer.getMostCommonNounPhrases(
                5, [item[1]])
        ])
        self.topics.config(text=topicStr)

    #on d click will open the article for display
    def on_click(self, event):
        item = self.tree.selection()[0]
        self.n = self.tree.item(item, 'values')
        tw = Toplevel(self)
        xoffset = int(self.winfo_screenwidth() / 2 - 1280 / 2)
        yoffset = int(self.winfo_screenheight() / 2 - 800 / 2)
        tw.geometry("%dx%d+%d+%d" %
                    (800, 600, xoffset, yoffset))  # set geometry of window
        tw.title(self.n[2])
        tb = Text(tw, width=90, height=40, font="Times 14", wrap=WORD)
        tb.insert('end', self.n[1])
        link = Label(tw, text=self.n[0])
        link.configure(foreground='blue', cursor='hand2')
        link.bind('<1>', self.op_link)
        auth = Label(tw, text='Author: ' + self.n[3])
        articledate = Label(tw, text='Date Published: ' + self.n[4])

        # window formatting for tw
        link.place(x=0, y=0, relwidth=1)
        tb.place(y=20, relwidth=1, relheight=1)
        auth.pack(side=LEFT, anchor='sw')
        articledate.pack(side=RIGHT, anchor='se')

    # op_link "double click on the link at the top of the page opens up the url link
    def op_link(self, event):
        webbrowser.open_new(self.n[0])

    def callEnable(self, event, searchType):
        self.after(100, lambda: self.enableSearch(event, searchType))

    # event bind when Return is entered after a title keyword is entered will enable the search button.
    def enableSearch(self, event, searchType):
        string = ''
        if searchType == 'DefaultSearch':
            string = self.ent_keyword.get()
        if string.strip() != '':
            self.but_search.configure(state='normal')
        else:
            self.but_search.configure(state='disabled')

    # check for when no event bind is present to be used to pass in and no need for searchType
    def enableSearch2(self):
        string = self.ent_keyword.get()
        if string.strip() != '':
            self.but_search.configure(state='normal')
        else:
            self.but_search.configure(state='disabled')
Exemple #4
0
class Multicolumn_Listbox(Frame):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)

        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_row(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_column(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_columns

    def __init__(self,
                 master,
                 columns,
                 data=None,
                 command=None,
                 sort=True,
                 select_mode=None,
                 heading_anchor=CENTER,
                 cell_anchor=W,
                 style=None,
                 height=None,
                 padding=None,
                 adjust_heading_to_content=False,
                 stripped_rows=None,
                 selection_background=None,
                 selection_foreground=None,
                 field_background=None,
                 heading_font=None,
                 heading_background=None,
                 heading_foreground=None,
                 cell_pady=2,
                 cell_background=None,
                 cell_foreground=None,
                 cell_font=None,
                 headers=True):

        self._stripped_rows = stripped_rows

        self._columns = columns

        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)

        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview" % self._style_index
            self._style_index += 1
        else:
            style_name = style

        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]

        if selection_foreground is not None:
            style_map["foeground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(Font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(Font) == 2:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1])

                    elif len(Font) == 3:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1],
                                         weight=cell_font[2])
                    else:
                        raise ValueError(
                            "Not possible more than 3 values for font")

            style_config["font"] = cell_font

        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace") + cell_pady
        style_config["rowheight"] = self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height

        if padding is not None:
            treeview_kwargs["padding"] = padding

        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""

        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)

        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(
                    i,
                    text=columns[i],
                    anchor=heading_anchor,
                    command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i,
                                      text=columns[i],
                                      anchor=heading_anchor)

            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)

        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight

    @property
    def font(self):
        return self._cell_font

    def configure_column(self,
                         index,
                         width=None,
                         minwidth=None,
                         anchor=None,
                         stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value

        self.interior.column('#%s' % (index + 1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1

        if self._stripped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i + 1],
                                            background=self._stripped_rows[i %
                                                                           2])

    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

        if index is None:
            index = self._number_of_rows - 1

        item_ID = self.interior.insert('', index, values=data)
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1

        if self._stripped_rows:
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID,
                                        background=self._stripped_rows[index %
                                                                       2])

            for i in range(index + 1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def column_data(self, index):
        return [
            self.interior.set(child_ID, index)
            for child_ID in self.interior.get_children('')
        ]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()):
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)

        self._number_of_rows = 0

    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)

    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if state is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows

    @property
    def number_of_columns(self):
        return self._number_of_columns

    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_toggle(item_ID)

    def select_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_remove(item_ID)

    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index]
                                             for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices

    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)

        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]

    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @table_data.setter
    def table_data(self, data):
        self.update(data)

    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d" % row)

        return self.interior.set(item, column)

    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]

        data = self.item_ID_to_row_data(item_ID)

        data[column] = value
        self.interior.item(item_ID, values=data)

    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")

    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID)
                for child_ID in self.interior.get_children('')]

        # if the data to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
        except ValueError:
            pass

        # now sort the data in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(
            col, command=lambda col=col: self.sort_by(col, not descending))

        if self._stripped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def destroy(self):
        self.interior.destroy()

    def item_ID(self, index):
        return self.interior.get_children()[index]
Exemple #5
0
class CheckDownload():
	"""
	检测需要下载的URL是否存在于数据库,展示面板
	"""
	def __init__(self, master, transaction, tuple_result, ori_args ):
		self.master = master
		self.tuple_result = tuple_result    #已经分好类的URL元组
		self.oriurl = ori_args[0]
		self.orilable = ori_args[1]
		self.transaction = transaction
		self.frame2 = Frame(self.master,width=10, height=2)
		# self.frame2.pack()
		self.frame2.grid(row=0, column=0)
		label = Label(self.frame2, text="数据库中已经存在的数据",width = 30,height = 3)
		label.grid(row=1, column=1)
		self.tree_date = Treeview(self.master, columns=['URL', 'Lable', 'Time'], show='headings', height=23)
		# self.tree_date.pack()
		self.tree_date.grid(row=2)
		# 设置列宽度
		self.tree_date.column('URL', width=600, anchor='center')
		self.tree_date.column('Lable', width=350, anchor='center')
		self.tree_date.column('Time', width=250, anchor='center')
		# 添加列名
		self.tree_date.heading('URL', text='URL')
		self.tree_date.heading('Lable', text='标签')
		self.tree_date.heading('Time', text='上次下载时间')
		
		# 绑定事件
		self.tree_date.bind('<Double-3>', self.deleteItem)
		self.frame3 = Frame(self.master)
		btn_yes = tk.Button(self.frame3, text='所列URL重新下载', command=self.downloadNewData)
		btn_no = tk.Button(self.frame3, text='使用数据库数据', command=self.usingOldData)
		self.frame3.grid(row=3)
		btn_no.grid(row=3, column=1)
		btn_yes.grid(row=3, column=2)
		
		# 将存在于数据库中的URL数据展示出来
		for key, value in self.tuple_result[1].items():
			self.tree_date.insert('', 1, values=(key, self.orilable[self.oriurl.index(key)], value['creattime_']))
		
	
	def deleteItem(self, event):  # 右键双击删除
		for item in self.tree_date.selection():
			self.tree_date.delete(item)
	
	
	def downloadNewData(self):
		kids = self.tree_date.get_children()
		urllists = []
		lablelist = []
		for item in kids:
			# 对输入的值进行去重
			url_ = self.tree_date.item(item, "values")[0]
			lable_ = self.tree_date.item(item, "values")[1]
			if url_ not in urllists:
				urllists.append(url_)
				lablelist.append(lable_)
		url_download = urllists + list(self.tuple_result[0].keys())
		#   此时urllists意味着需要新下载的数据,数据库中的旧数据需要即刻清除
		# p = Process(target=self.transaction.downloadDatas, args=(downloadqueue, self.oriurl, self.orilable, url_download, urllists))
		# p.start()
		p = threading.Thread(target=self.transaction.downloadDatas, args=(downloadqueue, self.oriurl, self.orilable, url_download, urllists))
		p.start()
		self.workSurfaceUI([self.oriurl, self.orilable])
	
	def usingOldData(self):
		kids = self.tree_date.get_children()
		urllists = []
		for item in kids:
			# 对输入的值进行去重
			url_ = self.tree_date.item(item, "values")[0]
			if url_ not in urllists:
				urllists.append(url_)
		# print("self.transaction.urllists:")
		# print(self.transaction.urllists)
		# print("urllists:")
		# print(urllists)
		download_urls = list(set(self.transaction.urllists) - set(urllists))
		delete_urls = list(set(self.tuple_result[1].keys()) - set(urllists))
		# print("本次数据URL: ")
		# print(download_urls)
		# print(delete_urls)
		if len(download_urls) != 0:
			# p = Process(target=self.transaction.downloadDatas, args=(downloadqueue, self.oriurl, self.orilable, download_urls, delete_urls))
			# p.start()
			p = threading.Thread(target=self.transaction.downloadDatas, args=(downloadqueue, self.oriurl, self.orilable, download_urls, delete_urls))
			p.start()
		else:
			# print("usingOldData方法中 len(download_urls)!=0 所以执行 downloadqueue.put(1)")
			downloadqueue.put("no_download_urls")
		self.workSurfaceUI([self.oriurl, self.orilable])
		
	def workSurfaceUI(self, args):
		self.frame2.destroy()
		self.frame3.destroy()
		self.tree_date.destroy()
		WorkSurface(self.master, self.transaction, self.tuple_result, args)
Exemple #6
0
class initface():
	def __init__(self, master,transaction, args):
		self.transaction = transaction
		self.master = master
		self.isOkToNextUI = True    #判断是否可以进入URL分析程序
		self.isOkToSelectSurface = True #判断是否可以进入选择界面
		self.classify_result = None #用于储存元组数据
		self.frame2 = Frame(self.master, height=200)
		# self.frame2.pack()
		self.frame2.grid(row=0, column=0)
		selectbtn = Button(self.frame2, text="选择数据", command=self.selectDatasSurface)
		label = Label(self.frame2, text="URL:  ")
		self.name = StringVar()
		self.entryName = Entry(self.frame2, textvariable=self.name, width=80)
		
		label2 = Label(self.frame2, text="标签:  ")
		self.lable2 = StringVar()
		self.entryName2 = Entry(self.frame2, textvariable=self.lable2, width=30)
		
		btGetName = Button(self.frame2, text="添加URL", command=self.processAddURL)
		startDlButton = Button(self.frame2, text="开始下载", command=self.processDownload)
		selectbtn.grid(row=1,column = 0)
		label.grid(row=1, column=1)
		self.entryName.grid(row=1, column=2)
		label2.grid(row=1, column=3)
		self.entryName2.grid(row=1, column=4)
		btGetName.grid(row=1, column=5)
		startDlButton.grid(row=1, column=6)
		self.tree_date = Treeview(self.master, columns=['URL','LABLE2'], show='headings', height=30)
		# self.tree_date.pack()
		self.tree_date.grid(row=2)
		# 设置列宽度
		self.tree_date.column('URL', width=758, anchor='center')
		self.tree_date.column('LABLE2', width=442, anchor='center')
		# 添加列名
		self.tree_date.heading('URL', text='URL')
		self.tree_date.heading('LABLE2', text='标签')
		# 绑定事件
		self.tree_date.bind('<Double-3>', self.deleteItem)
		# 当从数据分析页面返回时调用
		if self.transaction.urllists != []:
			for index in range(len(args[0])):
				self.tree_date.insert('', 1, values=(args[0][index], args[1][index]))
			
			# for key,value in self.receptdata[0].items():
			# 	self.tree_date.insert('', 1, values=(key,value['lable_']))
			# for key,value in self.receptdata[1].items():
			# 	self.tree_date.insert('', 1, values=(key, value['lable_']))
			
			# for item in self.transaction.urllists:
			# 	self.tree_date.insert('', 1, values=item)
	
	def selectDatasSurface(self):
		# print('点击了选择按钮')
		
		# 获取合适的URL
		if self.isOkToSelectSurface:
			self.isOkToSelectSurface = False
			t_classify = threading.Thread(target=self.loadAllDatas)
			t_classify.start()
		else:
			tkinter.messagebox.showinfo('TBProject Info', '请等待数据库数据提取完毕!')
	
	def loadAllDatas(self):
		# t_judge = MyThread(func=self.transaction.loadAllDatasFromDetials, args=("loadAllDatasFromDetials",))
		# t_judge.start()
		# t_judge.join()
		# # threadingqueue.put(1)
		# result_datas = t_judge.get_result()
		try:
			result_datas = self.transaction.loadAllDatasFromDetials()
		except:
			self.isOkToSelectSurface = True
			tkinter.messagebox.showerror('TBProject Error', 'initface ---> loadAllDatas: 数据库链接出现错误,请重试!')
			return
		self.frame2.destroy()
		self.tree_date.destroy()
		SelectionSurface(self.master, self.transaction, result_datas)
	
	
	def deleteItem(self, event):  # 右键双击删除
		for item in self.tree_date.selection():
			self.tree_date.delete(item)
			# item_text = self.tree_date.item(item, "values")
			# print(item_text[0])  # 输出所选行的第一列的值
	
	def processAddURL(self):
		url_ = self.name.get().strip()
		if url_==None or url_.strip()=="":
			self.entryName.delete(0, END)
			self.entryName2.delete(0, END)
			return
		if url_[0:4] != 'http':
			self.entryName.delete(0, END)
			self.entryName2.delete(0, END)
			tkinter.messagebox.showinfo('TBProject Info', "非正确网址格式: \r\n" + url_)
			return
		if ('tmall' not in url_) and ('taobao' not in url_):
			self.entryName.delete(0, END)
			self.entryName2.delete(0, END)
			tkinter.messagebox.showinfo('TBProject Info', "此URL不属于目标网站: \r\n" + url_)
			return
		lable_ = self.lable2.get()
		if lable_==None or lable_.strip()=="":
			lable_ = "-Default Lable-"
		self.tree_date.insert('', 1, values=(url_,lable_))
		self.entryName.delete(0,END)
		self.entryName2.delete(0, END)
		
	
	def processDownload(self):
		if len(self.tree_date.get_children())==0:
			return None
		# 获取合适的URL
		if self.isOkToNextUI:
			self.isOkToNextUI = False
			kids = self.tree_date.get_children()
			urllists = []
			lablelist = []
			for item in kids:
				# 对输入的值进行去重
				url_ = self.tree_date.item(item, "values")[0]
				lable_ = self.tree_date.item(item, "values")[1]
				if url_ not in urllists:
					urllists.append(url_)
					lablelist.append(lable_)
			# 如果可用网址为0,则清空treeview
			if len(urllists)==0:
				self.entryName.delete(0, END)
				for item in kids:
					self.tree_date.delete(item)
				return
			self.transaction.urllists = urllists
			t_classify = threading.Thread(target=self.classifyURL, args=(urllists,lablelist))
			t_classify.start()
		else:
			tkinter.messagebox.showinfo('TBProject Info', '请等待URL分析完毕')
		
		
		
	
	def classifyURL(self, urllists, lablelist):
		try:
			self.classify_result = self.transaction.classifyURLNewOrOld(urllists, lablelist)
		except:
			self.isOkToNextUI = True
			tkinter.messagebox.showerror('TBProject Error', 'initface ---> classifyURL: 数据库链接出现错误,请重试!')
			return
		
		self.judgeNextUI(urllists, lablelist)
	
	
	def judgeNextUI(self, oriurl, orilable):
		if len(self.classify_result[0]) != 0:
			newurllists = list(self.classify_result[0].keys())
		else:
			newurllists = []
		oldurllists = self.classify_result[1]
		if len(oldurllists) == 0: #说明没有旧数据
			# p = Process(target=self.transaction.downloadDatas, args=(downloadqueue, oriurl, orilable, newurllists))
			# p.start()
			p = threading.Thread(target=self.transaction.downloadDatas, args=(downloadqueue, oriurl, orilable, newurllists))
			p.start()
			self.workSurfaceUI([oriurl, orilable])
		else:   #说明存在一些URL在数据库中有存
			# 将两个列表都传给下一个界面,在下一个界面将数据分类展示
			self.checkDownloadUI(self.classify_result, oriurl, orilable)

	def workSurfaceUI(self, args):
		self.frame2.destroy()
		self.tree_date.destroy()
		WorkSurface(self.master, self.transaction, self.classify_result, args)
	
	def checkDownloadUI(self, args, oriurl, orilable):
		self.frame2.destroy()
		self.tree_date.destroy()
		CheckDownload(self.master, self.transaction, args, [oriurl, orilable])
Exemple #7
0
class handleDatasSurface():
	def __init__(self, master, transaction, tuple_result, args):
		self.transaction = transaction
		self.master = master
		self.args = args
		self.tuple_result = tuple_result
		self.deleteurls = []
		self.frame2 = Frame(self.master, width=10, height=2)
		# self.frame2.pack()
		self.frame2.grid(row=0, column=0)
		label = Label(self.frame2, text="本次运行时候使用的数据", width=30, height=3)
		label.grid(row=1, column=1)
		self.tree_date = Treeview(self.master, columns=['URL', 'Lable', 'Time'], show='headings', height=23)
		# self.tree_date.pack()
		self.tree_date.grid(row=2, column=0)
		# 设置列宽度
		self.tree_date.column('URL', width=450, anchor='center')
		self.tree_date.column('Lable', width=500, anchor='center')
		self.tree_date.column('Time', width=250, anchor='center')
		# 添加列名
		self.tree_date.heading('URL', text='URL')
		self.tree_date.heading('Lable', text='标签')
		self.tree_date.heading('Time', text='上次下载时间')
		
		# 绑定事件
		# 绑定左键单击 选中
		self.tree_date.bind('<Double-Button-1>', self.selectone)
		# 绑定右键单击 取消选中
		self.tree_date.bind('<Double-3>', self.refuseone)
		# 绑定键盘 Enter事件,展示URL
		self.tree_date.bind('<Return>', self.infoURL)
		self.frame3 = Frame(self.master)
		btn_yes = tk.Button(self.frame3, text='删除已经选择的数据', command=self.useSelectedData)
		# btn_no = tk.Button(self.frame3, text='使用数据库数据', command=self.usingOldData)
		self.frame3.grid(row=3)
		# btn_no.grid(row=3, column=1)
		btn_yes.grid(row=3, column=2)
		
		self.vsb = tk.ttk.Scrollbar(self.master, orient="vertical", command=self.tree_date.yview)
		# vsb.place(x=30 + 1100, y=95, height=300 + 20)
		self.tree_date.configure(yscrollcommand=self.vsb.set)
		# vsb.grid(row=2, columns = 1,sticky=NS)
		self.vsb.place(x=1182, y=60, height=480 + 20)
		# vsb.place(x=50 + 200, y=95, height=200 + 20)
		
		# 将存在于数据库中的URL数据展示出来
		# for key, value in self.tuple_result[1].items():
		# 	self.tree_date.insert('', 1, values=(key, self.orilable[self.oriurl.index(key)], value['creattime_']))
		tuple_ = self.tuple_result[0].copy()
		tuple_.update(self.tuple_result[1])
		for key,value in tuple_.items():
			self.tree_date.insert('', 1, values=(key, value['lable_'], value['creattime_']), tags=self.getrandomtgs())
				
		
		
	
	def deleteItem(self, event):  # 右键双击删除
		for item in self.tree_date.selection():
			self.tree_date.delete(item)
	
	def selectone(self, event):
		for item in self.tree_date.selection():
			# self.tree_date.columnconfigure (0,weight=1,background='yellow', foreground="red")
			# self.tree_date.configure ( background = 'yellow',foreground="red")
			# tages = self.tree_date.item(item, "values")[0]
			tages = self.tree_date.item(item, "tags")[0]
			url_ = self.tree_date.item(item, "values")[0].strip()
			if url_ not in self.deleteurls:
				self.deleteurls.append(url_)
			self.tree_date.tag_configure(tages, background='yellow', foreground="red")
	
	def refuseone(self, event):
		for item in self.tree_date.selection():
			tages = self.tree_date.item(item, "tags")[0]
			try:
				self.deleteurls.remove(self.tree_date.item(item, "values")[0].strip())
			except:
				pass
			self.tree_date.tag_configure(tages, background='white', foreground="black")
	
	def infoURL(self, event):
		for item in self.tree_date.selection():
			url_ = self.tree_date.item(item, "values")[0].strip()
			lable_ = self.tree_date.item(item, "values")[1]
			pyperclip.copy(url_)
			tkinter.messagebox.showinfo('TBProject Info', '选中的url为:\r\n%s' % url_ + "\r\n选中的标签为:\r\n%s" % lable_)
	
	def getrandomtgs(self):
		return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6))
	
	def useSelectedData(self):
		try:
			if len(self.deleteurls) != 0:
				t_classify = threading.Thread(target=self.transaction.deleteOldDatas, args=(self.deleteurls,))
				t_classify.start()
		except:
			tkinter.messagebox.showerror('TBProject Error', 'tryAnalysize: 数据库链接出现错误,请重试!')
			return
		tuple_ = self.tuple_result[0].copy()
		tuple_.update(self.tuple_result[1])
		for item in self.deleteurls:
			tuple_[item]['creattime_'] = "- Deleted -"
		self.frame2.destroy()
		self.frame3.destroy()
		self.tree_date.destroy()
		self.vsb.destroy()
		# self.transaction.urllists = 1
		WorkSurface(self.master, self.transaction, self.tuple_result, self.args, ishandle = True)
Exemple #8
0
class SelectionSurface():
	def __init__(self, master, transaction, result_data):
		self.transaction = transaction
		self.master = master
		self.result_data = result_data
		self.selecturl = []
		self.selectlable = []
		self.selecttime = []
		self.frame2 = Frame(self.master, width=10, height=2)
		# self.frame2.pack()
		self.frame2.grid(row=0, column=0)
		label = Label(self.frame2, text="数据库中已经存在的数据", width=30, height=3)
		label.grid(row=1, column=1)
		self.tree_date = Treeview(self.master, columns=['URL', 'Lable', 'Time'], show='headings', height=23)
		# self.tree_date.pack()
		self.tree_date.grid(row=2,column=0)
		# 设置列宽度
		self.tree_date.column('URL', width=450, anchor='center')
		self.tree_date.column('Lable', width=500, anchor='center')
		self.tree_date.column('Time', width=250, anchor='center')
		# 添加列名
		self.tree_date.heading('URL', text='URL')
		self.tree_date.heading('Lable', text='标签')
		self.tree_date.heading('Time', text='上次下载时间')
		
		# 绑定事件
		# 绑定左键单击 选中
		self.tree_date.bind('<Double-Button-1>', self.selectone)
		# 绑定右键单击 取消选中
		self.tree_date.bind('<Double-3>', self.refuseone)
		# 绑定键盘 Enter事件,展示URL
		self.tree_date.bind('<Return>', self.infoURL)
		self.frame3 = Frame(self.master)
		btn_yes = tk.Button(self.frame3, text='使用已经挑选的数据', command=self.useSelectedData)
		# btn_no = tk.Button(self.frame3, text='使用数据库数据', command=self.usingOldData)
		self.frame3.grid(row=3)
		# btn_no.grid(row=3, column=1)
		btn_yes.grid(row=3, column=2)
	
		self.vsb = tk.ttk.Scrollbar(self.master, orient="vertical", command=self.tree_date.yview)
		# vsb.place(x=30 + 1100, y=95, height=300 + 20)
		self.tree_date.configure(yscrollcommand=self.vsb.set)
		# vsb.grid(row=2, columns = 1,sticky=NS)
		self.vsb.place(x=1182, y=60, height=480 + 20)
		# vsb.place(x=50 + 200, y=95, height=200 + 20)
		
		# 将存在于数据库中的URL数据展示出来
		# for key, value in self.tuple_result[1].items():
		# 	self.tree_date.insert('', 1, values=(key, self.orilable[self.oriurl.index(key)], value['creattime_']))
		for item in self.result_data:
			self.tree_date.insert('', 1, values=(item[0], item[1], item[2]), tags=self.getrandomtgs())
	
	
	def deleteItem(self, event):  # 右键双击删除
		for item in self.tree_date.selection():
			self.tree_date.delete(item)
			
	def selectone(self, event):
		for item in self.tree_date.selection():
			# self.tree_date.columnconfigure (0,weight=1,background='yellow', foreground="red")
			# self.tree_date.configure ( background = 'yellow',foreground="red")
			# tages = self.tree_date.item(item, "values")[0]
			tages = self.tree_date.item(item, "tags")[0]
			url_ = self.tree_date.item(item, "values")[0].strip()
			lable_ = self.tree_date.item(item, "values")[1]
			time_ = self.tree_date.item(item, "values")[2]
			if url_ not in self.selecturl:
				self.selecturl.append(url_)
				self.selectlable.append(lable_)
				self.selecttime.append(time_)
			self.tree_date.tag_configure (tages, background = 'yellow',foreground="red")
			
	def refuseone(self, event):
		for item in self.tree_date.selection():
			tages = self.tree_date.item(item, "tags")[0]
			try:
				self.selecturl.remove(self.tree_date.item(item, "values")[0].strip())
				self.selectlable.remove(self.tree_date.item(item, "values")[1])
				self.selecttime.remove(self.tree_date.item(item, "values")[2])
			except:
				pass
			self.tree_date.tag_configure(tages, background='white', foreground="black")
	
	def infoURL(self, event):
		for item in self.tree_date.selection():
			url_ = self.tree_date.item(item, "values")[0].strip()
			lable_ = self.tree_date.item(item, "values")[1]
			pyperclip.copy(url_)
			tkinter.messagebox.showinfo('TBProject Info', '选中的url为:\r\n%s'%url_+"\r\n选中的标签为:\r\n%s"%lable_)
			
	def getrandomtgs(self):
		return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6))
	
	
	
	
	def useSelectedData(self):
		self.frame2.destroy()
		self.frame3.destroy()
		self.tree_date.destroy()
		self.vsb.destroy()
		self.transaction.urllists = 1
		initface(self.master, self.transaction, [self.selecturl,self.selectlable, self.selecttime])
Exemple #9
0
class SearchFrame(Frame):
    content = None

    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.analysisthread = None
        self.controller = controller  # set the controller
        self.title = "Article Search"  # title of the window

        #title
        path = os.getcwd() + '\\resources\cyspider.jpg'
        self.img = ImageTk.PhotoImage(Image.open(path))
        self.panel = Label(self, image=self.img)
        self.panel.pack()

        # widgets for results page
        # frame for individual analysis
        self.sf = LabelFrame(self,
                             width=550,
                             height=150,
                             background='#383838',
                             bd=6)

        # frame for results analysis
        self.sf2 = LabelFrame(self,
                              width=550,
                              height=150,
                              background='#383838',
                              bd=6)

        # labels for article topics
        self.topicsHead = Label(self,
                                text='Key Article Subjects',
                                font="times 16 underline",
                                background='#282828',
                                foreground='#5DE0DC')
        self.topics = Label(self,
                            text='Click on an article to see more info',
                            wraplength=500,
                            font='times 16',
                            background='#383838',
                            foreground='#5DE0DC',
                            anchor=W,
                            justify=LEFT)
        calltipwindow.createToolTip(
            self.topicsHead,
            "These are a few subjects that were mentioned in the article")

        # labels for results analysis
        self.resultTopicHead = Label(self,
                                     text='Most Mentioned Phrases in Results',
                                     font="times 16 underline",
                                     background='#282828',
                                     foreground='#5DE0DC')
        self.resultTopics = Label(self,
                                  text='Processing Data (0%)',
                                  wraplength=500,
                                  font='times 16',
                                  background='#383838',
                                  foreground='#5DE0DC',
                                  anchor=W,
                                  justify=LEFT)
        calltipwindow.createToolTip(
            self.resultTopicHead,
            "These are the most mentioned phrases in the resulting articles.")

        # helper class to improve code readability
        self.helper = cyhelper.SearchHelper(self)

        self.helper.showsearch()

    def search(self, url):
        # queue to share between gui and threads
        q = queue.Queue()
        self.helper.hidefilters()

        if SearchFrame.content is None:
            searchprogress = Progressbar(self,
                                         orient="horizontal",
                                         style='mongo.Horizontal.TProgressbar',
                                         length=700,
                                         mode="indeterminate")
            searchprogress.place(relx=.5, rely=.8, anchor=CENTER)
            searchprogress.start()

            proglabel = Label(self,
                              text="Fetching Results...",
                              font="Times 14",
                              bg="#282828",
                              fg="#FFFFFF")
            proglabel.place(relx=.5, rely=.765, anchor=CENTER)

            # get additional info from filters if they exist
            url = self.helper.addurlfilters(url)

            # start thread to get data from url
            thread = GetDataThread(url, q)
            thread.start()

            # wait until thread is done, then get data from queue
            self.updateuntildata(q, searchprogress)
            self.data = q.get(0)

            # get rid of progress bar
            searchprogress.destroy()
            proglabel.destroy()

        else:
            self.data = SearchFrame.content

        # make sure search didn't time out
        if self.data != "ReadTimeout":
            self.master.master.updateque.queue.clear()

            # start thread to analyze data and repeat process
            self.analysisthread = ResultsAnalysisThread(
                self.data, self.master.master.analyzer, q, self.resultTopics)
            self.analysisthread.start()

            self.resultTopics.config(text="Processing Data...(0%)")
            self.processingloop('percent')
            self.processingloop('dots')

            self.helper.hidesearch()

            style = Style(self)
            style.configure("Treeview",
                            rowheight=30,
                            fieldbackground='#bdbdbd')
            style.configure("Treeview.Heading",
                            background="#707070",
                            rowheight=60,
                            font="Ariel 14 bold")
            self.tree = Treeview(self,
                                 columns=('date', 'title'),
                                 selectmode='browse')
            self.tree['show'] = 'headings'

            self.tree.column('date', width=100, anchor=CENTER)
            self.tree.heading('date',
                              text="Date",
                              command=lambda: self.treeview_sort_column(
                                  self.tree, 'date', False))
            self.tree.column('title', width=900)

            self.tree.heading('title',
                              text="Article Title",
                              anchor=W,
                              command=lambda: self.treeview_sort_column(
                                  self.tree, 'title', False))
            self.tree.heading('title',
                              text="Article Title",
                              anchor=W,
                              command=lambda: self.treeview_sort_column(
                                  self.tree, 'title', False))

            #self.tree.place(relx=.3, relheight=1, width=1200)
            self.tree.place(x=330, relheight=1, width=760)

            self.treeyscb = Scrollbar(self,
                                      orient="vertical",
                                      command=self.tree.yview)
            self.treeyscb.place(relx=1, rely=.5, relheight=1, anchor=E)

            self.tree.configure(yscrollcommand=self.treeyscb.set)

            self.treexscb = Scrollbar(self,
                                      orient="horizontal",
                                      command=self.tree.xview)
            self.treexscb.place(relx=.3, rely=.999, width=755, anchor=SW)

            self.tree.configure(xscrollcommand=self.treexscb.set)
            self.sf.place(relx=0, rely=.055, relwidth=.30, relheight=.4)

            self.topicsHead.place(relx=.01,
                                  rely=.024,
                                  relwidth=.28,
                                  relheight=.03)
            self.topics.place(relx=.01, rely=.065, relwidth=.28)

            # frame for results analysis
            self.sf2.place(relx=0, rely=.51, relwidth=.30, relheight=.4)

            self.resultTopicHead.place(relx=.01,
                                       rely=.475,
                                       relwidth=.28,
                                       relheight=.03)
            self.resultTopics.place(relx=.01, rely=.52, relwidth=.28)

            # New Search Edit Search Save Search
            self.new_search = Button(self,
                                     text='New Search',
                                     background='#383838',
                                     foreground='#5DE0DC',
                                     font="Veranda 14",
                                     command=self.NewSearch)
            self.edit_search = Button(self,
                                      text='Edit Search',
                                      background='#383838',
                                      foreground='#5DE0DC',
                                      font="Veranda 14",
                                      command=self.EditSearch)
            self.save_search = Button(self,
                                      text='Save Search',
                                      background='#383838',
                                      foreground='#5DE0DC',
                                      font="Veranda 14",
                                      command=self.saveMenu)

            if self.data:
                for count, item in enumerate(self.data):
                    # remove BOM images first from body >uffff
                    item['body'] = ''.join(
                        c for c in unicodedata.normalize('NFC', item['body'])
                        if c <= '\uFFFF')
                    tagname = 'even' if count % 2 == 0 else 'odd'
                    self.tree.insert('',
                                     'end',
                                     values=(parser.parse(
                                         item['date']).strftime('%m/%d/%y'),
                                             item['title'], item['uri'],
                                             item['author'], item['body']),
                                     tag=tagname)

                self.tree.tag_configure('even',
                                        font='Verdana 14',
                                        background="#9fedea")
                self.tree.tag_configure('odd',
                                        font='Verdana 14',
                                        background="#dedede")
                self.tree.bind('<Double-1>', self.on_click)
                self.tree.bind('<<TreeviewSelect>>', self.on_single_click)

                self.treeview_sort_column(self.tree, 'date', True)

            else:
                self.topics.config(text='No Articles Matching Search')
                self.resultTopics.config(text='')

            self.new_search.place(relx=0,
                                  rely=.95,
                                  relwidth=.1,
                                  relheight=.05,
                                  anchor=NW)
            if SearchFrame.content is None:
                self.edit_search.place(relx=.1,
                                       rely=.95,
                                       relwidth=.1,
                                       relheight=.05,
                                       anchor=NW)
                if len(self.data) > 0:
                    self.save_search.place(relx=.2,
                                           rely=.95,
                                           relwidth=.1,
                                           relheight=.05,
                                           anchor=NW)

        else:
            messagebox.showerror(
                "Too Broad", "Search is too broad. Try refining with filters.")
            self.helper.ent_keyword.focus_set()

        SearchFrame.content = None
        pass

    def NewSearch(self):
        self.analysisthread.stopthread()
        self.deletesearch()
        self.helper.resetsearch()
        self.helper.showsearch()

    def EditSearch(self):
        self.analysisthread.stopthread()
        self.deletesearch()
        self.helper.showsearch()

    def saveMenu(self):
        # create main directory and subdir(current date) if not made already
        path = os.getcwd() + "/Sessions/" + str(datetime.date.today())
        if not os.path.exists(path):
            os.makedirs(path)
        # get a filename from the user or default to current time
        currentTime = datetime.datetime.now().strftime("%H_%M_%S")

        filename = filedialog.asksaveasfilename(defaultextension="txt",
                                                initialdir=path,
                                                initialfile=currentTime)
        if filename:
            self.saveFilename = filename
            with open(filename, 'w') as outfile:
                json.dump(self.data, outfile)
            # with open(filename, 'w') as f:
            #     f.write("Testing Save As/No Current Save")

    #defind clear search
    def deletesearch(self):
        self.tree.destroy()
        self.sf.place_forget()
        self.topicsHead.place_forget()
        self.topics.place_forget()
        self.sf2.place_forget()
        self.resultTopicHead.place_forget()
        self.resultTopics.place_forget()
        self.new_search.destroy()
        self.treexscb.destroy()
        self.treeyscb.destroy()
        try:
            self.edit_search.destroy()
            self.save_search.destroy()
        except AttributeError:
            pass

    #on click gets the articles information and displays it in the Key Article Subjects window
    def on_single_click(self, event):
        self.topicsHead.config(text="Key Article Subjects")
        item = self.tree.item(self.tree.selection()[0], 'values')
        topicStr = '\n\n'.join([
            '\n    '.join(textwrap.wrap('\u27a2' + phrase[0], width=33))
            for phrase in self.master.master.analyzer.getMostCommonNounPhrases(
                5, [item[4]], threading.Event(), 'one')
        ])
        self.topics.config(text=topicStr)

    #on d click will open the article for display
    def on_click(self, event):
        try:
            item = self.tree.selection()[0]
        except IndexError:
            return

        self.n = self.tree.item(item, 'values')
        tw = Toplevel(self)
        xoffset = int(self.winfo_screenwidth() / 2 - 1280 / 2)
        yoffset = int(self.winfo_screenheight() / 2 - 800 / 2)
        tw.geometry("%dx%d+%d+%d" %
                    (800, 600, xoffset, yoffset))  # set geometry of window
        tw.title(self.n[1])
        tb = Text(tw, width=90, height=40, font="Times 14", wrap=WORD)

        makemenu.ArticleMenu(tw, tb, self.n)

        tb.insert('end', self.n[4])
        tb.config(state=DISABLED)
        link = Label(tw, text=self.n[2])
        link.configure(foreground='blue', cursor='hand2')
        link.bind('<1>', self.op_link)
        auth = Label(tw, text='Author: ' + self.n[3])
        articledate = Label(tw, text='Date Published: ' + self.n[0])

        # window formatting for tw
        link.place(x=0, y=0, relwidth=1)
        tb.place(y=20, relwidth=1, relheight=1)
        auth.pack(side=LEFT, anchor='sw')
        articledate.pack(side=RIGHT, anchor='se')

    # op_link "double click on the link at the top of the page opens up the url link
    def op_link(self, event):
        webbrowser.open_new(self.n[2])

    def callEnable(self, event, searchtype):
        self.helper.callenable(event, searchtype)

    def updateuntildata(self, q, progress):
        while q.empty():
            time.sleep(.01)
            progress.step(1)
            progress.master.update()

    def processingloop(self, updatetype):
        string = self.resultTopics.cget('text')
        if len(string) and string[0] == 'P':
            if updatetype == 'percent':
                if not self.master.master.updateque.empty():
                    string = "{}({}%)".format(
                        re.search('Processing Data(\.|\s)*', string).group(0),
                        str(self.master.master.updateque.get(0)))
                    self.after(300, lambda: self.processingloop('percent'))
                else:
                    self.after(100, lambda: self.processingloop('percent'))
            elif updatetype == 'dots':
                numdots = len(string.split('.')) % 4
                string = "Processing Data" + numdots * '.' + (
                    3 - numdots) * ' ' + re.search('\(.+\)', string).group(0)
                self.after(300, lambda: self.processingloop('dots'))

        self.resultTopics.config(text=string)

    def treeview_sort_column(self, tv, col, reverse=False):
        l = [(tv.set(k, col), k) for k in tv.get_children('')]
        if col == 'date':
            l.sort(key=lambda t: "{}/{}/{}".format(t[0].split('/')[2], t[
                0].split('/')[0], t[0].split('/')[1]),
                   reverse=reverse)
        else:
            l.sort(key=lambda t: t[0], reverse=reverse)

        for index, (val, k) in enumerate(l):
            tv.move(k, '', index)

        for count, child in enumerate(tv.get_children()):
            tagn = 'even' if count % 2 == 0 else 'odd'
            tv.item(child, tag=tagn)

        tv.heading(
            col,
            command=lambda: self.treeview_sort_column(tv, col, not reverse))