// Copyright 2013 Michel Kraemer // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.undercouch.citeproc.tool; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import de.undercouch.citeproc.CSLTool; import de.undercouch.citeproc.ItemDataProvider; import de.undercouch.citeproc.csl.CSLItemData; import de.undercouch.citeproc.helper.CSLUtils; import de.undercouch.citeproc.zotero.ZoteroConnector; import de.undercouch.citeproc.zotero.ZoteroItemDataProvider; import de.undercouch.underline.CommandDesc; import de.undercouch.underline.CommandDescList; import de.undercouch.underline.OptionDesc; /** * Generates bibliographies and citations from Zotero * @author Michel Kraemer */ public class ZoteroCommand extends AbstractRemoteCommand { @OptionDesc(longName = "sync", shortName = "s", description = "force synchronization with Zotero") @Override public void setSync(boolean sync) { super.setSync(sync); } @CommandDescList({ @CommandDesc(longName = "bibliography", description = "generate bibliography from Zotero", command = ZoteroBibliographyCommand.class), @CommandDesc(longName = "citation", description = "generate citations from Zotero", command = ZoteroCitationCommand.class), @CommandDesc(longName = "list", description = "display sorted list of available citation IDs " + "in the Zotero library", command = ZoteroListCommand.class), @CommandDesc(longName = "json", description = "convert Zotero library to JSON", command = ZoteroJsonCommand.class), @CommandDesc(longName = "sync", description = "synchronize with Zotero", command = ZoteroSyncCommand.class) }) @Override public void setSubcommand(ProviderCommand subcommand) { super.setSubcommand(subcommand); } @Override public String getUsageName() { return "zotero"; } @Override public String getUsageDescription() { return "Connect to Zotero and generate styled citations and bibliographies"; } @Override protected ItemDataProvider createItemDataProvider(CSLItemData[] itemData) { return new ZoteroItemDataProvider(super.createItemDataProvider(itemData)); } @Override protected ZoteroConnector createRemoteConnector(String consumerKey, String consumerSecret) { return new ZoteroConnector(consumerKey, consumerSecret); } @Override protected String getAuthStoreFileName() { return "zotero-auth-store.conf"; } @Override protected String getCacheFileName() { return "zotero-cache.dat"; } /** * Reads the Zotero consumer key and consumer secret from an encrypted * file. This is indeed not the most secure way to save these tokens, but * it's certainly better than putting them unencrypted in this file. * @return the key and secret * @throws Exception if something goes wrong */ protected String[] readConsumer() throws Exception { String str = CSLUtils.readStreamToString(CSLTool.class.getResourceAsStream( "helper/tool/internal/citeproc-java-tool-consumer2"), "UTF-8"); byte[] arr = DatatypeConverter.parseBase64Binary(str); SecretKeySpec k = new SecretKeySpec("5zt&%3,oc\"??823_".getBytes(), "AES"); Cipher c = Cipher.getInstance("AES"); c.init(Cipher.DECRYPT_MODE, k); arr = c.doFinal(arr); arr = DatatypeConverter.parseBase64Binary(new String(arr)); String[] result = new String[] { "", "" }; for (int i = 0; i < 20; ++i) { result[0] += (char)arr[i + 789]; } for (int i = 0; i < 20; ++i) { result[1] += (char)arr[i + 1478]; } return result; } }