Mercurial > hg > MPIWGWeb
annotate SrvTxtUtils.py @ 159:ee79f6ba8d01
clean up staff editing and some zpt forms.
author | casties |
---|---|
date | Thu, 06 Jun 2013 15:34:20 +0200 |
parents | e0b343cee9dd |
children | 485bf377913a |
rev | line source |
---|---|
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
1 """Utility methods for handling XML, reading HTTP, etc""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
2 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
3 from App.ImageFile import ImageFile |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
4 from App.Common import rfc1123_date |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
5 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
6 import sys |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
7 import os |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
8 import stat |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
9 import urllib |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
10 import urllib2 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
11 import logging |
65 | 12 import time |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
13 |
49 | 14 import xml.etree.ElementTree as ET |
15 | |
137 | 16 srvTxtUtilsVersion = "1.9.2" |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
17 |
16 | 18 map_months = {'en': [u"", |
19 u"January", | |
20 u"February", | |
21 u"March", | |
22 u"April", | |
23 u"May", | |
24 u"June", | |
25 u"July", | |
26 u"August", | |
27 u"September", | |
28 u"October", | |
29 u"November", | |
30 u"December"], | |
31 'de': [u"", | |
32 u"Januar", | |
33 u"Februar", | |
34 u"M\u00e4rz", | |
35 u"April", | |
36 u"Mai", | |
37 u"Juni", | |
38 u"Juli", | |
39 u"August", | |
40 u"September", | |
41 u"Oktober", | |
42 u"November", | |
43 u"Dezember"]} | |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
44 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
45 def getInt(number, default=0): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
46 """returns always an int (0 in case of problems)""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
47 try: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
48 return int(number) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
49 except: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
50 return int(default) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
51 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
52 def getAt(array, idx, default=None): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
53 """returns element idx from array or default (in case of problems)""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
54 try: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
55 return array[idx] |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
56 except: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
57 return default |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
58 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
59 def unicodify(s): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
60 """decode str (utf-8 or latin-1 representation) into unicode object""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
61 if not s: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
62 return u"" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
63 if isinstance(s, str): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
64 try: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
65 return s.decode('utf-8') |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
66 except: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
67 return s.decode('latin-1') |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
68 else: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
69 return s |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
70 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
71 def utf8ify(s): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
72 """encode unicode object or string into byte string in utf-8 representation. |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
73 assumes string objects to be utf-8""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
74 if not s: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
75 return "" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
76 if isinstance(s, str): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
77 return s |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
78 else: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
79 return s.encode('utf-8') |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
80 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
81 def getText(node, recursive=0): |
49 | 82 """returns all text content of a (etree) node and its subnodes""" |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
83 if node is None: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
84 return '' |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
85 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
86 # ElementTree: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
87 text = node.text or '' |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
88 for e in node: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
89 if recursive: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
90 text += getText(e) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
91 else: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
92 text += e.text or '' |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
93 if e.tail: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
94 text += e.tail |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
95 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
96 # 4Suite: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
97 #nodelist=node.childNodes |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
98 #text = "" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
99 #for n in nodelist: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
100 # if n.nodeType == node.TEXT_NODE: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
101 # text = text + n.data |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
102 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
103 return text |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
104 |
49 | 105 |
106 def serialize(node): | |
107 """returns a string containing an XML snippet of (etree) node""" | |
108 s = ET.tostring(node, 'UTF-8') | |
109 # snip off XML declaration | |
110 if s.startswith('<?xml'): | |
111 i = s.find('?>') | |
112 return s[i+3:] | |
113 | |
114 return s | |
115 | |
116 | |
16 | 117 def getMonthName(mon, lang): |
118 """returns the name of the month mon in the language lang""" | |
119 return map_months[lang][mon] | |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
120 |
87
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
121 |
137 | 122 def getDateString(date=None, lang='en', withYear=True, monthNames=True, abbrev=False): |
87
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
123 """Return formatted date string.""" |
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
124 ds = None |
126 | 125 if callable(date.day): |
126 # callable members | |
127 day = date.day() | |
128 month = date.month() | |
129 year = date.year() | |
130 else: | |
131 # data members | |
132 day = date.day | |
133 month = date.month | |
134 year = date.year | |
135 | |
87
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
136 if lang.lower() == 'en': |
137 | 137 ds = "%s %s"%(getMonthName(month, lang), day) |
138 if withYear: | |
139 ds += ", %s"%year | |
140 | |
141 elif lang.lower() == 'de': | |
142 ds = "%s. %s"%(day, getMonthName(month, lang)) | |
87
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
143 if withYear: |
126 | 144 ds += " %s"%year |
137 | 145 |
146 elif lang.lower() == 'iso': | |
147 ds = date.isoformat() | |
87
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
148 |
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
149 return ds |
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
150 |
77f2478ae971
getDateString method to format dates in English and German.
casties
parents:
65
diff
changeset
|
151 |
0
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
152 def getHttpData(url, data=None, num_tries=3, timeout=10, noExceptions=False): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
153 """returns result from url+data HTTP request""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
154 # we do GET (by appending data to url) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
155 if isinstance(data, str) or isinstance(data, unicode): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
156 # if data is string then append |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
157 url = "%s?%s"%(url,data) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
158 elif isinstance(data, dict) or isinstance(data, list) or isinstance(data, tuple): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
159 # urlencode |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
160 url = "%s?%s"%(url,urllib.urlencode(data)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
161 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
162 response = None |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
163 errmsg = None |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
164 for cnt in range(num_tries): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
165 try: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
166 logging.debug("getHttpData(#%s %ss) url=%s"%(cnt+1,timeout,url)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
167 if sys.version_info < (2, 6): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
168 # set timeout on socket -- ugly :-( |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
169 import socket |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
170 socket.setdefaulttimeout(float(timeout)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
171 response = urllib2.urlopen(url) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
172 else: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
173 # timeout as parameter |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
174 response = urllib2.urlopen(url,timeout=float(timeout)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
175 # check result? |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
176 break |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
177 except urllib2.HTTPError, e: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
178 logging.error("getHttpData: HTTP error(%s): %s"%(e.code,e)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
179 errmsg = str(e) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
180 # stop trying |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
181 break |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
182 except urllib2.URLError, e: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
183 logging.error("getHttpData: URLLIB error(%s): %s"%(e.reason,e)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
184 errmsg = str(e) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
185 # stop trying |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
186 #break |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
187 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
188 if response is not None: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
189 data = response.read() |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
190 response.close() |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
191 return data |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
192 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
193 if noExceptions: |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
194 return None |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
195 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
196 raise IOError("ERROR fetching HTTP data from %s: %s"%(url,errmsg)) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
197 #return None |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
198 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
199 |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
200 def refreshingImageFileIndexHtml(self, REQUEST, RESPONSE): |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
201 """index_html method for App.ImageFile that updates the file info for each request.""" |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
202 stat_info = os.stat(self.path) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
203 self.size = stat_info[stat.ST_SIZE] |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
204 self.lmt = float(stat_info[stat.ST_MTIME]) or time.time() |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
205 self.lmh = rfc1123_date(self.lmt) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
206 # call original method |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
207 return ImageFile.index_html(self, REQUEST, RESPONSE) |
bca61e893fcc
first checkin of MPIWGWeb r2 branch from CVS into mercurial
casties
parents:
diff
changeset
|
208 |
65 | 209 |
210 def shortenString(s, l, ellipsis='...'): | |
211 """returns a string of length l (or l-1) by omitting characters in the middle of s, replacing with ellipsis.""" | |
212 l1 = int((l - len(ellipsis)) / 2) | |
213 return "%s%s%s"%(s[:l1],ellipsis,s[-l1:]) | |
214 |