<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6678165313864777430</id><updated>2025-11-08T04:20:47.540-08:00</updated><title type='text'>My Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-4266789266378747448</id><published>2015-03-09T04:30:00.000-07:00</published><updated>2015-11-23T02:21:42.096-08:00</updated><title type='text'>Best AdMob alternatives</title><content type='html'>&lt;a href=&quot;http://mopub.com/&quot;&gt;MoPub&lt;/a&gt;
&lt;br /&gt;
&lt;a href=&quot;http://axonix.com/&quot;&gt;Axonix (requires Google Play Services)&lt;/a&gt;
&lt;br /&gt;
&lt;a href=&quot;http://mobfox.com/&quot;&gt;MobFox (requires Google Play Services, but has custom API)&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.inmobi.com/&quot;&gt;InMobi (requires Google Play Services)&lt;/a&gt;
&lt;br /&gt;
&lt;a href=&quot;https://www.leadbolt.net/&quot;&gt;LeadBolt (only full screen ads)&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://tools.mmedia.com/apps/appsDashboard&quot; target=&quot;_blank&quot;&gt;MMedia (requires Google Play Services)&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;
&lt;br /&gt;
(pickup which one is lesser evil)</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/4266789266378747448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2015/03/admob-alternative.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/4266789266378747448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/4266789266378747448'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2015/03/admob-alternative.html' title='Best AdMob alternatives'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-1016361800147494841</id><published>2014-10-26T08:04:00.001-07:00</published><updated>2014-10-26T08:04:59.380-07:00</updated><title type='text'>Show longest continuous block of code not covered by tests</title><content type='html'>Usage:
nocov.py &lt;coverage-html-report&gt;
&lt;pre&gt;
import fileinput
count = 0
lengths = {}
first = 0
for line in fileinput.input():
    if first and (&#39;stm mis&#39; in line or &#39;pln&#39; in line):
        lengths[first] += 1
    else:
        t = line.split(&quot;id=&#39;t&quot;)
        if len(t) &lt; 2:
            continue
        first = t[-1].split(&quot;&#39;&quot;)[0]
        lengths[first] = 1

for x in sorted(lengths.items(), key=lambda (x, y): y):
    print x
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/1016361800147494841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/10/show-longest-continuos-block-of-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1016361800147494841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1016361800147494841'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/10/show-longest-continuos-block-of-code.html' title='Show longest continuous block of code not covered by tests'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-6736804101958410830</id><published>2014-10-26T08:02:00.000-07:00</published><updated>2014-10-26T08:02:14.017-07:00</updated><title type='text'>Profiling C++ scopes</title><content type='html'>The following simple class measure time spent in scope it is declared in:
&lt;pre&gt;
class profile {
    // usage: profile __profile(__FILE__, __LINE__);
    static map &lt; pair&lt;string, unsigned&gt;, clock_t&gt; __total;
    string _file;
    unsigned _line;
    clock_t _start;
public:
    profile(const char* file, unsigned line) :
        _file(file), _line(line), _start(clock()) {
    }
    ~profile() {
        clock_t d = clock() - _start;
        clock_t t = __total[make_pair(_file, _line)] += d;
        OutputDebugStringA(((string)_file + &#39;:&#39; + to_string(_line) + &quot;+=&quot; + to_string(d) + &quot; = &quot; + to_string(t) + &#39;\n&#39;).c_str());
    }
};
map &lt; pair&lt;string, unsigned&gt;, clock_t&gt; profile::__total;
&lt;/pre&gt;
Example:
&lt;pre&gt;
void foo() {
profile __profile(__FILE__, __LINE__); // measure time in foo
// other code
while (something) {
profile __profile(__FILE__, __LINE__); // measure time in while loop
}
}
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/6736804101958410830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/10/profiling-c-scopes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/6736804101958410830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/6736804101958410830'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/10/profiling-c-scopes.html' title='Profiling C++ scopes'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-1794477203617152581</id><published>2014-09-24T23:31:00.002-07:00</published><updated>2015-06-16T23:16:08.424-07:00</updated><title type='text'>VPS hosting shortlist</title><content type='html'>Linux:&lt;br /&gt;
&lt;a href=&quot;https://ititch.com/&quot;&gt;https://ititch.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.web-hosting.com/&quot;&gt;http://www.web-hosting.com/&lt;/a&gt; &lt;br /&gt;
&lt;a href=&quot;https://www.ovh.com/&quot;&gt;https://www.ovh.com/&lt;/a&gt;&lt;br&gt;
Windows:&lt;br /&gt;
&lt;a href=&quot;http://alt-hosting.com/&quot;&gt;http://alt-hosting.com/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/1794477203617152581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/09/web-hosting-short-list.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1794477203617152581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1794477203617152581'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/09/web-hosting-short-list.html' title='VPS hosting shortlist'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-7137792498672062059</id><published>2014-05-30T00:47:00.000-07:00</published><updated>2014-10-26T08:02:31.854-07:00</updated><title type='text'>Why I hate fxsol.co.uk?</title><content type='html'>Short answer: you can not get your money back. Once you send it to &lt;a href=&quot;http://www.fxsol.co.uk/&quot;&gt;FX Solutions&lt;/a&gt; consider them lost. They will find 1000 reasons but will not process your withdrawal request.&lt;br /&gt;
Long answer: just look at this:&lt;br /&gt;
&lt;h2&gt;
Case #1&lt;/h2&gt;
I have request to withdraw to another bank since my previous bank shut down:&lt;br /&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Mon, 31 Mar 2014 16:03:41 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Mr Z. MT650629 
  
 
Thank you for your recent withdrawal request. Unfortunately, we are unable to process your request as we are required to return the funds to the source bank account ending 3840 at Loyal Bank. 
  
Please reply to our email confirming the following information: 
 
 
ABA/SWIFT/BSB/BIC/IBAN/Sort Code - Please select as appropriate  
 
Bank Name 
 
Bank Address 
 
Beneficiary Name 
 
Bank Account Number 
 
Sort Code if applicable                                 
If you require any further assistance please contact us during opening hours on the contact details below.
 
 
Regards, 
Pedro Bennasar
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 06:41:04 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear customer, 
  
If this account ending 3840 is closed, you will need to provide a close proof so that we can return the fund to your other bank account. Thanks. 
  
 
Regards, 
Jiachen Shen
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 07:15:59 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear customer, 
  
If bank does not accept USD wire, does it mean that they will convert the USD into other currency when they receive the fund? Please confirm with your bank. Thanks. 
  
 
Regards, 
Jiachen Shen
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 13:28:59 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

No they do not accept incoming wire transfers at all since December 2013.
All incoming transfers will be put on hold or reversed.
PLEASE DO NOT SEND MONEY TO LOYALBANK! IT WILL BE LOST!

Please send to local bank account I&#39;ve provided. See attachment for the
proof I&#39;m owner of this account as well.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 10:55:14 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Mr Z. MT 650629 
  
We are in receipt of your withdraw request, however to be in compliance with our Anti Money Laundering  policy, we must send funds back to your original bank account with which you funded your account.  
  
Please provide the swift code, bank name, address and account number for the account ending in 3840 in order for us to proceed with your request.  
  
If your bank is not accepting incoming wires please provide us a confirmation on a headed paper from your bank, we are not allowed to call your bank due to the  Data Protection Act to check this. 
  
If we send the funds to Loyal Bank and they return it to us then we can check for alternative options. 
  
We look forward to hearing from you soon. 
 
Regards, 
Katya de Rios
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 17:20:09 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

If I add funds to account using another bank can I use it for
withdrawals after this?
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 1 Apr 2014 11:42:23 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Mr Z. MT 650629 
  
Could you please get a confirmation from your bank that they can not accept incoming wires so we see an alternative solution for you. 
  
If you deposit new funds we will only return this funds to the new bank account that you will use. 
  
Thank you. 
 
Regards, 
Katya de Rios
&lt;/pre&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Wed, 2 Apr 2014 10:57:59 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

That is ok I want to use this account in future. I&#39;ve sent funds. Details:

Dear Valued Customer

International Fund Transfer Transaction

Instruction Date : 02/04/2014 09:55
Transfer Date : 02/04/2014
Reference No : 14464
Payer A/C Name : IURII Z. , A/C No.: XXXXXXXXXX
Payee A/C Name : CITY INDEX LIMITED TRADING , A/C No.: GB47CHAS60924241408410
Address : PARK HOUSE, 16 FINSBURY CIRCUS
    LONDON EC2M 7EB
    UNITED KINGDOM
Receiver Bank : JPMORGAN CHASE BANK, N.A. , Branch :
Bank Code : CHASGB2L
Transfer Amount : USD 50.00
Exchange Rate : 32.4900000
Deduct Amount : THB 1,624.50
Fee : THB 1,100.00
Short Note : -
Remark : Your transaction may be declined due to a problem of the
destination bank.
    Please check your statement
Remittance Information : AC NO 650629 - - -
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Wed, 2 Apr 2014 08:03:28 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Sir, 
  
Per previously advised, funds will need to be withdrawn back to the source bank account. 
As you have advised that Loyal Bank no longer accepts incoming USD, and your account is still open with Loyal Bank. We will require you to provide confirmation from Loyal Bank that they are no longer able to accept USD into your bank account with them. 
  
Please advise so that we may proceed further. 
  
  
 
Regards, 
Anthony Chia
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Wed, 2 Apr 2014 15:44:16 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Mr Z. MT651310 
  
Kindly be informed that your $50 wire transfer has been now returned back to the remitter bank account since funds were originated from a different Country where you reside. Please note that in order to comply with our AML policy, funds must come from your Country of Residence. 
  
If you require any further assistance please contact us during opening hours on the contact details below.
 
 
Regards, 
Pedro Bennasar
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 3 Apr 2014 14:00:25 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

Then please send 1 USD to LoyalBank to verify it will not be processed.

Beneficiary:
Name: Z. Iurii
Address: XXX
Account number: XXXXXXXXX

Beneficiary Bank:
Name: Loyal Bank Limited
Address: Cedar Hill Crest, Villa, VC0100, Kingstown, St. Vincent and
the Grenadines, West Indies
SWIFT code: LOYAVCVX

This situation is an absurd. I&#39;m very disappointed by your withdrawal service...
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 3 Apr 2014 14:08:44 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

Attached the proof my Country of Residence is Thailand.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 3 Apr 2014 08:09:26 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear customer, 
  
We cannot process 1 USD withdraw to LoyalBank. You will need to get the bank provide proof that they cannot accept USD wire. Thanks. 
  
 
Regards, 
Jiachen Shen
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 3 Apr 2014 14:18:14 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

Are you kidding me?! In the email before you said you can process
withdrawals to LoyalBank only. Now you say you will not send my money
anywhere.
I can not provide the proof they do not accept anything. Their customer
support is not answering. They do not reply by email and by phone they
promised they will send it but didn&#39;t send anything. &lt;/pre&gt;
&lt;br /&gt;
...more than&amp;nbsp; one month has passed and I still haven&#39;t returned my money.
&lt;br /&gt;
&lt;h2&gt;
Case #2 &lt;/h2&gt;
Another attempt to withdraw my money:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 15 May 2014 19:20:34 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

Hello,

Please send another withdrawal of $400 using same instructions to same bank
account.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 15 May 2014 14:04:25 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Mr Z.,  MT650629 
  
We have noticed that your form states a different address to the one we have on file. 
Kindly complete and submit the attached form if you have changed your Country of Residence. 
Your withdrawal request will be processed upon receipt of your confirmation. 
  
 
Regards, 
Pedro Bennasar
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Fri, 16 May 2014 06:41:31 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

I see no attachment.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Fri, 16 May 2014 00:53:54 +0100
From: funding@fxsol.co.uk
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Client MT650629, 
  
Please see attached to update your contact information. 
Thank you. 
  
 
Regards, 
Siyuan Chang
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Sat, 17 May 2014 18:49:40 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: funding@fxsol.co.uk

Please see attachments.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Mon, 19 May 2014 10:26:38 +0100
From: &quot;FX Solutions&quot; &amp;lt;accounts@fxsol.co.uk&amp;gt;
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Iurii Z. 
  
Thank you very much for your email. 
  
Unfortunately, we are unable to update your address because the proof of address document you sent to us is not in English. 
  
Please re-send us one of the below documents in English. If the document is not in English, please have the document be translated in to English or verified by a certified accountant, lawyer or a notary public. 
  
1. copy of credit card statement dated within the last three months 
2. copy of bank statement dated within the last three months 
3. copy of utility bill dated within the last three months 
  
Kindly take note that e-statement and mobile bill are not accepted. 
  
We will update your record as soon as receipt of the above document. 
  
Feel free to let us know if you have any enquiry. 
  
 
Regards, 
Mei-Ling Chan
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Tue, 20 May 2014 16:52:42 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: FX Solutions &amp;lt;accounts@fxsol.co.uk&amp;gt;

Please see attachment for bank statement dated today. Address in top left
corner.

https://maps.google.ru/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=+&amp;amp;q=ao+nang&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Ao+Nang,+Mueang+Krabi+District,+Krabi,+Thailand&amp;amp;t=m&amp;amp;z=12&amp;amp;vpsrc=0&amp;amp;iwloc=A

https://maps.google.ru/maps?f=q&amp;amp;source=s_q&amp;amp;hl=th&amp;amp;geocode=+&amp;amp;q=ao+nang&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Ao+Nang,+Mueang+Krabi+District,+Krabi,+Thailand&amp;amp;t=m&amp;amp;z=12&amp;amp;vpsrc=0&amp;amp;iwloc=A
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Wed, 21 May 2014 09:37:18 +0100
From: &quot;FX Solutions&quot; &amp;lt;accounts@fxsol.co.uk&amp;gt;
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Iurii Z. 
  
As mentioned in my previous email, we are unable to verify documents which is not in English. Please have the document be translated in to English or verified by a certified accountant, lawyer or a notary public. 
  
Or you can request your bank to issue a letter to you which states your name, address and the account your are maintaining with the bank. 
  
Feel free to let us know if you have any enquiry. 
 
Regards, 
Mei-Ling Chan
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 22 May 2014 14:29:37 +0700
From: &quot;Yurii Z.&quot; &amp;lt;yurii....@gmail.com&amp;gt;
To: FX Solutions &amp;lt;accounts@fxsol.co.uk&amp;gt;

OK. Certified translation costs $30-50 per page. If you credit it to my
account I will send you certified translation.
&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre style=&quot;white-space: pre-wrap;&quot;&gt;Date: Thu, 22 May 2014 09:42:00 +0100
From: &quot;FX Solutions&quot; &amp;lt;accounts@fxsol.co.uk&amp;gt;
To: &amp;lt;yurii....@gmail.com&amp;gt;

Dear Iurii Z. 
  
I am afraid this translation cost shall be beared by client. 
  
As mentioned, you can request a letter in English from your bank stating your name, address and account number maintaining with the bank. We can accept this letter as the proof of address.   
  
 
Regards, 
Mei-Ling Chan&amp;nbsp;&lt;/pre&gt;
&lt;br /&gt;
Oh, I have to pay $50 for some papers just because FX Solutions UK decided they need it and I have to pay for it. Great.&lt;br /&gt;
So I strongly discourage anybody from putting their money to FX Solutions UK. If you want a good broker try Alpari or Pepperstone. They process withdrawals in 48 hours with no bureaucracy.
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/7137792498672062059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/05/why-i-hate-fxsolcouk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/7137792498672062059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/7137792498672062059'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/05/why-i-hate-fxsolcouk.html' title='Why I hate fxsol.co.uk?'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-4597575745666017766</id><published>2014-04-09T04:14:00.000-07:00</published><updated>2014-04-09T04:14:10.641-07:00</updated><title type='text'>Python cache dictionary</title><content type='html'>&lt;pre&gt;
class cachedict(dict):
    def __init__(self, factory):
        self.factory = factory

    def __missing__(self, key):
        value = self[key] = self.factory(key)
        return value
&lt;/pre&gt;
USAGE:
&lt;pre&gt;
d = cachedict(lambda x: x ** 2)
print d[2]  # 4
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/4597575745666017766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/04/python-cache-dictionary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/4597575745666017766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/4597575745666017766'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2014/04/python-cache-dictionary.html' title='Python cache dictionary'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-1792011223797654004</id><published>2013-06-01T22:59:00.003-07:00</published><updated>2015-03-21T03:51:51.782-07:00</updated><title type='text'>Best AdSense Alternatives</title><content type='html'>&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://adstract.adk2.com/&quot; target=&quot;_blank&quot;&gt;AdStract&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.revenuehits.com/lps/v41/?ref=@RH@ia_DeAA4Nv0&quot; target=&quot;_blank&quot;&gt;RevenueHits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.adcash.com/&quot; target=&quot;_blank&quot;&gt;Adcash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.clicksor.com/&quot; target=&quot;_blank&quot;&gt;Clicksor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.qadabra.com/&quot; target=&quot;_blank&quot;&gt;Qadabra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.bidvertiser.com/&quot; target=&quot;_blank&quot;&gt;BidVertiser&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/1792011223797654004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/06/best-adsense-alternatives.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1792011223797654004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/1792011223797654004'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/06/best-adsense-alternatives.html' title='Best AdSense Alternatives'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-7991256765761813053</id><published>2013-06-01T03:51:00.003-07:00</published><updated>2017-01-17T20:17:50.744-08:00</updated><title type='text'>Motorola Milestone 2 Firmware links</title><content type='html'>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://and-developers.com/sbf&quot; target=&quot;_blank&quot;&gt;and-developers.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sbf.droid-developers.org/umts_milestone2/list.php&quot; target=&quot;_blank&quot;&gt;droid-developers.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/cm-milestone2/&quot; target=&quot;_blank&quot;&gt;Cyanogenmod 10 for Milestone 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drive.google.com/drive/folders/0Bx33D6rXKkhEeEVDVXZkTjVGSUk&quot; target=&quot;_blank&quot;&gt;Cyanogen 11&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ndroidzone.com/2014/11/download-motorola-milestone-2-a953.html&quot; target=&quot;_blank&quot;&gt;http://www.ndroidzone.com/&lt;/a&gt;&lt;a href=&quot;https://firmware.center/firmware/Motorola/Milestone%202%20%28A953%29/Stock/&quot; target=&quot;_blank&quot;&gt;firmware.center&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/7991256765761813053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/06/motorola-milestone-2-firmware-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/7991256765761813053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/7991256765761813053'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/06/motorola-milestone-2-firmware-links.html' title='Motorola Milestone 2 Firmware links'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-6859075620186402201</id><published>2013-05-31T23:31:00.000-07:00</published><updated>2013-05-31T23:31:23.421-07:00</updated><title type='text'>GMail cleanup</title><content type='html'>This Python script cleans All Mail GMail folder by moving emails to Trash if there are more than 33 emails from same sender or email is more than 55 days old (values can be adjusted by editing code). IMAP must be enabled in order to work.
&lt;pre&gt;
#!/usr/bin/env python
from datetime import datetime, timedelta
from email.utils import parsedate, parseaddr
import imaplib
import re
import socket

socket.setdefaulttimeout(30)

IMAP_SERVER = &#39;imap.gmail.com&#39;
IMAP_PORT = 993


def main():
    clean(&#39;email1@gmail.com&#39;, &#39;password1&#39;)
    clean(&#39;email2@gmail.com&#39;, &#39;password2&#39;)


def clean(user, pwd):
    mbox = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
    rc, resp = mbox.login(user, pwd)
    print rc, resp
    r, data = mbox.select(&quot;[Gmail]/All Mail&quot;)
    assert r == &#39;OK&#39;
    r, data = mbox.expunge()
    assert r == &#39;OK&#39;
    r, (ids,) = mbox.search(None, &#39;ALL&#39;)
    assert r == &#39;OK&#39;
    r, data = mbox.fetch(
        &#39;1:*&#39;,
        &#39;(INTERNALDATE FLAGS BODY.PEEK[HEADER.FIELDS (FROM)])&#39;)
    assert r == &#39;OK&#39;
    threads = {}
    for row in data:
        if row == &#39;)&#39;:
            continue
        uid_date, subject = row
        m = re.compile(
            r&#39;(\d+) \(INTERNALDATE &quot;(.*)&quot; FLAGS \((.*)\) &#39;
            &#39;BODY\[HEADER\.FIELDS\ \(FROM\)\]\ \{\d+\}&#39;).match(uid_date)
        assert m, uid_date
        uid, date, flags = m.groups()
        if &#39;\\Flagged&#39; in flags:
            continue
        date = parsedate(date)
        uid = int(uid)
        _, frm = parseaddr(subject)
        threads.setdefault(frm, []).append((date, uid))
    uids = []
    for key, lst in sorted(threads.items(), key=lambda x: len(x[1])):
        # date descending
        lst.sort(reverse=True)
        for no, (date, uid) in enumerate(lst):
            if no &gt; 33 or datetime.now() - datetime(*date[:6]) &gt; timedelta(55):
                print key, date, uid
                uids.append(uid)
    # uids.sort(reverse=True)
    print len(uids)
    if uids:
        r, data = mbox.store(
            #&#39;,&#39;.join(str(uid) for uid in uids), &#39;+FLAGS&#39;, &#39;\\Deleted&#39;)
            &#39;,&#39;.join(str(uid) for uid in uids), &#39;+X-GM-LABELS&#39;, &#39;\\Trash&#39;)
        assert r == &#39;OK&#39;
    r, data = mbox.expunge()
    assert r == &#39;OK&#39;
    print &#39;ok&#39;
    mbox.close()
    mbox.logout()


if __name__ == &#39;__main__&#39;:
    main()

&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/6859075620186402201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/05/gmail-cleanup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/6859075620186402201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/6859075620186402201'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/05/gmail-cleanup.html' title='GMail cleanup'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-196263554784264237</id><published>2013-04-28T01:23:00.000-07:00</published><updated>2013-04-28T01:23:15.054-07:00</updated><title type='text'>XFCE reboot on Ctrl+Alt+Delete</title><content type='html'>xfconf-query -c xfce4-keyboard-shortcuts -n -p &quot;/commands/custom/&lt;Primary&gt;&lt;Alt&gt;Delete&quot; -t string -s &quot;xfce4-session-logout -r&quot;
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/196263554784264237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/04/xfce-reboot-on-ctrlaltdelete.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/196263554784264237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/196263554784264237'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/04/xfce-reboot-on-ctrlaltdelete.html' title='XFCE reboot on Ctrl+Alt+Delete'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-8558992857376602434</id><published>2013-04-28T01:22:00.003-07:00</published><updated>2013-04-28T01:22:57.740-07:00</updated><title type='text'>Exclude the only specific field from django serialization</title><content type='html'>MyModel._meta.get_field(&#39;my_field&#39;).serialize = False
</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/8558992857376602434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/04/exclude-only-specific-field-from-django.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/8558992857376602434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/8558992857376602434'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/04/exclude-only-specific-field-from-django.html' title='Exclude the only specific field from django serialization'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-3845130111593804622</id><published>2013-03-28T03:57:00.001-07:00</published><updated>2013-04-15T22:41:31.845-07:00</updated><title type='text'>Sort Firefox Bookmarks</title><content type='html'>&lt;code&gt;
% sqlite3 ~/.mozilla/firefox/*.default/places.sqlite &#39;update moz_bookmarks set position=(select count(*) from moz_bookmarks as b where lower(b.title) &amp;lt; lower(moz_bookmarks.title));&#39;
&lt;/code&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/3845130111593804622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/03/sort-firefox-bookmarks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/3845130111593804622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/3845130111593804622'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/03/sort-firefox-bookmarks.html' title='Sort Firefox Bookmarks'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-3528690881601140995</id><published>2013-01-30T05:20:00.000-08:00</published><updated>2013-04-15T22:40:24.449-07:00</updated><title type='text'>Autologin in FreeBSD without GDM</title><content type='html'>Autologin and startx without GDM or other display manager:

&lt;ol&gt;
&lt;li&gt;Add this line to /etc/gettytab to describe new terminal line with autologin
&lt;blockquote&gt;
al.username:al=username:tc=std.230400:
&lt;/blockquote&gt;
, where &amp;lt;username&amp;gt; is user to log in automatically.
&quot;al.username&quot; is the terminal name which can be any.
&lt;/li&gt;
&lt;li&gt;
Change ttyv0 line in /dev/ttys from this:
&lt;blockquote&gt;
ttyv0 &quot;/usr/libexec/getty Pc&quot;  xterm on  secure
&lt;/blockquote&gt;
to this
&lt;blockquote&gt;
ttyv0 &quot;/usr/libexec/getty al.username&quot; xterm on  secure
&lt;/blockquote&gt;
to spawn auto logged in terminal at Alt+F1 console.
&lt;/li&gt;
&lt;li&gt;
Set login shell on ttyv0 to start X11 immediately
&lt;blockquote&gt;
echo &#39;if $tty == ttyv0 startx&#39; &gt;&gt; ~/.login
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
Reboot.&lt;/li&gt;
&lt;li&gt;
X11 will start automatically for &amp;lt;username&amp;gt;.
&lt;/li&gt;
&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/3528690881601140995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/01/autologin-in-freebsd-without-gdm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/3528690881601140995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/3528690881601140995'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2013/01/autologin-in-freebsd-without-gdm.html' title='Autologin in FreeBSD without GDM'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-5948086932179868563</id><published>2012-09-10T00:55:00.000-07:00</published><updated>2013-02-11T19:59:14.215-08:00</updated><title type='text'>Django html5lib validating middleware</title><content type='html'>&lt;p&gt;Django middleware to validate every HTML response with html5lib.&lt;/p&gt;

&lt;h2&gt;Usage&lt;/h2&gt;

&lt;ol&gt;
    &lt;li&gt;Save to middleware.py&lt;/li&gt;
    &lt;li&gt;Add &#39;middleware.ProfileMiddleware&#39; to MIDDLEWARE_CLASSES&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Listing&lt;/h2&gt;
&lt;pre&gt;
from html5lib.html5parser import HTMLParser
from html5lib import treebuilders
from django.http import HttpResponse


class ValidateMiddleware(object):
    def process_request(self, request):
        pass

    def process_response(self, request, response):
        if response.content and &#39;html&#39; in response[&#39;Content-Type&#39;] \
                and &#39;disable-validation&#39; not in request.GET:
            # validate
            treebuilder = treebuilders.getTreeBuilder(&quot;simpleTree&quot;)
            parser = HTMLParser(tree=treebuilder, strict=True)
            try:
                parser.parse(response.content)
            except Exception:
                pass
            if parser.errors:
                # format output
                out = []
                lines = response.content.splitlines()
                for (row, col), e, d in parser.errors:
                    out.append(&#39;%s, %s&#39; % (e, d))
                    for x in range(max(0, row - 3), min(len(lines), row + 1)):
                        out.append(lines[x])
                    out.append(&#39; &#39; * col + &#39;^&#39;)
                out = &#39;\n&#39;.join(out)
                return HttpResponse(out, mimetype=&#39;text/plain&#39;)
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        return callback(request, *callback_args, **callback_kwargs)
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/5948086932179868563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2012/09/django-html5lib-validating-middleware.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/5948086932179868563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/5948086932179868563'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2012/09/django-html5lib-validating-middleware.html' title='Django html5lib validating middleware'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6678165313864777430.post-2749172766031116883</id><published>2012-06-21T19:52:00.002-07:00</published><updated>2013-02-11T20:28:31.214-08:00</updated><title type='text'>Django Profiling Middleware</title><content type='html'>&lt;p&gt;
This Django middleware can be used to collect and print accumulated profiling statistics on a running site. As opposed to popular individual view profiling tools this one profiles all existing views as they are being executed and saves statistics for later usage. On production (DEBUG=False) only each 20-th request is profiled to keep CPU overhead low.
&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Save to profile.py&lt;/li&gt;
&lt;li&gt;Add &#39;profile.ProfileMiddleware&#39; to MIDDLEWARE_CLASSES&lt;/li&gt;
&lt;li&gt;...run requests&lt;/li&gt;
&lt;li&gt;Visit http://mysite/profile/ to print accumulated statistics&lt;/li&gt;
&lt;li&gt;Visit http://mysite/myview?profile to profile this view only and print statistics immediately&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Listing&lt;/h2&gt;
&lt;pre&gt;
from cStringIO import StringIO
from django.conf import settings
from django.http import HttpResponse
from os import path
from random import randrange
import cProfile
import pstats

# see pstats.Stats.print_stats
RESTRICTIONS = 30,
# to keep stats in memory
STATS_FILE = None
# to dump accumulated stats to file after every request
STATS_FILE = &#39;/tmp/mysite.profile&#39;


class ProfileMiddleware(object):
    empty = True
    prof = cProfile.Profile()

    def process_request(self, request):
        if request.path.startswith(&#39;/profile/&#39;):
            # return collected stats
            if not (settings.DEBUG or request.user.is_staff):
                return HttpResponseForbidden(
                    &#39;Forbidden&#39;, content_type=&#39;text/plain&#39;)
            return self.print_stats()

    def process_response(self, request, response):
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        if &#39;profile&#39; in request.GET:
            # profile this view and print results
            self.prof.clear()
            self.prof.runcall(
                callback, request, *callback_args, **callback_kwargs)
            self.empty = False
            return self.print_stats(None)
        if not self.empty and not settings.DEBUG and randrange(20):
            # run without profiling
            return callback(request, *callback_args, **callback_kwargs)
        # run with profiling
        self.empty = False
        if STATS_FILE:
            self.prof.clear()
        retval = self.prof.runcall(
            callback, request, *callback_args, **callback_kwargs)
        if STATS_FILE:
            # merge stats
            self.save()
        return retval

    def save(self):
        stats = pstats.Stats(self.prof)
        stats.strip_dirs()
        if path.exists(STATS_FILE):
            try:
                stats.add(STATS_FILE)
            except (EOFError, ValueError):
                pass
        stats.dump_stats(STATS_FILE)

    def print_stats(self, input_file=STATS_FILE):
        # handle ourselfves
        out = StringIO()
        if input_file:
            stats = pstats.Stats(input_file, stream=out)
        else:
            if self.empty:
                return HttpResponse(&#39;No data yet.&#39;, content_type=&#39;text/plain&#39;)
            stats = pstats.Stats(self.prof, stream=out).strip_dirs()
        stats.sort_stats(&#39;cumulative&#39;).print_stats(*RESTRICTIONS)
        stats_str = out.getvalue()
        return HttpResponse(stats_str, content_type=&#39;text/plain&#39;)
&lt;/pre&gt;

&lt;h2&gt;See also&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://code.djangoproject.com/wiki/ProfilingDjango&quot;&gt;Profiling Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://djangosnippets.org/snippets/186/&quot;&gt;Profiling Middleware snippet #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://djangosnippets.org/snippets/605/&quot;&gt;Profiling Middleware snippet #2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://12-oz-programmer.blogspot.com/feeds/2749172766031116883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://12-oz-programmer.blogspot.com/2012/06/django-profiling-middleware.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/2749172766031116883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6678165313864777430/posts/default/2749172766031116883'/><link rel='alternate' type='text/html' href='http://12-oz-programmer.blogspot.com/2012/06/django-profiling-middleware.html' title='Django Profiling Middleware'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>