| Home | Trees | Indices | Help |
|
|---|
|
|
1 # 2 # Copyright (c) 2004-2008 rPath, Inc. 3 # 4 # This program is distributed under the terms of the Common Public License, 5 # version 1.0. A copy of this license should have been distributed with this 6 # source file in a file called LICENSE. If it is not present, the license 7 # is always available at http://www.rpath.com/permanent/licenses/CPL-1.0. 8 # 9 # This program is distributed in the hope that it will be useful, but 10 # without any warranty; without even the implied warranty of merchantability 11 # or fitness for a particular purpose. See the Common Public License for 12 # full details. 13 # 14 from httplib import HTTPConnection 15 from urllib2 import urlopen 16 import textwrap 17 import time 18 import urlparse 19 import xml.dom.minidom 20 import xml.parsers.expat 21 22 from conary.fmtroves import TroveCategories, LicenseCategories 23 from conary.local import schema 2426 (SHORT_DESC, LONG_DESC, 27 URL, LICENSE, CATEGORY, 28 SOURCE) = range(6) 29 30 # mapping from enum id to real name 31 className = {SHORT_DESC: "shortDesc", 32 LONG_DESC: "longDesc", 33 URL: "url", 34 LICENSE: "license", 35 CATEGORY: "category", 36 SOURCE: "source"} 37 38 (STRING, LIST) = range(2) 39 40 types = {SHORT_DESC: STRING, 41 LONG_DESC: STRING, 42 URL: LIST, 43 LICENSE: LIST, 44 CATEGORY: LIST, 45 SOURCE: STRING}465214953 - def add(self, itemId, versionId, branchId, shortDesc, longDesc, 54 urls, licenses, categories, source="", language="C"):55 cu = self.db.cursor() 56 57 if language == "C": 58 cu.execute(""" 59 INSERT INTO Metadata (itemId, versionId, branchId, timestamp) 60 VALUES(?, ?, ?, ?)""", itemId, versionId, branchId, time.time()) 61 mdId = cu.lastrowid 62 else: 63 cu.execute(""" 64 SELECT metadataId FROM Metadata 65 WHERE itemId=? AND versionId=? AND branchId=? ORDER BY timestamp DESC LIMIT 1""", 66 itemId, versionId, branchId) 67 mdId = cu.fetchone()[0] 68 69 for mdClass, data in (MDClass.SHORT_DESC, [shortDesc]),\ 70 (MDClass.LONG_DESC, [longDesc]),\ 71 (MDClass.URL, urls),\ 72 (MDClass.LICENSE, licenses),\ 73 (MDClass.CATEGORY, categories),\ 74 (MDClass.SOURCE, [source]): 75 for d in data: 76 cu.execute(""" 77 INSERT INTO MetadataItems (metadataId, class, data, language) 78 VALUES(?, ?, ?, ?)""", mdId, mdClass, d, language) 79 80 # XXX should I be calling commit here? 81 self.db.commit() 82 return mdId8385 cu = self.db.cursor() 86 87 cu.execute("SELECT metadataId FROM Metadata WHERE itemId=? AND versionId=? AND branchId=? ORDER BY timestamp DESC LIMIT 1", 88 itemId, versionId, branchId) 89 metadataId = cu.fetchone() 90 if metadataId: 91 metadataId = metadataId[0] 92 else: 93 return None 94 95 # URL, LICENSE, and CATEGORY are not translated 96 cu.execute(""" 97 SELECT class, data FROM MetadataItems 98 WHERE metadataId=? and (language=? OR class IN (?, ?, ?)) 99 """, (metadataId, language, 100 MDClass.URL, MDClass.LICENSE, MDClass.CATEGORY)) 101 102 # create a dictionary of metadata classes 103 # each key points to a list of metadata items 104 105 items = {} 106 for mdClass, className in MDClass.className.items(): 107 classType = MDClass.types[mdClass] 108 109 if classType == MDClass.STRING: 110 items[className] = "" 111 elif classType == MDClass.LIST: 112 items[className] = [] 113 else: 114 items[className] = None 115 116 for mdClass, data in cu: 117 className = MDClass.className[mdClass] 118 classType = MDClass.types[mdClass] 119 120 if classType == MDClass.STRING: 121 items[className] = data 122 elif classType == MDClass.LIST: 123 items[className].append(data) 124 125 for key, value in items.iteritems(): 126 if isinstance(value, list): 127 items[key] = sorted(value) 128 return items129131 cu = self.db.cursor() 132 cu.execute("""SELECT 133 Versions.version 134 FROM 135 Metadata, Branches, Versions 136 WHERE 137 Metadata.itemId=? AND Metadata.branchId=? 138 AND Metadata.branchId=Branches.branchId 139 AND Metadata.versionId=Versions.versionId 140 ORDER BY 141 Metadata.timeStamp DESC LIMIT 1""", 142 (itemId, branchId)) 143 144 item = cu.fetchone() 145 if item: 146 return item[0] 147 else: 148 return None151 """Follows a redirect one level and returns the location of the HTTP 302 redirect""" 152 url = urlparse.urlparse(url) 153 connection = HTTPConnection(url[1]) 154 connection.request("GET", url[2]) 155 request = connection.getresponse() 156 if request.status == 302: # header "Found:", might need more here 157 realUrl = request.getheader("Location") 158 else: 159 realUrl = urlparse.urlunparse(url) 160 return realUrl161163 shortDesc = "" 164 longDesc = "" 165 urls = [] 166 licenses = [] 167 categories = [] 168 language = "C" 169 version = None 170 source = "local" 171219 222173 if md: 174 self.shortDesc = md["shortDesc"] 175 self.longDesc = md["longDesc"] 176 self.urls = md["url"] 177 self.licenses = md["license"] 178 self.categories = md["category"] 179 if "version" in md: 180 self.version = md["version"] 181 if "source" in md and md["source"]: 182 self.source = md["source"] 183 if "language" in md: 184 self.language = md["language"]185187 return {"shortDesc": self.shortDesc, 188 "longDesc": self.longDesc, 189 "url": self.urls, 190 "license": self.licenses, 191 "category": self.categories, 192 "version": self.version, 193 "source": self.source, 194 "language": self.language}195197 return self.shortDesc198200 return self.longDesc201203 return self.urls204206 return self.licenses207209 return self.categories210212 return self.version213215 return self.source216218 return self.language224 if xmlDocStream: 225 # Most likely part of a test suite, although one may want a different 226 # plugin for xml metadata - a stream will work just fine 227 source = xmlDocStream 228 else: 229 source = urlopen('http://freshmeat.net/projects-xml/%s/%s.xml' % (troveName, troveName)) 230 231 try: 232 doc = xml.dom.minidom.parse(source) 233 metadata = {} 234 235 shortDesc = doc.getElementsByTagName("desc_short")[0] 236 if shortDesc.childNodes: 237 metadata["shortDesc"] = shortDesc.childNodes[0].data 238 239 longDesc = doc.getElementsByTagName("desc_full")[0] 240 if longDesc.childNodes: 241 metadata["longDesc"] = longDesc.childNodes[0].data 242 243 metadata["url"] = [] 244 urlHomepage = doc.getElementsByTagName("url_homepage")[0] 245 if urlHomepage.childNodes: 246 metadata["url"].append(resolveUrl(urlHomepage.childNodes[0].data)) 247 metadata["url"].append("http://freshmeat.net/projects/%s/" % troveName) 248 249 metadata["license"] = [] 250 metadata["category"] = [] 251 252 for node in doc.getElementsByTagName("trove_id"): 253 id = node.childNodes[0].data 254 if id in LicenseCategories: 255 name = LicenseCategories[id] 256 metadata["license"].append(name) 257 else: 258 name = TroveCategories[id] 259 if name.startswith('Topic ::'): 260 metadata["category"].append(name) 261 262 metadata["source"] = "freshmeat" 263 metadata["language"] = "C" 264 # Free the DOM - CNY-2674 265