class ElasticSearchModel: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) def get_a_b(self, handle, ring, q=None): # Connect to Elastic Search Node es_url = ES_NODE connections.create_connection(hosts=[es_url]) field = '_all' s = Search(index=handle,doc_type=ring) \ .query("match", **{field:q}) response = s.execute() print("Searching in %s/%s" % (handle, ring)) print(s.to_dict()) #return response out = [] for hit in response: # hit meta contains: index,score,id,doc_type # i.e: hit.meta.score item = collections.OrderedDict() item['_id'] = hit.meta.id #print #print(hit.meta.score) #print('%s/%s/%s'%(hit.meta.index,hit.meta.doc_type,hit.meta.id)) for m in hit: item[m] = hit[m] item[m + '_flag'] = u'1000' #print (m,hit[m]) out.append(item) return out def unindexer(self, handle, ring=None, idx=None): # Connect to Elastic Search Node es = Elasticsearch([ES_NODE]) out = {} out['unindexed'] = [] if handle and ring and idx: es.delete(index=handle, doc_type=ring, id=idx, ignore=[400, 404]) i = '%s/%s/%s' % (handle, ring, idx) elif handle and ring: #es.delete(index=handle,doc_type=ring, ignore=[400, 404]) This doesnt work # Could not make elasticsearch_py delete a doc_type only requests.delete('%s/%s/%s' % (ES_NODE, handle, ring)) i = '%s/%s' % (handle, ring) elif handle: es.indices.delete(index=handle, ignore=[400, 404]) i = '%s' % (handle) self.lggr.info('UnIndexing:%s' % i) out['unindexed'].append(i) d = {} d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' return d #'index':handle,'type':ringname,'id': idx def handle_indexer(self, url, handle): #1. Get all the active rings for this handle self.RIM = RingsModel() ringlist = self.RIM.user_get_rings(handle) print('RINGLIST:', ringlist) #2. Index one by one out = {} out['indexed'] = [] for ring in ringlist: result = self.indexer(url, handle, ring['ringname']) x = json.loads(result['json_out']) out['indexed'] += x['indexed'] self.lggr.info('Handle Indexed:%s' % handle) d = {} d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' return d def indexer(self, url, handle, ring, idx=None): self.lggr.info('START indexer') # Good to Index (a/b) and (a/b/c) as they use same ring_class. # If you want to index a whole handle (a) use handle_indexer # Connect to Elastic Search Node es_url = ES_NODE self.lggr.info('START @ create_connection') connections.create_connection(hosts=[es_url]) self.lggr.info('END @ create_connection') o = urlparse.urlparse(url) if idx: path = '_api/%s/%s/%s' % (handle, ring, idx) else: path = '_api/%s/%s' % (handle, ring) origin_url = urlparse.urlunparse( (URL_SCHEME, o.netloc, path, '', '', '')) schema, items = self.get_items(origin_url) #Preprare the ES Map (as a class) ring_class, ring_map = self.prepare_class(schema) #Create the index in the ES Cluster (indempotent action) self.create_index(ring_class, origin_url) #Index the item d = {} out = {} out['indexed'] = [] for item in items: #Check that item is valid before attempting to index it if self.valid_item(item, ring_map): #try: if True: handle, ring, idx = self.index_item( ring_class, origin_url, item) i = '%s/%s/%s' % (handle, ring, idx) out['indexed'].append(i) self.lggr.info('Indexed:%s' % i) else: #Here we store possible indexing errors if 'not_indexed' not in out: out['not_indexed'] = [] out['not_indexed'].append(item) self.lggr.error('Document invalid. Not Indexed:%s' % item) d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' self.lggr.info('END indexer') return d def valid_item(self, item, ring_map): self.lggr.info('START valid_item') print("Check item against map:") print(ring_map) v_item = {} for f in ring_map: #print(f) valid = False if f in item: #print(ring_map[f],type(ring_map[f])) #if ring_map[f] is elasticsearch_dsl.field.String: if isinstance(ring_map[f], String): #Check if item[f] is a string if (isinstance(item[f], str) or isinstance(item[f], unicode)): valid = True self.lggr.info('%s -> %s is a string (%s)' % (f, item[f], type(item[f]))) else: self.lggr.error('%s -> %s not a string (%s)' % (f, item[f], type(item[f]))) #elif ring_map[f] is elasticsearch_dsl.field.Object: elif isinstance(ring_map[f], Object): #Check if item[f] is an object if isinstance(item[f], dict): v_item[f] = {} print(ring_map[f].properties) for p in ring_map[f].properties: #Check if the property exists in the item if p in item[f]: #Check if the property is an elasticsearch_dsl.field.String: if isinstance(ring_map[f].properties[p], String): #Check if item[f] is a string if (isinstance(item[f][p], str) or isinstance(item[f][p], unicode)): v_item[f][p] = item[f][p] valid = True else: self.lggr.error('%s not a string (%s)' % (item[f], type(item[f]))) else: self.lggr.error('%s not in item' % p) else: self.lggr.error('%s not a dictionary (%s)' % (item[f], type(item[f]))) # TO-DO: Do we want nested objects? If yes develop. if valid: # Add field to the output v_item[f] = item[f] self.lggr.info('Valid item. Will Index') else: self.lggr.info('Invalid item. Will not index') else: self.lggr.info('%s not in map' % f) self.lggr.info('END valid_item') if len(v_item) > 0: return v_item else: return False def valid_api_url(self, url): o = urlparse.urlparse(url) p = o.path.split('/') if p[1] != '_api': path = '/_api' + o.path else: path = o.path return urlparse.urlunparse( (URL_SCHEME, o.netloc, path, '', 'schema=1&limit=_all', '')) def get_items(self, url): url = self.valid_api_url( url) + '&access_token=%s&fieldid=1' % TEMP_ACCESS_TOKEN self.lggr.info('START get_items ->%s' % url) result = requests.get(url, verify=False) self.lggr.info('result ->%s' % result.text) self.lggr.info('result.text ->%s' % result.text) r = result.json() self.lggr.info('result.json() ->%s' % r) schema = {'rings': r['rings'], 'fields': r['fields']} items = r['items'] self.lggr.info('END get_items') return schema, items def prepare_class(self, schema): self.lggr.info('START prepare_class') d = {} for field in schema['fields']: if field['FieldType'] == 'INTEGER': d[field['FieldId']] = Integer() elif field['FieldType'] == 'OBJECT': if field['FieldMultilingual']: f = {} f['spa'] = String(analyzer='spanish') f['eng'] = String(analyzer='english') f['ita'] = String(analyzer='italian') f['fra'] = String(analyzer='french') d[field['FieldId']] = Object(properties=f) else: #Some other kind of object d[field['FieldId']] = String() elif field['FieldType'] == 'ARRAY': d[field['FieldId']] = String() elif field['FieldType'] == 'BOOLEAN': d[field['FieldId']] = Integer() else: d[field['FieldId']] = String() print(d) raw_map = d.copy() self.lggr.info('END prepare_class') return type(str(schema['rings'][0]['RingName']), (DocType, ), d), raw_map def subtract_h_r_i(self, origin_url): self.lggr.info('START subtract_h_r_i') url = self.valid_api_url(origin_url) print(url) o = urlparse.urlparse(url) p = o.path.split('/') handle = p[2] if len(p) >= 4: ringname = p[3] else: ringname = None if len(p) >= 5: idx = p[4] else: idx = None self.lggr.info('END subtract_h_r_i') return handle, ringname, idx def create_index(self, ring_class, origin_url): self.lggr.info('START create_index') handle, ringname, idx = self.subtract_h_r_i(origin_url) # create the mappings in elasticsearch R = ring_class.init(handle) self.lggr.info('END create_index') return R def index_item(self, ring_class, origin_url, item): self.lggr.info('START index_item') handle, ringname, idx = self.subtract_h_r_i(origin_url) #overwrite the idx with items idx = item['_id'] # create the mappings in elasticsearch #print(R) #print(handle) #print(ringname) #print(idx) #print(item) # create and save an item article = ring_class(meta={ 'index': handle, 'type': ringname, 'id': idx }, **item) print(article) article.save() print('SAVED') self.lggr.info('END index_item') return (handle, ringname, idx)
class TeamsController: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) self.TEM = TeamsModel(tid=tid, ip=ip) self.PEM = PeopleModel(tid=tid, ip=ip) # GET/a def get_a_m(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization d['teamlistlen'] = len(peopleteams['teams']) d['teammembership'] = {} allteams = {} for teamd in peopleteams['teams']: #get the profilepic for this person self.lggr.debug('teamname:%s' % teamd['teamname']) for member in teamd['members']: self.lggr.debug('member:%s' % member['handle']) person_user_doc = self.MAM.select_user_doc_view( 'auth/userbasic', member['handle']) if person_user_doc: member['thumbnail'] = person_user_doc['profilepic'] if current_user.id == member['handle']: self.lggr.debug('%s is member' % member['handle']) if teamd['teamname'] == 'owner': d['teammembership'][ teamd['teamname']] = 'org_owner' else: if len(teamd['roles']) >= 1: d['teammembership'][teamd['teamname']] = teamd[ 'roles'][-1]['role'] allteams[teamd['teamname']] = 'org_owner' if 'owner' in d['teammembership']: d['teammembership'] = allteams d['teamlist'] = peopleteams['teams'] d['template'] = 'avispa_rest/get_a_m.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d # POST/a def post_a_m(self, handle, team, rqform=None, *args, **kargs): ''' Creates a new team ''' #We need to recover from request as it doesn't come via URL team = rqform.get('newteam') #Check if the team exists or not d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: redirect = url_for('avispa_rest.teams_a_m', handle=handle, _external=True, _scheme=URL_SCHEME) #This is an organization for teamd in peopleteams['teams']: if teamd['teamname'] == team: #This team exists in this handle! flash('This team exists already. Use a different name', 'ER') #redirect = '/'+handle+'/_teams' d = {'redirect': redirect, 'status': 200} return d if self.MAM.add_team(handle, team, current_user.id): self.lggr.debug('Awesome , you just created team %s ' % team) #msg = 'Item put with id: '+idx flash('Awesome , you just created team %s ' % team, 'UI') else: flash('There was an error adding team %s ' % team, 'UI') else: #This is not an organization #redirect = '/'+current_user.id redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def get_a_m_n(self, handle, team, *args, **kargs): d = {} rings = self.MAM.select_user_doc_view('rings/count', handle) d['rings'] = rings peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: if teamd['roles']: if teamd['roles'][-1]['role'] == 'team_admin': teamauth = 'RWX' elif teamd['roles'][-1]['role'] == 'team_writer': teamauth = 'RW' elif teamd['roles'][-1]['role'] == 'team_reader': teamauth = 'R' else: teamauth = '' teamd['teamauth'] = teamauth for member in teamd['members']: person_user_doc = self.MAM.select_user_doc_view( 'auth/userbasic', member['handle']) if person_user_doc: member['thumbnail'] = person_user_doc['profilepic'] d['team'] = teamd break d['template'] = 'avispa_rest/get_a_m_n.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d #DEPRECATED def put_a_m_n(self, handle, team, rqform=None, rqargs=None, *args, **kargs): #This function should be refactored into multiple functions that obey RESTFUL: # post_a_m_n_members , delete_a_m_n_members , post_a_m_n_rings, delete_a_m_n_rings d = {} if 'newmember' in rqform: member = rqform.get('newmember') if self.TEM.post_a_m_n_members(handle, team, member): self.lggr.debug('%s has been added to the team.' % member) flash('%s has been added to the team.' % member, 'UI') else: self.lggr.debug('%s is already part of this team.' % member) flash('%s is already part of this team.' % member, 'UI') if 'delmember' in rqargs: member = rqargs.get('delmember') if self.TEM.delete_a_m_n_members(handle, team, member): self.lggr.debug('%s has been deleted from the team.' % member) flash('%s has been deleted from the team.' % member, 'UI') else: self.lggr.error('There was an issue deleting: %s' % member) flash('There was an issue deleting: %s' % member, 'UI') if 'newring' in rqform: ring = rqform.get('newring') if self.TEM.post_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been added to the team.' % ring) flash('%s has been added to the team.' % ring, 'UI') else: self.lggr.error('%s already exists in this team.' % ring) flash('%s already exists in this team.' % ring, 'UI') if 'delring' in rqargs: ring = rqargs.get('delring') if self.TEM.delete_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been deleted from the team.' % ring) flash('%s has been deleted from the team.' % ring, 'UI') else: self.lggr.error('There was an issue deleting: %s' % ring) flash('There was an issue deleting: %s' % ring, 'UI') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d def post_a_m_n_p(self, handle, team, rqform): d = {} member = rqform.get('newmember') if self.TEM.post_a_m_n_members(handle, team, member): self.lggr.debug('%s has been added to the team.' % member) flash('%s has been added to the team.' % member, 'UI') else: self.lggr.debug('%s is already part of this team.' % member) flash('%s is already part of this team.' % member, 'UI') return d def delete_a_m_n_p_q(self, handle, team, member): '''Deletes a member from a team''' d = {} if self.TEM.delete_a_m_n_members(handle, team, member): self.lggr.debug('%s has been deleted from the team.' % member) flash('%s has been deleted from the team.' % member, 'UI') else: self.lggr.error('There was an issue deleting: %s' % member) flash('There was an issue deleting: %s' % member, 'UI') '''User Garbage collection''' # If a user no longer belongs to any team, it should be also released from the org # 1. Call TeamModel to check if this <member> exists in any other <team> in this <handle> memberships = self.TEM.get_a_m_all_p_q(handle, member) raise Exception # 2. If it doesn't, call the PeopleModel to delete this user if len(memberships) == 0: self.PEM.delete_a_p_q(handle, member) return d def post_a_m_n_r(self, handle, team, rqform): d = {} ring = rqform.get('newring') if self.TEM.post_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been added to the team.' % ring) flash('%s has been added to the team.' % ring, 'UI') else: self.lggr.error('%s already exists in this team.' % ring) flash('%s already exists in this team.' % ring, 'UI') return d def delete_a_m_n_r_b(self, handle, team, ring): d = {} if self.TEM.delete_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been deleted from the team.' % ring) flash('%s has been deleted from the team.' % ring, 'UI') else: self.lggr.error('There was an issue deleting: %s' % ring) flash('There was an issue deleting: %s' % ring, 'UI') return d #DELETE /a/b def delete_a_m_n(self, handle, team, *args, **kargs): #Will delete an existing team self.lggr.debug('Trying to delete the following team: %s' % team) d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization for teamd in peopleteams['teams']: if teamd['teamname'] == team: if self.MAM.delete_team(handle, team): self.lggr.debug('You just deleted team %s' % team) flash('You just deleted team %s' % team, 'UI') else: self.lggr.error( 'There was an error deleting team: %s' % team) flash('There was an error deleting team: %s' % team, 'ER') redirect = url_for('avispa_rest.teams_a_m', handle=handle, _external=True, _scheme=URL_SCHEME) else: #This is not an organization #redirect = '/'+current_user.id redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def get_a_m_n_settings(self, handle, team, *args, **kargs): #redirect = '/'+handle+'/_teams/'+team redirect = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def put_rq_a_m_n_settings(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: if teamd['roles']: if teamd['roles'][-1]['role'] == 'team_admin': teamauth = 'RWX' elif teamd['roles'][-1]['role'] == 'team_writer': teamauth = 'RW' elif teamd['roles'][-1]['role'] == 'team_reader': teamauth = 'R' else: teamauth = '' teamd['teamauth'] = teamauth d['team'] = teamd break d['template'] = 'avispa_rest/put_rq_a_m_n_settings.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d def put_a_m_n_settings(self, handle, team, rqform=None, *args, **kargs): d = {} p = {} if ('description' in rqform) or ('teamauth' in rqform): p['description'] = rqform.get('description') p['teamauth'] = rqform.get('teamauth') if self.TEM.put_a_m_n_settings(handle, team, p): self.lggr.debug('%s has been updated.' % team) flash('%s has been updated.' % team, 'UI') else: self.lggr.error('There was a problem updating team %s' % team) flash('There was a problem updating team %s' % team, 'ER') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d def get_a_m_n_invite(self, handle, team, *args, **kargs): #redirect = '/'+handle+'/_teams/'+team redirect = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def put_rq_a_m_n_invite(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: d['team'] = teamd break d['template'] = 'avispa_rest/put_rq_a_m_n_invite.html' return d def put_a_m_n_invite(self, handle, team, rqurl=None, rqform=None, *args, **kargs): d = {} self.EMM = EmailModel() collabraw = rqform.get('emails') valid_emails, invalid_emails = address.validate_list(collabraw, as_tuple=True) self.lggr.debug('valid_emails:%s' % valid_emails) self.lggr.debug('invalid_emails:%s' % invalid_emails) #2. If it is an email, send ring subscription url/token o = urlparse.urlparse(rqurl) host_url = urlparse.urlunparse((o.scheme, o.netloc, '', '', '', '')) #2a PENDING # Subtract team object from org document peopleteams = self.MAM.is_org(handle) if peopleteams: for teamd in peopleteams['teams']: teamfound = False if teamd['teamname'] == team: # This team actually exists in this org. You can continue with the invitations teamfound = True break if not teamfound: # This team doesnt exist. No invitation can be sent #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d # teamd carries the team object #Try to convert invalid_emails (myringIDs) into valid_emails for invite_handle in invalid_emails: user_doc = self.MAM.select_user_doc_view('auth/userbyhandle', invite_handle) if user_doc: if user_doc['email'] not in valid_emails: valid_emails.append(user_doc['email']) for email in valid_emails: email = str(email) invite = {} invite['email'] = email invite['count'] = 1 invite['team'] = team invite['token'] = flask_bcrypt.generate_password_hash( email + str(random.randint(0, 9999))) invite['lasttime'] = str(datetime.now()) invite['author'] = current_user.id user_doc = self.MAM.select_user_doc_view('auth/userbyemail', email) if user_doc: #You are inviting an existing myRing user existinguser = True else: #You are inviting a soon to be myRing user existinguser = False token = invite['token'] to = email subject = handle + " has invited you to collaborate in the following team : " + team # https://avispa.myring.io/_register?h=cdmit&t=staff&k=11111&[email protected] content = "Click here to start working with this team: " + host_url + "/_register?h=" + handle + "&t=" + team + "&k=" + token + "&e=" + email self.lggr.debug('%s,%s,%s' % (to, subject, content)) if self.EMM.send_one_email(to, subject, content): flash("Invitation email sent.", 'UI') self.MAM.append_to_user_field(handle, 'invitations', invite) else: flash("Invitation email failed.", 'UI') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d
class Upload: def __init__(self, handle): self.handle = handle self.rs_status = '' self.officialsizes = { 'r100': 100, 'r240': 240, 'r320': 320, 'r500': 500, 'r640': 640, 'r800': 800, 'r1024': 1024 } self.thumbnailsizes = {'t75': 75, 't150': 150} self.allowed_formats = set( ['txt', 'pdf', 'png', 'jpg', 'JPG', 'jpeg', 'gif']) logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, { 'tid': g.get('tid', None), 'ip': g.get('ip', None) }) def blob_from_s3(self, bucket, id): #Subtract original from s3 and put it in memory image_binary = '' return image_binary def blob_from_file(self, file): #Load the image blob print(file) file.seek(0) image_binary = file.read() return image_binary #DRIVER FUNCTION def do_upload(self, image_binary): response = {} image_sizes = [] #Load the image with Image(blob=image_binary) as img: #Prepare image components imgid = self._generate_imgid() filename = imgid + '.jpg' #Image analysis longside, shortside, orientation = self._img_orientation( img.width, img.height) #Constrain original if needed if longside > 2000: img = self._img_resize(img, 2000, orientation) path = '%s/%s' % (self.handle, 'o') self._s3_save(img, path, filename) m = self._generate_metadata(img.width, img.height, 'o') image_sizes.append(m) #Save scaled down versions and thumbnail #Plan of action regular_wo, thumb_wo = self._image_workorder(longside, shortside) #Scaled down versions for wo in regular_wo: with img.clone() as i: ii = self._img_resize(i, regular_wo[wo], orientation) path = '%s/%s' % (self.handle, wo) if STORE_MODE == 'LOCAL': self._local_save(i, path, filename) elif STORE_MODE == 'S3': self._s3_save(i, path, filename) m = self._generate_metadata(ii.width, ii.height, wo) image_sizes.append(m) #Thumbnail versions for wo in thumb_wo: with img.clone() as i: ii = self._img_resize(i, thumb_wo[wo], orientation) iii = self._img_thumbcrop(ii, orientation) path = '%s/%s' % (self.handle, wo) self._file_save(i, path, filename) m = self._generate_metadata(iii.width, iii.height, wo) image_sizes.append(m) response['status'] = self.rs_status response['imgid'] = imgid response['imgsizes'] = image_sizes return response #DRIVER FUNCTION def do_copy(self, from_handle, to_handle, imgid): #Pull file from S3 bucket f = self._pull_file_from_s3(origin, targetimgid) return response def _generate_metadata(self, width, height, sizename): multiplied = {} multiplied['mime-type'] = 'image/jpeg' multiplied['extension'] = 'jpg' multiplied['width'] = width multiplied['height'] = height multiplied['sizename'] = sizename multiplied['unit'] = 'pixel' #self.lggr.debug(multiplied) return multiplied def check_extension(self, filename): #TO-DO This a very soft check. Please implement Real Format Check if not '.' in filename and filename.rsplit( '.', 1)[1] in self.allowed_formats: self.lggr.error('Error: This file format is not allowed: ' + str(filename)) flash(u'This file format is not allowed: ' + str(filename), 'ER') self.rs_status = '415' return False return True def _pull_file_from_s3(self, handle, imgid): pass #1. Subtract image from S3 #2. Put it in self.f def _generate_imgid(self): return str(random.randrange(1000000000, 9999999999)) def _image_workorder(self, longside, shortside): regular_wo = {} thumb_wo = {} for r in self.officialsizes: if longside >= self.officialsizes[r]: regular_wo[r] = self.officialsizes[r] for t in self.thumbnailsizes: if shortside >= self.thumbnailsizes[t]: thumb_wo[t] = self.thumbnailsizes[t] return (regular_wo, thumb_wo) def _img_orientation(self, width, height): if width > height: longside = width shortside = height orientation = "landscape" if width < height: longside = height shortside = width orientation = "portrait" if width == height: longside = height shortside = width orientation = "square" return longside, shortside, orientation def _img_resize(self, img, mainside, orientation): if orientation == 'portrait': img.transform(resize='x' + str(mainside)) #Height based #img.resize(height=int(mainside)) elif orientation == 'landscape': img.transform(resize=str(mainside)) #Width based #img.resize(width=int(mainside)) #img.transform(resize=str(mainside)) elif orientation == 'square': img.transform(resize=str(mainside)) #Width based #img.resize(width=int(mainside)) return img def _img_thumbcrop(self, img, orientation): offset = abs(img.width - img.height) / 2 #This centers the crop if orientation == 'portrait': img.crop(0, offset, width=img.width, height=img.width) if orientation == 'landscape': img.crop(offset, 0, width=img.height, height=img.height) return img def _file_save(self, file, path, filename): self._s3_save(file, path, filename) def _s3_save(self, file, path, filename): self.lggr.info("Storing image in S3: %s/%s" % (path, filename)) conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) bucket = conn.get_bucket(IMAGE_BUCKET_NAME) #k = Key(bucket) k = boto.s3.key.Key(bucket) k.key = '%s/%s' % (path, filename) print(k) print(k.key) print(file) fl = cStringIO.StringIO() file.save(fl) #print fl fl.seek(0) k.set_contents_from_file(fl) k.set_acl('public-read') #AttributeError: 'Image' object has no attribute 'tell' #b = fl.read() #print(b) #k.set_contents_from_string(b) return True def check_upload_path(self, path): pass def check_filename(self): pass def set_max_filesize(self): pass def set_max_filename(self): pass def set_max_width(self): pass def set_max_height(self): pass def set_allowed_types(self, types): pass def set_image_properties(self): pass def set_xss_clean(self): pass def is_image(self): pass def is_allowed_filetype(self): pass def is_allowed_filesize(self): pass def is_allowed_dimensions(self): pass def validate_upload_path(self): pass def get_extension(self, filename): pass def clean_file_name(self, filename): pass def limit_filename_length(self, filename, length): pass def do_xss_clean(self): pass def set_error(self, msg): pass def display_errors(self): pass def mime_types(self, mime): pass def _prep_filename(self, filename): pass def _file_mime_type(self, file): pass
class PeopleController: def __init__(self,tid=None,ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.MAM = MainModel(tid=tid,ip=ip) self.PEM = PeopleModel(tid=tid,ip=ip) self.TEM = TeamsModel(tid=tid,ip=ip) # GET/a def get_a_p(self,handle,person,*args,**kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization d['peoplelist'] = peopleteams['people'] d['peoplelistlen'] = len(peopleteams['people']) for person in peopleteams['people']: #get the profilepic for this person person_user_doc = self.MAM.select_user_doc_view('auth/userbasic',person['handle']) if person_user_doc: person['thumbnail'] = person_user_doc['profilepic'] person['memberships'] = self.TEM.get_a_m_all_p_q(handle,person['handle']) d['template'] = 'avispa_rest/get_a_p.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d # POST/a def post_a_p(self,handle,person,rqform=None,*args,**kargs): #We need to recover from request as it doesn't come via URL person = rqform.get('newperson') #Check if the user exists or not if self.MAM.user_exists(person): result = self.PEM.post_a_p(handle,person) if result: self.lggr.debug('Awesome , you just added %s to the organization'%person) #msg = 'Item put with id: '+idx flash('Awesome , you just added %s to the organization'%person,'UI') else: self.lggr.error('Awesome , you just added %s to the organization'%person) flash('There was an error adding %s to the organization.'%s,'ER') else: self.lggr.debug('%s is not a MyRing user. Please create it first.'%person) flash('%s is not a MyRing user. Please create it first.'%person,'ER') #redirect = '/'+handle+'/_people' redirect = url_for('avispa_rest.people_a_p', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status':200} return d #DELETE /a/b def delete_a_p_q(self,handle,person,*args,**kargs): #Will delete an existing person self.lggr.debug('Trying to delete the following person: %s'%person) #Check if the user exists or not if self.MAM.user_exists(person): result = self.PEM.delete_a_p_q(handle,person) if result: self.lggr.debug('You just deleted %s from the organization'%person) flash('You just deleted %s from the organization'%person,'UI') else: self.lggr.error('There was an error deleting %s from the organization.'%person) flash('There was an error deleting %s from the organization.'%person,'ER') else: self.lggr.debug('%s is not a MyRing user.'%person) flash('%s is not a MyRing user.'%person,'ER') #redirect = '/'+handle+'/_people' redirect = url_for('avispa_rest.people_a_p', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status':200} return d
class User(UserMixin): def __init__(self, username=None, email=None, passhash=None, owner=None, location=None, url=None, profilepic=None, name=None, isOrg=False, active=True, id=None, onlogin=False, about=None, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.lggr.debug('__init__()') self.username = username self.email = email self.location = location self.passhash = passhash self.about = about self.url = url self.profilepic = profilepic self.name = name self.isOrg = isOrg self.active = active self.isAdmin = False self.id = None self.onlogin = onlogin if owner: self.owner = owner else: self.owner = username if isinstance(self.location, basestring): self.location = self.location.lower() if isinstance(self.email, basestring): self.email = self.email.lower() if isinstance(self.username, basestring): self.usernme = self.username.lower() self.ATM = AuthModel() def set_user(self): user = {} # Defaults coming via self user['username'] = self.username user['email'] = self.email user['location'] = self.location user['owner'] = self.owner user['location'] = self.location user['url'] = self.url user['profilepic'] = self.profilepic user['name'] = self.name user['passhash'] = self.passhash user['onlogin'] = self.onlogin user['about'] = self.about self.lggr.info(user) if not self.isOrg: self.lggr.info('is an Org') #You are registering a regular User if self.ATM.saas_create_user(user): self.lggr.info("new user id = %s " % user['username']) return user['username'] else: return False else: self.lggr.info('is NOT an Org') #You are registering an Organization if self.ATM.saas_create_orguser(user): self.lggr.info("new organization id = %s " % user['username']) return user['username'] else: return False def set_password_key(self, key): self.lggr.info('set_password_key:') self.lggr.info(self.id) return self.ATM.saas_create_password_key(self.id, key) def set_password(self, passhash): self.lggr.info('set_password:'******'value']['email'] self.location = dbUser['value']['location'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: return None except: self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error("there was an error") return None def get_user(self): #raise Exception ('stop here') try: if self.email: self.lggr.debug('self.email:' + self.email) dbUser = self.ATM.userdb_get_user_by_email(self.email) elif self.username: self.lggr.info('START AUTHENTICATION:' + self.username) dbUser = self.ATM.userdb_get_user_by_handle(self.username) else: return None if dbUser: self.lggr.info("END AUTHENTICATION:%s" % dbUser['value']['name']) self.name = dbUser['value']['name'] self.email = dbUser['value']['email'] self.url = dbUser['value']['url'] self.profilepic = dbUser['value']['profilepic'] self.location = dbUser['value']['location'] self.about = dbUser['value']['about'] self.onlogin = dbUser['value']['onlogin'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: self.lggr.error('User: not found') return None except (KeyError): self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error( "there was an error, we need to repair the user_document") preconditions = [ 'name', 'email', 'url', 'profilepic', 'location', 'about', 'onlogin' ] repaired = False for element_to_add in preconditions: MAM = MainModel() if MAM.repair_user_doc(element_to_add, dbUser['value']['_id']): repaired = True self.lggr.info('Repaired ' + element_to_add + '. ') #flash('Repaired '+element_to_add+'. ') #Let's try again if repaired: if self.email: dbUser = self.ATM.userdb_get_user_by_email(self.email) elif self.username: dbUser = self.ATM.userdb_get_user_by_handle(self.username) if dbUser: self.name = dbUser['value']['name'] self.email = dbUser['value']['email'] self.url = dbUser['value']['url'] self.profilepic = dbUser['value']['profilepic'] self.location = dbUser['value']['location'] self.about = dbUser['value']['about'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: return False else: return False def update_user_profile(self, request): dbUser = self.ATM.userdb_get_user_by_handle(self.username) changes = {} if dbUser: if request.form.get('profilepic') != dbUser['value']['profilepic']: self.lggr.info('profilepic changed!') changes['profilepic'] = request.form.get('profilepic') if request.form.get('name') != dbUser['value']['name']: self.lggr.info('name changed!') changes['name'] = request.form.get('name') mp_change = True if request.form.get('url') != dbUser['value']['url']: self.lggr.info('url changed!') changes['url'] = request.form.get('url') if request.form.get('location') != dbUser['value']['location']: self.lggr.info('location changed!') changes['location'] = request.form.get('location') if request.form.get('about') != dbUser['value']['about']: self.lggr.info('about changed!') changes['about'] = request.form.get('about') if request.form.get('onlogin') != dbUser['value']['onlogin']: self.lggr.info('onlogin changed!') changes['onlogin'] = request.form.get('onlogin') return self.ATM.saas_update_user_profile(self.username, changes) def is_valid_password_key(self, email, key): try: #self.lggr.info('flag1') dbUser = self.ATM.userdb_get_user_by_email(email) #self.lggr.info('flag2') #self.lggr.info(dbUser) if dbUser['value']['new_password_key'] == key: return True else: return False except: self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error("There was an error validating the Key") return False def is_active(self): return self.active def is_authenticated(self): return True def is_anonymous(self): return False
class CollectionsModel: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) #COLLECTIONSMODEL def get_a_x(self, handle): # Returns list of collections try: doc = self.MAM.select_user(handle) collections = doc['collections'] rings = doc['rings'] # 1. Here we need to call the DB again but now to get which validring = {} ringorigins = {} ringcounts = {} for ring in rings: if not 'deleted' in ring: ringname = str(ring['ringname']) if 'origin' in ring: ringorigin = str(ring['origin']) else: ringorigin = str(handle) ringorigins[ringname] = ringorigin ringcounts[ringname] = ring['count'] #raise Exception('debug') self.lggr.info(ringcounts) for coll in collections: for ring in coll['rings']: if ring['ringname'] in ringcounts: ring['count'] = ringcounts[ring['ringname']] if ring['ringname'] in ringorigins: ring['ringorigin'] = ringorigins[ring['ringname']] return collections except (ResourceNotFound, TypeError) as e: self.lggr.error("Notice: Expected error:%s,%s" % (sys.exc_info()[0], sys.exc_info()[1])) return False #COLLECTIONSMODEL def post_a_x(self, handle, collectiond): '''Creates new collection''' doc = self.MAM.select_user(handle) if 'description' not in collectiond: collectiond['description'] = '' newcollection = { 'collectionname': str(collectiond['name']), 'collectiondescription': str(collectiond['description']), 'version': str(collectiond['version']), 'rings': collectiond['ringlist'], 'added': str(datetime.now()) } doc['collections'].append(newcollection) self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def get_a_x_y(self, handle, collection): #Not used directly, but used by put_rq_a_x_y to return collection details #Returns just one collection try: doc = self.MAM.select_user(handle) collections = doc['collections'] rings = doc['rings'] validring = {} for ring in rings: if not 'deleted' in ring: ringname = str(ring['ringname']) validring[ringname] = ring['count'] for coll in collections: #coll['valid'] = True if coll['collectionname'] == collection: #coll['valid'] = True for ring in coll['rings']: if ring['ringname'] in validring: ring['count'] = validring[ring['ringname']] else: pass #InValid Collection, at least one of its rings is marked as deleted #coll['valid'] = False return coll return False except (ResourceNotFound, TypeError) as e: self.lggr.error("Notice: Expected error:%s,%s" % (sys.exc_info()[0], sys.exc_info()[1])) #COLLECTIONSMODEL def put_a_x_y(self, handle, collectiond): doc = self.MAM.select_user(handle) newcollection = { 'collectionname': str(collectiond['name']), 'collectiondescription': str(collectiond['description']), 'version': str(collectiond['version']), 'rings': collectiond['ringlist'], 'added': str(datetime.now()) } i = 0 for coll in doc['collections']: if coll['collectionname'] == newcollection['collectionname']: #This is a match. This is what we need to replace with incoming document doc['collections'][i] = newcollection i = i + 1 self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def patch_a_x_y(self, handle, collection, collectiond): doc = self.MAM.select_user(handle) path = {} if 'name' in collectiond: patch['collectionname'] = str(collectiond['name']) if 'description' in collectiond: patch['collectiondescription'] = str(collectiond['description']) if 'version' in collectiond: patch['version'] = str(collectiond['version']) if 'rings' in collectiond: patch['rings'] = collectiond['ringlist'] i = 0 for coll in doc['collections']: if coll['collectionname'] == collection: for p in patch: doc['collections'][i][p] = patch[p] i = i + 1 self.MAM.post_user_doc(doc) return True def add_ring_to_collection(self, handle, collection, ringd): doc = self.MAM.select_user(handle) for coll in doc['collections']: if coll['collectionname'] == collection: coll['rings'].append(ringd) self.lggr.info('Ring added to collection:', doc) self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def delete_a_x_y(self, handle, collection): doc = self.MAM.select_user(handle) i = 0 for coll in doc['collections']: if coll['collectionname'] == collection: del doc['collections'][i] i = i + 1 self.MAM.post_user_doc(doc) return True