1212"""
1313
1414import sys
15+ import time
1516import xml .etree .ElementTree as ET
1617
1718import niquests
@@ -172,6 +173,39 @@ def seed_contacts(s: niquests.Session, url: str, user: str) -> None:
172173 print (f" { COUNT } contacts with categories and varied name structures" )
173174
174175
176+ def _fetch_all_comments (s : niquests .Session , url : str , file_id : str ) -> list [tuple [str , str , str ]]:
177+ """Return all comments on file_id as list of (id, message, creation_ts)."""
178+ out : list [tuple [str , str , str ]] = []
179+ offset = 0
180+ while True :
181+ report = s .request (
182+ "REPORT" ,
183+ f"{ url } /remote.php/dav/comments/files/{ file_id } " ,
184+ data = (
185+ '<?xml version="1.0" encoding="utf-8"?>'
186+ '<oc:filter-comments xmlns:oc="http://owncloud.org/ns">'
187+ f"<oc:limit>100</oc:limit><oc:offset>{ offset } </oc:offset>"
188+ "</oc:filter-comments>"
189+ ),
190+ headers = {"Content-Type" : "application/xml" },
191+ )
192+ batch : list [tuple [str , str , str ]] = []
193+ for resp_el in ET .fromstring (report .text ).findall ("{DAV:}response" ):
194+ href = resp_el .find ("{DAV:}href" )
195+ msg_el = resp_el .find (".//{http://owncloud.org/ns}message" )
196+ ts_el = resp_el .find (".//{http://owncloud.org/ns}creationDateTime" )
197+ if href is not None and msg_el is not None and msg_el .text and ts_el is not None :
198+ cid = href .text .rstrip ("/" ).split ("/" )[- 1 ]
199+ batch .append ((cid , msg_el .text , ts_el .text or "" ))
200+ if not batch :
201+ break
202+ out .extend (batch )
203+ if len (batch ) < 100 :
204+ break
205+ offset += 100
206+ return out
207+
208+
175209def seed_comments (s : niquests .Session , url : str , user : str ) -> None :
176210 """Create a dedicated file and add many comments to it."""
177211 dav = f"{ url } /remote.php/dav/files/{ user } "
@@ -196,13 +230,25 @@ def seed_comments(s: niquests.Session, url: str, user: str) -> None:
196230 return
197231 file_id = fileid_el .text
198232
233+ expected = {f"Pagination test comment { i :03d} " for i in range (1 , COUNT + 1 )}
234+ existing = _fetch_all_comments (s , url , file_id )
235+ expected_ts = [ts for _ , msg , ts in existing if msg in expected ]
236+ if expected .issubset ({m for _ , m , _ in existing }) and len (set (expected_ts )) >= COUNT :
237+ print (f" { COUNT } comments on file { file_id } (already present with distinct timestamps)" )
238+ return
239+
240+ for cid , _ , _ in existing :
241+ s .delete (f"{ url } /remote.php/dav/comments/files/{ file_id } /{ cid } " )
242+
199243 for i in range (1 , COUNT + 1 ):
200244 s .post (
201245 f"{ url } /remote.php/dav/comments/files/{ file_id } " ,
202246 json = {"actorType" : "users" , "verb" : "comment" , "message" : f"Pagination test comment { i :03d} " },
203247 headers = {"Content-Type" : "application/json" },
204248 )
205- print (f" { COUNT } comments on file { file_id } " )
249+ if i < COUNT :
250+ time .sleep (1.05 )
251+ print (f" { COUNT } comments on file { file_id } (reset and re-created with 1.05s spacing for stable pagination)" )
206252
207253
208254def main () -> None :
0 commit comments