I want to program a "talking clock" for my blind father and I have an very old laptop, 768 RAM. I have tried many different things, from making an app on android with kivy, without any success, because on my laptop (a different one) seems to work like a charm but when I'm "buildoze" it just doesn't play any mp3. I've tried some answers provided on SO with no success. Now I thought to try to install different things, like Python libraries for 2.79 and even Java on my old laptop, but seems that because Linux Mint 2.0 it's no longer supported can't install anything...
Does anyone have any suggestion if I can use that old laptop for such a thing or I can make an app for Android that plays mp3's?
I quite a noobie 😛
Thanks
Quick, dirty, and simple: install espeak and run something like the following in a cron job as often as you like:
dt=$(date +'%A, %B %d, %Y. The time is %l %M %p.'); espeak "Today is $dt"
EDIT: On reflection, It might be better to write a shell script and call that from cron. Assuming your father's only challenge is blindness, he probably doesn't need to be reminded of the date every, say, fifteen minutes. A script could speak the date every eight hours, perhaps, and the time as often as is useful.
EDIT AGAIN: Here's a script I threw together for fun. Give it a try.
#!/bin/bash
# If espeak isn't installed, complain and quit
command -v espeak > /dev/null 2>&1 ||\
{ echo -e "$0 requires espeak to be installed. Exiting..." ; exit 1; }
# ** Set variables
date_now=$(date +'%A, %B %d, %Y')
military_time=$(date +'%R') # 24-hour time
minute=$(date +'%M')
# We don't need espeak to say "zero zero" for the minutes
if [ $minute = "00" ]; then
time_now=$(date +'%l %p')
else
time_now=$(date +'%l %M %p')
fi
# Speak the date only if it's 9am or 5pm
[[ $military_time = "09:00" || $military_time = "17:00" ]] && espeak "Today is $date_now."
espeak "The time is $time_now."
Here's a speaking-clock in JS - just load it into a WebView or something - but you don't even need to package an app: just put it in a HTML page with a PWA manifest and save that as a home-screen icon so it will work while offline.
Click "Run code snippet" and then the button.
It will work in any modern web-browser available for Android and Linux desktops (except Opera and the stock (non-Chrome) Android Browser - it will also work in any modern Linux desktop environment - or any desktop OS, really.
I hope the code is self-explanatory.
It uses the Web Speech Synthesis API which is widely supported (except by the not-Google-Chrome Android Browser for some reason).
Note that it is not possible to make it play automatically or on-load (so need to click the button first to make speech synthesis work), as most browsers (including Chrome) block scripts from auto-playing sounds without user-interaction; the same applies to <video>, <audio>, etc.
Eta voila:
function sayTime() {
if( window.speechSynthesis.speaking ) return;
const now = new Date();
var tts = new SpeechSynthesisUtterance();
tts.text = "The time is now " + now.toLocaleTimeString();
window.speechSynthesis.speak( tts );
}
let timerId = null;
function toggleSpeakingClock() {
if( timerId ) {
window.speechSynthesis.cancel();
window.clearInterval( timerId );
timerId = null;
btn.textContent = "Click me to start";
}
else {
timerId = window.setInterval( sayTime, 1000 );
const btn = document.getElementById('btn');
btn.textContent = "Click me to stop";
}
}
document.addEventListener( 'DOMContentLoaded', function() {
const btn = document.getElementById('btn');
btn.disabled = !( typeof window.speechSynthesis === 'object' ) && ( window.speechSynthesis !== null );
if( btn.disabled ) btn.textContent = "Your browser doesn't support TTS";
} );
<button id="btn" onclick="toggleSpeakingClock()" disabled>Please wait...</button>
Related
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.
I have a great headache.
I have a running 'web-app', writed whith Rails4, in production hosted on a Google Compute Engine virtual machine with Ubuntu 14.04, where I use Rpush gem/Firebase for notification to an Android app 'my-app'.
Locally I use a similar configuration for development: an environment rvm with same Rails version.
Simultaneously, with AndroidStudio, I'm developing 'my-app' android app.
On Ubuntu 16.04.
When Rails/Rpush send a notification, I receive it on 'my-app'.
So I controls both sides of notification process (except Firebase as middle tier).
Great.
It worked fine until some days ago.
Production enviroment continues to working well.
Locally, on development, when 'web-app' send a notification (through RPush/Firebase) I don't receive any kind of message, but I receive it in production, on 'released-version' of 'my-app' !!!
Normally, working local, when 'local' 'web-app' send notification, 'local' 'my-app' receive it;
in production, when 'host' 'we-app' send notification, 'released-version' of 'my-app' receive it.
For a few days is like if, in Firebase, in middle tier, each notification is broadcasted through 'released-version' of 'my-app', also if came from 'local' debug environment !!
Same releases for both envs.
It worked well until a few days ago.
Surely I've touched somethings ... the project is in progess.
I've much debugged, I've controlled many times configurations (local, host and Firebase) read many logs without results.
Everything seems working well !!
Someone know some ways to show me how debugging/understand this mysterious (for me) behavior ?
In Rails, when a message is saved, is triggered a method to push notification as described in GitHub by RPush repository.
In Android, in class 'MyFirebaseMessagingService extends FirebaseMessagingService', on overrided method 'onMessageReceived(RemoteMessage remoteMessage)' I receive messages (notification or data) - following 'quickstart-android/messaging' example.
In Firebase I have a project where I take 'Server Key' and 'google-services.json'.
My headache is growing.
Any advice is welcome.
UPDATE 20180326
I upgrade my question with code executed when sending message, configuration and an extract of rpush log (Rails server side - both local and hosted).
Rails method triggered after save 'Message'
def notify_gcm(data)
if Rpush::Gcm::App.find_by_name(<firebase_app>).nil?
app = Rpush::Gcm::App.new
app.name = <firebase_app>
app.auth_key = <firebase-server_key>
app.connections = 1
app.save!
end
n = Rpush::Gcm::Notification.new
n.app = Rpush::Gcm::App.find_by_name(<firebase_app>)
n.delay_while_idle = true
n.registration_ids = [<device_token>, ...]
n.priority = 'high'
n.content_available = true
# notification type: DATA MESSAGE
n.data = { data: { message: data[:message]["content"] }, notificationdata: { body: ..., title: ..., icon: ... }
}
n.save!
Rpush.push
end
config/initializers/rpush
Rpush.configure do |config|
config.client = :active_record
config.push_poll = 5
config.batch_size = 100
config.pid_file = 'tmp/rpush.pid'
config.log_file = 'log/rpush.log'
config.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::ERROR
end
Rpush log
BEGIN
INSERT INTO `rpush_notifications` (`type`, `app_id`, `delay_while_idle`, `registration_ids`, `priority`, `content_available`, `data`, `created_at`, `updated_at`) VALUES (...)
COMMIT
SELECT `rpush_apps`.* FROM `rpush_apps`[<firebase_app>] Starting 1 dispatcher...
SELECT COUNT(*) FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.719515'))
BEGIN
SELECT `rpush_notifications`.* FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.720521')) ORDER BY created_at ASC LIMIT 100 FOR UPDATE
UPDATE `rpush_notifications` SET processing = 1 WHERE rpush_notifications`.`id` = 210
COMMIT
SELECT COUNT(*) FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.774452'))
SELECT `rpush_apps`.* FROM `rpush_apps` WHERE `rpush_apps`.`id` = 1 LIMIT 1
[<firebase_app>] 210 sent to ... <proper registration_ids>
Rpush is started as a daemon by commandline:
rpush start -e production
SOLVED
Gemfile
removed gem 'rails_12factor', group :production
this it was been previously removed to hosted (production) :(
Ubuntu user here. I am looking for a way to copy all flash drive and phone/tablet data to a specified folder whenever they are inserted. The python code below works great for flash drives but for some reason it will not work on my android phone or tablet. Additionally, I would like to only copy picture and video file extensions. My intention is to come home after a day of filming and plug in all my devices and have the pictures and video copy over. Thanks!
import subprocess
import time
import shutil
#--
target_folder = "/path/to/target_folder"
excluded = ["media_extern"]
#--
def get_mountedlist():
return [(item.split()[0].replace("├─", "").replace("└─", ""),
item[item.find("/"):]) for item in subprocess.check_output(
["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]
def identify(disk):
command = "find /dev/disk -ls | grep /"+disk
output = subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
if "usb" in output:
return True
else:
return False
done = []
while True:
mounted = get_mountedlist()
new_paths = [dev for dev in get_mountedlist() if not dev in done and not dev[1] == "/"]
valid = [dev for dev in new_paths if (identify(dev[0]), dev[1].split("/")[-1] in excluded) == (True, False)]
for item in valid:
target = target_folder+"/"+item[1].split("/")[-1]
try:
shutil.rmtree(target)
except FileNotFoundError:
pass
shutil.copytree(item[1], target)
done = mounted
time.sleep(4)here
I've been trying to access the rear camera on an LG G4 Android phone running Chrome. I'm able to filter out the video sources from MediaStreamTrack.getSources(), but when I try to set a constraint to prefer the rear camera, I get the error TypeError: Failed to execute 'webkitGetUserMedia' on 'Navigator': Malformed constraints object. Below I have the code I'm using to filter the video sources:
if (navigator.getUserMedia) {
if (MediaStreamTrack.getSources) {
MediaStreamTrack.getSources(function(sourceInfos) {
var sources = [];
_.forEach(sourceInfos, function(info) {
if (info.kind === 'video') {
sources.push(info);
}
})
handleSources(sources);
})
}
}
Then I'm trying to select a source in the handleSources function mentioned above:
function handleSources(sources) {
var constraints = {
video: {
facingMode: 'environment' // Yeah, this definitely doesn't work.
}
}
getMedia(constraints); // This calls getUserMedia with the selected contraints
}
I've tried tons of different formats for the constraints object, but none of them seem to work. I know I'd be able to loop through all the sources and select the environmental camera from there, but I'd love to know how the actual syntax for this works. Googling for the answer only brings up https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Parameters, the syntax of which doesn't work.
It would appear as though earlier/different versions of the Android browser implement a different API for camera discovery. I have found that each phone I have access to (emulator and physical) seems to respect a different set of options. To make matters worse this seems to be an area where various documentation repositories insist on ignoring or removing the previously implemented APIs (even though we still need to know how to use them if we are going to be able to implement on anything but the newest phones).
The two major flavors of the API that I have found are the one that's currently documented (you refer to that API above) and one that was documented in a version of the WebRTC specification from October 2013. That flavor has a significantly different constraints specification that includes mandatory and optional properties. Your call above to getMedia would look like this under the older specification:
var constraints = {
video: {
mandatory: {
facingMode: 'environment'
}
}
}
getMedia(constraints);
Alternately, you can use optional settings, which are provided as an array instead so you can have multiple choices (these are evaluated in order):
var constraints = {
video: {
optional: [{
facingMode: 'environment'
}]
}
}
getMedia(constraints);
That having been said, your mileage may vary when it comes to finding filters that work. For example, the facingMode filter above does not function in my Android 5.0 emulator (it doesn't throw an error but it also doesn't present the environment-facing camera); however, using a device ID does work (which looks like this when mapped to your example):
var constraints = {
video: {
mandatory: {
sourceId: '<your source ID here>'
}
}
}
getMedia(constraints);
In the case of the Android 5.0 emulated device that I have done some testing with I am able to use MediaStreamTrack.getSources() to find the device I want (it returns the facing property with each camera). Note that the "recommended" replacement method navigator.mediaDevices.enumerateDevices() method is not present in this emulated device.
There are numerous other issues that you will see when using different emulated and physical devices, each of which has been quite problematic for me when implementing these APIs in the real world. I highly recommend using a combination of multiple physical devices (if you are in a work environment where you can get access to them), BrowserStack (to give you lots of real and emulated devices to test on), console.log(), and Vorlon.js (to view the console.log() output in real-time from all those emulated devices so you can see what's really going on).
I am currently working on this exact problem right now - if I find anything additional with respect to different API flavors that need supporting I will post an update here.
If you look at the Browser Compatibility section of the MDN page you linked to you'll see:
Chrome uses an outdated constraint syntax, but the syntax described here is available through the adapter.js polyfill.
You'll be happy to know that adapter.js now supports the facingMode constraint on Chrome for Android (use https fiddle for Chrome):
var gum = mode =>
navigator.mediaDevices.getUserMedia({video: {facingMode: {exact: mode}}})
.then(stream => (video.srcObject = stream))
.catch(e => log(e));
var stop = () => video.srcObject && video.srcObject.getTracks().map(t => t.stop());
var log = msg => div.innerHTML += msg + "<br>";
<button onclick="stop();gum('user')">Front</button>
<button onclick="stop();gum('environment')">Back</button>
<div id="div"></div><br>
<video id="video" height="320" autoplay></video>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
The { exact: } syntax means the constraint is required, and things fail if the user doesn't have the right camera. If you leave it out then the constraint is optional (though Firefox for Android will let users override the choice in the camera chooser in the permission prompt in that case).
adapter.js also supports navigator.mediaDevices.enumerateDevices(), which has replaced MediaStreamTrack.getSources.
I've really enjoyed experimenting with Meteor recently and so far i've found it to be a really neat little app. I've decided to migrate an old application over to meteor and have already made some good progress. The application is a live score updates application. While i've been able to demonstrate the concept i've found 2 issues which may prevent me from using it.
1) Data previously existed in a mySQL database so i've written a script to export the data into .js files. For those that might want to do similar, the main part of the PHP code is here.
$handle = fopen($output_file, "w");
foreach ( $tables as $key => $table ) {
$query = "SELECT * FROM $table_prefix$table";
$res = mysql_query($query);
while ( $row = mysql_fetch_assoc($res) ) {
$newTableName = "";
$parts = explode("_", $table);
foreach ( $parts as $k => $v ) {
$newTableName .= ucfirst($v);
}
$string = $newTableName.".insert({";
$first = true;
foreach ( $row as $columnName => $value ) {
if ( !$first ) { $string .= ", "; }
$string .= "$columnName : \"$value\"";
$first = false;
}
$string .= " });";
print $string . "<br>";
}
}
While this has worked for most of the tables, i have one table in particular which contains all the event information. This separate .js file contains 3600 lines of insert statements and it would seem that when this is in the application, the application breaks. If i rename the file to be 'event.js.save' for example, then the application is fine. More specifically, with this .js file in place, when i deploy the application i get..
mac:app user$ meteor deploy <domain>.meteor.com
Deploying to <domain>.meteor.com. Bundling ...
Errors prevented deploying:
Exception while bundling application:
RangeError: Maximum call stack size exceeded
So, Question number 1 is - how much has been done to test the scalability of this appliction?
2) The second issue i have is regarding mobile performance. I've spent a long time getting a stylesheet looking good on all platforms and have been really disappointed to see how quickly the battery on a mobile goes down.
When i load a page in Safari the 'progress' animation in the top right is constantly spinning and from what i've seen 5% of battery goes in probably 10 minutes.
Question number 2 - how is the connection kept alive for browsers? Is there anything that can be done to reduce the impact on mobile browsers?
Thanks.
1:
Applications are very scalable in the case that the meteor site managed the launch just fine with a massive amount of traffic all in one day when they had not planned for it.
The reason for your error is that you can't call that many statements that are the same in a row as far as I'm aware as js thinks it is crashing. I think there are ways to change this however or get round it.
As far as testing they have done I'm unsure, personally I would import the data by itterating through the data and inserting it rather than having it as that many calls (I think that is the issue).
2:
That is a bug that it is spinning however it is constantly checking over ajax or similar methods.
In future sockets will be used which I expect will be more efficient.
Perhaps there will be a way to tune down the number of queries and network intensive it is in the future.
Providing an updated source code to the issue above :
As discussed in one of the answers, the problem seemed to be the number of insert lines and that it was Javascript breaking not Meteor. I've since updated the code and thought others might be interested to.
The following PHP provides JSON output for a table...
// we connect to example.com and port 3307
$link = mysql_connect('localhost', 'username', 'password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
$db = mysql_select_db("databasename");
$tables = array (
$_REQUEST["table"]
);
$table_prefix = "tableprefix_";
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
foreach ( $tables as $key => $table ) {
$query = "SELECT * FROM $table_prefix$table";
$res = mysql_query($query);
$first = true;
print "[";
while ( $row = mysql_fetch_assoc($res) ) {
if ( !$first ) { print ", "; }
$first = false;
print ( json_encode($row) . "\n");
}
print "]";
}
mysql_close($link);
I can then use the following in the javascript to load the data.
Events = new Meteor.Collection("event");
if (Meteor.is_server) {
Meteor.startup(function () {
if (Events.find().count() === 0) {
$.getJSON('/ajax/event.json', function(data) {
$.each(data, function(key, val) {
Events.insert(val);
});
});
}
});
}
jonathanKingston said,
1: Applications are very scalable in the case that the meteor site
managed the launch just fine with a massive amount of traffic all in
one day when they had not planned for it.
Which is hilarious, because the home page for Meteor is not a Meteor app, and they had to take all Meteor demo apps off-line due to security / scalability reasons.
Looking forward to the next generation of FUD being spread by stupid programmers conned by pretty demos and Hacker News posts.