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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
""" Keryx library """
# Imports
import logging
import os.path
import platform
import socket
import re
import sys
# Append libkeryx to path so anything can use it's modules
sys.path.append(os.path.dirname(__file__))
import urlgrabber
try:
from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
from sqlalchemy.orm import sessionmaker, relation, backref
from sqlalchemy.ext.declarative import declarative_base
except:
logging.error('SQLAlchemy is not installed. Visit www.sqlalchemy.org to ' \
'get the latest version.')
sys.exit(1)
# Library metadata
__appname__ = 'libkeryx'
__version__ = '1.0.0'
__date__ = '2009-06-15'
__author__ = 'Chris Oliver <excid3@gmail.com>, Buran Ayuthia <the.ayuthias@gmail.com>'
__url__ = 'http://keryxproject.org'
definitions = []
Base = declarative_base()
class Definition:
"""Never should be instanciated itself"""
def __init__(self, project, db_filename):
# Create the project directores if they do not exist
# Set the project to be used for other methods in
# this class
self.project = project
# Create the directory to store the downloads. Downloads
# for all projects will be stored in the same folder to
# prevent multiple downloads of the same file
self.downloads_dir = 'downloads/'
#if not os.path.exists(self.downloads_dir):
# os.mkdir(self.downloads_dir)
# Set the database filename
sql_filename = 'sqlite:///' + db_filename
# Create engine
self.engine = create_engine(sql_filename)
# global application scope. create Session class, engine
Session = sessionmaker()
# connect to the database
self.connection = self.engine.connect()
# bind an individual Session to the connection
self.session = Session(bind=self.connection)
# create all the tables
Base.metadata.create_all(self.engine)
# Create the database tables
logging.info("Initializing shared database tables...")
# Call the overridden function of the actual definition
self.on_init(self.project)
def __del__(self):
"""Definition destructor
Commits all changes and closes database connection
"""
self.session.commit()
self.session.close()
def on_init(self, project):
"""Should be overridden in definition"""
pass
def create(self):
"""Create a new Keryx database"""
# Query to see if project exists already
found = self.session.query(Project).filter(Project.name==self.project).all()
if found:
logging.error("Project already exists")
return False
logging.info("Creating project...")
try:
self.on_create()
except Exception, e:
logging.error(e)
def on_create(self):
"""Should be overridden in definition"""
pass
def update_internet(self):
"""Should be overridden in definition"""
pass
# These are the mapper classes to help access the database easier.
# Only define the tables that are generic to all definitions not
# the definition-specific ones.
class Project(Base):
"""Table for storing projects"""
__tablename__ = "projects"
id = Column(Integer, primary_key=True)
name = Column(String)
architecture = Column(String)
hostname = Column(String)
definition = Column(String)
version = Column(String)
def __init__(self, name, architecture, hostname, definition, version):
self.name = name
self.architecture = architecture
self.hostname = hostname
self.definition = definition
self.version = version
def __repr__(self):
return "<Project('%s','%s','%s','%s','%s')>" % (self.name,
self.architecture, self.hostname, self.definition, self.version)
###################
# Functions
###################
def _initialize():
""" Initializes OS definitions """
global definitions
path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'definitions')
sys.path.append(path) # Append the path so that we can import from it
files = os.listdir(path)
test = re.compile('', re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
definitions = map(__import__, moduleNames)
logging.debug("Loaded %i definitions" % len(definitions))
def get_definition(project, db_filename):
""" Finds the correct definition based on the currrent OS or file """
# TODO: Make this dynamic
# Check the "keryx" table for the definition name and version
# Then load accordingly.
# For now we are going to hardcode this to load dpkg definitions
# TODO: Read the definition_version string from the file (if exists)
# If it does, compare versions with the __supports__ using
# getattr(definitions[0], '__supports__')
return getattr(definitions[0], definitions[0].__name__)(project, db_filename)
#############
# Entry point
#############
_initialize()
|