示例#1
0
    def deleteEvent(self, event):
        logging.debug('Discourse')

        dateTimeFormat = '%Y %b %d - %I:%M %p'

        description = event.htmlSummary()

        logging.debug('Connecting to API')

        discourse_api = DiscourseClient(
            self.getSetting('Website'),
            api_username=self.getSetting('Username'),
            api_key=self.getSetting('API Key'))

        logging.debug('Deleting post')
        title = 'Event notice: ' + event.title + ' (' \
            + event.start_date.strftime(dateTimeFormat) + ')'

        post_id = event.getExternalEventByPlatformName(self.name).ext_event_id
        try:
            post = discourse_api.update_post(post_id=post_id,
                                             content=description,
                                             category_id=int(self.getSetting('Category ID')),
                                             topic_id=None, title=title)

        except DiscourseClientError as err:
            if err.__str__() == "The requested URL or resource could not be found.":
                # Looks like the post is already gone
                return
            else:
                raise

        topic_id = post['post']['topic_id']
        discourse_api.delete_topic(topic_id=topic_id)
示例#2
0
def create_post(user, post_details, category_id=None, topic_id=None):
    """Call discourse API posts.json to create a new Topic or Post within a topic
    """

    logger.info('+ discourse.create_post')
    if not user.is_authenticated:
        return True, 'Please logon to Post to Discourse', 0, ''

    # Create Discourse client for user
    client = DiscourseClient(
        settings.DISCOURSE_HOST,
        api_username=user.username,
        api_key=settings.DISCOURSE_API_KEY)

    # Check user is present in Discourse
    error, error_message, user_id = get_user(client, user.username)
    if user_id == 0:
        return error, error_message, 0, ''

    title = post_details['title']
    content = post_details['content']
    tags = post_details['tags']

    if tags is None:
        tags = []

    if len(content) < 20:
        return True, 'Content must be more than 20 characters long in Discourse', 0, ''

    post = client.create_post(content, category_id, topic_id, title, tags)
    # posts url = / t / {topic_id} / {post_number}
    post_url = os.path.join(settings.DISCOURSE_HOST, 't',  str(post['topic_id']),  str(post['post_number']))
    logger.info('- discourse.create_post')

    return error, error_message, post['topic_id'], post_url
示例#3
0
    def updateEvent(self, event):
        logging.debug('Discourse')

        dateTimeFormat = '%Y %b %d - %I:%M %p'

        description = event.htmlSummary()

        logging.debug('Connecting to API')

        discourse_api = DiscourseClient(
            self.getSetting('Website'),
            api_username=self.getSetting('Username'),
            api_key=self.getSetting('API Key'))

        logging.debug('Updating post')
        title = 'Event notice: ' + event.title + ' (' \
            + event.start_date.strftime(dateTimeFormat) + ')'

        post_id = next(item.ext_event_id for item in event.external_events
                       if item.platformName() == self.name)
        try:
            discourse_api.update_post(post_id=post_id,
                                      content=description,
                                      category_id=int(self.getSetting('Category ID')),
                                      topic_id=None, title=title)
        except DiscourseClientError as err:
            if err.__str__() == "The requested URL or resource could not be found.":
                return False
            else:
                raise

        return True
示例#4
0
文件: app.py 项目: flipdot/voucherbot
def main():
    logging.basicConfig(format="%(asctime)s - %(levelname)s: %(message)s",
                        level=logging.INFO)

    assert DISCOURSE_CREDENTIALS[
        "api_key"], "Environment variable DISCOURSE_API_KEY not set"

    parser = argparse.ArgumentParser(
        description=
        'Updates voucher post, sends out vouchers via PM, receives returned vouchers via PM'
    )
    parser.add_argument('--dry',
                        action='store_true',
                        help='do not execute POST or PUT requests')
    parser.add_argument('--broadcast',
                        type=str,
                        help='send a message to all voucher owners')

    args = parser.parse_args()

    client = DiscourseClient(**DISCOURSE_CREDENTIALS)
    if args.dry:
        disable_request(client, 'POST')
        disable_request(client, 'PUT')

    test_login(client)

    vouchers = read_voucher_config()

    for voucher in vouchers:
        if not voucher['owner']:
            continue
        if voucher.get('message_id'):
            new_voucher_code = check_for_returned_voucher(client, voucher)
            if new_voucher_code:
                logging.info(f'Voucher returned by {get_username(voucher)}')
                send_message_to_user(
                    client,
                    voucher,
                    message=f'Prima, vielen Dank für "{new_voucher_code}"!')
                voucher['voucher'] = new_voucher_code
                voucher['owner'] = None
                voucher['message_id'] = None
                voucher['persons'] = None
            if args.broadcast:
                send_message_to_user(client, voucher, message=args.broadcast)
        else:
            send_voucher_to_user(client, voucher)

    post_content = render('voucher_table.md', vouchers=vouchers)
    client.update_post(VOUCHER_TABLE_POST_ID, post_content)

    if args.dry:
        logging.info(
            f'Dry run: Config written to voucher_dryrun.yml instead of {VOUCHER_CONFIG_PATH}'
        )
        write_voucher_config(vouchers, 'voucher_dryrun.yml')
    else:
        write_voucher_config(vouchers)
示例#5
0
def send_message_to_user(client: DiscourseClient,
                         voucher: VoucherConfigElement, message: str) -> None:
    username = get_username(voucher)
    message_id = voucher.get('message_id')
    if not message_id:
        return
    logging.info(f'Sending message to {username} (Thread {message_id})')
    client.create_post(message, topic_id=message_id)
示例#6
0
def process_category (category_details):
    """Check category is present in Table - If not create it in Discourse and store the id returned..
    """

    # DISCOURSE_DEV_POST_SUFFIX is used to differentiate the same target name from different dev systems in Discourse
    # It is not intended to be used for production when there is a dedicated Discourse.
    category_name = category_details['category_name'] + settings.DISCOURSE_DEV_POST_SUFFIX

    # Create Discourse client for fragalysis user
    client = DiscourseClient(
        settings.DISCOURSE_HOST,
        api_username=settings.DISCOURSE_USER,
        api_key=settings.DISCOURSE_API_KEY)

    try:
        category = DiscourseCategory.objects.get(category_name=category_name)
        category_id = category.discourse_category_id
        post_url = os.path.join(settings.DISCOURSE_HOST, 'c', str(category_id))
    except DiscourseCategory.DoesNotExist:
        category_id, post_url = create_category(client, category_name,
                                                category_details['parent_name'],
                                                category_details['category_colour'],
                                                category_details['category_text_colour'])
        DiscourseCategory.objects.create(category_name=category_name,
                                         discourse_category_id=category_id)
    return category_id, post_url
示例#7
0
def list_discourse_posts_for_topic(topic_title):
    """Call discourse APIs to retreive posts for the given topic

    Makes the translation from Fragalysis topic_name to discourse id.

    :param topic_title
    :return: error or json of posts.
    """
    print('+ discourse.get_discourse_posts_for_topic')
    posts = ''
    error = False

    # DISCOURSE_DEV_POST_SUFFIX is used to differentiate the same target name from different dev systems in Discourse
    # It is not intended to be used for production when there is a dedicated Discourse.
    if topic_title:
        topic_title = topic_title + settings.DISCOURSE_DEV_POST_SUFFIX

    # Get topic_id for title
    try:
        topic = DiscourseTopic.objects.get(topic_title=topic_title)
    except DiscourseTopic.DoesNotExist:
        topic = None

    if topic:
        # Create Discourse client
        client = DiscourseClient(
            settings.DISCOURSE_HOST,
            api_username=settings.DISCOURSE_USER,
            api_key=settings.DISCOURSE_API_KEY)
        posts = topic_posts(client, topic.discourse_topic_id)
    else:
        error = True

    print('- discourse.get_discourse_posts_for_topic')
    return error, posts
def list_discourse_posts_for_topic(topic_title):
    """Call discourse APIs to retreive posts for the given topic

    Makes the translation from Fragalysis topic_name to discourse id.

    :param topic_title
    :return: error or json of posts.
    """
    print('+ discourse.get_discourse_posts_for_topic')
    posts = ''
    error = False

    # Get topic_id for title
    try:
        topic = DiscourseTopic.objects.get(topic_title=topic_title)
    except DiscourseTopic.DoesNotExist:
        topic = None

    if topic:
        # Create Discourse client
        client = DiscourseClient(settings.DISCOURSE_HOST,
                                 api_username=settings.DISCOURSE_USER,
                                 api_key=settings.DISCOURSE_API_KEY)
        posts = topic_posts(client, topic.discourse_topic_id)
    else:
        error = True

    print('- discourse.get_discourse_posts_for_topic')
    return error, posts
示例#9
0
    def _auth_discourse_server(self):
        """Authenticate to Discourse

        This uses the API_SITE, API_USER, and API_KEY env vars.
        """
        # Load the config, so we can store secrets outside of env vars
        config = load_config()
        in_conf = "discourse" in config

        # Load the needed secrets either from the config file if it exists
        # or the env var if it's defined (which takes precedence)
        site = getenv("DISCOURSE_API_SITE") or (in_conf and
                                                config["discourse"]["site"])
        user = getenv("DISCOURSE_API_USER") or (in_conf and
                                                config["discourse"]["user"])
        key = getenv("DISCOURSE_API_KEY") or (in_conf
                                              and config["discourse"]["key"])
        for envvar in [site, user, key]:
            if not envvar:
                raise ValueError("DISCOURSE_API_SITE, DISCOURSE_API_USER, and",
                                 "DISCOURSE_API_KEY must be defined")
        # Authenticate to the server
        server = DiscourseClient(site, api_username=user, api_key=key)

        return server
示例#10
0
    def Setup(self):
        self.WA_API = WaApiClient()
        while (not self.WA_API.ConnectAPI(self.config.get('api', 'key'))):
            time.sleep(5)
        self.processed_filename = "followup_processed.txt"
        self.discourse_api = DiscourseClient(
            self.config.get('discourse_api', 'site'),
            api_username=self.config.get('discourse_api', 'username'),
            api_key=self.config.get('discourse_api', 'key'))

        self.member_levels = [
            'Monthly', '6 months', '12 months', "Scholarship (monthly)",
            "Scholarship (6 months)", "Scholarship (12 months)"
        ]
        self.group_name = 'MakeICT_Members'
        self.member_group_id = \
            self.discourse_api._get("/groups/{0}.json".format(self.group_name))['group']['id']
示例#11
0
    def __init__(self, feature, metrics):
        self.feature = feature
        self.metrics = metrics

        client = DiscourseClient(
                host="https://{}".format(os.environ.get("DISCOURSE_DOMAIN_NAME")),
                api_username=os.environ.get("DISCOURSE_CLIENT_API_USERNAME"),
                api_key=os.environ.get("DISCOURSE_CLIENT_API_TOKEN"))
        self.client = client
示例#12
0
文件: app.py 项目: flipdot/voucherbot
def send_voucher_to_user(client: DiscourseClient,
                         voucher: VoucherConfigElement):
    username = get_username(voucher)
    message_content = render('voucher_message.md', voucher=voucher)
    logging.info(f'Sending voucher to {username}')
    res = client.create_post(message_content,
                             title='Dein 36C3 Voucher',
                             archetype='private_message',
                             target_usernames=username)
    message_id = res.get('topic_id')
    logging.info(f'Sent, message_id is {message_id}')
    voucher['message_id'] = message_id
示例#13
0
def check_for_returned_voucher(client: DiscourseClient,
                               voucher: VoucherConfigElement) -> Optional[str]:
    message_id = voucher['message_id']
    posts = client.posts(message_id)
    user_posts = [
        post for post in posts['post_stream']['posts']
        if post['name'] != 'flipbot'
    ]
    user_posts_content = ' '.join([p['cooked'] for p in user_posts])
    new_voucher = re.search(r'CHAOS[a-zA-Z0-9]+', user_posts_content)
    if new_voucher:
        return new_voucher[0]
示例#14
0
文件: app.py 项目: flipdot/voucherbot
def disable_request(client: DiscourseClient,
                    disable_verb: Optional[str] = None,
                    disable_path: Optional[str] = None):
    original_request = client._request

    def new_request_fn(verb, path, *args, **kwargs):
        if disable_verb and verb == disable_verb or disable_path and path == disable_path:
            logging.info(
                f'Dry run. {verb} request to {path} was not made. Data:')
            logging.info(kwargs.get('data'))
            return {}
        return original_request(verb, path, *args, **kwargs)

    client._request = new_request_fn
示例#15
0
    def createEvent(self, event):
        logging.debug('Discourse')

        dateTimeFormat = '%Y %b %d - %I:%M %p'

        description = event.htmlSummary()

        logging.debug('Connecting to API')

        discourse_api = DiscourseClient(
            self.getSetting('Website'),
            api_username=self.getSetting('Username'),
            api_key=self.getSetting('API Key'))

        logging.debug('Creating post')
        title = 'Event notice: ' + event.title + ' (' \
            + event.start_date.strftime(dateTimeFormat) + ')'
        post = discourse_api.create_post(content=description,
                                         category_id=int(self.getSetting('Category ID')),
                                         topic_id=None, title=title)

        post_url = f"https://talk.makeict.org/t/{post['id']}"

        return (post['id'], post_url)
示例#16
0
def check_discourse_user(user):
    """Call discourse API to check discourse user exists
    """

    # Create Discourse client for user
    client = DiscourseClient(
        settings.DISCOURSE_HOST,
        api_username=user.username,
        api_key=settings.DISCOURSE_API_KEY)

    # Check user is present in Discourse
    error, error_message, user_id = get_user(client, user.username)
    if user_id == 0:
        return error, error_message, 0

    return error, error_message, user_id
def create_discourse_post(user, category_details=None, post_details=None):
    """Call discourse APIs to create the category, topic or post details as requested

    Makes the translation from Fragalysis topic_name to discourse id.
    :param user
    :param category_details (optional) (name=<target name required>, color=<hex> (optional defaults),
                                 text_color=<hex> (optional defaults), parent_category_name=<parent category>
                                 (initially can default to “Fragalysis targets” (this is a setting)
    :param post_details (optional) {title=<e.g session-project.name required>, content=<e.g session-project.description,
                                  created_date=<date>, tags[list]}
    :return: error or url of post.
    """

    logger.info('+ discourse.create_discourse_post')
    error = False
    post_url = ''
    if category_details is None and post_details is None:
        # Nothing to post
        return True

    if user is None:
        # User is not logger on
        return True

    category_id = 0

    # If category details exist then create/return the category using the fragalysis user
    if category_details:
        category_id, post_url = process_category(category_details)

    # If post details exist then create the post
    if post_details:
        # Create Discourse client for user
        client = DiscourseClient(settings.DISCOURSE_HOST,
                                 api_username=user.username,
                                 api_key=settings.DISCOURSE_API_KEY)

        # Check user is present in Discourse
        user_id = get_user(client, user.username)
        if user_id == 0:
            return True
        topic_id, post_url = process_post(client, category_id, post_details,
                                          user)

    logger.info('- discourse.create_discourse_post')
    return error, post_url
示例#18
0
    def run(self):
        try:
            from pydiscourse import DiscourseClient
        except ImportError as ie:
            print "--> pip install pydiscourse <--"
            raise ie
        client = DiscourseClient('https://discourse.corda.net',
                                 api_username='******',
                                 api_key=secrets.DISCOURSE_API_KEY)

        def old_way():
            usernames = set()
            more = "/directory_items?period=all"
            while (more):
                stuff = client._get(more)

                for di in stuff["directory_items"]:
                    usernames.add(di["user"]["username"])
                if len(stuff["directory_items"]
                       ) and "load_more_directory_items" in stuff:
                    more = stuff["load_more_directory_items"]
                else:
                    more = None

        def get_number_of_posts(client):
            categories = {
                x['id']: x['post_count']
                for x in client._get("/categories")["category_list"]
                ["categories"]
            }
            return sum(categories.values())

        def get_number_of_users(client):
            stuff = client._get("/directory_items?period=all")
            return stuff["total_rows_directory_items"]

        return {
            "discourse_user_count": get_number_of_users(client),
            "discourse_number_of_posts": get_number_of_posts(client)
        }
def process_category(category_details):
    """Check category is present in Table - If not create it in Discourse and store the id returned..
    """
    post_url = ''

    # Create Discourse client for fragalysis user
    client = DiscourseClient(settings.DISCOURSE_HOST,
                             api_username=settings.DISCOURSE_USER,
                             api_key=settings.DISCOURSE_API_KEY)

    try:
        category = DiscourseCategory.objects.get(
            category_name=category_details['category_name'])
        category_id = category.discourse_category_id
    except DiscourseCategory.DoesNotExist:
        category_id, post_url = create_category(
            client, category_details['category_name'],
            category_details['parent_name'],
            category_details['category_colour'],
            category_details['category_text_colour'])
        DiscourseCategory.objects.create(
            category_name=category_details['category_name'],
            discourse_category_id=category_id)
    return category_id, post_url
示例#20
0
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(console_handler)

logger.info('\nMigrate UseResponse to Discourse.')
logger.info('CHANGE OWNER.\n')

# ===================================================================
# connect to Discourse
# ===================================================================

logger.info('Connecting to Discourse...')
discourse = DiscourseClient(config.DISCOURSE_BASE_URL + '/' +
                            config.DISCOURSE_FOLDER,
                            api_username=(config.DISCOURSE_LOGIN),
                            api_key=(config.DISCOURSE_API_KEY))

# ===================================================================
# connect to mysql
# ===================================================================

logger.info('Connecting to UseResponse (mysql)...')
try:
    useresponse_db = MySQLdb.connect(
        use_unicode=True,
        charset='utf8',
        host=(config.USERESPONSE_DATABASE_HOST),
        port=(config.USERESPONSE_DATABASE_PORT),
        user=(config.USERESPONSE_DATABASE_LOGIN),
        passwd=(config.USERESPONSE_DATABASE_PASSWORD),
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(console_handler)

logger.info('\nMigrate UseResponse to Discourse.')
logger.info('Migrate TOPICS.\n')

# ===================================================================
# connect to Discourse
# ===================================================================

logger.info('Connecting to Discourse...')
discourse = DiscourseClient(config.DISCOURSE_BASE_URL + '/' +
                            config.DISCOURSE_FOLDER,
                            api_username=(config.DISCOURSE_LOGIN),
                            api_key=(config.DISCOURSE_API_KEY))

# ===================================================================
# connect to mysql
# ===================================================================

logger.info('Connecting to UseResponse (mysql)...')
try:
    useresponse_db = MySQLdb.connect(
        use_unicode=True,
        charset='utf8',
        host=(config.USERESPONSE_DATABASE_HOST),
        port=(config.USERESPONSE_DATABASE_PORT),
        user=(config.USERESPONSE_DATABASE_LOGIN),
        passwd=(config.USERESPONSE_DATABASE_PASSWORD),
#!/usr/bin/env python

from pydiscourse import DiscourseClient

client = DiscourseClient(
    "http://localhost:9292",
    api_key="8302ca56136b04e4b2b82bc03ca4d4346cb5dc3dad6e3881138b9c232d7d4b94",
    api_username="******",
)

res = client.upload_image("/home/sidd/Downloads/profile.png",
                          "avatar",
                          True,
                          userid=1)
示例#23
0
#!/usr/bin/env python3
# *-* coding: utf-8 *-*
from pydiscourse import DiscourseClient
from pydiscourse.exceptions import DiscourseClientError
from extract_Xnet_data import extract_all_groups, extract_groups_from_hruid
import yaml
import time

with open("config.yml") as conf_f:
    conf = yaml.load(conf_f)
    URL = conf['Discourse_API_URL']
    USERNAME = conf['Discourse_API_username']
    API_KEY = conf['Discourse_API_key']

client = DiscourseClient(URL, USERNAME, API_KEY)


def discourseName(netName):
    dName = netName
    if len(dName) < 3:
        #this name is too short for discourse, let's prepend _ to it
        dName = '_' * (3 - len(dName)) + dName
    elif len(dName) > 20:
        #this name is too long for discourse, let's cut it
        dName = dName[:20]
    return dName


def getAllDiscourseMembers():
    all_discourse_members = {}
    for member in client.users():
示例#24
0
    print("Error: No discourse username provided")
    sys.exit(1)

if discourse_api_key is None:
    print("Error: No discourse api_key provided")
    sys.exit(1)

bot = discord.Client()
discord_token = discord_config.get("token", None)

if discord_config is None:
    print("Error: No discord token provided")
    sys.exit(1)

discourse_client = DiscourseClient(discourse_site,
                                   api_username=discourse_username,
                                   api_key=discourse_api_key)


def get_news(bot, client):
    watch = ["yong", "hal"]
    latest = "last_posted_at"
    created = "created_at"
    # Adjust this according to where your server is located
    adjust_timezone = 5 * 60 * 60
    now = datetime.now().timestamp()
    update_id, update_slug = 257, "gameshell-updates"
    date_format = lambda _: datetime.strptime(_, "%Y-%m-%dT%H:%M:%S.%fZ")
    get_timestamp = lambda _: date_format(_).timestamp()

    topics = client.latest_topics()["topic_list"]["topics"]
示例#25
0
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(console_handler)

logger.info('\nMigrate UseResponse to Discourse.')
logger.info('Migrate USERS.\n')

# ===================================================================
# connect to Discourse
# ===================================================================

logger.info('Connecting to Discourse...')
discourse = DiscourseClient(config.DISCOURSE_BASE_URL + '/' +
                            config.DISCOURSE_FOLDER,
                            api_username=(config.DISCOURSE_LOGIN),
                            api_key=(config.DISCOURSE_API_KEY))

# ===================================================================
# connect to services
# ===================================================================

# connect to useresponse database
logger.info('Connecting to UseResponse (mysql) %s:%s...' %
            (config.DRUPAL_DATABASE_HOST, config.DRUPAL_DATABASE_PORT))
try:
    useresponse_db = MySQLdb.connect(
        use_unicode=True,
        charset='utf8',
        host=(config.USERESPONSE_DATABASE_HOST),
        port=(config.USERESPONSE_DATABASE_PORT),
示例#26
0
文件: app.py 项目: flipdot/voucherbot
def test_login(client: DiscourseClient) -> None:
    try:
        client.latest_topics()
    except DiscourseClientError as e:
        logging.error(f"Could not perform login: {e}")
        sys.exit(-1)
示例#27
0
class ChildScript(Script):
    def Setup(self):
        self.WA_API = WaApiClient()
        while (not self.WA_API.ConnectAPI(self.config.get('api', 'key'))):
            time.sleep(5)
        self.processed_filename = "followup_processed.txt"
        self.discourse_api = DiscourseClient(
            self.config.get('discourse_api', 'site'),
            api_username=self.config.get('discourse_api', 'username'),
            api_key=self.config.get('discourse_api', 'key'))

        self.member_levels = [
            'Monthly', '6 months', '12 months', "Scholarship (monthly)",
            "Scholarship (6 months)", "Scholarship (12 months)"
        ]
        self.group_name = 'MakeICT_Members'
        self.member_group_id = \
            self.discourse_api._get("/groups/{0}.json".format(self.group_name))['group']['id']

    def SyncUser(self, d_user, wa_contacts):
        # print(self.discourse_api.user_emails(d_user['user']['username']))
        print(d_user['username'], ':', d_user['emails'], ':',
              [c['Email'] for c in wa_contacts])
        is_member = False
        is_active = False

        # assert wa_contacts['Email'] in d_user['user']['emails']
        for contact in wa_contacts:
            try:
                is_member = contact['MembershipLevel'][
                    'Name'] in self.member_levels
            except KeyError:
                print("No WA membership level found")

            try:
                is_active = contact['Status'] == 'Active' and contact[
                    'MembershipEnabled']
            except KeyError:
                print("WA contact is not active")

            # If an active WildApricot account is found, stop looking and sync
            if is_member and is_active:
                break

        if is_member and is_active:
            print("User is an active member, adding user to group")

            try:
                if d_user['primary_group_id'] == self.member_group_id:
                    print("User is already in group")
                    return
                else:
                    print("User is not in group")
            except KeyError:
                print("User has no primary group")

            try:
                self.discourse_api.add_group_member(self.member_group_id,
                                                    d_user['username'])
            except DiscourseClientError:
                print("Failed to add user to group")

        else:
            print("user is not an active member")
            if (self.member_group_id == d_user['primary_group_id']):
                print("removing user from group")
                self.discourse_api.delete_group_member(self.member_group_id,
                                                       d_user['id'])
            else:
                print("user is not in group")

    def SyncUsers(self, disc_users, wa_users):
        for u in disc_users:
            # if u['user']['username'] != '':
            #     continue
            u = self.discourse_api.user_all(u['user']['id'])
            emails = self.discourse_api.user_emails(u['username'])
            email_list = [emails['email']]
            email_list += emails['secondary_emails']
            u['emails'] = email_list

            found_contacts = []
            for contact in wa_users:
                if contact['Email'] in u['emails']:
                    print("Found WA user for %s" % contact['Email'])
                    found_contacts.append(contact)

            self.SyncUser(u, found_contacts)

            time.sleep(2)

    def SyncAllUsers(self):
        response = self.discourse_api._get(
            '/directory_items.json?period=all&order=post_count')
        discourse_users = response['directory_items']
        while response['meta']['total_rows_directory_items'] > len(
                discourse_users):
            response = self.discourse_api._get(
                response['meta']['load_more_directory_items'])
            discourse_users += response['directory_items']
            print(response['meta']['total_rows_directory_items'])
            print(len(discourse_users))

        wa_contacts = self.WA_API.GetAllContacts()

        self.SyncUsers(discourse_users, wa_contacts)

    def SyncNewUsers(self):
        discourse_users = self.discourse_api.list_users("new")
        wa_contacts = self.WA_API.GetAllContacts()

        self.SyncUsers(discourse_users, wa_contacts)

    def Run(self):
        self.SyncAllUsers()
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(console_handler)

logger.info('\nMigrate UseResponse to Discourse.')
logger.info('Migrate COMMENTS.\n')

# ===================================================================
# connect to Discourse
# ===================================================================

logger.info('Connecting to Discourse...')
discourse = DiscourseClient(config.DISCOURSE_BASE_URL + '/' +
                            config.DISCOURSE_FOLDER,
                            api_username=(config.DISCOURSE_LOGIN),
                            api_key=(config.DISCOURSE_API_KEY))

# ===================================================================
# connect to mysql
# ===================================================================

logger.info('Connecting to UseResponse (mysql)...')
try:
    useresponse_db = MySQLdb.connect(
        use_unicode=True,
        charset='utf8',
        host=(config.USERESPONSE_DATABASE_HOST),
        port=(config.USERESPONSE_DATABASE_PORT),
        user=(config.USERESPONSE_DATABASE_LOGIN),
        passwd=(config.USERESPONSE_DATABASE_PASSWORD),
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(console_handler)

logger.info('\nMigrate UseResponse to Discourse.')
logger.info('Migrate ATTACHMENTS.\n')

# ===================================================================
# connect to Discourse
# ===================================================================

logger.info('Connecting to Discourse...')
discourse = DiscourseClient(
    config.DISCOURSE_BASE_URL + '/' + config.DISCOURSE_FOLDER + '/' + config.DISCOURSE_FOLDER,
    api_username=(config.DISCOURSE_LOGIN),
    api_key=(config.DISCOURSE_API_KEY)
)

# ===================================================================
# connect to mysql
# ===================================================================

logger.info('Connecting to UseResponse (mysql)...')
try:
    useresponse_db = MySQLdb.connect(use_unicode=True, charset='utf8',
                                     host=(config.USERESPONSE_DATABASE_HOST),
                                     port=(config.USERESPONSE_DATABASE_PORT),
                                     user=(config.USERESPONSE_DATABASE_LOGIN),
                                     passwd=(config.USERESPONSE_DATABASE_PASSWORD),
                                     db=(config.USERESPONSE_DATABASE_NAME),