Index: sitescripts/subscriptions/subscriptionParser.py |
=================================================================== |
--- a/sitescripts/subscriptions/subscriptionParser.py |
+++ b/sitescripts/subscriptions/subscriptionParser.py |
@@ -20,49 +20,49 @@ from urlparse import urlparse |
from StringIO import StringIO |
from ConfigParser import SafeConfigParser |
from sitescripts.utils import get_config, cached |
def warn(message): |
print >> sys.stderr, message |
class Subscription(object): |
- def defineProperty(propName, isSimple = False): |
- if isSimple: |
- def setProperty(dict, propName, value): |
- dict[propName] = value |
+ def define_property(propName, readonly=False): |
+ if readonly: |
+ return property(lambda self: self._data[propName]) |
+ else: |
+ def set_property(self, value): |
+ self._data[propName] = value |
- return property(lambda self: self._data[propName], lambda self, value: setProperty(self._data, propName, value)) |
- else: |
- return property(lambda self: self._data[propName]) |
+ return property(lambda self: self._data[propName], set_property) |
- name = defineProperty("name", True) |
- type = defineProperty("type", True) |
- maintainer = defineProperty("maintainer", True) |
- email = defineProperty("email", True) |
- specialization = defineProperty("specialization", True) |
- languages = defineProperty("languages", True) |
- recommendation = defineProperty("recommendation") |
- deprecated = defineProperty("deprecated") |
- unavailable = defineProperty("unavailable") |
- catchall = defineProperty("catchall") |
- supplements = defineProperty("supplements") |
- supplemented = defineProperty("supplemented") |
- variants = defineProperty("variants") |
- homepage = defineProperty("homepage", True) |
- contact = defineProperty("contact", True) |
- forum = defineProperty("forum", True) |
- faq = defineProperty("faq", True) |
- blog = defineProperty("blog", True) |
- changelog = defineProperty("changelog", True) |
- policy = defineProperty("policy", True) |
- digest = defineProperty("digest", True) |
- digestDay = defineProperty("digestDay", True) |
+ name = define_property("name") |
+ type = define_property("type") |
+ maintainer = define_property("maintainer") |
+ email = define_property("email") |
+ specialization = define_property("specialization") |
+ languages = define_property("languages") |
+ recommendation = define_property("recommendation", readonly=True) |
+ deprecated = define_property("deprecated", readonly=True) |
+ unavailable = define_property("unavailable", readonly=True) |
+ catchall = define_property("catchall", readonly=True) |
+ supplements = define_property("supplements", readonly=True) |
+ supplemented = define_property("supplemented", readonly=True) |
+ variants = define_property("variants", readonly=True) |
+ homepage = define_property("homepage") |
+ contact = define_property("contact") |
+ forum = define_property("forum") |
+ faq = define_property("faq") |
+ blog = define_property("blog") |
+ changelog = define_property("changelog") |
+ policy = define_property("policy") |
+ digest = define_property("digest") |
+ digestDay = define_property("digestDay") |
- def __init__(self, filePath, data): |
+ def __init__(self, path, data): |
self._data = { |
'name': None, |
'type': 'ads', |
'maintainer': None, |
'email': None, |
'specialization': None, |
'languages': None, |
'deprecated': False, |
@@ -77,31 +77,31 @@ class Subscription(object): |
'forum': None, |
'faq': None, |
'blog': None, |
'changelog': None, |
'policy': None, |
'digest': 'weekly', |
'digestDay': 'wed', |
} |
- self.parse(filePath, data) |
+ self.parse(path, data) |
- def parse(self, filePath, data): |
+ def parse(self, path, data): |
mandatory = [['email'], ['specialization'], ['homepage', 'contact', 'forum', 'faq', 'blog']] |
- weekDays = { |
+ weekdays = { |
'son': 0, |
'mon': 1, |
'tue': 2, |
'wed': 3, |
'thu': 4, |
'fri': 5, |
'sat': 6, |
} |
- self.name = re.sub(r'\.\w+$', r'', os.path.basename(filePath)) |
+ self.name = re.sub(r'\.\w+$', r'', os.path.basename(path)) |
for line in data: |
if not re.search(r'\S', line): |
continue |
parts = line.split('=', 1) |
key = parts[0].strip() |
if len(parts) > 1: |
@@ -109,152 +109,151 @@ class Subscription(object): |
else: |
value = '' |
try: |
# Might be a simple attribute - try setting the value |
if not hasattr(self, key): |
raise Exception() |
- oldValue = getattr(self, key) |
+ oldvalue = getattr(self, key) |
setattr(self, key, value) |
if value == '': |
- warn('Empty value given for attribute %s in %s' % (key, filePath)) |
- if oldValue != None and key != 'name' and key != 'type' and key != 'digest' and key != 'digestDay': |
- warn('Value for attribute %s is duplicated in %s' % (key, filePath)) |
+ warn('Empty value given for attribute %s in %s' % (key, path)) |
+ if oldvalue != None and key != 'name' and key != 'type' and key != 'digest' and key != 'digestDay': |
+ warn('Value for attribute %s is duplicated in %s' % (key, path)) |
except: |
# Not a simple attribute, needs special handling |
if key == 'supplements': |
if value == '': |
- warn('Empty value given for attribute %s in %s' % (key, filePath)) |
+ warn('Empty value given for attribute %s in %s' % (key, path)) |
self.supplements.append(value) |
elif key == 'list' or key == 'variant': |
if value == '': |
- warn('Empty value given for attribute %s in %s' % (key, filePath)) |
+ warn('Empty value given for attribute %s in %s' % (key, path)) |
keywords = { |
'recommendation': False, |
'catchall': False, |
'complete': False, |
} |
regexp = re.compile(r'\s*\[((?:\w+,)*\w+)\]$') |
match = re.search(regexp, value) |
if match: |
value = re.sub(regexp, r'', value) |
for keyword in match.group(1).split(','): |
keyword = keyword.lower() |
if keyword in keywords: |
keywords[keyword] = True |
else: |
- warn('Unknown keyword %s given for attribute %s in %s' % (keyword, key, filePath)) |
+ warn('Unknown keyword %s given for attribute %s in %s' % (keyword, key, path)) |
(name, url) = (self.name, value) |
if key == 'variant': |
match = re.search(r'(.+?)\s+(\S+)$', value) |
if match: |
(name, url) = (match.group(1), match.group(2)); |
else: |
- warn('Invalid variant format in %s, no name given?' % (filePath)) |
- if not _validateURL(url): |
- warn('Invalid list URL %s given in %s' % (url, filePath)) |
+ warn('Invalid variant format in %s, no name given?' % (path)) |
+ if not _validate_URL(url): |
+ warn('Invalid list URL %s given in %s' % (url, path)) |
self.variants.append([name, url, keywords['complete']]) |
if keywords['recommendation']: |
self._data['recommendation'] = self._data['variants'][-1] |
self._data['catchall'] = keywords['catchall'] |
elif key == 'deprecated' or key == 'unavailable': |
self._data[key] = True |
else: |
- warn('Unknown attribute %s in %s' % (key, filePath)) |
+ warn('Unknown attribute %s in %s' % (key, path)) |
if key == 'languages': |
settings = get_settings() |
- languageNames = [] |
+ languagenames = [] |
for language in value.split(','): |
if settings.has_option('languages', language): |
- languageNames.append(settings.get('languages', language)) |
+ languagenames.append(settings.get('languages', language)) |
else: |
- warn('Unknown language code %s in %s' % (language, filePath)) |
- self._data['languageSpecialization'] = ', '.join(languageNames) |
+ warn('Unknown language code %s in %s' % (language, path)) |
+ self._data['languageSpecialization'] = ', '.join(languagenames) |
if 'languageSpecialization' in self._data: |
if self.specialization != None: |
self.specialization += ", " + self._data['languageSpecialization'] |
else: |
self.specialization = self._data['languageSpecialization'] |
del self._data['languageSpecialization'] |
- for mandatorySet in mandatory: |
+ for group in mandatory: |
found = False |
- for key in mandatorySet: |
+ for key in group: |
if self._data[key] != None: |
found = True |
if not found: |
- str = ", ".join(mandatorySet) |
- warn('None of the attributes %s present in %s' % (str, filePath)) |
+ str = ", ".join(group) |
+ warn('None of the attributes %s present in %s' % (str, path)) |
if len(self.variants) == 0: |
- warn('No list locations given in %s' % (filePath)) |
+ warn('No list locations given in %s' % (path)) |
if self.type != 'ads' and self.type != 'other': |
- warn('Unknown type given in %s' % (filePath)) |
+ warn('Unknown type given in %s' % (path)) |
if self.digest != 'daily' and self.digest != 'weekly': |
- warn('Unknown digest frequency given in %s' % (filePath)) |
- if not self.digestDay[0:3].lower() in weekDays: |
- warn('Unknown digest day given in %s' % (filePath)) |
+ warn('Unknown digest frequency given in %s' % (path)) |
+ if not self.digestDay[0:3].lower() in weekdays: |
+ warn('Unknown digest day given in %s' % (path)) |
self.digestDay = 'wed' |
- self.digestDay = weekDays[self.digestDay[0:3].lower()] |
+ self.digestDay = weekdays[self.digestDay[0:3].lower()] |
if self.recommendation != None and (self.languages == None or not re.search(r'\S', self.languages)): |
- warn('Recommendation without languages in %s' % (filePath)) |
+ warn('Recommendation without languages in %s' % (path)) |
if len(self.supplements) == 0: |
for [name, url, complete] in self.variants: |
if complete: |
- warn('Variant marked as complete for non-supplemental subscription in %s' % (filePath)) |
+ warn('Variant marked as complete for non-supplemental subscription in %s' % (path)) |
break |
self.variants.sort(key=lambda variant: (self.recommendation == variant) * 2 + variant[2], reverse=True) |
-def parseFile(filePath, data): |
- return Subscription(filePath, data) |
+def parse_file(path, data): |
+ return Subscription(path, data) |
-def calculateSupplemented(lists): |
- for fileData in lists.itervalues(): |
- for supplements in fileData.supplements: |
+def calculate_supplemented(lists): |
+ for filedata in lists.itervalues(): |
+ for supplements in filedata.supplements: |
if supplements in lists: |
- lists[supplements].supplemented.append(fileData) |
+ lists[supplements].supplemented.append(filedata) |
else: |
- warn('Subscription %s supplements an unknown subscription %s' % (fileData.name, supplements)) |
+ warn('Subscription %s supplements an unknown subscription %s' % (filedata.name, supplements)) |
@cached(60) |
def get_settings(): |
repo = os.path.abspath(get_config().get('subscriptions', 'repository')) |
- settingsData = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'settings')]) |
+ settingsdata = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'settings')]) |
settings = SafeConfigParser() |
- settings.readfp(codecs.getreader('utf8')(StringIO(settingsData))) |
+ settings.readfp(codecs.getreader('utf8')(StringIO(settingsdata))) |
return settings |
def readSubscriptions(): |
repo = os.path.abspath(get_config().get('subscriptions', 'repository')) |
data = subprocess.check_output(['hg', 'archive', '-R', repo, '-r', 'default', '-t', 'tar', '-I', os.path.join(repo, '*.subscription'), '-']) |
result = {} |
- tarFile = tarfile.open(mode='r:', fileobj=StringIO(data)) |
- for fileInfo in tarFile: |
- fileData = parseFile(fileInfo.name, codecs.getreader('utf8')(tarFile.extractfile(fileInfo))) |
- if fileData.unavailable: |
- continue |
+ with tarfile.open(mode='r:', fileobj=StringIO(data)) as archive: |
+ for fileinfo in archive: |
+ filedata = parse_file(fileinfo.name, codecs.getreader('utf8')(archive.extractfile(fileinfo))) |
+ if filedata.unavailable: |
+ continue |
- if fileData.name in result: |
- warn('Name %s is claimed by multiple files' % (fileData.name)) |
- result[fileData.name] = fileData |
- tarFile.close() |
+ if filedata.name in result: |
+ warn('Name %s is claimed by multiple files' % (filedata.name)) |
+ result[filedata.name] = filedata |
- calculateSupplemented(result) |
+ calculate_supplemented(result) |
return result |
def getFallbackData(): |
repo = os.path.abspath(get_config().get('subscriptions', 'repository')) |
- redirectData = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'redirects')]) |
- goneData = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'gone')]) |
- return (redirectData, goneData) |
+ redirectdata = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'redirects')]) |
+ gonedata = subprocess.check_output(['hg', '-R', repo, 'cat', '-r', 'default', os.path.join(repo, 'gone')]) |
+ return (redirectdata, gonedata) |
-def _validateURL(url): |
- parseResult = urlparse(url) |
- return (parseResult.scheme == 'http' or parseResult.scheme == 'https') and parseResult.netloc != '' |
+def _validate_URL(url): |
+ parse_result = urlparse(url) |
+ return parse_result.scheme in ('http', 'https') and parse_result.netloc != '' |