<commit_before>"""
Create backup for certain date for specified channel in slack
"""
from datetime import datetime
import getpass
import logging
import os

import slackclient

from slack_backup import db
from slack_backup import objects as o
from slack_backup import download
from slack_backup import reporters


class Client(object):
    """
    This class is intended to provide an interface for getting, storing and
    querying data fetched out using Slack API.
    """
    def __init__(self, args):
        if 'token' in args:
            self.slack = slackclient.SlackClient(args.token)
            self.user = args.user
            self.password = args.password
            if not self.user and not self.password:
                logging.warning('No media will be downloaded, due to not '
                                'providing credentials for a slack account')
            elif not self.user and self.password:
                logging.warning('No media will be downloaded, due to not '
                                'providing username for a slack account')
            elif self.user and not self.password:
                self.password = <PASSWORD>pass(prompt='Provide password for '
                                                'your slack account: ')
            dbpath = self._get_asset_dir(args.database)
            self.downloader = download.Download(args, dbpath)
        self.engine = db.connect(args.database)
        self.session = db.Session()
        self.selected_channels = args.channels
        self.q = self.session.query

        if 'format' in args:
            self.reporter = reporters.get_reporter(args, self.q)

    def update(self):
        """
        Perform an update, store data to db
        """
        self.downloader.authorize()
        self.update_users()
        self.update_channels()
        self.update_history()

    def update_channels(self):
        """Fetch and update channel list with current state in db"""
        logging.info("Fetching and update channels information in DB")
        result = self._channels_list()

        if not result:
            return

        for data in result:
            channel = self.q(o.Channel).\
                filter(o.Channel.slackid == data['id']).one_or_none()

            if not channel:
                channel = o.Channel()
                self.session.add(channel)

            self._update_channel(channel, data)

        self.session.commit()

    def update_users(self):
        """Fetch and update user list with current state in db"""
        logging.info("Fetching and updating user information in DB")
        result = self.slack.api_call("users.list", presence=0)

        if not result.get("ok"):
            logging.error(result['error'])
            return

        for user_data in result['members']:
            user = self.q(o.User).\
                filter(o.User.slackid == user_data['id']).one_or_none()

            if user:
                user.update(user_data)
            else:
                user = o.User(user_data)
                self.session.add(user)
                self.session.flush()

            if user.profile.image_original:
                user.profile.image_path = self.downloader.\
                    download(user.profile.image_original, 'avatar')

        self.session.commit()

    def update_history(self):
        """
        Get the latest or all messages out of optionally selected channels
        """
        logging.info("Fetching and storing messages in DB")

        all_channels = self.q(o.Channel).all()
        if self.selected_channels:
            channels = [c for c in all_channels
                        if c.name in self.selected_channels]
        else:
            channels = all_channels

        for channel in channels:
            latest = self.q(o.Message).\
                filter(o.Message.channel == channel).\
                order_by(o.Message.ts.desc()).first()
            # NOTE(gryf): Trick out the API, which by default (latest and
            # oldest parameters set to 0) return certain amount of latest
            # messages, while we'd like to have it from the beginning of the
            # available history, if there is no database records available. In
            # that case value of 1 here will force the API to get messages
            # starting from first January 1970.
            latest = latest and latest.ts or 1

            while True:
                logging.debug("Fetching another portion of messages")
                messages, latest = self._channels_history(channel, latest)

                for msg in messages:
                    self._create_message(msg, channel)

                if latest is None:
                    break
<commit_msg>Added log for updating specific channel messages<commit_after>"""
Create backup for certain date for specified channel in slack
"""
from datetime import datetime
import getpass
import logging
import os

import slackclient

from slack_backup import db
from slack_backup import objects as o
from slack_backup import download
from slack_backup import reporters


class Client(object):
    """
    This class is intended to provide an interface for getting, storing and
    querying data fetched out using Slack API.
    """
    def __init__(self, args):
        if 'token' in args:
            self.slack = slackclient.SlackClient(args.token)
            self.user = args.user
            self.password = args.password
            if not self.user and not self.password:
                logging.warning('No media will be downloaded, due to not '
                                'providing credentials for a slack account')
            elif not self.user and self.password:
                logging.warning('No media will be downloaded, due to not '
                                'providing username for a slack account')
            elif self.user and not self.password:
                self.password = getpass.getpass(prompt='Provide password for '
                                                'your slack account: ')
            dbpath = self._get_asset_dir(args.database)
            self.downloader = download.Download(args, dbpath)
        self.engine = db.connect(args.database)
        self.session = db.Session()
        self.selected_channels = args.channels
        self.q = self.session.query

        if 'format' in args:
            self.reporter = reporters.get_reporter(args, self.q)

    def update(self):
        """
        Perform an update, store data to db
        """
        self.downloader.authorize()
        self.update_users()
        self.update_channels()
        self.update_history()

    def update_channels(self):
        """Fetch and update channel list with current state in db"""
        logging.info("Fetching and update channels information in DB")
        result = self._channels_list()

        if not result:
            return

        for data in result:
            channel = self.q(o.Channel).\
                filter(o.Channel.slackid == data['id']).one_or_none()

            if not channel:
                channel = o.Channel()
                self.session.add(channel)

            self._update_channel(channel, data)

        self.session.commit()

    def update_users(self):
        """Fetch and update user list with current state in db"""
        logging.info("Fetching and updating user information in DB")
        result = self.slack.api_call("users.list", presence=0)

        if not result.get("ok"):
            logging.error(result['error'])
            return

        for user_data in result['members']:
            user = self.q(o.User).\
                filter(o.User.slackid == user_data['id']).one_or_none()

            if user:
                user.update(user_data)
            else:
                user = o.User(user_data)
                self.session.add(user)
                self.session.flush()

            if user.profile.image_original:
                user.profile.image_path = self.downloader.\
                    download(user.profile.image_original, 'avatar')

        self.session.commit()

    def update_history(self):
        """
        Get the latest or all messages out of optionally selected channels
        """
        logging.info("Fetching and storing messages in DB")

        all_channels = self.q(o.Channel).all()
        if self.selected_channels:
            channels = [c for c in all_channels
                        if c.name in self.selected_channels]
        else:
            channels = all_channels

        for channel in channels:
            logging.info("Getting messages for channel `%s'", channel.name)
            latest = self.q(o.Message).\
                filter(o.Message.channel == channel).\
                order_by(o.Message.ts.desc()).first()
            # NOTE(gryf): Trick out the API, which by default (latest and
            # oldest parameters set to 0) return certain amount of latest
            # messages, while we'd like to have it from the beginning of the
            # available history, if there is no database records available. In
            # that case value of 1 here will force the API to get messages
            # starting from first January 1970.
            latest = latest and latest.ts or 1

            while True:
                logging.debug("Fetching another portion of messages")
                messages, latest = self._channels_history(channel, latest)

                for msg in messages:
                    self._create_message(msg, channel)

                if latest is None:
                    break

{'fraction_non_alphanumeric': 0.0815838702972355, 'fraction_numerical': 0.0016628559551028891, 'mean_word_length': 1.7990110529377545, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1643539', 'n_tokens_mistral': 2460, 'n_tokens_neox': 2323, 'n_words': 780}