Ejemplo n.º 1
0
 private boolean checkForToken() {
   if (!actFmPreferenceService.isLoggedIn()) {
     return false;
   }
   token = actFmPreferenceService.getToken();
   return true;
 }
Ejemplo n.º 2
0
  private void write(GtasksTaskContainer task) throws IOException {
    //  merge astrid dates with google dates
    if (!task.task.isSaved() && actFmPreferenceService.isLoggedIn()) titleMatchWithActFm(task.task);

    if (task.task.isSaved()) {
      Task local =
          PluginServices.getTaskService()
              .fetchById(task.task.getId(), Task.DUE_DATE, Task.COMPLETION_DATE);
      if (local == null) {
        task.task.clearValue(Task.ID);
      } else {
        mergeDates(task.task, local);
        if (task.task.isCompleted() && !local.isCompleted())
          StatisticsService.reportEvent(StatisticsConstants.GTASKS_TASK_COMPLETED);
      }
    } else { // Set default importance and reminders for remotely created tasks
      task.task.setValue(
          Task.IMPORTANCE,
          Preferences.getIntegerFromString(
              R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO));
      TaskDao.setDefaultReminders(task.task);
    }
    if (!TextUtils.isEmpty(task.task.getValue(Task.TITLE))) {
      task.task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
      gtasksMetadataService.saveTaskAndMetadata(task);
    }
  }
Ejemplo n.º 3
0
  @SuppressWarnings("nls")
  private static String userDisplay(Context context, String historyUserId, JSONObject userJson) {
    try {
      String id = userJson.getString("id");
      String name = userJson.getString("name");

      if (historyUserId.equals(id) && ActFmPreferenceService.userId().equals(id))
        return context.getString(R.string.history_yourself);
      else if (ActFmPreferenceService.userId().equals(id))
        return context.getString(R.string.history_you);
      else if (RemoteModel.isValidUuid(id)) return name;
      else return context.getString(R.string.history_a_deleted_user);
    } catch (JSONException e) {
      return context.getString(R.string.ENA_no_user).toLowerCase();
    }
  }
Ejemplo n.º 4
0
 public static Filter getAssignedByMeFilter(Resources r) {
   int themeFlags = ThemeService.getFilterThemeFlags();
   Filter f =
       new Filter(
           r.getString(R.string.BFE_Assigned),
           r.getString(R.string.BFE_Assigned),
           new QueryTemplate()
               .join(
                   Join.left(
                       Metadata.TABLE,
                       Criterion.and(
                           Metadata.KEY.eq(TaskRabbitMetadata.METADATA_KEY),
                           Task.ID.eq(Metadata.TASK))))
               .where(
                   Criterion.and(
                       TaskCriteria.isActive(),
                       Criterion.or(
                           Task.CREATOR_ID.eq(0),
                           Task.CREATOR_ID.eq(ActFmPreferenceService.userId())),
                       Criterion.or(Task.USER_ID.neq(0), TaskRabbitMetadata.ID.gt(0)))),
           null);
   f.listingIcon =
       ((BitmapDrawable)
               r.getDrawable(ThemeService.getDrawable(R.drawable.filter_assigned, themeFlags)))
           .getBitmap();
   return f;
 }
Ejemplo n.º 5
0
 public void updateTitle(boolean isNewTask) {
   ActionBar actionBar = getSupportActionBar();
   if (actionBar != null) {
     TextView title = ((TextView) actionBar.getCustomView().findViewById(R.id.title));
     if (ActFmPreferenceService.isPremiumUser()) title.setText(""); // $NON-NLS-1$
     else title.setText(isNewTask ? R.string.TEA_new_task : R.string.TAd_contextEditTask);
   }
 }
Ejemplo n.º 6
0
  /**
   * Perform upgrade from one version to the next. Needs to be called on the UI thread so it can
   * display a progress bar and then show users a change log.
   *
   * @param from
   * @param to
   */
  public void performUpgrade(final Context context, final int from) {
    if (from == 135) AddOnService.recordOem();

    if (from > 0 && from < V3_8_2) {
      if (Preferences.getBoolean(R.string.p_transparent_deprecated, false))
        Preferences.setString(R.string.p_theme, "transparent"); // $NON-NLS-1$
      else Preferences.setString(R.string.p_theme, "black"); // $NON-NLS-1$
    }

    if (from <= V3_9_1_1) {
      actFmPreferenceService.clearLastSyncDate();
    }

    // long running tasks: pop up a progress dialog
    final ProgressDialog dialog;
    if (from < V4_0_6 && context instanceof Activity)
      dialog = DialogUtilities.progressDialog(context, context.getString(R.string.DLG_upgrading));
    else dialog = null;

    final String lastSetVersionName = AstridPreferences.getCurrentVersionName();

    Preferences.setInt(AstridPreferences.P_UPGRADE_FROM, from);

    new Thread(
            new Runnable() {
              @Override
              public void run() {
                try {
                  // NOTE: This line should be uncommented whenever any new version requires a data
                  // migration
                  // TasksXmlExporter.exportTasks(context,
                  // TasksXmlExporter.ExportType.EXPORT_TYPE_ON_UPGRADE, null, null,
                  // lastSetVersionName);

                  if (from < V3_0_0) new Astrid2To3UpgradeHelper().upgrade2To3(context, from);

                  if (from < V3_1_0) new Astrid2To3UpgradeHelper().upgrade3To3_1(context, from);

                  if (from < V3_8_3_1) new TagCaseMigrator().performTagCaseMigration(context);

                  if (from < V3_8_4 && Preferences.getBoolean(R.string.p_showNotes, false))
                    taskService.clearDetails(Task.NOTES.neq("")); // $NON-NLS-1$

                  if (from < V4_0_6) new DueDateTimeMigrator().migrateDueTimes();

                } finally {
                  DialogUtilities.dismissDialog((Activity) context, dialog);
                  context.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
                }
              }
            })
        .start();
  }
Ejemplo n.º 7
0
 public static void readUser(
     JSONObject user, AbstractModel model, LongProperty idProperty, StringProperty userProperty)
     throws JSONException {
   long id = user.getLong("id");
   if (id == ActFmPreferenceService.userId()) {
     model.setValue(idProperty, 0L);
     if (userProperty != null) model.setValue(userProperty, "");
   } else {
     model.setValue(idProperty, id);
     if (userProperty != null) model.setValue(userProperty, user.toString());
   }
 }
Ejemplo n.º 8
0
 private static void populateUser() {
   try {
     user.put("name", Preferences.getStringValue(PREF_NAME));
     user.put("first_name", Preferences.getStringValue(PREF_FIRST_NAME));
     user.put("last_name", Preferences.getStringValue(PREF_LAST_NAME));
     user.put("premium", isPremiumUser());
     user.put("email", Preferences.getStringValue(PREF_EMAIL));
     user.put("picture", Preferences.getStringValue(PREF_PICTURE));
     user.put("id", ActFmPreferenceService.userId());
   } catch (JSONException e) {
     throw new RuntimeException(e);
   }
 }
Ejemplo n.º 9
0
  @SuppressWarnings("nls")
  private void refreshMembersPage() {
    tagName.setText(tagData.getValue(TagData.NAME));
    picture.setUrl(tagData.getValue(TagData.PICTURE));

    TextView ownerLabel = (TextView) findViewById(R.id.tag_owner);
    try {
      if (tagData.getFlag(TagData.FLAGS, TagData.FLAG_EMERGENT)) {
        ownerLabel.setText(String.format("<%s>", getString(R.string.actfm_TVA_tag_owner_none)));
      } else if (tagData.getValue(TagData.USER_ID) == 0) {
        ownerLabel.setText(Preferences.getStringValue(ActFmPreferenceService.PREF_NAME));
      } else {
        JSONObject owner = new JSONObject(tagData.getValue(TagData.USER));
        ownerLabel.setText(owner.getString("name"));
      }
    } catch (JSONException e) {
      Log.e("tag-view-activity", "json error refresh owner", e);
      ownerLabel.setText("<error>");
      System.err.println(tagData.getValue(TagData.USER));
    }

    tagMembers.removeAllViews();
    String peopleJson = tagData.getValue(TagData.MEMBERS);
    if (!TextUtils.isEmpty(peopleJson)) {
      try {
        JSONArray people = new JSONArray(peopleJson);
        for (int i = 0; i < people.length(); i++) {
          JSONObject person = people.getJSONObject(i);
          TextView textView = null;

          if (person.has("id") && person.getLong("id") == ActFmPreferenceService.userId())
            textView =
                tagMembers.addPerson(Preferences.getStringValue(ActFmPreferenceService.PREF_NAME));
          else if (!TextUtils.isEmpty(person.optString("name")))
            textView = tagMembers.addPerson(person.getString("name"));
          else if (!TextUtils.isEmpty(person.optString("email")))
            textView = tagMembers.addPerson(person.getString("email"));

          if (textView != null) {
            textView.setTag(person);
            textView.setEnabled(false);
          }
        }
      } catch (JSONException e) {
        System.err.println(peopleJson);
        Log.e("tag-view-activity", "json error refresh members", e);
      }
    }

    tagMembers.addPerson(""); // $NON-NLS-1$
  }
Ejemplo n.º 10
0
  @Override
  protected void afterInflate() {
    fileList = (LinearLayout) getView().findViewById(R.id.files_list);
    final LinearLayout finalList = fileList;
    fileList.removeAllViews();
    LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    for (final Metadata m : files) {
      final View fileRow = inflater.inflate(R.layout.file_row, null);

      setUpFileRow(m, fileRow, fileList, lp);
      View name = fileRow.findViewById(R.id.file_text);
      View clearFile = fileRow.findViewById(R.id.remove_file);

      setupFileClickListener(name, m);

      if (ActFmPreferenceService.isPremiumUser()) {
        clearFile.setVisibility(View.VISIBLE);
        clearFile.setOnClickListener(
            new OnClickListener() {
              @Override
              public void onClick(View v) {
                DialogUtilities.okCancelDialog(
                    activity,
                    activity.getString(R.string.premium_remove_file_confirm),
                    new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface d, int which) {
                        if (m.getValue(FileMetadata.REMOTE_ID) > 0) {
                          m.setValue(FileMetadata.DELETION_DATE, DateUtilities.now());
                          metadataService.save(m);
                          actFmSyncService.pushAttachmentInBackground(m);
                        } else {
                          metadataService.delete(m);
                        }

                        if (m.containsNonNullValue(FileMetadata.FILE_PATH)) {
                          File f = new File(m.getValue(FileMetadata.FILE_PATH));
                          f.delete();
                        }
                        files.remove(m);
                        refreshDisplayView();
                        finalList.removeView(fileRow);
                      }
                    },
                    null);
              }
            });
      }
    }
  }
Ejemplo n.º 11
0
  /** Helper method to set the contents and visibility of each field */
  @SuppressWarnings("nls")
  public synchronized void setFieldContentsAndVisibility(View view, Update update) {
    JSONObject user = ActFmPreferenceService.userFromModel(update);
    Resources r = activity.getResources();

    // picture
    final AsyncImageView pictureView = (AsyncImageView) view.findViewById(R.id.picture);
    {
      String pictureUrl = user.optString("picture");
      pictureView.setUrl(pictureUrl);
    }

    // name
    final TextView nameView = (TextView) view.findViewById(R.id.title);
    {
      String nameValue = user.optString("name");
      if (update.getValue(Update.ACTION_CODE).equals("task_comment"))
        nameValue =
            r.getString(R.string.UAd_title_comment, nameValue, update.getValue(Update.TARGET_NAME));
      nameView.setText(nameValue);
    }

    // description
    final TextView descriptionView = (TextView) view.findViewById(R.id.description);
    {
      String description = update.getValue(Update.ACTION);
      String message = update.getValue(Update.MESSAGE);
      if (update.getValue(Update.ACTION_CODE).equals("task_comment")
          || update.getValue(Update.ACTION_CODE).equals("tag_comment")) description = message;
      else if (!TextUtils.isEmpty(message)) description += " " + message;
      descriptionView.setText(description);
    }

    // date
    final TextView date = (TextView) view.findViewById(R.id.date);
    {
      CharSequence dateString =
          DateUtils.getRelativeTimeSpanString(
              update.getValue(Update.CREATION_DATE),
              DateUtilities.now(),
              DateUtils.MINUTE_IN_MILLIS,
              DateUtils.FORMAT_ABBREV_RELATIVE);
      date.setText(dateString);
    }
  }
Ejemplo n.º 12
0
  /** Helper method to set the contents and visibility of each field */
  @SuppressWarnings("nls")
  public synchronized void setFieldContentsAndVisibility(View view, Update update) {
    JSONObject user = ActFmPreferenceService.userFromModel(update);

    // picture
    final AsyncImageView pictureView = (AsyncImageView) view.findViewById(R.id.picture);
    {
      String pictureUrl = user.optString("picture");
      pictureView.setUrl(pictureUrl);
    }

    final AsyncImageView commentPictureView =
        (AsyncImageView) view.findViewById(R.id.comment_picture);
    {
      final String updatePicture = update.getValue(Update.PICTURE);
      setupImagePopupForCommentView(
          view,
          commentPictureView,
          updatePicture,
          update.getValue(Update.MESSAGE),
          fragment,
          imageCache);
    }

    // name
    final TextView nameView = (TextView) view.findViewById(R.id.title);
    {
      nameView.setText(getUpdateComment(update, user, linkColor, fromView));
    }

    // date
    final TextView date = (TextView) view.findViewById(R.id.date);
    {
      CharSequence dateString =
          DateUtils.getRelativeTimeSpanString(
              update.getValue(Update.CREATION_DATE),
              DateUtilities.now(),
              DateUtils.MINUTE_IN_MILLIS,
              DateUtils.FORMAT_ABBREV_RELATIVE);
      date.setText(dateString);
    }
  }
Ejemplo n.º 13
0
  public void loadViewForTaskID(long t) {
    try {
      fetchTask(t);
    } catch (SQLiteException e) {
      StartupService.handleSQLiteError(ContextManager.getContext(), e);
    }
    if (task == null) {
      return;
    }
    setUpInterface();
    setUpListAdapter();

    if (actFmPreferenceService.isLoggedIn()) {
      long pushedAt = task.getValue(Task.USER_ACTIVITIES_PUSHED_AT);
      if (DateUtilities.now() - pushedAt > DateUtilities.ONE_HOUR / 2) {
        refreshData();
      } else {
        loadingText.setText(R.string.ENA_no_comments);
        if (items.size() == 0) loadingText.setVisibility(View.VISIBLE);
      }
    }
  }
Ejemplo n.º 14
0
  @SuppressWarnings("nls")
  public static Spanned getUpdateComment(
      Update update, JSONObject user, String linkColor, String fromView) {
    if (user == null) {
      user = ActFmPreferenceService.userFromModel(update);
    }
    JSONObject otherUser = null;
    try {
      otherUser = new JSONObject(update.getValue(Update.OTHER_USER));
    } catch (JSONException e) {
      otherUser = new JSONObject();
    }

    return getUpdateComment(
        update.getValue(Update.ACTION_CODE),
        user.optString("name"),
        update.getValue(Update.TARGET_NAME),
        update.getValue(Update.MESSAGE),
        otherUser.optString("name"),
        update.getValue(Update.ACTION),
        linkColor,
        fromView);
  }
Ejemplo n.º 15
0
  @SuppressWarnings("nls")
  public static String getHistoryComment(
      final AstridActivity context, History history, User user, String linkColor, String fromView) {
    boolean hasTask = false;
    JSONArray taskAttrs = null;
    if (!TextUtils.isEmpty(history.getValue(History.TASK))) {
      try {
        taskAttrs = new JSONArray(history.getValue(History.TASK));
        hasTask = true;
      } catch (JSONException e) {
        //
      }
    }

    String item;
    String itemPosessive;
    if (FROM_TASK_VIEW.equals(fromView)) {
      item = context.getString(R.string.history_this_task);
    } else if (hasTask && taskAttrs != null) {
      item = taskAttrs.optString(1);
    } else {
      item = context.getString(R.string.history_this_list);
    }
    itemPosessive = item + "'s";

    String oldValue = history.getValue(History.OLD_VALUE);
    String newValue = history.getValue(History.NEW_VALUE);

    String result = "";
    String column = history.getValue(History.COLUMN);
    try {
      if (History.COL_TAG_ADDED.equals(column) || History.COL_TAG_REMOVED.equals(column)) {
        JSONArray tagObj = new JSONArray(newValue);
        String tagName = tagObj.getString(1);
        if (History.COL_TAG_ADDED.equals(column))
          result = context.getString(R.string.history_tag_added, item, tagName);
        else result = context.getString(R.string.history_tag_removed, item, tagName);

      } else if (History.COL_ATTACHMENT_ADDED.equals(column)
          || History.COL_ATTACHMENT_REMOVED.equals(column)) {
        JSONArray attachmentArray = new JSONArray(newValue);
        String attachmentName = attachmentArray.getString(0);
        if (History.COL_ATTACHMENT_ADDED.equals(column))
          result = context.getString(R.string.history_attach_added, attachmentName, item);
        else result = context.getString(R.string.history_attach_removed, attachmentName, item);
      } else if (History.COL_ACKNOWLEDGED.equals(column)) {
        result = context.getString(R.string.history_acknowledged, item);
      } else if (History.COL_SHARED_WITH.equals(column)
          || History.COL_UNSHARED_WITH.equals(column)) {
        JSONArray members = new JSONArray(newValue);
        String userId = history.getValue(History.USER_UUID);
        StringBuilder memberList = new StringBuilder();
        for (int i = 0; i < members.length(); i++) {
          JSONObject m = members.getJSONObject(i);
          memberList.append(userDisplay(context, userId, m));
          if (i != members.length() - 1) memberList.append(", ");
        }

        if (History.COL_SHARED_WITH.equals(column))
          result = context.getString(R.string.history_shared_with, item, memberList);
        else result = context.getString(R.string.history_unshared_with, item, memberList);
      } else if (History.COL_MEMBER_ADDED.equals(column)
          || History.COL_MEMBER_REMOVED.equals(column)) {
        JSONObject userValue = new JSONObject(newValue);
        if (history.getValue(History.USER_UUID).equals(userValue.optString("id"))
            && History.COL_MEMBER_REMOVED.equals(column))
          result = context.getString(R.string.history_left_list, item);
        else {
          String userDisplay = userDisplay(context, history.getValue(History.USER_UUID), userValue);
          if (History.COL_MEMBER_ADDED.equals(column))
            result = context.getString(R.string.history_added_user, userDisplay, item);
          else result = context.getString(R.string.history_removed_user, userDisplay, item);
        }
      } else if (History.COL_COMPLETED_AT.equals(column)) {
        if (!TextUtils.isEmpty(newValue) && !"null".equals(newValue)) {
          result = context.getString(R.string.history_completed, item);
        } else {
          result = context.getString(R.string.history_uncompleted, item);
        }
      } else if (History.COL_DELETED_AT.equals(column)) {
        if (!TextUtils.isEmpty(newValue) && !"null".equals(newValue)) {
          result = context.getString(R.string.history_deleted, item);
        } else {
          result = context.getString(R.string.history_undeleted, item);
        }
      } else if (History.COL_IMPORTANCE.equals(column)) {
        int oldPriority = AndroidUtilities.tryParseInt(oldValue, 0);
        int newPriority = AndroidUtilities.tryParseInt(newValue, 0);

        result =
            context.getString(
                R.string.history_importance_changed,
                itemPosessive,
                priorityString(oldPriority),
                priorityString(newPriority));
      } else if (History.COL_NOTES_LENGTH.equals(column)) {
        int oldLength = AndroidUtilities.tryParseInt(oldValue, 0);
        int newLength = AndroidUtilities.tryParseInt(newValue, 0);

        if (oldLength > 0 && newLength > oldLength)
          result =
              context.getString(
                  R.string.history_added_description_characters,
                  (newLength - oldLength),
                  itemPosessive);
        else if (newLength == 0)
          result = context.getString(R.string.history_removed_description, itemPosessive);
        else if (oldLength > 0 && newLength < oldLength)
          result =
              context.getString(
                  R.string.history_removed_description_characters,
                  (oldLength - newLength),
                  itemPosessive);
        else if (oldLength > 0 && oldLength == newLength)
          result = context.getString(R.string.history_updated_description, itemPosessive);
      } else if (History.COL_PUBLIC.equals(column)) {
        int value = AndroidUtilities.tryParseInt(newValue, 0);
        if (value > 0) result = context.getString(R.string.history_made_public, item);
        else result = context.getString(R.string.history_made_private, item);
      } else if (History.COL_DUE.equals(column)) {
        if (!TextUtils.isEmpty(oldValue)
            && !TextUtils.isEmpty(newValue)
            && !"null".equals(oldValue)
            && !"null".equals(newValue))
          result =
              context.getString(
                  R.string.history_changed_due_date,
                  itemPosessive,
                  dateString(context, oldValue, newValue),
                  dateString(context, newValue, oldValue));
        else if (!TextUtils.isEmpty(newValue) && !"null".equals(newValue))
          result =
              context.getString(
                  R.string.history_set_due_date,
                  itemPosessive,
                  dateString(
                      context, newValue, DateUtilities.timeToIso8601(DateUtilities.now(), true)));
        else result = context.getString(R.string.history_removed_due_date, itemPosessive);
      } else if (History.COL_REPEAT.equals(column)) {
        String repeatString = getRepeatString(context, newValue);
        if (!TextUtils.isEmpty(repeatString))
          result = context.getString(R.string.history_changed_repeat, itemPosessive, repeatString);
        else result = context.getString(R.string.history_removed_repeat, itemPosessive);
      } else if (History.COL_TASK_REPEATED.equals(column)) {
        result =
            context.getString(
                R.string.history_completed_repeating_task,
                item,
                dateString(context, newValue, oldValue));
      } else if (History.COL_TITLE.equals(column)) {
        if (!TextUtils.isEmpty(oldValue) && !"null".equals(oldValue))
          result =
              context.getString(R.string.history_title_changed, itemPosessive, oldValue, newValue);
        else result = context.getString(R.string.history_title_set, itemPosessive, newValue);
      } else if (History.COL_NAME.equals(column)) {
        if (!TextUtils.isEmpty(oldValue) && !"null".equals(oldValue))
          result = context.getString(R.string.history_name_changed, oldValue, newValue);
        else result = context.getString(R.string.history_name_set, newValue);
      } else if (History.COL_DESCRIPTION.equals(column)) {
        if (!TextUtils.isEmpty(oldValue) && !"null".equals(oldValue))
          result = context.getString(R.string.history_description_changed, oldValue, newValue);
        else result = context.getString(R.string.history_description_set, newValue);
      } else if (History.COL_PICTURE_ID.equals(column)
          || History.COL_DEFAULT_LIST_IMAGE_ID.equals(column)) {
        result = context.getString(R.string.history_changed_list_picture);
      } else if (History.COL_IS_SILENT.equals(column)) {
        int value = AndroidUtilities.tryParseInt(newValue, 0);
        if (value > 0) result = context.getString(R.string.history_silenced, item);
        else result = context.getString(R.string.history_unsilenced, item);
      } else if (History.COL_IS_FAVORITE.equals(column)) {
        int value = AndroidUtilities.tryParseInt(newValue, 0);
        if (value > 0) result = context.getString(R.string.history_favorited, item);
        else result = context.getString(R.string.history_unfavorited, item);
      } else if (History.COL_USER_ID.equals(column)) {
        String userId = history.getValue(History.USER_UUID);
        JSONObject userValue = new JSONObject(newValue);
        if (FROM_TAG_VIEW.equals(fromView) && !hasTask) {
          if (!TextUtils.isEmpty(oldValue) && !"null".equals(oldValue))
            result =
                context.getString(
                    R.string.history_changed_list_owner, userDisplay(context, userId, userValue));
          else result = context.getString(R.string.history_created_this_list);
        } else if (!TextUtils.isEmpty(oldValue)
            && !"null".equals(oldValue)
            && Task.USER_ID_UNASSIGNED.equals(userValue))
          result = context.getString(R.string.history_unassigned, item);
        else if (Task.USER_ID_UNASSIGNED.equals(oldValue)
            && userValue.optString("id").equals(ActFmPreferenceService.userId()))
          result = context.getString(R.string.history_claimed, item);
        else if (!TextUtils.isEmpty(oldValue) && !"null".equals(oldValue))
          result =
              context.getString(
                  R.string.history_assigned_to, item, userDisplay(context, userId, userValue));
        else if (!userValue.optString("id").equals(ActFmPreferenceService.userId())
            && !Task.USER_ID_UNASSIGNED.equals(userValue.optString("id")))
          result =
              context.getString(
                  R.string.history_created_for, item, userDisplay(context, userId, userValue));
        else result = context.getString(R.string.history_created, item);
      } else {
        result = context.getString(R.string.history_default, column, newValue);
      }
    } catch (Exception e) {
      e.printStackTrace();
      result = context.getString(R.string.history_default, column, newValue);
    }

    if (TextUtils.isEmpty(result))
      result = context.getString(R.string.history_default, column, newValue);

    String userDisplay;
    if (history.getValue(History.USER_UUID).equals(Task.USER_ID_SELF)
        || history.getValue(History.USER_UUID).equals(ActFmPreferenceService.userId())) {
      userDisplay = context.getString(R.string.update_string_user_self);
    } else if (user == null) {
      userDisplay = context.getString(R.string.ENA_no_user);
    } else {
      userDisplay = user.getDisplayName(USER_NAME, USER_FIRST_NAME, USER_LAST_NAME);
    }

    return userDisplay + " " + result;
  }
Ejemplo n.º 16
0
  /**
   * Save sharing settings
   *
   * @param toast toast to show after saving is finished
   * @return false if login is required & save should be halted
   */
  @SuppressWarnings("nls")
  public boolean saveSharingSettings(String toast) {
    if (task == null) return false;

    saveToast = toast;
    boolean dirty = false;
    try {
      JSONObject userJson = null;
      TextView assignedView = null;
      if (assignedCustom.getVisibility() == View.VISIBLE) {
        userJson = PeopleContainer.createUserJson(assignedCustom);
        assignedView = assignedCustom;
      } else if (assignedSpinner.getSelectedItem() != null) {
        userJson = ((AssignedToUser) assignedSpinner.getSelectedItem()).user;
      }

      if (userJson != null && userJson.optString("email").indexOf('@') == -1) {
        throw new ParseSharedException(
            assignedView,
            activity.getString(R.string.actfm_EPA_invalid_email, userJson.optString("email")));
      }

      if (userJson == null || userJson.optLong("id", -1) == 0) {
        dirty = task.getValue(Task.USER_ID) == 0L ? dirty : true;
        task.setValue(Task.USER_ID, 0L);
        if (!TextUtils.isEmpty(task.getValue(Task.USER))) task.setValue(Task.USER, "{}");
      } else {
        String user = userJson.toString();

        long taskUserId = -1;
        String taskUserEmail = "";
        try {
          JSONObject taskUser = new JSONObject(task.getValue(Task.USER));
          taskUserId = taskUser.optLong("id", -1);
          taskUserEmail = taskUser.optString("email");
        } catch (JSONException e) {
          // sad times
        }
        long userId = userJson.optLong("id", -1);
        String userEmail = userJson.optString("email");

        boolean match = (userId == taskUserId && userId != -1);
        match = match || (userEmail.equals(taskUserEmail) && !TextUtils.isEmpty(userEmail));

        dirty = match ? dirty : true;
        task.setValue(Task.USER_ID, userJson.optLong("id", -1));
        task.setValue(Task.USER, user);
      }

      JSONObject sharedWith = parseSharedWithAndTags();
      dirty = dirty || sharedWith.has("p");
      if (!TextUtils.isEmpty(task.getValue(Task.SHARED_WITH)) || sharedWith.length() != 0)
        task.setValue(Task.SHARED_WITH, sharedWith.toString());

      if (dirty) taskService.save(task);

      if (dirty && !actFmPreferenceService.isLoggedIn()) {
        activity.startActivityForResult(
            new Intent(activity, ActFmLoginActivity.class), loginRequestCode);
        return false;
      }

      if (dirty) shareTask(sharedWith);
      else showSaveToast();

      return true;
    } catch (JSONException e) {
      exceptionService.displayAndReportError(activity, "save-people", e);
    } catch (ParseSharedException e) {
      if (e.view != null) {
        e.view.setTextColor(Color.RED);
        e.view.requestFocus();
      }
      DialogUtilities.okDialog(activity, e.message, null);
    }
    return false;
  }
Ejemplo n.º 17
0
  @SuppressWarnings("nls")
  private void buildAssignedToSpinner(ArrayList<JSONObject> sharedPeople) throws JSONException {
    HashSet<Long> userIds = new HashSet<Long>();
    HashSet<String> emails = new HashSet<String>();
    HashMap<String, AssignedToUser> names = new HashMap<String, AssignedToUser>();

    if (task.getValue(Task.USER_ID) != 0) {
      JSONObject user = new JSONObject(task.getValue(Task.USER));
      sharedPeople.add(0, user);
    }

    JSONObject myself = new JSONObject();
    myself.put("id", 0L);
    sharedPeople.add(0, myself);

    // de-duplicate by user id and/or email
    spinnerValues.clear();
    for (int i = 0; i < sharedPeople.size(); i++) {
      JSONObject person = sharedPeople.get(i);
      if (person == null) continue;
      long id = person.optLong("id", -1);
      if (id == ActFmPreferenceService.userId() || (id > -1 && userIds.contains(id))) continue;
      userIds.add(id);

      String email = person.optString("email");
      if (!TextUtils.isEmpty(email) && emails.contains(email)) continue;
      emails.add(email);

      String name = person.optString("name");
      if (id == 0) name = activity.getString(R.string.actfm_EPA_assign_me);
      AssignedToUser atu = new AssignedToUser(name, person);
      spinnerValues.add(atu);
      if (names.containsKey(name)) {
        AssignedToUser user = names.get(name);
        if (user != null && user.user.has("email")) {
          user.label += " (" + user.user.optString("email") + ")";
          names.put(name, null);
        }
        if (!TextUtils.isEmpty("email")) atu.label += " (" + email + ")";
      } else if (TextUtils.isEmpty(name)) {
        if (!TextUtils.isEmpty("email")) atu.label = email;
        else spinnerValues.remove(atu);
      } else names.put(name, atu);
    }

    spinnerValues.add(
        new AssignedToUser(activity.getString(R.string.actfm_EPA_assign_custom), null));

    String assignedStr = task.getValue(Task.USER);
    int assignedIndex = 0;
    if (!TextUtils.isEmpty(assignedStr)) {
      JSONObject assigned = new JSONObject(assignedStr);
      long assignedId = assigned.optLong("id", -1);
      String assignedEmail = assigned.optString("email");
      for (int i = 0; i < spinnerValues.size(); i++) {
        JSONObject user = spinnerValues.get(i).user;
        if (user != null) {
          if (user.optLong("id") == assignedId
              || (user.optString("email").equals(assignedEmail)
                  && !(TextUtils.isEmpty(assignedEmail)))) assignedIndex = i;
        }
      }
    }

    final int selected = assignedIndex;
    final ArrayAdapter<AssignedToUser> usersAdapter =
        new ArrayAdapter<AssignedToUser>(
            activity, android.R.layout.simple_spinner_item, spinnerValues);
    usersAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    activity.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            assignedSpinner.setAdapter(usersAdapter);
            assignedSpinner.setSelection(selected);
          }
        });
  }
Ejemplo n.º 18
0
  private void sync() {
    try {
      int batchSize = 4;
      List<ClientToServerMessage<?>> messageBatch = new ArrayList<ClientToServerMessage<?>>();
      while (true) {
        synchronized (monitor) {
          while ((pendingMessages.isEmpty() && !timeForBackgroundSync())
              || !actFmPreferenceService.isLoggedIn()
              || !syncMigration) {
            try {
              if ((pendingMessages.isEmpty() || !actFmPreferenceService.isLoggedIn())
                  && notificationId >= 0) {
                notificationManager.cancel(notificationId);
                notificationId = -1;
              }
              monitor.wait();
              AndroidUtilities.sleepDeep(
                  500L); // Wait briefly for large database operations to finish (e.g. adding a task
                         // with several tags may trigger a message before all saves are done--fix
                         // this?)

              if (!syncMigration) {
                syncMigration =
                    Preferences.getBoolean(AstridNewSyncMigrator.PREF_SYNC_MIGRATION, false);
              }
            } catch (InterruptedException e) {
              // Ignored
            }
          }
        }

        boolean recordSyncSuccess = true;
        if (timeForBackgroundSync()) {
          repopulateQueueFromOutstandingTables();
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(
                  TaskListMetadata.class, NameMaps.PUSHED_AT_TASK_LIST_METADATA),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(Task.class, NameMaps.PUSHED_AT_TASKS),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(TagData.class, NameMaps.PUSHED_AT_TAGS),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(User.class, NameMaps.PUSHED_AT_USERS),
              DEFAULT_REFRESH_RUNNABLE);
          setTimeForBackgroundSync(false);
        }

        while (messageBatch.size() < batchSize && !pendingMessages.isEmpty()) {
          ClientToServerMessage<?> message = pendingMessages.remove(0);
          if (message != null) {
            messageBatch.add(message);
          }
        }

        if (!messageBatch.isEmpty() && checkForToken()) {
          JSONPayloadBuilder payload = new JSONPayloadBuilder();
          MultipartEntity entity = new MultipartEntity();
          boolean containsChangesHappened = false;
          for (int i = 0; i < messageBatch.size(); i++) {
            ClientToServerMessage<?> message = messageBatch.get(i);
            boolean success = payload.addMessage(message, entity);
            if (success) {
              if (message instanceof ChangesHappened) {
                containsChangesHappened = true;
              }
            } else {
              messageBatch.remove(i);
              i--;
            }
          }

          if (payload.getMessageCount() == 0) {
            messageBatch.clear();
            continue;
          }

          setupNotification();

          payload.addJSONObject(getClientVersion());

          JSONArray errors = null;
          try {
            JSONObject response =
                actFmInvoker.postSync(
                    payload.closeAndReturnString(), entity, containsChangesHappened, token);
            // process responses
            String time = response.optString("time");
            JSONArray serverMessagesJson = response.optJSONArray("messages");
            if (serverMessagesJson != null) {
              setWidgetSuppression(true);
              for (int i = 0; i < serverMessagesJson.length(); i++) {
                JSONObject serverMessageJson = serverMessagesJson.optJSONObject(i);
                if (serverMessageJson != null) {
                  ServerToClientMessage serverMessage =
                      ServerToClientMessage.instantiateMessage(serverMessageJson);
                  if (serverMessage != null) {
                    serverMessage.processMessage(time);
                  } else {
                    syncLog(
                        "Index "
                            + i
                            + " unable to instantiate message "
                            + serverMessageJson.toString());
                  }
                }
              }
              errors = response.optJSONArray("errors");
              boolean errorsExist = (errors != null && errors.length() > 0);
              replayOutstandingChanges(errorsExist);
              setWidgetSuppression(false);
            }

            batchSize = Math.max(12, Math.min(batchSize, messageBatch.size()) * 2);

            if (recordSyncSuccess) {
              actFmPreferenceService.setLastError(null, null);
              actFmPreferenceService.recordSuccessfulSync();
            }
          } catch (IOException e) {
            Log.e(ERROR_TAG, "IOException", e);
            batchSize = Math.max(batchSize / 2, 1);
          }

          Set<SyncMessageCallback> callbacksExecutedThisLoop = new HashSet<SyncMessageCallback>();
          Map<Integer, List<JSONArray>> errorMap = buildErrorMap(errors);
          for (int i = 0; i < messageBatch.size(); i++) {
            ClientToServerMessage<?> message = messageBatch.get(i);
            try {
              SyncMessageCallback r = pendingCallbacks.remove(message);
              if (r != null && !callbacksExecutedThisLoop.contains(r)) {
                List<JSONArray> errorList = errorMap.get(i);
                if (errorList == null || errorList.isEmpty()) {
                  r.runOnSuccess();
                } else {
                  r.runOnErrors(errorList);
                }

                callbacksExecutedThisLoop.add(r);
              }
            } catch (Exception e) {
              Log.e(ERROR_TAG, "Unexpected exception executing sync callback", e);
            }
          }

          messageBatch.clear();
        }
      }
    } catch (Exception e) {
      // In the worst case, restart thread if something goes wrong
      Log.e(ERROR_TAG, "Unexpected sync thread exception", e);
      thread = null;
      startSyncThread();
    }
  }
Ejemplo n.º 19
0
  @Override
  public void onReceive(Context context, Intent intent) {
    if (!Preferences.getBoolean(R.string.p_rmd_enabled, true)) return;

    DependencyInjectionService.getInstance().inject(this);

    int reengagementReminders = Preferences.getInt(ReengagementService.PREF_REENGAGEMENT_COUNT, 1);
    Preferences.setInt(ReengagementService.PREF_REENGAGEMENT_COUNT, reengagementReminders + 1);

    Intent notifIntent = new Intent(context, TaskListActivity.class);

    QueryTemplate template = new QueryTemplate().where(TaskCriteria.activeVisibleMine());
    String sql =
        SortHelper.adjustQueryForFlagsAndSort(template.toString(), 0, SortHelper.SORT_AUTO)
            + " LIMIT "
            + TASK_LIMIT; //$NON-NLS-1$

    boolean hasTasks = false;
    TodorooCursor<Task> tasks =
        taskService.query(
            Query.select(Task.ID).where(TaskCriteria.activeVisibleMine()).limit(TASK_LIMIT));
    try {
      hasTasks = tasks.getCount() > 0;
    } finally {
      tasks.close();
    }

    String title =
        Notifications.getRandomReminder(
            context.getResources().getStringArray(R.array.rmd_reengage_notif_titles));
    if (title.contains("%s")) { // $NON-NLS-1$
      String name = ""; // $NON-NLS-1$
      if (actFmPreferenceService.isLoggedIn()) {
        JSONObject thisUser = ActFmPreferenceService.thisUser();
        name = thisUser.optString("first_name"); // $NON-NLS-1$
        if (TextUtils.isEmpty(name)) name = thisUser.optString("name"); // $NON-NLS-1$
        if (TextUtils.isEmpty(name)) name = context.getString(R.string.rmd_reengage_name_default);
      }
      title = String.format(title, name);
    }

    String text =
        Notifications.getRandomReminder(
            context
                .getResources()
                .getStringArray(
                    hasTasks
                        ? R.array.rmd_reengage_dialog_options
                        : R.array.rmd_reengage_dialog_empty_options));

    FilterWithCustomIntent filter =
        new FilterWithCustomIntent(
            context.getString(R.string.rmd_NoA_filter),
            context.getString(R.string.rmd_NoA_filter),
            sql,
            null);
    filter.customTaskList = new ComponentName(context, ReengagementFragment.class);
    filter.customExtras = new Bundle();
    filter.customExtras.putString(ReengagementFragment.EXTRA_TEXT, text);

    notifIntent.setAction("NOTIFY_reengagement"); // $NON-NLS-1$
    notifIntent.putExtra(TaskListFragment.TOKEN_FILTER, filter);
    notifIntent.putExtra(ReengagementFragment.EXTRA_TEXT, text);
    notifIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    notifIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_REENGAGEMENT);

    NotificationManager manager = new AndroidNotificationManager(context);
    Notification notification =
        new Notification(R.drawable.notif_astrid, text, System.currentTimeMillis());

    PendingIntent pendingIntent =
        PendingIntent.getActivity(context, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    notification.setLatestEventInfo(context, title, text, pendingIntent);

    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    if (Preferences.getBoolean(R.string.p_rmd_persistent, true)) {
      notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_SHOW_LIGHTS;
      notification.ledOffMS = 5000;
      notification.ledOnMS = 700;
      notification.ledARGB = Color.YELLOW;
    } else {
      notification.defaults = Notification.DEFAULT_LIGHTS;
    }

    manager.notify(0, notification);
    Flags.set(Flags.REFRESH); // Forces a reload when app launches

    ReengagementService.scheduleReengagementAlarm(context);
  }
Ejemplo n.º 20
0
  /** Synchronize with server when data changes */
  public void pushTaskOnSave(Task task, ContentValues values) {
    long remoteId;
    if (task.containsValue(Task.REMOTE_ID)) remoteId = task.getValue(Task.REMOTE_ID);
    else {
      Task taskForRemote = taskService.fetchById(task.getId(), Task.REMOTE_ID);
      if (taskForRemote == null) return;
      remoteId = taskForRemote.getValue(Task.REMOTE_ID);
    }
    boolean newlyCreated = remoteId == 0;

    ArrayList<Object> params = new ArrayList<Object>();

    if (values.containsKey(Task.TITLE.name)) {
      params.add("title");
      params.add(task.getValue(Task.TITLE));
    }
    if (values.containsKey(Task.DUE_DATE.name)) {
      params.add("due");
      params.add(task.getValue(Task.DUE_DATE) / 1000L);
      params.add("has_due_time");
      params.add(task.hasDueTime() ? 1 : 0);
    }
    if (values.containsKey(Task.NOTES.name)) {
      params.add("notes");
      params.add(task.getValue(Task.NOTES));
    }
    if (values.containsKey(Task.DELETION_DATE.name)) {
      params.add("deleted_at");
      params.add(task.getValue(Task.DELETION_DATE) / 1000L);
    }
    if (values.containsKey(Task.COMPLETION_DATE.name)) {
      params.add("completed");
      params.add(task.getValue(Task.COMPLETION_DATE) / 1000L);
    }
    if (values.containsKey(Task.IMPORTANCE.name)) {
      params.add("importance");
      params.add(task.getValue(Task.IMPORTANCE));
    }
    if (values.containsKey(Task.RECURRENCE.name)) {
      params.add("repeat");
      params.add(task.getValue(Task.RECURRENCE));
    }
    if (values.containsKey(Task.USER_ID.name) && task.getValue(Task.USER_ID) >= 0) {
      params.add("user_id");
      if (task.getValue(Task.USER_ID) == 0) params.add(ActFmPreferenceService.userId());
      else params.add(task.getValue(Task.USER_ID));
    }
    if (Flags.checkAndClear(Flags.TAGS_CHANGED) || newlyCreated) {
      TodorooCursor<Metadata> cursor = TagService.getInstance().getTags(task.getId());
      try {
        if (cursor.getCount() == 0) {
          params.add("tags");
          params.add("");
        } else {
          Metadata metadata = new Metadata();
          for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            metadata.readFromCursor(cursor);
            if (metadata.containsNonNullValue(TagService.REMOTE_ID)
                && metadata.getValue(TagService.REMOTE_ID) > 0) {
              params.add("tag_ids[]");
              params.add(metadata.getValue(TagService.REMOTE_ID));
            } else {
              params.add("tags[]");
              params.add(metadata.getValue(TagService.TAG));
            }
          }
        }
      } finally {
        cursor.close();
      }
    }

    if (params.size() == 0 || !checkForToken()) return;

    System.err.println("PUSHN ON SAVE: " + task.getMergedValues());
    System.err.println("SETVALUES: " + values);

    if (!newlyCreated) {
      params.add("id");
      params.add(remoteId);
    } else if (!params.contains(Task.TITLE.name)) return;

    try {
      params.add("token");
      params.add(token);
      JSONObject result =
          actFmInvoker.invoke("task_save", params.toArray(new Object[params.size()]));
      ArrayList<Metadata> metadata = new ArrayList<Metadata>();
      JsonHelper.taskFromJson(result, task, metadata);
      task.setValue(Task.MODIFICATION_DATE, DateUtilities.now());
      task.setValue(Task.LAST_SYNC, DateUtilities.now());
      Flags.set(Flags.SUPPRESS_SYNC);
      taskDao.saveExisting(task);
    } catch (JSONException e) {
      handleException("task-save-json", e);
    } catch (IOException e) {
      handleException("task-save-io", e);
    }
  }
Ejemplo n.º 21
0
  private void showCalReminder(Context context, long eventId, boolean fromPostpone) {
    ContentResolver cr = context.getContentResolver();
    Uri eventUri = Calendars.getCalendarContentUri(Calendars.CALENDAR_CONTENT_EVENTS);

    if (AndroidUtilities.getSdkVersion() <= 7) return;

    String[] eventArg = new String[] {Long.toString(eventId)};
    Cursor event =
        cr.query(eventUri, EVENTS_PROJECTION, Calendars.ID_COLUMN_NAME + " = ?", eventArg, null);
    try {
      if (event.moveToFirst()) {
        int dtstartIndex = event.getColumnIndexOrThrow(Calendars.EVENTS_DTSTART_COL);
        int dtendIndex = event.getColumnIndexOrThrow(Calendars.EVENTS_DTEND_COL);
        int titleIndex = event.getColumnIndexOrThrow(Calendars.EVENTS_NAME_COL);

        String title = event.getString(titleIndex);
        long startTime = event.getLong(dtstartIndex);
        long endTime = event.getLong(dtendIndex);

        boolean shouldShowReminder;
        if (fromPostpone) {
          long timeAfter = DateUtilities.now() - endTime;
          shouldShowReminder = (timeAfter > DateUtilities.ONE_MINUTE * 2);
        } else {
          long timeUntil = startTime - DateUtilities.now();
          shouldShowReminder = (timeUntil > 0 && timeUntil < DateUtilities.ONE_MINUTE * 20);
        }

        if (shouldShowReminder) {
          // Get attendees
          Cursor attendees =
              cr.query(
                  Calendars.getCalendarContentUri(Calendars.CALENDAR_CONTENT_ATTENDEES),
                  ATTENDEES_PROJECTION,
                  Calendars.ATTENDEES_EVENT_ID_COL + " = ? ",
                  eventArg,
                  null);
          try {
            // Do something with attendees
            int emailIndex = attendees.getColumnIndexOrThrow(Calendars.ATTENDEES_EMAIL_COL);
            int nameIndex = attendees.getColumnIndexOrThrow(Calendars.ATTENDEES_NAME_COL);

            ArrayList<String> names = new ArrayList<String>();
            ArrayList<String> emails = new ArrayList<String>();

            Account[] accountArray = AccountManager.get(context).getAccounts();
            Set<String> phoneAccounts = new HashSet<String>();
            for (Account a : accountArray) {
              phoneAccounts.add(a.name);
            }

            String astridUser = ActFmPreferenceService.thisUser().optString("email");
            if (!TextUtils.isEmpty(astridUser)) phoneAccounts.add(astridUser);

            boolean includesMe = false;
            for (attendees.moveToFirst(); !attendees.isAfterLast(); attendees.moveToNext()) {
              String name = attendees.getString(nameIndex);
              String email = attendees.getString(emailIndex);
              if (!TextUtils.isEmpty(email)) {
                if (phoneAccounts.contains(email)) {
                  includesMe = true;
                  continue;
                }
                if (Constants.DEBUG)
                  Log.w(CalendarAlarmScheduler.TAG, "Attendee: " + name + ", email: " + email);
                names.add(name);
                emails.add(email);
              }
            }

            if (emails.size() > 0 && includesMe) {
              Intent reminderActivity = new Intent(context, CalendarReminderActivity.class);
              reminderActivity.putStringArrayListExtra(CalendarReminderActivity.TOKEN_NAMES, names);
              reminderActivity.putStringArrayListExtra(
                  CalendarReminderActivity.TOKEN_EMAILS, emails);
              reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_ID, eventId);
              reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_NAME, title);
              reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_START_TIME, startTime);
              reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_END_TIME, endTime);
              reminderActivity.putExtra(CalendarReminderActivity.TOKEN_FROM_POSTPONE, fromPostpone);
              reminderActivity.setFlags(
                  Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
              context.startActivity(reminderActivity);
            }
          } finally {
            attendees.close();
          }
        }
      }
    } finally {
      event.close();
    }
  }