├── showDB.py ├── image64.py ├── README.md └── gui.py /showDB.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import pprint 3 | from gui import * 4 | 5 | pprint.pprint(fs_load()) 6 | -------------------------------------------------------------------------------- /image64.py: -------------------------------------------------------------------------------- 1 | def convert(pic): 2 | with open(pic, "rb") as f: 3 | data12 = f.read() 4 | UU = data12.encode("base64") 5 | return(UU) 6 | 7 | #print(convert('divider.png')) 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | fast-photo-sorter 2 | ================= 3 | 4 | Organize a ton of photos by hashtags, made to be as fast as possible. 5 | 6 | run with: 7 | python gui.py 8 | 9 | then send your browser to URL: http://localhost:8090/ 10 | 11 | donations: 1676NCiezxodBpM5j1Zafnuxuaeuz2vfPR -------------------------------------------------------------------------------- /gui.py: -------------------------------------------------------------------------------- 1 | from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 2 | import string,cgi,time, json, random, copy, pickle, image64, os 3 | import PIL 4 | from PIL import Image 5 | PORT=8090 6 | picture_height4display=300 #counted in pixels. Change this to change the size of the displayed picture in your browser 7 | picture_height4thumbnail=300 #change this to make the picture in higher or lower detail. smaller numbers are less detailed and load quicker. 8 | output_file='save.txt' 9 | def fs2dic(fs): 10 | dic={} 11 | for i in fs.keys(): 12 | a=fs.getlist(i) 13 | if len(a)>0: 14 | dic[i]=fs.getlist(i)[0] 15 | else: 16 | dic[i]="" 17 | return dic 18 | def to_thumbnail(img): 19 | location=img 20 | baseheight = picture_height4thumbnail 21 | img = Image.open(img) 22 | hpercent = (baseheight/float(img.size[1])) 23 | wsize = int((float(img.size[0])*float(hpercent))) 24 | img = img.resize((wsize,baseheight), PIL.Image.ANTIALIAS) 25 | string=location[-3:]+'_thumbnail.jpg' 26 | img.save(string) 27 | img=file2hexPicture(string) 28 | return img 29 | 30 | form=''' 31 |
{} 34 | ''' 35 | def easyForm(link, button_says, moreHtml='', typee='post'): 36 | a=form.format(link, '{}', button_says, moreHtml, "{}") 37 | if typee=='get': 38 | return a.format('get', '{}') 39 | else: 40 | return a.format('post', '{}') 41 | linkHome = easyForm('/', 'HOME', '', 'get') 42 | def page1(): 43 | fs=fs_load() 44 | tags=[] 45 | for key in fs: 46 | if fs[key]['tag'] not in tags: 47 | tags.append(fs[key]['tag']) 48 | if '' in tags: 49 | tags.remove('') 50 | out="photo organizer
example: /home/Mike/Pictures
{}") 53 | out=out.format(easyForm('/writeQuit', 'Write & Quit')) 54 | out=out.format(easyForm('/delete', 'Delete saved tags')) 55 | ''' for tag in tags: 56 | out=out.format(easyForm('/viewPhotos', 'look at photos tagged as: '+tag, ''.format(tag))) 57 | ''' 58 | for tag in tags: 59 | out=out.format(easyForm('/renameGroup', 'retag every {} photo to: '.format(tag), ''.format(tag))) 60 | return out.format('') 61 | def hex2htmlPicture(string): 62 | return '{}/{}
{}'.format(len(photos)-len(untagged)+1,len(photos),'{}')) 122 | if 'thumbnail' in fs[photo]: 123 | out=out.format(hex2htmlPicture(fs[photo]['thumbnail'])) 124 | else: 125 | out=out.format(file2htmlPicture(photo)) 126 | out=out.format(easyForm('/tagPhotos', 'next_photo', ''.format(dic_in['location']))) 127 | out=out.format(easyForm('/tagPhotos', 'UNDO', ''.format(undoable, dic_in['location']))) 128 | out=out.format(linkHome) 129 | return out.format('') 130 | out=out.format('all photos have been tagged
{}') 131 | out=out.format(easyForm('/tagPhotos', 'UNDO', ''.format(undoable, dic_in['location']))) 132 | out=out.format(linkHome) 133 | return out.format('') 134 | def renameGroup(dic): 135 | newName=dic['newName'] 136 | oldName=dic['oldName'] 137 | fs=fs_load() 138 | for i in fs: 139 | if fs[i]['tag']==oldName: 140 | fs[i]['tag']=newName 141 | fs_save(fs) 142 | out=empty_page 143 | out=out.format('successfully renamed group
{}') 144 | print('linkhome: ' +str(type(linkHome))) 145 | out=out.format(linkHome) 146 | print('out: ' +str(out)) 147 | return out.format('') 148 | def writeQuit(dic): 149 | fs=fs_load() 150 | out={} 151 | for i in fs: 152 | if fs[i]['tag'] not in out: 153 | out[fs[i]['tag']]=[] 154 | out[fs[i]['tag']].append(i) 155 | f=open(output_file, 'w') 156 | for i in out: 157 | for j in out[i]: 158 | f.write('{}\t{}\n'.format(i, j)) 159 | f.close() 160 | out=empty_page.format('successfully saved to file {}
{}'.format(output_file, '{}')) 161 | out=out.format(linkHome) 162 | return out.format('') 163 | def delete(dic): 164 | fs_save(initial_db) 165 | out=empty_page.format('successfully deleted saved tags
{}') 166 | out=out.format(linkHome) 167 | return out.format('') 168 | '''def viewPhotos(dic_in): 169 | out='{}' 170 | photos=[] 171 | fs=fs_load() 172 | print('dic: ' +str(dic_in)) 173 | tag=dic_in['tag'] 174 | for i in fs: 175 | if fs[i]['tag']==tag: 176 | photos.append(i) 177 | if 'picture_numbered' in dic_in: 178 | n=int(dic_in['picture_numbered']) 179 | else: 180 | n=0 181 | out=out.format('photos tagged as {}
{}'.format(tag,'{}')) 182 | if n >= len(photos): 183 | n=0 184 | if 'retag' in dic_in: 185 | fs[photos[n]]['tag']=dic_in['retag'] 186 | fs_save(fs) 187 | photos.remove(photos[n]) 188 | if 'untag' in dic_in: 189 | fs.pop(photos[n]) 190 | fs[photos[n]]='' 191 | fs_save(fs) 192 | photos.remove(photos[n]) 193 | if n >= len(photos): 194 | out=out.format("no photos with this tag
{}") 195 | out=out.format(linkHome) 196 | return out.format('') 197 | out=out.format(file2htmlPicture(photos[n])) 198 | out=out.format(easyForm('/viewPhotos', 'next_photo', ''.format(dic_in['tag'], str(int(dic_in['picture_numbered'])+1)))) 199 | out=out.format(easyForm('/viewPhotos', 'untag_photo', ''.format(dic_in['tag'], dic_in['picture_numbered'], dic_in['picture_numbered']))) 200 | print('dic: ' +str(dic_in)) 201 | out=out.format(easyForm('/viewPhotos', 'retag_photo', ''.format('', dic_in['tag'], dic_in['picture_numbered']))) 202 | out=out.format(linkHome) 203 | return out.format('') 204 | ''' 205 | class MyHandler(BaseHTTPRequestHandler): 206 | def do_GET(self): 207 | try: 208 | if self.path == '/' : 209 | # page = make_index( '.' ) 210 | self.send_response(200) 211 | self.send_header('Content-type', 'text/html') 212 | self.end_headers() 213 | self.wfile.write(page1()) 214 | return 215 | else : # default: just send the file 216 | filepath = self.path[1:] # remove leading '/' 217 | if [].count(filepath)>0: 218 | # f = open( os.path.join(CWD, filepath), 'rb' ) 219 | #note that this potentially makes every file on your computer readable bny the internet 220 | self.send_response(200) 221 | self.send_header('Content-type', 'application/octet-stream') 222 | self.end_headers() 223 | self.wfile.write(f.read()) 224 | f.close() 225 | else: 226 | self.send_response(200) 227 | self.send_header('Content-type', 'text/html') 228 | self.end_headers() 229 | self.wfile.write("