def __init__(self, news_dir=None, config=None, max_news=None): """ Initiate object building :param news_dir: Path to directory containing templates :type news_dir: str :param config: Configuration object :type config: :class:`configParser` :param max_news: Number of news to get when displaying news (default :const:`News.MAX_NEWS`) :type max_news: int :raises SystemExit: If 'news_dir' is not a directory :raises SystemExit: If 'NEWS' section is not defined in :py:data:`manager.properties` :raises SystemExit: If 'news.dir' is not set in :py:data:`manager.properties` """ self.news_dir = None self.max_news = News.MAX_NEWS self.data = None if max_news: self.max_news = max_news if news_dir is not None: Utils.verbose("[news] 'news_dir' set from %s" % str(news_dir)) if not os.path.isdir(news_dir): Utils.error("News dir %s is not a directory." % news_dir) self.news_dir = news_dir if config is not None: if not config.has_section('NEWS'): Utils.error("Configuration has no 'NEWS' section.") elif not config.has_option('NEWS', 'news.dir'): Utils.error("Configuration has no 'news.dir' key.") else: self.news_dir = config.get('NEWS', 'news.dir') Utils.verbose("[news] 'news_dir' set to %s" % str(self.news_dir))
def _make_links(self, links=None, hard=False): """ Try to create the links (symbolic or hard) :param links: List of links to create :type links: list :param hard: Create hard link :type hard: boole :return: Number of created link(s) :rtype: int :raises SystemExit: If link(s) cannot be created """ if not links or not len(links): return 0 for slink, tlink in links: if not os.path.exists(tlink) and not os.path.islink(tlink): if Manager.get_simulate() and Manager.get_verbose(): Utils.verbose("Linking %s -> %s" % (tlink, os.path.relpath(slink, start=self.target))) else: try: if not Manager.get_simulate(): source_link = os.path.relpath(slink, start=self.target) if hard: os.link(source_link, tlink) else: os.symlink(source_link, tlink) except OSError as err: Utils.error("[%s] Can't create %slink %s: %s" % (self.manager.bank.name, 'hard ' if hard else 'sym', tlink, str(err))) self.add_link() return self.created_links
def _generate_dir_link(self, source=None, target=None, hard=False, fallback=None, requires=None, limit=0): """ Create a symbolic link between 'source' and 'target' for a directory :param source: Source directory to link :type source: str :param target: Destination directory name (relative to config param 'production.dir') :type target: str :param hard: Create hard link instead of symlink :type hard: bool (default False) :param fallback: Alternative source if source does not exist :type fallback: str :param requires: A required directory :type requires: str :param limit: Limit deepest search to `limit` depth, default 0, no limit :type limit: int :return: Number of created link(s) :rtype: int """ if not self._prepare_links(source=source, target=target, fallback=fallback, requires=requires, get_deepest=True, limit=limit): return 0 slink = os.path.join(self.source) tlink = os.path.join(self.target, self.manager.bank.name) self._make_links(links=[(slink, tlink)], hard=hard) if Manager.get_simulate() and Manager.get_verbose(): Utils.verbose("%s -> %s directory link done" % (self.target, self.source)) return self.created_links
def __init__(self, manager=None, name=None): """ Create the plugin object :param manager: Manager instance :type manager: :class:`biomajmanager.manager.Manager` :param name: Name of the plugin to load. [DEFAULT: load all plugins] :type name: String :raises SystemExit: If 'manager' arg is not given :raises SystemExit: If 'PLUGINS' section not found in :py:data:`manager.properties` :raises SystemExit: If 'plugins.dir' not set in :py:data:`manager.properties` :raises SystemExit: If 'plugins.list' not set in :py:data:`manager.properties` :raises SystemExit: If 'plugins.dir' does not exist """ self.pm = None self.name = None self.config = None self.manager = None if not manager: Utils.error("'manager' is required") self.manager = manager self.config = self.manager.config if not self.config.has_section('PLUGINS'): Utils.error("Can't load plugins, no section found!") if not self.config.has_option('MANAGER', 'plugins.dir'): Utils.error("plugins.dir not defined!") if not self.config.has_option('PLUGINS', 'plugins.list'): Utils.error("plugins.list is not defined!") if not os.path.isdir(self.config.get('MANAGER', 'plugins.dir')): Utils.error("Can't find plugins.dir") plugin_manager = PluginManager(directories_list=[self.config.get('MANAGER', 'plugins.dir')], categories_filter={Plugins.CATEGORY: BMPlugin}) plugin_manager.collectPlugins() self.pm = plugin_manager self.name = name user_plugins = [] # Load user wanted plugin(s) for plugin in self.config.get('PLUGINS', 'plugins.list').split(','): plugin.strip() # We need to lower the plugin name user_plugins.append(plugin) # This means that all plugins must inherits from BMPlugin for pluginInfo in plugin_manager.getPluginsOfCategory(Plugins.CATEGORY): Utils.verbose("[manager] plugin name => %s" % pluginInfo.name) if pluginInfo.name in user_plugins: if not pluginInfo.is_activated: Utils.verbose("[manager] plugin %s activated" % pluginInfo.name) plugin_manager.activatePluginByName(pluginInfo.name) setattr(self, pluginInfo.name, pluginInfo.plugin_object) pluginInfo.plugin_object.set_config(self.config) pluginInfo.plugin_object.set_manager(self.manager)
def generate_rss(self, rss_file=None, data=None): """ Generate RSS file from news :param rss_file: Path to file rss.xml :type rss_file: str :param data: Data to create RSS from :type data: dict data['news'] = { ... } :return: Boolean :rtype: bool :raises SystemExit: If 'news' key is not found in 'data' dict :raises SystemExit: If rss file cannot be opened """ if rss_file is not None: Utils.verbose("[rss] rss_file set to %s" % rss_file) self.rss_file = rss_file if data is None: data = self.get_news() elif 'news' not in data: Utils.error("Could not find 'news' key in data") if len(data['news']) == 0: Utils.warn("No data to display") return True items = [] try: for new in data['news']: item = Item(title=new['title'], description=new['text'], author=self.config.get('RSS', 'feed.author'), guid=Guid(self.config.get('RSS', 'feed.news.link') + '#' + str(new['item'])), pubDate=datetime.strptime(new['date'], self.config.get('RSS', 'rss.date.format') .replace('%%', '%')) ) items.append(item) feed = Feed(title=self.config.get('RSS', 'feed.title'), link=self.config.get('RSS', 'feed.link'), description=self.config.get('RSS', 'feed.description'), language=self.config.get('RSS', 'feed.language'), lastBuildDate=datetime.now(), items=items) if self.fh is None: self.fh = open(self.rss_file, 'w') Utils.uprint(feed.rss(), to=self.fh) if self.rss_file is not None: self.fh.close() except (NoOptionError, NoSectionError) as err: Utils.error("Option missing in config file: %s" % str(err)) except (OSError, IOError) as err: Utils.error("Can't open file %s: %s" % (self.rss_file, str(err))) return True
def __init__(self, rss_file=None, *args, **kwargs): """Initiate object building""" super(RSS, self).__init__(*args, **kwargs) self.rss_file = None self.fh = None if rss_file is not None: self.rss_file = rss_file if 'config' in kwargs: self.config = kwargs['config'] if self.config.has_option('RSS', 'rss.file') and self.rss_file is None: self.rss_file = self.config.get('RSS', 'rss.file') if self.rss_file is None: self.fh = sys.stdout Utils.verbose("[rss] rss_file set to %s" % str(self.rss_file))
def _generate_files_link(self, source=None, target=None, remove_ext=False): """ Links list of file from 'source' to 'target' directory. If remove_ext is set to True, then another link is created. This link is the same as the target link, without the file extension :param source: Source directory to link :type source: str :param target: Destination directory name (relative to config param 'production_dir') :type target: str :param remove_ext: Create another link of the file without the file name extension :type remove_ext: bool (default False) :return: Number of created link(s) :rtype: int """ if not self._prepare_links(source=source, target=target, get_deepest=True): return 0 # Get files in the source directory files = Utils.get_files(path=self.source) links = [] for ffile in files: # Source file link slink = os.path.join(self.source, ffile) tlink = os.path.join(self.target, ffile) links.append((slink, tlink)) if Manager.get_verbose(): Utils.verbose("[_generate_files_link] append slink %s" % slink) Utils.verbose("[_generate_files_link] append tlink %s" % tlink) # If asked to create another symbolic link without extension name if remove_ext: new_file = os.path.splitext(os.path.basename(ffile))[0] tlink = os.path.join(self.target, new_file) links.append((slink, tlink)) if Manager.get_verbose(): Utils.verbose("[_generate_files_link] [rm_ext=%s] append slink %s" % (str(remove_ext), slink)) Utils.verbose("[_generate_files_link] [rm_ext=%s] append tlink %s" % (str(remove_ext), tlink)) self._make_links(links=links) if Manager.get_simulate() and Manager.get_verbose(): Utils.verbose("%s -> %s file link done" % (self.target, self.source)) return self.created_links
def get_news(self, news_dir=None, reverse=True): """ Get the news to be displayed from the specific news.dir directory :param news_dir: Path to news directory :type news_dir: str :param reverse: Reverse list of news files, default True :type reverse: bool :return: news_files, list of news files found into 'news' directory :rtype: list :raises SystemExit: If path 'news_dir' does not exist :raises SystemExit: If 'news_dir' not set """ if news_dir is not None: if not os.path.isdir(news_dir): Utils.error("News dir %s is not a directory" % news_dir) else: self.news_dir = news_dir if not self.news_dir: Utils.error("Can't get news, no 'news.dir' defined.") news_data = [] item = 0 # shamefully copied from # http://stackoverflow.com/questions/168409/how-do-you-get-a-directory-listing-sorted-by-creation-date-in-python # get all entries in the directory w/ stats files = (os.path.join(self.news_dir, file) for file in os.listdir(self.news_dir)) #files = ((os.stat(path), path) for path in files) #files = ((stat[ST_CTIME], path) for stat, path in files if S_ISREG(stat[ST_MODE])) #for _, ifile in sorted(files): for ifile in sorted(files): with open(ifile) as new: Utils.verbose("[news] Reading news file %s ..." % ifile) (label, date, title) = new.readline().strip().split(':') text = '' for line in new.readlines(): text += line news_data.append({'label': label, 'date': date, 'title': title, 'text': text, 'item': item}) item += 1 new.close() if reverse: news_data.reverse() self.data = {'news': news_data} return self.data
def _prepare_links(self, source=None, target=None, get_deepest=False, fallback=None, requires=None, limit=0): """ Prepare stuff to create links :param source: Source path :type source: str :param target: Destination path :type target: str :param get_deepest: Try to find deepest directory(ies) from source :type get_deepest: bool :param fallback: Alternative source if source does not exist :type fallback: str :param requires: A required file or directory :type requires: str :param limit: Limit deepest search to `limit` depth, default 0, no limit :type limit: int :return: Boolean :rtype: bool :raises SystemExit: If 'source' or 'target' are None :raises SystemExit: If 'data.dir' not set in :py:data:`global.properties` :raises SystemExit: If 'production.dir' not set in :py:data:`manager.properties` :raises SystemExit: If 'target' directory cannot be created """ self._check_source_target_parameters(source=source, target=target) data_dir = self.bank_data_dir source = os.path.join(data_dir, source) target_dir = self.manager.config.get('MANAGER', 'production.dir') bank_name = self.manager.bank.name if requires is not None: if not os.path.exists(os.path.join(data_dir, requires)): Utils.warn("[%s] Can't create %s, requires param %s not here." % (bank_name, source, requires)) return False if not os.path.isdir(source): if fallback is None: if self.manager.get_verbose(): Utils.warn("[%s] %s does not exist" % (bank_name, source)) return False else: if self.manager.get_verbose(): Utils.verbose("[%s] %s does not exist. Fallback to %s" % (bank_name, source, fallback)) source = os.path.join(data_dir, fallback) if not os.path.isdir(source): if self.manager.get_verbose(): Utils.warn("[%s] Fallback %s does not exist" % (bank_name, source)) return False if get_deepest: source = Utils.get_deepest_dir(source, full=get_deepest, limit=limit) target = os.path.join(target_dir, target) # Check destination directory where to create link(s) if not os.path.exists(target) and not os.path.isdir(target): if Manager.get_simulate() and Manager.get_verbose(): Utils.verbose("[_prepare_links] [%s] Creating directory %s" % (bank_name, target)) else: try: if not Manager.get_simulate(): os.makedirs(target) except OSError as err: Utils.error("[%s] Can't create %s dir: %s" % (bank_name, target, str(err))) self.source = source self.target = target if Manager.get_verbose(): Utils.verbose("[prepare_links] source %s" % self.source) Utils.verbose("[prepare_links] target %s" % self.target) return True
def _clone_structure(self, source=None, target=None, remove_ext=False, limit=0): """ Create a directory structure from a source to a target point and link all files from source inside target :param source: Source directory to clone :type source: str :param target: Destination directory to create if does not exist :type target: str :param remove_ext: Create another link of the file without the file name extension :type remove_ext: bool :param limit: Limit subtree seach to value, default 0, no limit :tpye limit: int :return: True if structure cloning build OK, throws otherwise :rtype: bool :raise SystemExit: If error occurred during directory structure building """ self._check_source_target_parameters(source=source, target=target) # Check do_links.clone_dirs. As we want to recreate the same architecture as for the source, # we need to recreate the target because Utils.get_subtree removes the source path which contains # the target name target = os.path.join(target, source) source = os.path.join(self.bank_data_dir, source) subtrees = Utils.get_subtree(path=source, limit=limit) try: for subtree in subtrees: end_target = os.path.join(self.prod_dir, target, subtree) if not os.path.exists(end_target) and not os.path.isdir(end_target): if Manager.get_simulate() and Manager.get_verbose(): Utils.verbose("[_clone_structure] [%s] Creating directory %s" % (self.bank_name, end_target)) else: if not Manager.get_simulate(): os.makedirs(end_target) sub_files = Utils.get_files(path=os.path.join(source, subtree)) if len(sub_files) == 0: continue links = [] for ffile in sub_files: # Source file link slink = os.path.join(source, subtree, ffile) tlink = os.path.join(end_target, ffile) links.append((slink, tlink)) if Manager.get_verbose(): Utils.verbose("[_generate_files_link] append slink %s" % slink) Utils.verbose("[_generate_files_link] append tlink %s" % tlink) # If asked to create another symbolic link without extension name if remove_ext: new_file = os.path.splitext(os.path.basename(ffile))[0] tlink = os.path.join(end_target, new_file) links.append((slink, tlink)) if Manager.get_verbose(): Utils.verbose("[_generate_files_link] [rm_ext=%s] append slink %s" % (str(remove_ext), slink)) Utils.verbose("[_generate_files_link] [rm_ext=%s] append tlink %s" % (str(remove_ext), tlink)) # Set self.target for _make_links self.target = end_target self._make_links(links=links) except OSError as err: Utils.error("[%s] Can't create %s dir: %s (%s)" % (self.bank_name, end_target, str(err), os.access(end_target, os.W_OK))) return True