Skip to content

Commit cab951e

Browse files
authored
Merge pull request #53 from LOLINTERNETZ/fetch-and-log
Fetch and log
2 parents 20440b3 + 6c2db61 commit cab951e

7 files changed

Lines changed: 120 additions & 70 deletions

File tree

CHANGELOG.md

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,131 @@
1-
21
# Change Log for Visual Studio Code - Offline Gallery and Updater
32

3+
## [1.0.24] - 2023-06-05
4+
5+
### Fixed
6+
7+
- Improvements to requests session handling to prevent ConnectionErrors due to repeated connections. Thanks @tomer953 for reporting.
8+
9+
### Added
10+
11+
- Note about Firefox in Readme.md. Thanks @jmorcate for highlighting this gap.
12+
13+
### Changed
14+
15+
- Sort gallery listings with simple python sort.
16+
- Removed deprecated logzero dependency, switched to logging. Thanks @bdsoha for the implementation and note.
17+
418
## [1.0.23] - 2022-11-09
519

620
### Fixed
7-
- @forky2 resolved an issue related to incorrect version ordering (from reverse-alphanumberical to reverse-chronological), which prevented extensions updating correctly by vscode clients.
821

22+
- @forky2 resolved an issue related to incorrect version ordering (from reverse-alphanumberical to reverse-chronological), which prevented extensions updating correctly by vscode clients.
923

1024
## [1.0.22] - 2022-10-31
1125

1226
### Added
13-
- @maxtruxa added support for specifying docker container environment variable `SSLARGS` to control SSL arguments, or disable SSL by setting `BIND=0.0.0.0:80` and `SSLARGS=` (empty).
27+
28+
- @maxtruxa added support for specifying docker container environment variable `SSLARGS` to control SSL arguments, or disable SSL by setting `BIND=0.0.0.0:80` and `SSLARGS=` (empty).
1429

1530
### Changed
16-
- @Precioussheep improved consistency of the codebase, reducing bonus code and added typing.
1731

32+
- @Precioussheep improved consistency of the codebase, reducing bonus code and added typing.
1833

1934
## [1.0.21] - 2022-08-08
2035

2136
### Added
22-
- @tomer953 added support for fetching a specified number of recommended extensions `--total-recommended`.
23-
- @Ebsan added support for fetching pre-release extensions `--prerelease-extensions` and fix fetching other extensions [#31](https://github.com/LOLINTERNETZ/vscodeoffline/issues/31).
24-
- @Ebsan added support for specifying which Visual Studio Code version to masquerade as when fetching extensions `--vscode-version`.
37+
38+
- @tomer953 added support for fetching a specified number of recommended extensions `--total-recommended`.
39+
- @Ebsan added support for fetching pre-release extensions `--prerelease-extensions` and fix fetching other extensions [#31](https://github.com/LOLINTERNETZ/vscodeoffline/issues/31).
40+
- @Ebsan added support for specifying which Visual Studio Code version to masquerade as when fetching extensions `--vscode-version`.
2541

2642
### Changed
27-
- Merge dependabot suggestions for CI pipeline updates.
28-
- Utilise individual requests, rather than a Requests session, for fetching extensions to improve stability of fetch process. Should resolve [#33](https://github.com/LOLINTERNETZ/vscodeoffline/issues/33). Thanks @Ebsan for the fix and @annieherram for reporting.
29-
- Updated build-in certificate and key to update its expiry [#37](https://github.com/LOLINTERNETZ/vscodeoffline/issues/37). Included CA chain aswell. Thanks for reporting @Ebsan.
30-
- Removed platform suport for ia32 builds, as they're no longer provided since ~1.35.
31-
- Split out this changelog.
43+
44+
- Merge dependabot suggestions for CI pipeline updates.
45+
- Utilise individual requests, rather than a Requests session, for fetching extensions to improve stability of fetch process. Should resolve [#33](https://github.com/LOLINTERNETZ/vscodeoffline/issues/33). Thanks @Ebsan for the fix and @annieherram for reporting.
46+
- Updated build-in certificate and key to update its expiry [#37](https://github.com/LOLINTERNETZ/vscodeoffline/issues/37). Included CA chain aswell. Thanks for reporting @Ebsan.
47+
- Removed platform suport for ia32 builds, as they're no longer provided since ~1.35.
48+
- Split out this changelog.
3249

3350
### Fixed
34-
- @tomer953 removed a duplicate flag to QueryFlags.
35-
- @Ebsan fixed an issue with downloading cross-platform extensions [#24](https://github.com/LOLINTERNETZ/vscodeoffline/issues/24).
3651

52+
- @tomer953 removed a duplicate flag to QueryFlags.
53+
- @Ebsan fixed an issue with downloading cross-platform extensions [#24](https://github.com/LOLINTERNETZ/vscodeoffline/issues/24).
3754

3855
## [1.0.20]
56+
3957
### Fixed
40-
- Fixed an issue when downloading multiple versions of extensions. Thanks @forky2!
41-
58+
59+
- Fixed an issue when downloading multiple versions of extensions. Thanks @forky2!
60+
4261
## [1.0.19]
4362

4463
### Fixed
45-
- Lots of really solid bug fixes. Thank you to @fullylegit! Resilience improvements when fetching from marketplace. Thanks @forky2 and @ebsan.
4664

65+
- Lots of really solid bug fixes. Thank you to @fullylegit! Resilience improvements when fetching from marketplace. Thanks @forky2 and @ebsan.
4766

4867
## [1.0.18]
49-
68+
5069
### Changed
51-
- Meta release to trigger CI.
5270

71+
- Meta release to trigger CI.
5372

5473
## [1.0.17]
55-
74+
5675
### Changed
57-
- CORS support for gallery. Thanks @kenyon!
58-
76+
77+
- CORS support for gallery. Thanks @kenyon!
78+
5979
## [1.0.16]
6080

6181
### Changed
62-
- Support for saving sync logs to file. Thanks @ap0yuv!
6382

83+
- Support for saving sync logs to file. Thanks @ap0yuv!
6484

6585
## [1.0.16]
6686

6787
### Changed
68-
- Improve extension stats handling.
6988

70-
89+
- Improve extension stats handling.
90+
7191
## [1.0.14]
7292

7393
### Fixed
74-
- Fixed insider builds being re-fetched.
7594

76-
95+
- Fixed insider builds being re-fetched.
96+
7797
## [1.0.13]
78-
98+
7999
### Added
80-
- Added initial support for extension version handling. Hopefully this resolves issue #4.
81100

101+
- Added initial support for extension version handling. Hopefully this resolves issue #4.
82102

83103
## [1.0.12]
84-
85-
### Fixed
86-
- @ttutko fixed a bug preventing multiple build qualities (stable/insider) from being downloaded. Thanks @darkonejr for investigating and reporting.
87104

88-
105+
### Fixed
106+
107+
- @ttutko fixed a bug preventing multiple build qualities (stable/insider) from being downloaded. Thanks @darkonejr for investigating and reporting.
108+
89109
## [1.0.11]
90110

91111
### Fixed
92-
- Fixed bugs in Gallery sorting, and added timeouts for Sync.
93-
94-
112+
113+
- Fixed bugs in Gallery sorting, and added timeouts for Sync.
114+
95115
## [1.0.10]
96116

97117
### Changed
98-
- Refactored to improve consistency.
99118

119+
- Refactored to improve consistency.
100120

101121
## [1.0.9]
102-
122+
103123
### Added
104-
- Added support for Remote Development, currently (2019-05-12) available to insiders. Refactored various badness.
105124

125+
- Added support for Remote Development, currently (2019-05-12) available to insiders. Refactored various badness.
106126

107127
## [1.0.8]
108-
128+
109129
### Added
110-
- Insiders support and extension packs (remotes).
130+
131+
- Insiders support and extension packs (remotes).

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ services:
2323
image: lolinternet/vscgallery:latest
2424
build:
2525
context: ./
26-
dockerfile: ./vscoffline/vscgallery/Dockerfile
26+
dockerfile: ./vscoffline/vscgallery/Dockerfile
2727
volumes:
2828
# Enable for dev
29-
#- ./vscoffline/:/opt/vscoffline/:ro # Enable for dev
29+
#- ./vscoffline/:/opt/vscoffline/:ro
3030
- ./artifacts/:/artifacts/
3131
# Enable for custom SSL certs
3232
#- ./vscoffline/vscgallery/ssl/:/opt/vscoffline/vscgallery/ssl # Enable for custom SSL certs

vscoffline/server.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os, sys, time, json, glob
22
import falcon
33
from distutils.version import LooseVersion
4-
from logzero import logger as log
4+
import logging as log
55
from wsgiref import simple_server
66
from watchdog.observers.polling import PollingObserver
77
from watchdog.events import FileSystemEventHandler
@@ -164,7 +164,7 @@ def process_loaded_extension(self, extension, extensiondir):
164164
if "targetPlatform" in version:
165165
targetPlatform = version['targetPlatform']
166166
asseturi = vsc.URLROOT + os.path.join(extensiondir, version['version'], targetPlatform)
167-
else:
167+
else:
168168
asseturi = vsc.URLROOT + os.path.join(extensiondir, version['version'])
169169

170170
version['assetUri'] = asseturi
@@ -427,5 +427,10 @@ def on_modified(self, event):
427427
application.add_static_route('/artifacts/', '/artifacts/')
428428

429429
if __name__ == '__main__':
430+
log.basicConfig(
431+
format='[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s',
432+
datefmt='%y%m%d %H:%M:%S',
433+
level=log.DEBUG
434+
)
430435
httpd = simple_server.make_server('0.0.0.0', 5000, application)
431436
httpd.serve_forever()

vscoffline/sync.py

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
import pathlib
77
import hashlib
88
import uuid
9-
import logzero
109
import logging
1110
import json
1211
import time
1312
import datetime
1413
from typing import List
1514
from platform import release
16-
from logzero import logger as log
15+
import logging as log
1716
from pytimeparse.timeparse import timeparse
1817
import vsc
1918
from distutils.dir_util import create_tree
19+
from requests.adapters import HTTPAdapter, Retry
2020

2121

2222
class VSCUpdateDefinition(object):
@@ -225,7 +225,7 @@ def __init__(self, identity, raw=None):
225225
if 'extensionId' in raw:
226226
self.extensionId = raw['extensionId']
227227

228-
def download_assets(self, destination):
228+
def download_assets(self, destination, session):
229229
for version in self.versions:
230230
targetplatform = ''
231231
if "targetPlatform" in version:
@@ -242,12 +242,21 @@ def download_assets(self, destination):
242242
destfile = os.path.join(ver_destination, f'{asset}')
243243
create_tree(os.path.abspath(os.sep), (destfile,))
244244
if not os.path.exists(destfile):
245-
log.debug(
246-
f'Downloading {self.identity} {asset} to {destfile}')
247-
result = requests.get(
248-
url, allow_redirects=True, timeout=vsc.TIMEOUT)
249-
with open(destfile, 'wb') as dest:
250-
dest.write(result.content)
245+
for i in range(5):
246+
try:
247+
if i == 0:
248+
log.debug(f'Downloading {self.identity} {asset} to {destfile}')
249+
else:
250+
log.info(f'Retrying {i+1}, download {self.identity} {asset} to {destfile}')
251+
result = session.get(
252+
url, allow_redirects=True, timeout=vsc.TIMEOUT)
253+
with open(destfile, 'wb') as dest:
254+
dest.write(result.content)
255+
break
256+
except requests.exceptions.ProxyError:
257+
log.info("ProxyError: Retrying.")
258+
except requests.exceptions.ReadTimeout:
259+
log.info("ReadTimeout: Retrying.")
251260

252261
def process_embedded_extensions(self, destination, mp):
253262
"""
@@ -354,10 +363,11 @@ def signal_updated(artifactdir):
354363

355364
class VSCMarketplace(object):
356365

357-
def __init__(self, insider, prerelease, version):
366+
def __init__(self, insider, prerelease, version, session):
358367
self.insider = insider
359368
self.prerelease = prerelease
360369
self.version = version
370+
self.session = session
361371

362372
def get_recommendations(self, destination, totalrecommended):
363373
recommendations = self.search_top_n(totalrecommended)
@@ -389,7 +399,7 @@ def get_recommendations(self, destination, totalrecommended):
389399
return recommendations
390400

391401
def get_recommendations_old(self, destination):
392-
result = requests.get(vsc.URL_RECOMMENDATIONS,
402+
result = self.session.get(vsc.URL_RECOMMENDATIONS,
393403
allow_redirects=True, timeout=vsc.TIMEOUT)
394404
if result.status_code != 200:
395405
log.warning(
@@ -409,7 +419,7 @@ def get_recommendations_old(self, destination):
409419
return packages
410420

411421
def get_malicious(self, destination, extensions=None):
412-
result = requests.get(
422+
result = self.session.get(
413423
vsc.URL_MALICIOUS, allow_redirects=True, timeout=vsc.TIMEOUT)
414424
if result.status_code != 200:
415425
log.warning(
@@ -526,7 +536,7 @@ def _query_marketplace(self, filtertype, filtervalue, pageNumber=0, pageSize=500
526536
log.info("Retrying pull page %d attempt %d." %
527537
(pageNumber, i+1))
528538
try:
529-
result = requests.post(vsc.URL_MARKETPLACEQUERY, headers=self._headers(
539+
result = self.session.post(vsc.URL_MARKETPLACEQUERY, headers=self._headers(
530540
), json=query, allow_redirects=True, timeout=vsc.TIMEOUT)
531541
if result:
532542
break
@@ -664,16 +674,22 @@ def __repr__(self):
664674
config = parser.parse_args()
665675

666676
if config.debug:
667-
logzero.loglevel(logging.DEBUG)
677+
loglevel = logging.DEBUG
668678
else:
669-
logzero.loglevel(logging.INFO)
679+
loglevel = logging.INFO
670680

671681
if config.logfile:
672682
log_dir = os.path.dirname(os.path.abspath(config.logfile))
673683
if not os.path.exists(log_dir):
674684
raise FileNotFoundError(
675685
f'Log directory does not exist at {log_dir}')
676-
logzero.logfile(config.logfile, maxBytes=1000000, backupCount=3)
686+
logging.basicConfig(filename=config.logfile, encoding='utf-8', level=loglevel)
687+
else:
688+
log.basicConfig(
689+
format='[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s',
690+
datefmt='%y%m%d %H:%M:%S',
691+
level=loglevel
692+
)
677693

678694
config.artifactdir_installers = os.path.join(
679695
os.path.abspath(config.artifactdir), 'installers')
@@ -705,11 +721,17 @@ def __repr__(self):
705721
if config.frequency:
706722
config.frequency = timeparse(config.frequency)
707723

724+
session = requests.Session()
725+
retries = Retry(total=5,
726+
backoff_factor=0.1,
727+
status_forcelist=[ 500, 502, 503, 504 ])
728+
session.mount('https://', HTTPAdapter(max_retries=retries))
729+
708730
while True:
709731
versions = []
710732
extensions = {}
711733
mp = VSCMarketplace(config.checkinsider,
712-
config.prerelease, config.version)
734+
config.prerelease, config.version, session)
713735

714736
if config.checkbinaries and not config.skipbinaries:
715737
log.info('Syncing VS Code Update Versions')
@@ -776,15 +798,15 @@ def __repr__(self):
776798
log.info(
777799
f'Progress {count}/{len(extensions)} ({count/len(extensions)*100:.1f}%)')
778800
extensions[identity].download_assets(
779-
config.artifactdir_extensions)
801+
config.artifactdir_extensions, session)
780802
bonus = extensions[identity].process_embedded_extensions(
781803
config.artifactdir_extensions, mp) + bonus
782804
extensions[identity].save_state(config.artifactdir_extensions)
783805
count = count + 1
784806

785807
for bonusextension in bonus:
786808
log.debug(f'Processing Embedded Extension: {bonusextension}')
787-
bonusextension.download_assets(config.artifactdir_extensions)
809+
bonusextension.download_assets(config.artifactdir_extensions, session)
788810
bonusextension.save_state(config.artifactdir_extensions)
789811

790812
log.info('Complete')

0 commit comments

Comments
 (0)