def new_entry(argv): if len(argv) < 1: die(messages.missing_params.format("--new-entry")) blog_configuration = get_blog_configuration() content = {"authors": "", "tags": "", "categories": "", "title":argv[0]} try: wd = os.listdir(os.getcwd()) except OSError: die(messages.cannot_read_in.format(os.getcwd())) date = datetime.datetime.now() entry = dict() raw_entry_date = datetime.datetime.now() try: entry["ID"] = max([ int(filename.split("__")[0]) for filename in yield_entries_content()]) + 1 except ValueError: entry["ID"] = 1 entry["title"] = argv[0] entry["month"] = raw_entry_date.month entry["year"] = raw_entry_date.year entry["day"] = raw_entry_date.day entry["hour"] = raw_entry_date.hour entry["minute"] = raw_entry_date.minute entry["date"] = raw_entry_date entry_date = str(date.month)+'-'+str(date.day)+'-'+str(date.year)+'-'+str(date.hour)+'-'+str(date.minute) output_filename = os.getcwd()+'/entries/'+str(entry["ID"])+"__"+entry_date+"__"+entry["title"].replace(' ','_') stream = codecs.open(output_filename, 'w', encoding="utf-8") if len(argv) == 1: output = yaml.dump(content, default_flow_style=False, allow_unicode=True) + "---VENC-BEGIN-PREVIEW---\n---VENC-END-PREVIEW---\n" else: try: output = open(os.getcwd()+'/templates/'+argv[1], 'r').read().replace(".:GetEntryTitle:.", argv[0]) except FileNotFoundError as e: die(messages.file_not_found.format(os.getcwd()+"/templates/"+argv[1])) stream.write(output) stream.close() try: command = [arg for arg in blog_configuration["text_editor"].split(' ') if arg != ''] command.append(output_filename) subprocess.call(command) except FileNotFoundError: die(messages.unknown_command.format(blog_configuration["text_editor"])) notify(messages.entry_written)
def remote_copy(argv=list()): blog_configuration = get_blog_configuration() try: ftp = ftplib.FTP(blog_configuration["ftp_host"]) ftp.encoding = 'latin-1' except socket.gaierror as e: die(str(e)) username = input("VenC: " + messages.username) user_passwd = getpass.getpass(prompt="VenC: " + messages.user_passwd) try: ftp.login(user=username, passwd=user_passwd) ftp.cwd(blog_configuration["path"]["ftp"]) notify(messages.clean_ftp_directory) ftp_clean_destination(ftp) notify(messages.copy_to_ftp_directory) ftp_export_recursively(os.getcwd() + "/blog", ftp) except TimeoutError as e: die(str(e)) except ftplib.error_perm as e: die(str(e), color="YELLOW")
def install_theme(argv): if len(argv) < 1: print_themes() return blog_configuration = get_blog_configuration() if blog_configuration == None: notify(messages.no_blog_configuration) return new_folder_name = "theme "+str(datetime.datetime.now()).replace(':','-') try: shutil.move("theme", new_folder_name) except: pass try: shutil.copytree(os.path.expanduser("~")+"/.local/share/VenC/themes/"+argv[0], "theme") notify(messages.theme_installed) except FileNotFoundError as e: notify(messages.theme_doesnt_exists.format("'"+argv[0]+"'"),color='RED') ''' Restore previous states ''' try: shutil.move(new_folder_name, "theme") except Exception as e: die(str(e))
def new_entry(argv): blog_configuration = get_blog_configuration() if len(argv) < 1: die(messages.missing_params.format("--new-entry")) content = {"authors": "", "tags": "", "categories": "", "title":argv[0]} try: wd = os.listdir(os.getcwd()) except OSError: die(messages.cannot_read_in.format(os.getcwd())) date = datetime.datetime.now() entry = dict() raw_entry_date = datetime.datetime.now() try: entry["ID"] = max([ int(filename.split("__")[0]) for filename in yield_entries_content()]) + 1 except ValueError: entry["ID"] = 1 entry["title"] = argv[0] entry["month"] = raw_entry_date.month entry["year"] = raw_entry_date.year entry["day"] = raw_entry_date.day entry["hour"] = raw_entry_date.hour entry["minute"] = raw_entry_date.minute entry["date"] = raw_entry_date entry_date = str(date.month)+'-'+str(date.day)+'-'+str(date.year)+'-'+str(date.hour)+'-'+str(date.minute) output_filename = os.getcwd()+'/entries/'+str(entry["ID"])+"__"+entry_date+"__"+entry["title"].replace(' ','_') stream = codecs.open(output_filename, 'w', encoding="utf-8") if len(argv) == 1: output = yaml.dump(content, default_flow_style=False, allow_unicode=True) + "---VENC-BEGIN-PREVIEW---\n---VENC-END-PREVIEW---\n" else: try: output = open(os.getcwd()+'/templates/'+argv[1], 'r').read().replace(".:GetEntryTitle:.", argv[0]) except FileNotFoundError as e: die(messages.file_not_found.format(os.getcwd()+"/templates/"+argv[1])) stream.write(output) stream.close() try: command = [arg for arg in blog_configuration["text_editor"].split(' ') if arg != ''] command.append(output_filename) subprocess.call(command) except FileNotFoundError: die(messages.unknown_command.format(blog_configuration["text_editor"])) notify(messages.entry_written)
def __init__(self): notify("┌─ "+messages.loading_data) self.blog_configuration = get_blog_configuration() self.sort_by = self.blog_configuration["sort_by"] self.enable_jsonld = self.blog_configuration["enable_jsonld"] self.enable_jsonp = self.blog_configuration["enable_jsonp"] self.blog_url = blog_configuration["blog_url"]
def remote_copy(argv=list()): blog_configuration = get_blog_configuration() try: ftp = ftplib.FTP(blog_configuration["ftp_host"]) ftp.encoding='latin-1' except socket.gaierror as e: die(str(e)) username = input("VenC: "+messages.username) user_passwd = getpass.getpass(prompt="VenC: "+messages.user_passwd) try: ftp.login(user=username,passwd=user_passwd) ftp.cwd(blog_configuration["path"]["ftp"]) notify(messages.clean_ftp_directory) ftp_clean_destination(ftp) notify(messages.copy_to_ftp_directory) ftp_export_recursively(os.getcwd()+"/blog", ftp) except TimeoutError as e: die(str(e)) except ftplib.error_perm as e: die(str(e), color="YELLOW")
# 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 VenC. If not, see <http://www.gnu.org/licenses/>. import os import http.server import urllib.parse from venc2.datastore.configuration import get_blog_configuration from venc2.prompt import die from venc2.prompt import notify from venc2.l10n import messages blog_configuration = get_blog_configuration() class VenCServer(http.server.CGIHTTPRequestHandler): def do_GET(self): self.path = urllib.parse.unquote(self.path, encoding=blog_configuration["path_encoding"]) super().do_GET() def serv_blog(argv=list()): try: os.chdir("blog/") PORT = int(blog_configuration["server_port"]) server_address = ("", PORT) notify(messages.serving_blog.format(PORT)) httpd = http.server.HTTPServer(server_address, VenCServer) httpd.serve_forever()
def __init__(self): notify("┌─ " + messages.loading_data) self.root_page = None self.blog_configuration = get_blog_configuration() self.sort_by = self.blog_configuration["sort_by"] self.enable_jsonld = self.blog_configuration["enable_jsonld"] self.enable_jsonp = self.blog_configuration["enable_jsonp"] self.blog_url = self.blog_configuration["blog_url"] self.path_encoding = self.blog_configuration["path_encoding"] self.disable_threads = [ thread_name.strip() for thread_name in self.blog_configuration["disable_threads"].split(',') ] self.entries = list() self.entries_per_archives = list() self.entries_per_categories = list() try: self.cpu_threads_requested_entry = [None] * cpu_count() except NotImplementedError: self.cpu_threads_requested_entry = [None] self.max_category_weight = 1 self.categories_leaves = [] self.embed_providers = {} self.html_categories_tree = {} self.html_categories_leaves = {} self.html_blog_archives = {} self.cache_get_entry_attribute_by_id = {} self.cache_get_chapter_attribute_by_index = {} self.generation_timestamp = datetime.datetime.now() self.raw_chapters = {} self.chapters_index = [] self.html_chapters = {} # Build JSON-LD doc if any if self.enable_jsonld or self.enable_jsonp: if "https://schema.org" in self.blog_configuration.keys(): self.optionals_schemadotorg = self.blog_configuration[ "https://schema.org"] else: self.optionals_schemadotorg = {} self.entries_as_jsonld = {} self.archives_as_jsonld = {} self.categories_as_jsonld = {} self.root_site_to_jsonld() # Build entries try: jsonld_callback = self.entry_to_jsonld_callback if ( self.enable_jsonld or self.enable_jsonp) else None for filename in yield_entries_content(): self.entries.append( Entry( filename, self.blog_configuration["path"], jsonld_callback, self.blog_configuration["path"] ["archives_directory_name"], self.path_encoding)) # Might happen during Entry creation. except MalformedPatterns as e: from venc2.helpers import handle_malformed_patterns handle_malformed_patterns(e) self.entries = sorted(self.entries, key=lambda entry: self.sort(entry)) path_categories_sub_folders = self.blog_configuration["path"][ "categories_sub_folders"] + '/' path_archives_directory_name = self.blog_configuration["path"][ "archives_directory_name"] for entry_index in range(0, len(self.entries)): current_entry = self.entries[entry_index] if entry_index > 0: self.entries[entry_index - 1].next_entry = current_entry current_entry.previous_entry = self.entries[entry_index - 1] # Update entriesPerDates if path_archives_directory_name != '': formatted_date = current_entry.formatted_date entries_index = self.get_entries_index_for_given_date( formatted_date) if entries_index != None: self.entries_per_archives[entries_index].count += 1 self.entries_per_archives[entries_index].related_to.append( entry_index) else: self.entries_per_archives.append( MetadataNode(formatted_date, entry_index)) # Update entriesPerCategories try: if self.path_encoding == '': sub_folders = quirk_encoding( unidecode.unidecode(path_categories_sub_folders)) else: sub_folders = urllib_parse_quote( path_categories_sub_folders, encoding=self.path_encoding) except UnicodeEncodeError as e: notify("\"{0}\": ".format(path_categories_sub_folders) + str(e), color="YELLOW") sub_folders = sub_folders if sub_folders != '/' else '' build_categories_tree(entry_index, current_entry.raw_categories, self.entries_per_categories, self.categories_leaves, self.max_category_weight, self.set_max_category_weight, encoding=self.path_encoding, sub_folders=sub_folders) self.update_chapters(current_entry) # build chapters index path_chapters_sub_folders = self.blog_configuration["path"][ "chapters_sub_folders"] path_chapter_folder_name = self.blog_configuration["path"][ "chapter_directory_name"] #TODO: Might be not safe, must test level if is actually an int. Test as well the whole sequence. for chapter in sorted(self.raw_chapters.keys(), key=lambda x: int(x.replace('.', ''))): top = self.chapters_index index = '' levels = [ str(level) for level in chapter.split('.') if level != '' ] len_levels = len(levels) for i in range(0, len_levels): l = levels[i] if index == '': index = l else: index += '.' + l f = filter(lambda c: c.index == index, top) try: top = next(f).sub_chapters except StopIteration: if index in self.raw_chapters.keys(): # TODO: Replace this shitty bloc by a function call building path try: path = "\x1a" + ( (path_chapters_sub_folders + '/' if path_chapters_sub_folders != '' else '') + path_chapter_folder_name).format( **{ "chapter_name": self.raw_chapters[index].title, "chapter_index": index }) try: if self.path_encoding == '': path = quirk_encoding( unidecode.unidecode(path)) else: path = urllib_parse_quote( path, encoding=self.path_encoding) except UnicodeEncodeError as e: notify("\"{0}\": ".format( path_chapters_sub_folders) + str(e), color="YELLOW") except KeyError as e: from venc2.helpers import die die(messages.variable_error_in_filename.format(e)) top.append( Chapter(index, self.raw_chapters[index], path)) self.raw_chapters[index].chapter = top[-1] else: top.append(Chapter(index, None, '')) top = top[-1].sub_chapters # Setup BlogArchives Data self.blog_archives = list() path_archives_sub_folders = self.blog_configuration["path"][ "archives_sub_folders"] + '/' for node in self.entries_per_archives: try: if self.path_encoding == '': sub_folders = quirk_encoding( unidecode.unidecode(path_archives_sub_folders)) else: sub_folders = urllib_parse_quote( path_archives_sub_folders, encoding=self.path_encoding) except UnicodeEncodeError as e: notify("\"{0}\": ".format(path_archives_sub_folders) + str(e), color="YELLOW") sub_folders = sub_folders if sub_folders != '/' else '' self.blog_archives.append({ "value": node.value, "path": "\x1a" + sub_folders + node.value, "count": node.count, "weight": node.weight })
def __init__(self): notify("┌─ " + messages.loading_data) self.blog_configuration = get_blog_configuration() self.sort_by = self.blog_configuration["sort_by"] self.enable_jsonld = self.blog_configuration["enable_jsonld"] self.enable_jsonp = self.blog_configuration["enable_jsonp"] self.blog_url = self.blog_configuration["blog_url"] self.disable_threads = [ thread_name.strip() for thread_name in self.blog_configuration["disable_threads"].split(',') ] self.entries = list() self.entries_per_dates = list() self.entries_per_categories = list() self.requested_entry_index = 0 self.max_category_weight = 1 self.categories_leaves = [] self.embed_providers = {} self.html_categories_tree = {} self.html_categories_leaves = {} self.html_blog_dates = {} self.generation_timestamp = datetime.datetime.now() self.raw_chapters = {} self.chapters_index = [] self.html_chapters = {} # Build JSON-LD doc if any if self.enable_jsonld or self.enable_jsonp: if "https://schema.org" in self.blog_configuration.keys(): self.optionals_schemadotorg = self.blog_configuration[ "https://schema.org"] else: self.optionals_schemadotorg = {} self.entries_as_jsonld = {} self.archives_as_jsonld = {} self.categories_as_jsonld = {} self.root_site_to_jsonld() # Build entries try: jsonld_callback = self.entry_to_jsonld_callback if ( self.enable_jsonld or self.enable_jsonp) else None for filename in yield_entries_content(): self.entries.append( Entry( filename, self.blog_configuration["path"], jsonld_callback, self.blog_configuration["path"] ["dates_directory_name"], self.blog_configuration["path_encoding"])) except MalformedPatterns as e: from venc2.helpers import handle_malformed_patterns handle_malformed_patterns(e) self.entries = sorted(self.entries, key=lambda entry: self.sort(entry)) for entry_index in range(0, len(self.entries)): current_entry = self.entries[entry_index] if entry_index > 0: self.entries[entry_index - 1].next_entry = current_entry current_entry.previous_entry = self.entries[entry_index - 1] # Update entriesPerDates if self.blog_configuration["path"]["dates_directory_name"] != '': formatted_date = current_entry.formatted_date entries_index = self.get_entries_index_for_given_date( formatted_date) if entries_index != None: self.entries_per_dates[entries_index].count += 1 self.entries_per_dates[entries_index].related_to.append( entry_index) else: self.entries_per_dates.append( MetadataNode(formatted_date, entry_index)) # Update entriesPerCategories try: sub_folders = urllib.parse.quote( self.blog_configuration["path"]["categories_sub_folders"] + '/', encoding=self.blog_configuration["path_encoding"]) except UnicodeEncodeError as e: sub_folders = self.blog_configuration["path"][ "categories_sub_folders"] + '/' notify("\"{0}\": ".format(sub_folders) + str(e), color="YELLOW") sub_folders = sub_folders if sub_folders != '/' else '' build_categories_tree( entry_index, current_entry.raw_categories, self.entries_per_categories, self.categories_leaves, self.max_category_weight, self.set_max_category_weight, encoding=self.blog_configuration["path_encoding"], sub_folders=sub_folders) self.update_chapters(current_entry) # build chapters index for chapter in sorted(self.raw_chapters.keys()): top = self.chapters_index index = '' levels = [ str(level) for level in chapter.split('.') if str(level) != '' ] len_levels = len(levels) for i in range(0, len_levels): l = levels[i] if index == '': index = l else: index += '.' + l f = filter(lambda c: c.index == index, top) try: top = next(f).sub_chapters except StopIteration: try: top.append( Chapter(index, self.raw_chapters[index][1], self.raw_chapters[index][2])) except KeyError: top.append(Chapter(index, '', '')) top = top[-1].sub_chapters # Setup BlogArchives Data self.blog_dates = list() for node in self.entries_per_dates: try: sub_folders = urllib.parse.quote( self.blog_configuration["path"]["dates_sub_folders"] + '/', encoding=self.blog_configuration["path_encoding"]) except UnicodeEncodeError as e: sub_folders = self.blog_configuration["path"][ "dates_sub_folders"] + '/' notify("\"{0}\": ".format(sub_folders) + str(e), color="YELLOW") sub_folders = sub_folders if sub_folders != '/' else '' self.blog_dates.append({ "value": node.value, "path": ".:GetRelativeOrigin:." + sub_folders + node.value, "count": node.count, "weight": node.weight })
# 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 VenC. If not, see <http://www.gnu.org/licenses/>. import os import http.server import urllib.parse from venc2.datastore.configuration import get_blog_configuration from venc2.prompt import die from venc2.prompt import notify from venc2.l10n import messages blog_configuration = get_blog_configuration() class VenCServer(http.server.CGIHTTPRequestHandler): def __init__(self, request, client_address, server): super().__init__(request, client_address, server) def do_GET(self): self.path = urllib.parse.unquote(self.path, encoding=blog_configuration["path_encoding"]) super().do_GET() def serv_blog(argv=list()): try: os.chdir("blog/") PORT = int(argv[0]) if len(argv) else int(blog_configuration["server_port"]) server_address = ("", PORT) notify(messages.serving_blog.format(PORT))