An entry has one or more user-agents and zero or more rulelines
| 246 | |
| 247 | |
| 248 | class Entry: |
| 249 | """An entry has one or more user-agents and zero or more rulelines""" |
| 250 | def __init__(self): |
| 251 | self.useragents = [] |
| 252 | self.rulelines = [] |
| 253 | self.delay = None |
| 254 | self.req_rate = None |
| 255 | |
| 256 | def __str__(self): |
| 257 | ret = [] |
| 258 | for agent in self.useragents: |
| 259 | ret.append(f"User-agent: {agent}") |
| 260 | if self.delay is not None: |
| 261 | ret.append(f"Crawl-delay: {self.delay}") |
| 262 | if self.req_rate is not None: |
| 263 | rate = self.req_rate |
| 264 | ret.append(f"Request-rate: {rate.requests}/{rate.seconds}") |
| 265 | ret.extend(map(str, self.rulelines)) |
| 266 | return '\n'.join(ret) |
| 267 | |
| 268 | def applies_to(self, useragent): |
| 269 | """check if this entry applies to the specified agent""" |
| 270 | # split the name token and make it lower case |
| 271 | useragent = useragent.split("/")[0].lower() |
| 272 | for agent in self.useragents: |
| 273 | if agent == '*': |
| 274 | # we have the catch-all agent |
| 275 | return True |
| 276 | agent = agent.lower() |
| 277 | if agent in useragent: |
| 278 | return True |
| 279 | return False |
| 280 | |
| 281 | def allowance(self, filename): |
| 282 | """Preconditions: |
| 283 | - our agent applies to this entry |
| 284 | - filename is URL encoded""" |
| 285 | for line in self.rulelines: |
| 286 | if line.applies_to(filename): |
| 287 | return line.allowance |
| 288 | return True |
no outgoing calls
no test coverage detected
searching dependent graphs…