def add_custom_queries(request, url, debug_content=None, exclude=False): """ Add custom query parameters to the input url Inputs: :request: HttpRequest for this session :url: URL that query parameters will be added to :debug_content: Optional list of debug strings (Default: None) :exclude: Boolean; Should we prevent internal query strings (vs, z) from being added to the url (Default: False) Outputs: :redirect_url: Input url with added query strings, minus site id """ custom_queries = '&%s' % request.META.get('QUERY_STRING') params = {'url': url, 'query': custom_queries, 'exclusions': ['my.jobs.site.id']} if exclude: params['exclusions'] += ['vs', 'z'] redirect_url = replace_or_add_query(**params) if debug_content is not None: debug_content.append( 'ManipulatedLink(Custom Parameters)=%s' % redirect_url) return redirect_url
def add_custom_queries(request, url, debug_content=None, exclude=False): """ Add custom query parameters to the input url Inputs: :request: HttpRequest for this session :url: URL that query parameters will be added to :debug_content: Optional list of debug strings (Default: None) :exclude: Boolean; Should we prevent internal query strings (vs, z) from being added to the url (Default: False) Outputs: :redirect_url: Input url with added query strings, minus site id """ custom_queries = '&%s' % request.META.get('QUERY_STRING') params = { 'url': url, 'query': custom_queries, 'exclusions': ['my.jobs.site.id'] } if exclude: params['exclusions'] += ['vs', 'z'] redirect_url = replace_or_add_query(**params) if debug_content is not None: debug_content.append('ManipulatedLink(Custom Parameters)=%s' % redirect_url) return redirect_url
def get_syndication_redirect(request, redirect, guid, view_source, debug_content=None): """ Determines if the originating request was directed from a syndication feed, retrieves the site we are redirecting to, and constructs a response. Inputs: :request: HttpRequest for this session :redirect: Redirect instance for the current job GUID :view_source: :debug_content: List of debug strings (if provided) or None Outputs: :response: HttpResponsePermanentRedirect object if this is a syndication hit, otherwise None """ new_site_id = request.REQUEST.get('my.jobs.site.id', None) response = None if new_site_id is not None: try: new_site_id = int(new_site_id) except ValueError: pass else: try: site = Site.objects.get(id=new_site_id) except Site.DoesNotExist: return None redirect_url = 'http://{domain}/{id}/job/?vs={view_source}'.format( domain=site.domain, id=guid, view_source=view_source) enable_custom_queries = request.REQUEST.get('z') == '1' if enable_custom_queries: redirect_url = add_custom_queries(request, redirect_url, debug_content) redirect_url = add_view_source_group(redirect_url, view_source) if request.REQUEST.get('z') == '1': # Add all query parameters but my.jobs.site.id to redirect_url. redirect_url = replace_or_add_query( redirect_url, '&%s' % request.META.get('QUERY_STRING'), exclusions=['my.jobs.site.id']) response = HttpResponsePermanentRedirect(redirect_url) if debug_content is not None: debug_content.append('Syndication feed override: %s(%s)' % (site.name, site.domain)) debug_content.append('Syndication URL: %s' % redirect_url) return response
def add_view_source_group(url, view_source): """ Add Google Analytics campaigns to the given url, if applicable. """ vs = ViewSource.objects.filter( view_source_id=view_source).prefetch_related( 'viewsourcegroup_set').first() if (vs is not None and vs.include_ga_params and vs.viewsourcegroup_set.exists()): url = replace_or_add_query( url, '&utm_source={source}-DE' '&utm_medium={group}' '&utm_campaign={source}'.format( source=vs.name, group=vs.viewsourcegroup_set.first().name)) return url
def get_syndication_redirect(request, redirect, guid, view_source, debug_content=None): """ Determines if the originating request was directed from a syndication feed, retrieves the site we are redirecting to, and constructs a response. Inputs: :request: HttpRequest for this session :redirect: Redirect instance for the current job GUID :view_source: :debug_content: List of debug strings (if provided) or None Outputs: :response: HttpResponsePermanentRedirect object if this is a syndication hit, otherwise None """ new_site_id = request.REQUEST.get('my.jobs.site.id', None) response = None if new_site_id is not None: try: new_site_id = int(new_site_id) except ValueError: pass else: try: site = Site.objects.get(id=new_site_id) except Site.DoesNotExist: return None redirect_url = 'http://{domain}/{id}/job/?vs={view_source}'.format( domain=site.domain, id=guid, view_source=view_source) enable_custom_queries = request.REQUEST.get('z') == '1' if enable_custom_queries: redirect_url = add_custom_queries(request, redirect_url, debug_content) redirect_url = add_view_source_group(redirect_url, view_source) if request.REQUEST.get('z') == '1': # Add all query parameters but my.jobs.site.id to redirect_url. redirect_url = replace_or_add_query( redirect_url, '&%s' % request.META.get('QUERY_STRING'), exclusions=['my.jobs.site.id']) response = HttpResponsePermanentRedirect(redirect_url) if debug_content is not None: debug_content.append('Syndication feed override: %s(%s)' % (site.name, site.domain)) debug_content.append('Syndication URL: %s' % redirect_url) return response
def add_view_source_group(url, view_source): """ Add Google Analytics campaigns to the given url, if applicable. """ vs = ViewSource.objects.filter( view_source_id=view_source).prefetch_related( 'viewsourcegroup_set').first() if (vs is not None and vs.include_ga_params and vs.viewsourcegroup_set.exists()): url = replace_or_add_query( url, '&utm_source={source}-DE' '&utm_medium={group}' '&utm_campaign={source}'.format( source=vs.name, group=vs.viewsourcegroup_set.first().name)) return url
def do_manipulations(guid_redirect, manipulations, return_dict, debug_content=None): """ Performs the manipulations denoted by :manipulations: Inputs: :guid_redirect: Redirect object for this job :manipulations: List of DestinationManipulation objects :return_dict: Dictionary of values used in all levels of the main redirect view :debug_content: List of strings that will be output on the debug page Modifies: :return_dict: Potentially modifies the redirect_url key :debug_content: Potentially adds new debug strings """ if manipulations and not return_dict['redirect_url']: for manipulation in manipulations: method_name = manipulation.action if debug_content: debug_content.append( 'ActionTypeID=%s Action=%s' % (manipulation.action_type, manipulation.action)) try: redirect_method = getattr(redirect.actions, method_name) except AttributeError: pass else: if manipulation.action in [ 'doubleclickwrap', 'replacethenaddpre', 'sourceurlwrap', 'sourceurlwrapappend', 'sourceurlwrapunencoded', 'sourceurlwrapunencodedappend' ]: # These actions all result in our final url being # appended, usually as a query string, to a value # determined by the manipulation object; due to # this, we should add any custom query parameters # before doing the manipulation. if return_dict['enable_custom_queries']: guid_redirect.url = replace_or_add_query( guid_redirect.url, '&%s' % return_dict.get('qs'), exclusions=['vs', 'z']) redirect_url = redirect_method(guid_redirect, manipulation) else: redirect_url = redirect_method(guid_redirect, manipulation) # manipulations is a QuerySet, which doesn't # support negative indexing; reverse the set and # take the first element to get the last # DestinationManipulation object. if manipulation == manipulations.reverse()[:1][0]: # Only add custom query parameters after # processing the final DestinationManipulation # object to ensure we're not needlessly # replacing them on each iteration. if return_dict['enable_custom_queries']: redirect_url = replace_or_add_query( redirect_url, '&%s' % return_dict.get('qs'), exclusions=['vs', 'z']) return_dict['redirect_url'] = redirect_url if debug_content: debug_content.append( 'ActionTypeID=%s ManipulatedLink=%s VSID=%s' % (manipulation.action_type, return_dict['redirect_url'], manipulation.view_source)) guid_redirect.url = return_dict['redirect_url']
def get_redirect_url(request, guid_redirect, vsid, guid, debug_content=None): """ Does the majority of the work in determining what url we should redirect to Inputs: :request: The current request :guid_redirect: Redirect object for the current job :vsid: View source for the current request :guid: GUID cleared of all undesired characters debug_content: List of strings that will be output on the debug page Modifies: :debug_content: Potentially adds new debug strings """ return_dict = {'redirect_url': None, 'expired': False, 'facebook': False} if guid_redirect.expired_date: return_dict['expired'] = True if vsid == '294': # facebook redirect return_dict['facebook'] = True return_dict['redirect_url'] = 'http://apps.facebook.com/us-jobs/?jvid=%s%s' % \ (guid, vsid) else: manipulations = None # Check for a 'vs' request parameter. If it exists, this is an # apply click and vs should be used in place of vsid apply_vs = request.REQUEST.get('vs') skip_microsite = False vs_to_use = vsid if apply_vs: skip_microsite = True vs_to_use = apply_vs # Is this a new job (< 30 minutes old)? Used in conjunction # with the set of excluded view sources to determine if we # should redirect to a microsite new_job = (guid_redirect.new_date + timedelta(minutes=30)) > \ datetime.now(tz=timezone.utc) try: microsite = CanonicalMicrosite.objects.get(buid=guid_redirect.buid) except CanonicalMicrosite.DoesNotExist: microsite = None if microsite and return_dict.get('expired'): return_dict['browse_url'] = microsite.canonical_microsite_url try: vs_to_use = int(vs_to_use) except ValueError: # Should never happen unless someone manually types in the # url and makes a typo or their browser does something it # shouldn't with links, which is apparently quite common pass else: # vs_to_use in settings.EXCLUDED_VIEW_SOURCES or # (buid, vs_to_use) in settings.CUSTOM_EXCLUSIONS # The given view source should not redirect to a # microsite # microsite is None # This business unit has no associated microsite # skip_microsite: # Prevents microsite loops when the vs= parameter # is provided # new_job # This job is new and may not have propagated to # microsites yet; skip microsite redirects try_manipulations = ( (vs_to_use in settings.EXCLUDED_VIEW_SOURCES or (guid_redirect.buid, vs_to_use) in settings.CUSTOM_EXCLUSIONS or microsite is None) or skip_microsite or new_job) if try_manipulations: manipulations = get_manipulations(guid_redirect, vs_to_use) elif microsite: redirect_url = '%s%s/job/?vs=%s' % \ (microsite.canonical_microsite_url, guid, vs_to_use) redirect_url = add_view_source_group(redirect_url, vs_to_use) if request.REQUEST.get('z') == '1': # Enable adding vs and z to the query string; these # will be passed to the microsite, which will pass # them back to us on apply clicks redirect_url = replace_or_add_query( redirect_url, '&%s' % request.META.get('QUERY_STRING'), exclusions=[]) return_dict['redirect_url'] = redirect_url return_dict['enable_custom_queries'] = request.REQUEST.get( 'z') == '1' return_dict['qs'] = request.META['QUERY_STRING'] do_manipulations(guid_redirect, manipulations, return_dict, debug_content) return return_dict
def do_manipulations(guid_redirect, manipulations, return_dict, debug_content=None): """ Performs the manipulations denoted by :manipulations: Inputs: :guid_redirect: Redirect object for this job :manipulations: List of DestinationManipulation objects :return_dict: Dictionary of values used in all levels of the main redirect view :debug_content: List of strings that will be output on the debug page Modifies: :return_dict: Potentially modifies the redirect_url key :debug_content: Potentially adds new debug strings """ if manipulations and not return_dict['redirect_url']: for manipulation in manipulations: method_name = manipulation.action if debug_content: debug_content.append( 'ActionTypeID=%s Action=%s' % (manipulation.action_type, manipulation.action)) try: redirect_method = getattr(redirect.actions, method_name) except AttributeError: pass else: if manipulation.action in [ 'doubleclickwrap', 'replacethenaddpre', 'sourceurlwrap', 'sourceurlwrapappend', 'sourceurlwrapunencoded', 'sourceurlwrapunencodedappend']: # These actions all result in our final url being # appended, usually as a query string, to a value # determined by the manipulation object; due to # this, we should add any custom query parameters # before doing the manipulation. if return_dict['enable_custom_queries']: guid_redirect.url = replace_or_add_query( guid_redirect.url, '&%s' % return_dict.get('qs'), exclusions=['vs', 'z']) redirect_url = redirect_method(guid_redirect, manipulation) else: redirect_url = redirect_method(guid_redirect, manipulation) # manipulations is a QuerySet, which doesn't # support negative indexing; reverse the set and # take the first element to get the last # DestinationManipulation object. if manipulation == manipulations.reverse()[:1][0]: # Only add custom query parameters after # processing the final DestinationManipulation # object to ensure we're not needlessly # replacing them on each iteration. if return_dict['enable_custom_queries']: redirect_url = replace_or_add_query( redirect_url, '&%s' % return_dict.get('qs'), exclusions=['vs', 'z']) return_dict['redirect_url'] = redirect_url if debug_content: debug_content.append( 'ActionTypeID=%s ManipulatedLink=%s VSID=%s' % (manipulation.action_type, return_dict['redirect_url'], manipulation.view_source)) guid_redirect.url = return_dict['redirect_url']
def get_redirect_url(request, guid_redirect, vsid, guid, debug_content=None): """ Does the majority of the work in determining what url we should redirect to Inputs: :request: The current request :guid_redirect: Redirect object for the current job :vsid: View source for the current request :guid: GUID cleared of all undesired characters debug_content: List of strings that will be output on the debug page Modifies: :debug_content: Potentially adds new debug strings """ return_dict = {'redirect_url': None, 'expired': False, 'facebook': False} if guid_redirect.expired_date: return_dict['expired'] = True if vsid == '294': # facebook redirect return_dict['facebook'] = True return_dict['redirect_url'] = 'http://apps.facebook.com/us-jobs/?jvid=%s%s' % \ (guid, vsid) else: manipulations = None # Check for a 'vs' request parameter. If it exists, this is an # apply click and vs should be used in place of vsid apply_vs = request.REQUEST.get('vs') skip_microsite = False vs_to_use = vsid if apply_vs: skip_microsite = True vs_to_use = apply_vs # Is this a new job (< 30 minutes old)? Used in conjunction # with the set of excluded view sources to determine if we # should redirect to a microsite new_job = (guid_redirect.new_date + timedelta(minutes=30)) > \ datetime.now(tz=timezone.utc) try: microsite = CanonicalMicrosite.objects.get( buid=guid_redirect.buid) except CanonicalMicrosite.DoesNotExist: microsite = None if microsite and return_dict.get('expired'): return_dict['browse_url'] = microsite.canonical_microsite_url try: vs_to_use = int(vs_to_use) except ValueError: # Should never happen unless someone manually types in the # url and makes a typo or their browser does something it # shouldn't with links, which is apparently quite common pass else: # vs_to_use in settings.EXCLUDED_VIEW_SOURCES or # (buid, vs_to_use) in settings.CUSTOM_EXCLUSIONS # The given view source should not redirect to a # microsite # microsite is None # This business unit has no associated microsite # skip_microsite: # Prevents microsite loops when the vs= parameter # is provided # new_job # This job is new and may not have propagated to # microsites yet; skip microsite redirects try_manipulations = ( (vs_to_use in settings.EXCLUDED_VIEW_SOURCES or (guid_redirect.buid, vs_to_use) in settings.CUSTOM_EXCLUSIONS or microsite is None) or skip_microsite or new_job) if try_manipulations: manipulations = get_manipulations(guid_redirect, vs_to_use) elif microsite: redirect_url = '%s%s/job/?vs=%s' % \ (microsite.canonical_microsite_url, guid, vs_to_use) redirect_url = add_view_source_group(redirect_url, vs_to_use) if request.REQUEST.get('z') == '1': # Enable adding vs and z to the query string; these # will be passed to the microsite, which will pass # them back to us on apply clicks redirect_url = replace_or_add_query( redirect_url, '&%s' % request.META.get('QUERY_STRING'), exclusions=[]) return_dict['redirect_url'] = redirect_url return_dict['enable_custom_queries'] = request.REQUEST.get('z') == '1' return_dict['qs'] = request.META['QUERY_STRING'] do_manipulations(guid_redirect, manipulations, return_dict, debug_content) return return_dict