diff --git a/src/markup.py b/lib/markup.py similarity index 100% rename from src/markup.py rename to lib/markup.py diff --git a/src/vkdigest.py b/src/vkdigest.py deleted file mode 100755 index 54ad728..0000000 --- a/src/vkdigest.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (C) 2019, Maxim Lihachev, - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# -# pip install vk_api -# pip install lib/markup.py -# pip install configparser -# - -import os -import re -import sys -import json -import vk_api -import getopt -import markup -import string -import datetime -import configparser - -from markup import oneliner as _ - -from smtplib import SMTP_SSL as SMTP -from email.mime.text import MIMEText - -############################################################################ - - -def usage(): - print ''' - vkdigest — сценарий для получения сообщений из сообществ vk.com - с выводом в html и/или отправкой по электронной почте. - - Аргументы командной строки: - -h --help - вывести справку по использованию - -f --file - загрузить сообщества из файла - -u --url - открыть сообщество по адресу - -m --mail - отправить дайжест по электронной почте - -s --subj - тема сообщения, макросы: {DATE}, {URL}, {COMMENT} - -t --title - HTML-заголовок, то же самое, что и --subj - -c --cli - вывести дайжест на экран (по умолчанию) - -o --out - вывести дайжест в файл - ''' - sys.exit(2) - -############################################################################ - - -# Конфигурационный файл -CONFIG_FILE = os.path.join(os.path.dirname(__file__), os.pardir, 'conf/vkdigest.ini') - -# Вывод на экран -# -c | --cli -CLI_OUTPUT = True - -# Вывод в файл -# -f -# --file -FILE_OUTPUT = False - -# Отправка почты по умолчанию -SEND_MAIL = False - -# Путь до css-файла -CSS_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, 'css/vkdigest.css')) - -############################################################################ - - -def readConfig(config_file): - '''Чтение конфигурационного файла''' - global settings - settings = configparser.ConfigParser() - settings._interpolation = configparser.ExtendedInterpolation() - settings.read(config_file) - return settings - - -def opt(parameter): - '''Получение опции из файла''' - setting = parameter.split(":") - return settings.get(setting[0], setting[1]) - - -def enabled(opt): - return opt.lower() in ("yes", "true", "t", "1") - - -def timestamp_to_date(timestamp, fmt='%Y-%m-%d %H:%M:%S'): - '''Преобразование временного штампа в читаемую дату''' - return datetime.datetime.fromtimestamp(int(timestamp)).strftime(fmt) - - -def today(): - '''Текущая дата''' - return int(datetime.datetime.strptime(datetime.datetime.today().strftime('%Y-%m-%d'), '%Y-%m-%d').strftime("%s")) - - -def u(string): - return string.encode('utf-8') - -############################################################################ - -def make_title(): - '''Заголовок страницы и тема письма''' - return MAIL_SUBJECT.format(URL=opt('mail:url'), - COMMENT=opt('mail:comment'), - DATE=timestamp_to_date(today(), - '%Y-%m-%d')) - - -# Псевдоним для функции send_email -make_subject = make_title - - -def send_email(message): - '''Отправка письма с дайжестом''' - subject = make_subject() - - try: - msg = MIMEText(message, 'html') - msg['Subject'] = subject - msg['From'] = opt('mail:sender') - - conn = SMTP(opt('mail:SMTPserver')) - conn.set_debuglevel(False) - conn.login(opt('mail:username'), opt('mail:password')) - try: - conn.sendmail(opt('mail:sender'), opt('mail:destination'), msg.as_string()) - finally: - conn.quit() - - except Exception, exc: - sys.exit("mail failed; %s" % str(exc)) - -############################################################################ - -def auth(login, password): - '''Аутентификация в vk.com''' - vk_session = vk_api.VkApi(login, password) - try: - vk_session.auth() - return vk_session.get_api() - except vk_api.AuthError as error_msg: - print(error_msg) - return - - -def only_today(wall, date=None): - '''Записи за указанную дату''' - return [post for post in wall if post['date'] >= today()] - - -def get_group_url(group): - '''Адрес группы''' - return group.split(' ')[0] - - -def get_group_name(url): - '''HTTP-имя группы''' - return url.split('/')[-1] - - -def get_photos(attachments): - '''Получение ссылок на изображения''' - return [attachment['photo'] for attachment in attachments if attachment['type'] == 'photo'] - - -def get_documents(attachments): - '''Получение ссылок на документы''' - return [attachment['doc'] for attachment in attachments if attachment['type'] == 'doc'] - - -def get_links(attachments): - '''Получение ссылок''' - return [attachment['link'] for attachment in attachments if attachment['type'] == 'link'] - - -def group_info(name): - '''Информация о сообществе''' - # TODO: если репост со страницы пользователя, то вставляет название группы - return vk.groups.getById(group_ids=name)[0] - - -def wall_url(group_id, post_id): - '''Ссылка на конкретный пост''' - return "http://vk.com/wall" + str(group_id) + '_' + str(post_id) - - -def wall(name): - '''Получение записей со стены сообщества''' - id = group_info(get_group_name(name))['id'] - - content = vk.wall.get(owner_id=-id)['items'] - - if enabled(opt('digest:only_today')): - content = only_today(content) - - return content - -############################################################################ - - -def html_toc(groups): - '''Содержание дайжеста со ссылками на группы''' - HTML.h2("Сообщества:") - HTML.ul() - for group in groups: - if group.strip(): - group_name = get_group_name(get_group_url(group)) - info = group_info(group_name) - - HTML.li(_.a(u(info['name']), href='#' + u(group_name))) - HTML.ul.close() - HTML.br() - HTML.hr() - - -def groups_info(input_file): - '''Информация о группах, перечисленных в файле''' - f = open(input_file, "r") - groups = f.readlines() - f.close() - - if len(groups) > 1: - html_toc(groups) - - for group in groups: - if group.strip(): - url = get_group_url(group) - MAIL_URL = url - - if '#' in group: - MAIL_COMMENT = group.split('#')[1] - - group_info_html(url) - wall_html(url) - - -def group_info_html(name): - '''Информация о группе в формате HTML''' - group_name = get_group_name(name) - info = group_info(group_name) - - HTML.div(class_='group-info') - HTML.img(src=u(info['photo_50'])) - - if enabled(opt('digest:add_links')): - HTML.h1(_.a(u(info['name']), href="http://vk.com/" + u(info['screen_name'])), id=u(group_name)) - else: - HTML.h1(u(info['name']), id=u(group_name)) - - HTML.div.close() - HTML.br() - HTML.hr() - - -def wall_html(name): - '''Сообщения со стены сообщества в формате HTML''' - info = wall(name) - - for post in info: - if post['text'] or ('attachments' in post): - post_html(post) - # Репост - elif 'copy_history' in post: - post_html(post['copy_history'][0], True) - - -def post_html(content, repost=False): - '''Информация о посте в формате HTML''' - HTML.div(class_="post") - - if repost: - original_group = group_info(abs(content['owner_id'])) - original_name = u(original_group['name']) - original_url = wall_url(content['from_id'], content['id']) - - # Дата поста - HTML.h4() - - if enabled(opt('digest:add_links')): - HTML.add(_.a(timestamp_to_date(content['date']), href=wall_url(content['from_id'], content['id'])) + (' via ' + _.a(original_name, href=original_url) if repost else '')) - else: - HTML.add(timestamp_to_date(content['date']) + (' via ' + original_name if repost else '')) - - HTML.h4.close() - - # Текст поста - HTML.p(tuple(u(content['text']).splitlines())) - - # Документы - if 'attachments' in content: - for photo in get_photos(content['attachments']): - HTML.a(_.img(src=u(photo['photo_130'])), href=u(photo['photo_604'])) - - for document in get_documents(content['attachments']): - HTML.ul(_.li(_.a(u(document['title']), href=u(document['url'])))) - - for link in get_links(content['attachments']): - HTML.ul(_.li(_.a(u(link['title']), href=u(link['url'])))) - - HTML.br() - HTML.div.close() #
- HTML.hr() - -############################################################################ - - -# Чтение файла настроек -settings = [] -readConfig(CONFIG_FILE) - -MAIL_SUBJECT = opt('mail:subject') - -# Учётная запись vk.com -vk = auth(opt('vk:username'), opt('vk:password')) - -############################################################################ - -try: - opts, args = getopt.getopt(sys.argv[1:], 'f:u:s:t:o:mch', ['file=', 'url=', 'subj=', 'title=', 'out=', 'mail', 'cli', 'help']) -except getopt.GetoptError: - usage() - -if not opts: - usage() - -input_file = False -url = False - -CLI_OUTPUT_FLAG = False - -for option, arg in opts: - if option in ('-h', '--help'): - usage() - elif option in ('-f', '--file'): - input_file = arg - elif option in ('-u', '--url'): - url = arg - elif option in ('-s', '--subj'): - MAIL_SUBJECT = arg - elif option in ('-t', '--title'): - MAIL_SUBJECT = arg - elif option in ('-o', '--out'): - FILE_OUTPUT = arg - CLI_OUTPUT = False - elif option in ('-m', '--mail'): - SEND_MAIL = True - CLI_OUTPUT = False - elif option in ('-c', '--cli'): - CLI_OUTPUT_FLAG = True - else: - usage() - -if CLI_OUTPUT_FLAG: - CLI_OUTPUT = True - -HTML = markup.page() - -HTML.init( - title=make_title(), - lang="ru", - charset="utf-8", - css=(CSS_FILE if os.path.isfile(CSS_FILE) else "") -) - -if input_file: - if os.path.isfile(input_file): - groups_info(input_file) - else: - print "Неправильный входной файл ", input_file -elif url: - group_info_html(url) - wall_html(url) -else: - usage() - -############################################################################ - -if SEND_MAIL: - send_email(HTML()) - -if FILE_OUTPUT: - with open(FILE_OUTPUT, 'w') as outfile: - outfile.write(HTML()) - -if CLI_OUTPUT: - print HTML