Skip to content

Commit 169b973

Browse files
committed
search by player name
1 parent 223c811 commit 169b973

7 files changed

Lines changed: 650 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.exe
2+
*.dll
3+
*/.

app.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from layout import app_layout
2+
3+
class scraper:
4+
def __init__(self):
5+
self.app = True
6+
7+
def main(self):
8+
self.layout = app_layout()
9+
self.window = self.layout.main()
10+
11+
app = scraper()
12+
app.main()

layout.py

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
from tkinter.scrolledtext import ScrolledText
2+
from tkinter.ttk import *
3+
from tkinter import *
4+
from tkinter import font as tkFont
5+
import tkinter.messagebox as tkm
6+
from sofifa import sofifa
7+
from pes6es import pes6es
8+
9+
class app_layout:
10+
def __init__(self):
11+
self.__appname = 'SoFIFA Scraper'
12+
self.__pad = 5
13+
self.__win = Tk()
14+
self.__win.title(self.__appname)
15+
self.__win.iconbitmap('logo.ico')
16+
self.__win.resizable(False, False)
17+
self.player_list = []
18+
self.column_sort = 0
19+
self.pes6es = pes6es()
20+
self.sofifa = sofifa()
21+
self.__font = tkFont.Font(family='Consolas', size=10, weight='normal')
22+
self.__bgcolor = '#6633FF'
23+
self.__fgcolor = '#FFFFFF'
24+
self.__style = Style()
25+
self.__player_stats = ''
26+
27+
def __window_close(self):
28+
if tkm.askokcancel(self.__appname, 'Do you want to quit?'):
29+
self.__win.destroy()
30+
31+
def __about_app(self):
32+
msg = 'Edgar Santa Rosa (C) 2022\nGitHub: https://github.com/EdgarOSR'
33+
tkm.showinfo(self.__appname, msg)
34+
35+
### APP LAYOUT: BUTTONS, LABELS, ENTRIES ###
36+
def __app_labels(self):
37+
self.lbGame = Label(self.__win)
38+
self.lbVersion = Label(self.__win)
39+
self.lbCountry = Label(self.__win)
40+
self.lbClub = Label(self.__win)
41+
self.lbMinOvr = Label(self.__win)
42+
self.lbMaxOvr = Label(self.__win)
43+
self.lbSearch = Label(self.__win)
44+
self.lbPlayerID = Label(self.__win)
45+
self.lbPlayerName = Label(self.__win)
46+
47+
def __app_entries(self):
48+
self.txGame = Combobox(self.__win)
49+
self.txVersion = Combobox(self.__win)
50+
self.txCountry = Combobox(self.__win)
51+
self.txClub = Combobox(self.__win)
52+
self.txMinOvr = Combobox(self.__win)
53+
self.txMaxOvr = Combobox(self.__win)
54+
self.txSearch = Combobox(self.__win)
55+
self.txPlayerID = Entry(self.__win)
56+
self.txPlayerName = Entry(self.__win)
57+
self.txGameHidden = Combobox(self.__win)
58+
self.txVersionHidden = Combobox(self.__win)
59+
self.txCountryHidden = Combobox(self.__win)
60+
self.txClubHidden = Combobox(self.__win)
61+
self.txPlayerList = Treeview(self.__win)
62+
63+
def __app_buttons(self):
64+
self.btConvert = Button(self.__win)
65+
self.btClipboard = Button(self.__win)
66+
self.btAbout = Button(self.__win)
67+
self.btConvertClassic = Button(self.__win)
68+
69+
def __app_config(self):
70+
self.__win.option_add('*TCombobox*Listbox.font', self.__font)
71+
self.__style.configure('Treeview', font=self.__font)
72+
self.lbGame.config(text='Game', width=10, justify='left', font=self.__font, anchor='w')
73+
self.lbVersion.config(text='Version', width=10, justify='left', font=self.__font, anchor='w')
74+
self.lbCountry.config(text='Country', width=10, justify='left', font=self.__font, anchor='w')
75+
self.lbClub.config(text='Club', width=10, justify='left', font=self.__font, anchor='w')
76+
self.lbMinOvr.config(text='MinOVR', width=10, justify='left', font=self.__font, anchor='w')
77+
self.lbMaxOvr.config(text='MaxOVR', width=10, justify='left', font=self.__font, anchor='w')
78+
self.lbSearch.config(text='SearchType', width=10, justify='left', font=self.__font, anchor='w')
79+
self.lbPlayerID.config(text='PlayerID', width=10, justify='left', font=self.__font, anchor='w')
80+
self.lbPlayerName.config(text='PlayerName', width=10, justify='left', font=self.__font, anchor='w')
81+
self.btConvertClassic.config(text='Old Stats', width=20, bg=self.__bgcolor, fg=self.__fgcolor, font=self.__font)
82+
self.btConvert.config(text='Convert', width=20, bg=self.__bgcolor, fg=self.__fgcolor, font=self.__font)
83+
self.btClipboard.config(text='Clipboard', width=20, bg=self.__bgcolor, fg=self.__fgcolor, font=self.__font)
84+
self.btAbout.config(text='About', width=10, bg=self.__bgcolor, fg=self.__fgcolor, font=self.__font)
85+
self.txGame.config(width=20, state='readonly', values='', font=self.__font)
86+
self.txVersion.config(width=20, state='readonly', values='', font=self.__font)
87+
self.txCountry.config(width=20, state='readonly', values='', font=self.__font)
88+
self.txClub.config(width=20, state='readonly', values='', font=self.__font)
89+
self.txMinOvr.config(width=20, state='readonly', values='', font=self.__font)
90+
self.txMaxOvr.config(width=20, state='readonly', values='', font=self.__font)
91+
self.txSearch.config(width=20, state='readonly', values='', font=self.__font)
92+
self.txPlayerID.config(width=20, state='normal', font=self.__font)
93+
self.txPlayerName.config(width=20, state='normal', font=self.__font)
94+
self.txGameHidden.config(width=20, state='readonly', values='', font=self.__font)
95+
self.txVersionHidden.config(width=20, state='readonly', values='', font=self.__font)
96+
self.txCountryHidden.config(width=20, state='readonly', values='', font=self.__font)
97+
self.txClubHidden.config(width=20, state='readonly', values='', font=self.__font)
98+
self.txPlayerList.config(show='headings', selectmode='browse', columns=('bov','name','nation','pos','club'), height=20)
99+
self.txPlayerList.heading('bov', text='▲ OVR')
100+
self.txPlayerList.heading('name', text='NAME')
101+
self.txPlayerList.heading('club', text='CLUB')
102+
self.txPlayerList.heading('pos', text='POS')
103+
self.txPlayerList.heading('nation', text='NATION')
104+
self.txPlayerList.column('bov', width=48)
105+
self.txPlayerList.column('name', width=150)
106+
self.txPlayerList.column('nation', width=120)
107+
self.txPlayerList.column('pos', width=48)
108+
self.txPlayerList.column('club', width=180)
109+
110+
def __reset_tree_columns(self):
111+
self.txPlayerList.heading('bov', text='OVR')
112+
self.txPlayerList.heading('name', text='NAME')
113+
self.txPlayerList.heading('nation', text='NATION')
114+
self.txPlayerList.heading('pos', text='POS')
115+
self.txPlayerList.heading('club', text='CLUB')
116+
117+
def __app_grid_config(self):
118+
self.lbGame.grid(column=0, row=1, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
119+
self.lbVersion.grid(column=0, row=2, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
120+
self.lbCountry.grid(column=0, row=3, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
121+
self.lbClub.grid(column=0, row=4, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
122+
self.lbMinOvr.grid(column=0, row=5, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
123+
self.lbMaxOvr.grid(column=0, row=6, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
124+
self.lbSearch.grid(column=0, row=7, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
125+
self.lbPlayerName.grid(column=0, row=8, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
126+
# self.lbPlayerID.grid(column=0, row=9, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
127+
self.btAbout.grid(column=0, row=10, padx=self.__pad, pady=self.__pad, columnspan=2, sticky='nsew')
128+
self.btClipboard.grid(column=0, row=11, padx=self.__pad, pady=self.__pad, columnspan=2, sticky='nsew')
129+
self.btConvertClassic.grid(column=0, row=12, padx=self.__pad, pady=self.__pad, columnspan=2, sticky='nsew')
130+
self.btConvert.grid(column=0, row=13, padx=self.__pad, pady=self.__pad, columnspan=2, sticky='nsew')
131+
self.txGame.grid(column=1, row=1, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
132+
self.txVersion.grid(column=1, row=2, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
133+
self.txCountry.grid(column=1, row=3, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
134+
self.txClub.grid(column=1, row=4, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
135+
self.txMinOvr.grid(column=1, row=5, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
136+
self.txMaxOvr.grid(column=1, row=6, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
137+
self.txSearch.grid(column=1, row=7, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
138+
self.txPlayerName.grid(column=1, row=8, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
139+
# self.txPlayerID.grid(column=1, row=9, padx=self.__pad, pady=self.__pad, columnspan=1, sticky='nsew')
140+
self.txPlayerList.grid(column=2, row=0, padx=self.__pad, pady=self.__pad, columnspan=2, sticky='nsew', rowspan=14)
141+
142+
### SCRAP COMBO BOXES VALUES ###
143+
def load_combo_game(self):
144+
self.txGame['values'], self.txGameHidden['values'] = self.sofifa.get_games()
145+
self.txGame.current(0)
146+
self.txGameHidden.current(0)
147+
148+
def load_combo_version(self):
149+
game = str(self.txGameHidden.get())
150+
self.txVersion['values'], self.txVersionHidden['values'] = self.sofifa.get_versions(game)
151+
self.txVersion.current(0)
152+
self.txVersionHidden.current(0)
153+
154+
def load_combo_country(self):
155+
self.txCountry['values'], self.txCountryHidden['values'] = self.sofifa.get_countries()
156+
self.txCountry.current(0)
157+
self.txCountryHidden.current(0)
158+
159+
def load_combo_player(self):
160+
nation = str(self.txCountryHidden.get())
161+
club = int(self.txClubHidden.get())
162+
min_ovr = str(self.txMinOvr.get())
163+
max_ovr = str(self.txMaxOvr.get())
164+
version = str(self.txVersionHidden.get())
165+
selection = self.txSearch.get().lower()
166+
player_name = str(self.txPlayerName.get()).replace(' ','%20')
167+
self.player_list = self.sofifa.get_players(selection, nation, club, min_ovr, max_ovr, version, player_name)
168+
169+
def load_combo_club(self):
170+
nation = str(self.txCountryHidden.get())
171+
version = str(self.txVersionHidden.get())
172+
if(nation == 0):
173+
self.txClub['values'], self.txClubHidden['values'] = ('None', 'None'), (0, 0)
174+
else:
175+
self.txClub['values'], self.txClubHidden['values'] = self.sofifa.get_clubs(nation, version)
176+
self.txClub.current(0)
177+
self.txClubHidden.current(0)
178+
self.load_combo_player()
179+
self.__sort_player_list()
180+
181+
### COMMANDS ###
182+
def __on_select_game(self, event):
183+
index = self.txGame.current()
184+
self.txGameHidden.current(index)
185+
self.load_combo_version()
186+
self.load_combo_club()
187+
188+
def __on_select_player(self, event):
189+
index = self.txPlayerList.selection()[0]
190+
curItem = self.txPlayerList.focus()
191+
loc_value = self.txPlayerList.set(curItem, column='name')
192+
self.__win.clipboard_clear()
193+
self.__win.clipboard_append(loc_value)
194+
self.txPlayerID.delete(0,END)
195+
self.txPlayerID.insert(0, index)
196+
197+
def __sort_player_list(self):
198+
for item in self.txPlayerList.get_children():
199+
self.txPlayerList.delete(item)
200+
self.txPlayerID.delete(0,END)
201+
if(len(self.player_list) > 0):
202+
if(self.column_sort == 0):
203+
self.player_list.sort(key=lambda x:x[self.column_sort], reverse=True)
204+
else:
205+
self.player_list.sort(key=lambda x:x[self.column_sort], reverse=False)
206+
for player in self.player_list:
207+
self.txPlayerList.insert('', 'end', player[5], values=(player[0], player[1], player[4], player[3], player[2]))
208+
self.txPlayerList.selection_set(self.txPlayerList.get_children()[0])
209+
self.txPlayerID.insert(0, self.txPlayerList.selection()[0])
210+
else:
211+
self.txPlayerList.insert('', 'end', 0, values=(0,'Not found', 'None', 'None', 'None'))
212+
213+
def __sort_tree_columns(self, column_index):
214+
self.__reset_tree_columns()
215+
self.column_sort = column_index
216+
if column_index == 0:
217+
self.txPlayerList.heading('bov', text='▲ OVR')
218+
elif column_index == 1:
219+
self.txPlayerList.heading('name', text='▼ NAME')
220+
elif column_index == 2:
221+
self.txPlayerList.heading('club', text='▼ CLUB')
222+
elif column_index == 3:
223+
self.txPlayerList.heading('pos', text='▼ POS')
224+
elif column_index == 4:
225+
self.txPlayerList.heading('nation', text='▼ NATION')
226+
self.__sort_player_list()
227+
228+
def __on_select_clubs(self, event):
229+
index = self.txClub.current()
230+
self.txClubHidden.current(index)
231+
self.load_combo_player()
232+
self.__sort_player_list()
233+
234+
def __on_select_version_country(self, event):
235+
index = self.txVersion.current()
236+
self.txVersionHidden.current(index)
237+
index = self.txCountry.current()
238+
self.txCountryHidden.current(index)
239+
self.load_combo_club()
240+
self.__on_select_clubs(event)
241+
242+
def __binding_values(self):
243+
self.txGame.bind('<<ComboboxSelected>>', self.__on_select_game)
244+
self.txVersion.bind('<<ComboboxSelected>>', self.__on_select_version_country)
245+
self.txCountry.bind('<<ComboboxSelected>>', self.__on_select_version_country)
246+
self.txClub.bind('<<ComboboxSelected>>', self.__on_select_clubs)
247+
self.txSearch.bind('<<ComboboxSelected>>', self.__on_select_clubs)
248+
self.txMinOvr.bind('<<ComboboxSelected>>', self.__on_select_clubs)
249+
self.txMaxOvr.bind('<<ComboboxSelected>>', self.__on_select_clubs)
250+
self.txPlayerList.bind('<ButtonRelease-1>', self.__on_select_player)
251+
self.txPlayerName.bind('<Return>', self.__on_select_clubs)
252+
253+
def __set_commands(self):
254+
self.btConvertClassic.config(command=self.__search_stats_classic)
255+
self.btConvert.config(command=self.__search_stats_online)
256+
self.btClipboard.config(command=self.__copy_to_clipboard)
257+
self.btAbout.config(command=self.__about_app)
258+
self.txPlayerList.heading('bov', command=lambda: self.__sort_tree_columns(0))
259+
self.txPlayerList.heading('name', command=lambda: self.__sort_tree_columns(1))
260+
self.txPlayerList.heading('club', command=lambda: self.__sort_tree_columns(2))
261+
self.txPlayerList.heading('pos', command=lambda: self.__sort_tree_columns(3))
262+
self.txPlayerList.heading('nation', command=lambda: self.__sort_tree_columns(4))
263+
264+
# def __backup_stats(self):
265+
# player = str(self.txPlayerID.get())
266+
# version = str(self.txGameHidden.get())
267+
# nation = str(self.txCountry.get())
268+
# file_obj = open(f'statsdb/{nation}_{player}_{version}.txt', 'w')
269+
# file_obj.write(str(self.__player_stats))
270+
# file_obj.close()
271+
272+
def __copy_to_clipboard(self):
273+
self.__win.clipboard_clear()
274+
self.__win.clipboard_append(str(self.__player_stats))
275+
276+
def __search_stats_online(self):
277+
player = str(self.txPlayerID.get())
278+
if(player.isnumeric() == True):
279+
self.__player_stats = self.pes6es.convert_player(player)
280+
self.__copy_to_clipboard()
281+
else:
282+
tkm.showwarning(self.__appname, 'You must select a player first!')
283+
284+
def __search_stats_classic(self):
285+
player = str(self.txPlayerID.get())
286+
version = str(self.txGameHidden.get())
287+
season = str(self.txVersion.get())
288+
season = str(season[len(season)-4:len(season)])
289+
json = self.sofifa.player_json(player, version, season)
290+
if(player.isnumeric() == True):
291+
self.__player_stats = self.pes6es.convert_offline(json)
292+
self.__copy_to_clipboard()
293+
else:
294+
tkm.showwarning(self.__appname, 'You must select a player first!')
295+
296+
def __load_default_values(self):
297+
self.load_combo_game()
298+
self.load_combo_version()
299+
self.load_combo_country()
300+
self.txMinOvr['values'] = (60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99)
301+
self.txMinOvr.current(10)
302+
self.txMaxOvr['values'] = (60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99)
303+
self.txMaxOvr.current(END)
304+
self.txSearch['values'] = ('All', 'Updated', 'Removed', 'Free', 'Added')
305+
self.txSearch.current(0)
306+
self.load_combo_club()
307+
308+
def main(self):
309+
self.__app_labels()
310+
self.__app_entries()
311+
self.__app_buttons()
312+
self.__app_config()
313+
self.__app_grid_config()
314+
self.__binding_values()
315+
self.__set_commands()
316+
self.__load_default_values()
317+
self.__win.protocol('WM_DELETE_WINDOW', self.__window_close)
318+
self.__win.mainloop()

logo.ico

66.1 KB
Binary file not shown.

pes6es.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.chrome.options import Options
4+
from selenium.webdriver.chrome.service import Service as ChromeService
5+
from webdriver_manager.chrome import ChromeDriverManager
6+
from subprocess import CREATE_NO_WINDOW
7+
8+
class pes6es:
9+
def __init__(self):
10+
self.url = 'https://www.pes6.es/stats/fifa-to-pes6.php'
11+
12+
def __drive_initialize(self):
13+
chrome_service = ChromeService(ChromeDriverManager().install())
14+
chrome_service.creationflags = CREATE_NO_WINDOW
15+
chrome_options = Options()
16+
chrome_options.add_argument('--disable-extensions')
17+
chrome_options.add_argument('--headless')
18+
self.driver = webdriver.Chrome(service=chrome_service, options=chrome_options)
19+
20+
def __drive_close(self):
21+
self.driver.quit()
22+
23+
def convert_offline(self, json):
24+
self.__drive_initialize()
25+
self.driver.get(self.url)
26+
self.driver.find_element(By.CSS_SELECTOR, '#showManualStats').click()
27+
self.driver.find_element(By.CSS_SELECTOR, '#offlineStats').clear()
28+
self.driver.find_element(By.CSS_SELECTOR, '#offlineStats').send_keys(str(json))
29+
self.driver.find_element(By.CSS_SELECTOR, '#convertOffline').click()
30+
response = ''
31+
while response == '':
32+
response = self.driver.find_element(By.CSS_SELECTOR, '#statsToCopy').text.strip()
33+
response = response.replace('★','*')
34+
self.__drive_close()
35+
return response
36+
37+
def convert_player(self, player):
38+
self.__drive_initialize()
39+
self.driver.get(self.url)
40+
self.driver.find_element(By.CSS_SELECTOR, '#freeSoFifa').clear()
41+
self.driver.find_element(By.CSS_SELECTOR, '#freeSoFifa').send_keys(str(player))
42+
self.driver.find_element(By.CSS_SELECTOR, '#convertFreeSoFifa').click()
43+
response = ''
44+
while response == '':
45+
response = self.driver.find_element(By.CSS_SELECTOR, '#statsToCopy').text.strip()
46+
response = response = response.replace('★','*')
47+
self.__drive_close()
48+
return response

0 commit comments

Comments
 (0)