Merge branch 'master' of git://git.assembla.com/fpdb-gimick
This commit is contained in:
commit
a0d31bc33a
|
@ -109,9 +109,9 @@ class RushNotes(Aux_Window):
|
||||||
notepath = site_params_dict['site_path'] # this is a temporary hijack of site-path
|
notepath = site_params_dict['site_path'] # this is a temporary hijack of site-path
|
||||||
self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
|
self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
|
||||||
self.notefile = notepath + "/" + heroname + ".xml"
|
self.notefile = notepath + "/" + heroname + ".xml"
|
||||||
self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom")
|
self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom", "Apollo")
|
||||||
|
|
||||||
if not os.path.isfile(self.notefile):
|
if not (os.path.isfile(self.notefile)):
|
||||||
self.active = False
|
self.active = False
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -130,29 +130,34 @@ class RushNotes(Aux_Window):
|
||||||
xmlnotefile.unlink
|
xmlnotefile.unlink
|
||||||
|
|
||||||
#
|
#
|
||||||
# Create a fresh queue file with skeleton XML
|
# if queue file does not exist create a fresh queue file with skeleton XML
|
||||||
|
# This is possibly not totally safe, if multiple threads arrive
|
||||||
|
# here at the same time, but the consequences are not serious
|
||||||
#
|
#
|
||||||
|
|
||||||
self.queuefile = self.notefile + ".queue"
|
self.queuefile = self.notefile + ".queue"
|
||||||
queuedom = minidom.Document()
|
if not (os.path.isfile(self.queuefile)):
|
||||||
|
|
||||||
pld=queuedom.createElement("PLAYERDATA")
|
queuedom = minidom.Document()
|
||||||
queuedom.appendChild(pld)
|
|
||||||
|
|
||||||
nts=queuedom.createElement("NOTES")
|
pld=queuedom.createElement("PLAYERDATA")
|
||||||
pld.appendChild(nts)
|
queuedom.appendChild(pld)
|
||||||
|
|
||||||
nte = queuedom.createElement("NOTE")
|
nts=queuedom.createElement("NOTES")
|
||||||
nte = queuedom.createTextNode("\n")
|
pld.appendChild(nts)
|
||||||
nts.insertBefore(nte,None)
|
|
||||||
|
|
||||||
outputfile = open(self.queuefile, 'w')
|
nte = queuedom.createElement("NOTE")
|
||||||
queuedom.writexml(outputfile)
|
nte = queuedom.createTextNode("\n")
|
||||||
outputfile.close()
|
nts.insertBefore(nte,None)
|
||||||
queuedom.unlink
|
|
||||||
|
outputfile = open(self.queuefile, 'w')
|
||||||
|
queuedom.writexml(outputfile)
|
||||||
|
outputfile.close()
|
||||||
|
queuedom.unlink
|
||||||
|
|
||||||
if (debugmode):
|
if (debugmode):
|
||||||
#initialise logfiles
|
#initialise logfiles
|
||||||
debugfile=open("~Rushdebug.init", "w")
|
debugfile=open("~Rushdebug.init", "a")
|
||||||
debugfile.write("conf="+str(config)+"\n")
|
debugfile.write("conf="+str(config)+"\n")
|
||||||
debugfile.write("spdi="+str(site_params_dict)+"\n")
|
debugfile.write("spdi="+str(site_params_dict)+"\n")
|
||||||
debugfile.write("para="+str(params)+"\n")
|
debugfile.write("para="+str(params)+"\n")
|
||||||
|
@ -161,8 +166,6 @@ class RushNotes(Aux_Window):
|
||||||
debugfile.write("queu="+self.queuefile+"\n")
|
debugfile.write("queu="+self.queuefile+"\n")
|
||||||
debugfile.close()
|
debugfile.close()
|
||||||
|
|
||||||
open("~Rushdebug.data", "w").close()
|
|
||||||
|
|
||||||
|
|
||||||
def update_data(self, new_hand_id, db_connection):
|
def update_data(self, new_hand_id, db_connection):
|
||||||
#this method called once for every hand processed
|
#this method called once for every hand processed
|
||||||
|
@ -204,16 +207,19 @@ class RushNotes(Aux_Window):
|
||||||
vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
|
vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
|
||||||
pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
|
pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
|
||||||
three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
|
three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
|
||||||
|
four_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'four_B')[3] + " ")
|
||||||
cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
|
cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
|
||||||
|
|
||||||
fbbsteal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_BB_steal')[3] + " ")
|
fbbsteal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_BB_steal')[3] + " ")
|
||||||
|
f_3bet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_3bet')[3] + " ")
|
||||||
|
f_4bet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_4bet')[3] + " ")
|
||||||
|
|
||||||
steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
|
steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
|
||||||
ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
|
ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
|
||||||
agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
|
agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
|
||||||
BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3])
|
BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3])
|
||||||
if BBper100[6] == "-": BBper100=BBper100[0:6] + "(" + BBper100[7:] + ")"
|
if BBper100[6] == "-": BBper100=BBper100[0:6] + "(" + BBper100[7:] + ")"
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# grab villain known starting hands
|
# grab villain known starting hands
|
||||||
# only those where they VPIP'd, so limp in the BB will not be shown
|
# only those where they VPIP'd, so limp in the BB will not be shown
|
||||||
|
@ -269,10 +275,13 @@ class RushNotes(Aux_Window):
|
||||||
# for later search/replace by Merge module
|
# for later search/replace by Merge module
|
||||||
#
|
#
|
||||||
xmlqueuedict[playername] = ("~fpdb~" + "\n" +
|
xmlqueuedict[playername] = ("~fpdb~" + "\n" +
|
||||||
n + vpip + pfr + three_B + fbbsteal + "\n" +
|
n + vpip + pfr + "\n" +
|
||||||
steal + cbet + ffreq1 + "\n" +
|
steal + cbet + fbbsteal + ffreq1 + "\n" +
|
||||||
|
three_B + four_B + f_3bet + f_4bet + "\n" +
|
||||||
agg_freq + BBper100 + "\n" +
|
agg_freq + BBper100 + "\n" +
|
||||||
PFcall+"\n"+PFaggr+"\n"+PFdefend +"\n"
|
PFcall+"\n"+
|
||||||
|
PFaggr+"\n"+
|
||||||
|
PFdefend +"\n"+
|
||||||
"~ends~")
|
"~ends~")
|
||||||
|
|
||||||
if (debugmode):
|
if (debugmode):
|
||||||
|
|
|
@ -105,8 +105,6 @@ if not os.path.isfile(sys.argv[1]):
|
||||||
|
|
||||||
if not os.path.isfile((sys.argv[1]+".queue")):
|
if not os.path.isfile((sys.argv[1]+".queue")):
|
||||||
print "Nothing found to merge, quitting"
|
print "Nothing found to merge, quitting"
|
||||||
print "Did the HUD not get started during the last session?"
|
|
||||||
print "Has the HUD been stopped and started without merging?"
|
|
||||||
quit()
|
quit()
|
||||||
|
|
||||||
print "***************************************************************"
|
print "***************************************************************"
|
||||||
|
@ -117,7 +115,7 @@ print "has stopped completely"
|
||||||
print "***************************************************************"
|
print "***************************************************************"
|
||||||
print
|
print
|
||||||
print "read from: ", sys.argv[1]
|
print "read from: ", sys.argv[1]
|
||||||
print "merge with: ", sys.argv[1]+".queue"
|
print "updated with: ", sys.argv[1]+".queue"
|
||||||
|
|
||||||
#read queue and turn into a dict
|
#read queue and turn into a dict
|
||||||
queuedict = {}
|
queuedict = {}
|
||||||
|
@ -172,7 +170,7 @@ mergednotes.close()
|
||||||
|
|
||||||
xmlnotefile.unlink
|
xmlnotefile.unlink
|
||||||
|
|
||||||
print "Merged file has been written to: ", sys.argv[1]+".merged"
|
print "written to: ", sys.argv[1]+".merged"
|
||||||
print ""
|
print ""
|
||||||
print "number in queue: ", statqueue
|
print "number in queue: ", statqueue
|
||||||
print "existing players updated: ", statupdated
|
print "existing players updated: ", statupdated
|
||||||
|
@ -180,5 +178,7 @@ print "new players added: ", statadded
|
||||||
print "\n"
|
print "\n"
|
||||||
print "Use a viewer to check the contents of the merge file."
|
print "Use a viewer to check the contents of the merge file."
|
||||||
print "If you are happy, carry out the following steps:"
|
print "If you are happy, carry out the following steps:"
|
||||||
print "1 Rename or delete the existing notes file (normally <heroname>.xml"
|
print "1 Rename or delete the existing notes file (normally <heroname>.xml)"
|
||||||
print "2 Rename the .merged file to become the new notes file"
|
print "2 Rename the .merged file to become the new notes file"
|
||||||
|
print "3 Delete the .queue file (it will be created at the next rush autoimport)"
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,6 @@ Important info:
|
||||||
The Merge process can only be run when ftp client is shutdown
|
The Merge process can only be run when ftp client is shutdown
|
||||||
- otherwise ftp overwrites the xml on exit.
|
- otherwise ftp overwrites the xml on exit.
|
||||||
|
|
||||||
Restarting the autoimport will empty the notes"queue" so avoid restarting
|
|
||||||
autoimport until the previous notes "queue" has been merged. You will
|
|
||||||
lose all the queued notes, but these will be regenerated the next time
|
|
||||||
the villian is at your table, so it isn't the end of the world.
|
|
||||||
|
|
||||||
Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed,
|
Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed,
|
||||||
you have been warned!
|
you have been warned!
|
||||||
|
|
||||||
|
@ -27,7 +22,8 @@ Existing colour codings should be preserved,
|
||||||
this process does not change or set colourcodings.
|
this process does not change or set colourcodings.
|
||||||
|
|
||||||
Copies of the live ftp notes file should be preserved everytime
|
Copies of the live ftp notes file should be preserved everytime
|
||||||
RushNotesAux (i.e. the HUD is started)
|
RushNotesAux (i.e. the HUD is started). If you play at different
|
||||||
|
rush tables, the backup will be created several times.
|
||||||
|
|
||||||
The AW is hard-coded with just the table names of Micro Rush Poker,
|
The AW is hard-coded with just the table names of Micro Rush Poker,
|
||||||
and should ignore all other hands.
|
and should ignore all other hands.
|
||||||
|
@ -35,7 +31,7 @@ The AW is hard-coded with just the table names of Micro Rush Poker,
|
||||||
What might not work?
|
What might not work?
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
This isn't tested with Windows, and probably won't work, feedback welcome.
|
This should work with windows sourcecode version, but will not work with the exe download.
|
||||||
Hasn't been tested for co-existance with other sites, feedback welcome.
|
Hasn't been tested for co-existance with other sites, feedback welcome.
|
||||||
Whenever FTP change their notes file format, this will all break rather spectacularly,
|
Whenever FTP change their notes file format, this will all break rather spectacularly,
|
||||||
you have been warned!
|
you have been warned!
|
||||||
|
@ -77,7 +73,7 @@ execute the following:
|
||||||
./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
|
./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
|
||||||
|
|
||||||
A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
|
A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
|
||||||
If you are happy with it, replace the existing (myname.xml file)
|
If you are happy with it, replace the existing (myname.xml file) and delete the .queue file.
|
||||||
|
|
||||||
|
|
||||||
Since the updates aren't real time, it would be ok to play the rush
|
Since the updates aren't real time, it would be ok to play the rush
|
||||||
|
@ -176,7 +172,7 @@ Process overview
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
1/ The HUD process is started.
|
1/ The HUD process is started.
|
||||||
1.1/ when the first hand is received, h fresh holding file is created, and
|
1.1/ when the first hand is received, a queue file is created if not already there, and
|
||||||
a copy of the current live xml note file is created as a security backup.
|
a copy of the current live xml note file is created as a security backup.
|
||||||
2/ For every hand played, the auxillary window is called
|
2/ For every hand played, the auxillary window is called
|
||||||
3/ Based upon the players in the hand, fpdb will be interrogated
|
3/ Based upon the players in the hand, fpdb will be interrogated
|
||||||
|
@ -191,4 +187,4 @@ existing notes, but this cannot be guaranteed.
|
||||||
they replace the existing note file.
|
they replace the existing note file.
|
||||||
9/ Note that this process never updates the live notes file in situ, but
|
9/ Note that this process never updates the live notes file in situ, but
|
||||||
there is a risk that something goes wrong, and that existing notes could be destroyed.
|
there is a risk that something goes wrong, and that existing notes could be destroyed.
|
||||||
|
10/ the queue file can be deleted to reduce re-processing next time.
|
||||||
|
|
|
@ -2294,7 +2294,7 @@ class Sql:
|
||||||
end AS pofafq
|
end AS pofafq
|
||||||
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
||||||
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
||||||
end AS aggfac
|
end AS aggfac
|
||||||
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
||||||
|
@ -2415,7 +2415,7 @@ class Sql:
|
||||||
end AS pofafq
|
end AS pofafq
|
||||||
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
||||||
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
||||||
end AS aggfac
|
end AS aggfac
|
||||||
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
||||||
|
@ -2537,7 +2537,7 @@ class Sql:
|
||||||
end AS pofafq
|
end AS pofafq
|
||||||
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
|
||||||
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
|
||||||
end AS aggfac
|
end AS aggfac
|
||||||
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
|
||||||
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
|
||||||
|
|
Loading…
Reference in New Issue
Block a user