Compdigitec Labs

Phabricator LDAP (and other) account integration table

By admin | January 17, 2016

phabricator_user.user_externalaccount

See also https://secure.phabricator.com/T4279

For LDAP, the following structure is used:

Topics: PHP | 1 Comment »

Possible crash in method_exists() with PHP 5.3

By admin | August 9, 2014

Apparently in some versions of PHP 5.3, calling method_exists() on a class which doesn’t exist seems to cause a crash. The solution, seen here, apparently involves checking class_exists() to prevent a potentially crashing call to method_exists().

This particular bug was causing the administration page of the MathJax-LaTeX WordPress plugin to be blank in the admin interface.

The trick is to replace the two lines in mathjax-latex-admin.php lines 91-92:

$wp_latex_disabled = method_exists('WP_LaTeX','init') ? "disabled='true'" : "";
$wp_latex_disabled_warning = method_exists('WP_LaTeX','init') ? "Disable wp-latex to use this syntax." : "";

with:

$wp_latex_disabled = (class_exists('WP_LaTeX', false) && method_exists('WP_LaTeX','init')) ? "disabled='true'" : "";
$wp_latex_disabled_warning = (class_exists('WP_LaTeX', false) && method_exists('WP_LaTeX','init')) ? "Disable wp-latex to use this syntax." : "";

Topics: PHP | No Comments »

Disable dragging of an element in JSXGraph

By admin | July 20, 2014

Set the attribute ‘fixed‘ to true in JXG.GeometryElement:

var line = board.create('line', [ [0,0], [1,1] ], {dash:0, strokeColor:"#FF0000", strokeWidth:3, fixed: true});

or

var line = board.create('line', [ [0,0], [1,1] ], {dash:0, strokeColor:"#FF0000", strokeWidth:3});
line.setAttribute({ fixed: true });
board.update();

Topics: (X)HTML, Windows | 1 Comment »

Reverse engineering the Fischertechnik blinker

By admin | July 13, 2014

The Fischertechnik blinker comes in a enclosed case with no other sensory inputs with two wires, a yellow wire and a blue wire.

The Fischertechnik blinker

The Fischertechnik blinker

As such, I reverse engineered the Fischertechnik blinker to understand how it works through desoldering, a camera, and a lot of drawing on the GIMP.

It turns out that the blinker is intended to be used like a switch in a series circuit before a load, with the yellow lead being the positive end and the blue lead being the negative end.

Series circuit with FT blinker on mySTEM board

Series circuit with FT blinker on mySTEM board

The main idea here is that the board uses a 555 timer (555C EZ606 with STMicroelectronics logo, surface-mounted) with fixed frequency (fixed R1, R2 and C) in astable mode to control a BSP 75N MOSFET transistor.

The power supply for the ICs is controlled in parallel with a diode and a 470Ω resistor to protect the ICs, while the MOSFET controls the connection to the other lead.

It features an unknown-model fuse (VW UG4 GP613) on the emitter of the transistor, presumably to protect the circuit from excess.

A diode and 100 µF capacitor cap are present, possibly to smooth out the power input for the ICs during temporary dislocations. Considering that it is a Fischertechnik component, its purpose is probably to ensure continued reliability when it is handled roughly, shaken, and dropped by students.

After complete disassembly:

Fischertechnik blinker, disassembled

Fischertechnik blinker, disassembled

With traces and PCB features:

Front view, with traces and PCB features

Front view, with traces and PCB features

Back view, with traces and PCB features

Back view, with traces and PCB features

Schematic:

Fischertechnik blinker schematic

Fischertechnik blinker schematic

Since C is a generic-looking ceramic capacitor with no markings, its capacitance was estimated by using the period.

The light was measured to blink 100 times in 41.21 seconds, giving:
$$
T = 0.4121 \text{s} \\
f = 2.426 \text{s}^{-1}
$$

Given R1 = 1 MΩ and R2 = 1.2 MΩ from above and f = 2.426, we can calculate C using the following equation:
$$
f = \dfrac{1}{\ln 2 * C * (R_1 + 2*R_2)}
$$

C then works out to about 0.175 µF.

Topics: Electronics | 1 Comment »

Reverse proxy with HTML rewriting using Apache

By admin | May 25, 2014

<VirtualHost *:80>
 ServerName foo.example.com

 ... other directives ...

 ProxyHTMLEnable On (comment in some cases)
 SetOutputFilter proxy-html
 SetOutputFilter inflate;proxy-html;deflate  (for compression issues - e.g. The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression)

 ProxyHTMLURLMap http://192.168.12.34/myfolders/ /
 ProxyHTMLURLMap /myfolders /
</VirtualHost>

Topics: Linux | 1 Comment »

How to get the classic Firefox look back

By admin | November 20, 2013

Firefox, restored to a classic look

Firefox, restored to a classic look

While all the latest dynamic changes (such as the new Australis UX) may be interesting, you may be looking to get that classic Firefox look back for productivity reasons. Here is a list of recommended addons to restore your Firefox back to something to do work with:

Topics: Internet | No Comments »

Fixing IllegalStateException: The content of the adapter has changed but ListView did not receive a notification

By admin | November 16, 2013

Recently while working with a custom BaseAdapter in ListView, I came across this error:

E/InputEventReceiver(30380): Exception dispatching input event.
E/MessageQueue-JNI(30380): Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI(30380): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131230721, class android.widget.ListView) with Adapter(class com.compdigitec.libvlcandroidsample.DirectoryAdapter)]
E/MessageQueue-JNI(30380): 	at android.widget.ListView.layoutChildren(ListView.java:1544)
E/MessageQueue-JNI(30380): 	at android.widget.AbsListView.onTouchEvent(AbsListView.java:3403)
E/MessageQueue-JNI(30380): 	at android.view.View.dispatchTouchEvent(View.java:7239)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
E/MessageQueue-JNI(30380): 	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
E/MessageQueue-JNI(30380): 	at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
E/MessageQueue-JNI(30380): 	at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
E/MessageQueue-JNI(30380): 	at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
E/MessageQueue-JNI(30380): 	at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
E/MessageQueue-JNI(30380): 	at android.view.View.dispatchPointerEvent(View.java:7419)
E/MessageQueue-JNI(30380): 	at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
E/MessageQueue-JNI(30380): 	at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
E/MessageQueue-JNI(30380): 	at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
E/MessageQueue-JNI(30380): 	at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
E/MessageQueue-JNI(30380): 	at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
E/MessageQueue-JNI(30380): 	at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
E/MessageQueue-JNI(30380): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/MessageQueue-JNI(30380): 	at android.os.MessageQueue.next(MessageQueue.java:125)
E/MessageQueue-JNI(30380): 	at android.os.Looper.loop(Looper.java:124)
E/MessageQueue-JNI(30380): 	at android.app.ActivityThread.main(ActivityThread.java:5191)
E/MessageQueue-JNI(30380): 	at java.lang.reflect.Method.invokeNative(Native Method)
E/MessageQueue-JNI(30380): 	at java.lang.reflect.Method.invoke(Method.java:511)
E/MessageQueue-JNI(30380): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
E/MessageQueue-JNI(30380): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
E/MessageQueue-JNI(30380): 	at dalvik.system.NativeStart.main(Native Method)

this.notifyDataSetChanged() was already being called, so that couldn’t have been the problem.

The solution?
If registerDataSetObserver() and unregisterDataSetObserver() are going to be overridden, ensure that the superclass’ methods are being called too. If you forget to call them, then when Android registers the ListView dataset observer, nothing is going to happen.

    @Override
    public void registerDataSetObserver(DataSetObserver arg0) {
        // ...stuff
        super.registerDataSetObserver(arg0);
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver arg0) {
        // ...stuff
        super.unregisterDataSetObserver(arg0);
    }

Topics: Mobile | No Comments »

Importing upstream tarballs in Debian with gbp import-orig

By admin | October 6, 2013

gbp import-orig --pristine-tar --upstream-branch=upstream ../programname-0.9.9.tar.xz

To build it:

gbp buildpackage --git-ignore-new --git-export-dir=../build-area/ --git-no-purge

Topics: Linux | 1 Comment »

Apache Active Directory authentication

By admin | September 15, 2013

Add this to /etc/ldap/ldap.conf:

REFERRALS off

Then add this to a block:

 AuthLDAPBindDN "ApacheUser@example.com"
 AuthLDAPBindPassword "the password used for apache lookups"
 AuthLDAPURL "ldap://192.168.88.2:389/dc=example,dc=com?sAMAccountName?sub?(objectClass=user)" NONE

 AuthzLDAPAuthoritative off
 AuthBasicProvider ldap
 AuthType Basic
 AuthName "Please enter your computer logon (Active Directory) to enter."
 # Important, otherwise you get "(9)Bad file descriptor: Could not open password file: (null)"
 AuthUserFile /dev/null
 Require ldap-group cn=Users
 Require valid-user

Topics: Linux | 2 Comments »

Reverse proxy HTTPS with Apache

By admin | August 23, 2013

The procedure is mostly similar to the procedure with regular HTTP, but there are a few gimmicks involved here:

  1. Generate a self-signed one or purchase a SSL certificate (*.crt) for the server in question.
  2. Make sure you run ‘sudo a2enmod ssl‘ to enable SSL.
  3. Make sure you have enable the proxy module with ‘sudo a2enmod proxy‘ as well.

Below is a sample reverse HTTPS proxy configuration.

<VirtualHost *:443>
    <Proxy *>
     Order Deny,Allow
     Allow from all
    </Proxy>

 SSLEngine On
 SSLProxyEngine On
 SSLCertificateFile /etc/apache2/cert/server.crt <!-- path to your certifcate and key -->
 SSLCertificateKeyFile /etc/apache2/cert/server.key
 SSLProxyCheckPeerCN off
 SSLProxyCheckPeerExpire off
 SSLProxyCheckPeerName off

 ProxyRequests Off
 ProxyPass / https://192.168.42.3/
 ProxyPassReverse / https://192.168.42.3/
 ProxyPreserveHost On
</VirtualHost>

Replace 192.168.42.3 with the internal IP address of your server, as before (keep the http(s):// portion).

Topics: Linux | No Comments »

If you found this article helpful or interesting, please help Compdigitec spread the word. Don’t forget to subscribe to Compdigitec Labs for more useful and interesting articles! « Older Entries Newer Entries »