From 1666a0c6c9815d1529e52e83c2cc5444f3ccd9af Mon Sep 17 00:00:00 2001 From: Praveen N Patil Date: Wed, 12 Mar 2025 22:47:34 +0530 Subject: [PATCH 1/2] Replace oauth2client with google-auth and google-auth-oauthlib in google-calendar integration --- zulip/integrations/google/google-calendar | 25 +++++++++++++------ zulip/integrations/google/requirements.txt | 4 ++- .../bots/google_search/google_search.py | 2 +- .../zulip_bots/bots/twitpost/twitpost.py | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/zulip/integrations/google/google-calendar b/zulip/integrations/google/google-calendar index 85906bd46..ecec9c435 100755 --- a/zulip/integrations/google/google-calendar +++ b/zulip/integrations/google/google-calendar @@ -14,8 +14,8 @@ from typing import List, Optional, Set, Tuple import dateutil.parser import httplib2 import pytz -from oauth2client import client -from oauth2client.file import Storage +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow try: from googleapiclient import discovery @@ -88,7 +88,7 @@ if not options.zulip_email: zulip_client = zulip.init_from_options(options) -def get_credentials() -> client.Credentials: +def get_credentials() -> Credentials: """Gets valid user credentials from storage. If nothing has been stored, or if the stored credentials are invalid, @@ -101,9 +101,19 @@ def get_credentials() -> client.Credentials: try: credential_path = os.path.join(HOME_DIR, "google-credentials.json") - store = Storage(credential_path) - return store.get() - except client.Error: + if os.path.exists(credential_path): + # Load credentials from the file + credentials = Credentials.from_authorized_user_file(credential_path, SCOPES) + else: + # Run the OAuth flow to get new credentials + flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES) + credentials = flow.run_local_server(port=0) + # Save the credentials for the next run + with open(credential_path, "w") as token: + token.write(credentials.to_json()) + + return credentials + except FileNotFoundError: logging.exception("Error while trying to open the `google-credentials.json` file.") sys.exit(1) except OSError: @@ -113,8 +123,7 @@ def get_credentials() -> client.Credentials: def populate_events() -> Optional[None]: credentials = get_credentials() - creds = credentials.authorize(httplib2.Http()) - service = discovery.build("calendar", "v3", http=creds) + service = discovery.build("calendar", "v3", credentials=credentials) now = datetime.datetime.now(pytz.utc).isoformat() feed = ( diff --git a/zulip/integrations/google/requirements.txt b/zulip/integrations/google/requirements.txt index 139c0705b..58d23c07e 100644 --- a/zulip/integrations/google/requirements.txt +++ b/zulip/integrations/google/requirements.txt @@ -1,2 +1,4 @@ httplib2>=0.22.0 -oauth2client>=4.1.3 +google-auth>=2.0.0 +google-auth-oauthlib>=0.4.6 +google-api-python-client>=2.0.0 diff --git a/zulip_bots/zulip_bots/bots/google_search/google_search.py b/zulip_bots/zulip_bots/bots/google_search/google_search.py index e1fb5083a..4b45a8946 100644 --- a/zulip_bots/zulip_bots/bots/google_search/google_search.py +++ b/zulip_bots/zulip_bots/bots/google_search/google_search.py @@ -18,7 +18,7 @@ def google_search(keywords: str) -> List[Dict[str, str]]: # Gets all search URLs search = soup.find(id="search") assert isinstance(search, Tag) - anchors = search.findAll("a") + anchors = search.find_all("a") results = [] for a in anchors: diff --git a/zulip_bots/zulip_bots/bots/twitpost/twitpost.py b/zulip_bots/zulip_bots/bots/twitpost/twitpost.py index 2a77241b3..c74077de3 100644 --- a/zulip_bots/zulip_bots/bots/twitpost/twitpost.py +++ b/zulip_bots/zulip_bots/bots/twitpost/twitpost.py @@ -23,7 +23,7 @@ def usage(self) -> str: def initialize(self, bot_handler: AbstractBotHandler) -> None: self.config_info = bot_handler.get_config_info("twitter") - auth = tweepy.OAuthHandler( + auth = tweepy.OAuth1UserHandler( self.config_info["consumer_key"], self.config_info["consumer_secret"] ) auth.set_access_token( From b456bb87ad1b2d83dcfb48fb93e9d1bf64ebfe9d Mon Sep 17 00:00:00 2001 From: Praveen N Patil Date: Mon, 17 Mar 2025 16:55:52 +0530 Subject: [PATCH 2/2] Update CI configuration to upgrade pip and install PGroonga extension - Added a step to upgrade pip to the latest version to avoid warnings about outdated pip. - Added steps to install the PGroonga extension and restart PostgreSQL to ensure the schema exists. This resolves issues with the outdated pip version and the missing PGroonga schema during the CI process. --- .github/workflows/zulip-ci.yml | 10 ++++++++++ zulip/integrations/google/google-calendar | 4 +--- zulip/integrations/google/requirements.txt | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/zulip-ci.yml b/.github/workflows/zulip-ci.yml index 36bdb7ca9..beb55e856 100644 --- a/.github/workflows/zulip-ci.yml +++ b/.github/workflows/zulip-ci.yml @@ -67,12 +67,22 @@ jobs: ref: ${{ matrix.server_version }} path: server + - name: Upgrade pip + run: | + python -m pip install --upgrade pip + - name: Install dependencies run: | cd server # This is the main setup job for the test suite ./tools/ci/setup-backend --skip-dev-db-build + # Install PGroonga extension + sudo sh -c 'echo "deb http://packages.groonga.org/debian/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/groonga.list' + sudo apt-get update + sudo apt-get install -y postgresql-14-pgroonga + sudo service postgresql restart + # Cleaning caches is mostly unnecessary in GitHub Actions, because # most builds don't get to write to the cache. # scripts/lib/clean_unused_caches.py --verbose --threshold 0 diff --git a/zulip/integrations/google/google-calendar b/zulip/integrations/google/google-calendar index ecec9c435..e1af25e4a 100755 --- a/zulip/integrations/google/google-calendar +++ b/zulip/integrations/google/google-calendar @@ -12,7 +12,6 @@ import time from typing import List, Optional, Set, Tuple import dateutil.parser -import httplib2 import pytz from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow @@ -111,8 +110,7 @@ def get_credentials() -> Credentials: # Save the credentials for the next run with open(credential_path, "w") as token: token.write(credentials.to_json()) - - return credentials + return credentials except FileNotFoundError: logging.exception("Error while trying to open the `google-credentials.json` file.") sys.exit(1) diff --git a/zulip/integrations/google/requirements.txt b/zulip/integrations/google/requirements.txt index 58d23c07e..d24e2f052 100644 --- a/zulip/integrations/google/requirements.txt +++ b/zulip/integrations/google/requirements.txt @@ -1,4 +1,5 @@ -httplib2>=0.22.0 google-auth>=2.0.0 google-auth-oauthlib>=0.4.6 google-api-python-client>=2.0.0 +types-google-auth==2.0.0 +types-google-auth-oauthlib==0.4.6 \ No newline at end of file