/ backend / providers / sixtshare.py
sixtshare.py
  1  from decimal import Decimal
  2  from typing import List
  3  
  4  from scrapy.http import HtmlResponse
  5  
  6  from cache.store import strip_all_get_decimal
  7  from models.interface import ProviderInterface, VehicleOption, Calculator
  8  
  9  
 10  class SixtShareCalculator(Calculator):
 11      unlock_fee: int
 12      pay_km_from: int = 200
 13      three_hour_price: int
 14      six_hour_price: int
 15  
 16      def total_price(self) -> Decimal:
 17          price = self.unlock_fee
 18          hours = self.vehicle_request.time_minutes / 60
 19          minutes = self.vehicle_request.time_minutes % 60
 20  
 21          if 3 <= hours <= 6:
 22              price += self.three_hour_price
 23              price += self.price_per_minute * minutes
 24              self.pay_km_from = 80
 25          elif hours > 6:
 26              price += self.six_hour_price
 27              price += self.price_per_minute * minutes
 28              self.pay_km_from = 120
 29          else:
 30              price += self.price_per_minute * self.vehicle_request.time_minutes
 31  
 32          if self.vehicle_request.distance_kilometer > self.pay_km_from:
 33              price += self.price_per_km * (
 34                  self.vehicle_request.distance_kilometer - self.pay_km_from
 35              )
 36  
 37          return Decimal(price)
 38  
 39  
 40  class SixtShare(ProviderInterface):
 41      async def get_vehicles_options(self) -> List[VehicleOption]:
 42          pricing_page = self.get_pricing_html()[0]
 43          response = HtmlResponse(
 44              url=pricing_page.url, body=pricing_page.html, encoding="utf-8"
 45          )
 46  
 47          xpaths = [
 48              "/html/body/main/section[5]/section[3]/div/div/section[1]/div/div[2]/table/tbody/tr[1]/td[2]",  # price per minute
 49              "/html/body/main/section[5]/section[3]/div/div/section[1]/div/div[2]/table/tbody/tr[3]/td[2]",  # price per km
 50              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[1]/td[2]",  # three hours class 1
 51              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[1]/td[3]",  # six hours class 1
 52              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[2]/td[2]",  # three hours class 2
 53              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[2]/td[3]",  # six hours class 2
 54              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[3]/td[2]",  # three hours class 3
 55              "/html/body/main/section[5]/section[3]/div/div/section[2]/div/div[2]/table/tbody/tr[3]/td[3]",  # six hours class 3
 56          ]
 57  
 58          (
 59              price_per_minute,
 60              price_per_km,
 61              three_hours_class_1,
 62              six_hours_class_1,
 63              three_hours_class_2,
 64              six_hours_class_2,
 65              three_hours_class_3,
 66              six_hours_class_3,
 67          ) = tuple(
 68              strip_all_get_decimal(response.xpath(xpath).extract()[0].strip())
 69              for xpath in xpaths
 70          )
 71  
 72          class_3_calc = SixtShareCalculator(
 73              price_per_minute=price_per_minute,
 74              price_per_km=price_per_km,
 75              three_hour_price=int(three_hours_class_3),
 76              six_hour_price=int(six_hours_class_3),
 77              unlock_fee=3,
 78              vehicle_request=self.vehicle_request,
 79          )
 80          return [
 81              VehicleOption(
 82                  calculator=SixtShareCalculator(
 83                      price_per_minute=price_per_minute,
 84                      price_per_km=price_per_km,
 85                      three_hour_price=int(three_hours_class_1),
 86                      six_hour_price=int(six_hours_class_1),
 87                      unlock_fee=1,
 88                      vehicle_request=self.vehicle_request,
 89                  ),
 90                  electric=True,
 91                  vehicle_image="sixt-share-class-1.png",
 92                  provider="Sixt Share",
 93                  type="Klasse 1",
 94              ),
 95              VehicleOption(
 96                  calculator=SixtShareCalculator(
 97                      price_per_minute=price_per_minute,
 98                      price_per_km=price_per_km,
 99                      three_hour_price=int(three_hours_class_2),
100                      six_hour_price=int(six_hours_class_2),
101                      unlock_fee=1,
102                      vehicle_request=self.vehicle_request,
103                  ),
104                  electric=True,
105                  vehicle_image="sixt-share-class-2.png",
106                  provider="Sixt Share",
107                  type="Klasse 2",
108              ),
109              VehicleOption(
110                  calculator=class_3_calc,
111                  vehicle_image="sixt-share-class-3.png",
112                  electric=True,
113                  provider="Sixt Share",
114                  type="Klasse 3",
115              ),
116              VehicleOption(
117                  calculator=class_3_calc,
118                  vehicle_image="sixt-share-class-4.png",
119                  electric=True,
120                  provider="Sixt Share",
121                  type="Klasse 4",
122              ),
123          ]