Разговоры о важном

Материал из IT в школе
Перейти к навигацииПерейти к поиску


Вот уже год мы говорим учителям, что скачивать "разговоры о важном" надо заранее. А воз и ныне там. Появилась идея скачать материалы автоматом в общую папку досок и запускать оттуда. Непонятно выдержит ли инфраструктура такую нагрузку. Будем пробовать. Кому интересно публикую скрипт для скачивания.

talks.sh

#!/bin/bash
#файл кладется в /root/ на Линукс (в моем случае Ubuntu, но это не существенно) сервере
#набираем crontab -e и добавляем строку "0 0 * * * /root/talks.sh"
#а еще надо сначала установить (или проверить наличие) утилиту mount.gluster
#xxx xxx замените на цифры, которые использует сеть в Вашей школе

sudo mount.glusterfs 10.xxx.xxx.20:/share /mnt
sudo /root/talks.py 
sudo umount /mnt

talks.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#утилита скачивание ВСЕХ имеющихся в наличии файлов "разговоров о важном"  в /mnt/public
#перед запуском проверьте наличие всех библиотек описанных в import, особенно logzero и bs4
#все библиотеки ставятся через pip (pip3)

import shutil
import pathlib
import os
import argparse
import hashlib
import requests
from logzero import logger as log
from pprint import pformat
from time import sleep
from bs4 import BeautifulSoup as bs

url="https://razgovor.edsoo.ru/"



class Yadiredo:
    API_ENDPOINT = 'https://cloud-api.yandex.net/v1/disk/public/resources/?public_key={}&path=/{}&offset={}'

    def md5sum(self, file_path):
        md5 = hashlib.md5()
        with open(file_path, 'rb') as f:
            for chunk in iter(lambda: f.read(128 * md5.block_size), b''):
                md5.update(chunk)
        return md5.hexdigest()

    def download_file(self, target_path, url):
        log.info('downloading')
        r = requests.get(url, stream=True)
        with open(target_path, 'wb') as f:
            shutil.copyfileobj(r.raw, f)

    def check_local_file(self, target_path, size, checksum):
        if os.path.isfile(target_path):
            if size == os.path.getsize(target_path):
                if checksum == self.md5sum(target_path):
                    return True
                else:
                    log.warning('checksum mismatch')
            else:
                log.warning('size mismatch')
        else:
            log.warning('missing')
        return False

    def try_as_file(self, j, current_path):
        if 'file' in j:
            file_save_path = os.path.join(current_path, j['name'])
            log.info(f'processing {file_save_path}')
            if not self.check_local_file(file_save_path, j['size'], j['md5']):
                self.download_file(file_save_path, j['file'])
            else:
                log.info('correct')
            return True
        return False

    def download_path(self, target_path, public_key, source_path, offset=0):
        log.info('getting "{}" at offset {}'.format(source_path, offset))
        current_path = os.path.join(target_path, source_path)
        pathlib.Path(current_path).mkdir(parents=True, exist_ok=True)
        jsn = requests.get(self.API_ENDPOINT.format(public_key, source_path, offset)).json()
        if self.try_as_file(jsn, current_path):
            return
        try:
            emb = jsn['_embedded']
        except KeyError:
            log.error(pformat(jsn))
            return
        items = emb['items']
        for i in items:
            if self.try_as_file(i, current_path):
                continue
            else:
                subdir_path = os.path.join(source_path, i['name'])
                self.download_path(target_path, public_key, subdir_path)

        last = offset + emb['limit']
        if last < emb['total']:
            self.download_path(target_path, public_key, source_path, last)


def scanall(url):
 r = requests.get(url)
 if (r.status_code==200):
#  soup=bs(r.text,features="lxml")
  soup=bs(r.text)
  e = soup.find_all('a')
  for a in e:
    if "topic" in a['href']:
     if a.find("div",class_="card-date"):
      d=a.div.find_all("div",class_="card-date")
      date=d[0].span.get_text()
      rr = requests.get(url+a['href'][1:])
      if (rr.status_code==200):
#       ssoup=bs(rr.text,features="lxml")
       ssoup=bs(rr.text)
       groups=ssoup.find_all('div',class_='topic-resource-group')
       for group in groups:
        cls=group.find("span").get_text()
        public_key=group.find('div',class_='topic-resource-download').a['href']
        d = Yadiredo()
        d.download_path("/mnt/public/Разговоры о важном/"+date+"/"+cls,public_key, '')



scanall(url)