Git Product home page Git Product logo

proximity's People

Contributors

fluxaugur avatar revned avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proximity's Issues

Change device does nothing

Hi there, would love to checkout how proximity works, however, I cannot seem to select a blue-tooth device. In the bluetooth section of the preferences I have a message "A bluetooth-enabled device has not be selected". Clicking "Change Device" does not do anything.

Am I missing something? My Galaxy S5 is connected to my mac and works with other bluetooth proximity software.

Thanks much for any help!

My mac:
Model Name: iMac
Model Identifier: iMac14,2
Processor Name: Intel Core i5
Processor Speed: 3.2 GHz
Number of Processors: 1
Total Number of Cores: 4
L2 Cache (per Core): 256 KB
L3 Cache: 6 MB
Memory: 16 GB
Boot ROM Version: IM142.0118.B07
SMC Version (system): 2.15f7

Signal strength slider

I would suggest that you implemented a way to control when scripts trickered based on the strength of the bluetooth connection. This would be greatly appreciated.

Only compiled .scpt scripts are supported

The UI presents editable text fields that point to script file names. Users can enter .applescript files, .sh files, or other scripts. However, Proximity only runs compiled .scpt files: all others are silently ignored.

Please amend the UI to prevent such confusion.

  • Disable editing of the script file name text fields. This way, users cannot type invalid file names.
  • Label the file name fields with an explicit requirement that all scripts be .scpt files.

Finally, consider adding support for other script types, and adding the file extensions to the Finder script selector.

  • .applescript
  • .app
  • .sh
  • .zsh
  • .py
  • .pl
  • .rb
  • arbitrary script files

Flesh out a basic README

Please include a README.md file that describes Proximity's purpose, and links to download the app.

Not Working On Lion

I am running Lion DP4 and just downloaded Proximity.

The application will open, however, if I try and open up Preferences.... nothing happens.

Make Proximity 'try again' a couple of times before deciding the device is out of range.

Sometimes BT devices need some time to wake up and will not respond to the
fist query. I had to patch Proximity (even previous versions) like below to
make out of range detection more reliable.

Index: reduxcomputing-proximity-read-only/AppController.m
===================================================================
--- reduxcomputing-proximity-read-only/AppController.m  (revision 22)
+++ reduxcomputing-proximity-read-only/AppController.m  (working copy)
@@ -1,6 +1,6 @@
 #import "AppController.h"
+#include 
 
-
 @implementation AppController
 
 
@@ -91,9 +91,12 @@
 
 - (BOOL)isInRange
 {
-   if( device && [device remoteNameRequest:nil] == kIOReturnSuccess )
-       return true;
-   
+   int repeat_count = 3;
+   do {
+       if( device && [device remoteNameRequest:nil] == kIOReturnSuccess )
+           return true;
+       usleep(500000L);
+   } while(--repeat_count);
    return false;
 }

Status bar hangs

Hey guys,

I've been trying to make this work under Mountain Lion. All seems OK expect one problem. Basically when you click the statusbar icon, the program hangs there for 4-5 seconds. I've identified the culprit but can't seem to find a valid replacement :

in userdefaultsload function :

device = [NSKeyedUnarchiver unarchiveObjectWithData:deviceAsData];

Also, I've modified the script a bit the work better with 10.8 :

  • replace [device getName] by [device name] on line 187 and 309 (deprecated)
  • replace [device getAddressString] by [device addressString] on line 187 and 310 (deprecated)
  • modified target build settings to work os 64 bits and 10.8
  • remove "retain" references (no need to do this with ARC)
  • added [NSApp activateIgnoringOtherApps:YES]; to showWindow so that prefs windows is always on top

Thanks a lot for your help

Cheers

Here's the full AppController.m

#import "AppController.h"


@implementation AppController


#pragma mark -
#pragma mark Delegate Methods

- (void)applicationWillTerminate:(NSNotification *)aNotification
{
    [self stopMonitoring];
}

- (void)awakeFromNib
{
    NSBundle *bundle = [NSBundle mainBundle];
    inRangeImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"inRange" ofType: @"png"]];
    inRangeAltImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"inRangeAlt" ofType: @"png"]]; 
    outOfRangeImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"outRange" ofType: @"png"]];
    outOfRangeAltImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"outOfRange" ofType: @"png"]];  

    priorStatus = OutOfRange;

    [self createMenuBar];
    [self userDefaultsLoad];
}

- (void)windowWillClose:(NSNotification *)aNotification
{
    [self userDefaultsSave];
    [self stopMonitoring];
    [self startMonitoring];
}


#pragma mark -
#pragma mark AppController Methods

- (void)createMenuBar
{
    NSMenu *myMenu;
    NSMenuItem *menuItem;

    // Menu for status bar item
    myMenu = [[NSMenu alloc] init];

    // Prefences menu item
    menuItem = [myMenu addItemWithTitle:@"Preferences" action:@selector(showWindow:) keyEquivalent:@""];
    [menuItem setTarget:self];

    // Quit menu item
    [myMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];

    // Space on status bar
    statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];

    // Attributes of space on status bar
    [statusItem setHighlightMode:YES];
    [statusItem setMenu:myMenu];

    [self menuIconOutOfRange];  
}

- (void)handleTimer:(NSTimer *)theTimer
{
    if( [self isInRange] )
    {
        if( priorStatus == OutOfRange )
        {
            priorStatus = InRange;

            [self menuIconInRange];
            [self runInRangeScript];
        }
    }
    else
    {
        if( priorStatus == InRange )
        {
            priorStatus = OutOfRange;

            [self menuIconOutOfRange];
            [self runOutOfRangeScript];
        }
    }

    [self startMonitoring];
}

- (BOOL)isInRange
{
    if( device && [device remoteNameRequest:nil] == kIOReturnSuccess )
        return true;

    return false;
}

- (void)menuIconInRange
{   
    [statusItem setImage:inRangeImage];
    [statusItem setAlternateImage:inRangeAltImage];

    //[statusItem   setTitle:@"O"];
}

- (void)menuIconOutOfRange
{
    [statusItem setImage:outOfRangeImage];
    [statusItem setAlternateImage:outOfRangeAltImage];

//  [statusItem setTitle:@"X"];
}

- (BOOL)newVersionAvailable
{
    NSURL *url = [NSURL URLWithString:@"http://reduxcomputing.com/download/Proximity.plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfURL:url];
    NSArray *version = [[dict valueForKey:@"version"] componentsSeparatedByString:@"."];

    int newVersionMajor = [[version objectAtIndex:0] intValue];
    int newVersionMinor = [[version objectAtIndex:1] intValue];

    if( thisVersionMajor < newVersionMajor || thisVersionMinor < newVersionMinor )
        return YES;

    return NO;
}

- (void)runInRangeScript
{
    NSAppleScript *script;
    NSDictionary *errDict;
    NSAppleEventDescriptor *ae;

    script = [[NSAppleScript alloc]
              initWithContentsOfURL:[NSURL fileURLWithPath:[inRangeScriptPath stringValue]]
              error:&errDict];
    ae = [script executeAndReturnError:&errDict];       
}

- (void)runOutOfRangeScript
{
    NSAppleScript *script;
    NSDictionary *errDict;
    NSAppleEventDescriptor *ae;

    script = [[NSAppleScript alloc]
              initWithContentsOfURL:[NSURL fileURLWithPath:[outOfRangeScriptPath stringValue]] 
              error:&errDict];
    ae = [script executeAndReturnError:&errDict];   
}

- (void)startMonitoring
{
    if( [monitoringEnabled state] == NSOnState )
    {
        timer = [NSTimer scheduledTimerWithTimeInterval:[timerInterval intValue]
                                                 target:self
                                               selector:@selector(handleTimer:)
                                               userInfo:nil
                                                repeats:NO];
    }       
}

- (void)stopMonitoring
{
    [timer invalidate];
}

- (void)userDefaultsLoad
{
    NSUserDefaults *defaults;
    NSData *deviceAsData;

    defaults = [NSUserDefaults standardUserDefaults];

    // Device
    deviceAsData = [defaults objectForKey:@"device"];
    if( [deviceAsData length] > 0 )
    {
        device = [NSKeyedUnarchiver unarchiveObjectWithData:deviceAsData];
        [deviceName setStringValue:[NSString stringWithFormat:@"%@ (%@)",
                                    [device name], [device addressString]]];

        if( [self isInRange] )
        {           
            priorStatus = InRange;
            [self menuIconInRange];
        }
        else
        {
            priorStatus = OutOfRange;
            [self menuIconOutOfRange];
        }
    }

    //Timer interval
    if( [[defaults stringForKey:@"timerInterval"] length] > 0 )
        [timerInterval setStringValue:[defaults stringForKey:@"timerInterval"]];

    // Out of range script path
    if( [[defaults stringForKey:@"outOfRangeScriptPath"] length] > 0 )
        [outOfRangeScriptPath setStringValue:[defaults stringForKey:@"outOfRangeScriptPath"]];

    // In range script path
    if( [[defaults stringForKey:@"inRangeScriptPath"] length] > 0 )
        [inRangeScriptPath setStringValue:[defaults stringForKey:@"inRangeScriptPath"]];

    // Check for updates on startup
    BOOL updating = [defaults boolForKey:@"updating"];
    if( updating ) {
        [checkUpdatesOnStartup setState:NSOnState];
        if( [self newVersionAvailable] )
        {
            if( NSRunAlertPanel( @"Proximity", @"A new version of Proximity is available for download.",
                                @"Close", @"Download", nil, nil ) == NSAlertAlternateReturn )
            {
                [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://reduxcomputing.com/proximity/"]];
            }
        }
    }

    // Monitoring enabled
    BOOL monitoring = [defaults boolForKey:@"enabled"];
    if( monitoring ) {
        [monitoringEnabled setState:NSOnState];
        [self startMonitoring];
    }

    // Run scripts on startup
    BOOL startup = [defaults boolForKey:@"executeOnStartup"];
    if( startup )
    {
        [runScriptsOnStartup setState:NSOnState];

        if( monitoring )
        {
            if( [self isInRange] ) {
                [self runInRangeScript];
            } else {
                [self runOutOfRangeScript];
            }
        }
    }

}

- (void)userDefaultsSave
{
    NSUserDefaults *defaults;
    NSData *deviceAsData;

    defaults = [NSUserDefaults standardUserDefaults];

    // Monitoring enabled
    BOOL monitoring = ( [monitoringEnabled state] == NSOnState ? TRUE : FALSE );
    [defaults setBool:monitoring forKey:@"enabled"];

    // Update checking
    BOOL updating = ( [checkUpdatesOnStartup state] == NSOnState ? TRUE : FALSE );
    [defaults setBool:updating forKey:@"updating"];

    // Execute scripts on startup
    BOOL startup = ( [runScriptsOnStartup state] == NSOnState ? TRUE : FALSE );
    [defaults setBool:startup forKey:@"executeOnStartup"];

    // Timer interval
    [defaults setObject:[timerInterval stringValue] forKey:@"timerInterval"];

    // In range script
    [defaults setObject:[inRangeScriptPath stringValue] forKey:@"inRangeScriptPath"];

    // Out of range script
    [defaults setObject:[outOfRangeScriptPath stringValue] forKey:@"outOfRangeScriptPath"];

    // Device
    if( device ) {
        deviceAsData = [NSKeyedArchiver archivedDataWithRootObject:device];
        [defaults setObject:deviceAsData forKey:@"device"];
    }

    [defaults synchronize];
}


#pragma mark -
#pragma mark Interface Methods

- (IBAction)changeDevice:(id)sender
{
    IOBluetoothDeviceSelectorController *deviceSelector;
    deviceSelector = [IOBluetoothDeviceSelectorController deviceSelector];
    [deviceSelector runModal];

    NSArray *results;
    results = [deviceSelector getResults];

    if( !results )
        return;

    device = [results objectAtIndex:0];

    [deviceName setStringValue:[NSString stringWithFormat:@"%@ (%@)",
                                [device name],
                                [device addressString]]];    
}

- (IBAction)checkConnectivity:(id)sender
{
    [progressIndicator startAnimation:nil];

    if( [self isInRange] )
    {
        [progressIndicator stopAnimation:nil];
        NSRunAlertPanel( @"Found", @"Device is powered on and in range", nil, nil, nil, nil );
    }
    else
    {
        [progressIndicator stopAnimation:nil];
        NSRunAlertPanel( @"Not Found", @"Device is powered off or out of range", nil, nil, nil, nil );
    }
}

- (IBAction)checkForUpdates:(id)sender
{
    if( [self newVersionAvailable] )
    {
        if( NSRunAlertPanel( @"Proximity", @"A new version of Proximity is available for download.",
                            @"Close", @"Download", nil, nil ) == NSAlertAlternateReturn )
        {
            [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://reduxcomputing.com/proximity/"]];
        }
    }
    else
    {
        NSRunAlertPanel( @"Proximity", @"You have the latest version.", @"Close", nil, nil, nil );
    }
}

- (IBAction)donate:(id)sender
{
    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://reduxcomputing.com/donate.php"]];
}

- (IBAction)enableMonitoring:(id)sender
{
    // See windowWillClose: method
}

- (IBAction)inRangeScriptChange:(id)sender
{
    NSOpenPanel *op = [NSOpenPanel openPanel];
    [op runModalForDirectory:@"~" file:nil types:[NSArray arrayWithObject:@"scpt"]];

    NSArray *filenames = [op filenames];
    [inRangeScriptPath setStringValue:[filenames objectAtIndex:0]]; 
}

- (IBAction)inRangeScriptClear:(id)sender
{
    [inRangeScriptPath setStringValue:@""];
}

- (IBAction)inRangeScriptTest:(id)sender
{
    [self runInRangeScript];
}

- (IBAction)outOfRangeScriptChange:(id)sender
{
    NSOpenPanel *op = [NSOpenPanel openPanel];
    [op runModalForDirectory:@"~" file:nil types:[NSArray arrayWithObject:@"scpt"]];

    NSArray *filenames = [op filenames];
    [outOfRangeScriptPath setStringValue:[filenames objectAtIndex:0]];    
}

- (IBAction)outOfRangeScriptClear:(id)sender
{
    [outOfRangeScriptPath setStringValue:@""];
}

- (IBAction)outOfRangeScriptTest:(id)sender
{
    [self runOutOfRangeScript];
}

- (void)showWindow:(id)sender
{
    [NSApp activateIgnoringOtherApps:YES];
    [prefsWindow makeKeyAndOrderFront:self];
    [prefsWindow center];

    [self stopMonitoring];
}


@end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.