44import uuid
55import hashlib
66import requests
7+ from urllib .parse import urlparse
78
89class ECL :
910 '''
@@ -23,14 +24,47 @@ def __init__(self, url, user, password, timeout=60, debug=False):
2324 timeout (int): request timeout in seconds
2425 '''
2526
26- self ._url = url
27+ self ._url = url if self . check_server ( url ) else self . get_active_server ()
2728 self ._password = password
2829 self ._user = user
2930
3031 self ._to = timeout
3132
3233 self ._debug = debug
3334
35+ def check_server (self , base_url , timeout = 5 ):
36+ """
37+ Check if a server is responsive.
38+ Returns True if server responds, False otherwise.
39+ """
40+ if base_url == '' or base_url is None :
41+ return False
42+ try :
43+ response = requests .get (base_url , timeout = timeout )
44+ return response .status_code == 200
45+ except requests .exceptions .RequestException :
46+ return False
47+
48+ def get_active_server (self , base_url = "https://dbweb0.fnal.gov/ECL/sbnd/E/index" ):
49+ """
50+ Follow redirect from dbweb0 to find the active server.
51+ Returns the base URL of the active server.
52+ """
53+ try :
54+ # Make a request that allows redirects
55+ response = requests .get (base_url , allow_redirects = True , timeout = 10 )
56+
57+ # Extract the final URL after redirects
58+ final_url = response .url
59+
60+ # Parse to get the scheme and netloc (e.g., https://dbweb1.fnal.gov:8443)
61+ parsed = urlparse (final_url )
62+ active_server = f"{ parsed .scheme } ://{ parsed .netloc } /ECL/sbnd/E"
63+
64+ return active_server
65+ except requests .exceptions .RequestException as e :
66+ print (f"Error discovering active server: { e } " )
67+ return None
3468
3569 def generate_salt (self ):
3670 '''
@@ -59,20 +93,62 @@ def signature(self, arguments, data=''):
5993 return m .hexdigest ()
6094
6195
62- def search (self , category = 'Purity+Monitors' , limit = 2 ):
96+ def search (self ,
97+ category = 'Purity+Monitors' ,
98+ after = '' ,
99+ before = '' ,
100+ form_name = '' ,
101+ tag = '' ,
102+ username = '' ,
103+ substring = '' ,
104+ words = '' ,
105+ limit = 100 ):
63106 '''
64107 Searched the last entries in a given category
65108
66109 Args:
67110 category (str): the category to search in
111+ after (str): searches for entries after a certain date. The date has to be in the following formats:
112+ <n>days (ex: "1days" for the last 24h entries)
113+ <n>hours (ex: "1hours" for the last hour entries)
114+ <n>minutes (ex: "1minutes" for the last minute entries)
115+ yyyy-mm-dd+hh:mm:ss (ex: "2012-04-01+12:00:00"
116+ before (str): searches for entries before a certain date. The date has to be in the following formats:
117+ <n>days (ex: "1days" for the last 24h entries)
118+ <n>hours (ex: "1hours" for the last hour entries)
119+ <n>minutes (ex: "1minutes" for the last minute entries)
120+ yyyy-mm-dd+hh:mm:ss (ex: "2012-04-01+12:00:00"
121+ form_name: searches entries that have "form_name" only
122+ tag: searches entries with a certain tag only
123+ username: searches entries from a particular user only
124+ substring: search for entries having specified text as substring - can be slow
125+ words: indexed search for entries having the words
68126 limit (int): limit to the number of entries
69127 '''
70128
71129 url = self ._url
72130 url += '/xml_search?'
73131
74- arguments = f'c={ category } &'
75- arguments += f'l={ limit } &'
132+ arguments = ''
133+
134+ if len (category ):
135+ arguments += f'c={ category } &'
136+ if len (after ):
137+ arguments += f'a={ after } &'
138+ if len (before ):
139+ arguments += f'b={ before } &'
140+ if len (form_name ):
141+ arguments += f'f={ form_name } &'
142+ if len (tag ):
143+ arguments += f't={ tag } &'
144+ if len (username ):
145+ arguments += f'u={ username } &'
146+ if len (substring ):
147+ arguments += f'st={ substring } &'
148+ if len (words ):
149+ arguments += f'si={ words } &'
150+ if limit is not None :
151+ arguments += f'l={ limit } &'
76152 arguments += self .generate_salt ()
77153
78154 # headers = {'content-type': 'text/xml'}
@@ -87,6 +163,8 @@ def search(self, category='Purity+Monitors', limit=2):
87163
88164 return r .text
89165
166+
167+
90168 def get_entry (self , entry_id = 2968 ):
91169 '''
92170 Gets a particular entry.
0 commit comments