var tipuesearch = {"pages":[{"title":"About","text":"I set up this blog when I started out learning Python with every intention to post new things as I learned them. It was going to be great. I'd learn new things and then type them up so that I'd have notes to refer back to and so that others could learn from the mistakes I'd made along the way. It turns out that just typing into a note taking application is easier. I started with programming back when I was 12 in BASIC on an Amstrad CPC 464. I played with Visual Basic and Delphi as a hobby in my teens but didn't really get very far with either. I didn't plan on becoming a developer as a career, but that happened accidentally when I started working at an office in Manchester. It turns out many small, time consuming tasks can be replaced with scripts and that evolved into desktop application and web development before I realised what was happening. After having tried out a few tools I mainly use Python with PyQt for desktop and Django/Flask for web and am enjoying learning new things as I go. I might write some of those things up here. Or I might just type them into my notebook.","tags":"pages","url":"https://overthere.co.uk/about/","loc":"https://overthere.co.uk/about/"},{"title":"Bing Wallpaper Changer","text":"About This program will run in the system tray and check for a new daily Bing image on a user defined interval. If the URL for the image has changed since the last check the new image will be downloaded and applied as the current wallpaper. There is also the option to run a command after the wallpaper has been applied. This is useful for anyone that uses software that overlays data onto their wallpaper, Such as BgInfo from Sysinternals. The last two week's worth of images is available on a History tab - just double click a thumbnail to apply a wallpaper. If using this and you want to keep an old wallpaper don't forget to disable to the automatic updating from the main Settings tab, otherwise the wallpaper will be replaced with the daily wallpaper on the next update check. Why? I don't use Bing as a search engine, but I do very much like their daily images. I was excited when I first heard about the official Bing Desktop application, but wasn't keen on the toolbar that was added to my desktop. I tried to just live with it for a while but it caused problems with a few full screen applications when it refreshed. After not being able to find a similar program with the features I wanted I decided to write my own. Screenshots Changelog 1.6 Added support for extra desktop environments under Linux. Improved performance of History tab when loading images from disk. Ability to switch between black and white icon for system tray. 1.5 Ability to save images to a custom folder. Increased History tab range back up to 3 weeks; duplicate dates will be ignored. 1.4 Command line switches for closing after applying wallpaper (—quit). 1.3 Added ability to set old Bing wallpapers from the History tab by double clicking the thumbnail. Reduced History tab range from three weeks to two as duplicates were shown when Bing had featured interactive images on the homepage. 1.2 Added option to system tray menu to directly open settings page. Wallpaper change is now permanent and should be retained after logoff/shutdown. Switched to Qt downloading methods instead of Python. Initial Linux support added in source. Tested on Ubuntu 13.04 - working fine apart from QSystemTrayIcon not being displayed. Need to find how that's handled in Ubuntu now… 1.1 Added Settings and History tabs to the main window. Fixed broken refresh when current Bing image is the same as previously downloaded image. GUI fixes. 1.0 First release with basic functionality. Download Version 1.6 (~9.1 MB )","tags":"Software","url":"https://overthere.co.uk/bing-wallpaper-changer/","loc":"https://overthere.co.uk/bing-wallpaper-changer/"},{"title":"Convert local path to UNC path in Python","text":"I recently had the need to convert a local path to a UNC path for an application I was writing. The application monitors a local folder for files and serves them to a client over the network as requested, but for the client to be able to access the file the path had to be a UNC path. There didn't seem to be a built in way to do this in Python so here's what I ended up with. When the NetworkPaths class is initialised it will build a dictionary of available Windows shares on the current machine with the path as the key and share name as the value. It then creates a list of the share paths ordered by longest first. When the convert method is given a path it works through the list of stored share paths checking to see if any match the start of the given path. If a match is found it builds the UNC path using the dictionary lookup to get the share name. class NetworkPaths ( object ): def __init__ ( self ): super ( NetworkPaths , self ) . __init__ () obj_wmi_service = win32com . client . Dispatch ( 'WbemScripting.SWbemLocator' ) obj_s_wbem_services = obj_wmi_service . ConnectServer ( '.' , 'root\\cimv2' ) items = obj_s_wbem_services . ExecQuery ( 'SELECT * FROM Win32_Share' ) self . shares_lookup = { str ( share . Path ): str ( share . Name ) for share in items if share . Path and not '$' in share . Name and not share . Name == 'Users' } self . shares = sorted (( x for x in self . shares_lookup . keys ()), key = len , reverse = True ) def convert ( self , local_path ): if local_path [: 2 ] == ' \\\\\\\\ ' : # Path is already UNC. return local_path for share_path in self . shares : if local_path . lower () . startswith ( share_path . lower ()): # We have a match. Return the UNC path. if local_path [ len ( share_path )] == ' \\\\ ' : path_end = local_path [ len ( share_path ) + 1 :] else : path_end = local_path [ len ( share_path ):] unc_path = os . path . join ( ' \\\\\\\\ {0:s} ' . format ( os . getenv ( 'COMPUTERNAME' )), self . shares_lookup [ share_path ], path_end ) return unc_path # No match found. return None For example, given the path C:\\Users\\Gary Hughes\\Desktop\\Batch Files\\Full Backup.bat on my machine: network_paths = NetworkPaths () print network_paths . convert ( r 'C:\\Users\\Gary Hughes\\Desktop\\Batch Files\\Full Backup.bat' ) returns: \\\\IRUSH\\Desktop\\Batch Files\\Full Backup.bat With the paths sorted by longest first this should ensure the shortest UNC path is returned.","tags":"Tutorials","url":"https://overthere.co.uk/2014/09/02/python-local-path-to-unc/","loc":"https://overthere.co.uk/2014/09/02/python-local-path-to-unc/"},{"title":"Bing Wallpaper Changer","text":"About This program will run in the system tray and check for a new daily Bing image on a user defined interval. If the URL for the image has changed since the last check the new image will be downloaded and applied as the current wallpaper. There is also the option to run a command after the wallpaper has been applied. This is useful for anyone that uses software that overlays data onto their wallpaper, Such as BgInfo from Sysinternals. The last two week's worth of images is available on a History tab - just double click a thumbnail to apply a wallpaper. If using this and you want to keep an old wallpaper don't forget to disable to the automatic updating from the main Settings tab, otherwise the wallpaper will be replaced with the daily wallpaper on the next update check. New Version Since this blog post I've posted new versions. Take a look at the Bing Wallpaper Changer page. Why? I don't use Bing as a search engine, but I do very much like their daily images. I was excited when I first heard about the official Bing Desktop application, but wasn't keen on the toolbar that was added to my desktop. I tried to just live with it for a while but it caused problems with a few full screen applications when it refreshed. After not being able to find a similar program with the features I wanted I decided to write my own. Changelog 1.3 Added ability to set old Bing wallpapers from the History tab by double clicking the thumbnail. Reduced History tab range from three weeks to two as duplicates were shown when Bing had featured interactive images on the homepage. 1.2 Added option to system tray menu to directly open settings page. Wallpaper change is now permanent and should be retained after logoff/shutdown. Switched to Qt downloading methods instead of Python. Initial Linux support added in source. Tested on Ubuntu 13.04 - working fine apart from QSystemTrayIcon not being displayed. Need to find how that's handled in Ubuntu now… 1.1 Added Settings and History tabs to the main window. Fixed broken refresh when current Bing image is the same as previously downloaded image. GUI fixes. 1.0 First release with basic functionality.","tags":"Software","url":"https://overthere.co.uk/2013/09/01/bing-wallpaper-changer/","loc":"https://overthere.co.uk/2013/09/01/bing-wallpaper-changer/"},{"title":"Improving PyPDF2 with PDFtk","text":"PyPDF2 (forked from pyPdf ) is wonderful. I use it a fair bit in my job, mainly for chopping up PDFs and re-assembling the pages in a different order. It does sometimes have difficulty with non-standard PDFs though that seem fine in other programs. This can be frustrating. The one that I've been battling with today from some PDFs provided by a client was: PyPDF2 . utils . PdfReadError : EOF marker not found I managed to find a workaround using PDFtk to fix the PDF in memory at the first sign of any trouble. It works well so far, so in case anyone else is having similar issues I thought I'd write it up. So here's how I was opening PDF files before. from PyPDF2 import PdfFileReader from cStringIO import StringIO input_path = 'c:/test_in.pdf' with open ( input_path , 'rb' ) as input_file : input_buffer = StringIO ( input_file . read ()) input_pdf = PdfFileReader ( input_buffer ) At that point you're free to do whatever it is you want to do with input_pdf . Providing of course that it loaded without issue. I'm loading the file into a StringIO object first for speed; the program this is from does lots of things with the file and StringIO made things much faster. So to work around the EOF problem I add a new decompress_pdf function that gets called if there's a problem parsing the PDF . It takes the data from the StringIO and sends it to a PDFtk process on stdin that simply runs PDFtk's uncompress command on the data. The fixed PDF is read back from stdout and returned as a StringIO , where things will hopefully carry on as if nothing happened. from PyPDF2 import PdfFileReader , utils from cStringIO import StringIO import subprocess input_path = 'c:/test_in.pdf' def decompress_pdf ( temp_buffer ): temp_buffer . seek ( 0 ) # Make sure we're at the start of the file. process = subprocess . Popen ([ 'pdftk.exe' , '-' , # Read from stdin. 'output' , '-' , # Write to stdout. 'uncompress' ], stdin = temp_buffer , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) stdout , stderr = process . communicate () return StringIO ( stdout ) with open ( input_path , 'rb' ) as input_file : input_buffer = StringIO ( input_file . read ()) try : input_pdf = PdfFileReader ( input_buffer ) except utils . PdfReadError : input_pdf = PdfFileReader ( decompress_pdf ( input_file )) The problem I was seeing seemed to be because of invalid characters appearing after the %% EOF marker in the PDF . PDFtk seems better at fixing this and spits out a valid PDF when the uncompress command is used. Of course, more error detection would be good in case parsing still fails, but this worked for me today and made me happy.","tags":"Tutorials","url":"https://overthere.co.uk/2013/07/22/improving-pypdf2-with-pdftk/","loc":"https://overthere.co.uk/2013/07/22/improving-pypdf2-with-pdftk/"},{"title":"New Blog!","text":"I've moved this site from WordPress to Pelican . Pelican is awesome. WordPress is written in PHP and uses MySQL to store the data needed to build each page. The good thing about WordPress is that the pages are built as they are requested. The bad thing about WordPress is that the pages are built as they are requested. The whole database-driven dynamic page thing can slow down a site quite a bit, especially if you're only using a basic hosting package. If like me you also install a boatload of plugins and themes to test things out the database gets full of cruft adding to more slowdowns. I experimented with various different caching plugins and they seemed to work great for a couple of weeks and then they'd stop updating the content and serve up week-old stale pages. I never found out why. So a caching plugin basically saves a copy of a generated page as a static HTML file and serves it back up if the page is requested again instead of having to recreate it. It's a way of turning your nice dynamic site into a static site. So why not just have a static site? Well, it's good to have themes, plugins and control over other parts of the site to be able to change things quickly. It's also nice to have a nice interface for writing posts. While looking for alternative blogging platforms that might improve the speed of my site I stumbled across Pelican. The fact that it's written in Python had me interested right away. Pelican doesn't require any kind of fiddly setting up of the web host, it just parses a config file with site settings, takes posts written in single Markdown files and creates a static HTML site. When you add a new post by creating a new Markdown file the whole site can be regenerated again. Very quickly. Tie this with rsync for quick deployment back to the web host and you have a very customisable and fast blogging solution that's also fun to use. I started out with a couple of the default themes with my own tweaks, but have finally settled on a Pelican port of the default Octopress (similar to Pelican but Ruby based) theme by Maurizio Sambati along with some excellent modifications by Jake Vanderplas . I'm very much happy with the results.","tags":"Blog","url":"https://overthere.co.uk/2013/06/14/new-blog/","loc":"https://overthere.co.uk/2013/06/14/new-blog/"},{"title":"QGraphicsView with mouse wrapping","text":"In a document management program that I'm writing I'm displaying images in a QGraphicsView . The QGraphicsView supports a drag mode that allows a user to simply click and drag within the view to pan around, which works great when a large image is displayed and the user has zoomed in quite far. Panning the image this way does mean that the user has to click back on the image and move the mouse again when the mouse reaches the end of the screen. I needed a way to implement mouse wrapping so that when the mouse reaches the end of the QGraphicsView during panning and the user is still holding down the left mouse button the mouse will jump to the opposite edge, giving a smooth continuous pan. Here's what I came up with… from PyQt4.QtCore import Qt , QEvent , QTimer from PyQt4.QtGui import QWidget , QGraphicsView , QVBoxLayout , \\ QApplication , QGraphicsScene , QBrush , QColor , QMouseEvent , \\ QCursor class GraphicsView ( QGraphicsView ): def mouseMoveEvent ( self , event ): width , height = self . width (), self . height () event_x , event_y = event . x (), event . y () if event_y < 0 or event_y > height or \\ event_x < 0 or event_x > width : # Mouse cursor has left the widget. Wrap the mouse. global_pos = self . mapToGlobal ( event . pos ()) if event_y < 0 or event_y > height : # Cursor left on the y axis. Move cursor to the # opposite side. global_pos . setY ( global_pos . y () + ( height if event_y < 0 else - height )) else : # Cursor left on the x axis. Move cursor to the # opposite side. global_pos . setX ( global_pos . x () + ( width if event_x < 0 else - width )) # For the scroll hand dragging to work with mouse wrapping # we have to emulate a mouse release, move the cursor and # then emulate a mouse press. Not doing this causes the # scroll hand drag to stop after the cursor has moved. r_event = QMouseEvent ( QEvent . MouseButtonRelease , self . mapFromGlobal ( QCursor . pos ()), Qt . LeftButton , Qt . NoButton , Qt . NoModifier ) self . mouseReleaseEvent ( r_event ) QCursor . setPos ( global_pos ) p_event = QMouseEvent ( QEvent . MouseButtonPress , self . mapFromGlobal ( QCursor . pos ()), Qt . LeftButton , Qt . LeftButton , Qt . NoModifier ) QTimer . singleShot ( 0 , lambda : self . mousePressEvent ( p_event )) else : QGraphicsView . mouseMoveEvent ( self , event ) class Widget ( QWidget ): def __init__ ( self , parent = None ): QWidget . __init__ ( self , parent ) self . scene = QGraphicsScene () self . scene . setSceneRect ( - 5000 , - 5000 , 5000 , 5000 ) self . g_view = GraphicsView ( self . scene ) self . g_view . setBackgroundBrush ( QBrush ( QColor ( 'black' ), Qt . DiagCrossPattern )) self . g_view . setDragMode ( QGraphicsView . ScrollHandDrag ) self . g_view . scale ( 5 , 5 ) v_layout = QVBoxLayout () v_layout . addWidget ( self . g_view ) self . setLayout ( v_layout ) if __name__ == '__main__' : import sys app = QApplication ( sys . argv ) widget = Widget () widget . show () sys . exit ( app . exec_ ()) The code above uses a sub-classed QGraphicsView . The mousePressEvent checks to see if the mouse cursor has left the QGraphicsView ; if it has then it moves the mouse to the opposite edge. The bit that had me stuck were the mouseReleaseEvent and mousePressEvent calls. When moving the cursor the drag was still active, so the image just panned back as if the user had moved the mouse. The mouse events are called to simulate releasing the mouse button, moving the pointer and then pressing the mouse button again. This gives a smooth continuous pan until you run out of either image or desk space :).","tags":"Tutorials","url":"https://overthere.co.uk/2012/11/29/qgraphicsview-with-mouse-wrapping/","loc":"https://overthere.co.uk/2012/11/29/qgraphicsview-with-mouse-wrapping/"},{"title":"Using QStyledItemDelegate on a QTableView","text":"Most databases store dates in the format YYYY-MM-DD . When using a QTableView to display a database table in PyQt it's useful to be able to display this in a different format. Being from the UK I'd rather have the date displayed in the UK style – DD/MM/YYYY . This is where QStyledItemDelegate comes in. I'd put off looking into this for a while because whenever I tried to look in to using QStyledItemDelegate I saw people mentioning paint methods. I know nothing about painting in PyQt and get quite scared when I see it mentioned. I really need to get over that. Not to worry though, because it's not needed… Just subclass QStyledItemDelegate and have it take the variable date_format in its __init__ method: class DateFormatDelegate ( QStyledItemDelegate ): def __init__ ( self , date_format ): QStyledItemDelegate . __init__ ( self ) self . date_format = date_format def displayText ( self , value , locale ): return value . toDate () . toString ( self . date_format ) This way we can customise the date format without changing the class making it a little more portable. On your QTableView call setItemDelegateForColumn() and pass it your column index and a new instance of your subclassed QStyledItemDelegate with a date format: self . tableResults . setItemDelegateForColumn ( 3 , DateFormatDelegate ( 'dd/MM/yyyy' )) Much easier than I expected.","tags":"Tutorials","url":"https://overthere.co.uk/2012/07/29/using-qstyleditemdelegate-on-a-qtableview/","loc":"https://overthere.co.uk/2012/07/29/using-qstyleditemdelegate-on-a-qtableview/"},{"title":"Splitting old-style JPEG encoded TIFFs","text":"The tiffsplit program from the libtiff library does a good job of splitting multi-page TIFF files into single pages. It doesn't seem that great at handling TIFFs saved with ‘old-style' JPEG encoding. It'll produce files, and the correct number of files too, but the files are actually in JPEG format. Most image viewers won't open them still because they're JPEG files with TIFF headers. Assuming you have a TIFF file made up entirely of old-style JPEG encoded images you can loop through the files that tiffsplit has exported and remove the first eight bytes to give valid JPEG files. The Python function below will write the contents of a given file that come after the first eight bytes into a new file with the ‘ .jpg ' extension before deleting the original passed file. def remove_header ( path ): \"\"\" Write the contents of the given file after the first 8 bytes to a new file, then delete the original. \"\"\" new_path = ' %s .jpg' % os . path . splitext ( path )[ 0 ] with open ( path , 'rb' ) as input_file : with open ( new_path , 'wb' ) as output_file : input_file . seek ( 8 ) output_file . write ( input_file . read ()) os . remove ( path )","tags":"Blog","url":"https://overthere.co.uk/2012/05/18/splitting-old-style-jpeg-encoded-tiffs/","loc":"https://overthere.co.uk/2012/05/18/splitting-old-style-jpeg-encoded-tiffs/"},{"title":"Windows 7 Minimal Taskbar Menu","text":"Right clicking the taskbar in Windows 7 and selecting Toolbars and New Toolbar will let you select a folder on your computer to add as a taskbar menu. Here's how to make the label take up less space… When you create a new toolbar Windows will add the folder name as a label: I'd prefer it to not take up as much space. Wanting to create a menu for quick AutoHotkey scripts I started with a folder named, simply, ‘Scripts'. Too big. I thought maybe if I created a folder containing just a space character that would work. Then I'd just have a menu without a label - I don't really need a label anyway and I'm all for saving taskbar space. But no. Have you every tried creating a folder in Windows named just with the space character? It doesn't seem to work. It kept being named ‘New Folder' instead. Then I remembered an old trick. I can't even remember what it was for now, but I was using Windows 95 at the time so it was a while aog. I needed to put a space into something but the software I was using prevented it. I used a different character instead; the non-breaking space (Alt+0160 on the numerical keypad under Windows). I gave it a go and sure enough I was able to create a new folder with a seemingly blank character. So the menu now? Much nicer.","tags":"Blog","url":"https://overthere.co.uk/2011/10/20/windows-7-minimal-taskbar-menu/","loc":"https://overthere.co.uk/2011/10/20/windows-7-minimal-taskbar-menu/"},{"title":"Cleaning QR Codes","text":"At work we use QR Codes . It's a pretty recent thing. For a few clients we used to scan pages of a file and then have the scanner operator stop what they were doing to give the TIFF file a meaningful filename. Now we have the clients supply cover sheets, generated with custom software, that contain QR codes. These then get processed after scanning and before the scan of the header sheet is discarded the indexing data is decoded using ZBar through an AutoHotkey script. A few days ago we hit a problem. We'd scanned a few thousand pages but the script was unable to decode any of the indexing data from the QR codes. Not a single page. After looking into it I found that there were quality issues with the printing of the cover sheet. I could tell that the QR code was valid because the app I use on my mobile phone could read it fine, but ZBar could not. And ZBar is what matters – I wasn't about to sit down decoding QR codes with my phone all day. Here's one of the troublesome codes: After playing with the QR code image in Photoshop for a bit I found a way of making the code readable to ZBar. I still needed a way to process the image from within a script on the processing machines, for which we do not have a Photoshop license. GraphicsMagick to the rescue! Or ImageMagick , if that's your thing. The AutoHotkey script was modified so that if no data was returned when attempting to read the QR code it would run the image through an extra function outputting a ‘fixed' version of the image to a temporary file before reading that file instead and returning the data. The clean up used in GraphicsMagick is just: gm convert \"\" -blur 200 -level 80 \"