Compare commits

..

No commits in common. "4ea74637a3d7f59accef14b4a2885c34edd3dfc5" and "0fa52645c2605be8afd3e63f92ccfb068e106131" have entirely different histories.

2 changed files with 30 additions and 73 deletions

View file

@ -53,12 +53,6 @@ def unescape_simplified_quoted_printable(s, encoding='utf-8'):
return quopri.decodestring(s).decode(encoding) return quopri.decodestring(s).decode(encoding)
def decode_inline_encodings(s):
s = unescape_and_decode_quoted_printable(s)
s = unescape_and_decode_base64(s)
return s
def ascii_strip(s): def ascii_strip(s):
if not s: if not s:
return None return None
@ -140,7 +134,8 @@ def decode_email_segment(segment, charset, transfer_encoding):
import base64 import base64
segment = base64.b64decode(segment).decode('utf-8') segment = base64.b64decode(segment).decode('utf-8')
else: else:
segment = decode_inline_encodings(segment.decode('utf-8')) segment = unescape_and_decode_quoted_printable(segment)
segment = unescape_and_decode_base64(segment)
return segment return segment
@ -165,7 +160,7 @@ def parse_email_body(raw, log=None):
segment = part.get_payload() segment = part.get_payload()
if not segment: if not segment:
continue continue
segment = decode_email_segment(segment.encode('utf-8'), charset, part.get('Content-Transfer-Encoding')) segment = decode_email_segment(segment, charset, part.get('Content-Transfer-Encoding'))
log.debug(segment) log.debug(segment)
body = body + segment body = body + segment
elif 'attachment' in cdispo or 'inline' in cdispo: elif 'attachment' in cdispo or 'inline' in cdispo:
@ -198,8 +193,7 @@ def parse_email_body(raw, log=None):
else: else:
log.warning("Unknown content type %s", parsed.get_content_type()) log.warning("Unknown content type %s", parsed.get_content_type())
body = "Unknown content type" body = "Unknown content type"
body = decode_email_segment(body.encode('utf-8'), parsed.get_content_charset(), body = decode_email_segment(body, parsed.get_content_charset(), parsed.get('Content-Transfer-Encoding'))
parsed.get('Content-Transfer-Encoding'))
log.debug(body) log.debug(body)
return parsed, body, attachments return parsed, body, attachments
@ -227,9 +221,8 @@ def receive_email(envelope, log=None):
subject = ascii_strip(parsed.get('Subject')) subject = ascii_strip(parsed.get('Subject'))
if not subject: if not subject:
subject = "No subject" subject = "No subject"
subject = decode_inline_encodings(subject) subject = unescape_and_decode_quoted_printable(subject)
recipient = decode_inline_encodings(recipient) subject = unescape_and_decode_base64(subject)
sender = decode_inline_encodings(sender)
target_event = find_target_event(recipient) target_event = find_target_event(recipient)
active_issue_thread, new = find_active_issue_thread(header_in_reply_to, recipient, subject, target_event) active_issue_thread, new = find_active_issue_thread(header_in_reply_to, recipient, subject, target_event)
@ -263,7 +256,7 @@ do not create a new request.
Your c3lf (Cloakroom + Lost&Found) Team'''.format(active_issue_thread.short_uuid()) Your c3lf (Cloakroom + Lost&Found) Team'''.format(active_issue_thread.short_uuid())
reply_email = Email.objects.create( reply_email = Email.objects.create(
sender=recipient, recipient=sender, body=body, subject=subject, sender=recipient, recipient=sender, body=body, subject=ascii_strip(subject),
in_reply_to=header_message_id, event=target_event, issue_thread=active_issue_thread) in_reply_to=header_message_id, event=target_event, issue_thread=active_issue_thread)
reply = make_reply(reply_email, references, event=target_event.slug if target_event else None) reply = make_reply(reply_email, references, event=target_event.slug if target_event else None)
else: else:

View file

@ -77,26 +77,10 @@ const store = createStore({
getEventTickets: (state, getters) => getters.getEventSlug === 'all' ? getters.getAllTickets : getters.getAllTickets.filter(t => t.event === getters.getEventSlug || (t.event == null && getters.getEventSlug === 'none')), getEventTickets: (state, getters) => getters.getEventSlug === 'all' ? getters.getAllTickets : getters.getAllTickets.filter(t => t.event === getters.getEventSlug || (t.event == null && getters.getEventSlug === 'none')),
isItemsLoaded: (state, getters) => (getters.getEventSlug === 'all' || getters.getEventSlug === 'none') ? !!state.loadedItems : Object.keys(state.loadedItems).includes(getters.getEventSlug), isItemsLoaded: (state, getters) => (getters.getEventSlug === 'all' || getters.getEventSlug === 'none') ? !!state.loadedItems : Object.keys(state.loadedItems).includes(getters.getEventSlug),
isTicketsLoaded: (state, getters) => (getters.getEventSlug === 'all' || getters.getEventSlug === 'none') ? !!state.loadedTickets : Object.keys(state.loadedTickets).includes(getters.getEventSlug), isTicketsLoaded: (state, getters) => (getters.getEventSlug === 'all' || getters.getEventSlug === 'none') ? !!state.loadedTickets : Object.keys(state.loadedTickets).includes(getters.getEventSlug),
getItemsSearchResults: (state, getters) => { getItemsSearchResults: (state, getters) => state.loadedItemSearchResults[getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || [],
if (getters.getEventSlug === 'all') { getTicketsSearchResults: (state, getters) => state.loadedTicketSearchResults[getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || [],
return state.events.map(e => { isItemsSearchLoaded: (state, getters) => Object.keys(state.loadedItemSearchResults).includes(getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))),
return state.loadedItemSearchResults[e.slug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || [] isTicketsSearchLoaded: (state, getters) => Object.keys(state.loadedTicketSearchResults).includes(getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))),
}).flat();
} else {
return state.loadedItemSearchResults[getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || []
}
},
getTicketsSearchResults: (state, getters) => {
if (getters.getEventSlug === 'all') {
return state.events.map(e => {
return state.loadedTicketSearchResults[e.slug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || []
}).flat();
} else {
return state.loadedTicketSearchResults[getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))] || []
}
},
isItemsSearchLoaded: (state, getters) => Object.keys(state.loadedItemSearchResults).includes(getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))) || getters.getEventSlug === 'all',
isTicketsSearchLoaded: (state, getters) => Object.keys(state.loadedTicketSearchResults).includes(getters.getEventSlug + '/' + base64.encode(utf8.encode(getters.searchQuery))) || getters.getEventSlug === 'all',
getActiveView: state => router.currentRoute.value.name || 'items', getActiveView: state => router.currentRoute.value.name || 'items',
getFilters: state => router.currentRoute.value.query, getFilters: state => router.currentRoute.value.query,
getBoxes: state => state.loadedBoxes, getBoxes: state => state.loadedBoxes,
@ -395,8 +379,9 @@ const store = createStore({
}, },
async loadEventItems({commit, getters, state}) { async loadEventItems({commit, getters, state}) {
if (!state.user.token) return; if (!state.user.token) return;
const load = async (slug) => { if (state.fetchedData.items > Date.now() - 1000 * 60 * 60 * 24) return;
try { try {
const slug = getters.getEventSlug;
const {data, success} = await getters.session.get(`/2/${slug}/items/`); const {data, success} = await getters.session.get(`/2/${slug}/items/`);
if (data && success) { if (data && success) {
commit('setItems', {slug, items: data}); commit('setItems', {slug, items: data});
@ -404,17 +389,10 @@ const store = createStore({
} catch (e) { } catch (e) {
console.error("Error loading items"); console.error("Error loading items");
} }
}
const slug = getters.getEventSlug;
if (slug === 'all') {
await Promise.all(state.events.map(e => load(e.slug)));
} else {
await load(slug);
}
}, },
async searchEventItems({commit, getters, state}, query) { async searchEventItems({commit, getters, state}, query) {
const encoded_query = base64.encode(utf8.encode(query)); const encoded_query = base64.encode(utf8.encode(query));
const load = async (slug) => { const slug = getters.getEventSlug;
if (Object.keys(state.loadedItemSearchResults).includes(slug + '/' + encoded_query)) return; if (Object.keys(state.loadedItemSearchResults).includes(slug + '/' + encoded_query)) return;
const { const {
data, success data, success
@ -422,13 +400,6 @@ const store = createStore({
if (data && success) { if (data && success) {
commit('setItemSearchResults', {slug, query: encoded_query, items: data}); commit('setItemSearchResults', {slug, query: encoded_query, items: data});
} }
}
const slug = getters.getEventSlug;
if (slug === 'all') {
await Promise.all(state.events.map(e => load(e.slug)));
} else {
await load(slug);
}
}, },
async loadBoxes({commit, state, getters}) { async loadBoxes({commit, state, getters}) {
if (!state.user.token) return; if (!state.user.token) return;
@ -475,19 +446,12 @@ const store = createStore({
}, },
async searchEventTickets({commit, getters, state}, query) { async searchEventTickets({commit, getters, state}, query) {
const encoded_query = base64.encode(utf8.encode(query)); const encoded_query = base64.encode(utf8.encode(query));
const load = async (slug) => { const slug = getters.getEventSlug;
if (Object.keys(state.loadedTicketSearchResults).includes(slug + '/' + encoded_query)) return; if (Object.keys(state.loadedTicketSearchResults).includes(slug + '/' + encoded_query)) return;
const { const {
data, success data, success
} = await getters.session.get(`/2/${slug}/tickets/${encoded_query}/`); } = await getters.session.get(`/2/${slug}/tickets/${encoded_query}/`);
if (data && success) commit('setTicketSearchResults', {slug, query: encoded_query, items: data}); if (data && success) commit('setTicketSearchResults', {slug, query: encoded_query, items: data});
}
const slug = getters.getEventSlug;
if (slug === 'all') {
await Promise.all(state.events.map(e => load(e.slug)));
} else {
await load(slug);
}
}, },
async sendMail({commit, dispatch, state, getters}, {id, message}) { async sendMail({commit, dispatch, state, getters}, {id, message}) {
const {data, success} = await getters.session.post(`/2/tickets/${id}/reply/`, {message}, const {data, success} = await getters.session.post(`/2/tickets/${id}/reply/`, {message},