import asyncio
import html
import logging

import feedparser
import telepot
import yaml


class Server(object):
    def __init__(self, filename='config.yml'):
        self.filename = filename
        try:
            with open(filename, 'r', encoding='utf-8') as stream:
                try:
                    self.config = yaml.load(stream)
                except yaml.YAMLError as err:
                    logging.error(err)
        except OSError as err:
            logging.error(err)

    def run(self):
        loop = asyncio.get_event_loop()
        for feed in self.config['feeds']:
            forwarder = FeedForwarder(token=self.config['token'],
                                      url=feed['url'],
                                      userId=feed['id'])
            if 'delay' in feed:
                forwarder.delay = feed['delay']
            if 'format' in feed:
                forwarder.customFormat = feed['format'].replace('\\n', '\n')
            if 'preview' in feed:
                forwarder.telegramPreview = feed['preview']
            asyncio.ensure_future(forwarder.run())
        loop.run_forever()


class FeedForwarder(object):
    def __init__(self, token, url, userId,
                 delay=600,
                 customFormat='<b>$title$</b>\n$url$',
                 telegramPreview=True):
        self.bot = telepot.Bot(token)
        self.url = url
        self.userId = userId
        self.delay = delay
        self.customFormat = customFormat
        self.telegramPreview = telegramPreview
        self.feed = feedparser.parse(url)
        self.title = self.feed['feed']['title']

    # Загрузка нового RSS и сравнение с загруженной ранее
    # Возвращает массив новых записей newEntries
    def getUpdates(self):
        newEntries = []
        updatedFeed = feedparser.parse(self.url)
        if len(updatedFeed["entries"]) > 0:
            logging.debug('Get {} records from "{}", old feed contains {}'
                          .format(len(updatedFeed['entries']),
                                  self.url,
                                  len(self.feed['entries'])))
            for newEntry in updatedFeed['entries']:
                isNewEntry = True
                for oldEntry in self.feed['entries']:
                    if newEntry["id"] == oldEntry["id"]:
                        isNewEntry = False
                if isNewEntry is True:
                    newEntries.append(newEntry)
                # if entry not in self.feed['entries']:
                #     newEntries.append(entry)
            self.feed = updatedFeed
        else:
            logging.warning('Get empty feed from "{}"'.format(self.url))
        return newEntries

    async def run(self):
        logging.info('Start listening "{}" on "{}"'.format(self.title,
                                                           self.url))
        self.sendTelegram(self.userId,
                          self.prepareMessage(self.feed["entries"][0]))
        while True:
            await asyncio.sleep(self.delay)
            rssNewEntries = self.getUpdates()
            if len(rssNewEntries) > 0:
                logging.info('Get {} new entries from "{}"'.
                             format(len(rssNewEntries), self.url))
            for entry in rssNewEntries:
                    self.sendTelegram(self.userId,
                                      self.prepareMessage(entry))

    def prepareMessage(self, entry):
        text = self.customFormat
        logging.info("Prepare to sending entry {}".format(entry["id"]))
        text = text.replace('$url$', entry['id'])
        text = text.replace('$title$', html.escape(entry['title']))
        text = text.replace('$time$', entry["published"])
        text = text.replace('$description$', html.escape(entry['summary']))
        if 'author' in entry:
            text = text.replace('$author$', html.escape(entry['author']))
        if 'tags' in entry:
            tags = []
            for tag in entry['tags']:
                tags.append(tag['term'])
            text = text.replace('$tags$', html.escape(', '.join(tags)))
        return text

    def sendTelegram(self, id, text, textFormat='HTML'):
        logging.debug('Sending to {}: "{}"'.format(id, text))
        disablePagePreview = not self.telegramPreview
        try:
            self.bot.sendMessage(id,
                                 text,
                                 parse_mode=textFormat,
                                 disable_web_page_preview=disablePagePreview)
        except Exception as err:
            logging.warning(err)

@@ -34,16 +34,44 @@
  logging
+%0Afrom string import Template
 %0A%0Aimport
@@ -1477,31 +1477,25 @@
        self.
-customF
+f
 ormat = cust
@@ -1874,25 +1874,25 @@
 tedFeed%5B
-%22
+'
 entries
-%22
+'
 %5D) %3E 0:%0A
@@ -2715,16 +2715,1030 @@
 ntries%0A%0A
+    def sendEntry(self, id, entry):%0A        tags = %5B%5D%0A        if 'tags' in entry:%0A            for tag in entry%5B'tags'%5D:%0A                tags.append(tag%5B'term'%5D)%0A%0A        templateDict = dict(author=html.escape(entry%5B'author'%5D),%0A                            description=html.escape(entry%5B'summary'%5D),%0A                            tags=html.escape(', '.join(tags)),%0A                            time=entry%5B'published'%5D,%0A                            title=html.escape(entry%5B'title'%5D),%0A                            url=entry%5B'id'%5D)%0A%0A        outputText = Template(self.customFormat).safe_substitute(templateDict)%0A        logging.info('Send to %22%7B%7D%22: %22%7B%7D%22'.format(id, outputText))%0A        disablePagePreview = not self.telegramPreview%0A        try:%0A            self.bot.sendMessage(id,%0A                                 outputText,%0A                                 parse_mode='HTML',%0A                                 disable_web_page_preview=disablePagePreview)%0A        except Exception as err:%0A            logging.warning(err)%0A%0A
     asyn
@@ -3908,32 +3908,29 @@
    self.send
-Telegram
+Entry
 (self.userId
@@ -3934,55 +3934,9 @@
 rId,
-%0A                          self.prepareMessage(
+ 
 self
@@ -3955,17 +3955,16 @@
 es%22%5D%5B0%5D)
-)
 %0A       
@@ -4306,1275 +4306,30 @@
 send
-Telegram(self.userId,%0A                                      self.prepareMessage(entry))%0A%0A    def prepareMessage(self, entry):%0A        text = self.customFormat%0A        logging.info(%22Prepare to sending entry %7B%7D%22.format(entry%5B%22id%22%5D))%0A        text = text.replace('$url$', entry%5B'id'%5D)%0A        text = text.replace('$title$', html.escape(entry%5B'title'%5D))%0A        text = text.replace('$time$', entry%5B%22published%22%5D)%0A        text = text.replace('$description$', html.escape(entry%5B'summary'%5D))%0A        if 'author' in entry:%0A            text = text.replace('$author$', html.escape(entry%5B'author'%5D))%0A        if 'tags' in entry:%0A            tags = %5B%5D%0A            for tag in entry%5B'tags'%5D:%0A                tags.append(tag%5B'term'%5D)%0A            text = text.replace('$tags$', html.escape(', '.join(tags)))%0A        return text%0A%0A    def sendTelegram(self, id, text, textFormat='HTML'):%0A        logging.debug('Sending to %7B%7D: %22%7B%7D%22'.format(id, text))%0A        disablePagePreview = not self.telegramPreview%0A        try:%0A            self.bot.sendMessage(id,%0A                                 text,%0A                                 parse_mode=textFormat,%0A                                 disable_web_page_preview=disablePagePreview)%0A        except Exception as err:%0A            logging.warning(err
+Entry(self.userId, entry
 )%0A

remove prepareText and add string's Template parsing