Разговоры о важном
Материал из IT в школе
Версия от 08:46, 3 октября 2023; Kekaloav (обсуждение | вклад)
Вот уже год мы говорим учителям, что скачивать "разговоры о важном" надо заранее. А воз и ныне там. Появилась идея скачать материалы автоматом в общую папку досок и запускать оттуда. Непонятно выдержит ли инфраструктура такую нагрузку. Будем пробовать. Кому интересно публикую скрипт для скачивания.
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)