|
1 | 1 | import os |
2 | 2 | import re |
3 | 3 | import json |
4 | | -import pytz |
5 | 4 | import zlib |
6 | 5 | import base64 |
7 | 6 | import shutil |
8 | 7 | import urllib.parse |
9 | 8 | import urllib.request |
10 | | -import dateutil.parser |
11 | 9 | from datetime import datetime |
12 | 10 |
|
| 11 | +this_dir = os.path.dirname(os.path.realpath(__file__)) |
| 12 | + |
| 13 | +try: |
| 14 | + from requests_toolbelt import MultipartEncode |
| 15 | + import pytz |
| 16 | + import dateutil.parser |
| 17 | +except ImportError: |
| 18 | + # this is to import all dependencies shipped with package (e.g. to use in qgis-plugin) |
| 19 | + deps_dir = os.path.join(this_dir, 'deps') |
| 20 | + if os.path.exists(deps_dir): |
| 21 | + import sys |
| 22 | + for f in os.listdir(os.path.join(deps_dir)): |
| 23 | + sys.path.append(os.path.join(deps_dir, f)) |
| 24 | + |
| 25 | + from requests_toolbelt import MultipartEncode |
| 26 | + import pytz |
| 27 | + import dateutil.parser |
| 28 | + |
13 | 29 | from .utils import save_to_file, generate_checksum, move_file |
14 | | -from .multipart import MultipartReader, MultipartEncoder, Field, parse_boundary |
| 30 | +from .multipart import MultipartReader, parse_boundary |
15 | 31 |
|
16 | 32 |
|
17 | 33 | class InvalidProject(Exception): |
@@ -372,15 +388,26 @@ def push_project(self, directory): |
372 | 388 | changes = project_changes(server_info["files"], files) |
373 | 389 | count = sum(len(items) for items in changes.values()) |
374 | 390 | if count: |
375 | | - def fields(): |
376 | | - yield Field("changes", json.dumps(changes).encode("utf-8")) |
377 | | - for file in (changes["added"] + changes["updated"]): |
378 | | - path = file["path"] |
379 | | - with open(os.path.join(directory, path), "rb") as f: |
380 | | - yield Field(path, f, filename=path, content_type="application/octet-stream") |
381 | | - |
382 | | - encoder = MultipartEncoder(fields()) |
383 | | - resp = self.post("/v1/project/data_sync/{}".format(project_path), encoder, encoder.get_headers()) |
| 391 | + # Custom MultipartEncoder doesn't compute Content-Length, |
| 392 | + # which is currently required by gunicorn. |
| 393 | + # def fields(): |
| 394 | + # yield Field("changes", json.dumps(changes).encode("utf-8")) |
| 395 | + # for file in (changes["added"] + changes["updated"]): |
| 396 | + # path = file["path"] |
| 397 | + # with open(os.path.join(directory, path), "rb") as f: |
| 398 | + # yield Field(path, f, filename=path, content_type="application/octet-stream") |
| 399 | + # encoder = MultipartEncoder(fields()) |
| 400 | + |
| 401 | + fields = {"changes": json.dumps(changes).encode("utf-8")} |
| 402 | + for file in (changes["added"] + changes["updated"]): |
| 403 | + path = file["path"] |
| 404 | + fields[path] = (path, open(os.path.join(directory, path), 'rb'), "application/octet-stream") |
| 405 | + encoder = MultipartEncoder(fields=fields) |
| 406 | + headers = { |
| 407 | + "Content-Type": encoder.content_type, |
| 408 | + "Content-Length": encoder.len |
| 409 | + } |
| 410 | + resp = self.post("/v1/project/data_sync/{}".format(project_path), encoder, headers=headers) |
384 | 411 | new_project_info = json.load(resp) |
385 | 412 | local_info["files"] = new_project_info["files"] |
386 | 413 | local_info["version"] = new_project_info["version"] |
|
0 commit comments