Converting .db to .vcf - android

I accidentally deleted my contacts and i don't have a backup for that now i got the contacts2.db and i am trying to covert the .db to .vcf. Now i am using Ruby to convert the file and here is what i did
gem install sqlite3
gem install vpim
path to contacts2-to-vcard.rb/contacts2-to-vcard.rb > contacts.vcf
i always says 'Access Denied.' And i set the folder to full control but whenever i run that command it change to read only, by the way i am using windows 8. Any help? Or is there a alternate why to convert .db to .vcf? TIA

Yank it out of the DB (this is all in Ruby):
require 'sqlite3'
path_to_contactsdb_file = "/SAMPLE/PATH/TO/contacts2.db"
db = SQLite3::Database.new path_to_contactsdb_file
raw_contacts = db.execute("select _id,display_name from raw_contacts")
contacts = {}
raw_contacts.each do |x|
contacts[x[1]] = {}
contacts[x[1]]['rcid'] = x[0]
contacts[x[1]]['nums'] = db.execute("select normalized_number from phone_lookup where raw_contact_id=" + x[0].to_s)
end
Pull it to CSV:
output_filepath = "/SAMPLE/EXAMPLE/FILEPATH"
csv = ""
contacts.each do |k,v|
csv += '"' + k + '",'
v['nums'].each do |num|
csv += '"' + num[0] + '",'
end
csv += "\n"
end
File.open(output_filepath,"w") {|file| file.write(csv) }
Then you can use a CSV import app, do it through Google contacts import through CSV, etc.. You can send me a fruit basket.
If it MUST be in a VCF format, then just change the output syntax of the CSV. Look up a sample VCF file, I couldn't be bothered.

I've been trying to use Dustin van Schouwen's code to do this task. I wanted to thank him for it, first of all, and then mention a few details I needed to add/change to make it work for me:
This line:
db = SQLite3::Database.new path_to_contactsdb_file
I changed to:
db = SQLite3::Database.new ("contacts2.db")
As when using the previous one, even though it doesn't give an error, it doesn't seem to actually connect to the database (I think it creates an empty one).
The other change I needed to do was at this other line:
csv += '"' + k + '",
If "k" is nil, the code will fail, so I introduced an if (ternary syntax) to solve it, and it worked fine:
csv += '"' + (k == nil ? "" : k) + '",'

A bit late for OP sorry. I can't give tips on ruby anyway.
But I stumbled here when searching a solution for my own needs.
I finally came up with a python solution:
https://gitlab.com/Arnaudv6/contacts2.db-2-vcard
based on previous works documented on above page.
Please refer to "todo" section at beginning of the script
for details on what is not implemented to date.

Related

Run Powershell Command from Oracle Procedure

I need to print pdf documents to my network printer from my android studio application. I want to print the pdf as is with all images and formatting, however, the solutions I have found only allow for the extraction and printing of text from the pdf.
I have also seen solutions mentioning tools like Ghostscript etc which are supposed to convert the pdf to a postscript file, but these tools do not work with Android Studio or at-least I haven't figured out how to integrate them into my application. I cannot pay for tools like jPDFPrint which does exactly what I need.
I started thinking about a work around and came upon the idea of sending my pdf as a blob to my oracle database and invoke a power shell command from a procedure to print it to a specific printer.
I've created and tested the below command to print to my network printer from my PC which works great.
Start-Process -FilePath “c:\test.pdf” –Verb PrintTo '\\PrintServer\PrinterName' -PassThru | %{sleep 10;$_} | kill
Now I need help with the oracle part. Is it possible to invoke or run a powershell command from within oracle 12c and pass it the pdf blob as well as the printer name?
To extract the BLOB to a PDF.
Create you system folder, eg c:\printthis.
Then create the Oracle directory object mapped to this folder:
CREATE OR REPLACE DIRECTORY print_dir AS 'C:\print_this';
GRANT READ WRITE ON DIRECTORY print_dir TO PUBLIC;
This procedure to extract the BLOB to a file.
CREATE OR REPLACE PROCEDURE extract_pdf ( p_id IN VARCHAR2 ) AS
CURSOR c1 IS
SELECT doc_blob, doc_name
FROM doc_table
WHERE doc_id = p_id;
r1 c1%ROWTYPE;
v_size NUMBER( 5,0) := 32000;
v_len NUMBER(38,0);
v_buffer RAW(32000);
v_file UTL_FILE.FILE_TYPE;
BEGIN
OPEN c1;
FETCH c1 INTO r1;
v_file := UTL_FILE.FOPEN('PRINT_DIR', r1.doc_name, 'wb', 32760 );
v_start := 1;
v_len := DBMS_LOB.GETLENGTH( r.bbl_fic );
WHILE v_start <= v_len LOOP
DBMS_LOB.READ(
r.bbl_fic,
LEAST( v_len - v_start + 1, v_size ),
v_start,
v_buffer
);
UTL_FILE.PUT_RAW( v_file, v_buffer );
UTL_FILE.FFLUSH( v_file );
v_start := v_start + v_size;
END LOOP;
UTL_FILE.FCLOSE( v_file );
-- Write the CMD file
v_file := UTL_FILE.FOPEN('PRINT_DIR', r1.doc_name || '.bat', 'w' );
UTL_FILE.PUT_LINE( 'Start-Process -FilePath “c:\print_this\' || r1.doc_name || '” –Verb PrintTo '\\PrintServer\PrinterName' -PassThru | %{sleep 10;$_} | kill' );
UTL_FILE.CLOSE(v_file);
END;
/
A Windows At job that runs, polls the c:\print_this folder for files and runs the .bat command, then deletes it.
#ECHO OFF
setlocal enabledelayedexpansion
for %%f in (c:\print_this\*.bat) do (
echo "Name: %%f"
powershell %%f
del %%f
)
The question remains of how to stitch this together. Your Android app calls your procedure to store the PDF as a BLOB. It must also be able to call the procedure suggested above to extract the saved BLOB to a database server file, so this procedure to extract the ODF AND create the print bat script is called after the save BLOB.
The Task Scheduler job polls the directory for the bat scripts, runs them deletes them.
You cannot directly issue a command to the server host from within Oracle. You can use DBMS_SCHEDULER. In the above example, the job would take the doc_id as a parameter, and execute this via DBMS_SCHEDULER.RUN_JOB. I cant remember how to do this precisely, but I hope my other suggestion with the Task Scheduler in Windows is fruitful for you.
You can use the PL/SQL package DBMS_SCHEDULER procedure create_program, using the program_type=>'EXECUTABLE' to do what you want. Then you would have your process that sends the data to oracle create a job to invoke that program. The DBMS_SCHEDULER package is pretty complex so you'll probably need to hunt around for tutorials/tips; you may want to search https://asktom.oracle.com for starters.

ADB command from macOS application with special characters

I want to pull a file from my android device through an adb command from my macOS application.
Everything works perfect with the code below, except when the name of the file I want to pull contains special characters like german umlauts (äöüÄÖÜ).
I get this error:
adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory.
But when I use the command adb pull /storage/emulated/0/Download/Böse ~/Desktop from within the Terminal.app, the file will be pulled to my computer.
The strange thing here is that if I copy the substring /storage/emulated/0/Download/Böse from the Xcode console output, the command is also not working within the Terminal.app until I delete the ö and replace it with an ö from my keyboard input.
I tried replacing the ö with the unicode representation \u{00f6}, but this has no effect (but the console output still shows an ö but the 'wrong' encoded one.
// Configure task.
let task = Process()
task.launchPath = "~/Library/Android/sdk/platform-tools/adb"
task.arguments = ["pull", "/storage/emulated/0/Download/Böse", "~/Desktop"]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
// adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory
print(output)
I found the following in the documentation, how the Process handles the arguments that I provide:
The NSTask object converts both path and the strings in arguments to appropriate C-style strings (using fileSystemRepresentation) before passing them to the task via argv[] . The strings in arguments do not undergo shell expansion, so you do not need to do special quoting, and shell variables, such as $PWD, are not resolved.
It seems like I am not the only one with this problem, and I found this workaround:
How to work around NSTask calling -[NSString fileSystemRepresentation] for arguments, but I was not able to make it work with Swift.
As a workaround I am now writing my adb command to a file and execute it from a bash command in my application.
let source = "/storage/emulated/0/Download/Böse"
let destination = "~/Desktop"
guard let uniqueURL = URL(string: destination + "/" + ProcessInfo.processInfo.globallyUniqueString) else { return }
// Write command to file
let scriptContent = "#!/bin/bash\n~/Library/Android/sdk/platform-tools/adb pull -a \"" + source + "\" \"" + destination + "\""
try? scriptContent.write(to: uniqueURL, atomically: false, encoding: .utf8)
// Configure task.
let task = Process()
task.environment = ["LC_ALL": "de_DE.UTF-8", "LANG": "de_DE.UTF-8"]
task.launchPath = "/bin/bash"
task.arguments = [uniqueURL.path]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
try? task.run()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
print(output)
Even though this is working for now, it is not a satisfactory solution as it is not very elegant and not efficient too, so any improvements or better answers are welcome.

WebView app (PhoneGap Build), not saving localStorage after restart

For some reason, when I restart my PhoneGap app - it looses the localStorage vales that were stored before! I'm saving them in the normal way:
localStorage.setItem("foo","value");
This stores it just fine. However, when you restart the app (or leave the device off for a random amount of time), it seems to randomly loose the data. I've found a heck of a lot of posts about this - but no definative answer on how to get it to be persistent in a PhoneGap Build WebView app,
Any suggestions are much welcomed!
This seems to be quite a common problem with WebView apps:
Android 2.3.6 + Phonegap + localStorage
Android - Making Webview DomStorage persistant after app closed
I can't find a solution that works with PhoneGap Build apps though
An actual example I'm using, is:
var current_id = parseInt(currentId) + 1;
localStorage.setItem("entry_"+current_id,save_string);
localStorage.setItem("entryId",current_id);
..and then to extract it (not that this is important, as the problem is with the data going missing, and not with accessing it)
for (var i = 0; i < localStorage.length; i++){
if (localStorage.key(i).match("entry_")) {
outputString += "\n" + localStorage.getItem(localStorage.key(i));
}
}
I'm wondering if maybe upgrading from PhoneGap Build cli-5.2.0 to cli-6.0.0 may help. I will do this, and give it a whirl.
I guess another option, would be to use a SQL database to locally store the device (its just a bit trickier to setup, and means re-writing my code)
UPDATE: Not the ideal solution - but I have now moved the app over to use WebSQL for the app. It was a bit tricky to get the hang of (never used it before) - but seems to do the job, and shouldn't loose the data :)
EDIT
i tried it like this and it worked:
var current_id = parseInt(currentId) + 1;
localStorage.setItem("entry_"+current_id,save_string);
localStorage.setItem("entryId",current_id);
/*
//this is for checking, what is stored in localStorage
console.log("length: " + localStorage.length);
for(var i = 0; i < localStorage.length; i++) {
console.log(localStorage.key(i));
}
*/
var myEntryIdFromStorage = localStorage.getItem("entryId");
var myItem = localStorage.getItem("entry_" + myEntryIdFromStorage);
Old answer for clarification
How do you get your localstorage?
normally you should store items like you did:
var permanentStorage = window.localstorage;
permanentStorage.setItem("foo", "bar");
and get them back by initializing the permanentStorage the same way and:
//assuming you have permanentStorage in the same script file
//or else you have to initialize it again:
//var permanentStorage = window.localstorage;
var myItem = permanentStorage.getItem("foo");
console.log("myItem: " + myItem);
The method store item uses two parameters: the identifier and the data itself. Please check, that the identifier with which you store your data is the same as the one, with which you get it back.
Do you get any errors? Is the return (stored in my example in myItem) null or undefined or just an empty string? Does this fail in the browser or on the device?
You could clarify your question by providing more code or error messages!

Titanium install DB

I have some trouble with installing a database with Ti.Database.install(). Here's what I'm doing:
Open new default alloy project
Add some code to controllers/index.js so the file looks like this
var db = Ti.Database.install('/testimusDB.sqlite', 'testimusDB');
var rs = db.execute('SELECT * FROM testimusTable');
db.close();
while (rs.isValidRow())
{
var name = rs.fieldByName('name');
var age = rs.fieldByName('age');
alert(name + ' is ' + age + 'years old');
rs.next();
}
rs.close();
$.index.open();
create a DB with FF Plugin SQLite Manager called testimusDB.sqlite
and copy it to the REsources Folder of the Project
Start the App via Titanium Studio on a Samsung S3
What I get is
Runtime Error: LOCATION: [101,19] ti:/invoker.js
MESSAGE: Uncaught Error: Resources/testimusDB.sqlite SOURCE: return
delegate.apply(invoker._thisObj_,args);
People with the same problem solved it by reducing the size of the DB (mine is 64 KB) or by using absolute path (I tried absolute-/relative- path and sqlite-/db-/sql- suffix). Any ideas how to solve this problem?
Okay I got it: You can't use install() when you're using alloy! (If anybody knows an official source for this information please let me know). You need to use models to sync the database. This guy and this guide helped me a lot.
Thanks for the answers.
Close connection to db at the end of operation:
rs.close();
db.close();
Size of the database doesn't matter. I'm using much bigger one: >10MB.

Coding python on android

First of all, sorry. I am new to both programming and programming on my android device, but for some reason when I go to compile this code and run it using Python For Android. It keeps returning this error:
File "/storage/emulated/programming/pass.py", line 4, in
username = input("Username: ") File"", line 1, in
NameError: name 'user' is not defined
security = 0
username = ""
while not username:
username = input("username: ")
password = ""
while not password:
password = input("password: ")
if username == "user" and password == "pass":
security = 5
print (" Hello, security level is:" , security)
else:
print("invalid login")
Now, when I run this same bit of code on my PC, I do not get this error. Is anyone here familiar with writing Python code with Python For Android and Droidedit? I have installed all available modules.
Im guessing p4a is not py3.0+ therefore you need raw_input not input
in python2 raw_input is the same as input in python3+
using input in python2 is the same as doing eval(input("Username:")) in python 3
>>> x = raw_input("Enter Equation:")
Enter Equation: 5 + 3
>>> print repr(x)
'5 + 3'
>>> y = input("Enter Equation:") #this is the same as eval(input(msg)) in py3+
Enter Equation: 5 + 3
>>> print repr(y)
`8`
some further info regarding your error specifically. in python2 input attempts to evaluate the user input into python code. you are entering "user" as the username. python then tries to make it into code interpreting it as a variable. if for example you entered 543 for the username it would work fine. also if you entered "user" including the quotes it would work fine as both would evaluate down to python values (the quotes make it a string instead of a variable, and python knows what ints are)

Categories

Resources