Cannot delete Room Calendar item with exchagelib code - exchangewebservices

My problem looks weird.
Exchange 2010 SP1. Code looks for conflicting record in Room Calendar and suposed to delete it.
Code looks like:
#DELEGATE also doesn't work
roomAccount = Account(primary_smtp_address=room_mailbox, config=config,
autodiscover=False, access_type=IMPERSONATION)
items = roomAccount.calendar.filter(start__gt=now_with_past)
for item in items:
if (start_dt_ews != start_dt_remote or item.subject != remote_record_subject or duration != remote_record_duration):
has_conflicts = detect_conflicts(roomAccount, item)
if has_conflicts:
process_conflict(item, 'update_conflict')
remove_meeting_data(item, item.organizer)
continue
def detect_conflicts(roomAccount, item):
try:
has_conflicts = False
if item.conflicting_meeting_count > 0:
if item.start_dt != item.start:
has_conflicts = True
return has_conflicts
except Exception as e:
trace_back = traceback.format_exc()
log_str = "Error in process_service " + str(e) + " " + str(trace_back)
Logger.error(log_str)
return False
def process_conflict(item, category):
if item.recurrence:
conflict_notify_and_delete(item, category, True)
else:
conflict_notify_and_delete(item, category, False)
Logger.error(item.subject + " meeting conflict error.")
def conflict_notify_and_delete(item, category, serial):
send_email(item.organizer, category, (item.subject))
try:
if serial:
item.delete(affected_task_occurrences=ALL_OCCURRENCIES)
item.save()
else:
# doesn't work
item.delete(send_meeting_cancellations=SEND_TO_NONE,
affected_task_occurrences=ALL_OCCURRENCIES)
# or also doesn't work
item.delete()
# or raise trash folder absense error.
item.move_to_trash()
# or raise trash folder absense error again.
item.soft_delete()
#abrakadabra atempts with rescheduling and subsequent deletion raise
# "Set action is invalid for property. (field: FieldURI(field_uri='calendar:StartTimeZone'))" error
item.start = UTC_NOW() + timedelta(days=6000)
item.save(update_fields=['start'])
item.delete()
The strangest fact about all this - any of delete() processing simply silent - no errors, no exceptions, everything looks like to be just fine while actually nothing is deleted of modified.. Second strangest fact - sometimes but not every time i'm trying to item.save() after item.delete() , it raise " AttributeError("Folder must be supplied when in save-only mode")", but item may be deleted at once. And may be not :((
This weird things happen only in part of code that process conflicting calendar items. Notconflicting items processing is fine - deleting and modifiying are ok.
Does anybody has any idea, what is going on and how to finally delete conflicting record from Room calendar without canceling a meeting from organizers's calendar - we do not want user to loose his item and information inside it? I've tried to google EWS setiings that can cause such weirdness but with no luck :(

Related

Weird KeyError (Python)

So, I have to work with this JSON (from URL):
{'player': {'racing': 25260.154000000017, 'player': 259114.57700000296}, 'farming': {'fishing': 33783.390999999414, 'mining': 29048.60500000002, 'farming': 25334.504000000023}, 'piloting': {'piloting': 25570.18800000001, 'cargos': 3080.713000000036, 'heli': 10433.977000000004}, 'physical': {'strength': 198358.86700000675}, 'business': {'business': 50922.88500000005}, 'trucking': {'mechanic': 2724.5620000000004, 'garbage': 755.642999999997, 'trucking': 223784.99700000713, 'postop': 1411.4190000000006}, 'train': {'bus': 669.1940000000001, 'train': 1363.805999999999}, 'ems': {'fire': 25449.43400000001, 'ems': 13844.628000000012}, 'hunting': {'skill': 4179.033000000316}, 'casino': {'casino': 18545.526000000027}}
It is indeed one line. I am trying to make it so that for example, I can get racing, which is the first one you see. For this, you need go into Player first, and then you can get to Racing. How do I do this?
My current code:
def allthethings():
# Grab all the skills
geturl = ("http://server.tycoon.community:30120/status/data/" + str(setting_playerid))
print(geturl)
a = requests.get(geturl,headers={"X-Tycoon-Key":setting_apikeyTT}).json()
jsonconverted = (a["data"]["gaptitudes_v"])
print(jsonconverted)
# Convert JSON into many, many variables
Raw_RACR = jsonconverted['player.racing']
print(Raw_RACR)
I believe this is all the code that is needed.
Also, this is the error:
KeyError: 'player.racing'

Is a "Try / Except ValueError UNLESS" possible?

I'm new to python and have been trying like hell for the past few hours to figure out how to get this to work properly...
It's very simple code I'm sure, but I'm just not getting it.
It should be pretty self-explanatory below in the code, but basically I'm asking a user to input the date of an event as an 'int' and if it's not a number, then ask them to try again... UNLESS it's a "?"
while True:
date = None
street = str(input('Name of street?: ').title())
city = str(input("In what city?: ").title())
while True:
try:
year = int(input("Date of event? (or '?'): "))
if date == "?":
break
except Exception:
print("That's not a date, try again!")
continue
break
It seems that it's not even getting to see IF because it gets caught by the 'except' before it can.
If you're going to display help or something when a '?' is input, then just call the function to display the help where you have the break currently.
if date == "?":
display_help()
continue
Then, split reading the input and processing it into two steps.
in = input("Date of event? (or '?'): ")
if in == "?":
display_help()
continue
year = int(in)
Also, you ask for a date but then assume that a year is entered, I'd be more explicit in your promt.
"Please enter the year of the event, ex: 1998"
or whatever form you actually want it in.
Trying using a valueError exception. Also I think in your post you mentioned you wanted to enter a date as integer, so I replaced year with the date. If you wanted the year to be an integer you can replace the variable date with year. If you wanted to the user to enter a year, day and month then this program needs to be redesigned a bit.
date = None
street = str(input('Name of street?: ').title())
city = str(input("In what city?: ").title())
while True:
date = input("Date of event? (or '?'): ")
if date == "?":
break
else:
try:
date = int(date)
except ValueError:
print("That's not a date, try again!")
continue
break

Script properties becomes corrupt: Failed to save Project Properties for script

Script properties becomes "corrupt" after a call to "PropertiesService.getScriptProperties().setProperties(properties)" in my script. By "corrupt", I mean I can no longer add or edit existing properties in: "File -> Project properties -> Script properties", and when I first try I receive the error message "Failed to save Project Properties for script." I've tried deleting all properties and re-adding them, I tried deleting all browser cache, and I tried minimizing my Properties calls to ensure(?) I'm not exceeding quotas.
After this error, going to "File -> Project properties" results in in a endlessly spinning busy cursor while it tries to load the "Info" tab. Re-loading the spreadsheet allows "File -> Project properties" to properly load, but any edits made to properties in the "Script properties" tab brings back the error and spinning cursor problem.
I've narrowed down the culprit in my script but I cannot figure out why it's causing this problem. In my "onOpen()" method I am building up ~125 properties, and then I set them with one call to "setProperties()". The properties go into Script Properties okay, and they function as expected, but this programmatic setting of script properties is definitely the cause of the "Failed to save Project Properties for script." error message.
Link to a copy of my Google spreadsheet containing the script causing the problem. The 3 calls causing the problem are commented with "SETPROPS", and the call to set the properties is commented with "BROKE!". This problem, or ones similar, have come up in the past but seem to be "fixed" or no longer occur.
The code sequence is as follows:
I clear all script properties with: PropertiesService.getScriptProperties().deleteAllProperties()
I call three methods, each taking a "properties" argument.
Each of these 3 methods does nearly the same thing. They each add key/value pairs to "properties".
After each of the 3 methods is called, I set the properties with:
if (Object.getOwnPropertyNames(properties).length !== 0)
{
PropertiesService.getScriptProperties().setProperties(properties);
}
Here is one of the 3 methods that adds to the "properties" var (initialize with: var properties = {};). The other 3 methods add to the properties variable in the same manner, but operate on different data.
function setScriptPropertiesShipSizesForFaction(properties, factionName)
{
var dataSheetName = factionName + "Data";
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dataSheetName);
var shipValues = dataSheet.getRange('B3:D200').getValues();
var index = 0;
while ( (index < shipValues.length) && (shipValues[index][0] != "") )
{
var key = '_shipSize_' + normalize(shipValues[index][0]);
var value = shipValues[index][2];
properties[key] = value;
index++;
}
}
I believe I am not exceeded any Google script quota. I do not get any error messages from the call to "setProperties", and I do not see any errors in Google's Stackdriving Logging. At the bottom of this post I have a list of what I am setting in ScriptProperties. It's logging output, with syntax: key=value.
_shipSize_ArquitensCC=S
_shipSize_ArquitensLC=S
_shipSize_AssaultFrigateMk2A=M
_shipSize_AssaultFrigateMk2B=M
_shipSize_CR90-A=S
_shipSize_CR90-B=S
_shipSize_GR-75CombatRetrofits=S
_shipSize_GR-75MediumTransports=S
_shipSize_Gladiator1=S
_shipSize_Gladiator2=S
_shipSize_GozantiAssault=S
_shipSize_GozantiCruisers=S
_shipSize_HammerheadScout=S
_shipSize_HammerheadTorpedo=S
_shipSize_ISD1=L
_shipSize_ISD2=L
_shipSize_ISDCymoon=L
_shipSize_ISDKuat=L
_shipSize_InterdictorCombat=M
_shipSize_InterdictorSuppression=M
_shipSize_MC30cScout=S
_shipSize_MC30cTorpedo=S
_shipSize_MC75ArmoredCruiser=L
_shipSize_MC75OrdnanceCruiser=L
_shipSize_MC80AssaultCruiser=L
_shipSize_MC80BattleCruiser=L
_shipSize_MC80CommandCruiser=L
_shipSize_MC80StarCruiser=L
_shipSize_Nebulon-BEscort=S
_shipSize_Nebulon-BSupport=S
_shipSize_PeltaAssault=S
_shipSize_PeltaCommand=S
_shipSize_QuasarFire1=M
_shipSize_QuasarFire2=M
_shipSize_Raider1=S
_shipSize_Raider2=S
_shipSize_Victory1=M
_shipSize_Victory2=M
_upgradeKeyPrefix_EmpireDEFENSIVE 2=6.0
_upgradeKeyPrefix_EmpireDEFENSIVE=5.0
_upgradeKeyPrefix_EmpireEXPERIMENTAL 2=8.0
_upgradeKeyPrefix_EmpireEXPERIMENTAL=7.0
_upgradeKeyPrefix_EmpireFLEET COMMAND=9.0
_upgradeKeyPrefix_EmpireFLEET SUPPORT=10.0
_upgradeKeyPrefix_EmpireION CANNONS=11.0
_upgradeKeyPrefix_EmpireOFFENSIVE 2=13.0
_upgradeKeyPrefix_EmpireOFFENSIVE=12.0
_upgradeKeyPrefix_EmpireOFFICER=4.0
_upgradeKeyPrefix_EmpireORDNANCE=14.0
_upgradeKeyPrefix_EmpireSUPPORT TEAM=15.0
_upgradeKeyPrefix_EmpireTITLE=3.0
_upgradeKeyPrefix_EmpireTURBOLASER 2=17.0
_upgradeKeyPrefix_EmpireTURBOLASER=16.0
_upgradeKeyPrefix_EmpireWEAPONS TEAM 2=19.0
_upgradeKeyPrefix_EmpireWEAPONS TEAM=18.0
_upgradeKeyPrefix_RebelDEFENSIVE 2=7.0
_upgradeKeyPrefix_RebelDEFENSIVE=6.0
_upgradeKeyPrefix_RebelFLEET COMMAND=8.0
_upgradeKeyPrefix_RebelFLEET SUPPORT=9.0
_upgradeKeyPrefix_RebelION CANNONS=10.0
_upgradeKeyPrefix_RebelOFFENSIVE=11.0
_upgradeKeyPrefix_RebelOFFICER 2=5.0
_upgradeKeyPrefix_RebelOFFICER=4.0
_upgradeKeyPrefix_RebelORDNANCE 2=13.0
_upgradeKeyPrefix_RebelORDNANCE=12.0
_upgradeKeyPrefix_RebelSUPPORT TEAM=14.0
_upgradeKeyPrefix_RebelTITLE=3.0
_upgradeKeyPrefix_RebelTURBOLASER 2=16.0
_upgradeKeyPrefix_RebelTURBOLASER=15.0
_upgradeKeyPrefix_RebelWEAPONS TEAM=17.0
_upgradeSize_BailOrgana=ML
_upgradeSize_DisposableCapacitors=SM
_upgradeSize_GovernorPryce=ML
_upgradeSize_HardenedBulkheads=L
_upgradeSize_StrategicAdviser=L calculatedDataSheetName=Calculated Data cellCommander=E2 colEmpirePlayerNames=1 colRebelPlayerNames=8
colShipNames=2 colSquadNames=2 colUpgradesStart=3
colVariableUpgradesEndEmpire=19 colVariableUpgradesEndRebel=17
colVariableUpgradesStartEmpire=5 colVariableUpgradesStartRebel=6
disabledBgColor=#999999 enabledBgColor=#93c47d
factionNameEmpire=Empire factionNameRebel=Rebel
indexFleetSheetsStart=3
multipleIconUpgrade_BoardingEngineers=OFFENSIVE,WEAPONS TEAM
multipleIconUpgrade_BoardingTroopers=OFFENSIVE,WEAPONS TEAM
multipleIconUpgrade_ChamSyndulla=OFFENSIVE,WEAPONS TEAM
multipleIconUpgrade_DarthVader=OFFENSIVE,WEAPONS TEAM
multipleIconUpgrade_JynErso=OFFENSIVE,WEAPONS TEAM playersPerTeam=3
rowPlayerNamesStart=7 rowShipsEnd=17 rowShipsStart=6
rowSquadNamesEnd=44 rowSquadNamesStart=21 rowUpgradeNames=5
sheetNameSystemTracking=Systems Tracking sheetNameTeamStatus=Team
Status upgradeKeyPrefix=_upgradeKeyPrefix_
upgradeKeyPrefixEmpireDEFENSIVE 2=6.0
upgradeKeyPrefixEmpireDEFENSIVE=5.0
upgradeKeyPrefixEmpireEXPERIMENTAL 2=8.0
upgradeKeyPrefixEmpireEXPERIMENTAL=7.0 upgradeKeyPrefixEmpireFLEET
COMMAND=9.0 upgradeKeyPrefixEmpireFLEET SUPPORT=10.0
upgradeKeyPrefixEmpireION CANNONS=11.0
upgradeKeyPrefixEmpireOFFENSIVE 2=13.0
upgradeKeyPrefixEmpireOFFENSIVE=12.0
upgradeKeyPrefixEmpireOFFICER=4.0 upgradeKeyPrefixEmpireORDNANCE=14.0
upgradeKeyPrefixEmpireSUPPORT TEAM=15.0
upgradeKeyPrefixEmpireTITLE=3.0 upgradeKeyPrefixEmpireTURBOLASER
2=17.0 upgradeKeyPrefixEmpireTURBOLASER=16.0
upgradeKeyPrefixEmpireWEAPONS TEAM 2=19.0
upgradeKeyPrefixEmpireWEAPONS TEAM=18.0
upgradeKeyPrefixRebelDEFENSIVE 2=7.0
upgradeKeyPrefixRebelDEFENSIVE=6.0 upgradeKeyPrefixRebelFLEET
COMMAND=8.0 upgradeKeyPrefixRebelFLEET SUPPORT=9.0
upgradeKeyPrefixRebelION CANNONS=10.0
upgradeKeyPrefixRebelOFFENSIVE=11.0 upgradeKeyPrefixRebelOFFICER
2=5.0 upgradeKeyPrefixRebelOFFICER=4.0 upgradeKeyPrefixRebelORDNANCE
2=13.0 upgradeKeyPrefixRebelORDNANCE=12.0
upgradeKeyPrefixRebelSUPPORT TEAM=14.0 upgradeKeyPrefixRebelTITLE=3.0
upgradeKeyPrefixRebelTURBOLASER 2=16.0
upgradeKeyPrefixRebelTURBOLASER=15.0 upgradeKeyPrefixRebelWEAPONS
TEAM=17.0 upgradeRegex_DEFENSIVE 2=MC80\s+Assault
upgradeRegex_DEFENSIVE=Arquitens|ISD\s+(2|Kuat)|Assault\s+Frigate|CR90|MC30|MC75|MC80\s+(Assault|Command)
upgradeRegex_EXPERIMENTAL 2=Suppression
upgradeRegex_EXPERIMENTAL=Interdictor upgradeRegex_FLEET
COMMAND=Pelta|ISD\s+Cymoon upgradeRegex_FLEET SUPPORT=Gozanti|GR\-75
upgradeRegex_ION
CANNONS=CR90\-B|ISD\s+(2|Kuat|1)|Interdictor|MC75\s+Armored|MC80|Raider\s+2|Victory\s+2
upgradeRegex_OFFENSIVE 2=ISD\s+1|Quasar\s+Fire\s+1
upgradeRegex_OFFENSIVE=Gozanti|ISD|Interdictor|Quasar|Raider|Victory|Assault\s+Frigate|GR\-75|Hammerhead|MC75|MC80\s+Command|Pelta\s+Command
upgradeRegex_ORDNANCE 2=MC75\s+Ordnance
upgradeRegex_ORDNANCE=Hammerhead\s+Torpedo|Gladiator|ISD\s+Kuat|MC30|MC75|Raider\s+1|Victory\s+1|Pelta\s+Assault
upgradeRegex_SUPPORT
TEAM=Arquitens\s+CC|CR90|Gladiator|Interdictor|MC80|Pelta|Nebulon
upgradeRegex_TURBOLASER 2=ISD\s+Cymoon|MC80\s+(Star|Battle)
upgradeRegex_TURBOLASER=Arquitens|Assault\s+Frigate|CR90\-A|Hammerhead\s+Scout|ISD\s+(2|Cymoon|1)|MC30|MC75\s+Armored|MC80|Nebulon|Victory
upgradeRegex_WEAPONS TEAM 2=Quasar\s+Fire\s+2 upgradeRegex_WEAPONS
TEAM=Assault\s+Frigate|Hammerhead|Gladiator|ISD|MC30|MC75|MC80\s+(Battle|Star)|Quasar|Raider|Victory
For what it's worth, I'm experiencing much the same problem too. There's an older version of this Google Apps Script running and it's got around the same number of Properties. Going via the GAS interface I can't delete any of the properties. I've only just come across this problem so I haven't yet delved into a solution. The property I'm storing is a token for each user for a Service Account to utilise, so I'm hoping a programmatic purge of the tokens every x days will suffice. I'll post updates here.
In my case i couldn't save any file because an old linked library was deleted.

Update planned order - two committed modifications, only one saved

I need to update two information on one object: the quantity (PLAF-gsmng) and refresh the planned order via the module function 'MD_SET_ACTION_PLAF'.
I successfully find a way to update each data separately. But when I execute the both solutions the second modification is not saved on the database.
Do you know how I can change the quantity & set the action on PLAF (Planned order) table ?
Do you know other module function to update only the quantity ?
Maybe a parameter missing ?
It's like if the second object is locked (sm12 empty, no sy-subrc = locked) ... and the modification is not committed.
I tried to:
change the order of the algorithm (refresh and after, change PLAF)
add, remove, move the COMMIT WORK & COMMIT WORK AND WAIT
add DEQUEUE_ALL or DEQUEUE_EMPLAFE
This is the current code:
1) Read the data
lv_plannedorder = '00000000001'
"Read PLAF data
SELECT SINGLE * FROM PLAF INTO ls_plaf WHERE plnum = lv_plannedorder.
2) Update Quantity data
" Standard configuration for FM MD_PLANNED_ORDER_CHANGE
CLEAR ls_610.
ls_610-nodia = 'X'. " No dialog display
ls_610-bapco = space. " BAPI type. Do not use mode 2 -> Action PLAF-MDACC will be autmatically set up to APCH by the FM
ls_610-bapix = 'X'. " Run BAPI
ls_610-unlox = 'X'. " Update PLAF
" Customize values
MOVE p_gsmng TO ls_plaf-gsmng. " Change quantity value
MOVE sy-datlo TO ls_plaf-mdacd. " Change by/datetime, because ls_610-bapco <> 2.
MOVE sy-uzeit TO ls_plaf-mdact.
CALL FUNCTION 'MD_PLANNED_ORDER_CHANGE'
EXPORTING
ecm61o = ls_610
eplaf = ls_plaf
EXCEPTIONS
locked = 1
locking_error = 2
OTHERS = 3.
" Already committed on the module function
" sy-subrc = 0
If I go on the PLAF table, I can see that the quantity is edited. It's working :)
3) Refresh BOM & change Action (MDACC) and others fields
CLEAR ls_imdcd.
ls_imdcd-pafxl = 'X'.
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = lv_plannedorder
iaccto = 'BOME'
iaenkz = 'X'
imdcd = ls_imdcd
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3
OTHERS = 4.
IF sy-subrc = 0.
COMMIT WORK.
ENDIF.
If I go on the table, no modification (only the modif. of the part 2. can be found on it).
Any idea ?
Maybe because the ls_610-bapco = space ?
It should be possible to update planned order quantity with MD_SET_ACTION_PLAF too, at least SAP Help tells us so. Why don't you use it like that?
Its call for changing the quantity should possibly look like this:
DATA: lt_acct LIKE TABLE OF MDACCTO,
ls_acct LIKE LINE OF lt_acct.
ls_acct-accto = 'BOME'.
APPEND lt_acct.
ls_acct-accto = 'CPOD'.
APPEND lt_acct.
is_mdcd-GSMNG = 'value' "updated quantity value
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = iv_plnum
iaenkz = 'X'
IVBKZ = 'X'
imdcd = is_mdcd "filled with your BOME-related data + new quantity
TABLES
TMDACCTO = lt_accto
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3.
So there is no more need for separate call of MD_PLANNED_ORDER_CHANGE anymore and no more problems with update.
I used word possibly because I didn't find any example of this FM call in the Web (and SAP docu is quite ambiguous), so I propose this solution just as is, without verification.
P.S. Possible actions are listed in T46AS table, and possible impact of imdcd fields on order can be checked in MDAC transaction. It is somewhat GUI equivalent of this FM for single order.

PyQt stacked widget not moving to next page until function ends

Hi i have a program that when a button is pressed it should move to the next stacked widget replace some text in some labels and then execute some functions but this is not working and moves to the next page when the functions completes
The code is :
QtCore.QObject.connect(self.StartBtn, QtCore.SIGNAL(_fromUtf8("clicked()")), self.start) #Start
def nextPage(self):
current_page = self.stackedWidget.currentIndex()
i = int(current_page) + 1
self.stackedWidget.setCurrentIndex(i)
def start(self):
self.nextPage()
self.animation()
self.runFunctions()
def runFunctions(self):
try:
self.DbLabel.setText(_translate("MainWindow", "Checking Database", None))
if checkDb == True:
self.DbLabel.setText(_translate("MainWindow", "Checking Database ", None))
self.checkDbFun()
self.DbLabel.setText(_translate("MainWindow", "Database checked", None))
else:
self.checkedDbImg.setPixmap(QtGui.QPixmap(_fromUtf8("Files\\x.png")))
self.DbLabel.setText(_translate("MainWindow", "Database not checked", None))
except Exception as e:
self.AlertMessage(e)
def animation(self):
self.LoadingGif = QtGui.QLabel(MainWindow)
movie = QtGui.QMovie("Files\\loading.png")
self.LoadingGif.setMovie(movie)
self.LoadingGif.setAlignment(QtCore.Qt.AlignCenter)
self.gridLayout_2.addWidget(self.LoadingGif, 4, 1, 1, 1)
movie.start()
So what i want is to press StartBtn then move to next stacked widget page load the animation image and then run the functions
You probably need to let Qt process events in order for the tab change to take effect. You could do that two ways:
insert a qApp.processEvents() between the animation() and runFunctions() (qApp is in PyQt5.QtWidgets)
call runFunctions() via a single-shot timer: QTimer.singleShot(0, runFunctions), which will schuedule runFunctions via the event loop, so any pending events will first be processed (because runFunctions() is the latest added), then runFunctions() will get called. If you actually have params for runFunctions(), use a lambda.
I favor the first approach because I find it more clearly indicates what is happening (events need to be processed), but I recommend also adding a comment on that line that "so stack tab can change".
BTW you should be use the new-style notation for signals-slot connections, much cleaner, of the form "signal.connect(slot)":
self.StartBtn.clicked.connect(self.start)
So for approach #1 your code would look like this:
from PyQt5.QtWidgets import qApp
...
self.StartBtn.clicked.connect(self.start)
...
def start(self):
self.nextPage()
self.animation()
qApp.processEvents()
self.runFunctions()
...