Пример #1
0
 function setOfferLocation(Offer $offer)
 {
     $location = Location::findOrFail(Input::get('location_id'));
     $offer->location()->associate($location);
     $offer->save();
     return view('offer_location_changed')->with(['offer' => $offer]);
 }
Пример #2
0
 /**
  * Execute the job.
  *
  * @return void
  */
 public function handle(ParserLoggerInterface $logger, Client $client)
 {
     $context = ['url' => $this->url->url];
     try {
         $response = $client->get($this->url->url, ['allow_redirects' => false]);
     } catch (ClientException $e) {
         $logger->error('Client error', self::arrayInsert($context, 'exception', $e));
         throw $e;
     }
     if (200 !== ($code = $response->getStatusCode())) {
         switch ($code) {
             case 301:
                 if (preg_match('/from404/', $response->getHeaderLine('Location'))) {
                     $logger->warning('Offer deleted', $context);
                 } else {
                     $grabbedUrl = null;
                     try {
                         $grabbedUrl = GrabbedUrl::create(['url' => $response->getHeaderLine('Location')]);
                     } catch (QueryException $e) {
                         return;
                     }
                     if ($grabbedUrl) {
                         $this->dispatch(new Parse($grabbedUrl));
                         $logger->info('Dispatched new job', self::arrayInsert($context, 'new_url', $response->getHeaderLine('Location')));
                     }
                 }
                 return;
             default:
                 $logger->error('Invalid response code ' . $code, $context);
         }
     }
     $responseHtml = $response->getBody()->getContents();
     $crawler = new Crawler($responseHtml);
     $offer = new Offer();
     $offer->href = $this->url->url;
     $requiredFieldsCommands = ['phones' => function () use($client) {
         return self::getPhones($client, self::getOlxId($this->url->url));
     }, 'cat_path' => function () use($responseHtml) {
         return self::getCatPath($responseHtml);
     }];
     foreach ($requiredFieldsCommands as $field => $command) {
         try {
             $offer->{$field} = $command();
         } catch (\Exception $e) {
             $logger->error('Unable to extract required fields', self::arrayInsert($context, 'required_field', $field));
             throw $e;
         }
     }
     $fieldsCommands = ['price_string' => function () use($crawler) {
         return $crawler->filter('.pricelabel.tcenter')->first()->text();
     }, 'title' => function () use($crawler) {
         return $crawler->filter('.offerheadinner > h1')->text();
     }, 'olx_id' => function () {
         return self::getOlxId($this->url->url);
     }, 'description' => function () use($crawler) {
         return $crawler->filter('#textContent')->text();
     }, 'date_string' => function () use($crawler) {
         return self::getDate($crawler);
     }, 'offer_number' => function () use($crawler) {
         return self::getOfferNumber($crawler);
     }];
     $failedFields = [];
     foreach ($fieldsCommands as $field => $command) {
         try {
             $offer->{$field} = trim($command());
         } catch (\Exception $e) {
             array_push($failedFields, $field);
         }
     }
     $detailsTables = $crawler->filter('table.details table.item');
     $details = [];
     foreach ($detailsTables as $detailsTable) {
         /** @var $detailsTable Crawler */
         try {
             $details[$detailsTable->getElementsByTagName('th')->item(0)->textContent] = preg_replace('/\\t*|\\n*|\\s{2,}/u', '', $detailsTable->getElementsByTagName('td')->item(0)->textContent);
         } catch (\Exception $e) {
             array_push($failedFields, $detailsTable->text());
         }
     }
     if ($details) {
         $offer->details = $details;
     }
     if ($failedFields and $failedFields !== ["price_string"]) {
         // lots of offers don't have assigned price
         $logger->warning('Failed fields', self::arrayInsert($context, 'failed_fields', $failedFields));
     }
     if ($olxTimestamp = self::parseDate($offer->date_string)) {
         $offer->created_at_olx = $olxTimestamp;
     }
     try {
         $offer->save();
     } catch (QueryException $e) {
         if (23000 === intval($e->getCode())) {
             return;
             // duplicate offer, finish job
         }
         $logger->error('', self::arrayInsert($context, 'exception', $e));
         throw $e;
     }
     if ($offer) {
         try {
             $detectPhones = new DetectPhones($offer);
             $detectPhones->handle();
         } catch (\Exception $e) {
             \Log::critical('Failed to detect phones', ['exception' => $e]);
         }
     }
     if ($offer->wasRecentlyCreated) {
         $photos = [];
         try {
             $photos = $crawler->filter('#bigGallery a')->reduce(function (Crawler $node, $i) {
                 return (bool) $node->attr('href');
             })->extract('href');
         } catch (Exception $e) {
             $logger->error('Failed to get photos', self::arrayInsert($context, 'exception', $e));
         }
         if ($photos) {
             foreach ($photos as $photo) {
                 $offer->photos()->create(['url' => $photo]);
             }
         }
         if ($locationString = self::getLocationString($crawler)) {
             if ($location = Location::where('location', $locationString)->first()) {
                 $offer->location()->associate($location);
                 $offer->save();
             } else {
                 try {
                     $location = Location::create(['location' => $locationString]);
                 } catch (QueryException $e) {
                     $logger->error('Unable to create Location', self::arrayInsert($context, 'location', $locationString));
                 }
                 if ($location instanceof Location) {
                     $offer->location()->associate($location);
                     $offer->save();
                 }
             }
         }
     }
     Event::fire(new OfferParsed($offer));
 }