<commit_before>package com.gimranov.zandy.app.data;

import java.util.ArrayList;
import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;

import com.gimranov.zandy.app.task.APIRequest;

import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class Attachment {

	public String key;
	public String parentKey;
	public String etag;
	public String status;
	public String dbId;
	public String title;
	public String filename;
	public String url;
	
	/**
	 * Queue of attachments that need to be synced, because they're dirty
	 */
	public static ArrayList<Attachment> queue;
	
	/**
	 * APIRequest.API_DIRTY means that we'll try to push this version up to the server
	 */
	public String dirty;
	
	/**
	 * Zotero's JSON format for attachment / child information
	 * 
	 * linkMode:	O = file attachment, in ZFS?
	 * 				1 = link attachment?
	 */
	public JSONObject content;
	
	public static Database db;
	
	private static final String TAG = "com.gimranov.zandy.app.data.Attachment";
	
	public static final String ZFS_AVAILABLE = "Available for download";
	public static final String ZFS_LOCAL = "Downloaded";	
	public static final String UNKNOWN = "Status unknown";	

	public Attachment () {
		if (queue == null) queue = new ArrayList<Attachment>();
		parentKey = title = filename = url = status = etag = dirty = "";
		content = new JSONObject();
	}
	
	public Attachment(Context c, String type, String parentKey) {
		this();
		content = new JSONObject();
		try {
			content.put("itemType", type);
		} catch (JSONException e) {
			Log.d(TAG,"JSON exception caught setting itemType in Attachment constructor", e);
		}
		key = UUID.randomUUID().toString();
		this.parentKey = parentKey;
		dirty = APIRequest.API_NEW;
	}
	
	public String getType () {
		String type = "";
		try {
			type = content.getString("itemType");
			if (type.equals("attachment"))
				type = content.getString("mimeType");
			if (type.equals("note"))
				type = "note";
		} catch (JSONException e) {
			Log.e(TAG, "JSON exception parsing attachment content",e);
		}
		return type;
	}
	
	public void setNoteText (String text) {
		if (getType().equals("note")) {
			try {
				content.put("note", text);
			} catch (JSONException e) {
				Log.e(TAG, "JSON exception setting note text",e);
			}
		}
	}
	
	public void save() {
		Attachment existing = load(key);
		if (dbId == null && existing == null) {
			Log.d(TAG, "Saving new, with status: "+status);
			String[] args = { key, parentKey, title, filename, url, status, etag, dirty, content.toString() };
			Cursor cur = db
					.rawQuery(
							"insert into attachments (attachment_key, item_key, title, filename, url, status, etag, dirty, content) "
									+ "values (?, ?, ?, ?, ?, ?, ?, ?, ?)",
							args);
			if (cur != null)
				cur.close();
			Attachment fromDB = load(key);
			dbId = fromDB.dbId;
		} else {
			Log.d(TAG, "Saving new, with status: "+status);
			if (dbId == null)
				dbId = existing.dbId;
			String[] args = { key, parentKey, title, filename, url, status, etag, dirty, content.toString(), dbId };
			Log.i(TAG, "Updating existing attachment");
			Cursor cur = db
					.rawQuery(
							"update attachments set attachment_key=?, item_key=?, title=?," +
							" filename=?, url=?, status=?, etag=?, dirty=?, " +
							" content=? "
									+ " where _id=?", args);
			if (cur != null)
				cur.close();
		}
		db.close();
	}
	
	/**
	 * Identifies dirty items in the database and queues them for syncing
	 */
	public static void queue() {
		Log.d(TAG, "Clearing attachment dirty queue before repopulation");
		queue.clear();
		Attachment attachment;
		String[] cols = Database.ATTCOLS;
		String[] args = { APIRequest.API_CLEAN };
		Cursor cur = db.query("attachments", cols, "dirty != ?", args, null, null,
				null, null);

		if (cur == null) {
			Log.d(TAG, "No dirty attachments found in database");
			queue.clear();
			return;
		}

		do {
			Log.d(TAG, "Adding attachment to dirty queue");
			attachment = load(cur);
			queue.add(attachment);
		} while (cur.moveToNext() != false);

		if (cur != null)
			cur.close();
	}

	/**
	 * Get an Attachment from the current cursor position.<commit_msg>Initialize Attachment.queue before clearing; resolves NullPointerException crash report from Nov 6<commit_after>package com.gimranov.zandy.app.data;

import java.util.ArrayList;
import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;

import com.gimranov.zandy.app.task.APIRequest;

import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class Attachment {

	public String key;
	public String parentKey;
	public String etag;
	public String status;
	public String dbId;
	public String title;
	public String filename;
	public String url;
	
	/**
	 * Queue of attachments that need to be synced, because they're dirty
	 */
	public static ArrayList<Attachment> queue;
	
	/**
	 * APIRequest.API_DIRTY means that we'll try to push this version up to the server
	 */
	public String dirty;
	
	/**
	 * Zotero's JSON format for attachment / child information
	 * 
	 * linkMode:	O = file attachment, in ZFS?
	 * 				1 = link attachment?
	 */
	public JSONObject content;
	
	public static Database db;
	
	private static final String TAG = "com.gimranov.zandy.app.data.Attachment";
	
	public static final String ZFS_AVAILABLE = "Available for download";
	public static final String ZFS_LOCAL = "Downloaded";	
	public static final String UNKNOWN = "Status unknown";	

	public Attachment () {
		if (queue == null) queue = new ArrayList<Attachment>();
		parentKey = title = filename = url = status = etag = dirty = "";
		content = new JSONObject();
	}
	
	public Attachment(Context c, String type, String parentKey) {
		this();
		content = new JSONObject();
		try {
			content.put("itemType", type);
		} catch (JSONException e) {
			Log.d(TAG,"JSON exception caught setting itemType in Attachment constructor", e);
		}
		key = UUID.randomUUID().toString();
		this.parentKey = parentKey;
		dirty = APIRequest.API_NEW;
	}
	
	public String getType () {
		String type = "";
		try {
			type = content.getString("itemType");
			if (type.equals("attachment"))
				type = content.getString("mimeType");
			if (type.equals("note"))
				type = "note";
		} catch (JSONException e) {
			Log.e(TAG, "JSON exception parsing attachment content",e);
		}
		return type;
	}
	
	public void setNoteText (String text) {
		if (getType().equals("note")) {
			try {
				content.put("note", text);
			} catch (JSONException e) {
				Log.e(TAG, "JSON exception setting note text",e);
			}
		}
	}
	
	public void save() {
		Attachment existing = load(key);
		if (dbId == null && existing == null) {
			Log.d(TAG, "Saving new, with status: "+status);
			String[] args = { key, parentKey, title, filename, url, status, etag, dirty, content.toString() };
			Cursor cur = db
					.rawQuery(
							"insert into attachments (attachment_key, item_key, title, filename, url, status, etag, dirty, content) "
									+ "values (?, ?, ?, ?, ?, ?, ?, ?, ?)",
							args);
			if (cur != null)
				cur.close();
			Attachment fromDB = load(key);
			dbId = fromDB.dbId;
		} else {
			Log.d(TAG, "Saving new, with status: "+status);
			if (dbId == null)
				dbId = existing.dbId;
			String[] args = { key, parentKey, title, filename, url, status, etag, dirty, content.toString(), dbId };
			Log.i(TAG, "Updating existing attachment");
			Cursor cur = db
					.rawQuery(
							"update attachments set attachment_key=?, item_key=?, title=?," +
							" filename=?, url=?, status=?, etag=?, dirty=?, " +
							" content=? "
									+ " where _id=?", args);
			if (cur != null)
				cur.close();
		}
		db.close();
	}
	
	/**
	 * Identifies dirty items in the database and queues them for syncing
	 */
	public static void queue() {
		if (queue == null) {
			// Initialize the queue if necessary
			queue = new ArrayList<Attachment>();
		}
		Log.d(TAG, "Clearing attachment dirty queue before repopulation");
		queue.clear();
		Attachment attachment;
		String[] cols = Database.ATTCOLS;
		String[] args = { APIRequest.API_CLEAN };
		Cursor cur = db.query("attachments", cols, "dirty != ?", args, null, null,
				null, null);

		if (cur == null) {
			Log.d(TAG, "No dirty attachments found in database");
			queue.clear();
			return;
		}

		do {
			Log.d(TAG, "Adding attachment to dirty queue");
			attachment = load(cur);
			queue.add(attachment);
		} while (cur.moveToNext() != false);

		if (cur != null)
			cur.close();
	}

	/**
	 * Get an Attachment from the current cursor position.
{'fraction_non_alphanumeric': 0.13713620488940628, 'fraction_numerical': 0.0003492433061699651, 'mean_word_length': 3.401127049180328, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2882863', 'n_tokens_mistral': 3127, 'n_tokens_neox': 2691, 'n_words': 834}