~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/canonical/codehosting/scripts/modifiedbranches.py

  • Committer: Abel Deuring
  • Date: 2009-04-17 10:32:16 UTC
  • mfrom: (8244 devel)
  • mto: This revision was merged to the branch mainline in revision 8328.
  • Revision ID: abel.deuring@canonical.com-20090417103216-4safqqplnos0kw8w
RF merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2009 Canonical Ltd.  All rights reserved.
 
2
 
 
3
"""Implementation of the Launchpad script to list modified branches."""
 
4
 
 
5
__metaclass__ = type
 
6
__all__ = ['ModifiedBranchesScript']
 
7
 
 
8
 
 
9
from datetime import datetime, timedelta
 
10
import os
 
11
from time import strptime
 
12
 
 
13
import pytz
 
14
from zope.component import getUtility
 
15
 
 
16
from canonical.codehosting.vfs import branch_id_to_path
 
17
from canonical.config import config
 
18
from canonical.launchpad.scripts.base import (
 
19
    LaunchpadScript, LaunchpadScriptFailure)
 
20
from lp.code.interfaces.branch import BranchType
 
21
from lp.code.interfaces.branchcollection import IAllBranches
 
22
 
 
23
 
 
24
class ModifiedBranchesScript(LaunchpadScript):
 
25
    """List branches modified since the specified time.
 
26
 
 
27
    Only branches that have been modified since the specified time will be
 
28
    returned.  It is possible that the branch will have been modified only in
 
29
    the web UI and not actually received any more revisions, and will be a
 
30
    false positive.
 
31
 
 
32
    If the branch is REMOTE it is ignored.
 
33
    If the branch is HOSTED, both the hosted and mirrored area are returned.
 
34
    If the branch is an IMPORT or MIRROR branch, only the mirrored area is
 
35
    shown.
 
36
    """
 
37
 
 
38
    description = (
 
39
        "List branch paths for branches modified since the specified time.")
 
40
 
 
41
    def __init__(self, name, dbuser=None, test_args=None):
 
42
        LaunchpadScript.__init__(self, name, dbuser, test_args)
 
43
        # Cache this on object creation so it can be used in tests.
 
44
        self.now_timestamp = datetime.utcnow()
 
45
 
 
46
    def add_my_options(self):
 
47
        self.parser.add_option(
 
48
            "-s", "--since", metavar="DATE",
 
49
            help="A date in the format YYYY-MM-DD.  Branches that "
 
50
            "have been modified since this date will be returned.")
 
51
        self.parser.add_option(
 
52
            "-l", "--last-hours", metavar="HOURS", type="int",
 
53
            help="Return the branches that have been modified in "
 
54
            "the last HOURS number of hours.")
 
55
 
 
56
    def get_last_modified_epoch(self):
 
57
        """Return the timezone aware datetime for the last modified epoch. """
 
58
        if (self.options.last_hours is not None and
 
59
            self.options.since is not None):
 
60
            raise LaunchpadScriptFailure(
 
61
                "Only one of --since or --last-hours can be specified.")
 
62
        last_modified = None
 
63
        if self.options.last_hours is not None:
 
64
            last_modified = (
 
65
                self.now_timestamp - timedelta(hours=self.options.last_hours))
 
66
        elif self.options.since is not None:
 
67
            try:
 
68
                parsed_time = strptime(self.options.since, '%Y-%m-%d')
 
69
                last_modified = datetime(*(parsed_time[:3]))
 
70
            except ValueError, e:
 
71
                raise LaunchpadScriptFailure(str(e))
 
72
        else:
 
73
            raise LaunchpadScriptFailure(
 
74
                "One of --since or --last-hours needs to be specified.")
 
75
 
 
76
        # Make the datetime timezone aware.
 
77
        return last_modified.replace(tzinfo=pytz.UTC)
 
78
 
 
79
    def branch_locations(self, branch):
 
80
        """Return a list of branch paths for the given branch."""
 
81
        path = branch_id_to_path(branch.id)
 
82
        yield os.path.join(config.codehosting.mirrored_branches_root, path)
 
83
        if branch.branch_type == BranchType.HOSTED:
 
84
            yield os.path.join(config.codehosting.hosted_branches_root, path)
 
85
 
 
86
    def main(self):
 
87
        last_modified = self.get_last_modified_epoch()
 
88
        self.logger.info(
 
89
            "Looking for branches modified since %s", last_modified)
 
90
        collection = getUtility(IAllBranches)
 
91
        collection = collection.withBranchType(
 
92
            BranchType.HOSTED, BranchType.MIRRORED, BranchType.IMPORTED)
 
93
        collection = collection.scannedSince(last_modified)
 
94
        for branch in collection.getBranches():
 
95
            self.logger.info(branch.unique_name)
 
96
            for location in self.branch_locations(branch):
 
97
                print location
 
98
 
 
99
        self.logger.info("Done.")
 
100