Fix logging

- Following advice here: https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library
- Renamed the logger: client -> fbchat
- Remove logging_level init parameter from Client
- Use print instead of log.info in examples
This commit is contained in:
Mads Marquart
2019-08-28 22:27:29 +02:00
parent d84ad487ee
commit d3a0ffc478
10 changed files with 30 additions and 40 deletions

View File

@@ -1,4 +1,4 @@
from fbchat import log, Client from fbchat import Client
# Subclass fbchat.Client and override required methods # Subclass fbchat.Client and override required methods
class EchoBot(Client): class EchoBot(Client):
@@ -6,7 +6,7 @@ class EchoBot(Client):
self.markAsDelivered(thread_id, message_object.uid) self.markAsDelivered(thread_id, message_object.uid)
self.markAsRead(thread_id) self.markAsRead(thread_id)
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name)) print("{} from {} in {}".format(message_object, thread_id, thread_type.name))
# If you're not the author, echo # If you're not the author, echo
if author_id != self.uid: if author_id != self.uid:

View File

@@ -1,4 +1,4 @@
from fbchat import log, Client from fbchat import Client
from fbchat.models import * from fbchat.models import *
# Change this to your group id # Change this to your group id
@@ -19,21 +19,21 @@ old_nicknames = {
class KeepBot(Client): class KeepBot(Client):
def onColorChange(self, author_id, new_color, thread_id, thread_type, **kwargs): def onColorChange(self, author_id, new_color, thread_id, thread_type, **kwargs):
if old_thread_id == thread_id and old_color != new_color: if old_thread_id == thread_id and old_color != new_color:
log.info( print(
"{} changed the thread color. It will be changed back".format(author_id) "{} changed the thread color. It will be changed back".format(author_id)
) )
self.changeThreadColor(old_color, thread_id=thread_id) self.changeThreadColor(old_color, thread_id=thread_id)
def onEmojiChange(self, author_id, new_emoji, thread_id, thread_type, **kwargs): def onEmojiChange(self, author_id, new_emoji, thread_id, thread_type, **kwargs):
if old_thread_id == thread_id and new_emoji != old_emoji: if old_thread_id == thread_id and new_emoji != old_emoji:
log.info( print(
"{} changed the thread emoji. It will be changed back".format(author_id) "{} changed the thread emoji. It will be changed back".format(author_id)
) )
self.changeThreadEmoji(old_emoji, thread_id=thread_id) self.changeThreadEmoji(old_emoji, thread_id=thread_id)
def onPeopleAdded(self, added_ids, author_id, thread_id, **kwargs): def onPeopleAdded(self, added_ids, author_id, thread_id, **kwargs):
if old_thread_id == thread_id and author_id != self.uid: if old_thread_id == thread_id and author_id != self.uid:
log.info("{} got added. They will be removed".format(added_ids)) print("{} got added. They will be removed".format(added_ids))
for added_id in added_ids: for added_id in added_ids:
self.removeUserFromGroup(added_id, thread_id=thread_id) self.removeUserFromGroup(added_id, thread_id=thread_id)
@@ -44,12 +44,12 @@ class KeepBot(Client):
and removed_id != self.uid and removed_id != self.uid
and author_id != self.uid and author_id != self.uid
): ):
log.info("{} got removed. They will be re-added".format(removed_id)) print("{} got removed. They will be re-added".format(removed_id))
self.addUsersToGroup(removed_id, thread_id=thread_id) self.addUsersToGroup(removed_id, thread_id=thread_id)
def onTitleChange(self, author_id, new_title, thread_id, thread_type, **kwargs): def onTitleChange(self, author_id, new_title, thread_id, thread_type, **kwargs):
if old_thread_id == thread_id and old_title != new_title: if old_thread_id == thread_id and old_title != new_title:
log.info( print(
"{} changed the thread title. It will be changed back".format(author_id) "{} changed the thread title. It will be changed back".format(author_id)
) )
self.changeThreadTitle( self.changeThreadTitle(
@@ -64,7 +64,7 @@ class KeepBot(Client):
and changed_for in old_nicknames and changed_for in old_nicknames
and old_nicknames[changed_for] != new_nickname and old_nicknames[changed_for] != new_nickname
): ):
log.info( print(
"{} changed {}'s' nickname. It will be changed back".format( "{} changed {}'s' nickname. It will be changed back".format(
author_id, changed_for author_id, changed_for
) )

View File

@@ -1,4 +1,4 @@
from fbchat import log, Client from fbchat import Client
from fbchat.models import * from fbchat.models import *
@@ -6,7 +6,7 @@ class RemoveBot(Client):
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs): def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
# We can only kick people from group chats, so no need to try if it's a user chat # We can only kick people from group chats, so no need to try if it's a user chat
if message_object.text == "Remove me!" and thread_type == ThreadType.GROUP: if message_object.text == "Remove me!" and thread_type == ThreadType.GROUP:
log.info("{} will be removed from {}".format(author_id, thread_id)) print("{} will be removed from {}".format(author_id, thread_id))
self.removeUserFromGroup(author_id, thread_id=thread_id) self.removeUserFromGroup(author_id, thread_id=thread_id)
else: else:
# Sends the data to the inherited onMessage, so that we can still see when a message is recieved # Sends the data to the inherited onMessage, so that we can still see when a message is recieved

View File

@@ -3,6 +3,10 @@
:copyright: (c) 2015 - 2019 by Taehoon Kim :copyright: (c) 2015 - 2019 by Taehoon Kim
:license: BSD 3-Clause, see LICENSE for more details. :license: BSD 3-Clause, see LICENSE for more details.
""" """
import logging as _logging
# Set default logging handler to avoid "No handler found" warnings.
_logging.getLogger(__name__).addHandler(_logging.NullHandler())
# These imports are far too general, but they're needed for backwards compatbility. # These imports are far too general, but they're needed for backwards compatbility.
from .models import * from .models import *

View File

@@ -56,13 +56,7 @@ class Client:
return self._uid return self._uid
def __init__( def __init__(
self, self, email, password, user_agent=None, max_tries=5, session_cookies=None
email,
password,
user_agent=None,
max_tries=5,
session_cookies=None,
logging_level=logging.INFO,
): ):
"""Initialize and log in the client. """Initialize and log in the client.
@@ -72,7 +66,6 @@ class Client:
user_agent: Custom user agent to use when sending requests. If `None`, user agent will be chosen from a premade list user_agent: Custom user agent to use when sending requests. If `None`, user agent will be chosen from a premade list
max_tries (int): Maximum number of times to try logging in max_tries (int): Maximum number of times to try logging in
session_cookies (dict): Cookies from a previous session (Will default to login if these are invalid) session_cookies (dict): Cookies from a previous session (Will default to login if these are invalid)
logging_level (int): Configures the `logging level <https://docs.python.org/3/library/logging.html#logging-levels>`_. Defaults to ``logging.INFO``
Raises: Raises:
FBchatException: On failed login FBchatException: On failed login
@@ -85,8 +78,6 @@ class Client:
self._markAlive = True self._markAlive = True
self._buddylist = dict() self._buddylist = dict()
handler.setLevel(logging_level)
# If session cookies aren't set, not properly loaded or gives us an invalid session, then do the login # If session cookies aren't set, not properly loaded or gives us an invalid session, then do the login
if ( if (
not session_cookies not session_cookies

View File

@@ -1,7 +1,7 @@
import logging import logging
import aenum import aenum
log = logging.getLogger("client") log = logging.getLogger("fbchat")
class Enum(aenum.Enum): class Enum(aenum.Enum):

View File

@@ -1,5 +1,6 @@
import json import json
import re import re
from ._core import log
from . import _util from . import _util
from ._exception import FBchatException from ._exception import FBchatException
@@ -54,7 +55,7 @@ def response_to_json(content):
else: else:
rtn[int(key[1:])] = value["data"] rtn[int(key[1:])] = value["data"]
_util.log.debug(rtn) log.debug(rtn)
return rtn return rtn

View File

@@ -1,8 +1,8 @@
import attr import attr
import json import json
from string import Formatter from string import Formatter
from ._core import log, Enum
from . import _util, _attachment, _location, _file, _quick_reply, _sticker from . import _util, _attachment, _location, _file, _quick_reply, _sticker
from ._core import Enum
class EmojiSize(Enum): class EmojiSize(Enum):
@@ -324,7 +324,7 @@ class Message:
for mention in _util.parse_json(data["data"]["prng"]) for mention in _util.parse_json(data["data"]["prng"])
] ]
except Exception: except Exception:
_util.log.exception("An exception occured while reading attachments") log.exception("An exception occured while reading attachments")
if data.get("attachments"): if data.get("attachments"):
try: try:
@@ -361,7 +361,7 @@ class Message:
rtn.attachments.append(attachment) rtn.attachments.append(attachment)
except Exception: except Exception:
_util.log.exception( log.exception(
"An exception occured while reading attachments: {}".format( "An exception occured while reading attachments: {}".format(
data["attachments"] data["attachments"]
) )

View File

@@ -4,6 +4,7 @@ import re
import requests import requests
import random import random
from ._core import log
from . import _graphql, _util, _exception from . import _graphql, _util, _exception
FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"') FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"')
@@ -50,7 +51,7 @@ def _2fa_helper(session, code, r):
data["nh"] = soup.find("input", {"name": "nh"})["value"] data["nh"] = soup.find("input", {"name": "nh"})["value"]
data["submit[Submit Code]"] = "Submit Code" data["submit[Submit Code]"] = "Submit Code"
data["codes_submitted"] = 0 data["codes_submitted"] = 0
_util.log.info("Submitting 2FA code.") log.info("Submitting 2FA code.")
r = session.post(url, data=data) r = session.post(url, data=data)
@@ -63,7 +64,7 @@ def _2fa_helper(session, code, r):
data["name_action_selected"] = "save_device" data["name_action_selected"] = "save_device"
data["submit[Continue]"] = "Continue" data["submit[Continue]"] = "Continue"
_util.log.info("Saving browser.") log.info("Saving browser.")
# At this stage, we have dtsg, nh, name_action_selected, submit[Continue] # At this stage, we have dtsg, nh, name_action_selected, submit[Continue]
r = session.post(url, data=data) r = session.post(url, data=data)
@@ -71,7 +72,7 @@ def _2fa_helper(session, code, r):
return r return r
del data["name_action_selected"] del data["name_action_selected"]
_util.log.info("Starting Facebook checkup flow.") log.info("Starting Facebook checkup flow.")
# At this stage, we have dtsg, nh, submit[Continue] # At this stage, we have dtsg, nh, submit[Continue]
r = session.post(url, data=data) r = session.post(url, data=data)
@@ -80,7 +81,7 @@ def _2fa_helper(session, code, r):
del data["submit[Continue]"] del data["submit[Continue]"]
data["submit[This was me]"] = "This Was Me" data["submit[This was me]"] = "This Was Me"
_util.log.info("Verifying login attempt.") log.info("Verifying login attempt.")
# At this stage, we have dtsg, nh, submit[This was me] # At this stage, we have dtsg, nh, submit[This was me]
r = session.post(url, data=data) r = session.post(url, data=data)
@@ -90,7 +91,7 @@ def _2fa_helper(session, code, r):
del data["submit[This was me]"] del data["submit[This was me]"]
data["submit[Continue]"] = "Continue" data["submit[Continue]"] = "Continue"
data["name_action_selected"] = "save_device" data["name_action_selected"] = "save_device"
_util.log.info("Saving device again.") log.info("Saving device again.")
# At this stage, we have dtsg, nh, submit[Continue], name_action_selected # At this stage, we have dtsg, nh, submit[Continue], name_action_selected
r = session.post(url, data=data) r = session.post(url, data=data)
return r return r
@@ -207,7 +208,7 @@ class State:
def _do_refresh(self): def _do_refresh(self):
# TODO: Raise the error instead, and make the user do the refresh manually # TODO: Raise the error instead, and make the user do the refresh manually
# It may be a bad idea to do this in an exception handler, if you have a better method, please suggest it! # It may be a bad idea to do this in an exception handler, if you have a better method, please suggest it!
_util.log.warning("Refreshing state and resending request") log.warning("Refreshing state and resending request")
new = State.from_session(session=self._session) new = State.from_session(session=self._session)
self.user_id = new.user_id self.user_id = new.user_id
self._fb_dtsg = new._fb_dtsg self._fb_dtsg = new._fb_dtsg

View File

@@ -7,8 +7,8 @@ from mimetypes import guess_type
from os.path import basename from os.path import basename
from urllib.parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
import warnings import warnings
import logging
import requests import requests
from ._core import log
from ._exception import ( from ._exception import (
FBchatException, FBchatException,
FBchatFacebookError, FBchatFacebookError,
@@ -17,13 +17,6 @@ from ._exception import (
FBchatPleaseRefresh, FBchatPleaseRefresh,
) )
# Log settings
log = logging.getLogger("client")
log.setLevel(logging.DEBUG)
# Creates the console handler
handler = logging.StreamHandler()
log.addHandler(handler)
#: Default list of user agents #: Default list of user agents
USER_AGENTS = [ USER_AGENTS = [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",