Sly32

Рейтинг
378
Регистрация
29.03.2012
Должность
Software engineer
sumpsonb #:
а что не так?

Для начала:

parser/index_api.py:1:1: F401 'json' imported but unused
parser/index_api.py:4:1: F401 'datetime.datetime' imported but unused
parser/index_api.py:9:1: E302 expected 2 blank lines, found 1
parser/index_api.py:13:1: W293 blank line contains whitespace
parser/index_api.py:14:1: W293 blank line contains whitespace
parser/index_api.py:15:9: E303 too many blank lines (2)
parser/index_api.py:22:1: W293 blank line contains whitespace
parser/index_api.py:23:1: W293 blank line contains whitespace
parser/index_api.py:24:9: E303 too many blank lines (2)
parser/index_api.py:36:1: W293 blank line contains whitespace
parser/index_api.py:38:30: F541 f-string is missing placeholders
parser/index_api.py:40:1: W293 blank line contains whitespace
parser/index_api.py:47:1: W293 blank line contains whitespace
parser/index_api.py:52:1: W293 blank line contains whitespace
parser/index_api.py:56:1: W293 blank line contains whitespace
parser/index_api.py:59:64: W504 line break after binary operator
parser/index_api.py:59:67: W291 trailing whitespace
parser/index_api.py:60:71: W504 line break after binary operator
parser/index_api.py:60:74: W291 trailing whitespace
parser/index_api.py:61:21: E129 visually indented line with same indent as next logical line
parser/index_api.py:71:1: W293 blank line contains whitespace
parser/index_api.py:80:1: W293 blank line contains whitespace
parser/index_api.py:84:1: W293 blank line contains whitespace
parser/index_api.py:88:1: W293 blank line contains whitespace
parser/index_api.py:90:1: W293 blank line contains whitespace
parser/index_api.py:93:1: W293 blank line contains whitespace
parser/index_api.py:99:30: W291 trailing whitespace
parser/index_api.py:100:1: W293 blank line contains whitespace
parser/index_api.py:101:1: W293 blank line contains whitespace
parser/index_api.py:102:13: E303 too many blank lines (2)
parser/index_api.py:108:1: W293 blank line contains whitespace
parser/index_api.py:110:1: W293 blank line contains whitespace
parser/index_api.py:114:1: E305 expected 2 blank lines after class or function definition, found 1
parser/index_api.py:119:1: W293 blank line contains whitespace
parser/index_api.py:121:27: W292 no newline at end of file

Это арбнет может позволить себе писать не соблюдая кодстайл и не думая как там потом интерпретатор будет корячится. Правда, допускаю что что-то из этого - из-за ошибки копирования.
Теперь по замечаниям:
- Логгер не нужно пихать в класс - это нарушает бизнес логику, не дает его переиспользовать,  возникаю сложности с тестированием. 
- Хорошая практика обьявлять сессию как контекст-менеджер. Нужно обьяснять зачем? 
- один метод - одно действие. вспоминаем SOLID. поэтому разбиваем process_urls. В черновом варианте примерно так:

import json
import time
import logging
from datetime import datetime
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
import os
from contextlib import contextmanager
from typing import List, Tuple, Optional

def setup_logger(name: str, log_file: str) -> logging.Logger:
    """Configure and return a logger with file and console handlers."""
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    
    if not logger.handlers:
        # File handler
        file_handler = logging.FileHandler(log_file)
        file_handler.setFormatter(
            logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s',
                            datefmt='%Y-%m-%d %H:%M:%S')
        )
        logger.addHandler(file_handler)
        
        # Console handler
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(
            logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s')
        )
        logger.addHandler(console_handler)
    
    return logger

class GoogleIndexingAPI:
    def __init__(self, service_account_file: str, urls_file: str, logger: logging.Logger):
        self.service_account_file = service_account_file
        self.urls_file = urls_file
        self.logger = logger

    @contextmanager
    def get_authenticated_session(self):
        """Context manager for handling authenticated sessions."""
        try:
            credentials = service_account.Credentials.from_service_account_file(
                self.service_account_file,
                scopes=['https://www.googleapis.com/auth/indexing']
            )
            session = AuthorizedSession(credentials)
            self.logger.info("Successfully authenticated with service account")
            yield session
        except Exception as e:
            self.logger.error(f"Authentication failed: {str(e)}")
            yield None
        finally:
            if session:
                session.close()

    def submit_url(self, session: AuthorizedSession, url: str) -> bool:
        """Submit a single URL for indexing."""
        api_url = 'https://indexing.googleapis.com/v3/urlNotifications:publish'
        data = {'url': url, 'type': 'URL_UPDATED'}
        
        try:
            self.logger.info(f"Submitting URL to index: {url}")
            response = session.post(api_url, json=data)
            
            if response.status_code == 200:
                response_data = response.json()
                if self._validate_response(response_data, url):
                    self.logger.info(f"Successfully submitted URL: {url}")
                    return True
            
            self.logger.error(f"Failed to submit URL {url}. Status: {response.status_code}")
            return False
            
        except Exception as e:
            self.logger.error(f"Error submitting URL {url}: {str(e)}")
            return False

    def _validate_response(self, response_data: dict, url: str) -> bool:
        """Validate the API response data."""
        return ('urlNotificationMetadata' in response_data and
                'url' in response_data['urlNotificationMetadata'] and
                response_data['urlNotificationMetadata']['url'] == url)

    def _read_urls(self) -> List[str]:
        """Read URLs from file."""
        with open(self.urls_file, 'r') as f:
            return [line.strip() for line in f if line.strip()]

    def _save_failed_urls(self, failed_urls: List[str]) -> None:
        """Save failed URLs to file."""
        if failed_urls:
            failed_file = 'failed_urls.txt'
            with open(failed_file, 'w') as f:
                for url in failed_urls:
                    f.write(f"{url}\n")
            self.logger.info(f"Failed URLs written to {failed_file}")

    def process_urls(self) -> Tuple[int, int]:
        """Process all URLs from the input file."""
        if not os.path.exists(self.urls_file):
            self.logger.error(f"URLs file not found: {self.urls_file}")
            return (0, 0)
            
        try:
            urls = self._read_urls()
            self.logger.info(f"Found {len(urls)} URLs to process")
            
            successful_urls = []
            failed_urls = []
            
            with self.get_authenticated_session() as session:
                if not session:
                    return (0, 0)
                
                for url in urls:
                    if self.submit_url(session, url):
                        successful_urls.append(url)
                    else:
                        failed_urls.append(url)
                    time.sleep(1)
            
            self._save_failed_urls(failed_urls)
            self.logger.info(f"Processing complete. Success: {len(successful_urls)}, Failed: {len(failed_urls)}")
            return len(successful_urls), len(failed_urls)
            
        except Exception as e:
            self.logger.error(f"Error processing URLs: {str(e)}")
            return (0, 0)

def main():
    # Configuration
    SERVICE_ACCOUNT_FILE = "service-account.json"
    URLS_FILE = "urls.txt"
    LOG_FILE = "indexing.log"
    
    # Setup logger
    logger = setup_logger("google_indexing", LOG_FILE)
    
    # Initialize and run indexer
    indexer = GoogleIndexingAPI(SERVICE_ACCOUNT_FILE, URLS_FILE, logger)
    success, failed = indexer.process_urls()
    
    return success, failed

if __name__ == "__main__":
    main()

Ну и работать со сторонним апи в синхронном коде я бы вообще не стал. Использование threading ускорит работу минимум в 4 раза. 
это все так, навскидку. Если повозиться, можно еще пооптимизировать. 

alaev #:
Сила притяжения действует всегда,

Где я тебя спрашивал про силу притяжения? Понимаю, что тебе сложно сосредоточится, поэтому напоминаю - разговор был про ускорение свободного падения - для тела не имеющего опоры.

alaev #:
У тебя с пониманием разделов физики плохо.

Я теперь полностью уверен, что ты врешь про институты. Ты вообще не понимаешь о чем идет речь. Какая подьемная сила будет у колеса, катящегося по дороге? Разберись уже, когда она возникает, двоечник.

Какая подьемная сила может быть у пули? Почитай в принципе, что это такое, раз уж приплел. Не понимаю, как можно быть настолько...
Ты идешь по дороге и пялишься в тик-ток и вдруг яма - ты что - перелетишь ее используя подьемную силу? 
ты ... упадешь на дно. Если  ты шел медленно, прямо у края ямы и рухнешь, со стороны откуда шел. Если довольно быстро - упадешь ближе к дальнему краю. Если ты бежал стелефоном в руках, чего обычно люди не делают, но от тебя можно всего ожидать - ты возможно и не упадешь а повиснешь на другой стороне или даже перепрыгнешь(сомневаюсь)
Уже даже интересно, дойдет ли это до тебя или дальше будешь бред из нейросетей постить?

alaev #:
Ускорение свободного падения, как ты говоришь, "действовать" не начинает, оно всегда действовало. И на колесо, и на глушак

Да ладно? То есть ты сидишь в кресле и падаешь? с какой скоростью? Или все-таки ты начинаешь падать, когда под тобой нет опоры? 

Ну может давай к баллистике перейдем? Что происходит с пулей, когда она вылетает из ствола? Чтоб не было вопросов - ствол расположен горизонально? Крыльев у пули нет) Двигателя нет. Она будет взлетать или падать? 
От начальной скорости зависит, сколько она пролетит?
Никакого отношения центр масс к данной задаче не имеет. Гуглишь и сам не понимаешь что))) 

alaev #:

Ты тут словоблудием занят.

Скорость - вектор. И силы, действующие на авто, тоже векторные величины.

В школе это объясняют.

Но в школе не изучают взаимодействие вращающегося колеса с неподвижным препятствием.

Я уже сомневаюсь, что ты даже в школе учился... Не можешь понять элементарное. Давай я тебе как для восьмиклассника обьясню. Что такое скорость - знаешь? За сколько ты сможешь проехать, например 50 см сможешь высчитать? Дальше. Что такое ускорение свободного падения знаешь? Если нет то почитай. Когда колесо теряет опору, что на него начинает действовать? Ускорение свободного падения. Форумлу расчета знаешь?
А теперь ты знаешь, что за Х секунд ты проедешь А метров. При этом за эти же Х секунд колесо провалится в них тоже на В метров. Соответственно на выезде из ямы для колеса образуется условное препятствие в С метров высотой.  Следишь за логикой или уже пошел пасьянс раскладывать? Теперь простая задача - если скорость будет в 2 раза выше, сможешь посчитать, насколько времени тебе понадобиться меньше, чтобы проехать те же А метров? И Высота С изменится или нет и соответственно удар по подвеске. 
А теперь скажи мне каким боком тут марка автомобиля, вращение колеса... Понимаешь что в данном случае это константы, которые вообще не важны?

Сомневаюсь, конечно что до тебя дошло. Любопытно посмотреть как будешь выкручиваться тут. Примешаешь качество дорог в Польше?

alaev #:
Я на скорости 100 км/ч ночью вовремя не заметил колесо на МКАДе и наехал на него

Ну правильно, чего жалеть мамкину вольву)))😂

sigiziy #:
Либо план Б - очень медленно без буханий. Промежуточные варианты неприемлемы.

Вообще-то как по мне - самый правильны вариант) Если конечно колесо достает до дна ямы) Но иначе это уже каскадерство. Проще обьехать

Сергей про е-ком #:
Но размер ямы имеет значение в таком случае, как и диаметр колеса.

Конечно имеет. Как у прыгуна - чем быстрее разгонишься, тем дальше прыгнешь. Так и тут есть определенная скорость, двигаясь с которой ты не ударишься колесом о край ямы а просто перелетишь ее. 

Повторюсь - разговор только о том работает ли принцип "Выше скорость - меньше яма"  Понятно что можно учитывать дополнительно массу параметров - подвеска, горизонтальность движения,  масса автомобиля, сопротивление воздуха и тд. 

Простая формула за 8-й класс )))

Сергей про е-ком #:
Так ты даже время отработки амортизаторов не посчитал, скорость падения колеса в корреляции со скоростью движения, про то, что есть ещё пневмо. )

Конечно не считал. А зачем? Включай логику. Мы НЕ ищем идеальный автомобиль для прохождения ям. Мы ищем зависимость от СКОРОСТИ! Для авто с убитыми амортизаторами добавится  при ударе еще и сила удара от пружины. Но зависимость от скорости в целом не поменяется. Чем быстрее он проскочит яму - тем меньше туда опуститься колесо. Все остальное уже флуд аля алаев

Панове, я, мягко говоря, в шоке. Я предполагал, конечно, что в сеошники идут не самые образованные люди. Но попасть в ареал обитания людей с полным отсутствием логики, умения вести беседу в нужном ключе, с отсутствием знаний базовых за среднюю школу - это перебор.
Признаю, что самый главный глупец - это я. Попытался ответить на простой вопрос, используя базовые знания математики и физики.  
Dmitriy_2014 :
Слышал такую мульку, что типа лучше ямы на скорости проезжать, чем притормозить перед ними, типа так пролетаешь незаметно, как относитесь к такой теории?

Заметьте - я не брал весь вопрос, а выбрал интересующую меня часть. Мастерство вождения, способы проезда - это все было бы хорошо, если бы  побежавшие комментировать не цитировали бы меня. Ответь спокойно свою версию и иди дальше. Но нет, прибежали нечитатели. Вместо ям выросли кочки, начали махать водительскими удостоверениями, выяснять, какая у меня машина...
А вопрос и ответ -то именно в рамках базового образования, я даже не уверен, что среднего. В каком классе проходят скорость? Что такое ускорение свободного падения? И всего то нужно взять длину ямы, скорость автомобиля и посчитать, насколько колесо погрузиться в яму. Это высшая математика? 
Дальше, построить вектор направления удара в этом случае от оси колеса - чем глубже колесо упало - тем больше угол удара. Чем он больше - тем сильнее сам удар. Этого достаточно для базовых выводов.
4 формулы из школьного учебника.
А устроили вакханалию...

poruchick #:
Если грамотно разгрузить сторону, по которой яма (для пешеходов - свалить центр тяжести на сторону, противоположную колесу над ямой), удара не будет вообще ни на какой скорости. Для этого не нужно быть дипломированным физиком)))

Еще один нечитатель нарисовался...
Когда обсуждается вопрос:

Dmitriy_2014 :
Слышал такую мульку, что типа лучше ямы на скорости проезжать, чем притормозить перед ними, типа так пролетаешь незаметно, как относитесь к такой теории?

При чем тут твои советы "опытного" обладателя карточки, которые не только лишь все знают?

alaev #:
И почему яма именно? А не камень или бордюр?

Потому что когда тема про ямы - говорят про яму. Но ты, как обычно не состоянии прочитать топик.

Всего: 7663