vk feed module

This commit is contained in:
2019-01-25 19:33:22 +03:00
parent 747713bce0
commit 90d8c02a08
9 changed files with 147 additions and 13 deletions

View File

@@ -30,3 +30,4 @@ class FeedsAppConfigForm(ConfigForm):
feed_bot_token = forms.CharField(required=True)
vk_username = forms.CharField(required=True)
vk_password = forms.CharField(required=True)
vk_auth = forms.CharField(required=False, widget=forms.Textarea())

View File

@@ -0,0 +1,25 @@
# Generated by Django 2.1.5 on 2019-01-25 16:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('feeds', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='VKFeedModuleConfig',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('owner_id', models.IntegerField()),
('send_text', models.BooleanField(default=True)),
('send_links', models.BooleanField(default=True)),
],
options={
'abstract': False,
},
),
]

View File

@@ -28,8 +28,8 @@ class Feed(models.Model):
if self.last_check and timezone.now() < self.last_check + self.check_interval:
return
self.lock = True
self.save()
# self.lock = True
# self.save()
execute_feed.delay(self.pk)
class Meta:

View File

@@ -1,3 +1,4 @@
from .echo import EchoFeedModuleConfig
from .vk_feed import VKFeedModuleConfig
FEED_MODULES = [EchoFeedModuleConfig]
FEED_MODULES = [EchoFeedModuleConfig, VKFeedModuleConfig]

77
feeds/modules/vk_feed.py Normal file
View File

@@ -0,0 +1,77 @@
import os
import tempfile
import requests
import sentry_sdk
from django.db import models
from djconfig import config
from telebot import TeleBot
from telebot.types import InputMediaPhoto
from vk_api import VkApi
from vk_api.audio import VkAudio
from feeds.models import FeedModuleConfig
from feeds.utils import DatabaseConfig
def get_vk_photo(attachment):
for size in (2560, 1280, 807, 604, 130, 75):
if f'photo_{size}' in attachment:
return attachment[f'photo_{size}']
return None
def get_file(url):
fname = '?'.join(url.split('?')[:-1])
extension = os.path.basename(fname).split('.')[-1]
f = tempfile.NamedTemporaryFile(suffix=f'.{extension}' if extension else None)
r = requests.get(url, stream=True)
for chunk in r.iter_content(1024 * 1024):
if chunk:
f.write(chunk)
f.seek(0)
return f
class VKFeedModuleConfig(FeedModuleConfig):
owner_id = models.IntegerField()
send_text = models.BooleanField(default=True)
send_links = models.BooleanField(default=True)
MODULE_NAME = 'VK feed'
def execute(self, bot: TeleBot, chat_id, last_id):
config._reload_maybe()
vk_session = VkApi(login=config.vk_username, password=config.vk_password, config=DatabaseConfig,
api_version='5.60')
vk_session.auth()
vk_audio = VkAudio(vk_session)
vk = vk_session.get_api()
wall_data = vk.wall.get(owner_id=self.owner_id)
for post in reversed(wall_data['items']):
if post['id'] > last_id:
try:
if self.send_text and post['text']:
bot.send_message(chat_id, post['text'])
if 'attachments' in post:
photos = []
for image in filter(lambda a: 'photo' in a, post['attachments']):
url = get_vk_photo(image['photo'])
if url:
photos.append(url.replace('\\', ''))
if len(photos) == 1:
bot.send_photo(chat_id, photos[0])
elif len(photos) > 1:
bot.send_media_group(chat_id, [InputMediaPhoto(photo) for photo in photos])
for a in post['attachments']:
if 'audio' in a:
f = get_file(vk_audio.get_audio_by_id(a['audio']['owner_id'], a['audio']['id']))
bot.send_audio(chat_id, f, a['audio'].get('duration'),
a['audio'].get('artist'), a['audio'].get('title'))
if self.send_links:
bot.send_message(chat_id, f"https://vk.com/wall{post['owner_id']}_{post['id']}",
disable_web_page_preview=True)
except Exception as e:
sentry_sdk.capture_exception(e)
last_id = post['id']
return last_id

View File

@@ -1,3 +1,6 @@
from pprint import pprint
from django.conf import settings
from django.utils import timezone
from telebot import TeleBot
from djconfig import config
@@ -7,8 +10,13 @@ from config.celery import app
@app.task()
def execute_feed(feed_pk):
config._reload_maybe()
from feeds.models import Feed
from django.db import connections
c = connections['default'].cursor()
print(c.db.__dict__)
# config._reload_maybe()
try:
feed = Feed.objects.get(pk=feed_pk)

View File

@@ -1,7 +1,11 @@
import yaml
from django.views.generic import TemplateView
from djconfig import config
from jconfig.base import BaseConfig
from yaml.parser import ParserError
from cabinet.utils import CabinetViewMixin
from feeds.forms import FeedForm, get_config_form
from feeds.forms import FeedForm, get_config_form, FeedsAppConfigForm
from feeds.models import Feed
@@ -36,3 +40,19 @@ class BaseFeedConfigView(CabinetViewMixin, TemplateView):
ctx['feed_form'], ctx['config_form'] = self.get_forms() if forms is None else forms
ctx['feed_module'] = self.get_content_type().model_class()
return ctx
class DatabaseConfig(BaseConfig):
__slots__ = ()
def load(self, **kwargs):
config._reload_maybe()
try:
settings = yaml.load(config.vk_auth)
except (ParserError, AttributeError):
settings = {}
settings.setdefault(self.section_name, {})
return settings
def save(self):
FeedsAppConfigForm(data={'vk_auth': yaml.dump(self._settings)}).save()