1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# -*- coding: utf-8 -*-
"""
client.py
~~~~~~~~~
This module implements a interface between g-octave and the octave-forge
Subversion repository.
:copyright: (c) 2010 by Rafael Goncalves Martins
:license: GPL-2, see LICENSE for more details.
"""
import os
import pysvn
import shutil
import subprocess
import sys
import urllib2
import revisions
from g_octave import config
class SvnClient:
url = 'https://octave.svn.sourceforge.net/svnroot/octave/trunk/octave-forge/'
categories = ['main', 'extra', 'language', 'nonfree']
exclude = ['CONTENTS', 'INDEX', 'Makefile', 'base']
def __init__(self, create_revisions=True, verbose=False):
conf = config.Config()
json_file = os.path.join(conf.db, 'revisions.json')
self._verbose = verbose
self._client = pysvn.Client()
self._revisions = revisions.Revisions(json_file)
self.packages = {}
if create_revisions and not os.path.exists(json_file):
self.update_revisions()
else:
self.packages = self._revisions.get()
def update_revisions(self):
updated = []
for category in self.categories:
self.packages[category] = self._list_packages(category)
for category in self.packages:
for package in self.packages[category]:
old_revision = self._revisions.get(category, package)
current_revision = self.packages[category][package]
if current_revision is None or current_revision > old_revision:
self._revisions.set(category, package, current_revision)
updated.append((category, package))
return updated
def _list_packages(self, category):
try:
if self._verbose:
print 'Listing packages from: ' + category
pkg_list = self._client.list(
self.url + '/' + category + '/',
depth = pysvn.depth.immediates
)
except pysvn.ClientError, err:
print >> sys.stderr, 'Error: ' + str(err)
tmp = {}
for props, lock in pkg_list:
filename = props.repos_path.split('/')[-1]
if filename not in self.exclude and filename != category:
tmp[filename] = props.created_rev.number
return tmp
def create_description_tree(self, dest, categories=['main', 'extra', 'language']):
for category in categories:
if category not in self.categories:
continue
for pkg, revision in self.packages[category]:
current_dir = os.path.join(dest, category, pkg)
os.makedirs(current_dir)
try:
if self._verbose:
print 'Fetching DESCRIPTION from: %s/%s' % (category, pkg)
fp = urllib2.urlopen(
self.url + '/' + category + '/' + pkg + '/DESCRIPTION'
)
with open(os.path.join(current_dir, 'DESCRIPTION'), 'w') as fp_:
shutil.copyfileobj(fp, fp_)
except urllib2.URLError:
pass
def checkout_package(self, category, name, dest, stable=True):
if stable:
# get DESCRIPTION revision
try:
info = self._client.info2(
self.url + '/' + category + '/' + name + '/DESCRIPTION'
)
except pysvn.ClientError, err:
return False
revision = info[0][1].last_changed_rev
try:
self._client.checkout(
self.url + '/' + category + '/' + name + '/',
dest,
revision = stable and revision or \
pysvn.Revision(pysvn.opt_revision_kind.head)
)
except pysvn.ClientError, err:
return False
return True
|