/** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
   try {
     super.onCreate(savedInstanceState);
     mDbHelper = new CatalogueDBAdapter(this);
     mDbHelper.open();
     setContentView(R.layout.administration_functions);
     Bundle extras = getIntent().getExtras();
     if (extras != null && extras.containsKey(DOAUTO)) {
       try {
         if (extras.getString(DOAUTO).equals("export")) {
           finish_after = true;
           mExportOnStartup = true;
         } else {
           throw new RuntimeException("Unsupported DOAUTO option");
         }
       } catch (NullPointerException e) {
         Logger.logError(e);
       }
     }
     setupAdmin();
     Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
   } catch (Exception e) {
     Logger.logError(e);
   }
 }
  public static void searchGoogle(
      String mIsbn, String author, String title, Bundle bookData, boolean fetchThumbnail) {
    // replace spaces with %20
    author = author.replace(" ", "%20");
    title = title.replace(" ", "%20");

    String path = "http://books.google.com/books/feeds/volumes";
    if (mIsbn.equals("")) {
      path += "?q=" + "intitle:" + title + "+inauthor:" + author + "";
    } else {
      path += "?q=ISBN:" + mIsbn;
    }
    URL url;

    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser;
    SearchGoogleBooksHandler handler = new SearchGoogleBooksHandler();
    SearchGoogleBooksEntryHandler entryHandler =
        new SearchGoogleBooksEntryHandler(bookData, fetchThumbnail);

    try {
      url = new URL(path);
      parser = factory.newSAXParser();
      int count = 0;
      // We can't Toast anything from here; it no longer runs in UI thread. So let the caller deal
      // with any exceptions.
      parser.parse(Utils.getInputStream(url), handler);
      count = handler.getCount();
      if (count > 0) {
        String id = handler.getId();
        url = new URL(id);
        parser = factory.newSAXParser();
        parser.parse(Utils.getInputStream(url), entryHandler);
      }
      return;
    } catch (MalformedURLException e) {
      Logger.logError(e);
    } catch (ParserConfigurationException e) {
      Logger.logError(e);
    } catch (SAXException e) {
      Logger.logError(e);
    } catch (Exception e) {
      Logger.logError(e);
    }
    return;
  }
 /**
  * Import all data from the passed CSV file spec
  *
  * <p>return void
  *
  * @throws IOException
  */
 private void importData(String filespec) {
   ImportThread thread;
   try {
     thread = new ImportThread(getTaskManager(), filespec);
   } catch (IOException e) {
     Logger.logError(e);
     Toast.makeText(
             this,
             getString(R.string.problem_starting_import_arg, e.getMessage()),
             Toast.LENGTH_LONG)
         .show();
     return;
   }
   thread.start();
 }
  /** Combine all the data and create a book or display an error. */
  private void sendResults() {
    // This list will be the actual order of the result we apply, based on the
    // actual results and the default order.
    ArrayList<Integer> results = new ArrayList<Integer>();

    if (mHasIsbn) {
      // If ISBN was passed, ignore entries with the wrong ISBN, and put entries with no ISBN at the
      // end
      ArrayList<Integer> uncertain = new ArrayList<Integer>();
      for (int i : mDefaultReliabilityOrder) {
        if (mSearchResults.containsKey(i)) {
          Bundle bookData = mSearchResults.get(i);
          if (bookData.containsKey(CatalogueDBAdapter.KEY_ISBN)) {
            String isbn = bookData.getString(CatalogueDBAdapter.KEY_ISBN);
            if (IsbnUtils.matches(mIsbn, isbn)) {
              results.add(i);
            }
          } else {
            uncertain.add(i);
          }
        }
      }
      for (Integer i : uncertain) {
        results.add(i);
      }
      // Add the passed ISBN first; avoid overwriting
      mBookData.putString(CatalogueDBAdapter.KEY_ISBN, mIsbn);
    } else {
      // If ISBN was not passed, then just used the default order
      for (int i : mDefaultReliabilityOrder) results.add(i);
    }

    // Merge the data we have. We do this in a fixed order rather than as the threads finish.
    for (int i : results) accumulateData(i);

    // If there are thumbnails present, pick the biggest, delete others and rename.
    Utils.cleanupThumbnails(mBookData);

    // Try to use/construct authors
    String authors = null;
    try {
      authors = mBookData.getString(CatalogueDBAdapter.KEY_AUTHOR_DETAILS);
    } catch (Exception e) {
    }

    if (authors == null || authors.equals("")) {
      authors = mAuthor;
    }

    if (authors != null && !authors.equals("")) {
      // Decode the collected author names and convert to an ArrayList
      ArrayList<Author> aa = Utils.getAuthorUtils().decodeList(authors, '|', false);
      mBookData.putSerializable(CatalogueDBAdapter.KEY_AUTHOR_ARRAY, aa);
    }

    // Try to use/construct title
    String title = null;
    try {
      title = mBookData.getString(CatalogueDBAdapter.KEY_TITLE);
    } catch (Exception e) {
    }

    if (title == null || title.equals("")) title = mTitle;

    if (title != null && !title.equals("")) {
      mBookData.putString(CatalogueDBAdapter.KEY_TITLE, title);
    }

    // Try to use/construct isbn
    String isbn = null;
    try {
      isbn = mBookData.getString(CatalogueDBAdapter.KEY_ISBN);
    } catch (Exception e) {
    }

    if (isbn == null || isbn.equals("")) isbn = mIsbn;

    if (isbn != null && !isbn.equals("")) {
      mBookData.putString(CatalogueDBAdapter.KEY_ISBN, isbn);
    }

    // Try to use/construct series
    String series = null;
    try {
      series = mBookData.getString(CatalogueDBAdapter.KEY_SERIES_DETAILS);
    } catch (Exception e) {
    }

    if (series != null && !series.equals("")) {
      // Decode the collected series names and convert to an ArrayList
      try {
        ArrayList<Series> sa = Utils.getSeriesUtils().decodeList(series, '|', false);
        mBookData.putSerializable(CatalogueDBAdapter.KEY_SERIES_ARRAY, sa);
      } catch (Exception e) {
        Logger.logError(e);
      }
    } else {
      // add series to stop crashing
      mBookData.putSerializable(CatalogueDBAdapter.KEY_SERIES_ARRAY, new ArrayList<Series>());
    }

    //
    // TODO: this needs to be locale-specific. Currently we probably get good-enough data without
    // forcing a cleanup.
    //
    // Removed 20-Jan-2016 PJW; see Issue 717.
    //
    // Cleanup other fields
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_TITLE);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_PUBLISHER);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_DATE_PUBLISHED);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_SERIES_NAME);

    // If book is not found or missing required data, warn the user
    if (authors == null || authors.length() == 0 || title == null || title.length() == 0) {
      mTaskManager.doToast(BookCatalogueApp.getResourceString(R.string.book_not_found));
    }
    // Pass the data back
    sendSearchFinished();
  }
  public void onExportFinished(ExportThread task) {
    if (task.isCancelled()) {
      if (finish_after) finish();
      return;
    }

    AlertDialog alertDialog = new AlertDialog.Builder(AdministrationFunctions.this).create();
    alertDialog.setTitle(R.string.email_export);
    alertDialog.setIcon(android.R.drawable.ic_menu_send);
    alertDialog.setButton2(
        getResources().getString(R.string.ok),
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
            // setup the mail message
            final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
            emailIntent.setType("plain/text");
            // emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
            // context.getString(R.string.debug_email).split(";"));
            String subject =
                "[" + getString(R.string.app_name) + "] " + getString(R.string.export_data);
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
            // emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
            // context.getString(R.string.debug_body));
            // has to be an ArrayList
            ArrayList<Uri> uris = new ArrayList<Uri>();
            // Find all files of interest to send
            try {
              File fileIn = new File(StorageUtils.getSharedStoragePath() + "/" + "export.csv");
              Uri u = Uri.fromFile(fileIn);
              uris.add(u);
              // Send it, if there are any files to send.
              emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
              startActivity(Intent.createChooser(emailIntent, "Send mail..."));
            } catch (NullPointerException e) {
              Logger.logError(e);
              Toast.makeText(
                      AdministrationFunctions.this,
                      R.string.export_failed_sdcard,
                      Toast.LENGTH_LONG)
                  .show();
            }

            dialog.dismiss();
          }
        });
    alertDialog.setButton(
        getResources().getString(R.string.cancel),
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
            // do nothing
            dialog.dismiss();
          }
        });

    alertDialog.setOnDismissListener(
        new OnDismissListener() {
          @Override
          public void onDismiss(DialogInterface dialog) {
            if (finish_after) finish();
          }
        });

    if (!isFinishing()) {
      try {
        //
        // Catch errors resulting from 'back' being pressed multiple times so that the activity is
        // destroyed
        // before the dialog can be shown.
        // See http://code.google.com/p/android/issues/detail?id=3953
        //
        alertDialog.show();
      } catch (Exception e) {
        Logger.logError(e);
      }
    }
  }