Meanwhile the design, and the server is going on I was working on the backend and I hope this will help Attached is the adaptation of apt2sql to work on opkg repositories opkg2sql.py. now at least it provided almost the same information as apt2sql I have succesfuly import the "all" architecture, but I have some problems with the arm4t due a bug on the version of python-sqlalchemy with UTF-8 chars, I have forced it to ascii and trying again.
Regarding apt-portal For those worried about package filtering and problems on automatic import the repo don't worry , as far as I can see (Joao please tell me if I'm wrong) the package import is not the information finally showing on description on the aplication showcase in fact app/app clasification/app info has to be introduced by "hand" with the web editor/adminstrator or directly in the table and you select wich package is related , on playdeb I see you can hide package classified them as int even if they are linked to any app. Well classifying all the thousand packages this way will be a little bit wasting of time so we will have to filter them previously to enter on the bd, there is a field called Section in the Package file of the repo that can be used for that propose I guess, filtering all packages marked as "base", "devel", etc, etc we must work on this list and look if we have to create another classes finally to manage the opkg packages instead of reusing the debian ones. BTW, I have not successfully yet classified a packages and make it apperar in the Uptades section from the demo playdeb application, they appears as linked and classified in the Packages tab I really noob on python, in fact this is my first python project (not counting the PoCoMoko attempt) I'm using my rusty php programing skills, but I think we can do great things with this apt-portal as base. -- David Reyes Samblas Martinez http://www.tuxbrain.com Open ultraportable & embedded solutions Openmoko, Openpandora, Arduino Hey, watch out!!! There's a linux in your pocket!!!
#!/usr/bin/python # # (C) Copyright 2009, TUXBRAIN S.L. - http://www.tuxbrain.com # -------------------------------------------------------------------- # Based on apt2sql.py from GetDeb Team - https://launchpad.net/~getdeb # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # -------------------------------------------------------------------- # # This file imports opkg packages from a repository to an sql database # control files. """ Usage: opkg2sql.py [--database mysql://user:passw...@localhost/apt2sql] \ [archive_root_url version arquitecture1[,arquetecture2,... ] Example: opkg2sql.py http://build.shr-project.org shr-unstable all """ # sqlalchemy uses a deprecated module import warnings warnings.simplefilter("ignore",DeprecationWarning) import sys import os import socket import urllib2 import zlib import gzip import tempfile import re from datetime import datetime from optparse import OptionParser from urllib2 import Request, urlopen, URLError, HTTPError from localaux import * from packages_model import * from dpkg_control import * from lockfile import * Log = Logger() def get_last_mofified_time(file_url): """ Returns the last mofidifed time for the specified url """ try: f = urllib2.urlopen(file_url) except HTTPError, e: Log.print_("Error %s : %s" % (e.code, file_url)) return None last_modified = f.info()['Last-Modified'] f.close() d_last_modified = datetime.strptime(last_modified, '%a, %d %b %Y %H:%M:%S %Z') return d_last_modified #Due opkg lacks of Release file and informed PackageList #this is a simplified version of the original apt2sql.py fuction #avoinding checkings done using those files #TODO Maybe some arch checkings can be done scaning directories directly from # the html returned of the archive_url/version/ikpg directory def import_repository(archive_url, version, architectures): """ Import a repository into the dabase """ # Now let's import the Packages file for each architecture # Some redundancies and fixes values where done to mantain the same # class structure of Package and PackageList # TODO opkg is also used in OpenWRT based distros so we must find a way # to discrimite the Origin value now is hardcoded to "OE" for arch in architectures: packages_file = "%s/%s/ipk/%s/Packages.gz" \ % (archive_url, version, arch) packagelist = \ PackageList.query.filter_by( \ version = version, \ architecture = arch).first() \ or \ PackageList( \ suite = version, \ version = version, \ component = version, \ origin = "OE", \ label = "", \ architecture = arch, \ description = "", \ date = get_last_mofified_time(packages_file)\ ) import_packages_file(archive_url, packagelist, packages_file, version) packagelist = None def import_packages_file(archive_url, packagelist, packages_file, distro_version): """ Imports packages information from a packages file """ Log.log("Downloading %s" % packages_file) try: f = urllib2.urlopen(packages_file) except HTTPError, e: session.rollback() # Rollback the suite insert print "%s : %s" % (e.code, packages_file) return -1 data = f.read() f.close() # Decompress the file contents tmpfile = tempfile.NamedTemporaryFile(delete = False) tmpfile.write(data) tmpfile.close() f = gzip.open(tmpfile.name) data = f.read() f.close() os.unlink(tmpfile.name) keep_packages_list = [] # info from packages loaded from the file for package_info in data.split("\n\n"): if (not package_info or package_info.replace('\n','') == '') : # happens at the end of the file continue control = DebianControlFile(contents = package_info) package_name = control['Package'] source = control['Source'] version = control['Version'] architecture = control['Architecture'] description = control['Description'].encode('ascii','ignore') homepage = control['HomePage'] package = Package.query.filter_by( \ package = package_name, \ version = version, \ architecture = architecture).first() if not package: # New package opk_filename = "%s/%s/ipk/%s/%s" % (archive_url, distro_version, architecture, control['Filename']) last_modified = get_last_mofified_time(opk_filename) Log.print_("Inserting %s %s %s %s" % (package_name, source \ , version, architecture)) package = Package( package = package_name \ , source = source \ , version = version \ , architecture = architecture \ , last_modified = last_modified \ , description = description \ , homepage = homepage \ ) # Create relation if needed if not packagelist in package.lists: Log.print_("Including %s -> %s" % (package, packagelist)) package.lists.append(packagelist) # Add to in memory list to skip removal keep_packages_list.append("%s %s %s" % (package.package, package.version, package.architecture)) # Remove all relations to packages which were not imported # on the loop above must_remove = [] for package in packagelist.packages: list_item = "%s %s %s" % (package.package, package.version \ , package.architecture) if list_item in keep_packages_list: keep_packages_list.remove(list_item) else: Log.print_("Removing %s" % `package`) must_remove.append(package) for package in must_remove: packagelist.packages.remove(package) session.commit() del data def main(): parser = OptionParser() parser.add_option("-d", "--database", action = "store", type="string", dest="database", help = "specificy the database URI\n\n" \ "Examples\n\n" \ " mysql://user:passw...@localhost/apt2sql" \ " sqlite:///apt2sql.db" \ ) parser.add_option("-f", "--force-rpool", action = "store_true", dest="rpool", default=False, help = "force to use rpool path instead of pool") parser.add_option("-q", "--quiet", action = "store_false", dest="verbose", default=True, help = "don't print status messages to stdout") parser.add_option("-r", "--recreate-tables", action = "store_true", dest="recreate_tables", default=False, help = "recreate db tables") parser.add_option("-s", "--sql-echo", action = "store_true", dest="sql_echo", default=False, help = "echo the sql statements") (options, args) = parser.parse_args() db_url = options.database or "sqlite:///apt2sql.db" if len(args) < 2: print "Usage: %s " \ "archive_root_url suite [component1[, component2] ]" \ % os.path.basename(__file__) sys.exit(2) archive_url = args[0] version = args[1] architectures = None if len(args) > 2: architectures = args[2].split(",") Log.verbose = options.verbose try: lock = LockFile("opkg2sql") except LockFile.AlreadyLockedError: Log.log("Unable to acquire lock, exiting") return # We set the database engine here metadata.bind = db_url metadata.bind.echo = options.sql_echo setup_all(True) if options.recreate_tables: drop_all() setup_all(True) import_repository(archive_url, version, architectures) if __name__ == '__main__': try: main() except KeyboardInterrupt: print 'User requested interrupt' sys.exit(1)
_______________________________________________ Openmoko community mailing list community@lists.openmoko.org http://lists.openmoko.org/mailman/listinfo/community