| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Get stats about your activity. | 6 """Get stats about your activity. |
| 7 | 7 |
| 8 Example: | 8 Example: |
| 9 - my_activity.py for stats for the current week (last week on mondays). | 9 - my_activity.py for stats for the current week (last week on mondays). |
| 10 - my_activity.py -Q for stats for last quarter. | 10 - my_activity.py -Q for stats for last quarter. |
| 11 - my_activity.py -Y for stats for this year. | 11 - my_activity.py -Y for stats for this year. |
| 12 - my_activity.py -b 4/5/12 for stats since 4/5/12. | 12 - my_activity.py -b 4/5/12 for stats since 4/5/12. |
| 13 - my_activity.py -b 4/5/12 -e 6/7/12 for stats between 4/5/12 and 6/7/12. | 13 - my_activity.py -b 4/5/12 -e 6/7/12 for stats between 4/5/12 and 6/7/12. |
| 14 """ | 14 """ |
| 15 | 15 |
| 16 # TODO(vadimsh): This script knows too much about ClientLogin and cookies. It |
| 17 # will stop to work on ~20 Apr 2015. |
| 18 |
| 16 # These services typically only provide a created time and a last modified time | 19 # These services typically only provide a created time and a last modified time |
| 17 # for each item for general queries. This is not enough to determine if there | 20 # for each item for general queries. This is not enough to determine if there |
| 18 # was activity in a given time period. So, we first query for all things created | 21 # was activity in a given time period. So, we first query for all things created |
| 19 # before end and modified after begin. Then, we get the details of each item and | 22 # before end and modified after begin. Then, we get the details of each item and |
| 20 # check those details to determine if there was activity in the given period. | 23 # check those details to determine if there was activity in the given period. |
| 21 # This means that query time scales mostly with (today() - begin). | 24 # This means that query time scales mostly with (today() - begin). |
| 22 | 25 |
| 23 import cookielib | 26 import cookielib |
| 24 import datetime | 27 import datetime |
| 25 from datetime import datetime | 28 from datetime import datetime |
| 26 from datetime import timedelta | 29 from datetime import timedelta |
| 27 from functools import partial | 30 from functools import partial |
| 28 import json | 31 import json |
| 29 import optparse | 32 import optparse |
| 30 import os | 33 import os |
| 31 import subprocess | 34 import subprocess |
| 32 import sys | 35 import sys |
| 33 import urllib | 36 import urllib |
| 34 import urllib2 | 37 import urllib2 |
| 35 | 38 |
| 39 import auth |
| 36 import gerrit_util | 40 import gerrit_util |
| 37 import rietveld | 41 import rietveld |
| 38 from third_party import upload | 42 from third_party import upload |
| 39 | 43 |
| 40 try: | 44 try: |
| 41 from dateutil.relativedelta import relativedelta # pylint: disable=F0401 | 45 from dateutil.relativedelta import relativedelta # pylint: disable=F0401 |
| 42 except ImportError: | 46 except ImportError: |
| 43 print 'python-dateutil package required' | 47 print 'python-dateutil package required' |
| 44 exit(1) | 48 exit(1) |
| 45 | 49 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 for instance in filtered_instances: | 264 for instance in filtered_instances: |
| 261 print '\t' + instance['url'] | 265 print '\t' + instance['url'] |
| 262 print 'Use --auth if you would like to authenticate to them.\n' | 266 print 'Use --auth if you would like to authenticate to them.\n' |
| 263 | 267 |
| 264 def rietveld_search(self, instance, owner=None, reviewer=None): | 268 def rietveld_search(self, instance, owner=None, reviewer=None): |
| 265 if instance['requires_auth'] and not instance['auth']: | 269 if instance['requires_auth'] and not instance['auth']: |
| 266 return [] | 270 return [] |
| 267 | 271 |
| 268 | 272 |
| 269 email = None if instance['auth'] else '' | 273 email = None if instance['auth'] else '' |
| 270 remote = rietveld.Rietveld('https://' + instance['url'], email, None) | 274 auth_config = auth.extract_auth_config_from_options(self.options) |
| 275 remote = rietveld.Rietveld('https://' + instance['url'], auth_config, email) |
| 271 | 276 |
| 272 # See def search() in rietveld.py to see all the filters you can use. | 277 # See def search() in rietveld.py to see all the filters you can use. |
| 273 query_modified_after = None | 278 query_modified_after = None |
| 274 | 279 |
| 275 if instance['supports_owner_modified_query']: | 280 if instance['supports_owner_modified_query']: |
| 276 query_modified_after = self.modified_after.strftime('%Y-%m-%d') | 281 query_modified_after = self.modified_after.strftime('%Y-%m-%d') |
| 277 | 282 |
| 278 # Rietveld does not allow search by both created_before and modified_after. | 283 # Rietveld does not allow search by both created_before and modified_after. |
| 279 # (And some instances don't allow search by both owner and modified_after) | 284 # (And some instances don't allow search by both owner and modified_after) |
| 280 owner_email = None | 285 owner_email = None |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 help='Specifies the format to use when printing reviews.') | 778 help='Specifies the format to use when printing reviews.') |
| 774 output_format_group.add_option( | 779 output_format_group.add_option( |
| 775 '--output-format-heading', metavar='<format>', | 780 '--output-format-heading', metavar='<format>', |
| 776 default=u'{heading}:', | 781 default=u'{heading}:', |
| 777 help='Specifies the format to use when printing headings.') | 782 help='Specifies the format to use when printing headings.') |
| 778 output_format_group.add_option( | 783 output_format_group.add_option( |
| 779 '-m', '--markdown', action='store_true', | 784 '-m', '--markdown', action='store_true', |
| 780 help='Use markdown-friendly output (overrides --output-format ' | 785 help='Use markdown-friendly output (overrides --output-format ' |
| 781 'and --output-format-heading)') | 786 'and --output-format-heading)') |
| 782 parser.add_option_group(output_format_group) | 787 parser.add_option_group(output_format_group) |
| 788 auth.add_auth_options(parser) |
| 783 | 789 |
| 784 # Remove description formatting | 790 # Remove description formatting |
| 785 parser.format_description = ( | 791 parser.format_description = ( |
| 786 lambda _: parser.description) # pylint: disable=E1101 | 792 lambda _: parser.description) # pylint: disable=E1101 |
| 787 | 793 |
| 788 options, args = parser.parse_args() | 794 options, args = parser.parse_args() |
| 789 options.local_user = os.environ.get('USER') | 795 options.local_user = os.environ.get('USER') |
| 790 if args: | 796 if args: |
| 791 parser.error('Args unsupported') | 797 parser.error('Args unsupported') |
| 792 if not options.user: | 798 if not options.user: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 my_activity.print_issues() | 858 my_activity.print_issues() |
| 853 return 0 | 859 return 0 |
| 854 | 860 |
| 855 | 861 |
| 856 if __name__ == '__main__': | 862 if __name__ == '__main__': |
| 857 try: | 863 try: |
| 858 sys.exit(main()) | 864 sys.exit(main()) |
| 859 except KeyboardInterrupt: | 865 except KeyboardInterrupt: |
| 860 sys.stderr.write('interrupted\n') | 866 sys.stderr.write('interrupted\n') |
| 861 sys.exit(1) | 867 sys.exit(1) |
| OLD | NEW |