示例#1
0
def update_notes():
  """ Updates the notes field of a specific record ; redirects to GET /hours """
  #######################################################
  
  # get index of completed record
  # TODO: ensure this is good, in case of template changes
  index = int(bottle.request.forms.get("index"))
  
  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
  
  # TODO: again, check after template changes
  newNotes = bottle.request.forms.get("notesDisplay")
  # replace <br> with " " in case of enter button being pressed
  newNotes = newNotes.replace("<br>", " ").strip()

  # set the anchor cookie ; if the record's notes are successfully changed, it gets deleted
  Cookies.set.anchor(bottle.response, index)

  #######################################################

  if newNotes:
    records = recorder.parseRecordsFromFile(name, date)
    
    records[index].notes = newNotes
    
    recorder.writeRecords(name, date, records)
    
    # delete cookie if task completed
    Cookies.delete.anchor(bottle.response)
  
  #######################################################

  bottle.redirect('hours')
示例#2
0
def ack_sent_records():
  """ Catches the return message from the logging server ; redirects to GET /hours with the message as a query param """
  # TODO: again, test, but it doesn't look like it will be used
  
  msg = bottle.request.query['msg'] or ''

  bottle.redirect('hours?msg={0}'.format(msg))
示例#3
0
def delete_single_record():
  """ Deletes one record from the list of records currently displayed at GET /hours ; redirects to GET /hours """
  #######################################################
  
  # get index based on which delete button was clicked / which form was submitted
  # TODO: ensure this is good, in case of template changes
  index = int(bottle.request.forms.get('index'))
  
  # get name and date cookies
  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
    
  # read and parse records from file
  records = recorder.parseRecordsFromFile(name, date)
  
  #######################################################
  
  # upon redirect, anchor to where the record was deleted
  # open that form and insert notes from the deleted record
  Cookies.set.anchor(bottle.response, index)
  Cookies.set.notes(bottle.response, records[index].notes)

  #######################################################

  # delete record
  del records[index]
  
  # write back updated records
  recorder.writeRecords(name, date, records)
  
  #######################################################
  
  bottle.redirect('hours')
示例#4
0
def set_cookies():
  """ Sets name and date cookies for pulling records without altering them ; redirects to GET /hours """
  #######################################################
  
  # get name of user provided in specified field
  name = bottle.request.forms.get("name") or ""
  
  # the forward and backward arrows set this value so that the date can be modified by it (-1|0|1)
  timeDelta = int(bottle.request.forms.get("time-delta") or 0)
  
  if timeDelta != 0:
    # if a non-zero time delta exists, use the existing date cookie
    # otherwise, the empty HTML date field will cause recorder to always provide the current date
    date = Cookies.get.date(bottle.request)
  else:
    # get date: either set manually or defaults to current day
    date = recorder.validateDate(bottle.request.forms.get("date"))

  date += dt.timedelta(days=timeDelta)
  
  #######################################################
  
  # set name and date cookie
  Cookies.set.name(bottle.response, name)
  Cookies.set.date(bottle.response, date)
  
  #######################################################
  
  # redirect to GET /hours
  bottle.redirect('hours')
示例#5
0
def scontrol_show_node():
    anchor = str(bottle.request.forms.get('anchor') or -1)
    bottle.response.set_cookie("anchor", anchor)

    requested = str(bottle.request.forms.get('node') or -1)
    bottle.response.set_cookie("requested", requested)

    bottle.redirect('/slurm#' + anchor)
示例#6
0
def email_records():
  """ Sends an SMTP email from ENV.SENDER to ENV.RECEIVERS containing records pulled with the name and date cookies ;
    redirects to GET /hours
  """
  #######################################################
  
  # get name and date cookies
  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
  
  # sets flag based on user's confirmation / denial from popup alert
  emailConfirm = (bottle.request.forms.get("emailConfirm") == "true")
  
  #######################################################

  total = recorder.getTotalForPayPeriod(name, date)
  
  #######################################################
  
  currentTimeShort = time.strftime("%m/%d")
  
  subject = "Hours {0} (Total: {1})".format(currentTimeShort, str(total))
  
  #######################################################
  
  if all((emailConfirm, name, ENV.SENDER, ENV.RECEIVERS)):
    
    # get records corresponding to name and date
    records = recorder.parseRecordsFromFile(name, date)
    
    #TODO: check to make sure this works instead of the old commented line (make sure "\n" isn't needed at the end)
    body = "\n".join([record.emailFormat() for record in records])
    # for record in records:
    #   body += record.emailFormat() + "\n"
    
    # message = "Subject: %s\n\n%s" % (subject, body)
    # TODO: check to make sure this works instead of the old commented line
    message = "Subject: {subject}\n\n{body}".format(subject=subject, body=body)
      
    try:
      mail = smtplib.SMTP(ENV.HOST)
      mail.sendmail(ENV.SENDER, ENV.RECEIVERS, message)
      mail.quit()
      
      # if in debug mode, print info on successful email
      if ENV.DEBUG:
        cp.printOk("SENDER: {sender}".format(sender=ENV.SENDER))
        cp.printOk("RECEIVERS: {receivers}".format(receivers=ENV.RECEIVERS))
        cp.printOk("-- MESSAGE --\n{message}".format(message=message))
    
    except smtplib.SMTPException as e:
      # TODO: make sure this works
      cp.printFail(e)
  
  bottle.redirect('hours')
示例#7
0
def send_records():
  """ Uses modu.crypto to encrypt and send records pulled with the name and date cookies ; redirects to GET /hours """
  # TODO: test this ; not sure if it's going to be used
  #######################################################

  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
  
  confirm = (bottle.request.forms.get('confirm') == "true")
  
  # will use form-supplied values but defaults to values read from config file
  address = bottle.request.forms.get('address').strip() or ENV.LOGGING_SERVER_ADDRESS
  port = bottle.request.forms.get('port').strip() or ENV.LOGGING_SERVER_PORT
  
  #######################################################
  
  if all((confirm, name, address, port)):
        
    # parse records from file
    records = recorder.parseRecordsFromFile(name, date)
    
    # turn records into a '\n'-separated string
    recordString = '\n'.join([r.emailFormat() for r in records])
    
    # if in debug mode and about to send records, display info
    if ENV.DEBUG:
      cp.printOk("SENDING TO: {0}:{1}".format(address, port))
      cp.printOK("-- RECORDS --\n{records}".format(records=recordString))
    
    try:
      # encrypt and encode recordString
      encryptedRecords = crypto.getEncodedString(recordString)
      
      address = "/".join(bottle.request.url.split("/")[:-1]) + "/ack"
      
      # encrypts and encodes host address for rerouting back to hours
      encryptedAddress = crypto.getEncodedString(address)
      
      # send name, date, and encoded records to receiving server
      bottle.redirect('http://{address}:{port}/receive?n={name}&d={date}&r={encryptedRecords}&a={encryptedAddress}'
        .format(address=address, port=port,
                name=name, date=date,
                encryptedRecords=encryptedRecords, encryptedAddress=encryptedAddress))
    
    # thrown if config/crypto not found
    # TODO: is this error too specific or even accurate?
    except TypeError as e:
      cp.printFail(e)

  bottle.redirect('hours')
示例#8
0
def complete_end_time():
  """ Completes a pending record by supplying an end time ; redirects to GET /hours """
  #######################################################
  
  # get index of completed record
  # TODO: ensure this is good, in case of template changes
  index = int(bottle.request.forms.get('index'))
  
  # get the submitted end time (which has already been pattern matched) OR get current rounded time
  # TODO: ensure this is good, in case of template changes
  end = recorder.parseTime(bottle.request.forms.get('completeEnd')) or recorder.getCurrentRoundedTime()
  
  # get name and date cookies
  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)

  # set the anchor cookie ; if the record is successfully completed, it gets deleted
  Cookies.set.anchor(bottle.response, index)
  
  #######################################################
  
  # get records from file
  records = recorder.parseRecordsFromFile(name, date)
  
  # get particular record to complete
  record = records[index]
  
  # set the end time - THEN check if it is valid
  record.setEnd(end)
  
  # don't accept an invalid or invalidly placed record
  if recorder.checkIfValid(records, record, index):
    
    if not record.durationLocked:
      # calculate and set duration
      record.calculateAndSetDuration()
    
    # write back record
    records[index] = record
    recorder.writeRecords(name, date, records)
    
    # delete cookie if task completed
    Cookies.delete.anchor(bottle.response)
  
  #######################################################

  bottle.redirect('hours')
示例#9
0
def delete_records():
  """ Deletes all the records in the file corresponding to the name and date cookies ; redirects to GET /hours """
  #######################################################
  
  # get name and date cookies
  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
  
  # sets flag based on user's confirmation / denial from the popup alert
  deleteConfirm = (bottle.request.forms.get("deleteConfirm") == "true")
  
  #######################################################
  
  if deleteConfirm and name:
    # delete both of the user's record files (hidden and normal)
    recorder.deleteRecords(name, date)
  
  #######################################################
  
  # redirect back to hours page
  bottle.redirect('hours')
示例#10
0
def toggle_emergency():
  """ Toggles a single record's Y/N emergency field ; writes to file ; redirects to GET /hours """
  ##############################################

  name = Cookies.get.name(bottle.request)
  date = Cookies.get.date(bottle.request)
  
  ##############################################

  # TODO: ensure this is good, in case of template changes
  index = int(bottle.request.forms.get('index'))
  # don't delete on task completion (stay anchored to edited record to easily view the change)
  Cookies.set.anchor(bottle.response, index)
  
  ##############################################
  
  records = recorder.parseRecordsFromFile(name, date)

  records[index].emergency = "N" if records[index].emergency == "Y" else "Y"
  
  recorder.writeRecords(name, date, records)

  bottle.redirect('hours')
示例#11
0
def hours_post():
  """ POST /hours ; Main page post ; parses form data ; reads/writes files ; redirects to GET /hours
  Extra explicit because of logical complexity
  1) get name, date, and index from the request
  2) parse the new record from the request
  3) read records on file for the user and date
  4) using the name and date cookies, check if the user has seen any records for that date
  5) check that the new record is valid and fits in the record list at the index and that no records have gone unseen
  if true:
    5.1) insert the new record at the index
    5.2) adjust adjacent records
    5.3) write the new record list to file
    5.4) delete the anchor cookie (successful POST means anchor back to the top of the page)
    5.5) delete the notes cookies (since it pertains to the inserted record only)
  else:
    5.1) save the index as the anchor cookie for GET /hours
    5.2) save the new (invalid) record's notes to a cookie
  6) set the name and date cookies to the values pulled from the request
  7) redirect to GET /hours
  """
  #######################################################
  
  # name of user
  name = bottle.request.forms.get("name").strip()
  # date : either picked by user or default today
  date = Cookies.get.date(bottle.request)
  # index for inserting new Record into the list of records
  index = int(bottle.request.forms.get("index"))
  
  #######################################################
  
  # parses form data and returns a Record obj
  newRecord = recorder.parseRecordFromHTML(bottle.request)
  
  # reads and parses Records on file
  records = recorder.parseRecordsFromFile(name, date)
  
  #######################################################

  # if the name cookie is equal to the name pulled from the request
  # and the date cookie is equal to the date pulled from the request
  # then any records on file have already been pulled, and it is safe to insert into the list
  recordsPulled = ((Cookies.get.name(bottle.request) == name) and (Cookies.get.date(bottle.request) == date))
  
  # checks if newRecord.start < newRecord.end
  # and that newRecord doesn't exceed the outer limits of adjacent records
  # also ensures that the user has seen any records that exist
  if recorder.checkIfValid(records, newRecord, index) and (recordsPulled or not records):
      
    # insert new record at index provided from template form
    records.insert(index, newRecord)
    
    # adjust timings of adjacent records in case of overlap
    recorder.adjustAdjacentRecords(records, index)
    
    # write back updated list
    recorder.writeRecords(name, date, records)
    
    # after posting a new record, delete the anchor and notes cookies
    Cookies.delete.anchor(bottle.response)
    Cookies.delete.notes(bottle.response)
  
  else:
    # if the record was invalid
    # or there were records the user hadn't seen
    # then save the index to anchor to the correct record form upon reload
    # and save the notes to avoid retyping
    Cookies.set.anchor(bottle.response, index)
    Cookies.set.notes(bottle.response, newRecord.notes)
  
  #######################################################
  
  # set name cookie with most recently used name (for insurance mostly)
  Cookies.set.name(bottle.response, name)
  Cookies.set.date(bottle.response, date)
  
  bottle.redirect('hours')