refactor: implement token validation and localize UI labels and status messages
This commit is contained in:
@@ -102,7 +102,18 @@ STRINGS = {
|
|||||||
"msg_upload_success": "'{name}' uploadet succesfuldt.",
|
"msg_upload_success": "'{name}' uploadet succesfuldt.",
|
||||||
"msg_upload_failed": "Upload af '{name}' fejlede med kode {code}",
|
"msg_upload_failed": "Upload af '{name}' fejlede med kode {code}",
|
||||||
"msg_delete_failed": "Kunne ikke slette '{name}'. Stopper...",
|
"msg_delete_failed": "Kunne ikke slette '{name}'. Stopper...",
|
||||||
"msg_deleted_status": "Slettet {count} af {total} emner."
|
"msg_deleted_status": "Slettet {count} af {total} emner.",
|
||||||
|
"msg_fetching_file": "Henter '{name}'...",
|
||||||
|
"msg_opening_file": "Åbner '{name}'...",
|
||||||
|
"msg_waiting_for_file": "Venter på '{name}'...",
|
||||||
|
"msg_editing_file": "Redigerer '{name}' - Luk for at gemme.",
|
||||||
|
"msg_file_unchanged": "Ingen ændringer fundet. Springer upload over.",
|
||||||
|
"msg_updating_changes": "Uploader ændringer...",
|
||||||
|
"msg_checking_in": "Tjekker '{name}' ind...",
|
||||||
|
"msg_update_success": "Succes! '{name}' er opdateret.",
|
||||||
|
"msg_update_failed_code": "Upload fejlede: {code}",
|
||||||
|
"msg_unknown_error": "Ukendt fejl",
|
||||||
|
"type_unknown": "Ukendt"
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"title": "SharePoint Explorer",
|
"title": "SharePoint Explorer",
|
||||||
@@ -155,7 +166,18 @@ STRINGS = {
|
|||||||
"msg_upload_success": "'{name}' uploaded successfully.",
|
"msg_upload_success": "'{name}' uploaded successfully.",
|
||||||
"msg_upload_failed": "Upload of '{name}' failed with status {code}",
|
"msg_upload_failed": "Upload of '{name}' failed with status {code}",
|
||||||
"msg_delete_failed": "Could not delete '{name}'. Stopping...",
|
"msg_delete_failed": "Could not delete '{name}'. Stopping...",
|
||||||
"msg_deleted_status": "Deleted {count} of {total} items."
|
"msg_deleted_status": "Deleted {count} of {total} items.",
|
||||||
|
"msg_fetching_file": "Fetching '{name}'...",
|
||||||
|
"msg_opening_file": "Opening '{name}'...",
|
||||||
|
"msg_waiting_for_file": "Waiting for '{name}'...",
|
||||||
|
"msg_editing_file": "Editing '{name}' - Close window to save.",
|
||||||
|
"msg_file_unchanged": "No changes found. Skipping upload.",
|
||||||
|
"msg_updating_changes": "Uploading changes...",
|
||||||
|
"msg_checking_in": "Checking in '{name}'...",
|
||||||
|
"msg_update_success": "Success! '{name}' has been updated.",
|
||||||
|
"msg_update_failed_code": "Upload failed: {code}",
|
||||||
|
"msg_unknown_error": "Unknown error",
|
||||||
|
"type_unknown": "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,18 +291,18 @@ class SharePointApp(wx.Frame):
|
|||||||
nav_panel = wx.Panel(panel)
|
nav_panel = wx.Panel(panel)
|
||||||
nav_hbox = wx.BoxSizer(wx.HORIZONTAL)
|
nav_hbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
|
||||||
self.back_btn = wx.Button(nav_panel, label="← Tilbage", size=(100, 30))
|
self.back_btn = wx.Button(nav_panel, label=self.get_txt("btn_back"), size=(100, 30))
|
||||||
self.back_btn.Disable()
|
self.back_btn.Disable()
|
||||||
self.back_btn.Bind(wx.EVT_BUTTON, self.go_back)
|
self.back_btn.Bind(wx.EVT_BUTTON, self.go_back)
|
||||||
nav_hbox.Add(self.back_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
|
nav_hbox.Add(self.back_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
|
||||||
|
|
||||||
self.home_btn = wx.Button(nav_panel, label="🏠 Hjem", size=(100, 30))
|
self.home_btn = wx.Button(nav_panel, label=self.get_txt("btn_home"), size=(100, 30))
|
||||||
self.home_btn.Disable()
|
self.home_btn.Disable()
|
||||||
self.home_btn.Bind(wx.EVT_BUTTON, self.load_sites)
|
self.home_btn.Bind(wx.EVT_BUTTON, self.load_sites)
|
||||||
nav_hbox.Add(self.home_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
nav_hbox.Add(self.home_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||||
|
|
||||||
# NY KNAP: Gem ændringer (Vises kun ved redigering)
|
# NY KNAP: Gem ændringer (Vises kun ved redigering)
|
||||||
self.done_btn = wx.Button(nav_panel, label="💾 Gem ændringer i SharePoint", size=(200, 30))
|
self.done_btn = wx.Button(nav_panel, label=self.get_txt("btn_save_changes"), size=(200, 30))
|
||||||
self.done_btn.SetBackgroundColour(wx.Colour(255, 69, 0)) # OrangeRed
|
self.done_btn.SetBackgroundColour(wx.Colour(255, 69, 0)) # OrangeRed
|
||||||
self.done_btn.SetForegroundColour(wx.WHITE)
|
self.done_btn.SetForegroundColour(wx.WHITE)
|
||||||
self.done_btn.Hide()
|
self.done_btn.Hide()
|
||||||
@@ -288,17 +310,17 @@ class SharePointApp(wx.Frame):
|
|||||||
nav_hbox.Add(self.done_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
|
nav_hbox.Add(self.done_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
|
||||||
|
|
||||||
# NYE KNAPPER: Upload og Ny Mappe (Vises kun når man er inde i et drev/mappe)
|
# NYE KNAPPER: Upload og Ny Mappe (Vises kun når man er inde i et drev/mappe)
|
||||||
self.upload_btn = wx.Button(nav_panel, label="📤 Upload Fil", size=(120, 30))
|
self.upload_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_file"), size=(120, 30))
|
||||||
self.upload_btn.Hide()
|
self.upload_btn.Hide()
|
||||||
self.upload_btn.Bind(wx.EVT_BUTTON, self.on_upload_clicked)
|
self.upload_btn.Bind(wx.EVT_BUTTON, self.on_upload_clicked)
|
||||||
nav_hbox.Add(self.upload_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
nav_hbox.Add(self.upload_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||||
|
|
||||||
self.upload_folder_btn = wx.Button(nav_panel, label="📁 Upload Mappe", size=(120, 30))
|
self.upload_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_folder"), size=(120, 30))
|
||||||
self.upload_folder_btn.Hide()
|
self.upload_folder_btn.Hide()
|
||||||
self.upload_folder_btn.Bind(wx.EVT_BUTTON, self.on_upload_folder_clicked)
|
self.upload_folder_btn.Bind(wx.EVT_BUTTON, self.on_upload_folder_clicked)
|
||||||
nav_hbox.Add(self.upload_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
nav_hbox.Add(self.upload_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||||
|
|
||||||
self.new_folder_btn = wx.Button(nav_panel, label="➕ Ny Mappe", size=(100, 30))
|
self.new_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_new_folder"), size=(100, 30))
|
||||||
self.new_folder_btn.Hide()
|
self.new_folder_btn.Hide()
|
||||||
self.new_folder_btn.Bind(wx.EVT_BUTTON, self.on_new_folder_clicked)
|
self.new_folder_btn.Bind(wx.EVT_BUTTON, self.on_new_folder_clicked)
|
||||||
nav_hbox.Add(self.new_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
nav_hbox.Add(self.new_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||||
@@ -340,10 +362,10 @@ class SharePointApp(wx.Frame):
|
|||||||
# Right side: File Area - ListCtrl
|
# Right side: File Area - ListCtrl
|
||||||
self.list_ctrl = wx.ListCtrl(self.splitter, style=wx.LC_REPORT | wx.BORDER_SUNKEN)
|
self.list_ctrl = wx.ListCtrl(self.splitter, style=wx.LC_REPORT | wx.BORDER_SUNKEN)
|
||||||
self.list_ctrl.AssignImageList(self.image_list, wx.IMAGE_LIST_SMALL)
|
self.list_ctrl.AssignImageList(self.image_list, wx.IMAGE_LIST_SMALL)
|
||||||
self.list_ctrl.InsertColumn(0, "Navn", width=450)
|
self.list_ctrl.InsertColumn(0, self.get_txt("col_name"), width=450)
|
||||||
self.list_ctrl.InsertColumn(1, "Type", width=120)
|
self.list_ctrl.InsertColumn(1, self.get_txt("col_type"), width=120)
|
||||||
self.list_ctrl.InsertColumn(2, "Størrelse", width=80)
|
self.list_ctrl.InsertColumn(2, self.get_txt("col_size"), width=80)
|
||||||
self.list_ctrl.InsertColumn(3, "Sidst ændret", width=180)
|
self.list_ctrl.InsertColumn(3, self.get_txt("col_modified"), width=180)
|
||||||
|
|
||||||
self.list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_item_activated)
|
self.list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_item_activated)
|
||||||
self.list_ctrl.Bind(wx.EVT_CONTEXT_MENU, self.on_right_click)
|
self.list_ctrl.Bind(wx.EVT_CONTEXT_MENU, self.on_right_click)
|
||||||
@@ -358,7 +380,7 @@ class SharePointApp(wx.Frame):
|
|||||||
|
|
||||||
# 4. STATUS BAR
|
# 4. STATUS BAR
|
||||||
self.status_bar = self.CreateStatusBar()
|
self.status_bar = self.CreateStatusBar()
|
||||||
self.status_bar.SetStatusText("Klar")
|
self.status_bar.SetStatusText(self.get_txt("status_ready"))
|
||||||
|
|
||||||
panel.SetSizer(vbox)
|
panel.SetSizer(vbox)
|
||||||
self.Layout()
|
self.Layout()
|
||||||
@@ -422,6 +444,7 @@ class SharePointApp(wx.Frame):
|
|||||||
threading.Thread(target=self._delete_multiple_bg, args=(items,), daemon=True).start()
|
threading.Thread(target=self._delete_multiple_bg, args=(items,), daemon=True).start()
|
||||||
|
|
||||||
def _delete_multiple_bg(self, items):
|
def _delete_multiple_bg(self, items):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
self.lock_ui(True)
|
self.lock_ui(True)
|
||||||
count = 0
|
count = 0
|
||||||
total = len(items)
|
total = len(items)
|
||||||
@@ -450,6 +473,7 @@ class SharePointApp(wx.Frame):
|
|||||||
threading.Thread(target=self._upload_file_bg, args=(path, self.current_drive_id, self.current_folder_id), daemon=True).start()
|
threading.Thread(target=self._upload_file_bg, args=(path, self.current_drive_id, self.current_folder_id), daemon=True).start()
|
||||||
|
|
||||||
def _upload_file_bg(self, local_path, drive_id, parent_id):
|
def _upload_file_bg(self, local_path, drive_id, parent_id):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
filename = os.path.basename(local_path)
|
filename = os.path.basename(local_path)
|
||||||
self.set_status(self.get_txt("msg_uploading", name=filename))
|
self.set_status(self.get_txt("msg_uploading", name=filename))
|
||||||
# Simpel upload (virker op til 4MB)
|
# Simpel upload (virker op til 4MB)
|
||||||
@@ -474,6 +498,7 @@ class SharePointApp(wx.Frame):
|
|||||||
threading.Thread(target=self._upload_folder_bg, args=(path, self.current_drive_id, self.current_folder_id), daemon=True).start()
|
threading.Thread(target=self._upload_folder_bg, args=(path, self.current_drive_id, self.current_folder_id), daemon=True).start()
|
||||||
|
|
||||||
def _upload_folder_bg(self, local_dir, drive_id, parent_id):
|
def _upload_folder_bg(self, local_dir, drive_id, parent_id):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
dirname = os.path.basename(local_dir)
|
dirname = os.path.basename(local_dir)
|
||||||
self.set_status(self.get_txt("msg_creating_folder", name=dirname))
|
self.set_status(self.get_txt("msg_creating_folder", name=dirname))
|
||||||
|
|
||||||
@@ -518,6 +543,7 @@ class SharePointApp(wx.Frame):
|
|||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def _create_folder_bg(self, name, drive_id, parent_id):
|
def _create_folder_bg(self, name, drive_id, parent_id):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
self.set_status(self.get_txt("msg_creating_folder", name=name))
|
self.set_status(self.get_txt("msg_creating_folder", name=name))
|
||||||
folder_id = self._create_folder_sync(name, drive_id, parent_id)
|
folder_id = self._create_folder_sync(name, drive_id, parent_id)
|
||||||
if folder_id:
|
if folder_id:
|
||||||
@@ -535,6 +561,7 @@ class SharePointApp(wx.Frame):
|
|||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def _rename_item_bg(self, item, new_name):
|
def _rename_item_bg(self, item, new_name):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
self.set_status(f"{self.get_txt('msg_rename')}...")
|
self.set_status(f"{self.get_txt('msg_rename')}...")
|
||||||
url = f"https://graph.microsoft.com/v1.0/drives/{item['drive_id']}/items/{item['id']}"
|
url = f"https://graph.microsoft.com/v1.0/drives/{item['drive_id']}/items/{item['id']}"
|
||||||
body = {"name": new_name}
|
body = {"name": new_name}
|
||||||
@@ -648,7 +675,7 @@ class SharePointApp(wx.Frame):
|
|||||||
curr = self.tree_ctrl.GetItemParent(curr)
|
curr = self.tree_ctrl.GetItemParent(curr)
|
||||||
|
|
||||||
# Start ikon/label
|
# Start ikon/label
|
||||||
self._add_path_segment("📍 SharePoint", "ROOT")
|
self._add_path_segment("📍 " + self.get_txt("title"), "ROOT")
|
||||||
|
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
arrow = wx.StaticText(self.path_panel, label=" > ")
|
arrow = wx.StaticText(self.path_panel, label=" > ")
|
||||||
@@ -677,6 +704,23 @@ class SharePointApp(wx.Frame):
|
|||||||
|
|
||||||
self.path_sizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2)
|
self.path_sizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2)
|
||||||
|
|
||||||
|
def ensure_valid_token(self):
|
||||||
|
"""Sikrer at vi har et gyldigt token. Returnerer True hvis OK."""
|
||||||
|
try:
|
||||||
|
app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY)
|
||||||
|
accounts = app.get_accounts()
|
||||||
|
if not accounts:
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = app.acquire_token_silent(SCOPES, account=accounts[0])
|
||||||
|
if result and "access_token" in result:
|
||||||
|
self.access_token = result["access_token"]
|
||||||
|
self.headers = {'Authorization': f'Bearer {self.access_token}'}
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
def login(self, event):
|
def login(self, event):
|
||||||
self.set_status(self.get_txt("status_logging_in"))
|
self.set_status(self.get_txt("status_logging_in"))
|
||||||
app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY)
|
app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY)
|
||||||
@@ -684,7 +728,8 @@ class SharePointApp(wx.Frame):
|
|||||||
result = None
|
result = None
|
||||||
if accounts:
|
if accounts:
|
||||||
result = app.acquire_token_silent(SCOPES, account=accounts[0])
|
result = app.acquire_token_silent(SCOPES, account=accounts[0])
|
||||||
if not result:
|
|
||||||
|
if not result or "access_token" not in result:
|
||||||
result = app.acquire_token_interactive(scopes=SCOPES)
|
result = app.acquire_token_interactive(scopes=SCOPES)
|
||||||
|
|
||||||
if "access_token" in result:
|
if "access_token" in result:
|
||||||
@@ -697,7 +742,7 @@ class SharePointApp(wx.Frame):
|
|||||||
self.load_sites()
|
self.load_sites()
|
||||||
else:
|
else:
|
||||||
self.set_status(self.get_txt("status_login_failed"))
|
self.set_status(self.get_txt("status_login_failed"))
|
||||||
wx.MessageBox(result.get("error_description", "Unknown error"), self.get_txt("msg_error"), wx.OK | wx.ICON_ERROR)
|
wx.MessageBox(result.get("error_description", self.get_txt("msg_unknown_error")), self.get_txt("msg_error"), wx.OK | wx.ICON_ERROR)
|
||||||
|
|
||||||
def load_sites(self, event=None):
|
def load_sites(self, event=None):
|
||||||
self.set_status(self.get_txt("status_fetching_sites"))
|
self.set_status(self.get_txt("status_fetching_sites"))
|
||||||
@@ -715,6 +760,7 @@ class SharePointApp(wx.Frame):
|
|||||||
threading.Thread(target=self._fetch_sites_bg, daemon=True).start()
|
threading.Thread(target=self._fetch_sites_bg, daemon=True).start()
|
||||||
|
|
||||||
def _fetch_sites_bg(self):
|
def _fetch_sites_bg(self):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
url = "https://graph.microsoft.com/v1.0/sites?search=*"
|
url = "https://graph.microsoft.com/v1.0/sites?search=*"
|
||||||
res = requests.get(url, headers=self.headers)
|
res = requests.get(url, headers=self.headers)
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
@@ -722,7 +768,7 @@ class SharePointApp(wx.Frame):
|
|||||||
sites.sort(key=lambda x: x.get('displayName', x.get('name', '')).lower())
|
sites.sort(key=lambda x: x.get('displayName', x.get('name', '')).lower())
|
||||||
wx.CallAfter(self._populate_sites_tree, sites)
|
wx.CallAfter(self._populate_sites_tree, sites)
|
||||||
else:
|
else:
|
||||||
self.set_status("Kunne ikke hente sites.")
|
self.set_status(self.get_txt("msg_unknown_error"))
|
||||||
|
|
||||||
def _populate_sites_tree(self, sites):
|
def _populate_sites_tree(self, sites):
|
||||||
self.set_status(f"{len(sites)} sites.")
|
self.set_status(f"{len(sites)} sites.")
|
||||||
@@ -756,6 +802,7 @@ class SharePointApp(wx.Frame):
|
|||||||
threading.Thread(target=self._fetch_tree_children_bg, args=(item, data), daemon=True).start()
|
threading.Thread(target=self._fetch_tree_children_bg, args=(item, data), daemon=True).start()
|
||||||
|
|
||||||
def _fetch_tree_children_bg(self, parent_node, data):
|
def _fetch_tree_children_bg(self, parent_node, data):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
if data['type'] == "SITE":
|
if data['type'] == "SITE":
|
||||||
url = f"https://graph.microsoft.com/v1.0/sites/{data['id']}/drives"
|
url = f"https://graph.microsoft.com/v1.0/sites/{data['id']}/drives"
|
||||||
res = requests.get(url, headers=self.headers)
|
res = requests.get(url, headers=self.headers)
|
||||||
@@ -786,7 +833,7 @@ class SharePointApp(wx.Frame):
|
|||||||
target_node = None
|
target_node = None
|
||||||
|
|
||||||
for drive in drives:
|
for drive in drives:
|
||||||
name = drive.get('name', 'Ukendt')
|
name = drive.get('name', self.get_txt("type_unknown"))
|
||||||
drive_id = drive['id']
|
drive_id = drive['id']
|
||||||
node = self.tree_ctrl.AppendItem(parent_node, name, image=self.idx_drive)
|
node = self.tree_ctrl.AppendItem(parent_node, name, image=self.idx_drive)
|
||||||
self.tree_item_data[node] = {
|
self.tree_item_data[node] = {
|
||||||
@@ -849,6 +896,7 @@ class SharePointApp(wx.Frame):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def _fetch_list_contents_bg(self, data):
|
def _fetch_list_contents_bg(self, data):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
items_data = []
|
items_data = []
|
||||||
if data['type'] == "SITE":
|
if data['type'] == "SITE":
|
||||||
url = f"https://graph.microsoft.com/v1.0/sites/{data['id']}/drives"
|
url = f"https://graph.microsoft.com/v1.0/sites/{data['id']}/drives"
|
||||||
@@ -971,6 +1019,7 @@ class SharePointApp(wx.Frame):
|
|||||||
self.is_navigating_back = False
|
self.is_navigating_back = False
|
||||||
|
|
||||||
def process_file(self, item_id, file_name):
|
def process_file(self, item_id, file_name):
|
||||||
|
if not self.ensure_valid_token(): return
|
||||||
self.is_editing = True
|
self.is_editing = True
|
||||||
self.lock_ui(True)
|
self.lock_ui(True)
|
||||||
try:
|
try:
|
||||||
@@ -988,10 +1037,10 @@ class SharePointApp(wx.Frame):
|
|||||||
local_path = os.path.join(working_dir, file_name)
|
local_path = os.path.join(working_dir, file_name)
|
||||||
|
|
||||||
# 2. Download
|
# 2. Download
|
||||||
self.set_status(f"Henter '{file_name}'...")
|
self.set_status(self.get_txt("msg_fetching_file", name=file_name))
|
||||||
res = requests.get(f"{base_url}/content", headers=self.headers)
|
res = requests.get(f"{base_url}/content", headers=self.headers)
|
||||||
if res.status_code != 200:
|
if res.status_code != 200:
|
||||||
raise Exception(f"Kunne ikke hente fil: {res.status_code}")
|
raise Exception(f"{self.get_txt('msg_unknown_error')}: {res.status_code}")
|
||||||
|
|
||||||
with open(local_path, 'wb') as f:
|
with open(local_path, 'wb') as f:
|
||||||
f.write(res.content)
|
f.write(res.content)
|
||||||
@@ -1003,11 +1052,11 @@ class SharePointApp(wx.Frame):
|
|||||||
requests.post(f"{base_url}/checkout", headers=self.headers)
|
requests.post(f"{base_url}/checkout", headers=self.headers)
|
||||||
|
|
||||||
# 3. Åbn & Overvåg
|
# 3. Åbn & Overvåg
|
||||||
self.set_status(f"Åbner '{file_name}'...")
|
self.set_status(self.get_txt("msg_opening_file", name=file_name))
|
||||||
os.startfile(local_path)
|
os.startfile(local_path)
|
||||||
|
|
||||||
locked = False
|
locked = False
|
||||||
self.set_status(f"Venter på '{file_name}'...")
|
self.set_status(self.get_txt("msg_waiting_for_file", name=file_name))
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
try:
|
try:
|
||||||
@@ -1017,7 +1066,7 @@ class SharePointApp(wx.Frame):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if locked:
|
if locked:
|
||||||
self.set_status(f"Redigerer '{file_name}' - Luk for at gemme.")
|
self.set_status(self.get_txt("msg_editing_file", name=file_name))
|
||||||
while True:
|
while True:
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
try:
|
try:
|
||||||
@@ -1026,7 +1075,7 @@ class SharePointApp(wx.Frame):
|
|||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.set_status("Fillås ikke detekteret.")
|
self.set_status(self.get_txt("msg_waiting_for_file", name=file_name))
|
||||||
self.edit_wait_event.clear()
|
self.edit_wait_event.clear()
|
||||||
wx.CallAfter(self.done_btn.Show)
|
wx.CallAfter(self.done_btn.Show)
|
||||||
wx.CallAfter(self.Layout)
|
wx.CallAfter(self.Layout)
|
||||||
@@ -1037,17 +1086,17 @@ class SharePointApp(wx.Frame):
|
|||||||
# 4. Tjek om noget er ændret
|
# 4. Tjek om noget er ændret
|
||||||
new_hash = get_file_hash(local_path)
|
new_hash = get_file_hash(local_path)
|
||||||
if original_hash == new_hash:
|
if original_hash == new_hash:
|
||||||
self.set_status("Ingen ændringer fundet. Springer upload over.")
|
self.set_status(self.get_txt("msg_file_unchanged"))
|
||||||
else:
|
else:
|
||||||
# 5. Upload (kun hvis ændret)
|
# 5. Upload (kun hvis ændret)
|
||||||
self.set_status(f"Uploader ændringer...")
|
self.set_status(self.get_txt("msg_updating_changes"))
|
||||||
with open(local_path, 'rb') as f:
|
with open(local_path, 'rb') as f:
|
||||||
upload_res = requests.put(f"{base_url}/content", headers=self.headers, data=f)
|
upload_res = requests.put(f"{base_url}/content", headers=self.headers, data=f)
|
||||||
if upload_res.status_code not in [200, 201]:
|
if upload_res.status_code not in [200, 201]:
|
||||||
raise Exception(f"Upload fejlede: {upload_res.status_code}")
|
raise Exception(f"{self.get_txt('msg_update_failed_code', code=upload_res.status_code)}")
|
||||||
|
|
||||||
# 6. Checkin (Uanset om ændret eller ej, for at frigive lås)
|
# 6. Checkin (Uanset om ændret eller ej, for at frigive lås)
|
||||||
self.set_status(f"Tjekker '{file_name}' ind...")
|
self.set_status(self.get_txt("msg_checking_in", name=file_name))
|
||||||
requests.post(f"{base_url}/checkin", headers=self.headers, json={"comment": "SP Explorer Edit"})
|
requests.post(f"{base_url}/checkin", headers=self.headers, json={"comment": "SP Explorer Edit"})
|
||||||
|
|
||||||
# Oprydning: Slet fil og derefter mappe
|
# Oprydning: Slet fil og derefter mappe
|
||||||
@@ -1057,13 +1106,13 @@ class SharePointApp(wx.Frame):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.set_status(f"Succes! '{file_name}' er opdateret.")
|
self.set_status(self.get_txt("msg_update_success", name=file_name))
|
||||||
self.show_info(f"Filen '{file_name}' er gemt og tjekket ind korrekt.", wx.ICON_INFORMATION)
|
self.show_info(self.get_txt("msg_update_success", name=file_name), wx.ICON_INFORMATION)
|
||||||
self._refresh_current_view()
|
self._refresh_current_view()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.set_status(f"Fejl: {str(e)}")
|
self.set_status(f"{self.get_txt('msg_error')}: {str(e)}")
|
||||||
self.show_info(f"Der skete en fejl: {e}", wx.ICON_ERROR)
|
self.show_info(f"{self.get_txt('msg_error')}: {e}", wx.ICON_ERROR)
|
||||||
finally:
|
finally:
|
||||||
self.is_editing = False
|
self.is_editing = False
|
||||||
self.lock_ui(False)
|
self.lock_ui(False)
|
||||||
|
|||||||
Reference in New Issue
Block a user