From b1cfc82fefbe42d731850bea5661bb6eafedbbc8 Mon Sep 17 00:00:00 2001
From: Julen Landa Alustiza <jlanda@fedoraproject.org>
Date: Nov 15 2019 11:00:31 +0000
Subject: [PATCH 1/4] Unblock arrow 0.15.0 from requirements.txt


This reverts commit ce72a7e16c73d3221930676904e90b6c80919951.

---

diff --git a/requirements.txt b/requirements.txt
index db74e16..c877d94 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
 # Used for when working from a virtualenv.
 # Use this file by running "$ pip install -r requirements.txt"
 alembic
-arrow < 0.15.0
+arrow
 bcrypt
 binaryornot
 bleach

From df6da32197f2055c9d4305ce702316f87ba68147 Mon Sep 17 00:00:00 2001
From: Julen Landa Alustiza <jlanda@fedoraproject.org>
Date: Nov 15 2019 11:00:31 +0000
Subject: [PATCH 2/4] pagure/api/user: catch arrow 0.15's ValueError


---

diff --git a/pagure/api/user.py b/pagure/api/user.py
index 6b3d3e0..68ea6cc 100644
--- a/pagure/api/user.py
+++ b/pagure/api/user.py
@@ -727,7 +727,7 @@ def api_view_user_activity_date(username, date):
     try:
         date = arrow.get(date)
         date = date.strftime("%Y-%m-%d")
-    except arrow.parser.ParserError as err:
+    except (arrow.parser.ParserError, ValueError) as err:
         raise pagure.exceptions.APIError(
             400, error_code=APIERROR.ENOCODE, error=str(err)
         )

From 37b6c526bfbbf02586b412296ae358ae2e96a6d2 Mon Sep 17 00:00:00 2001
From: Julen Landa Alustiza <jlanda@fedoraproject.org>
Date: Nov 15 2019 11:00:31 +0000
Subject: [PATCH 3/4] tests: arrow >= 0.15 support


---

diff --git a/tests/__init__.py b/tests/__init__.py
index 153fdae..8aeb7cf 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -512,6 +512,19 @@ class SimplePagureTest(unittest.TestCase):
             wtforms_v[idx] = val
         return tuple(wtforms_v)
 
+    def get_arrow_version(self):
+        """ Returns the arrow version as a tuple."""
+        import arrow
+
+        arrow_v = arrow.__version__.split(".")
+        for idx, val in enumerate(arrow_v):
+            try:
+                val = int(val)
+            except ValueError:
+                pass
+            arrow_v[idx] = val
+        return tuple(arrow_v)
+
     def assertURLEqual(self, url_1, url_2):
         url_parsed_1 = list(urlparse(url_1))
         url_parsed_1[4] = parse_qs(url_parsed_1[4])
diff --git a/tests/test_pagure_flask_api_user.py b/tests/test_pagure_flask_api_user.py
index e85704c..b95f85c 100644
--- a/tests/test_pagure_flask_api_user.py
+++ b/tests/test_pagure_flask_api_user.py
@@ -328,17 +328,38 @@ class PagureFlaskApiUSertests(tests.Modeltests):
         output = self.app.get("/api/0/user/pingou/activity/AABB")
         self.assertEqual(output.status_code, 400)
 
-        # Invalid date
+        # Invalid date, arrow >= 0.15 throws an exception,
+        # previous versions parsed it
         output = self.app.get("/api/0/user/pingou/activity/2016asd")
-        self.assertEqual(output.status_code, 200)
-        exp = {"activities": [], "date": "2016-01-01"}
-        self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
-
-        # Date parsed, just not really as expected
+        if self.get_arrow_version() >= (0, 15):
+            self.assertEqual(output.status_code, 400)
+            exp = {
+                "error": "Could not match input '2016asd' to any of the following formats: "
+                "YYYY-MM-DD, YYYY-M-DD, YYYY-M-D, YYYY/MM/DD, YYYY/M/DD, YYYY/M/D, "
+                "YYYY.MM.DD, YYYY.M.DD, YYYY.M.D, YYYYMMDD, YYYY-DDDD, YYYYDDDD, "
+                "YYYY-MM, YYYY/MM, YYYY.MM, YYYY",
+                "error_code": "ENOCODE",
+            }
+            self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
+        else:
+            self.assertEqual(output.status_code, 200)
+            exp = {"activities": [], "date": "2016-01-01"}
+            self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
+
+        # Invalid date, arrow => throws an exception,
+        # previous versions parsed it just not really as expected
         output = self.app.get("/api/0/user/pingou/activity/20161245")
-        self.assertEqual(output.status_code, 200)
-        exp = {"activities": [], "date": "1970-08-22"}
-        self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
+        if self.get_arrow_version() >= (0, 15):
+            self.assertEqual(output.status_code, 400)
+            exp = {
+                "error": "day is out of range for month",
+                "error_code": "ENOCODE",
+            }
+            self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
+        else:
+            self.assertEqual(output.status_code, 200)
+            exp = {"activities": [], "date": "1970-08-22"}
+            self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
 
         date = datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
         # Retrieve the user's logs for today

From eb7ca5eb60f12ff17e580e3777db492c2a64815f Mon Sep 17 00:00:00 2001
From: Julen Landa Alustiza <jlanda@fedoraproject.org>
Date: Nov 15 2019 11:00:31 +0000
Subject: [PATCH 4/4] pagure/api/user: capture ValueError exception on arrow.get()


---

diff --git a/pagure/api/user.py b/pagure/api/user.py
index 68ea6cc..1d3ee30 100644
--- a/pagure/api/user.py
+++ b/pagure/api/user.py
@@ -636,7 +636,7 @@ def api_view_user_activity_stats(username):
             try:
 
                 return arrow.get(d, tz).replace(hour=12).timestamp
-            except arrow.parser.ParserError:
+            except (arrow.parser.ParserError, ValueError):
                 # if tz is invalid for some reason, just go with UTC
                 return arrow.get(d).replace(hour=12).timestamp
         else:

