Saturday, December 13, 2014

Play C64 SID files under Linux

VLC didn't work, neither did totem, and couldn't get sidplay to work.

Install audacity
then install the "exotic" plugins package, namely audacious-plugins-exotic

There you go. You can load and play your sid files from within audacity.


Thursday, December 4, 2014

ASP.Net OData V4 with inherited key: A primitive value was specified; however, a value of the non-primitive type '' was expected

At the time of writing this, there is absolutely no help on the net on this error I keep on getting. By trial and error, I've been able not to explain the message, but at least find the cause.

In my case, I have two classes:

class BaseClass
{
  public int ID {get; set;}
}
class DerivedClass : BaseClass {  public string A { get; set; }
}

And in the modelBuilder configuration (which may not be necessary here but in my case, the builder would treat some other property as the primary key instead of this one and caused other cryptic errors):

builder.EntitySet<DerivedClass>("DerivedClasses").EntityType.HasKey(c => c.ID);

Now in my DerivesClassesController ODataController, if I try to access the derived class like so:

http://someaddress/api/DerivedClasses

I get this OData V4 formatted error (in french) :
{ "error":{ "code":"","message":"An error has occurred.","innererror":{ "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{ "message":"Une valeur primitive a \u00e9t\u00e9 sp\u00e9cifi\u00e9e alors qu'une valeur de type non primitif '' \u00e9tait attendue.","type":"Microsoft.OData.Core.ODataException","stacktrace":" \u00e0 Microsoft.OData.Core.ValidationUtils.ValidateIsExpectedPrimitiveType(Object value, IEdmPrimitiveTypeReference valuePrimitiveTypeReference, IEdmTypeReference expectedTypeReference, Boolean bypassValidation)\r\n \u00e0 .............................
(Here I used to suggest defining a "new int ID" in the DerivedClass which worked but was kind of dirty and defeated the whole base class purpose. Here's a better way:)

The trick is to map the base class' ID property:

builder.EntityType<BaseClass>().HasKey(c => c.ID);

And do not remap the key on each derived class or you'll end up with a cryptic "The sequence contains more than one element" error.

The problem with this, however, is that the builder will try to map every entity that is inherited from the base class which you might or might not want. As of this writing, there is no way of preventing this automatic discovery.

So another trick is to explicitly ignore all derived types and only after that, remap wanted entities. Doing this by hand would be problematic wouldn't it. So here's a nice reflective loop that'll do the ignore part in a couple of lines. Place this just after the base class key definition so you end up with:

builder.EntitySet<DerivedClass>("DerivedClasses").EntityType.HasKey(c => c.ID);

var types = AppDomain.CurrentDomain.GetAssemblies()
 .SelectMany(a => a.GetTypes())
 .Where(t => t.IsSubclassOf(typeof(AbstractModel)));

foreach (var type in types)
 builder.Ignore(types.ToArray());

Then proceed on the derived types mappings as usual.

Wednesday, December 3, 2014

ASP.Net: OData V4 Controller giving 406

What an obscure one...

If you have a seemingly complete controller and opening this url:

http://yoursite/api/Products

returns actual OData v4 results BUT this:

http://yoursite/api/Products(1)

returns a 404 error with:

No type was found that matches the controller named 'Products(1)'

then make sure your "using"s are adequate in your controller:

using System.Web.OData; <-- this should be used

vs

using System.Web.Http.OData;

By default, the WebAPI 2 ODataController template generates a class with the latter, and it gave me trouble.

Friday, November 28, 2014

ASP.Net: Web API 2 + Help Pages + OData

Doing each of them separately is fairly easy and there's lots of tutorials on how to do it. But as for mixing them together, I've not seen much. Some blogs claim it's not possible and buggy and mostly lead to 404 and 406 errors. Well, out of luck, I made it work. The secret is in the ROUTING!

I don't understand all the concepts behind this and I believe most of us don't, and don't care to. Still, feel free to explain the unexplained in the comments.

So, I started with a ASP.Net Application project. I Selected Web API for the template so I could have the help pages ready. Then I added the needed stuff for OData V4 following this really nice tutorial. Last, I had to configure the ROUTES, and that is where all hell resides (well, that's what all the blog posts and obscure SO questions lead me to think). THe following has been taken from my SO answer.

The order in which the routes are configured has an impact. In my case, I also have some standard MVC controllers and help pages.

Global.asax:
protected void Application_Start()
{
 AreaRegistration.RegisterAllAreas();
 GlobalConfiguration.Configure(config =>
 {
  ODataConfig.Register(config); //this has to be before WebApi
  WebApiConfig.Register(config);
 });
 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 RouteConfig.RegisterRoutes(RouteTable.Routes);
}

The filter and routeTable parts weren't there when I started my project and are needed.

ODataConfig.cs:
public static void Register(HttpConfiguration config)
{
  config.MapHttpAttributeRoutes(); //This has to be called before the following OData mapping, so also before WebApi mapping
    
  ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    
  builder.EntitySet("Sites");
  //Moar!
    
  config.MapODataServiceRoute("ODataRoute", "api", builder.GetEdmModel());
}

WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
  config.Routes.MapHttpRoute( //MapHTTPRoute for controllers inheriting ApiController
     name: "DefaultApi",
     routeTemplate: "api/{controller}/{id}",
     defaults: new { id = RouteParameter.Optional }
  );
}

RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
  routes.MapRoute( //MapRoute for controllers inheriting from standard Controller
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  );
}

This has to be in that EXACT ORDER. I tried moving the calls around and ended up with either MVC, Api or Odata broken with 404 or 406 errors.

So I can call:

localhost:xxx/ -> leads to help pages (home controller, index page)

localhost:xxx/api/ -> leads to the OData $metadata

localhost:xxx/api/Sites -> leads to the Get method of my SitesController inheriting from ODataController

localhost:xxx/api/Test -> leads to the Get method of my TestController inheriting from ApiController.

Saturday, November 22, 2014

Linux: Slow wifi with Intel and iwl3945

I have this lovely Thinkpad T60 on which I replaced the Atheros Wifi card for an Intel one a few years ago. I'm using Fedora 20 on it and noticed the wifi connection, although negociated to 54Mbps wouldn't get any better actual speed than 1 Mbps. I was on the edge of getting an Atheros back but here's what I did to fix the problem:

As root, add a new file:
/etc/modprobe.d/iwl3945.conf
With content:
options iwl3945 disable_hw_scan=0
then:
modprobe -r iwl3945 
modprobe iwl3945
No need to restart, the changes were instantaneous.

I don't know if it also helped, but prior to that I had removed NetworkManager and installed wicd instead. Look around on how to do this if the above solution alone didn't work. One thing though if you install wicd-gtk, I had to add my user to the "users" group and then reboot. This had nothing to do with the problem. I reinstalled NetworkManager and everything was still fine.

All thanks to this comment on ubuntu launchpad. It's from 2011 but still works.

Monday, November 17, 2014

WatchGuard: failed to open shared memory for openvpn command

I was having problem connecting to a VPN using WatchGuard Mobile VPN with SSL. Here's my log:
2014-11-17T10:16:27.568 VERSION file is 5.23, client version is 5.23
2014-11-17T10:16:27.851 failed to open shared memory for openvpn command (error: 2), please check the WatchGuard SSLVPN Service
2014-11-17T10:16:27.851 Failed to launched openvpn. retCP=0
I tried various things, and it turns out that I was using version 11.9.1. I uninstalled the client and reinstalled the version located on the firewall, which was 11.7.3 and now everything works.

Along the hair pulling and googling, the typo in the last log line made me laugh a bit.

Friday, October 31, 2014

jQuery default JSON parser for AJAX calls

By default, jQuery auto detects the response format of an AJAX request and uses a predefined list of converters to use. Here's how I set the default converter when an AJAX call returns JSON data:
$.ajaxSetup({ converters: { '* text': window.String, 'text html': true, 'text json': parseDotNetJson, 'text xml': jQuery.parseXML } }); function parseDotNetJson(data) { return JSON.parse(data, function(key, value) { if (typeof value === 'string') { var a = /\/Date\((-?\d*)\)\//.exec(value); if (a) return new Date(+a[1]); } return value; }); }
I place this code in the root of a script file. I use this to convert dates parsed to JSON by ASP.Net MVC.

More info

Thursday, October 30, 2014

DevExtreme - Get dxTextBox value the JQuery way

Fairly simple. Let's say you have this:
<div id="batch-id"></div>
Which is converted to a dxTextBox:
$('#batch-id').dxTextBox();
And you want to get the value the official way:
var x = $('#batch-id').dxTextBox('instance').option('value');
You can set the value this way:
$('#batch-id').dxTextBox('instance').option('value', 666);
You can also directly query the element using classic jQuery:
$('#batch-id input').val();

Saturday, October 25, 2014

CoCo 2 with a PC 3.5 floppy drive

Now for something a little bit more vintage. I've revived my TRS-80 Color Computer 2 and wanted to give it an ultimate go with all the stuff that's now available on the net. The CoCo community is not very large, but it's still there. So I went on and tried to get the poor old thing to communicate with the now popular DriveWire 4 through a serial cable. But that's another blog post.

I'll talk here about the 3.5 inch floppy drive. They're still kind of available and cheap so, they're good replacements for the original 5.25 drives, and more reliable too. I looked around for many hours and found much complicated stuff, but I just wanted to sink a couple of boats in Battle Stations. So I decided to write this post, should it be helpful to someone one day, who also decides to blow some dust off their CoCo 2 ;)

Hooking the drive to a CoCo

Alright so here's what you'll need, no modification, no hack, no fiddling with the circuits:
  • A CoCo 2 system with a floppy disk controller.
  • A floppy cable, straight trough, with the two kinds of connectors (one "edge connector" for the controller, and a "plug connector" for the drive) Those used to be common. You could also use a edge to plug converter and use a more nowadays-common "all-plugs" cable.
  • A 3.5 floppy drive
  • A power source to power the drive.
This part is fairly easy. You just hook the drive to the controller. And that's it. I used the two connectors that were the closest to each other. Forgive the arrangement, it's messy, but it works:

I first used a nearby PC (they're everywhere in my appartment!) to power the drive.
Start the CoCo, type in DRIVE 1, and you're all set. You can insert a floppy, DSKINI1 on it, LOAD" from and SAVE" to it. You might have to put a piece of tape on the HD hole of the floppy to make it low density.

What if I need to use Drive 0?

For technical reasons, all standard PC floppy drives are hard wired to be DRIVE 1. Some have jumpers that make this configurable:
See DS1 and DS0? DS1 is jumped. You would have to unjump DS1 and jump DS0.
But that's not all. The CoCo uses a different technique than on PC to select which drive it talks to so the ordinary twisted cable won't work:
"There are 34 wires in the ribbon cable (1-34). Each odd wire is Ground. Each even wire is a control or data line. The Drive Select 0 and Drive Select 1 wires (numbers 12 and 14) are separated by 1 ground wire (13). 
You have to carefully remove the ribbon cable from the connector, seperate those three wires (DS0, GND, DS1) from the others and twist them so that the two drive select wires switch positions, then put all 34 wires back into the connector." -- Source

Writing a CoCo DSK image to a floppy from a PC

Here's what you'll need:
  • A PC (The OS will define which software you'll use. I used Debian.)
  • Another floppy drive attached to the motherboard of the PC. USB drives can't work.
I'll only talk about how to do it using Debian. Other Linux distros should have no real problem adapting the instructons. As for Windows, you're on your own, sorry... You might just want to get yourself a nice LiveBoot distribution of Ubuntu. Go ahead, the Linux turn nowadays is a fun and friendly journey! ;)

Ensure you have your floppy drive hooked to your motherboard. Then, you'll need fdutils so in a terminal:
sudo apt-get install fdutils
As a side note, no additional configuration of the utils is needed. apt will also install mtools as a dependency which will come with the proper /etc/mediaprm file configured with the correct CoCo entries in it.

Next:
  • Put a piece of tape on the HD hole of the floppy to make it low density ;)
  • Run the following command to tell the system how to format the disk. You'll have to run this every time you put a floppy in the drive:
sudo setfdprm /dev/fd0 coco1
  • Format the disk:
sudo fdformat /dev/fd0
  • Write the image to the disk:
sudo dd if=bstations.dsk of=/dev/fd0 
  • If any of the above two commands fail to read data from the disk, you might try to reenter the fdformat command and try again. this happened to me a couple of times.
  • Put the disk in the CoCo drive and sink some boats ;)

Reading a CoCo floppy to a DSK image on a PC

Install fdutils as explained above. Next, issue the setfdprm command explained above and enter:
sudo dd if=/dev/fd0 of=myimage.dsk count=315
If the dd command fails to write to the disk, you might have to enter the setfdprm command a couple of times before the dd command works, at least each time a floppy is inserted.

Floppy power source

If you want to build a power source yourself, you only need to provide 5V. Most floppies will need around 1A. No need for 12V. Be aware that the cartridge port of the CoCo has a 5V pin, but it is rated for 300mA only, so be safe and use an external source.
I used a spare D-Link wall adapter and replaced its connector with a floppy power connector I had left.

Hook both a 3.5 floppy drive and a CoCo drive to the CoCo

This is fairly easy. You'll need to ensure your floppy cable has enough connectors, and that there is no twist in between the used connectors.

Next, proceede to a "dental extraction" on the connector that'll connect the CoCo drive. Look at your original CoCo drive cable, if you have one, and look at the DRIVE 0 connector. You'll notice some pins (3) are missing. You'll have to remove them from your connector as well. So gently (those things are fragile like crystal) open the connector, remove the cable, remove the uneeded pins, put the cable back and reassemble the connector. Here's mine:
Notice the three removed pins. This is for DRIVE 0.
This is the whole setup.
There you have it. You can now backup your old 5.25 floppies to more trustworthy 3.5's!
You'll need one 3.5 for each 5.25 side, but who cares ;)

What if my 3.5 drive is DRIVE 0?

Then you want the CoCo as DRIVE 1. The process is the same, but the removed pins will be different:
This is for DRIVE 1 on the original CoCo cable. As a side note, also notice the straighten twist on the modified cable.

Additional infos

Here's a great repository of disk images I use myself. You'll find Battle Stations somewhere in there ;)

So this is what has worked for me. I tried a lot of things and failed many times, wondering each time what was wrong. Don't give up! I'd like to thank the guys at #coco_talk on freenode, they've been a great help and very friendly!

Feel free to ask any question in the comments below!

Wednesday, September 24, 2014

VS: Automatically create a NuGet Package from project upon build

Here's a neat little approach I use to effortlessly build NuGet packages.

- Get NuGet.exe and put it in the project folder. I also add it to our source control.
- Create a new Build Target named "NuGet". (optional, see below)
- In the Post Build Events of the project you want to make a NuGet package from, enter this:
if $(ConfigurationName) == NuGet (
  "$(ProjectDir)nuget.exe" pack "$(ProjectDir)$(ProjectFileName)" -OutputDirectory "\\target\directory\NuGet Feed" -Prop Configuration=$(ConfigurationName)
)
To use it, you just select the NuGet target, and build the project. It'll build the package and put it in the OutputDirectory folder.

The new "NuGet" target is in fact optional and you could use "Release" in the Post Build Event condition.

Also, you might want to edit the project's Assembly Infos and set the Company, Name, and Description properties. Pay special attention to the Version property too. Those properties appear in the NuGet package manager.

For more information on NuGet and how to get it, check this out.
To learn how to make a NuGet feed, check this out. Especially the local one. It's as simple as making a new directory, and this is what I use.

Have fun!

UPDATE:
Here's a NuGet with more features to do just that:
https://www.nuget.org/packages/CreateNewNuGetPackageFromProjectAfterEachBuild/

Friday, August 22, 2014

Entity Framework 6 Code First: error 3023: Problem in mapping fragments starting at lines xxxx:Column has no default value and is not nullable. A column value is required to store entity data

There are many reasons why this error would happen. There's a known bug in 6.1 which will be fixed in 6.2. But my problem wasn't related to it. Here's what happened for me.

I use a single table, tbl_Person,  to map a hierarchy, like this example, where Person is abstract :

And I use this mapping using Fluent API:

modelBuilder.Entity<Person>()
 .ToTable("tbl_Person")
 .HasKey(m => m.PersonID)
 .Map<Student =>(m.Requires (discrimination stuff) )
 .Map<Instructor>(m => m.Requires (discrimination stuff) )

And then later, I added another kind of Person to my model. Let's say a "Director"  but I forgot to add the mapping. That got me the error whenever I would try to use a DbContext. So I just added the mapping for "Director" and the error went away.

By the way, a discriminator column can be NOT NULL and have no default value, as opposed to what the error lead me to think.

Coffee time!

Tuesday, August 19, 2014

Entity Framework Code First: map to updatable view with INSTEAD OF INSERT trigger

At first, I was glad we could map entities to SQL views. Just map them to a view instead of a table. But when we need to update or delete, we need an updatable view. This is doable as explained here. My view was a join of multiple tables so I had to rely on an INSTEAD OF triggers. This works fine in theory or if you do your own queries. However, Entity Framework (v6 in my case) doesn't like them very much and I get this error when I add a new entity:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

Here' why it thinks no rows were affected. Using SQL Server Profiler, I've been able to catch the following query that EF generates when I call SaveChanges() on my DbContext:

exec sp_executesql 
N'INSERT [dbo].[vw_ErpAndType]([Description], [ConnectionString], ...)
VALUES (@0, NULL, ...)
SELECT [idERP]
FROM [dbo].[vw_ErpAndType]
WHERE @@ROWCOUNT > 0 AND [idERP] = scope_identity()'
,N'@0 nvarchar(max) ,@1 bit, ...'
,@0=N'bill',@1=0 ...

See that part in bold and underlined red? This is how EF gets the key of the newly inserted row and give it back to the business object. The problem is that when there's an INSTEAD OF INSERT trigger, that scope_identity() instruction returns NULL because the trigger happens in another scope. So even if the insertion is successful, the query returns nothing and thus, EF thinks nothing happened and throws the error.

The workaround would be for EF to use @@identity instead but I don't believe we can do that.

This is as far as I went trying to use updatable views with EF. Now I'll see what can be done with mapped stored procedures for insert-delete-update.

Tuesday, July 1, 2014

Zebra EPL - Truncate text field

Zebra ZPL has this neat TB command which limits the field bounds. EPL doesn't seem to have this kind of feature. Here's how I've been able to do this. Place all the text fields in a form and use a variable with a maximum length:
V00,35,L,"" 
A600,30,1,4,6,2,N,V00 
A310,850,1,c,2,2,N,"ACCEPTED" 
?
1234567890123456789012345678901234567890
The result is:
1234567890123456789012345
ACCEPTED


Tuesday, May 20, 2014

DevExpress GridView CustomUnboundColumnData, e.Column always refers to same column

This just happened to me and the solution is very easy. I just didn't check for a solution at the right place. This will happen if your unbound columns all share the same FieldName, so make sure they are unique across the GridView.

Thursday, April 10, 2014

Devexpress WPF how to make Buttons

In case you were wondering where ordinary buttons went in devexpress for WPF, here is an example of how to make one.

First, make sure to set the dxe namespace:

xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" 

then:

<dxe:ButtonEdit Height="23" Margin="195,137,0,0" Width="75" ShowText="False" AllowDefaultButton="False">
 <dxe:ButtonInfo Content="Cancel" Click="btnBack_Click" />
</dxe:ButtonEdit>

Wednesday, April 2, 2014

Devexpress WPF Gridview: set row cell font size

Quite simple, even though I couldn't find anything on that matter. Here's a complete example, giving you can locate the automatically created TableView element in your XAML:

<dxg:TableView Name="tableView1" 
   ShowGroupPanel="False" 
   NavigationStyle="Row" >
 <dxg:TableView.CellStyle>
  <Style>
   <Setter Property="TextElement.FontSize" Value="8" />
  </Style>
 </dxg:TableView.CellStyle>
</dxg:TableView>

Friday, March 21, 2014

Installshield LE: -4340: Internal Build Error, solved (somehow)

Thanks Flexera for the complete lack of support on this error... Well, my research had me understand the following:

  • The setup build crashes at a step which should write this in the log, but doesn't:
    Searching project for extract-at-build components...
  • It's component related (ocx?).
  • In my case, I have home made components (User Controls) in my project. They may be the cause.
  • In my case, it wasn't a dependency problem.
By repeatedly cleaning and rebuilding my projects individually, the error SOMEHOW went away. I couldn't control the problem so that's all the information I have. I hope it helps.

Tuesday, February 25, 2014

Visual Paradigm: Re-register

I'm using the Community Edition. I screwed up my email address when I tried to register so I never received the activation code. Here's what their kind support team told me to do so I can register again:

Remove the VisualParadigm folder located in %userprofile%\AppData\Local 

Start Visual Paradigm again and you should see the registration form again.

Friday, February 7, 2014

DevExpress MVC: Add an enum to a ComboBox

Here is a nice extension method I did to add an enum (text and values) to a DevExpress MVC ComboBox. it might also work with other kinds of widgets.

public static void AddEnum<TEnum>(this ListEditItemCollection instance)
 where TEnum : struct
{
 foreach (TEnum tos in (TEnum[])Enum.GetValues(typeof(TEnum)))
 {
  instance.Add(Enum.GetName(typeof(TEnum), tos), Convert.ToInt32(tos));
 }
}

Then I can do this:

Html.DevExpress().ComboBoxFor(model => model.OrderStatus,
 cbSettings =>
 {
  cbSettings.Properties.Items.AddEnum<Tag.TagOrderStatus>();
 }
).GetHtml();

the "struct" type constraint limits the type that can be used as the generic type, but won't limit it to only enums. Sh*t will hit the fan if something else that an enum is used, but it's a bit too complicated to apply a real functional compile time limit.

Have fun!

Monday, January 27, 2014

C# .Net: Get the value of a static property of a generic type

I did a base type for a singleton pattern and used a generic type later to refer to a inherited type. Here is how I got access to the Instance method:

instance = (T)typeof(T).GetProperty("Instance"BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public).GetValue(nullnew object[] { });

This will call the base class Instance property and return the singleton instance of the inherited T class.

It's a bit hard to explain in words... I still hope it helps someone ;)