diff --git a/ImageMetaTag/db.py b/ImageMetaTag/db.py index c618fa1..c4e4857 100644 --- a/ImageMetaTag/db.py +++ b/ImageMetaTag/db.py @@ -32,6 +32,7 @@ def db_name_to_info_key(in_str): return str(in_str).replace('__', ' ') def write_img_to_dbfile(db_file, img_filename, img_info, add_strict=False, + attempt_replace=False, timeout=DEFAULT_DB_TIMEOUT): ''' Writes image metadata to a database. @@ -48,6 +49,7 @@ def write_img_to_dbfile(db_file, img_filename, img_info, add_strict=False, Options: * add_strict - passed into :func:`ImageMetaTag.db.write_img_to_open_db` + * attempt_replace - passed into :func:`ImageMetaTag.db.write_img_to_open_db` * timeout - default timeout to try and write to the database. This is commonly used in :func:`ImageMetaTag.savefig` @@ -61,7 +63,8 @@ def write_img_to_dbfile(db_file, img_filename, img_info, add_strict=False, # open the database: dbcn, dbcr = open_or_create_db_file(db_file, img_info, timeout=timeout) # now write: - write_img_to_open_db(dbcr, img_filename, img_info, add_strict=add_strict) + write_img_to_open_db(dbcr, img_filename, img_info, + add_strict=add_strict, attempt_replace=attempt_replace) # now commit that databasde entry and close: dbcn.commit() dbcn.close() @@ -140,7 +143,7 @@ def read(db_file, required_tags=None, tag_strings=None, read_img_info_from_dbfile = read def merge_db_files(main_db_file, add_db_file, delete_add_db=False, - delete_added_entries=False, + delete_added_entries=False, attempt_replace=False, db_timeout=DEFAULT_DB_TIMEOUT, db_attempts=DEFAULT_DB_ATTEMPTS): ''' Merges two ImageMetaTag database files, with the contents of add_db_file added @@ -169,7 +172,8 @@ def merge_db_files(main_db_file, add_db_file, delete_add_db=False, dbcn, dbcr = open_db_file(main_db_file, timeout=db_timeout) # and add in the new contents: for add_file, add_info in add_tags.iteritems(): - write_img_to_open_db(dbcr, add_file, add_info) + write_img_to_open_db(dbcr, add_file, add_info, + attempt_replace=attempt_replace) dbcn.commit() # if we got here, then we're good! wrote_db = True @@ -332,9 +336,9 @@ def write_img_to_open_db(dbcr, filename, img_info, add_strict=False, attempt_rep except sqlite3.IntegrityError: if attempt_replace: # try an INSERT OR REPLACE - add_command.replace('INSERT ', 'INSERT OR REPLACE ') + add_repl_command = add_command.replace('INSERT ', 'INSERT OR REPLACE ') # if this fails, want it to report it's error message as is, so no 'try': - dbcr.execute(add_command, add_list) + dbcr.execute(add_repl_command, add_list) else: # this file is already in the database (as the primary key, so do nothing...) pass diff --git a/ImageMetaTag/savefig.py b/ImageMetaTag/savefig.py index 5402da2..dc4a2c1 100644 --- a/ImageMetaTag/savefig.py +++ b/ImageMetaTag/savefig.py @@ -30,7 +30,7 @@ def savefig(filename, img_format=None, img_converter=0, do_trim=False, trim_bord do_thumb=False, img_tags=None, keep_open=False, dpi=None, logo_file=None, logo_width=40, logo_padding=0, logo_pos=0, db_file=None, db_timeout=DEFAULT_DB_TIMEOUT, db_attempts=DEFAULT_DB_ATTEMPTS, - db_full_paths=False, + db_replace=False, db_full_paths=False, verbose=False, ): ''' A wrapper around matplotlib.pyplot.savefig, to include file size optimisation and @@ -54,6 +54,9 @@ def savefig(filename, img_format=None, img_converter=0, do_trim=False, trim_bord db_full_paths is True. * db_timeout - change the database timeout (in seconds). * db_attempts - change the number of attempts to write to the database. + * db_replace - if True, an image's metadata will be replaced in the database if it \ + already exists. This can be slow, and the metadata is usually the same so \ + the default is db_replace=False. * dpi - change the image resolution passed into matplotlib.savefig. * keep_open - by default, this savefig wrapper closes the figure after use, except if \ keep_open is True. @@ -151,7 +154,8 @@ def savefig(filename, img_format=None, img_converter=0, do_trim=False, trim_bord n_tries = 1 while not wrote_db and n_tries <= db_attempts: try: - db.write_img_to_dbfile(db_file, db_filename, img_tags, timeout=db_timeout) + db.write_img_to_dbfile(db_file, db_filename, img_tags, timeout=db_timeout, + attempt_replace=db_replace) wrote_db = True except sqlite3.OperationalError as OpErr: if 'database is locked' in OpErr.message: diff --git a/ImageMetaTag/webpage.py b/ImageMetaTag/webpage.py index 225b291..fef9813 100644 --- a/ImageMetaTag/webpage.py +++ b/ImageMetaTag/webpage.py @@ -102,7 +102,8 @@ def write_full_page(img_dict, filepath, title, page_filename=None, tab_s_name=No * compression - default False. If True, then the json data object will be compressed \ using zlib string compression. When read into the browser, we will use \ pako to inflate it (https://github.com/nodeca/pako) - * css - CSS file used to style webpage + * css - Optional CSS file used to style webpage. By default a small amount of css is \ + written out in the page header. Returns a list of files that the the created webpage is dependent upon ''' diff --git a/docs/build/doctrees/db.doctree b/docs/build/doctrees/db.doctree index 66ecb07..d5374ff 100644 Binary files a/docs/build/doctrees/db.doctree and b/docs/build/doctrees/db.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index 18ee086..e895f19 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/savefig.doctree b/docs/build/doctrees/savefig.doctree index 130a4fe..4b1c36f 100644 Binary files a/docs/build/doctrees/savefig.doctree and b/docs/build/doctrees/savefig.doctree differ diff --git a/docs/build/doctrees/webpage.doctree b/docs/build/doctrees/webpage.doctree index 4a3b97b..03ccc1f 100644 Binary files a/docs/build/doctrees/webpage.doctree and b/docs/build/doctrees/webpage.doctree differ diff --git a/docs/build/html/_modules/ImageMetaTag/db.html b/docs/build/html/_modules/ImageMetaTag/db.html index b31ea4a..cd8ed5c 100644 --- a/docs/build/html/_modules/ImageMetaTag/db.html +++ b/docs/build/html/_modules/ImageMetaTag/db.html @@ -102,6 +102,7 @@
return str(in_str).replace('__', ' ')
Options:
* add_strict - passed into :func:`ImageMetaTag.db.write_img_to_open_db`
+ * attempt_replace - passed into :func:`ImageMetaTag.db.write_img_to_open_db`
* timeout - default timeout to try and write to the database.
This is commonly used in :func:`ImageMetaTag.savefig`
@@ -131,7 +133,8 @@ Source code for ImageMetaTag.db
# open the database:
dbcn, dbcr = open_or_create_db_file(db_file, img_info, timeout=timeout)
# now write:
- write_img_to_open_db(dbcr, img_filename, img_info, add_strict=add_strict)
+ write_img_to_open_db(dbcr, img_filename, img_info,
+ add_strict=add_strict, attempt_replace=attempt_replace)
# now commit that databasde entry and close:
dbcn.commit()
dbcn.close()
@@ -210,7 +213,7 @@ Source code for ImageMetaTag.db
read_img_info_from_dbfile = read
[docs]def merge_db_files(main_db_file, add_db_file, delete_add_db=False,
- delete_added_entries=False,
+ delete_added_entries=False, attempt_replace=False,
db_timeout=DEFAULT_DB_TIMEOUT, db_attempts=DEFAULT_DB_ATTEMPTS):
'''
Merges two ImageMetaTag database files, with the contents of add_db_file added
@@ -239,7 +242,8 @@ Source code for ImageMetaTag.db
dbcn, dbcr = open_db_file(main_db_file, timeout=db_timeout)
# and add in the new contents:
for add_file, add_info in add_tags.iteritems():
- write_img_to_open_db(dbcr, add_file, add_info)
+ write_img_to_open_db(dbcr, add_file, add_info,
+ attempt_replace=attempt_replace)
dbcn.commit()
# if we got here, then we're good!
wrote_db = True
@@ -303,7 +307,7 @@ Source code for ImageMetaTag.db
def create_table_for_img_info(dbcr, img_info):
'Creates a database table, in a database cursor, to store for the input img_info'
-
+
create_command = 'CREATE TABLE {}(fname TEXT PRIMARY KEY,'.format(SQLITE_IMG_INFO_TABLE)
for key in img_info.keys():
create_command += ' "{}" TEXT,'.format(info_key_to_db_name(key))
@@ -316,7 +320,8 @@ Source code for ImageMetaTag.db
except sqlite3.OperationalError as OpErr:
if 'table {} already exists'.format(SQLITE_IMG_INFO_TABLE) in OpErr.message:
# another process has just created the table, so sleep(1)
- # This is only when a db file is created so isn't called often (and the race condition is rare!)
+ # This is only when a db file is created so isn't called often
+ # (and the race condition is rare!)
time.sleep(1)
else:
# everything else needs to be reported and raised immediately:
@@ -401,9 +406,9 @@ Source code for ImageMetaTag.db
except sqlite3.IntegrityError:
if attempt_replace:
# try an INSERT OR REPLACE
- add_command.replace('INSERT ', 'INSERT OR REPLACE ')
+ add_repl_command = add_command.replace('INSERT ', 'INSERT OR REPLACE ')
# if this fails, want it to report it's error message as is, so no 'try':
- dbcr.execute(add_command, add_list)
+ dbcr.execute(add_repl_command, add_list)
else:
# this file is already in the database (as the primary key, so do nothing...)
pass
@@ -576,8 +581,8 @@ Source code for ImageMetaTag.db
pass
else:
if allow_retries:
- # split the list of filenames up into appropciately sized chunks, so that concurrent
- # delete commands each have a chance to complete:
+ # split the list of filenames up into appropciately sized chunks, so that
+ # concurrent delete commands each have a chance to complete:
# 200 is arbriatily chosen, but seems to work
chunk_size = 200
chunks = __gen_chunk_of_list(fn_list, chunk_size)
@@ -591,10 +596,12 @@ Source code for ImageMetaTag.db
dbcn, dbcr = open_db_file(db_file, timeout=db_timeout)
# go through the file chunk, one by one, and delete:
for fname in chunk_o_filenames:
+ del_cmd = "DELETE FROM {} WHERE fname=?"
try:
- dbcr.execute("DELETE FROM %s WHERE fname=?" % SQLITE_IMG_INFO_TABLE, (fname,))
+ dbcr.execute(del_cmd.format(SQLITE_IMG_INFO_TABLE), (fname,))
except sqlite3.OperationalError as OpErr_file:
- if OpErr_file.message == 'no such table: {}'.format(SQLITE_IMG_INFO_TABLE):
+ err_check = 'no such table: {}'.format(SQLITE_IMG_INFO_TABLE)
+ if OpErr_file.message == err_check:
# the db file exists, but it doesn't have anything in it:
if not skip_warning:
msg = ('WARNING: Unable to delete file entry "{}" from'
diff --git a/docs/build/html/_modules/ImageMetaTag/webpage.html b/docs/build/html/_modules/ImageMetaTag/webpage.html
index 6e5af98..5b0efb7 100644
--- a/docs/build/html/_modules/ImageMetaTag/webpage.html
+++ b/docs/build/html/_modules/ImageMetaTag/webpage.html
@@ -132,7 +132,7 @@ Source code for ImageMetaTag.webpage
show_singleton_selectors=True, optgroups=None,
url_type='int', only_show_rel_url=False, verbose=False,
style='horiz dropdowns', write_intmed_tmpfile=False,
- description=None, keywords=None):
+ description=None, keywords=None, css=None):
'''
Writes out an :class:`ImageMetaTag.ImageDict` as a webpage, to a given file location.
The files are created as temporary files and when complete they replace any files that
@@ -172,6 +172,8 @@ Source code for ImageMetaTag.webpage
* compression - default False. If True, then the json data object will be compressed \
using zlib string compression. When read into the browser, we will use \
pako to inflate it (https://github.com/nodeca/pako)
+ * css - Optional CSS file used to style webpage. By default a small amount of css is \
+ written out in the page header.
Returns a list of files that the the created webpage is dependent upon
'''
@@ -236,14 +238,26 @@ Source code for ImageMetaTag.webpage
ind = _indent_up_one(ind)
out_file.write(ind + '<head>\n')
ind = _indent_up_one(ind)
- if not title is None:
+ if title is not None:
out_file.write('{}<title>{}</title>\n'.format(ind, title))
out_str = ind+'<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\n'
out_file.write(out_str)
- if style == 'horiz dropdowns':
- # write out a little css at the top:
- css = '''{0}<style>
+ if css:
+ shutil.copy(css, file_dir)
+ base_css = os.path.basename(css)
+ page_dependencies.append(base_css)
+ out_str = ind+'<link rel="stylesheet" type="text/css" href="{0}">\n'
+ out_file.write(out_str.format(base_css))
+
+ else:
+ if style == 'horiz dropdowns':
+ # write out a little css at the top:
+ css = '''{0}<style>
+{0} body {{
+{0} background-color: #ffffff;
+{0} color: #000000;
+{0} }}
{0} body, div, dl, dt, dd, li, h1, h2 {{
{0} margin: 0;
{0} padding: 0;
@@ -306,7 +320,7 @@ Source code for ImageMetaTag.webpage
{0} }}
{0}</style>
'''
- out_file.write(css.format(ind))
+ out_file.write(css.format(ind))
# now write out the specific stuff to the html header:
if img_dict is None:
@@ -334,14 +348,11 @@ Source code for ImageMetaTag.webpage
out_file.write(ind + '</head>\n')
# now start the body:
- margins = 'leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"'
- bgcolor = 'bcolor="#FFFFFF"'
- text_color = 'text="#000000"'
- out_file.write('{}<body {} {} {}>\n'.format(ind, bgcolor, text_color, margins))
+ out_file.write('{}<body>\n'.format(ind))
# the preamble is the first thing to go in the body:
- if not preamble is None:
- out_file.write(preamble)
+ if preamble is not None:
+ out_file.write(preamble + '\n')
# now the img_dict content:
if img_dict is None:
out_file.write('<p><h1>No images are available for this page.</h1></p>')
@@ -362,14 +373,14 @@ Source code for ImageMetaTag.webpage
show_singleton_selectors=show_singleton_selectors,
animated_level=anim_level)
# the body is done, so the postamble comes in:
- if not postamble is None:
+ if postamble is not None:
out_file.write(postamble + '\n')
# finish the body, and html:
out_file.write(ind + '</body>\n')
out_file.write('\n</html>')
- if write_intmed_tmpfile:
+ if write_intmed_tmpfile:
tmp_files_to_mv = json_files + [(tmp_html_filepath, filepath)]
else:
tmp_files_to_mv = json_files
@@ -435,12 +446,12 @@ Source code for ImageMetaTag.webpage
if ind is None:
ind = ''
- if not description is None:
+ if description is not None:
file_obj.write('{}<meta name="description" content="{}">\n'.format(ind, description))
- if not keywords is None:
+ if keywords is not None:
file_obj.write('{}<meta name="keywords" content="{}">\n'.format(ind, keywords))
- if not img_dict is None:
+ if img_dict is not None:
## add a reference to the data structure:
#out_str = '{}<script type="text/javascript" src="{}"></script>\n'.format(ind, json_files)
#file_obj.write(out_str)
@@ -450,7 +461,7 @@ Source code for ImageMetaTag.webpage
out_str = '{}<script type="text/javascript" src="{}"></script>\n'.format(ind, js_file)
file_obj.write(out_str)
- # now write out the javascript cnfiguration variables:
+ # now write out the javascript configuration variables:
file_obj.write(ind + '<script type="text/javascript">\n')
ind = _indent_up_one(ind)
# define, read in and parse the json file:
@@ -495,7 +506,7 @@ Source code for ImageMetaTag.webpage
if initial_selectors is None:
# if it's not set, then set it to something invalid, and the validator
# in the javascript will sort it out. It MUST be the right length though:
- file_obj.write('{}var selected_id = {}\n;'.format(ind, str([-1]*dict_depth)))
+ file_obj.write('{}var selected_id = {};\n'.format(ind, str([-1]*dict_depth)))
else:
if not isinstance(initial_selectors, list):
msg = 'Input initial_selectors must be a list, of length the depth of the ImageDict'
@@ -590,7 +601,8 @@ Source code for ImageMetaTag.webpage
# now some top level things:
if style == 'horiz dropdowns':
- file_obj.write('''{0}// other top level derived variables
+ file_obj.write('''
+{0}// other top level derived variables
{0}// the depth of the ImageMetaTag ImageDict (number of selectors):
{0}var n_deep = selected_id.length;
{0}// a list of the options available to the animator buttons, with the current selection
diff --git a/docs/build/html/db.html b/docs/build/html/db.html
index fa7f040..ee896ef 100644
--- a/docs/build/html/db.html
+++ b/docs/build/html/db.html
@@ -109,7 +109,7 @@ Commonly used functionsFor most use cases, the following functions provide the required functionality to use the database:
-
-ImageMetaTag.db.write_img_to_dbfile(db_file, img_filename, img_info, add_strict=False, timeout=6)[source]¶
+ImageMetaTag.db.write_img_to_dbfile(db_file, img_filename, img_info, add_strict=False, attempt_replace=False, timeout=6)[source]¶
Writes image metadata to a database.
Arguments:
@@ -120,6 +120,7 @@ Commonly used functionsOptions:
- add_strict - passed into ImageMetaTag.db.write_img_to_open_db()
+- attempt_replace - passed into ImageMetaTag.db.write_img_to_open_db()
- timeout - default timeout to try and write to the database.
This is commonly used in ImageMetaTag.savefig()
@@ -176,7 +177,7 @@ Commonly used functions
-
-ImageMetaTag.db.merge_db_files(main_db_file, add_db_file, delete_add_db=False, delete_added_entries=False, db_timeout=6, db_attempts=20)[source]¶
+ImageMetaTag.db.merge_db_files(main_db_file, add_db_file, delete_add_db=False, delete_added_entries=False, attempt_replace=False, db_timeout=6, db_attempts=20)[source]¶
Merges two ImageMetaTag database files, with the contents of add_db_file added
to the main_db_file. The databases should have the same tags within them for the
merge to work.
diff --git a/docs/build/html/savefig.html b/docs/build/html/savefig.html
index 857251c..8e1d792 100644
--- a/docs/build/html/savefig.html
+++ b/docs/build/html/savefig.html
@@ -107,7 +107,7 @@ The savefig wrapper
-
-ImageMetaTag.savefig(filename, img_format=None, img_converter=0, do_trim=False, trim_border=0, do_thumb=False, img_tags=None, keep_open=False, dpi=None, logo_file=None, logo_width=40, logo_padding=0, logo_pos=0, db_file=None, db_timeout=6, db_attempts=20, db_full_paths=False, verbose=False)¶
+ImageMetaTag.savefig(filename, img_format=None, img_converter=0, do_trim=False, trim_border=0, do_thumb=False, img_tags=None, keep_open=False, dpi=None, logo_file=None, logo_width=40, logo_padding=0, logo_pos=0, db_file=None, db_timeout=6, db_attempts=20, db_replace=False, db_full_paths=False, verbose=False)¶
A wrapper around matplotlib.pyplot.savefig, to include file size optimisation and
image tagging.
The filesize optimisation depends on the img_converter input passes into
@@ -122,6 +122,7 @@
The savefig wrapperQuick search
Writing a whole page¶
-
-ImageMetaTag.webpage.write_full_page(img_dict, filepath, title, page_filename=None, tab_s_name=None, preamble=None, postamble=None, compression=False, initial_selectors=None, show_selector_names=False, show_singleton_selectors=True, optgroups=None, url_type='int', only_show_rel_url=False, verbose=False, style='horiz dropdowns', write_intmed_tmpfile=False, description=None, keywords=None)[source]¶
+ImageMetaTag.webpage.write_full_page(img_dict, filepath, title, page_filename=None, tab_s_name=None, preamble=None, postamble=None, compression=False, initial_selectors=None, show_selector_names=False, show_singleton_selectors=True, optgroups=None, url_type='int', only_show_rel_url=False, verbose=False, style='horiz dropdowns', write_intmed_tmpfile=False, description=None, keywords=None, css=None)[source]¶
Writes out an ImageMetaTag.ImageDict as a webpage, to a given file location.
The files are created as temporary files and when complete they replace any files that
are currently in the specified location.
@@ -152,6 +152,7 @@ Writing a whole pagedescription - html description metadata
- keywords - html keyword metadata
- compression - default False. If True, then the json data object will be compressed using zlib string compression. When read into the browser, we will use pako to inflate it (https://github.com/nodeca/pako)
+- css - Optional CSS file used to style webpage. By default a small amount of css is written out in the page header.
Returns a list of files that the the created webpage is dependent upon
diff --git a/release_process b/release_process
index ddc3119..546eff0 100644
--- a/release_process
+++ b/release_process
@@ -15,7 +15,7 @@ convention (http://semver.org/)
time to make sure it works, as the code at this stage is what will be
released.
-2) Update the documentation, from the docs directory:
+3) Update the documentation, from the docs directory:
cd docs
* Clean the documentation build:
make html clean
@@ -23,18 +23,20 @@ convention (http://semver.org/)
new build:
PYTHONPATH=../ make html
-3) Commit the version number and documentation changes:
+4) Commit the version number and documentation changes:
git commit -a
git push origin {{ branch_name }}
-4) Start a pull request for your branch on your github fork and follow the
+5) Start a pull request for your branch on your github fork and follow the
process to merge it to the master branch.
+6) Test the package works at the commit which you intend to release by installing from the specific commit to a temporary location. Install it using the setup.py and run the test.py script.
+
From this point onwards, admin rights are required to both image-meta-tag and image-meta-tag-feedstock repositories.
-5) Pulbish a release in the image-meta-tag repository for the new release
+7) Pulbish a release in the image-meta-tag repository for the new release
number at: https://github.com/SciTools-incubator/image-meta-tag/releases
* Tag version is just the version number e.g. '0.6.7' in the code.
* The convention used for the release title adds 'vn' before the number, e.g.
@@ -42,7 +44,7 @@ number at: https://github.com/SciTools-incubator/image-meta-tag/releases
* The release description can be used to give a very brief outline of the
changes.
-6) Update the recipe on the conda-forge-feedstock:
+8) Update the recipe on the conda-forge-feedstock:
* The main repository is:
https://github.com/conda-forge/image-meta-tag-feedstock
* The location of admin branches is: