2 # -*- coding: utf-8 -*-
4 # import.py - part of the FDroid server tools
5 # Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 from optparse import OptionParser
30 # Read configuration...
31 execfile('config.py', globals())
35 # Parse command line...
36 parser = OptionParser()
37 parser.add_option("-u", "--url", default=None,
38 help="Project URL to import from.")
39 parser.add_option("-s", "--subdir", default=None,
40 help="Path to main android project subdirectory, if not in root.")
41 (options, args) = parser.parse_args()
44 print "Specify project url."
49 if not os.path.isdir(tmp_dir):
50 print "Creating temporary directory"
54 apps = common.read_metadata()
56 # Figure out what kind of project it is...
60 if url.startswith('https://github.com'):
61 projecttype = 'github'
65 elif url.startswith('https://gitorious.org/'):
66 projecttype = 'gitorious'
67 repo = 'https://git.gitorious.org/' + url[22:] + '.git'
70 elif url.startswith('https://bitbucket.org/'):
73 projecttype = 'bitbucket'
74 sourcecode = url + '/src'
75 issuetracker = url + '/issues'
78 elif url.startswith('http://code.google.com/p/'):
79 if not url.endswith('/'):
81 projecttype = 'googlecode'
82 sourcecode = url + 'source/checkout'
83 issuetracker = url + 'issues/list'
85 # Figure out the repo type and adddress...
86 req = urllib.urlopen(sourcecode)
87 if req.getcode() != 200:
88 print 'Unable to find source at ' + sourcecode + ' - return code ' + str(req.getcode())
92 index = page.find('hg clone')
95 repo = page[index + 9:]
96 index = repo.find('<')
98 print "Error while getting repo address"
102 index=page.find('git clone')
105 repo = page[index + 10:]
106 index = repo.find('<')
108 print "Error while getting repo address"
112 index=page.find('svn checkout')
115 repo = page[index + 13:]
116 prefix = '<strong><em>http</em></strong>'
117 if not repo.startswith(prefix):
118 print "Unexpected checkout instructions format"
120 repo = 'http' + repo[len(prefix):]
121 index = repo.find('<')
123 print "Error while getting repo address - no end tag? '" + repo + "'"
126 index = repo.find(' ')
128 print "Error while getting repo address - no space? '" + repo + "'"
132 print "Unable to determine vcs type"
135 # Figure out the license...
136 req = urllib.urlopen(url)
137 if req.getcode() != 200:
138 print 'Unable to find project page at ' + sourcecode + ' - return code ' + str(req.getcode())
141 index = page.find('Code license')
143 print "Couldn't find license data"
146 lprefix = 'rel="nofollow">'
147 index = ltext.find(lprefix)
149 print "Couldn't find license text"
151 ltext = ltext[index + len(lprefix):]
152 index = ltext.find('<')
154 print "License text not formatted as expected"
156 ltext = ltext[:index]
157 if ltext == 'GNU GPL v3':
159 elif ltext == 'GNU GPL v2':
161 elif ltext == 'Apache License 2.0':
163 elif ltext == 'MIT License':
166 print "License " + ltext + " is not recognised"
170 print "Unable to determine the project type."
173 # Get a copy of the source so we can extract some info...
174 print 'Getting source from ' + repotype + ' repo at ' + repo
175 src_dir = os.path.join(tmp_dir, 'importer')
176 if os.path.exists(tmp_dir):
177 shutil.rmtree(tmp_dir)
178 vcs = common.getvcs(repotype, repo, src_dir)
179 vcs.gotorevision(None)
181 root_dir = os.path.join(src_dir, options.subdir)
185 # Check AndroidManiifest.xml exists...
186 manifest = os.path.join(root_dir, 'AndroidManifest.xml')
187 if not os.path.exists(manifest):
188 print "AndroidManifest.xml did not exist in the expected location. Specify --subdir?"
191 # Extract some information...
192 version, vercode, package = common.parse_androidmanifest(manifest)
194 print "Couldn't find package ID"
197 print "Couldn't find latest version name"
200 print "Couldn't find latest version code"
203 # Make sure it's actually new...
205 if app['id'] == package:
206 print "Package " + package + " already exists"
209 # Construct the metadata...
210 app = common.parse_metadata(None)
212 app['Web Site'] = url
213 app['Source Code'] = sourcecode
215 app['Issue Tracker'] = issuetracker
217 app['License'] = license
218 app['Repo Type'] = repotype
221 # Create a build line...
223 build['version'] = version
224 build['vercode'] = vercode
225 build['commit'] = '?'
227 build['subdir'] = options.subdir
228 if os.path.exists(os.path.join(root_dir, 'jni')):
229 build['buildjni'] = 'yes'
230 app['builds'].append(build)
231 app['comments'].append(('build:' + version,
232 "#Generated by import.py - check this is the right version, and find the right commit!"))
234 metafile = os.path.join('metadata', package + '.txt')
235 common.write_metadata(metafile, app)
236 print "Wrote " + metafile
239 if __name__ == "__main__":