Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: sitescripts/extensions/bin/createNightlies.py

Issue 29374637: Issue 4549 - Implement the Windows Store API to upload development builds (Closed)
Left Patch Set: Update buildtools. Remove submission update logic. Always close requests. Created Feb. 16, 2017, 7:06 a.m.
Right Patch Set: Rebase Created Feb. 16, 2017, 1:14 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « ensure_dependencies.py ('k') | sitescripts/extensions/test/sitescripts.ini.template » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-2016 Eyeo GmbH 2 # Copyright (C) 2006-2016 Eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 request.add_header('Authorization', auth_token) 532 request.add_header('Authorization', auth_token)
533 request.add_header('x-goog-api-version', '2') 533 request.add_header('x-goog-api-version', '2')
534 request.add_header('Content-Length', '0') 534 request.add_header('Content-Length', '0')
535 535
536 response = json.load(opener.open(request)) 536 response = json.load(opener.open(request))
537 537
538 if any(status not in ('OK', 'ITEM_PENDING_REVIEW') for status in respons e['status']): 538 if any(status not in ('OK', 'ITEM_PENDING_REVIEW') for status in respons e['status']):
539 raise Exception({'status': response['status'], 'statusDetail': respo nse['statusDetail']}) 539 raise Exception({'status': response['status'], 'statusDetail': respo nse['statusDetail']})
540 540
541 def get_windows_store_access_token(self): 541 def get_windows_store_access_token(self):
542 auth_token = ''
Sebastian Noack 2017/02/16 11:01:12 Defining auth_token here seems redundant.
543 # use refresh token to obtain a valid access token 542 # use refresh token to obtain a valid access token
544 # https://docs.microsoft.com/en-us/azure/active-directory/active-directo ry-protocols-oauth-code#refreshing-the-access-tokens 543 # https://docs.microsoft.com/en-us/azure/active-directory/active-directo ry-protocols-oauth-code#refreshing-the-access-tokens
545 server = 'https://login.microsoftonline.com' 544 server = 'https://login.microsoftonline.com'
546 token_path = '{}/{}/oauth2/token'.format(server, self.config.tenantID) 545 token_path = '{}/{}/oauth2/token'.format(server, self.config.tenantID)
547 546
548 opener = urllib2.build_opener(HTTPErrorBodyHandler) 547 opener = urllib2.build_opener(HTTPErrorBodyHandler)
549 post_data = urlencode([ 548 post_data = urlencode([
550 ('refresh_token', self.config.refreshToken), 549 ('refresh_token', self.config.refreshToken),
551 ('client_id', self.config.clientID), 550 ('client_id', self.config.clientID),
552 ('client_secret', self.config.clientSecret), 551 ('client_secret', self.config.clientSecret),
553 ('grant_type', 'refresh_token'), 552 ('grant_type', 'refresh_token'),
554 ('resource', 'https://graph.windows.net') 553 ('resource', 'https://graph.windows.net')
555 ]) 554 ])
556 request = urllib2.Request(token_path, post_data) 555 request = urllib2.Request(token_path, post_data)
557 with contextlib.closing(opener.open(request)) as response: 556 with contextlib.closing(opener.open(request)) as response:
558 data = json.load(response) 557 data = json.load(response)
559 auth_token = '{0[token_type]} {0[access_token]}'.format(data) 558 auth_token = '{0[token_type]} {0[access_token]}'.format(data)
560 559
561 return auth_token 560 return auth_token
562 561
563 def upload_appx_file_to_windows_store(self, file_upload_url): 562 def upload_appx_file_to_windows_store(self, file_upload_url):
564
Sebastian Noack 2017/02/16 11:01:12 Nit: We don't add a blank line at the beginning of
565 # Add .appx file to a .zip file 563 # Add .appx file to a .zip file
566 zip_path = os.path.splitext(self.path)[0] + '.zip' 564 zip_path = os.path.splitext(self.path)[0] + '.zip'
567 with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf: 565 with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
568 zf.write(self.path, os.path.basename(self.path)) 566 zf.write(self.path, os.path.basename(self.path))
569 567
570 # Upload that .zip file 568 # Upload that .zip file
571 file_upload_url = file_upload_url.replace('+', '%2B') 569 file_upload_url = file_upload_url.replace('+', '%2B')
572 request = urllib2.Request(file_upload_url) 570 request = urllib2.Request(file_upload_url)
573 request.get_method = lambda: 'PUT' 571 request.get_method = lambda: 'PUT'
574 request.add_header('x-ms-blob-type', 'BlockBlob') 572 request.add_header('x-ms-blob-type', 'BlockBlob')
575 573
576 opener = urllib2.build_opener(HTTPErrorBodyHandler) 574 opener = urllib2.build_opener(HTTPErrorBodyHandler)
577 575
578 with open(zip_path, 'rb') as file: 576 with open(zip_path, 'rb') as file:
579 request.add_header('Content-Length', 577 request.add_header('Content-Length',
580 os.fstat(file.fileno()).st_size - file.tell()) 578 os.fstat(file.fileno()).st_size - file.tell())
581 request.add_data(file) 579 request.add_data(file)
582 opener.open(request).close() 580 opener.open(request).close()
583 581
582 # Clone the previous submission for the new one. Largely based on code
583 # from https://msdn.microsoft.com/en-us/windows/uwp/monetize/python-code-exa mples-for-the-windows-store-submission-api#create-an-app-submission
584 def upload_to_windows_store(self): 584 def upload_to_windows_store(self):
585
586 auth_token = self.get_windows_store_access_token()
Sebastian Noack 2017/02/16 11:01:13 This variable seems redundant, just inline it belo
587
588 opener = urllib2.build_opener(HTTPErrorBodyHandler) 585 opener = urllib2.build_opener(HTTPErrorBodyHandler)
589 586
590 # Clone the previous submission for the new one. Largely based on code 587 headers = {'Authorization': self.get_windows_store_access_token(),
591 # from https://msdn.microsoft.com/en-us/windows/uwp/monetize/python-code -examples-for-the-windows-store-submission-api#create-an-app-submission
592 headers = {'Authorization': auth_token,
593 'Content-type': 'application/json'} 588 'Content-type': 'application/json'}
594 589
595 # Get application 590 # Get application
596 # https://docs.microsoft.com/en-us/windows/uwp/monetize/get-an-app 591 # https://docs.microsoft.com/en-us/windows/uwp/monetize/get-an-app
597 api_path = '{}/v1.0/my/applications/{}'.format( 592 api_path = '{}/v1.0/my/applications/{}'.format(
598 'https://manage.devcenter.microsoft.com', 593 'https://manage.devcenter.microsoft.com',
599 self.config.devbuildGalleryID 594 self.config.devbuildGalleryID
600 ) 595 )
601 596
602 request = urllib2.Request(api_path, None, headers) 597 request = urllib2.Request(api_path, None, headers)
(...skipping 13 matching lines...) Expand all
616 # Create submission 611 # Create submission
617 # https://msdn.microsoft.com/en-us/windows/uwp/monetize/create-an-app-su bmission 612 # https://msdn.microsoft.com/en-us/windows/uwp/monetize/create-an-app-su bmission
618 request = urllib2.Request(submissions_path, '', headers) 613 request = urllib2.Request(submissions_path, '', headers)
619 request.get_method = lambda: 'POST' 614 request.get_method = lambda: 'POST'
620 with contextlib.closing(opener.open(request)) as response: 615 with contextlib.closing(opener.open(request)) as response:
621 submission = json.load(response) 616 submission = json.load(response)
622 617
623 submission_id = submission['id'] 618 submission_id = submission['id']
624 file_upload_url = submission['fileUploadUrl'] 619 file_upload_url = submission['fileUploadUrl']
625 620
626 new_submission_path = '{}/{}'.format( 621 new_submission_path = '{}/{}'.format(submissions_path,
Sebastian Noack 2017/02/16 11:01:13 Nit: We generally prefer aligning arguments over h
627 submissions_path, submission_id) 622 submission_id)
628 623
629 request = urllib2.Request(new_submission_path, None, headers) 624 request = urllib2.Request(new_submission_path, None, headers)
630 opener.open(request).close() 625 opener.open(request).close()
631 626
632 self.upload_appx_file_to_windows_store(file_upload_url) 627 self.upload_appx_file_to_windows_store(file_upload_url)
633 628
634 # Commit submission 629 # Commit submission
635 # https://msdn.microsoft.com/en-us/windows/uwp/monetize/commit-an-app-su bmission 630 # https://msdn.microsoft.com/en-us/windows/uwp/monetize/commit-an-app-su bmission
636 commit_path = '{}/commit'.format(new_submission_path) 631 commit_path = '{}/commit'.format(new_submission_path)
637 request = urllib2.Request(commit_path, '', headers) 632 request = urllib2.Request(commit_path, '', headers)
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 except Exception as ex: 724 except Exception as ex:
730 logging.error('The build for %s failed:', repo) 725 logging.error('The build for %s failed:', repo)
731 logging.exception(ex) 726 logging.exception(ex)
732 727
733 file = open(nightlyConfigFile, 'wb') 728 file = open(nightlyConfigFile, 'wb')
734 nightlyConfig.write(file) 729 nightlyConfig.write(file)
735 730
736 731
737 if __name__ == '__main__': 732 if __name__ == '__main__':
738 main() 733 main()
LEFTRIGHT

Powered by Google App Engine
This is Rietveld