def ParseError(msg, request, status=400): caltitle = request.POST.get("title", '') callocation = request.POST.get("location", '') shiftinput = request.POST.get("roster", None) if not caltitle: caltitle = request.GET.get("title", '') if not callocation: callocation = request.GET.get("location", '') dbroster = Roster( event_title=caltitle, event_location=callocation, raw_roster=shiftinput, method='site', created=dtnow(), success=False, error=msg ) if request.POST.get('bm', False): dbroster.method = 'bookmarklet' dbroster.version = request.POST.get('v', '_none_') dbroster.save() return JSONError(msg, status)
def parse(request): if not request.POST: return JSONError('Method must be POST') bookmarklet = request.POST.get('bm', False) raw = request.POST.get('roster', False) if not raw: return ParseError('Roster not specified', request) title = request.POST.get("title", "") location = request.POST.get("location", "") sat_regex_str = r'(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s{1,5}(\d{2}),?\s{1,5}(2\d{3})' matched_sat = re.findall(sat_regex_str, raw) if len(matched_sat) != 1: return ParseError('Could not determine dates for the roster. Make sure you copy from "Schedule begins" onwards', request) try: sat, roster, hours = parse_roster(raw) hours = hours.seconds / 60.0 / 60.0 dump = {'sat': sat, 'roster': roster} except Exception: return ParseError('Unexpected error interpreting the roster.', request) if len(roster) < 1: return ParseError('Found no shifts.', request) accesstoken = makeAccessCode(10) method = 'bookmarklet' if bookmarklet else 'site' dbroster = Roster( token=accesstoken, event_title=limit(title, 100), event_location=limit(location, 100), method=method, created=dtnow(), success=True, dump=pickle.dumps(dump), ) dbroster.save() json_response = { "status": "success", "hours": hours, "accesstoken": accesstoken, "bookmarklet": bookmarklet, } return HttpResponse(json.dumps(json_response), content_type='application/json; charset=utf8')
def download(request, accesstoken): deferred = Roster.objects.filter(token=accesstoken) if not deferred: return HttpResponse('No rosters exist for key %s ' % accesstoken) deferred = deferred[0] if len(deferred.dump) < 1: return HttpResponse('Access token %s has expired.' % accesstoken) if request.GET.get('location'): deferred.event_location = request.GET.get('location') if request.GET.get('title'): deferred.event_title = request.GET.get('title') title = deferred.event_title location = deferred.event_location store, store_location, structured_location = find_store(deferred) if store: location = store_location if not title: title = 'Shift' cal = Calendar() cal.add('prodid', '-//roster genius') cal.add('version', '2.0') dump = pickle.loads(deferred.dump) sat = dump['sat'] roster = dump['roster'] filename = "%s %s" % (sat.strftime("%d %b"), re.sub(r'\W+', '', title)) for day in roster: e = Event() formatted_title = smarttitle.format(title, day['start'], day['end']) e.add('summary', formatted_title) e.add('dtstart', day['start']) e.add('dtend', day['end']) e.add('dtstamp', dtnow()) e.add("priority", 1) duration = day.get('hours') description = "Roster generated by roster genius" if duration: hours = duration.seconds//3600 minutes = (duration.seconds//60) % 60 if minutes != 0: dur = "%sh %sm" % (hours, minutes) else: dur = "%s hours" % hours description = r'Scheduled for %s today\n%s' % (dur, description) e.add('description', description) try: # TODO: handle unicode here properly so we dont need the try/except e["uid"] = hashlib.md5(str(day['start']) + str(day['end']) + title + str(location) + get_client_ip(request)).hexdigest() except: e["uid"] = str(uuid.uuid4()) if location: formatted_location = smarttitle.format(location, day['start'], day['end']) e.add("location", formatted_location.replace(",", "\,")) # Escape comma with a backslash if structured_location: e['X-APPLE-STRUCTURED-LOCATION'] = structured_location cal.add_component(e) icsfile = cal.to_ical() icsfile = icsfile.replace('X-APPLE-STRUCTURED-LOCATION:', 'X-APPLE-STRUCTURED-LOCATION;') deferred.dump = '' deferred.downloaded = True deferred.save() response = HttpResponse(icsfile, content_type='text/calendar') response['Content-Disposition'] = 'attachment; filename=' + filename + '.ics' return response