+#!/usr/bin/python
+# Copyright (c) 2016 Samsung Electronics Co., Ltd
+#
+# Licensed under the Flora License, Version 1.1 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://floralicense.org/license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Contributors:
+# - S-Core Co., Ltd
+
import logging
+import requests
+import re
from operator import itemgetter
+from tic.utils.rpmmisc import meetRequireVersion
def make_view_data(pkg_group):
logger = logging.getLogger(__name__)
+ def _select_provide_rpm(capability, require):
+ provide_list = []
+ if require.get('ver') is not None:
+ for provide in capability:
+ ver_data = provide['data']
+ if not ver_data.get('ver'):
+ ver_data = pkg_dict.get(provide['name']).get('version')
+ if meetRequireVersion(require, ver_data):
+ provide_list.append(provide)
+ else:
+ provide_list = capability
+
+ result = []
+ for provide in provide_list:
+ result.append(pkg_dict[provide['name']])
+
+ return result
+
def set_meta_require(meta_info):
meta_nodes = meta_info.get('nodes')
+ children = set()
for child_meta in meta_nodes:
- refer_count[child_meta['id']] += 1
set_meta_require(child_meta)
-
- req_list = pkg_dict[meta_info['text']].get('requires')
- if req_list is not None:
- for req in req_list:
- if provides.get(req['name']):
- provide_info = provides[req['name']][0]
- pkg_name = provide_info['name']
- if 'meta' not in pkg_dict[pkg_name]:
- child_pkg = pkg_dict[pkg_name]
- meta_nodes.append(make_node(child_pkg))
- refer_count[child_pkg['id']] += 1
+ children.add(child_meta['metaname'])
+
+ duplicate = set()
+ pkg_info = pkg_dict[meta_info['metaname']]
+ for dep_tag in ['requires', 'recommends', 'suggests']:
+ if pkg_info.get(dep_tag):
+ for req in pkg_info.get(dep_tag):
+ targets = []
+ if req['name'] in provides:
+ targets = _select_provide_rpm(provides[req['name']], req)
+ elif req['name'] in files:
+ for fname in files[req['name']]:
+ targets.append(pkg_dict.get(fname))
+ elif req['name'] in pkg_dict:
+ targets.append(pkg_dict.get(req['name']))
else:
- # The meta-pkg of the other group are excluded.
# the dependent package does not exist.
pass
-
- def make_node(pkg_info):
- return dict(id=pkg_info['id'], text=pkg_info['name'], nodes=[])
-
+
+ for pkg in targets:
+ # The meta-pkg of the other group are excluded.
+ if pkg['name'] not in duplicate:
+ refer_count[pkg['id']] += 1
+ duplicate.add(pkg['name'])
+
+ if pkg.get('meta'):
+ if not pkg['name'] in children:
+ meta_nodes.append(make_linked_meta_node(pkg['name'], pkg['summary'], meta_info['category']))
+ else:
+ meta_nodes.append(make_node(pkg, meta_info.get('category')))
+ # Added 'zz' to non meta-package because they are to be listed last
+ meta_nodes = sorted(meta_nodes, key = lambda k: 'aa'+k['metaname'] if 'metaname' in k else 'zz'+k['text'])
+ meta_info['nodes'] = meta_nodes
+
+ if meta_info['metaname'] =='building-blocks-sub2-Preset_iot-examples-3_RPI3_headless_devboard':
+ print(pkg_info)
+ def make_node(pkg_info, category=None):
+ n = dict(text=pkg_info['name'], nodes=[])
+ if category: n['category'] = category
+ return n
+ def make_meta_node(pkgname, viewtext):
+ return dict(text=viewtext, metaname=pkgname, nodes=[])
+ def make_linked_meta_node(pkgname, viewtext, cat):
+ return dict(text='<i>'+viewtext+'</i>', metaname=pkgname, nodes=[], category=cat)
+ def is_blank_ui_meta_node(pkgname):
+ return (pkgname[-8:-2] == '__UI__')
+ def handle_ui_meta_node(tag, node):
+ node['selectable'] = False
+ node['hideCheckbox'] = True
+ if tag == 'BR' or tag == 'br':
+ node['text'] = ''
+ elif tag == 'HR' or tag == 'hr':
+ node['text'] = '<hr style="margin-bottom: 0px; margin-top: 0px; border-style: inset; border-width: 3px" />'
+ elif tag == 'SD' or tag == 'sd':
+ node['text'] = ''
+ node['backColor'] = '#101010'
+ elif tag == 'SM' or tag == 'sm':
+ # Keep the summary text
+ node['text'] = node['text']
+ elif tag == 'HT' or tag == 'ht':
+ # Keep the summary (TODO: verify the usage of HTML tags.)
+ node['text'] = node['text'] # Do we need conversion?
+ else:
+ node['text'] = ''
+ return node
+ def handle_description(node):
+ if 'metaname' in node:
+ name = node['metaname']
+ pkg_info = pkg_dict[name]
+ desc = pkg_info.get('description')
+ if desc[0:10] == '__KS_URL__':
+ logger.info("Processing "+name+" for its description: "+pkg_info.get('description'))
+ # Extract URL from __KS_URL__
+ ksURL = desc[11:].splitlines()[0].strip()
+ # Omit the first line with __KS_URL__ from showing.
+ pkg_info['description'] = desc[len(desc.splitlines(True)[0]):]
+
+ # Search for filename if directory is given
+ # e.g., Convert http://a.com/a/ to https://a.com/a/blahblah.ks
+ # Works for file-indexing html
+ if ksURL[-3:].lower() != ".ks":
+ error = 0
+ if ksURL[-1:] != "/":
+ ksURL += "/"
+ r = requests.get(ksURL)
+ if r.status_code == requests.codes.ok:
+ m = re.search('>([^<]*\\.ks)\\s*<', r.text)
+ else:
+ error = 1
+ if error == 0 and not m.group(1):
+ m = re.search('"([^"]*\\.ks)\\s*"', r.text)
+ if not m.group(1):
+ m = re.search("'([^']*\\.ks)\\s*'", r.text)
+ if not m.group(1):
+ error = 1
+ if error == 1:
+ node['icon'] = 'glyphicon glyphicon-remove-sign'
+ node['tooltip'] = 'Cannot find image base from' + ksURL
+ return node
+ ksURL += m.group(1)
+ node['tooltip'] = 'Image base from '+ksURL
+ node['ks'] = ksURL
+ elif desc[0:10] == '__EXPAND__':
+ # Omit the first line with __EXPAND__ from showing.
+ pkg_info['description'] = desc[len(desc.splitlines(True)[0]):]
+ node['state'] = { 'expanded': True }
+ return node
+
# view_data for tree view on web-ui
view_data = []
# temporary dictionary for referencing meta
pkg_dict = pkg_group['pkg_dict']
provides = pkg_group['provides']
+ files = pkg_group['files']
refer_count = [0] * len(pkg_dict)
- # sort by pkg_name ([0]:name, [1]:root, [2]:sub1)
+ # sort meta-pkg by pkt_name in ascending order
meta_info = pkg_group.get('meta_info')
meta_info['root'] = sorted(meta_info['root'], key=itemgetter(0))
meta_info['sub1'] = sorted(meta_info['sub1'], key=itemgetter(0))
meta_info['sub2'] = sorted(meta_info['sub2'], key=itemgetter(0))
+ # make category rpms
+ category_dict = {}
+ if meta_info.get('category'):
+ for category in meta_info['category']:
+ c_rpm = pkg_dict[category[0]]
+ if hasattr(c_rpm.get('suggests'), '__iter__'):
+ for suggest in c_rpm.get('suggests'):
+ category_dict[suggest['name']] = category[1]
+ else:
+ logger.info(c_rpm.get('suggests'))
+ logger.info(c_rpm.get('name'))
+
+
# make tree of meta
for root in meta_info['root']:
- root_node = make_node(pkg_dict[root[0]])
+ root_node = make_meta_node(root[0], root[1])
view_ref[root[0]] = root_node
+ if root[0] in category_dict:
+ root_node['category'] = category_dict[root[0]]
+ if is_blank_ui_meta_node(root[0]):
+ name = root[0]
+ sub1_node = handle_ui_meta_node(name[-2:], root_node)
+ root_node = handle_description(root_node)
view_data.append(root_node)
for sub1 in meta_info['sub1']:
- sub1_node = make_node(pkg_dict[sub1[0]])
+ sub1_node = make_meta_node(sub1[0], sub1[2])
view_ref[sub1[0]] = sub1_node
+ if is_blank_ui_meta_node(sub1[0]):
+ name = sub1[0]
+ sub1_node = handle_ui_meta_node(name[-2:], sub1_node)
+ sub1_node = handle_description(sub1_node)
# search root
if sub1[1] in view_ref:
# add to root node
+ if 'category' in view_ref[sub1[1]] and view_ref[sub1[1]]['category']:
+ sub1_node['category'] = view_ref[sub1[1]]['category']
view_ref[sub1[1]]['nodes'].append(sub1_node)
else:
# If root-meta does not exist, sub1 is added to top-level
view_data.append(sub1_node)
for sub2 in meta_info['sub2']:
- sub2_node = make_node(pkg_dict[sub2[0]])
+ sub2_node = make_meta_node(sub2[0], sub2[3])
view_ref[sub2[0]] = sub2_node
+ if is_blank_ui_meta_node(sub2[0]):
+ name = sub2[0]
+ sub1_node = handle_ui_meta_node(name[-2:], sub2_node)
+ sub2_node = handle_description(sub2_node)
# search sub1
if sub2[2] in view_ref:
+ if 'category' in view_ref[sub2[2]] and view_ref[sub2[2]]['category']:
+ sub2_node['category'] = view_ref[sub2[2]]['category']
view_ref[sub2[2]]['nodes'].append(sub2_node)
# search root
elif sub2[1] in view_ref:
+ if view_ref[sub2[1]]['category']:
+ sub2_node['category'] = view_ref[sub2[1]]['category']
# If sub1-meta does not exist, sub2 is added to child of root-meta
view_ref[sub2[1]]['nodes'].append(sub2_node)
else:
# configure meta dependency tree (requires)
for meta_pkg in view_data:
- refer_count[meta_pkg['id']] += 1
set_meta_require(meta_pkg)
-
+
#The remaining rpms are grouped into a MISC tree
misc_info = {}
- misc_info['text'] = 'MISC'
+ misc_info['text'] = 'Advanced (individual packages)'
misc_info['nodes'] = []
for k, v in pkg_dict.iteritems():
- # Pkg is not referenced from Meta-pkg
- if refer_count[v['id']] == 0:
+ # Add ALL non-block packages
+ if v['name'][0:15] != 'building-blocks':
misc_info['nodes'].append(make_node(v))
-
- logger.info('meta: %d, misc: %d', len(view_ref), len(misc_info['nodes']))
-
+ misc_info['nodes'] = sorted(misc_info['nodes'], key = lambda k: k['metaname'] if 'metaname' in k else k['text'])
+
view_data.append(misc_info)
-
+ logger.info('meta: %d, misc: %d', len(view_ref), len(misc_info['nodes']))
return view_data
-