def get_nice_info(file_id): #TODO make it more flexible, put the strings in the config infos_html = StringIO() ddlink = lambda i, k, v : '<a href="%s%s%s">%s</a>' % (config.base_url,i,urlquote(k),v) fsi = db.query("select * from images where id = %s" % file_id)[0] fmi = {} for i in config.have_many_values: fmi[i] = db.query("select value from %(index)ss iv, images_%(index)ss ii where ii.image_id = %(file_id)s and ii.%(index)s_id = iv.id" % {"index" : i, "file_id": file_id}) if fsi.author or fsi.date or fsi.album or fsi.location: infos_html.write("Taken") if fsi.author: infos_html.write(" by %s" % ddlink("author", fsi.author, fsi.author)) if fsi.date: infos_html.write( " the %s" % ddlink("date", fsi.date, hr_tag("date", fsi.date))) if fsi.album: infos_html.write( " when doing the %s" % ddlink("album", fsi.album, fsi.album)) if fsi.location: infos_html.write(" at %s" % ddlink("location", fsi.location, fsi.location)) infos_html.write(".<br/>") for (i, values) in fmi.items(): if len(values) > 0: if i == "subject": infos_html.write("You can admire %s.<br/>" % englishhelper.list_nouns_as_links(i, [row.value for row in values], ddlink)) elif i == "tag": infos_html.write("%s should describe this image.<br/>" % englishhelper.list_nouns_as_links(i, [row.value for row in values], ddlink)) return infos_html.getvalue()
def get_default_values(sel_ik, index): """will print all the possible keys an index could use in order to still show at least one file with the current selection of i/k in mind""" value_per_index = [] #get all the possible values from the index if sel_ik: #building the ignore clause for (sel_index, sel_value) in sel_ik: if sel_index == index: if value_per_index: value_per_index.append(sel_value) else: value_per_index = [sel_value, ] if value_per_index: ignore_clause = "and %s not in ("+", ".join(['"'+ivalue+'"' for ivalue in value_per_index])+")" else: ignore_clause = "" if index in config.have_many_values: additional_clauses = build_clauses(sel_ik, 'and ', 'images.') if ignore_clause: temp_ignore_clause = ignore_clause % "value" else: temp_ignore_clause = "" #web.debug('GET VALUE : select value, count(images.id) as quantity from images_%(index)ss , %(index)ss, images where %(index)s_id = %(index)ss.id and images_%(index)ss.image_id = images.id %(temp_ignore_clause)s %(additional_clauses)s group by %(index)s_id' % (vars())) return db.query('select value, count(images.id) as quantity from images_%ss , %ss, images where %s_id = %ss.id and images_%ss.image_id = images.id %s %s group by %s_id order by %s' % (index, index, index, index, index, temp_ignore_clause , additional_clauses, index, get_order(index))) else: additional_clauses = build_clauses(sel_ik, 'and ') if index in config.compound_indexes.keys(): #need to get database specific query to match value db_value = config.compound_indexes[index]['reverse_query']() else: db_value = index if ignore_clause: temp_ignore_clause = ignore_clause % db_value else: temp_ignore_clause = "" #web.debug('GET VALUE: select %s as value, count(id) as quantity from images where 1=1 %s %s group by value' % (db_value, temp_ignore_clause , additional_clauses)) return db.query('select %s as value, count(id) as quantity from images where 1=1 %s %s group by value order by %s' % (db_value, temp_ignore_clause , additional_clauses, get_order(index))) else: #simpler case, left here for the sake of simplicity if index in config.have_many_values: #web.debug('select value, count(image_id) as quantity from images_%ss , %ss where %s_id = id group by %s_id' % (index, index, index, index)) return db.query('select value, count(image_id) as quantity from images_%ss , %ss where %s_id = id group by %s_id order by %s' % (index, index, index, index , get_order(index))) else : if index in config.compound_indexes.keys(): #need to get database specific query to match value db_value = config.compound_indexes[index]['reverse_query']() else: db_value = index return db.query('select %s as value, count(id) as quantity from images group by value order by %s' % (db_value, get_order(index)))
def get_all_values(index): if index in config.have_many_values: db_values = db.query('select value from %ss' % index) return [row.value for row in db_values] elif index in config.compound_indexes.keys(): compound_info = config.compound_indexes[index] db_values = db.query('select distinct(%s) as value from images order by %s' % (compound_info['reverse_query'](), get_order(index))) return [str(row.value) for row in db_values] else: db_values = db.query('select distinct(%s) as value from images order by %s' % (index, get_order(index))) return [row.value for row in db_values]
def store_infos(infos, extra_db_entries): print " %s" % (infos) #web.debug(" %s" % (infos)) simple_infos = infos.copy() multiple_infos = {} for imv in config.have_many_values: try: del simple_infos[imv] multiple_infos[imv] = infos[imv] except KeyError: pass #checking for file renaming with sha possiblePrevFiles = db.query("select id, filename, batch from images where sha ='"+infos['sha']+"'") updatingFile = False if len(possiblePrevFiles) == 1: #file found in db print "INFO duplicate found : "+infos['filename'] prevFile = possiblePrevFiles[0] file_id = prevFile.id simple_infos['batch'] = prevFile.batch try: extra_db_entries.remove(prevFile.filename) db.update('images', 'id = %s' % file_id, None, **simple_infos) updatingFile = True except ValueError: #raise with .remove when the filename do not match print "WARNING duplicate sha accross fileset, creating new entry" else: if len(possiblePrevFiles) > 1: #more than one file with this sha... print "INFO sha present multiple time for file : "+infos["filename"] file_id = db.insert('images', True, **simple_infos) for index in multiple_infos.keys(): #store the value in its table for value in multiple_infos[index]: try: value_id = db.insert(index+'s', True, **{"value" : value}) #debuginsert(index+'s', False, **{"value" : value}) except: #TODO should be IntegrityError for mysql but not sure how best integrate that without breaking the DB abstraction... #but if the error wasn't an IntegrityError then the next line should fail value_id = db.query('select id from %ss where value = "%s"' % (index, value))[0].id #store the relationship between the value and the file try: db.insert("images_"+index+'s', False, **{index+"_id": value_id, "image_id" : file_id}) except Exception, inst: #if we are update a file we might raise some integrity error here if updatingFile: pass else: raise inst
def sync(): #list all files from disk and DB global db disk_entries = get_files() db_entries = [f['filename'] for f in db.query("select filename from images")] extra_db_entries = [] print "%s disk entries\n%s db entries\n" % (len(disk_entries), len(db_entries)) for f in db_entries: if f in disk_entries: disk_entries.remove(f) else: extra_db_entries.append(f) print "%s EXTRA disk entries" % (len(disk_entries)) build_all(disk_entries, extra_db_entries) print "\n%s EXTRA db entries" % (len(extra_db_entries)) for f in extra_db_entries: print "removing %s from DB" % f #remove the info from the db file_id = db.query('select id from images where filename = "%s"' % f)[0].id db.query("delete from images where id = %s" % file_id) for imv in config.have_many_values: #removing the infos from the various multiple indexes db.query("delete from images_%ss where image_id = %s" % (imv, file_id)) for imv in config.have_many_values: print "cleaning the possibles orphan values for the index %s" % imv db.query("delete from %ss where id not in (select %s_id from images_%ss)" % (imv, imv, imv))
def select_files(sel_ik): q = StringIO() q.write('select id, filename from images ') q.write(build_clauses(sel_ik,'where ')) q.write(' order by date desc ') web.debug('file query = %s' % q.getvalue()) return db.query(q.getvalue())
def select_clusters_of_files(sel_ik): q = StringIO() q.write('select * from images ') q.write(build_clauses(sel_ik,'where ')) q.write(' order by date desc ') files = [f for f in db.query(q.getvalue())] web.debug('file query = %s' % q.getvalue()) #clustering happens here. (clustered_files, cluster_pivot) = cluster_files(files, sel_ik) if len(clustered_files.keys()) < config.minimum_pivot_value: return (files, None, None) return (files, clustered_files, cluster_pivot)
def print_selection(mindex=[], mkey=[], file_id = None, response_format = "html", sizeX = config.image_preview): """prints a browsing page including the selected indexes, the index which are still selectable and the result of the current selection as thumbnails""" render = template.render('templates/') template.Template.globals['HTML'] = HTMLTemplates template.Template.globals['config'] = config template.Template.globals['uihelper'] = uihelper selection = None indexes = None file_url = None print mindex print mkey if file_id: #we need to request the filename db_file = db.query("select filename from images where id = %s" % file_id) if len(db_file) == 1: file_path = db_file[0].filename file_url = config.web_alias + file_path[len(config.base_dir):] #first let's see if anything was choosen if mindex: #choosing the kind of situation we have to handle if len(mindex) == len(mkey): #we have the same number of indexes and key so we can print image list sel_ik = build_sel_ik(mindex, mkey, len(mkey)) print "xx_xxxxxx" print sel_ik #selecting files from the given index values #files = indexhelper.select_files (sel_ik) files, clustered_files, cluster_pivot = indexhelper.select_clusters_of_files(sel_ik) if files: cache_key = uihelper.build_link(sel_ik) #get the index possible values index_othervalues = {} for index in config.indexes: index_othervalues[index] = [i for i in indexhelper.get_values(sel_ik, index)] #now also get the selected index possible values without them (changing stuff) sel_index_othervalues = {} for (index, value) in sel_ik: temp_sel_ik = sel_ik[:] temp_sel_ik.remove((index,value)) sel_index_othervalues[index] = len(indexhelper.get_values(temp_sel_ik, index)) if len(files) == 1 and not file_id: #TODO have the redirect be a temporary one, or check how long the browser retain the redirect web.found('%s%s/%s%s' % (config.base_url, uihelper.build_link(sel_ik), config.file_url_id, files[0].id)) else: if response_format in config.format_http_header.keys(): web.header("Content-Type", config.format_http_header[response_format]) #render.web.render('browse.'+response_format) return render.browse(file_url,file_id,sel_ik,sel_index_othervalues,index_othervalues,files,clustered_files,cluster_pivot) elif len(mindex)-len(mkey) == 1: #there is a different process if len(mindex) and len(mkey) are differents, #it means an index was selected but no key for it we have to print the #keys for which the current selection of indexes/keys has left some images to view sel_ik = build_sel_ik(mindex, mkey, len(mkey)) current_index = mindex[-1] index_possible_values = indexhelper.get_values(sel_ik, current_index) #if for_ajax: # web.render('browsechoosevalue.ajax') #else: #web.render('browsechoosevalue.'+response_format) return render.browsechoosevalue(current_index,index_possible_values,sel_ik) else: #complaining about the uneven (more than usual at least) numbers of index and keys provided print("you have selected %s index but only %s keys where given\ , stop messing around with things you don't understand please ;)<br/>"\ % (len(mindex), len(mkey))) elif file_url: web.render('browse.html') else: indexes = [idx for idx in config.root_indexes if idx != 'tag'] all_tags = indexhelper.get_values(None, "tag") return render.browseroot(all_tags, indexes)