~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to scripts/modified-branches.py

  • Committer: Tim Penhey
  • Date: 2009-04-03 01:47:44 UTC
  • mto: This revision was merged to the branch mainline in revision 8144.
  • Revision ID: tim.penhey@canonical.com-20090403014744-pzbumewt6dbqs5ud
A script to be used for smart backups.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python2.4
 
2
# Copyright 2007 Canonical Ltd.  All rights reserved.
 
3
# This script uses relative imports.
 
4
# pylint: disable-msg=W0403
 
5
 
 
6
"""Script to print disk locations of modified branches.
 
7
 
 
8
This script will be used by IS for the rsync backups.
 
9
 
 
10
Only branches that have been modified since the specified time will be
 
11
returned.  It is possible that the branch will have been modified only in the
 
12
web UI and not actually recieved any more revisions, and will be a false
 
13
positive.
 
14
 
 
15
If the branch is REMOTE it is ignored.
 
16
If the branch is HOSTED, both the hosted and mirrored area are returned.
 
17
If the branch is an IMPORT or MIRROR branch, only the mirrored area is shown.
 
18
"""
 
19
 
 
20
# This script does not use the standard Launchpad script framework as it is
 
21
# not intended to be run by itself.
 
22
 
 
23
 
 
24
import _pythonpath
 
25
from datetime import datetime, timedelta
 
26
import logging
 
27
import os
 
28
from time import strptime
 
29
import sys
 
30
 
 
31
from pytz import UTC
 
32
from zope.component import getUtility
 
33
 
 
34
from canonical.codehosting.vfs.branchfs import branch_id_to_path
 
35
from canonical.config import config
 
36
from canonical.launchpad.database.branch import Branch
 
37
from canonical.launchpad.interfaces.branch import BranchType
 
38
from canonical.launchpad.scripts.base import LaunchpadScript
 
39
from canonical.launchpad.webapp.interfaces import (
 
40
    IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
 
41
 
 
42
 
 
43
class ModifiedBranchesScript(LaunchpadScript):
 
44
    """List branches modified since the specified time."""
 
45
 
 
46
    description = (
 
47
        "List branch paths for branches modified since the specified time.")
 
48
 
 
49
    def add_my_options(self):
 
50
        self.parser.add_option(
 
51
            "-s", "--since", metavar="DATE",
 
52
            help="A date in the format YYYY-MM-DD.  Branches that "
 
53
            "have been modified since this date will be returned.")
 
54
        self.parser.add_option(
 
55
            "-l", "--last-hours", metavar="HOURS", type="int",
 
56
            help="Return the branches that have been modified in "
 
57
            "the last HOURS number of hours.")
 
58
 
 
59
    def main(self):
 
60
        if (self.options.last_hours is not None and
 
61
            self.options.since is not None):
 
62
            print "Only one of --since or --last-hours can be specified."
 
63
            sys.exit(1)
 
64
        last_modified = None
 
65
        if self.options.last_hours is not None:
 
66
            last_modified = (
 
67
                datetime.utcnow() - timedelta(hours=self.options.last_hours))
 
68
        elif self.options.since is not None:
 
69
            try:
 
70
                parsed_time = strptime(self.options.since, '%Y-%m-%d')
 
71
                last_modified = datetime(*(parsed_time[:3]))
 
72
            except ValueError, e:
 
73
                print e
 
74
                sys.exit(1)
 
75
        else:
 
76
            print "One of --since or --last-hours needs to be specified."
 
77
            sys.exit(1)
 
78
        # Make the datetime timezone aware.
 
79
        last_modified = last_modified.replace(tzinfo=UTC)
 
80
        self.logger.info(
 
81
            "Looking for branches modified since %s", last_modified)
 
82
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
 
83
        branches = store.find(
 
84
            Branch, Branch.date_last_modified > last_modified)
 
85
        for branch in branches:
 
86
            self.logger.info(branch.unique_name)
 
87
            branch_type = branch.branch_type
 
88
            if branch_type == BranchType.REMOTE:
 
89
                self.logger.info("remote branch, skipping")
 
90
                continue
 
91
            path = branch_id_to_path(branch.id)
 
92
            if branch_type == BranchType.HOSTED:
 
93
                print os.path.join(
 
94
                    config.codehosting.hosted_branches_root, path)
 
95
            print os.path.join(
 
96
                config.codehosting.mirrored_branches_root, path)
 
97
 
 
98
        self.logger.info("Done.")
 
99
 
 
100
 
 
101
if __name__ == '__main__':
 
102
    script = ModifiedBranchesScript('modified-branches')
 
103
    script.run()